github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/mappers/bluetooth_mapper/action_manager/action_manager.go (about)

     1  /*
     2  Copyright 2019 The KubeEdge Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8     http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package actionmanager
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"strings"
    23  
    24  	"github.com/paypal/gatt"
    25  	"k8s.io/klog"
    26  
    27  	"github.com/kubeedge/kubeedge/mappers/bluetooth_mapper/data_converter"
    28  )
    29  
    30  const (
    31  	ActionWrite = "WRITE"
    32  	ActionRead  = "READ"
    33  )
    34  
    35  // GattPeripheral  represents the remote gatt peripheral device
    36  var GattPeripheral gatt.Peripheral
    37  
    38  // CharacteristicsList contains the set of characteristics exposed by the device
    39  var CharacteristicsList = make([]*gatt.Characteristic, 0)
    40  
    41  // Operation is structure to define device operation
    42  type Operation struct {
    43  	// Action can be one of read/write corresponding to get/set respectively
    44  	Action string `yaml:"action" json:"action"`
    45  	// Characteristic refers to the characteristic on which the operation needs to be performed
    46  	CharacteristicUUID string `yaml:"characteristic-uuid" json:"characteristic-uuid"`
    47  	// Value is the value to be written in case of write action and value read from the device in case of read action
    48  	Value []byte `yaml:"value" json:"value"`
    49  }
    50  
    51  // Action is structure to define a device action
    52  type Action struct {
    53  	// PerformImmediately indicates whether the action is to be performed immediately or not
    54  	PerformImmediately bool `yaml:"perform-immediately" json:"perform-immediately"`
    55  	// Name is the name of the Action
    56  	Name string `yaml:"name" json:"name"`
    57  	// Operation specifies the operation to be performed for this action
    58  	Operation Operation `yaml:"operation" json:"operation"`
    59  }
    60  
    61  //ActionManager is a structure that contains a list of actions
    62  type ActionManager struct {
    63  	Actions []Action `yaml:"actions"`
    64  }
    65  
    66  //PerformOperation executes the operation
    67  func (action *Action) PerformOperation(readConverter ...dataconverter.DataRead) {
    68  	klog.Infof("Performing operations associated with action:  %s", action.Name)
    69  	characteristic, err := FindCharacteristic(action.Operation.CharacteristicUUID)
    70  	if err != nil {
    71  		klog.Errorf("Error in finding characteristics: %s", err)
    72  	}
    73  	if strings.ToUpper(action.Operation.Action) == ActionRead {
    74  		readValue, err := ReadCharacteristic(GattPeripheral, characteristic)
    75  		if err != nil {
    76  			klog.Errorf("Error in reading  characteristic: %s", err)
    77  			return
    78  		}
    79  		converted := false
    80  		for _, conversionAction := range readConverter[0].Actions {
    81  			if strings.EqualFold(conversionAction.ActionName, action.Name) {
    82  				convertedValue := fmt.Sprintf("%f", conversionAction.ConversionOperation.ConvertReadData(readValue))
    83  				action.Operation.Value = []byte(convertedValue)
    84  				converted = true
    85  			}
    86  		}
    87  		if !converted {
    88  			action.Operation.Value = readValue
    89  		}
    90  		klog.Info("Read Successful")
    91  	} else if strings.ToUpper(action.Operation.Action) == ActionWrite {
    92  		if action.Operation.Value == nil {
    93  			klog.Errorf("Please provide a value to be written")
    94  			return
    95  		}
    96  		err := WriteCharacteristic(GattPeripheral, characteristic, action.Operation.Value)
    97  		if err != nil {
    98  			klog.Errorf("Error in writing characteristic: %s", err)
    99  			return
   100  		}
   101  		klog.Info("Write Successful")
   102  	}
   103  }
   104  
   105  //FindCharacteristic is used to find the bluetooth characteristic
   106  func FindCharacteristic(characteristicUUID string) (*gatt.Characteristic, error) {
   107  	for _, c := range CharacteristicsList {
   108  		if c.UUID().String() == characteristicUUID {
   109  			return c, nil
   110  		}
   111  	}
   112  	return nil, errors.New("unable to find the specified characteristic: " + characteristicUUID)
   113  }
   114  
   115  //ReadCharacteristic is used to read the value of the characteristic
   116  func ReadCharacteristic(p gatt.Peripheral, c *gatt.Characteristic) ([]byte, error) {
   117  	value, err := p.ReadCharacteristic(c)
   118  	if err != nil {
   119  		klog.Errorf("Error in reading characteristic, err: %s\n", err)
   120  		return nil, err
   121  	}
   122  	return value, nil
   123  }
   124  
   125  //WriteCharacteristic is used to write some value into the characteristic
   126  func WriteCharacteristic(p gatt.Peripheral, c *gatt.Characteristic, b []byte) error {
   127  	err := p.WriteCharacteristic(c, b, false)
   128  	if err != nil {
   129  		klog.Errorf("Error in writing characteristic, err: %s\n", err)
   130  		return err
   131  	}
   132  	return nil
   133  }