SHOW:
|
|
- or go back to the newest paste.
| 1 | # Broadlink RM2 Python Plugin for Domoticz | |
| 2 | # | |
| 3 | # Dev. Platform : Win10 x64 & Py 3.5.3 x86 | |
| 4 | # | |
| 5 | - | # Author: zak45, 2017 |
| 5 | + | # Author: zak45, 2017-2018 |
| 6 | # 1.1.0: code compatible py 3.x | |
| 7 | - | # Send learned command stored in ini file |
| 7 | + | # 2.0.0: import from e-Control or any other ini file with similar structure |
| 8 | - | # One param required: ini file full path name |
| 8 | + | # webserver for file transfer |
| 9 | - | # Can be used stand alone |
| 9 | + | # Off action managed for generated devices |
| 10 | # clean action to erase files from import folder | |
| 11 | # 3.0.0: Add Remote Control device with custom codes on ini file | |
| 12 | # Broadlink lib to v 0.5.0: timeout error solved, Pad the payload for AES encryption (16) (TC2 switch), Add support for pure python AES implementation ... | |
| 13 | # 4.0.0: Add eSensor / Smart plug / Multi plug devices | |
| 14 | # --> big thanks to deennoo to have provided test devices : http://domo-attitude.fr | |
| 15 | # support for chinese char thanks to : https://zhougy0717.github.io/2017/07/31/Smart%20Home%20with%20Domoticz%20+%20BroadLink%20+%20Synology%20+%20Amazon%20Echo/ | |
| 16 | # Change the way to retreive module by using 'site', no more 'copy' should be necessary specially for linux systems | |
| 17 | # Broadlink lib to v 0.6.0 | |
| 18 | # socket.setdefaulttimeout put on comment as plugin framework is on trouble on onheartbeat(): even with other plugins. | |
| 19 | # | |
| 20 | ||
| 21 | - | brohost = "" |
| 21 | + | # Below is what will be displayed in Domoticz GUI under HW |
| 22 | - | bromac = "" |
| 22 | + | |
| 23 | """ | |
| 24 | <plugin key="BroadlinkRM2" name="Broadlink RM2 with Kodi Remote" author="zak45" version="4.0.0" wikilink="http://www.domoticz.com/wiki/plugins/BroadlinkRM2.html" externallink="https://github.com/mjg59/python-broadlink"> | |
| 25 | <params> | |
| 26 | <param field="Address" label="IP Address" width="200px" required="true" default="127.0.0.1"/> | |
| 27 | <param field="Mode1" label="Mac" width="100px" required="true" default="000000000000"/> | |
| 28 | <param field="Mode3" label="Device Type" width="250px" required="true" default="DIS"> | |
| 29 | <options> | |
| 30 | - | print('Nothing to send')
|
| 30 | + | <option label= "Discovery" value="DIS"/> |
| 31 | - | sys.exit(3) |
| 31 | + | <option label= "Remote Control RM2/RM mini3" value="RM2"/> |
| 32 | <option label= "Remote Control RM2/RM mini3 with Temperature device" value="RM2T"/> | |
| 33 | <option label= "eSensor multi sensors A1" value="A1"/> | |
| 34 | <option label= "SmartPlug 1" value="SP1"/> | |
| 35 | <option label= "SmartPlug 2/3" value="SP2"/> | |
| 36 | <option label= "SmartPlug 3S" value="SP3S"/> | |
| 37 | - | print( "Code Sent....") |
| 37 | + | <option label= "MultiPlug 1" value="MP1"/> |
| 38 | </options> | |
| 39 | </param> | |
| 40 | <param field="Mode2" label="Folder to store ini files (RM2/RM mini3)" width="300px" required="true" default="C:/BroadlinkRM2"/> | |
| 41 | <param field="Mode4" label="Generate import Device (RM2/RM mini3)" width="75px"> | |
| 42 | <options> | |
| 43 | <option label= "False" value="no"/> | |
| 44 | <option label= "True" value="yes" default="True"/> | |
| 45 | </options> | |
| 46 | </param> | |
| 47 | - | global device, brohost, bromac |
| 47 | + | <param field="Mode5" label="Port for HTTP server (RM2/RM mini3)" width="50px" required="true" default="9000"/> |
| 48 | <param field="Mode6" label="Debug" width="75px"> | |
| 49 | <options> | |
| 50 | - | device = broadlink.rm(host=(brohost,80), mac=bytearray.fromhex(bromac), devtype=0x279d) |
| 50 | + | <option label="True" value="Debug"/> |
| 51 | <option label="False" value="Normal" default="True" /> | |
| 52 | </options> | |
| 53 | - | print( "Connected to Broadlink device.") |
| 53 | + | </param> |
| 54 | </params> | |
| 55 | - | print( "Error Connecting to Broadlink device....") |
| 55 | + | </plugin> |
| 56 | - | sys.exit(2) |
| 56 | + | """ |
| 57 | # | |
| 58 | # Main Import | |
| 59 | import Domoticz | |
| 60 | - | path=sys.argv[1] |
| 60 | + | |
| 61 | import datetime | |
| 62 | - | if not os.path.exists(path): |
| 62 | + | import time |
| 63 | - | print(' ini file not found: ' + path)
|
| 63 | + | import codecs |
| 64 | - | sys.exit(1) |
| 64 | + | import subprocess |
| 65 | import socket | |
| 66 | - | config = configparser.ConfigParser() |
| 66 | + | |
| 67 | - | config.read(path) |
| 67 | + | |
| 68 | - | Unit=config.get("DEFAULT", "Unit")
|
| 68 | + | # Required for import: path is OS dependent |
| 69 | - | brohost=config.get("Device", "host")
|
| 69 | + | # Python framework in Domoticz do not include OS dependent path |
| 70 | - | bromac=config.get("Device", "mac")
|
| 70 | + | |
| 71 | - | sendCommand = config.get("LearnedCode", Unit)
|
| 71 | + | import site |
| 72 | - | broadlinkConnect() |
| 72 | + | |
| 73 | - | send() |
| 73 | + | |
| 74 | path='' | |
| 75 | path=site.getsitepackages() | |
| 76 | for i in path: | |
| 77 | sys.path.append(i) | |
| 78 | # | |
| 79 | import broadlink | |
| 80 | # | |
| 81 | isConnected = False | |
| 82 | numberDev = 2 | |
| 83 | bypass = False | |
| 84 | temp = 0 | |
| 85 | learnedCommand = "None" | |
| 86 | sendCommand = "" | |
| 87 | loadedCommand = "" | |
| 88 | nbUpdate = 1 | |
| 89 | isRunning = False | |
| 90 | custom = "" | |
| 91 | clear = False | |
| 92 | RemoteCommand = "" | |
| 93 | state = True | |
| 94 | statemp1 = {}
| |
| 95 | energy = 0 | |
| 96 | ||
| 97 | # Domoticz call back functions | |
| 98 | # | |
| 99 | ||
| 100 | # Executed once at HW creation/ update. Can create up to 255 devices. | |
| 101 | def onStart(): | |
| 102 | global numberDev, nbUpdate | |
| 103 | ||
| 104 | if Parameters["Mode6"] == "Debug": | |
| 105 | Domoticz.Debugging(1) | |
| 106 | ||
| 107 | if (Parameters["Mode3"] == 'DIS'): | |
| 108 | if ( 1 not in Devices): | |
| 109 | Domoticz.Device(Name="Discovery", Unit=1, Type=17, Image=2, Switchtype=17, Used=1).Create() | |
| 110 | if ( 2 not in Devices): | |
| 111 | Domoticz.Device(Name="Discovery Info", Unit=2, TypeName="Text", Used=1).Create() | |
| 112 | ||
| 113 | elif (Parameters["Mode3"] == 'RM2T' or Parameters["Mode3"] == 'RM2'): | |
| 114 | if ( 1 not in Devices ): | |
| 115 | Options = { "LevelActions" :"||||" ,
| |
| 116 | "LevelNames" :"Off|Learn|Test|Save|Reset" , | |
| 117 | "LevelOffHidden":"true", | |
| 118 | "SelectorStyle" :"0" | |
| 119 | } | |
| 120 | Domoticz.Device(Name="Command", Unit=1, TypeName="Selector Switch", Switchtype=18, Image=12, Options=Options, Used=1).Create() | |
| 121 | ||
| 122 | if ( 2 not in Devices and Parameters["Mode3"] == 'RM2T'): | |
| 123 | Domoticz.Device(Name="Temp", Unit=2, TypeName="Temperature", Used=1).Create() | |
| 124 | ||
| 125 | if ( 254 not in Devices ): | |
| 126 | Domoticz.Device(Name="Remote", Unit=254, Type=17, Image=2, Switchtype=17, Used=1).Create() | |
| 127 | ||
| 128 | if ( 255 not in Devices and Parameters["Mode4"] == 'yes' ): | |
| 129 | Options = { "LevelActions" :"||||" ,
| |
| 130 | "LevelNames" :"Off|WebStart|Generate|Import|Clear" , | |
| 131 | "LevelOffHidden":"true", | |
| 132 | "SelectorStyle" :"0" | |
| 133 | } | |
| 134 | Domoticz.Device(Name="Import", Unit=255, TypeName="Selector Switch", Switchtype=18, Image=12, Options=Options, Used=1).Create() | |
| 135 | ||
| 136 | elif (Parameters["Mode3"] == 'SP1' or Parameters["Mode3"] == 'SP2' or Parameters["Mode3"] == 'SP3S'): | |
| 137 | if ( 1 not in Devices ): | |
| 138 | Domoticz.Device(Name=str(Parameters["Mode3"]), Unit=1,TypeName="Switch", Image=1, Used=1).Create() | |
| 139 | if Parameters["Mode3"] == 'SP3S': | |
| 140 | if ( 2 not in Devices ): | |
| 141 | Domoticz.Device(Name=str(Parameters["Mode3"]), Unit=2,TypeName="Usage", Used=1).Create() | |
| 142 | if ( 3 not in Devices ): | |
| 143 | Domoticz.Device(Name=str(Parameters["Mode3"]), Unit=3,TypeName="kWh", Used=1).Create() | |
| 144 | ||
| 145 | elif (Parameters["Mode3"] == 'A1'): | |
| 146 | if ( 1 not in Devices ): | |
| 147 | Domoticz.Device(Name=str(Parameters["Mode3"]) + ' - Status', Unit=1,Type=17, Image=17, Switchtype=17, Used=1).Create() | |
| 148 | if ( 2 not in Devices ): | |
| 149 | Domoticz.Device(Name=str(Parameters["Mode3"]) + ' - Temperature', Unit=2,TypeName="Temperature", Used=1).Create() | |
| 150 | if ( 3 not in Devices ): | |
| 151 | Domoticz.Device(Name=str(Parameters["Mode3"]) + ' - Humidity', Unit=3,TypeName="Humidity", Used=1).Create() | |
| 152 | if ( 4 not in Devices ): | |
| 153 | Domoticz.Device(Name=str(Parameters["Mode3"]) + ' - Air Quality', Unit=4,TypeName="Air Quality", Used=1).Create() | |
| 154 | if ( 5 not in Devices ): | |
| 155 | Domoticz.Device(Name=str(Parameters["Mode3"]) + ' - Noise', Unit=5,TypeName="Sound Level", Used=1).Create() | |
| 156 | if ( 6 not in Devices ): | |
| 157 | Domoticz.Device(Name=str(Parameters["Mode3"]) + ' - Light', Unit=6,TypeName="Illumination", Used=1).Create() | |
| 158 | ||
| 159 | elif (Parameters["Mode3"] == 'MP1'): | |
| 160 | if ( 1 not in Devices ): | |
| 161 | Domoticz.Device(Name=str(Parameters["Mode3"]) + ' - Status', Unit=1,TypeName="Switch",Image=9, Used=1).Create() | |
| 162 | if ( 2 not in Devices ): | |
| 163 | Domoticz.Device(Name=str(Parameters["Mode3"]) + ' - plug1', Unit=2,TypeName="Switch",Image=1, Used=1).Create() | |
| 164 | if ( 3 not in Devices ): | |
| 165 | Domoticz.Device(Name=str(Parameters["Mode3"]) + ' - plug2', Unit=3,TypeName="Switch",Image=1, Used=1).Create() | |
| 166 | if ( 4 not in Devices ): | |
| 167 | Domoticz.Device(Name=str(Parameters["Mode3"]) + ' - plug3', Unit=4,TypeName="Switch",Image=1, Used=1).Create() | |
| 168 | if ( 5 not in Devices ): | |
| 169 | Domoticz.Device(Name=str(Parameters["Mode3"]) + ' - plug4', Unit=5,TypeName="Switch",Image=1, Used=1).Create() | |
| 170 | ||
| 171 | ||
| 172 | DumpConfigToLog() | |
| 173 | Domoticz.Heartbeat(30) | |
| 174 | ||
| 175 | numberDev = len(Devices) - 1 | |
| 176 | if (255 in Devices): | |
| 177 | UpdateDevice(255, 0, 'Off') | |
| 178 | numberDev = numberDev - 1 | |
| 179 | ||
| 180 | Domoticz.Log("Connecting to: "+Parameters["Address"]+":"+Parameters["Mode1"])
| |
| 181 | ||
| 182 | if Parameters["Mode3"] == 'RM2' or Parameters["Mode3"] == 'RM2T' or Parameters["Mode3"] == 'A1': | |
| 183 | if not broadlinkConnect(): | |
| 184 | UpdateDevice(1, 0, 'Off') | |
| 185 | else: | |
| 186 | UpdateDevice(1, 1, '10') | |
| 187 | elif Parameters["Mode3"] != 'DIS': | |
| 188 | if checkPower(): | |
| 189 | if state: | |
| 190 | UpdateDevice(1, 1, 'On') | |
| 191 | # if (Parameters["Mode3"] == 'MP1'): | |
| 192 | # AllPlugOn() | |
| 193 | else: | |
| 194 | UpdateDevice(1, 0, 'Off') | |
| 195 | # if (Parameters["Mode3"] == 'MP1'): | |
| 196 | # AllPlugOff() | |
| 197 | else: | |
| 198 | UpdateDevice(1, 0, 'Off') | |
| 199 | # if (Parameters["Mode3"] == 'MP1'): | |
| 200 | # AllPlugOff() | |
| 201 | ||
| 202 | if Parameters["Mode3"] == 'RM2' or Parameters["Mode3"] == 'RM2T': | |
| 203 | if not os.path.exists(Parameters["Mode2"] + "/import"): | |
| 204 | os.makedirs(Parameters["Mode2"] + "/import") | |
| 205 | if not os.path.exists(Parameters["Mode2"] + "/remote"): | |
| 206 | os.makedirs(Parameters["Mode2"] + "/remote") | |
| 207 | ||
| 208 | genRemote() | |
| 209 | ||
| 210 | Domoticz.Log("Device Number begin to : "+ str(numberDev))
| |
| 211 | ||
| 212 | return True | |
| 213 | ||
| 214 | # executed each time we click on device thru domoticz GUI | |
| 215 | def onCommand(Unit, Command, Level, Hue): | |
| 216 | global sendCommand, isRunning, learnedCommand, isConnected | |
| 217 | ||
| 218 | Domoticz.Log("onCommand called for Unit " + str(Unit) + ": Parameter '" + str(Command) + "', Level: " + str(Level) + " , Connected : " + str(isConnected))
| |
| 219 | ||
| 220 | Command = Command.strip() | |
| 221 | ||
| 222 | if (Command == 'Set Level'): | |
| 223 | if (Parameters["Mode3"] == 'RM2T' or Parameters["Mode3"] == 'RM2'): | |
| 224 | if (Unit == 1): # Command selector | |
| 225 | if (Level == 10): | |
| 226 | learn() | |
| 227 | if (Level == 20): | |
| 228 | sendCommand = learnedCommand | |
| 229 | if learnedCommand == "None": | |
| 230 | Domoticz.Log('Nothing to send')
| |
| 231 | else: | |
| 232 | send() | |
| 233 | if (Level == 30): | |
| 234 | if learnedCommand == "None": | |
| 235 | Domoticz.Log('Nothing to save')
| |
| 236 | else: | |
| 237 | custom = "" | |
| 238 | if save(): | |
| 239 | UpdateDevice(1,1,'10') | |
| 240 | learnedCommand = "None" | |
| 241 | if (Level == 40): | |
| 242 | if learnedCommand == "None": | |
| 243 | Domoticz.Log('Nothing to reset')
| |
| 244 | else: | |
| 245 | reset() | |
| 246 | elif (Unit == 255): | |
| 247 | if (Level == 10): | |
| 248 | if startWeb(): | |
| 249 | isRunning = True | |
| 250 | UpdateDevice(255,1,'10') | |
| 251 | else: | |
| 252 | UpdateDevice(255,0,'Off') | |
| 253 | Domoticz.Error ('Not able to start Web server')
| |
| 254 | if (Level == 20): | |
| 255 | if createIniImport(): | |
| 256 | UpdateDevice(255,1,'20') | |
| 257 | else: | |
| 258 | UpdateDevice(255,0,'Off') | |
| 259 | Domoticz.Error ('Error with json files to import')
| |
| 260 | if (Level == 30): | |
| 261 | clear = False | |
| 262 | if manageIniImport(clear): | |
| 263 | UpdateDevice(255,1,'30') | |
| 264 | else: | |
| 265 | UpdateDevice(255,0,'Off') | |
| 266 | if (Level == 40): | |
| 267 | clear = True | |
| 268 | if manageIniImport(clear): | |
| 269 | UpdateDevice(255,1,'40') | |
| 270 | else: | |
| 271 | UpdateDevice(255,0,'Off') | |
| 272 | else: | |
| 273 | Domoticz.Error('Unit unknown')
| |
| 274 | ||
| 275 | elif (Command == 'On'): | |
| 276 | ||
| 277 | if (Unit == 1 and Parameters['Mode3'] == 'DIS'): # Discovery | |
| 278 | if Discover(): | |
| 279 | UpdateDevice(Unit, 1, 'Found : ' + str(len(brodevices )) + ' device(s)') | |
| 280 | else: | |
| 281 | Domoticz.Error('Not able to find Broadlink device')
| |
| 282 | elif (Unit==254 and RemoteCommand != "" ): | |
| 283 | UpdateDevice(Unit, 1, 'On') | |
| 284 | elif ( Unit==1 and (Parameters['Mode3'] == 'SP1' or Parameters['Mode3'] == 'SP2' or Parameters['Mode3'] == 'SP3S')): | |
| 285 | try: | |
| 286 | device.set_power(True) | |
| 287 | UpdateDevice(Unit,1,'On') | |
| 288 | except: | |
| 289 | Domoticz.Error(' error to put ON SP1/SP2/SP3 ')
| |
| 290 | isConnected = False | |
| 291 | elif (Parameters['Mode3'] == 'MP1'): | |
| 292 | if ( Unit > 1 and Unit < 6): | |
| 293 | try: | |
| 294 | device.set_power(Unit - 1, True) | |
| 295 | UpdateDevice(Unit,1,'On') | |
| 296 | except: | |
| 297 | Domoticz.Error(' Error to put ON MP1 for plug : ' + str(Unit -1))
| |
| 298 | else: | |
| 299 | if (Parameters["Mode3"] == 'RM2T' or Parameters["Mode3"] == 'RM2'): | |
| 300 | genCommand(Unit) | |
| 301 | else: | |
| 302 | Domoticz.Error('Unknown command')
| |
| 303 | ||
| 304 | elif (Command == 'Off'): | |
| 305 | ||
| 306 | if (Unit == 1 and Parameters['Mode3'] == 'DIS'): # Discovery | |
| 307 | UpdateDevice(Unit, 0, 'Off') | |
| 308 | elif ( Unit==1 and (Parameters['Mode3'] == 'SP1' or Parameters['Mode3'] == 'SP2' or Parameters['Mode3'] == 'SP3S')): | |
| 309 | try: | |
| 310 | device.set_power(False) | |
| 311 | UpdateDevice(Unit,0,'Off') | |
| 312 | except: | |
| 313 | Domoticz.Error(' error to put Off SP1/SP2/SP3 ')
| |
| 314 | isConnected = False | |
| 315 | elif (Parameters['Mode3'] == 'MP1'): | |
| 316 | if ( Unit > 1 and Unit < 6): | |
| 317 | try: | |
| 318 | device.set_power(Unit - 1, False) | |
| 319 | UpdateDevice(Unit,0,'Off') | |
| 320 | except: | |
| 321 | Domoticz.Error(' Error to put Off MP1 for plug : ' + str(Unit -1))
| |
| 322 | else: | |
| 323 | try: | |
| 324 | UpdateDevice(Unit, 0, 'Off') | |
| 325 | except: | |
| 326 | Domoticz.Error('Unit error update')
| |
| 327 | raise | |
| 328 | elif ( Unit == 254): | |
| 329 | if remoteSend(Command): | |
| 330 | UpdateDevice(Unit, 1, Command) | |
| 331 | else: | |
| 332 | UpdateDevice(Unit, 1, 'undefined') | |
| 333 | ||
| 334 | else: | |
| 335 | Domoticz.Error('Unknown command')
| |
| 336 | ||
| 337 | return True | |
| 338 | ||
| 339 | # execution depend of Domoticz.Heartbeat(x) x in seconds | |
| 340 | def onHeartbeat(): | |
| 341 | global bypass, isConnected, isRunning, state | |
| 342 | ||
| 343 | now = datetime.datetime.now() | |
| 344 | ||
| 345 | if (255 in Devices and isRunning == True): | |
| 346 | isAlive() | |
| 347 | ||
| 348 | if bypass is True: | |
| 349 | bypass = False | |
| 350 | return | |
| 351 | # for RM2T type we check temp every 2 minutes | |
| 352 | if Parameters["Mode3"] == 'RM2T': | |
| 353 | if ((now.minute % 2) == 0): | |
| 354 | bypass = True | |
| 355 | if isConnected: | |
| 356 | if checkTemp(): | |
| 357 | UpdateDevice(2, 1, temp) | |
| 358 | UpdateDevice(1,1,'10') | |
| 359 | else: | |
| 360 | isConnected = False | |
| 361 | UpdateDevice(1,0,'Off') | |
| 362 | else: | |
| 363 | broadlinkConnect() | |
| 364 | # for A1 we get sensor data every 30 seconds | |
| 365 | elif Parameters["Mode3"] == 'A1': | |
| 366 | if Parameters["Mode6"] == "Debug": | |
| 367 | Domoticz.Log(" A1 called")
| |
| 368 | if ((now.minute % 1) == 0): | |
| 369 | bypass = False | |
| 370 | if isConnected: | |
| 371 | if checkSensor(): | |
| 372 | UpdateDevice(1, 1, 'Get Data From Sensors') | |
| 373 | else: | |
| 374 | isConnected = False | |
| 375 | else: | |
| 376 | broadlinkConnect() | |
| 377 | # for SP3S we get energy/status data every 30 seconds | |
| 378 | elif Parameters["Mode3"] == 'SP3S': | |
| 379 | if Parameters["Mode6"] == "Debug": | |
| 380 | Domoticz.Log(" SP3S called")
| |
| 381 | if ((now.minute % 1) == 0): | |
| 382 | bypass = False | |
| 383 | if isConnected: | |
| 384 | if getEnergy(): | |
| 385 | UpdateDevice(2, 0, str(energy)) | |
| 386 | UpdateDevice(3, 0, str(energy)) | |
| 387 | else: | |
| 388 | isConnected = False | |
| 389 | if checkPower(): | |
| 390 | if state: | |
| 391 | UpdateDevice(1, 1, 'On') | |
| 392 | else: | |
| 393 | UpdateDevice(1, 0, 'Off') | |
| 394 | else: | |
| 395 | isConnected = False | |
| 396 | else: | |
| 397 | broadlinkConnect() | |
| 398 | # for MP1 we check status every 1 minute | |
| 399 | # elif Parameters["Mode3"] == 'MP1': | |
| 400 | # if Parameters["Mode6"] == "Debug": | |
| 401 | # Domoticz.Log("MP1 called")
| |
| 402 | # if ((now.minute % 1) == 0): | |
| 403 | # bypass = True | |
| 404 | # if isConnected: | |
| 405 | # if checkPower(): | |
| 406 | # if statemp1: | |
| 407 | # UpdateDevice(1, 1, 'On') | |
| 408 | # AllPlugOn() | |
| 409 | # else: | |
| 410 | # UpdateDevice(1, 0, 'Off') | |
| 411 | # AllPlugOff() | |
| 412 | # else: | |
| 413 | # isConnected = False | |
| 414 | # else: | |
| 415 | # broadlinkConnect() | |
| 416 | # for SP1/2 we check status every 1 minute | |
| 417 | elif Parameters["Mode3"] == 'SP1' or Parameters["Mode3"] == 'SP2': | |
| 418 | if Parameters["Mode6"] == "Debug": | |
| 419 | Domoticz.Log("SP1/SP2 called")
| |
| 420 | if ((now.minute % 1) == 0): | |
| 421 | bypass = True | |
| 422 | if isConnected: | |
| 423 | if checkPower(): | |
| 424 | if state: | |
| 425 | UpdateDevice(1, 1, 'On') | |
| 426 | else: | |
| 427 | UpdateDevice(1, 0, 'Off') | |
| 428 | else: | |
| 429 | isConnected = False | |
| 430 | else: | |
| 431 | broadlinkConnect() | |
| 432 | # for DIS we do nothing | |
| 433 | elif Parameters["Mode3"] == 'DIS': | |
| 434 | return | |
| 435 | # for RM2 we try to connect every 5 minutes if checkTemp is False | |
| 436 | else: | |
| 437 | if (now.minute % 5 == 0): | |
| 438 | if not checkTemp(): | |
| 439 | UpdateDevice(1,0,'Off') | |
| 440 | if broadlinkConnect(): | |
| 441 | UpdateDevice(1,1,'10') | |
| 442 | bypass = True | |
| 443 | ||
| 444 | return True | |
| 445 | ||
| 446 | # executed once when HW updated/removed | |
| 447 | def onStop(): | |
| 448 | Domoticz.Log("onStop called")
| |
| 449 | return True | |
| 450 | ||
| 451 | # Generic helper functions | |
| 452 | def DumpConfigToLog(): | |
| 453 | for x in Parameters: | |
| 454 | if Parameters[x] != "": | |
| 455 | Domoticz.Debug( "'" + x + "':'" + str(Parameters[x]) + "'") | |
| 456 | Domoticz.Debug("Device count: " + str(len(Devices)))
| |
| 457 | for x in Devices: | |
| 458 | Domoticz.Debug("Device: " + str(x) + " - " + str(Devices[x]))
| |
| 459 | Domoticz.Debug("Device ID: '" + str(Devices[x].ID) + "'")
| |
| 460 | Domoticz.Debug("Device Name: '" + Devices[x].Name + "'")
| |
| 461 | Domoticz.Debug("Device nValue: " + str(Devices[x].nValue))
| |
| 462 | Domoticz.Debug("Device sValue: '" + Devices[x].sValue + "'")
| |
| 463 | Domoticz.Debug("Device LastLevel: " + str(Devices[x].LastLevel))
| |
| 464 | return | |
| 465 | ||
| 466 | # Update Device into DB | |
| 467 | def UpdateDevice(Unit, nValue, sValue): | |
| 468 | # Make sure that the Domoticz device still exists (they can be deleted) before updating it | |
| 469 | if (Unit in Devices): | |
| 470 | if Unit == 1: | |
| 471 | if (Devices[Unit].nValue != nValue) or (Devices[Unit].sValue != sValue): | |
| 472 | Devices[Unit].Update(nValue=nValue, sValue=str(sValue)) | |
| 473 | Domoticz.Log("Update "+str(nValue)+":'"+str(sValue)+"' ("+Devices[Unit].Name+")")
| |
| 474 | else: | |
| 475 | Devices[Unit].Update(nValue=nValue, sValue=str(sValue)) | |
| 476 | Domoticz.Log("Update "+str(nValue)+":'"+str(sValue)+"' ("+Devices[Unit].Name+")")
| |
| 477 | return | |
| 478 | ||
| 479 | # generate command to execute and update name in ini file if necessary | |
| 480 | def genCommand(Unit): | |
| 481 | global loadedCommand, sendCommand, nbUpdate | |
| 482 | ||
| 483 | Domoticz.Log('Generate on Command for learned code stored on unit/ini :' + str(Unit))
| |
| 484 | ||
| 485 | path=str(Parameters["Mode2"]) + "/" + str(Parameters["Key"]) + "-" + str(Parameters["HardwareID"]) + "-" + str(Unit) + ".ini" | |
| 486 | ||
| 487 | if not os.path.exists(path): | |
| 488 | Domoticz.Error(' ini file not found: ' + str(path))
| |
| 489 | return | |
| 490 | ||
| 491 | config = configparser.ConfigParser() | |
| 492 | config.read(path,encoding='utf8') | |
| 493 | loadedCommand = config.get("LearnedCode", str(Unit))
| |
| 494 | if Parameters["Mode6"] == "Debug": | |
| 495 | Domoticz.Log(" Code loaded : " + loadedCommand)
| |
| 496 | sendCommand = loadedCommand | |
| 497 | if isConnected: | |
| 498 | send() | |
| 499 | if Parameters["Mode6"] == "Debug": | |
| 500 | Domoticz.Log(' <b> Command line : ' + '"' + Parameters['HomeFolder'] + 'plugin_send.py' + '" ' + path + ' </b>')
| |
| 501 | ||
| 502 | if Unit in Devices: | |
| 503 | try: | |
| 504 | UpdateDevice(Unit,1,'On-'+str(nbUpdate)) | |
| 505 | nbUpdate +=1 | |
| 506 | except: | |
| 507 | Domoticz.Error("Not able to update device : " + str(Unit))
| |
| 508 | ||
| 509 | try: | |
| 510 | if not (Devices[Unit].Name == config.get("DEFAULT","customname")):
| |
| 511 | ||
| 512 | config.set('DEFAULT','customname',Devices[Unit].Name)
| |
| 513 | ||
| 514 | try: | |
| 515 | with open(path, 'w') as configfile: | |
| 516 | config.write(configfile) | |
| 517 | except IOError: | |
| 518 | Domoticz.Error('Error updating config file')
| |
| 519 | raise | |
| 520 | except: | |
| 521 | Domoticz.Error('Error updating config file, customname param missing')
| |
| 522 | raise | |
| 523 | ||
| 524 | return | |
| 525 | ||
| 526 | # save learned/imported code and create Domoticz device | |
| 527 | def save(): | |
| 528 | global path, learnedCommand, Unit, numberDev, custom | |
| 529 | ||
| 530 | numberDev +=1 | |
| 531 | path=str(Parameters["Mode2"]) + "/" + str(Parameters["Key"]) + "-" + str(Parameters["HardwareID"]) + "-" + str(numberDev) + ".ini" | |
| 532 | ||
| 533 | if os.path.exists(path): | |
| 534 | Domoticz.Error('File exist : ' + path)
| |
| 535 | return False | |
| 536 | else: | |
| 537 | try: | |
| 538 | create_config(path,str(numberDev),learnedCommand,custom) | |
| 539 | except: | |
| 540 | Domoticz.Error('Not able to create : ' + path)
| |
| 541 | return False | |
| 542 | try: | |
| 543 | Domoticz.Device(Name=str(Parameters["HardwareID"])+"-" + str(numberDev)+ " " + custom, Unit=numberDev, TypeName="Selector Switch", Type=244, Switchtype=9, Subtype=73).Create() | |
| 544 | except: | |
| 545 | Domoticz.Error('Not able to create device')
| |
| 546 | return False | |
| 547 | ||
| 548 | if Parameters["Mode6"] == "Debug": | |
| 549 | Domoticz.Log(' <b> Command line : ' + '"' + Parameters['HomeFolder'] + 'plugin_send.py' + '" ' + path + ' </b>')
| |
| 550 | ||
| 551 | return True | |
| 552 | ||
| 553 | def reset(): | |
| 554 | global learnedCommand | |
| 555 | ||
| 556 | UpdateDevice(1, 0, 'Off') | |
| 557 | learnedCommand = "None" | |
| 558 | if Parameters["Mode6"] == "Debug": | |
| 559 | Domoticz.Log("Reset learned command")
| |
| 560 | ||
| 561 | return True | |
| 562 | ||
| 563 | # discover Broadlink device on the Network | |
| 564 | def Discover(): | |
| 565 | global brodevices | |
| 566 | ||
| 567 | Domoticz.Log("All plugin system is on pause for 5s...")
| |
| 568 | brodevices = broadlink.discover(timeout=5) | |
| 569 | Domoticz.Log("Found " + str(len(brodevices )) + " broadlink devices")
| |
| 570 | ||
| 571 | if str(len(brodevices )) == 0: | |
| 572 | return False | |
| 573 | ||
| 574 | txtdevice = '' | |
| 575 | ||
| 576 | for index, item in enumerate(brodevices): | |
| 577 | ||
| 578 | brodevices[index].auth() | |
| 579 | ||
| 580 | broip = brodevices[index].host | |
| 581 | broip = str(broip) | |
| 582 | Domoticz.Log( "<b>Device " + str(index + 1) +" Host address = " + broip[1:19] + "</b>") | |
| 583 | txtdevice = txtdevice + "[Device " + str(index + 1) +" Host address = " + broip[1:19] + "]" | |
| 584 | macadd = ''.join(format(x, '02x') for x in brodevices[index].mac[::-1]) | |
| 585 | macadd = str(macadd) | |
| 586 | brotype = str(brodevices[index].type) | |
| 587 | Domoticz.Log( "<b>Device " + str(index + 1) +" MAC address = " + macadd + " Type: " + brotype + "</b>") | |
| 588 | txtdevice = txtdevice + "[Device " + str(index + 1) +" MAC address = " + macadd + " Type: " + brotype + "]" | |
| 589 | if len(txtdevice) > 200:txtdevice=txtdevice[0:197] + '...' | |
| 590 | ||
| 591 | UpdateDevice(2,1,txtdevice) | |
| 592 | ||
| 593 | return True | |
| 594 | ||
| 595 | # Put Broadlink on Learn , packet received converted to Hex | |
| 596 | def learn(): | |
| 597 | global learnedCommand | |
| 598 | ||
| 599 | if not isConnected: | |
| 600 | broadlinkConnect() | |
| 601 | ||
| 602 | Domoticz.Log("All plugin system is on pause for 5s...")
| |
| 603 | Domoticz.Log("When Broadlink led is lit press the button on your remote within 5 seconds")
| |
| 604 | ||
| 605 | try: | |
| 606 | device.enter_learning() | |
| 607 | except: | |
| 608 | Domoticz.Error ('Not able to learn command')
| |
| 609 | return False | |
| 610 | ||
| 611 | time.sleep(5) | |
| 612 | ||
| 613 | ir_packet = device.check_data() | |
| 614 | if Parameters["Mode6"] == "Debug": | |
| 615 | Domoticz.Log(str(ir_packet)) | |
| 616 | ||
| 617 | if str(ir_packet) == "None": | |
| 618 | Domoticz.Log('Command not received')
| |
| 619 | learnedCommand= "None" | |
| 620 | return False | |
| 621 | ||
| 622 | learnedCommand=(codecs.encode(ir_packet, 'hex_codec')).decode('utf-8')
| |
| 623 | if Parameters["Mode6"] == "Debug": | |
| 624 | Domoticz.Log(learnedCommand) | |
| 625 | ||
| 626 | Domoticz.Log( "Code stored in memory" ) | |
| 627 | UpdateDevice(1, 1, '20') | |
| 628 | ||
| 629 | return True | |
| 630 | ||
| 631 | # send Hex command | |
| 632 | def send(): | |
| 633 | global sendCommand | |
| 634 | ||
| 635 | if not sendCommand: | |
| 636 | Domoticz.Error('Nothing to send')
| |
| 637 | return False | |
| 638 | ||
| 639 | sendCommand = bytes.fromhex(sendCommand) | |
| 640 | if Parameters["Mode6"] == "Debug": | |
| 641 | Domoticz.Log(str(sendCommand)) | |
| 642 | ||
| 643 | try: | |
| 644 | device.send_data(sendCommand) | |
| 645 | Domoticz.Log( "Code Sent....") | |
| 646 | except: | |
| 647 | Domoticz.Error( "Code Sent WARNING....Probably timeout") | |
| 648 | return False | |
| 649 | ||
| 650 | return True | |
| 651 | ||
| 652 | #Create a config file | |
| 653 | def create_config(path,Unit,learnedCommand,custom): | |
| 654 | ||
| 655 | config = configparser.ConfigParser() | |
| 656 | config['DEFAULT'] = { 'PluginKey' : Parameters["Key"],
| |
| 657 | 'PluginName' : Parameters["Name"], | |
| 658 | 'PluginFolder' : Parameters["HomeFolder"], | |
| 659 | 'HardwareID' : Parameters["HardwareID"], | |
| 660 | 'Unit' : Unit, | |
| 661 | 'CustomName' : custom | |
| 662 | } | |
| 663 | ||
| 664 | config['Device'] = { 'Host' : Parameters["Address"],
| |
| 665 | 'Mac' : Parameters["Mode1"] | |
| 666 | } | |
| 667 | config['LearnedCode'] = {}
| |
| 668 | UniteCode = config['LearnedCode'] | |
| 669 | UniteCode[str(Unit)] = learnedCommand | |
| 670 | try: | |
| 671 | with open(path, 'w') as configfile: | |
| 672 | config.write(configfile) | |
| 673 | except IOError: | |
| 674 | Domoticz.Error('Error create config file')
| |
| 675 | raise | |
| 676 | ||
| 677 | if Parameters["Mode6"] == "Debug": | |
| 678 | Domoticz.Log( "ini file creation...." + path) | |
| 679 | ||
| 680 | return | |
| 681 | ||
| 682 | # connect to Broadlink | |
| 683 | def broadlinkConnect(): | |
| 684 | global device, isConnected | |
| 685 | ||
| 686 | try: | |
| 687 | if (Parameters["Mode3"] == 'RM2T' or Parameters["Mode3"] == 'RM2'): | |
| 688 | device = broadlink.rm(host=(Parameters["Address"],80), mac=bytearray.fromhex(Parameters["Mode1"]), devtype=0x279d) | |
| 689 | elif (Parameters["Mode3"] == 'A1'): | |
| 690 | device = broadlink.a1(host=(Parameters["Address"],80), mac=bytearray.fromhex(Parameters["Mode1"]), devtype=0x2714) | |
| 691 | elif (Parameters["Mode3"] == 'SP1'): | |
| 692 | device = broadlink.sp1(host=(Parameters["Address"],80), mac=bytearray.fromhex(Parameters["Mode1"]), devtype=0) | |
| 693 | elif (Parameters["Mode3"] == 'SP2' or Parameters["Mode3"] == 'SP3S'): | |
| 694 | device = broadlink.sp2(host=(Parameters["Address"],80), mac=bytearray.fromhex(Parameters["Mode1"]), devtype=0x2711) | |
| 695 | elif (Parameters["Mode3"] == 'MP1'): | |
| 696 | device = broadlink.mp1(host=(Parameters["Address"],80), mac=bytearray.fromhex(Parameters["Mode1"]), devtype=0x4EB5) | |
| 697 | else: | |
| 698 | device = 'unknown' | |
| 699 | device.auth() | |
| 700 | device.host | |
| 701 | isConnected = True | |
| 702 | Domoticz.Log( "Connected to Broadlink device: " + str(Parameters["Address"])) | |
| 703 | except: | |
| 704 | Domoticz.Error( "Error Connecting to Broadlink device...." + str(Parameters["Address"])) | |
| 705 | isConnected = False | |
| 706 | return False | |
| 707 | ||
| 708 | return True | |
| 709 | ||
| 710 | # get temperature for RM2T | |
| 711 | def checkTemp(): | |
| 712 | global temp | |
| 713 | ||
| 714 | try: | |
| 715 | temp=device.check_temperature() | |
| 716 | except: | |
| 717 | Domoticz.Error( "Error getting temperature data from Broadlink device....Timeout") | |
| 718 | return False | |
| 719 | ||
| 720 | if temp > 60: | |
| 721 | return False | |
| 722 | ||
| 723 | return True | |
| 724 | ||
| 725 | # Start Web server for Transfert for RM2/RM2T | |
| 726 | def startWeb(): | |
| 727 | ||
| 728 | if sys.platform.startswith('linux'):
| |
| 729 | # linux specific code here | |
| 730 | cmdFile = Parameters["HomeFolder"] + 'plugin_http.sh' | |
| 731 | elif sys.platform.startswith('darwin'):
| |
| 732 | # mac | |
| 733 | cmdFile = Parameters["HomeFolder"] + 'plugin_http.sh' | |
| 734 | elif sys.platform.startswith('win32'):
| |
| 735 | # win specific | |
| 736 | cmdFile = '"' + Parameters["HomeFolder"] + 'plugin_http.cmd' + '"' | |
| 737 | ||
| 738 | commandtoexecute = cmdFile + " 0.0.0.0 " + Parameters["Mode5"] + " " + Parameters["Mode2"] | |
| 739 | ||
| 740 | try: | |
| 741 | subprocess.check_call(commandtoexecute, shell=True, timeout=2) | |
| 742 | except subprocess.CalledProcessError as e: | |
| 743 | Domoticz.Error(str(e.returncode)) | |
| 744 | Domoticz.Error(str(e.cmd)) | |
| 745 | Domoticz.Error(str(e.output)) | |
| 746 | return False | |
| 747 | ||
| 748 | if Parameters["Mode6"] == "Debug": | |
| 749 | Domoticz.Log("Subprocess " + commandtoexecute + " launched...")
| |
| 750 | ||
| 751 | return True | |
| 752 | ||
| 753 | # check Webserver is running, if not put device Off | |
| 754 | def isAlive(): | |
| 755 | global isRunning | |
| 756 | ||
| 757 | socket.setdefaulttimeout(2) | |
| 758 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
| 759 | ||
| 760 | try: | |
| 761 | s.connect(('127.0.0.1', int(Parameters["Mode5"])))
| |
| 762 | isRunning = True | |
| 763 | s.sendall(b"GET /") | |
| 764 | except socket.error as e: | |
| 765 | isRunning = False | |
| 766 | UpdateDevice(255,0,'Off') | |
| 767 | ||
| 768 | s.close() | |
| 769 | if Parameters["Mode6"] == "Debug": | |
| 770 | Domoticz.Log("Web isAlive status :" +str(isRunning))
| |
| 771 | ||
| 772 | return | |
| 773 | ||
| 774 | #import json files and transfrom to ini file and hex imported code for RM2/RM2T | |
| 775 | def createIniImport(): | |
| 776 | global learnedCommand, custom | |
| 777 | ||
| 778 | import json | |
| 779 | ||
| 780 | path=Parameters["Mode2"] + "/import/" | |
| 781 | ||
| 782 | try: | |
| 783 | with open(path+"jsonSubIr", encoding='utf8') as remote_name: | |
| 784 | data_remote = json.load(remote_name) | |
| 785 | except ValueError: # includes simplejson.decoder.JSONDecodeError | |
| 786 | return False | |
| 787 | ||
| 788 | try: | |
| 789 | with open(path+"jsonButton", encoding='utf8') as button_name: | |
| 790 | data_button = json.load(button_name) | |
| 791 | except ValueError: # includes simplejson.decoder.JSONDecodeError | |
| 792 | return False | |
| 793 | ||
| 794 | try: | |
| 795 | with open(path+"jsonIrCode", encoding='utf8') as code_name: | |
| 796 | data_code = json.load(code_name) | |
| 797 | except ValueError: # includes simplejson.decoder.JSONDecodeError | |
| 798 | return False | |
| 799 | ||
| 800 | recCode = open(path+"simulate.txt", 'w') | |
| 801 | CRLF="\n" | |
| 802 | ||
| 803 | for i in range(0, len(data_code)): | |
| 804 | button = data_code[i]['buttonId'] | |
| 805 | for j in range(0, len(data_button)): | |
| 806 | if data_button[j]['id'] == button: | |
| 807 | numName = data_button[j]['subIRId'] | |
| 808 | buttonName = data_button[j]['name'] | |
| 809 | for k in range(0, len(data_remote)): | |
| 810 | if data_remote[k]['id'] == numName: | |
| 811 | name = data_remote[k]['name'] | |
| 812 | break | |
| 813 | else: | |
| 814 | name = "unknown" | |
| 815 | break | |
| 816 | else: | |
| 817 | buttonName = "unknown" | |
| 818 | ||
| 819 | code = ''.join('%02x' % (i & 0xff) for i in data_code[i]['code'])
| |
| 820 | result = "Numrec : " + str(i) + " Button number: " + str(button ) + " " + "Number name : " + str(numName) + " Name : " + name + " " + buttonName + " Code : " + str(code) | |
| 821 | custom = name + " " + buttonName | |
| 822 | path = Parameters["Mode2"] + "/import/" + "IMP-" + str(i) + ".ini" | |
| 823 | ||
| 824 | create_config(path,i,code,custom) | |
| 825 | recCode.writelines(result+CRLF) | |
| 826 | ||
| 827 | if Parameters["Mode6"] == "Debug": | |
| 828 | Domoticz.Log(result) | |
| 829 | ||
| 830 | filelink = "file://" + Parameters["Mode2"] + "/import/" + "simulate.txt" | |
| 831 | Domoticz.Log("Number of devices to create : " + str( i + 1 ))
| |
| 832 | Domoticz.Log("You need to select Import for that")
| |
| 833 | Domoticz.Log('Simulate.txt file has been created with all codes on it. Click <a target="_blank" href="' + filelink + '" style="color:blue">here</a> to see the path')
| |
| 834 | ||
| 835 | return True | |
| 836 | ||
| 837 | # if clear is True we will erase all files, if False we will create devices and erase ini files | |
| 838 | def manageIniImport(clear): | |
| 839 | global custom, learnedCommand | |
| 840 | ||
| 841 | import glob | |
| 842 | import errno | |
| 843 | ||
| 844 | path = Parameters["Mode2"] + "/import/*.ini" | |
| 845 | files = glob.glob(path) | |
| 846 | ||
| 847 | if not files: | |
| 848 | Domoticz.Log("No ini files found")
| |
| 849 | if clear == False: | |
| 850 | return False | |
| 851 | else: | |
| 852 | for name in files: # 'file' is a builtin type, 'name' is a less-ambiguous variable name. | |
| 853 | if clear == False: | |
| 854 | try: | |
| 855 | with open(name) as f: # No need to specify 'r': this is the default. | |
| 856 | config = configparser.ConfigParser() | |
| 857 | config.read(name,encoding='utf8') | |
| 858 | UnitNumber=config.get("DEFAULT", "unit")
| |
| 859 | custom=config.get("DEFAULT", "customname")
| |
| 860 | learnedCommand = config.get("LearnedCode", str(UnitNumber))
| |
| 861 | createDev() | |
| 862 | except IOError as exc: | |
| 863 | if exc.errno != errno.EISDIR: # Do not fail if a directory is found, just ignore it. | |
| 864 | raise # Propagate other kinds of IOErro | |
| 865 | os.remove(name) | |
| 866 | if Parameters["Mode6"] == "Debug": | |
| 867 | Domoticz.Log(name + " removed") | |
| 868 | ||
| 869 | if clear == True: | |
| 870 | path = Parameters["Mode2"] + "/import/json*" | |
| 871 | files = glob.glob(path) | |
| 872 | if not files: | |
| 873 | Domoticz.Log("No json files found")
| |
| 874 | return False | |
| 875 | else: | |
| 876 | for name in files: | |
| 877 | os.remove(name) | |
| 878 | if Parameters["Mode6"] == "Debug": | |
| 879 | Domoticz.Log(name + " removed") | |
| 880 | ||
| 881 | return True | |
| 882 | ||
| 883 | def createDev(): | |
| 884 | ||
| 885 | if not save() and numberDev < 254: | |
| 886 | createDev() | |
| 887 | ||
| 888 | return | |
| 889 | ||
| 890 | def remoteSend(Command): | |
| 891 | ||
| 892 | if Command in remoteKEY: | |
| 893 | k = remoteKEY.index(Command) | |
| 894 | try: | |
| 895 | genCommand(remotetoSEND[k]) | |
| 896 | except IndexError: | |
| 897 | Domoticz.Error('Send error or Remote command not set in ini file: ' + Command)
| |
| 898 | return False | |
| 899 | if Parameters["Mode6"] == "Debug": | |
| 900 | Domoticz.Log('Remote send: ' + str(k+1) + " " + str(remotetoSEND[k]))
| |
| 901 | else: | |
| 902 | Domoticz.Error('Remote command not defined: ' + Command)
| |
| 903 | return False | |
| 904 | ||
| 905 | return True | |
| 906 | ||
| 907 | # get config ini file | |
| 908 | def get_remoteconfig(): | |
| 909 | global RemoteCommand | |
| 910 | ||
| 911 | name = Parameters["Mode2"] + "/remote/plugin_remote_"+ str(Parameters["HardwareID"]) + ".ini" | |
| 912 | ||
| 913 | if os.path.isfile(name): | |
| 914 | try: | |
| 915 | with open(name) as f: # No need to specify 'r': this is the default. | |
| 916 | config = configparser.ConfigParser() | |
| 917 | config.read(name,encoding='utf8') | |
| 918 | RemoteCommand = config.get("Custom", "Command")
| |
| 919 | except IOError as exc: | |
| 920 | Domoticz.Error('error : ' + str(exc))
| |
| 921 | raise # Propagate other kinds of IOErro | |
| 922 | ||
| 923 | if Parameters["Mode6"] == "Debug": | |
| 924 | Domoticz.Log( "ini file read...." + name) | |
| 925 | Domoticz.Log( "Custom Commands: " + RemoteCommand) | |
| 926 | else: | |
| 927 | if Parameters["Mode6"] == "Debug": | |
| 928 | Domoticz.Log( "No ini file :" + name) | |
| 929 | Domoticz.Log( "Custom Commands for Remote not managed") | |
| 930 | ||
| 931 | return | |
| 932 | ||
| 933 | # generate tuple for remote | |
| 934 | def genRemote(): | |
| 935 | global remoteKEY, remotetoSEND | |
| 936 | ||
| 937 | from ast import literal_eval as make_tuple | |
| 938 | ||
| 939 | get_remoteconfig() | |
| 940 | ||
| 941 | if RemoteCommand: | |
| 942 | remotetoSEND = make_tuple(RemoteCommand) | |
| 943 | ||
| 944 | remoteKEY=( "Home", | |
| 945 | "Up", | |
| 946 | "Info", | |
| 947 | "Left", | |
| 948 | "Select", | |
| 949 | "Right", | |
| 950 | "Back", | |
| 951 | "Down", | |
| 952 | "ContextMenu", | |
| 953 | "ChannelUp", | |
| 954 | "FullScreen", | |
| 955 | "VolumeUp", | |
| 956 | "Channels", | |
| 957 | "ShowSubtitles", | |
| 958 | "Mute", | |
| 959 | "ChannelDown", | |
| 960 | "Stop", | |
| 961 | "VolumeDown", | |
| 962 | "BigStepBack", | |
| 963 | "Rewind", | |
| 964 | "PlayPause", | |
| 965 | "FastForward", | |
| 966 | "BigStepForward" | |
| 967 | ) | |
| 968 | ||
| 969 | return | |
| 970 | ||
| 971 | # retreive sensors data and update devices for type A1 | |
| 972 | def checkSensor(): | |
| 973 | ||
| 974 | # data | |
| 975 | try: | |
| 976 | data=device.check_sensors() | |
| 977 | except: | |
| 978 | Domoticz.Error( "Error getting sensor data from Broadlink device....Timeout") | |
| 979 | return False | |
| 980 | ||
| 981 | if Parameters["Mode6"] == "Debug": | |
| 982 | Domoticz.Log(str(data)) | |
| 983 | ||
| 984 | # raw data | |
| 985 | try: | |
| 986 | data_raw=device.check_sensors_raw() | |
| 987 | except: | |
| 988 | Domoticz.Error( "Error getting sensor data raw from Broadlink device....Timeout") | |
| 989 | return False | |
| 990 | ||
| 991 | if Parameters["Mode6"] == "Debug": | |
| 992 | Domoticz.Log(str(data_raw)) | |
| 993 | ||
| 994 | # temperature | |
| 995 | tem = data['temperature'] | |
| 996 | ||
| 997 | UpdateDevice(2,0,str(tem)) | |
| 998 | ||
| 999 | # humidity | |
| 1000 | hum = data['humidity'] | |
| 1001 | if hum < 50: | |
| 1002 | hum_raw = "0" | |
| 1003 | elif hum < 60: | |
| 1004 | hum_raw = "1" | |
| 1005 | elif hum < 70: | |
| 1006 | hum_raw = "2" | |
| 1007 | else: | |
| 1008 | hum_raw = "3" | |
| 1009 | ||
| 1010 | UpdateDevice(3,int(hum),hum_raw) | |
| 1011 | ||
| 1012 | # air quality | |
| 1013 | air = data['air_quality'] | |
| 1014 | air_raw = data_raw['air_quality'] | |
| 1015 | if air_raw == 0: | |
| 1016 | air_raw = 400 | |
| 1017 | elif air_raw == 1: | |
| 1018 | air_raw = 800 | |
| 1019 | elif air_raw == 2: | |
| 1020 | air_raw = 1000 | |
| 1021 | elif air_raw == 3: | |
| 1022 | air_raw = 1800 | |
| 1023 | else: | |
| 1024 | air_raw = 2800 | |
| 1025 | ||
| 1026 | UpdateDevice(4,int(air_raw),str(air)) | |
| 1027 | ||
| 1028 | # noise | |
| 1029 | noi = data['noise'] | |
| 1030 | noi_raw = data_raw['noise'] | |
| 1031 | if noi_raw == 0: | |
| 1032 | noi_raw = 20 | |
| 1033 | elif noi_raw == 1: | |
| 1034 | noi_raw = 60 | |
| 1035 | elif noi_raw == 2: | |
| 1036 | noi_raw = 80 | |
| 1037 | else: | |
| 1038 | noi_raw = 120 | |
| 1039 | ||
| 1040 | UpdateDevice(5,0,int(noi_raw)) | |
| 1041 | ||
| 1042 | # illimunation | |
| 1043 | lux = data['light'] | |
| 1044 | lux_raw = data_raw['light'] | |
| 1045 | if lux_raw == 0: | |
| 1046 | lux_raw = 10 | |
| 1047 | elif lux_raw == 1: | |
| 1048 | lux_raw = 200 | |
| 1049 | elif lux_raw == 2: | |
| 1050 | lux_raw = 400 | |
| 1051 | elif lux_raw == 3: | |
| 1052 | lux_raw = 800 | |
| 1053 | else: | |
| 1054 | lux_raw = 1600 | |
| 1055 | ||
| 1056 | UpdateDevice(6,0,int(lux_raw)) | |
| 1057 | ||
| 1058 | ||
| 1059 | return True | |
| 1060 | ||
| 1061 | # SP1/2/3 devices | |
| 1062 | def checkPower(): | |
| 1063 | global state | |
| 1064 | ||
| 1065 | try: | |
| 1066 | state = device.check_power() | |
| 1067 | if Parameters["Mode6"] == "Debug": | |
| 1068 | Domoticz.Log( ' Power state : ' + str(state)) | |
| 1069 | except: | |
| 1070 | Domoticz.Error ('check power error')
| |
| 1071 | return False | |
| 1072 | ||
| 1073 | return True | |
| 1074 | ||
| 1075 | # MP1 Device | |
| 1076 | def checkPowerMP1(): | |
| 1077 | global statemp1 | |
| 1078 | ||
| 1079 | statemp1 = {}
| |
| 1080 | ||
| 1081 | try: | |
| 1082 | statemp1 = device.check_power() | |
| 1083 | if Parameters["Mode6"] == "Debug": | |
| 1084 | Domoticz.Log( ' Power state : ' + str(statemp1)) | |
| 1085 | except: | |
| 1086 | Domoticz.Error ('MP1 check power error')
| |
| 1087 | return False | |
| 1088 | ||
| 1089 | return True | |
| 1090 | ||
| 1091 | # SP3s device (SP2) | |
| 1092 | def getEnergy(): | |
| 1093 | global energy | |
| 1094 | ||
| 1095 | try: | |
| 1096 | energy = device.get_energy() | |
| 1097 | if Parameters["Mode6"] == "Debug": | |
| 1098 | Domoticz.Log( ' Energy : ' + str(energy)) | |
| 1099 | except: | |
| 1100 | Domoticz.Error ('Get Energy error')
| |
| 1101 | return False | |
| 1102 | ||
| 1103 | return True | |
| 1104 | ||
| 1105 | # we put all switchs of the MP1 device to Off | |
| 1106 | def AllPlugOff(): | |
| 1107 | ||
| 1108 | UpdateDevice (2,0,'Off') | |
| 1109 | UpdateDevice (3,0,'Off') | |
| 1110 | UpdateDevice (4,0,'Off') | |
| 1111 | UpdateDevice (5,0,'Off') | |
| 1112 | ||
| 1113 | return | |
| 1114 | ||
| 1115 | # we put all switchs of the MP1 device to On | |
| 1116 | def AllPlugOn(): | |
| 1117 | ||
| 1118 | UpdateDevice (2,1,'On') | |
| 1119 | UpdateDevice (3,1,'On') | |
| 1120 | UpdateDevice (4,1,'On') | |
| 1121 | UpdateDevice (5,1,'On') | |
| 1122 | ||
| 1123 | return |