github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/mappers/bluetooth_mapper/configuration/config.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 configuration 18 19 import ( 20 "encoding/json" 21 "errors" 22 "io/ioutil" 23 "reflect" 24 "strings" 25 26 "gopkg.in/yaml.v2" 27 28 "github.com/kubeedge/kubeedge/mappers/bluetooth_mapper/action_manager" 29 "github.com/kubeedge/kubeedge/mappers/bluetooth_mapper/data_converter" 30 "github.com/kubeedge/kubeedge/mappers/bluetooth_mapper/scheduler" 31 "github.com/kubeedge/kubeedge/mappers/bluetooth_mapper/watcher" 32 ) 33 34 //ConfigFilePath contains the location of the configuration file 35 var ConfigFilePath = "configuration/config.yaml" 36 37 //ConfigMapPath contains the location of the configuration file 38 var ConfigMapPath = "/opt/kubeedge/deviceProfile.json" 39 40 //Config is the global configuration used by all the modules of the mapper 41 var Config *BLEConfig 42 43 //Blutooth protocol name 44 const ( 45 ProtocolName string = "BLUETOOTH" 46 READWRITE string = "ReadWrite" 47 READ string = "ReadOnly" 48 ) 49 50 //BLEConfig is the main structure that stores the configuration information read from both the config file as well as the config map 51 type BLEConfig struct { 52 Mqtt Mqtt `yaml:"mqtt"` 53 Device Device `yaml:"device"` 54 Watcher watcher.Watcher `yaml:"watcher"` 55 Scheduler scheduler.Scheduler `yaml:"scheduler"` 56 ActionManager actionmanager.ActionManager `yaml:"action-manager"` 57 Converter dataconverter.Converter `yaml:"data-converter"` 58 } 59 60 //ReadConfigFile is the structure that is used to read the config file to get configuration information from the user 61 type ReadConfigFile struct { 62 Mqtt Mqtt `yaml:"mqtt"` 63 DeviceModelName string `yaml:"device-model-name"` 64 ActionManager ActionManagerConfig `yaml:"action-manager"` 65 Watcher watcher.Watcher `yaml:"watcher"` 66 Scheduler scheduler.Scheduler `yaml:"scheduler"` 67 } 68 69 //ActionManagerConfig is a structure that contains a list of actions 70 type ActionManagerConfig struct { 71 Actions []Action `yaml:"actions"` 72 } 73 74 //Action is structure to define a device action 75 type Action struct { 76 //PerformImmediately signifies whether the action is to be performed by the action-manager immediately or not 77 PerformImmediately bool `yaml:"perform-immediately" json:"perform-immediately"` 78 //Name is the name of the Action 79 Name string `yaml:"name" json:"name"` 80 //PropertyName is the name of the property defined in the device CRD 81 PropertyName string `yaml:"device-property-name" json:"device-property-name"` 82 } 83 84 //Mqtt structure contains the MQTT specific configurations 85 type Mqtt struct { 86 Mode int `yaml:"mode"` 87 InternalServer string `yaml:"internal-server"` 88 Server string `yaml:"server"` 89 } 90 91 //Device structure contains the device specific configurations 92 type Device struct { 93 ID string `yaml:"id"` 94 Name string `yaml:"name"` 95 } 96 97 //ReadFromConfigFile is used to load the information from the configuration file 98 func (readConfigFile *ReadConfigFile) ReadFromConfigFile() error { 99 yamlFile, err := ioutil.ReadFile(ConfigFilePath) 100 if err != nil { 101 return err 102 } 103 err = yaml.Unmarshal(yamlFile, readConfigFile) 104 if err != nil { 105 return err 106 } 107 return nil 108 } 109 110 //Load is used to consolidate the information loaded from the configuration file and the configmaps 111 func (b *BLEConfig) Load() error { 112 readConfigFile := ReadConfigFile{} 113 readConfigMap := DeviceProfile{} 114 err := readConfigFile.ReadFromConfigFile() 115 if err != nil { 116 return errors.New("Error while reading from configuration file " + err.Error()) 117 } 118 err = readConfigMap.ReadFromConfigMap() 119 if err != nil { 120 return errors.New("Error while reading from config map " + err.Error()) 121 } 122 b.Mqtt = readConfigFile.Mqtt 123 b.Scheduler = readConfigFile.Scheduler 124 b.Watcher = readConfigFile.Watcher 125 // Assign device information obtained from config file 126 for _, device := range readConfigMap.DeviceInstances { 127 if strings.EqualFold(device.Model, readConfigFile.DeviceModelName) { 128 b.Device.ID = device.ID 129 b.Device.Name = device.Model 130 } 131 } 132 // Assign information required by action manager 133 for _, actionConfig := range readConfigFile.ActionManager.Actions { 134 action := actionmanager.Action{} 135 action.Name = actionConfig.Name 136 action.PerformImmediately = actionConfig.PerformImmediately 137 138 for _, propertyVisitor := range readConfigMap.PropertyVisitors { 139 if strings.EqualFold(propertyVisitor.ModelName, b.Device.Name) && strings.EqualFold(propertyVisitor.PropertyName, actionConfig.PropertyName) && strings.ToUpper(propertyVisitor.Protocol) == ProtocolName { 140 propertyVisitorBytes, err := json.Marshal(propertyVisitor.VisitorConfig) 141 if err != nil { 142 return errors.New("Error in marshalling data property visitor configuration: " + err.Error()) 143 } 144 bluetoothPropertyVisitor := VisitorConfigBluetooth{} 145 err = json.Unmarshal(propertyVisitorBytes, &bluetoothPropertyVisitor) 146 if err != nil { 147 return errors.New("Error in unmarshalling data property visitor configuration: " + err.Error()) 148 } 149 action.Operation.CharacteristicUUID = bluetoothPropertyVisitor.CharacteristicUUID 150 newBluetoothVisitorConfig := VisitorConfigBluetooth{} 151 if !reflect.DeepEqual(bluetoothPropertyVisitor.BluetoothDataConverter, newBluetoothVisitorConfig.BluetoothDataConverter) { 152 readAction := dataconverter.ReadAction{} 153 readAction.ActionName = actionConfig.Name 154 readAction.ConversionOperation.StartIndex = bluetoothPropertyVisitor.BluetoothDataConverter.StartIndex 155 readAction.ConversionOperation.EndIndex = bluetoothPropertyVisitor.BluetoothDataConverter.EndIndex 156 readAction.ConversionOperation.ShiftRight = bluetoothPropertyVisitor.BluetoothDataConverter.ShiftRight 157 readAction.ConversionOperation.ShiftLeft = bluetoothPropertyVisitor.BluetoothDataConverter.ShiftLeft 158 for _, readOperations := range bluetoothPropertyVisitor.BluetoothDataConverter.OrderOfOperations { 159 readAction.ConversionOperation.OrderOfExecution = append(readAction.ConversionOperation.OrderOfExecution, readOperations.BluetoothOperationType) 160 switch strings.ToUpper(readOperations.BluetoothOperationType) { 161 case strings.ToUpper(BluetoothAdd): 162 readAction.ConversionOperation.Add = readOperations.BluetoothOperationValue 163 case strings.ToUpper(BluetoothSubtract): 164 readAction.ConversionOperation.Subtract = readOperations.BluetoothOperationValue 165 case strings.ToUpper(BluetoothMultiply): 166 readAction.ConversionOperation.Multiply = readOperations.BluetoothOperationValue 167 case strings.ToUpper(BluetoothDivide): 168 readAction.ConversionOperation.Divide = readOperations.BluetoothOperationValue 169 } 170 } 171 b.Converter.DataRead.Actions = append(b.Converter.DataRead.Actions, readAction) 172 } 173 if bluetoothPropertyVisitor.DataWriteToBluetooth != nil { 174 writeAttribute := dataconverter.WriteAttribute{} 175 writeAttribute.Operations = make(map[string]dataconverter.DataMap, 1) 176 dataMap := dataconverter.DataMap{} 177 dataMap.DataMapping = bluetoothPropertyVisitor.DataWriteToBluetooth 178 writeAttribute.Operations[actionConfig.Name] = dataMap 179 writeAttribute.Name = propertyVisitor.PropertyName 180 b.Converter.DataWrite.Attributes = append(b.Converter.DataWrite.Attributes, writeAttribute) 181 } 182 } 183 } 184 for _, deviceModel := range readConfigMap.DeviceModels { 185 if strings.EqualFold(deviceModel.Name, b.Device.Name) { 186 for _, property := range deviceModel.Properties { 187 if strings.EqualFold(property.Name, actionConfig.PropertyName) { 188 if property.AccessMode == READWRITE { 189 action.Operation.Action = "Write" 190 if strings.ToUpper(property.DataType) == "INT" { 191 value := string(int(property.DefaultValue.(float64))) 192 action.Operation.Value = []byte(value) 193 } else if strings.ToUpper(property.DataType) == "STRING" { 194 for _, converterAttribute := range b.Converter.DataWrite.Attributes { 195 if strings.EqualFold(converterAttribute.Name, actionConfig.PropertyName) { 196 for operationName, dataMap := range converterAttribute.Operations { 197 if action.Name == operationName { 198 if _, ok := dataMap.DataMapping[property.DefaultValue.(string)]; ok { 199 action.Operation.Value = dataMap.DataMapping[property.DefaultValue.(string)] 200 } 201 } 202 } 203 } 204 } 205 } 206 } else if property.AccessMode == READ { 207 action.Operation.Action = "Read" 208 } 209 } 210 } 211 } 212 } 213 b.ActionManager.Actions = append(b.ActionManager.Actions, action) 214 } 215 Config = b 216 return nil 217 }