· 8 years ago · Aug 27, 2018, 06:06 PM
1
2#
3# Author: zaraki673
4#
5
6"""
7<plugin key="Zigate" name="Zigate plugin" author="zaraki673" version="2.3.5 developement" wikilink="http://www.domoticz.com/wiki/Zigate" externallink="https://www.zigate.fr/">
8 <params>
9 <param field="Mode1" label="Model" width="75px">
10 <options>
11 <option label="USB" value="USB" default="true" />
12 <option label="Wifi" value="Wifi"/>
13 </options>
14 </param>
15 <param field="Address" label="IP" width="150px" required="true" default="0.0.0.0"/>
16 <param field="Port" label="Port" width="150px" required="true" default="9999"/>
17 <param field="SerialPort" label="Serial Port" width="150px" required="true" default="/dev/ttyUSB0"/>
18 <param field="Mode5" label="Channel " width="50px" required="true" default="11" />
19 <param field="Mode2" label="Permit join time on start (0 disable join; 1-254 up to 254 sec ; 255 enable join all the time) " width="75px" required="true" default="254" />
20 <param field="Mode3" label="Erase Persistent Data ( !!! full devices setup need !!! ) " width="75px">
21 <options>
22 <option label="True" value="True"/>
23 <option label="False" value="False" default="true" />
24 </options>
25 </param>
26 <param field="Mode6" label="Debug" width="150px">
27 <options>
28 <option label="None" value="0" default="true" />
29 <option label="Python Only" value="2"/>
30 <option label="Basic Debugging" value="62"/>
31 <option label="Basic+Messages" value="126"/>
32 <option label="Connections Only" value="16"/>
33 <option label="Connections+Python" value="18"/>
34 <option label="Connections+Queue" value="144"/>
35 <option label="All" value="-1"/>
36 </options>
37 </param>
38 </params>
39</plugin>
40"""
41
42import Domoticz
43import binascii
44import time
45import struct
46import json
47
48FirmwareVersion = ''
49HeartbeatCount = 88 # request a network status 10s after start
50
51class BasePlugin:
52 enabled = False
53
54 def __init__(self):
55 self.ListOfDevices = {} # {DevicesAddresse : { status : status_de_detection, data : {ep list ou autres en fonctions du status}}, DevicesAddresse : ...}
56 self.HBcount=0
57 return
58
59 def onStart(self):
60 Domoticz.Log("onStart called")
61 Domoticz.Log("Development branch")
62 global ReqRcv
63 global ZigateConn
64 if Parameters["Mode6"] != "0":
65 Domoticz.Debugging(int(Parameters["Mode6"]))
66 DumpConfigToLog()
67 if Parameters["Mode1"] == "USB":
68 ZigateConn = Domoticz.Connection(Name="ZiGate", Transport="Serial", Protocol="None", Address=Parameters["SerialPort"], Baud=115200)
69 ZigateConn.Connect()
70 if Parameters["Mode1"] == "Wifi":
71 ZigateConn = Domoticz.Connection(Name="Zigate", Transport="TCP/IP", Protocol="None ", Address=Parameters["Address"], Port=Parameters["Port"])
72 ZigateConn.Connect()
73 ReqRcv=bytearray()
74
75 for x in Devices : # initialise listeofdevices avec les devices en bases domoticz
76 ID = Devices[x].DeviceID
77 try:
78 self.ListOfDevices[ID]=eval(Devices[x].Options['Zigate'])
79 Domoticz.Log("Device : [" + str(x) + "] ID = " + ID + " Options['Zigate'] = " + Devices[x].Options['Zigate'] + " loaded into self.ListOfDevices")
80 except:
81 Domoticz.Error("Error loading Device " +str(Devices[x]) + " not loaded int Zigate Plugin!" )
82 self.ListOfDevices[ID]={}
83
84 #Import DeviceConf.txt
85 tmpread=""
86 with open(Parameters["HomeFolder"]+"DeviceConf.txt", 'r') as myfile:
87 tmpread+=myfile.read().replace('\n', '')
88 myfile.close()
89 Domoticz.Debug("DeviceConf.txt = " + str(tmpread))
90 self.DeviceConf=eval(tmpread)
91 #Import DeviceList.txt
92 with open(Parameters["HomeFolder"]+"DeviceList.txt", 'r') as myfile2:
93 Domoticz.Debug("DeviceList.txt open ")
94 for line in myfile2:
95 (key, val) = line.split(":",1)
96 key = key.replace(" ","")
97 key = key.replace("'","")
98 CheckDeviceList(self, key, val)
99 return
100
101
102 def onStop(self):
103 ZigateConn.Disconnect()
104 WriteDeviceList(self, 0)
105 Domoticz.Log("onStop called")
106
107 def onConnect(self, Connection, Status, Description):
108 Domoticz.Log("onConnect called")
109 global isConnected
110
111 if (Status == 0):
112 isConnected = True
113 Domoticz.Log("Connected successfully")
114 if Parameters["Mode3"] == "True":
115 ################### ZiGate - ErasePD ##################
116 sendZigateCmd("0012", "")
117 ZigateConf()
118 else:
119 Domoticz.Error("Failed to connect ("+str(Status)+")")
120 Domoticz.Debug("Failed to connect ("+str(Status)+") with error: "+Description)
121 return True
122
123 def onMessage(self, Connection, Data):
124 Domoticz.Debug("onMessage called on Connection " +str(Connection) + " Data = '" +str(Data) + "'")
125 global ReqRcv
126
127 # Version 3 - Binary reading to avoid mixing end of Frame - Thanks to CLDFR
128 ReqRcv += Data # Add the incoming data
129 Domoticz.Debug("onMessage incoming data : '" + str(binascii.hexlify(ReqRcv).decode('utf-8'))+ "'" )
130
131 # Zigate Frames start with 0x01 and finished with 0x03
132 # It happens that we get some
133 while 1 : # Loop until we have 0x03
134 Zero1=-1
135 Zero3=-1
136 idx = 0
137 for val in ReqRcv[0:len(ReqRcv)] :
138 if Zero1 == - 1 and Zero3 == -1 and val == 1 : # Do we get a 0x01
139 Zero1 = idx # we have identify the Frame start
140
141 if Zero1 != -1 and val == 3 : # If we have already started a Frame and do we get a 0x03
142 Zero3 = idx + 1
143 break # If we got 0x03, let process the Frame
144 idx += 1
145
146 if Zero3 == -1 : # No 0x03 in the Buffer, let's breat and wait to get more data
147 return
148
149 Domoticz.Debug("onMessage Frame : Zero1=" + str(Zero1) + " Zero3=" + str(Zero3) )
150
151 BinMsg = ReqRcv[Zero1:Zero3] # What is before 0x03 is in the Frame to be process
152 ReqRcv = ReqRcv[Zero3:] # What is after 0x03 has to be reworked.
153
154 # Process the incoming Frame
155 AsciiMsg=binascii.hexlify(BinMsg).decode('utf-8')
156 Domoticz.Debug("onMessage Frame : " + str(AsciiMsg) )
157 ZigateDecode(self, AsciiMsg) # decode this Frame
158
159 Domoticz.Debug("onMessage Remaining Frame : " + str(binascii.hexlify(ReqRcv).decode('utf-8') ))
160
161 return
162
163 def onCommand(self, Unit, Command, Level, Hue):
164 Domoticz.Log("#########################")
165 Domoticz.Log("onCommand called for Unit " + str(Unit) + ": Parameter '" + str(Command) + "', Level: " + str(Level) + " Hue: " + str(Hue) )
166
167 DSwitchtype= str(Devices[Unit].SwitchType)
168 DOptions = Devices[Unit].Options
169 Dtypename=DOptions['TypeName']
170 Dzigate=eval(DOptions['Zigate'])
171 SignalLevel = self.ListOfDevices[Devices[Unit].DeviceID]['RSSI']
172
173 EPin="01"
174 EPout="01" # If we don't have a cluster search, or if we don't find an EPout for a cluster search, then lets use EPout=01
175 ClusterSearch = ""
176 if Dtypename=="Switch" or Dtypename=="Plug" or Dtypename=="MSwitch" or Dtypename=="Smoke" or Dtypename=="DSwitch" or Dtypename=="Button" or Dtypename=="DButton":
177 ClusterSearch="0006"
178 if Dtypename=="LvlControl" :
179 ClusterSearch="0008"
180 if Dtypename=="ColorControl" :
181 ClusterSearch="0300"
182
183 for tmpEp in self.ListOfDevices[Devices[Unit].DeviceID]['Ep'] :
184 if ClusterSearch in self.ListOfDevices[Devices[Unit].DeviceID]['Ep'][tmpEp] : #switch cluster
185 EPout=tmpEp
186
187 Domoticz.Log("Dtypename : " + Dtypename)
188
189 if Command == "On" :
190 sendZigateCmd("0092","02" + Devices[Unit].DeviceID + EPin + EPout + "01")
191 UpdateDevice_v2(Unit, 1, "On",DOptions, SignalLevel)
192
193 if Command == "Off" :
194 if (False):#Pas trouve un moyen sans problemes
195 if (Dtypename=="LvlControl") or (Dtypename == 'ColorControl') :
196 #Disabled for level control and color control
197 Command == "Set Level"
198 Level = 1
199 else:
200 sendZigateCmd("0092","02" + Devices[Unit].DeviceID + EPin + EPout + "00")
201 UpdateDevice_v2(Unit, 0, "Off",DOptions, SignalLevel)
202
203 if Command == "Set Level" :
204 self.ListOfDevices[Devices[Unit].DeviceID]['Heartbeat'] = 0 # As we update the Device, let's restart and do the next pool in 5'
205 OnOff = '01' # 00 = off, 01 = on
206 value=Hex_Format(2,round(1+Level*253/100)) #To prevent off state with dimmer, only available with switch
207 sendZigateCmd("0081","02" + Devices[Unit].DeviceID + EPin + EPout + OnOff + value + "0010")
208 UpdateDevice_v2(Unit, 1, str(Level) ,DOptions, SignalLevel) #Need to use 1 as nvalue else, it will set it to off
209
210 if Command == "Set Color" :
211 Domoticz.Debug("onCommand - Set Color - Level = " + str(Level) + " Hue = " + str(Hue) )
212 Hue_List = json.loads(Hue)
213
214 def hex_to_rgb(h):
215 ''' convert hex color to rgb tuple '''
216 h = h.strip('#')
217 return tuple(int(h[i:i+2], 16)/255 for i in (0, 2 ,4))
218
219 def rgb_to_xy(rgb):
220 ''' convert rgb tuple to xy tuple '''
221 red, green, blue = rgb
222 r = ((red + 0.055) / (1.0 + 0.055))**2.4 if (red > 0.04045) else (red / 12.92)
223 g = ((green + 0.055) / (1.0 + 0.055))**2.4 if (green > 0.04045) else (green / 12.92)
224 b = ((blue + 0.055) / (1.0 + 0.055))**2.4 if (blue > 0.04045) else (blue / 12.92)
225 X = r * 0.664511 + g * 0.154324 + b * 0.162028
226 Y = r * 0.283881 + g * 0.668433 + b * 0.047685
227 Z = r * 0.000088 + g * 0.072310 + b * 0.986039
228 cx = 0
229 cy = 0
230 if (X + Y + Z) != 0:
231 cx = X / (X + Y + Z)
232 cy = Y / (X + Y + Z)
233 return (cx, cy)
234
235 self.ListOfDevices[Devices[Unit].DeviceID]['Heartbeat'] = 0 # As we update the Device, let's restart and do the next pool in 5'
236
237 #First manage level
238 OnOff = '01' # 00 = off, 01 = on
239 value=Hex_Format(2,round(1+Level*254/100)) #To prevent off state
240 sendZigateCmd("0081","02" + Devices[Unit].DeviceID + EPin + EPout + OnOff + value + "0000")
241
242 #Now color
243 #CT mode
244 if Hue_List['m'] == 2:
245 #Value is in mireds (not kelvin)
246 #Correct values are from 153 (6500K) up to 588 (1700K)
247 # t is 0 > 255
248 TempKelvin = int(((255 - int(Hue_List['t']))*(6500-1700)/255)+1700);
249 TempMired = 1000000 // TempKelvin
250 sendZigateCmd("00C0","02" + Devices[Unit].DeviceID + EPin + EPout + Hex_Format(4,TempMired) + "0000")
251 #CW WW mode, don't exist ???
252 elif Hue_List['m'] == 9999:
253 ww = int(Hue_List['ww'])
254 cw = int(Hue_List['cw'])
255 cwww = Hex_Format(2,cw) + Hex_Format(2,ww)
256 #Use it as it ?
257 strTemp = str(cwww)
258 sendZigateCmd("00C0","02" + Devices[Unit].DeviceID + EPin + EPout + strTemp + "0000")
259 #RGB mode
260 elif Hue_List['m'] == 3:
261 x, y = rgb_to_xy((int(Hue_List['r']),int(Hue_List['g']),int(Hue_List['b'])))
262 #Convert 0>1 to 0>FFFF
263 x = int(x*65536)
264 y = int(y*65536)
265 strxy = Hex_Format(4,x) + Hex_Format(4,y)
266 sendZigateCmd("00B7","02" + Devices[Unit].DeviceID + EPin + EPout + strxy + "0000")
267 #With saturation and hue, not seen in domoticz but present on zigate
268 elif Hue_List['m'] == 9998:
269 saturation = 0 #0 > 100
270 hue2 = 0 #0 > 360
271 hue2 = int(hue2*254//360)
272 saturation = int(saturation*254//100)
273 sendZigateCmd("0C0","02" + Devices[Unit].DeviceID + EPin + EPout + Hex_Format(2,hue2) + Hex_Format(2,saturation) + "0000")
274
275 #Update Device
276 UpdateDevice_v2(Unit, 1, str(value) ,DOptions, SignalLevel, str(Hue))
277
278
279 def onDisconnect(self, Connection):
280 Domoticz.Log("onDisconnect called")
281
282 def onHeartbeat(self):
283 global FirmwareVersion
284 global HeartbeatCount
285
286 #Domoticz.Log("onHeartbeat called" )
287 Domoticz.Debug("ListOfDevices : " + str(self.ListOfDevices))
288
289 ## Check the Network status every 15' / Only possible if FirmwareVersion > 3.0d
290 if str(FirmwareVersion) == "030d" :
291 if HeartbeatCount >= 90 :
292 Domoticz.Debug("request Network Status")
293 sendZigateCmd("0009","")
294 HeartbeatCount = 0
295 else :
296 HeartbeatCount = HeartbeatCount + 1
297
298 for key in self.ListOfDevices :
299 status=self.ListOfDevices[key]['Status']
300 RIA=int(self.ListOfDevices[key]['RIA'])
301 self.ListOfDevices[key]['Heartbeat']=str(int(self.ListOfDevices[key]['Heartbeat'])+1)
302
303 ########## Known Devices
304 if status == "inDB" :
305 # device id type shutter, let check the shutter status every 5' ( 30 * onHearbeat period ( 10s ) )
306 if self.ListOfDevices[key]['Model'] == "shutter.Profalux" and self.ListOfDevices[key]['Heartbeat']>="30" :
307 Domoticz.Debug("Request a Read attribute for the shutter " + str(key) )
308 self.ListOfDevices[key]['Heartbeat']="0"
309 ReadAttributeRequest_0008(self, key)
310
311 ########## UnKnown Devices - Creation process
312 if status != "inDB" :
313 # Request EP list
314 if status=="004d" and self.ListOfDevices[key]['Heartbeat']=="1":
315 Domoticz.Log("Creation process for " + str(key) + " Info: " + str(self.ListOfDevices[key]) )
316 # We should check if the device has not been already created via IEEE
317 if IEEEExist( self, self.ListOfDevices[key]['IEEE'] ) == False :
318 Domoticz.Debug("onHeartbeat - new device discovered request EP list with 0x0045 and lets wait for 0x8045: " + key)
319 sendZigateCmd("0045", str(key))
320 self.ListOfDevices[key]['Status']="0045"
321 self.ListOfDevices[key]['Heartbeat']="0"
322 else :
323 for dup in self.ListOfDevices :
324 if self.ListOfDevices[key]['IEEE'] == self.ListOfDevices[dup]['IEEE'] and self.ListOfDevices[dup]['status'] == "inDB":
325 Domoticz.Error("onHearbeat - Device : " + str(key) + "already known under IEEE: " +str(self.ListOfDevices[key]['IEEE'] ) + " Duplicate of " + str(dup) )
326 self.ListOfDevices[key]['Status']="DUP"
327 self.ListOfDevices[key]['Heartbeat']="0"
328 self.ListOfDevices[key]['RIA']="99"
329 oktocreate=True
330 break
331
332 # Request Simple Descriptor for each EP
333 if status=="8045" and self.ListOfDevices[key]['Heartbeat']=="1":
334 Domoticz.Debug("onHeartbeat - new device discovered 0x8045 received " + key)
335 for cle in self.ListOfDevices[key]['Ep']:
336 Domoticz.Debug("onHeartbeat - new device discovered request Simple Descriptor 0x0043 and wait for 0x8043 for EP " + cle + ", of : " + key)
337 sendZigateCmd("0043", str(key)+str(cle))
338 self.ListOfDevices[key]['Status']="0043"
339 self.ListOfDevices[key]['Heartbeat']="0"
340
341 # Timeout Management
342 # We should wonder if we want to go in an infinite loop.
343 if status=="004d" and self.ListOfDevices[key]['Heartbeat']>="9":
344 Domoticz.Debug("onHeartbeat - new device discovered but no processing done, let's Timeout: " + key)
345 self.ListOfDevices[key]['Heartbeat']="0"
346 if status=="0045" and self.ListOfDevices[key]['Heartbeat']>="9":
347 Domoticz.Debug("onHeartbeat - new device discovered 0x8045 not received in time: " + key)
348 self.ListOfDevices[key]['Heartbeat']="0"
349 self.ListOfDevices[key]['Status']="004d"
350 if status=="8045" and self.ListOfDevices[key]['Heartbeat']>="9":
351 Domoticz.Debug("onHeartbeat - new device discovered 0x8045 not received in time: " + key)
352 self.ListOfDevices[key]['Heartbeat']="0"
353 self.ListOfDevices[key]['Status']="004d"
354 if status=="0043" and self.ListOfDevices[key]['Heartbeat']>="9":
355 Domoticz.Debug("onHeartbeat - new device discovered 0x8043 not received in time: " + key)
356 self.ListOfDevices[key]['Heartbeat']="0"
357 self.ListOfDevices[key]['Status']="8045"
358
359 # What RIA stand for ???????
360 if status=="8043" and self.ListOfDevices[key]['Heartbeat']>="9" and self.ListOfDevices[key]['RIA']>="10":
361 self.ListOfDevices[key]['Heartbeat']="0"
362 self.ListOfDevices[key]['Status']="UNKNOW"
363
364 if status != "UNKNOW" and status != "DUP":
365 if self.ListOfDevices[key]['MacCapa']=="8e" : # Device sur secteur
366 if self.ListOfDevices[key]['ProfileID']=="c05e" : # ZLL: ZigBee Light Link
367 # telecommande Tradfi 30338849.Tradfri
368 if self.ListOfDevices[key]['ZDeviceID']=="0830" :
369 self.ListOfDevices[key]['Model']="Command.30338849.Tradfri"
370 if self.ListOfDevices[key]['Ep']=={} :
371 self.ListOfDevices[key]['Ep']={'01':{'0000','0001','0009','0b05','1000'}}
372 # ampoule Tradfri LED1624G9
373 if self.ListOfDevices[key]['ZDeviceID']=="0200" :
374 self.ListOfDevices[key]['Model']="Ampoule.LED1624G9.Tradfri"
375 if self.ListOfDevices[key]['Ep']=={} :
376 self.ListOfDevices[key]['Ep']={'01':{'0006','0008','0300'}}
377 # ampoule Tradfi LED1545G12.Tradfri
378 if self.ListOfDevices[key]['ZDeviceID']=="0220" :
379 self.ListOfDevices[key]['Model']="Ampoule.LED1545G12.Tradfri"
380 if self.ListOfDevices[key]['Ep']=={} :
381 self.ListOfDevices[key]['Ep']={'01': {'0006', '0008', '0300'}}
382 # ampoule Tradfri LED1622G12.Tradfri ou phillips hue white
383 if self.ListOfDevices[key]['ZDeviceID']=="0100" :
384 self.ListOfDevices[key]['Model']="Ampoule.LED1622G12.Tradfri"
385 if self.ListOfDevices[key]['Ep']=={} :
386 self.ListOfDevices[key]['Ep']={'01': {'0006', '0008'}}
387 # plug osram
388 if self.ListOfDevices[key]['ZDeviceID']=="0010" :
389 self.ListOfDevices[key]['Model']="plug.Osram"
390 if self.ListOfDevices[key]['Ep']=={} :
391 self.ListOfDevices[key]['Ep']={'03': {'0006'}}
392
393 if self.ListOfDevices[key]['ProfileID']=="0104" : # profile home automation
394 # plug salus
395 if self.ListOfDevices[key]['ZDeviceID']=="0051" : # device id type plug on/off
396 self.ListOfDevices[key]['Model']="plug.Salus"
397 if self.ListOfDevices[key]['Ep']=={} :
398 self.ListOfDevices[key]['Ep']={'09': {'0006'}}
399 # ampoule Tradfi
400 if self.ListOfDevices[key]['ZDeviceID']=="0100" : # device id type light on/off
401 self.ListOfDevices[key]['Model']="Ampoule.LED1622G12.Tradfri"
402 if self.ListOfDevices[key]['Ep']=={} :
403 self.ListOfDevices[key]['Ep']={'01': {'0006', '0008'}}
404 # shutter profalux
405 if self.ListOfDevices[key]['ZDeviceID']=="0200" : # device id type shutter
406 self.ListOfDevices[key]['Model']="shutter.Profalux"
407 if self.ListOfDevices[key]['Ep']=={} :
408 self.ListOfDevices[key]['Ep']={'01':{'0006','0008'}}
409 # phillips hue
410 if self.ListOfDevices[key]['ProfileID']=="a1e0" :
411 if self.ListOfDevices[key]['ZDeviceID']=="0061" :
412 self.ListOfDevices[key]['Model']="Ampoule.phillips.hue"
413 if self.ListOfDevices[key]['Ep']=={} :
414 self.ListOfDevices[key]['Ep']={'01': {'0006', '0008'}}
415
416 # At that stage , we should have all information to create the Device Status 8043 is set in Decode8043 when receiving
417
418 if (RIA>=10 or self.ListOfDevices[key]['Model']!= {}) :
419 #creer le device ds domoticz en se basant sur les clusterID ou le Model si il est connu
420 IsCreated=False
421 #IEEEexist=False
422 x=0
423 nbrdevices=0
424 for x in Devices:
425 if Devices[x].DeviceID == str(key) :
426 IsCreated = True
427 Domoticz.Debug("onHeartbeat - Devices already exist. Unit=" + str(x) + " versus " + str(self.ListOfDevices[key]) )
428 #DOptions = Devices[x].Options
429 #Dzigate=eval(DOptions['Zigate'])
430 #Domoticz.Debug("HearBeat - Devices[x].Options['Zigate']['IEEE']=" + str(Dzigate['IEEE']))
431 #Domoticz.Debug("HearBeat - self.ListOfDevices[key]['IEEE']=" + str(self.ListOfDevices[key]['IEEE']))
432 #if Dzigate['IEEE']!='' and self.ListOfDevices[key]['IEEE']!='' :
433 # if Dzigate['IEEE']==self.ListOfDevices[key]['IEEE'] :
434 # IEEEexist = True
435 # Domoticz.Debug("HearBeat - Devices IEEE already exist. Unit=" + str(x))
436 if IsCreated == False : #and IEEEexist == False:
437 Domoticz.Debug("onHeartbeat - creating device id : " + str(key) + " with : " + str(self.ListOfDevices[key]) )
438 CreateDomoDevice(self, key)
439 #if IsCreated == False and IEEEexist == True :
440 # Domoticz.Debug("HearBeat - updating device id : " + str(key))
441 # UpdateDomoDevice(self, key)
442
443 #end (RIA>=10 or self.ListOfDevices[key]['Model']!= {})
444 #end status != "UNKNOW"
445 #end status != inDB
446 #end for key in ListOfDevices
447
448 ResetDevice("Motion",5)
449 WriteDeviceList(self, 200)
450
451 if (ZigateConn.Connected() != True):
452 ZigateConn.Connect()
453
454 return True
455
456
457global _plugin
458_plugin = BasePlugin()
459
460def onStart():
461 global _plugin
462 _plugin.onStart()
463
464def onStop():
465 global _plugin
466 _plugin.onStop()
467
468def onConnect(Connection, Status, Description):
469 global _plugin
470 _plugin.onConnect(Connection, Status, Description)
471
472def onMessage(Connection, Data):
473 global _plugin
474 _plugin.onMessage(Connection, Data)
475
476def onCommand(Unit, Command, Level, Hue):
477 global _plugin
478 _plugin.onCommand(Unit, Command, Level, Hue)
479
480def onDisconnect(Connection):
481 global _plugin
482 _plugin.onDisconnect(Connection)
483
484def onHeartbeat():
485 global _plugin
486 _plugin.onHeartbeat()
487
488# Generic helper functions
489def DumpConfigToLog():
490 for x in Parameters:
491 if Parameters[x] != "":
492 Domoticz.Debug( "'" + x + "':'" + str(Parameters[x]) + "'")
493 Domoticz.Debug("Device count: " + str(len(Devices)))
494 for x in Devices:
495 Domoticz.Debug("Device: " + str(x) + " - " + str(Devices[x]))
496 Domoticz.Debug("Device ID: '" + str(Devices[x].ID) + "'")
497 Domoticz.Debug("Device Name: '" + Devices[x].Name + "'")
498 Domoticz.Debug("Device nValue: " + str(Devices[x].nValue))
499 Domoticz.Debug("Device sValue: '" + Devices[x].sValue + "'")
500 Domoticz.Debug("Device LastLevel: " + str(Devices[x].LastLevel))
501 Domoticz.Debug("Device Options: " + str(Devices[x].Options))
502 return
503
504def ZigateConf():
505 global FirmwareVersion
506
507 ################### ZiGate - get Firmware version #############
508 # answer is expected on message 8010
509 sendZigateCmd("0010","")
510
511 ################### ZiGate - set channel ##################
512 sendZigateCmd("0021", "0000" + returnlen(2,hex(int(Parameters["Mode5"]))[2:4]) + "00")
513
514 ################### ZiGate - Set Type COORDINATOR #################
515 sendZigateCmd("0023","00")
516
517 ################### ZiGate - start network ##################
518 sendZigateCmd("0024","")
519
520 ################### ZiGate - Request Device List #############
521 # answer is expected on message 8015. Only available since firmware 03.0b
522 if str(FirmwareVersion) == "030d" or str(FirmwareVersion) == "030c" or str(FirmwareVersion == "030b") :
523 Domoticz.Log("ZigateConf - Request : Get List of Device " + str(FirmwareVersion) )
524 sendZigateCmd("0015","")
525 else :
526 Domoticz.Error("Cannot request Get List of Device due to low firmware level" + str(FirmwareVersion) )
527
528 ################### ZiGate - discover mode 255 sec Max ##################
529 #### Set discover mode only if requested - so != 0 #####
530 if Parameters["Mode2"] != "0":
531 if str(Parameters["Mode2"])=="255":
532 Domoticz.Status("Zigate enter in discover mode for ever")
533 else :
534 Domoticz.Status("Zigate enter in discover mode for " + str(Parameters["Mode2"]) + " Secs" )
535 sendZigateCmd("0049","FFFC" + hex(int(Parameters["Mode2"]))[2:4] + "00")
536
537def ZigateDecode(self, Data): # supprime le transcodage
538 Domoticz.Debug("ZigateDecode - decodind data : " + Data)
539 Out=""
540 Outtmp=""
541 Transcode = False
542 for c in Data :
543 Outtmp+=c
544 if len(Outtmp)==2 :
545 if Outtmp == "02" :
546 Transcode=True
547 else :
548 if Transcode == True:
549 Transcode = False
550 if Outtmp[0]=="1" :
551 Out+="0"
552 else :
553 Out+="1"
554 Out+=Outtmp[1]
555 else :
556 Out+=Outtmp
557 Outtmp=""
558 ZigateRead(self, Out)
559
560def ZigateEncode(Data): # ajoute le transcodage
561 Domoticz.Debug("ZigateEncode - Encodind data : " + Data)
562 Out=""
563 Outtmp=""
564 Transcode = False
565 for c in Data :
566 Outtmp+=c
567 if len(Outtmp)==2 :
568 if Outtmp[0] == "1" and Outtmp != "10":
569 if Outtmp[1] == "0" :
570 Outtmp="0200"
571 Out+=Outtmp
572 else :
573 Out+=Outtmp
574 elif Outtmp[0] == "0" :
575 Out+="021" + Outtmp[1]
576 else :
577 Out+=Outtmp
578 Outtmp=""
579 Domoticz.Debug("Transcode in : " + str(Data) + " / out :" + str(Out) )
580 return Out
581
582def sendZigateCmd(cmd,datas) :
583 if datas == "" :
584 length="0000"
585 else :
586 length=returnlen(4,(str(hex(int(round(len(datas)/2)))).split('x')[-1])) # by Cortexlegeni
587 Domoticz.Debug("sendZigateCmd - length is : " + str(length) )
588 if datas =="" :
589 checksumCmd=getChecksum(cmd,length,"0")
590 if len(checksumCmd)==1 :
591 strchecksum="0" + str(checksumCmd)
592 else :
593 strchecksum=checksumCmd
594 lineinput="01" + str(ZigateEncode(cmd)) + str(ZigateEncode(length)) + str(ZigateEncode(strchecksum)) + "03"
595 else :
596 checksumCmd=getChecksum(cmd,length,datas)
597 if len(checksumCmd)==1 :
598 strchecksum="0" + str(checksumCmd)
599 else :
600 strchecksum=checksumCmd
601 lineinput="01" + str(ZigateEncode(cmd)) + str(ZigateEncode(length)) + str(ZigateEncode(strchecksum)) + str(ZigateEncode(datas)) + "03"
602 Domoticz.Debug("sendZigateCmd - Comand send : " + str(lineinput))
603 if Parameters["Mode1"] == "USB":
604 ZigateConn.Send(bytes.fromhex(str(lineinput)))
605 if Parameters["Mode1"] == "Wifi":
606 ZigateConn.Send(bytes.fromhex(str(lineinput))+bytes("\r\n",'utf-8'),1)
607
608def ZigateRead(self, Data):
609 Domoticz.Debug("ZigateRead - decoded data : " + Data + " lenght : " + str(len(Data)) )
610
611 FrameStart=Data[0:2]
612 FrameStop=Data[len(Data)-2:len(Data)]
613 if ( FrameStart != "01" and FrameStop != "03" ):
614 Domoticz.Error("ZigateRead received a non-zigate frame Data : " + Data + " FS/FS = " + FrameStart + "/" + FrameStop )
615 return
616
617 MsgType=Data[2:6]
618 MsgLength=Data[6:10]
619 MsgCRC=Data[10:12]
620
621 if len(Data) > 12 :
622 # We have Payload : data + rssi
623 MsgData=Data[12:len(Data)-4]
624 MsgRSSI=Data[len(Data)-4:len(Data)-2]
625 calculatedchecksum=getChecksum( MsgType , MsgLength , MsgData + MsgRSSI)
626 else :
627 MsgData=""
628 MsgRSSI=""
629 calculatedchecksum=getChecksum( MsgType , MsgLength , "0")
630
631 if ( int(calculatedchecksum,16) != int(MsgCRC,16) ) :
632 Domoticz.Error("ZigateRead - Checksum error: " + calculatedchecksum + " / " + MsgCRC + " MsgType = " + MsgType + " MsgLength : " + MsgLength + " RawData '" + Data + "'" )
633 return
634
635 Domoticz.Debug("ZigateRead - Message Type : " + MsgType + ", Data : " + MsgData + ", RSSI : " + MsgRSSI + ", Length : " + MsgLength + ", Checksum : " + MsgCRC)
636
637
638 if str(MsgType)=="004d": # Device announce
639 Domoticz.Debug("ZigateRead - MsgType 004d - Reception Device announce : " + Data)
640 Decode004d(self, MsgData)
641 return
642
643 elif str(MsgType)=="00d1": #
644 Domoticz.Debug("ZigateRead - MsgType 00d1 - Reception Touchlink status : " + Data)
645 return
646
647 elif str(MsgType)=="8000": # Status
648 Domoticz.Debug("ZigateRead - MsgType 8000 - reception status : " + Data)
649 #Decode8000(self, MsgData)
650 Decode8000_v2(self, MsgData)
651 return
652
653 elif str(MsgType)=="8001": # Log
654 Domoticz.Debug("ZigateRead - MsgType 8001 - Reception log Level : " + Data)
655 Decode8001(self, MsgData)
656 return
657
658 elif str(MsgType)=="8002": #
659 Domoticz.Debug("ZigateRead - MsgType 8002 - Reception Data indication : " + Data)
660 return
661
662 elif str(MsgType)=="8003": #
663 Domoticz.Debug("ZigateRead - MsgType 8003 - Reception Liste des cluster de l'objet : " + Data)
664 return
665
666 elif str(MsgType)=="8004": #
667 Domoticz.Debug("ZigateRead - MsgType 8004 - Reception Liste des attributs de l'objet : " + Data)
668 return
669
670 elif str(MsgType)=="8005": #
671 Domoticz.Debug("ZigateRead - MsgType 8005 - Reception Liste des commandes de l'objet : " + Data)
672 return
673
674 elif str(MsgType)=="8006": #
675 Domoticz.Debug("ZigateRead - MsgType 8006 - Reception Non factory new restart : " + Data)
676 return
677
678 elif str(MsgType)=="8007": #
679 Domoticz.Debug("ZigateRead - MsgType 8007 - Reception Factory new restart : " + Data)
680 return
681
682 elif str(MsgType)=="8009": #
683 Domoticz.Debug("ZigateRead - MsgType 8009 - Network State response : " + Data)
684 Decode8009( self, MsgData)
685 return
686
687
688 elif str(MsgType)=="8010": # Version
689 Domoticz.Debug("ZigateRead - MsgType 8010 - Reception Version list : " + Data)
690 Decode8010(self, MsgData)
691 return
692
693 elif str(MsgType)=="8014": #
694 Domoticz.Debug("ZigateRead - MsgType 8014 - Reception Permit join status response : " + Data)
695 Decode8014(self, MsgData)
696 return
697
698 elif str(MsgType)=="8015": #
699 Domoticz.Debug("ZigateRead - MsgType 8015 - Get devices list : " + Data)
700 Decode8015(self, MsgData)
701 return
702
703
704 elif str(MsgType)=="8024": #
705 Domoticz.Debug("ZigateRead - MsgType 8024 - Reception Network joined /formed : " + Data)
706 return
707
708 elif str(MsgType)=="8028": #
709 Domoticz.Debug("ZigateRead - MsgType 8028 - Reception Authenticate response : " + Data)
710 return
711
712 elif str(MsgType)=="8029": #
713 Domoticz.Debug("ZigateRead - MsgType 8029 - Reception Out of band commissioning data response : " + Data)
714 return
715
716 elif str(MsgType)=="802b": #
717 Domoticz.Debug("ZigateRead - MsgType 802b - Reception User descriptor notify : " + Data)
718 return
719
720 elif str(MsgType)=="802c": #
721 Domoticz.Debug("ZigateRead - MsgType 802c - Reception User descriptor response : " + Data)
722 return
723
724 elif str(MsgType)=="8030": #
725 Domoticz.Debug("ZigateRead - MsgType 8030 - Reception Bind response : " + Data)
726 return
727
728 elif str(MsgType)=="8031": #
729 Domoticz.Debug("ZigateRead - MsgType 8031 - Reception Unbind response : " + Data)
730 return
731
732 elif str(MsgType)=="8034": #
733 Domoticz.Debug("ZigateRead - MsgType 8034 - Reception Coplex Descriptor response : " + Data)
734 return
735
736 elif str(MsgType)=="8040": #
737 Domoticz.Debug("ZigateRead - MsgType 8040 - Reception Network address response : " + Data)
738 return
739
740 elif str(MsgType)=="8041": #
741 Domoticz.Debug("ZigateRead - MsgType 8041 - Reception IEEE address response : " + Data)
742 return
743
744 elif str(MsgType)=="8042": #
745 Domoticz.Debug("ZigateRead - MsgType 8042 - Reception Node descriptor response : " + Data)
746 Decode8042(self, MsgData)
747 return
748
749 elif str(MsgType)=="8043": # Simple Descriptor Response
750 Domoticz.Debug("ZigateRead - MsgType 8043 - Reception Simple descriptor response " + Data)
751 Decode8043(self, MsgData)
752 return
753
754 elif str(MsgType)=="8044": #
755 Domoticz.Debug("ZigateRead - MsgType 8044 - Reception Power descriptor response : " + Data)
756 Decode8044(self, MsgData)
757 return
758
759 elif str(MsgType)=="8045": # Active Endpoints Response
760 Domoticz.Debug("ZigateRead - MsgType 8045 - Reception Active endpoint response : " + Data)
761 Decode8045(self, MsgData)
762 return
763
764 elif str(MsgType)=="8046": #
765 Domoticz.Debug("ZigateRead - MsgType 8046 - Reception Match descriptor response : " + Data)
766 return
767
768 elif str(MsgType)=="8047": #
769 Domoticz.Debug("ZigateRead - MsgType 8047 - Reception Management leave response : " + Data)
770 return
771
772 elif str(MsgType)=="8048": #
773 Domoticz.Debug("ZigateRead - MsgType 8048 - Reception Leave indication : " + Data)
774 return
775
776 elif str(MsgType)=="804a": #
777 Domoticz.Debug("ZigateRead - MsgType 804a - Reception Management Network Update response : " + Data)
778 return
779
780 elif str(MsgType)=="804b": #
781 Domoticz.Debug("ZigateRead - MsgType 804b - Reception System server discovery response : " + Data)
782 return
783
784 elif str(MsgType)=="804e": #
785 Domoticz.Debug("ZigateRead - MsgType 804e - Reception Management LQI response : " + Data)
786 return
787
788 elif str(MsgType)=="8060": #
789 Domoticz.Debug("ZigateRead - MsgType 8060 - Reception Add group response : " + Data)
790 return
791
792 elif str(MsgType)=="8061": #
793 Domoticz.Debug("ZigateRead - MsgType 8061 - Reception Viex group response : " + Data)
794 return
795
796 elif str(MsgType)=="8062": #
797 Domoticz.Debug("ZigateRead - MsgType 8062 - Reception Get group Membership response : " + Data)
798 return
799
800 elif str(MsgType)=="8063": #
801 Domoticz.Debug("ZigateRead - MsgType 8063 - Reception Remove group response : " + Data)
802 return
803
804 elif str(MsgType)=="80a0": #
805 Domoticz.Debug("ZigateRead - MsgType 80a0 - Reception View scene response : " + Data)
806 return
807
808 elif str(MsgType)=="80a1": #
809 Domoticz.Debug("ZigateRead - MsgType 80a1 - Reception Add scene response : " + Data)
810 return
811
812 elif str(MsgType)=="80a2": #
813 Domoticz.Debug("ZigateRead - MsgType 80a2 - Reception Remove scene response : " + Data)
814 return
815
816 elif str(MsgType)=="80a3": #
817 Domoticz.Debug("ZigateRead - MsgType 80a3 - Reception Remove all scene response : " + Data)
818 return
819
820 elif str(MsgType)=="80a4": #
821 Domoticz.Debug("ZigateRead - MsgType 80a4 - Reception Store scene response : " + Data)
822 return
823
824 elif str(MsgType)=="80a6": #
825 Domoticz.Debug("ZigateRead - MsgType 80a6 - Reception Scene membership response : " + Data)
826 return
827
828 elif str(MsgType)=="8100": #
829 Domoticz.Debug("ZigateRead - MsgType 8100 - Reception Real individual attribute response : " + Data)
830 Decode8100(self, MsgData, MsgRSSI)
831 return
832
833 elif str(MsgType)=="8101": # Default Response
834 Domoticz.Debug("ZigateRead - MsgType 8101 - Default Response: " + Data)
835 Decode8101(self, MsgData)
836 return
837
838 elif str(MsgType)=="8102": # Report Individual Attribute response
839 Domoticz.Debug("ZigateRead - MsgType 8102 - Report Individual Attribute response : " + Data)
840 Decode8102(self, MsgData, MsgRSSI)
841 return
842
843 elif str(MsgType)=="8110": #
844 Domoticz.Debug("ZigateRead - MsgType 8110 - Reception Write attribute response : " + Data)
845 return
846
847 elif str(MsgType)=="8120": #
848 Domoticz.Debug("ZigateRead - MsgType 8120 - Reception Configure reporting response : " + Data)
849 return
850
851 elif str(MsgType)=="8140": #
852 Domoticz.Debug("ZigateRead - MsgType 8140 - Reception Attribute discovery response : " + Data)
853 return
854
855 elif str(MsgType)=="8401": # Reception Zone status change notification
856 Domoticz.Debug("ZigateRead - MsgType 8401 - Reception Zone status change notification : " + Data)
857 Decode8401(self, MsgData)
858 return
859
860 elif str(MsgType)=="8701": #
861 Domoticz.Debug("ZigateRead - MsgType 8701 - Reception Router discovery confirm : " + Data)
862 Decode8701(self, MsgData)
863 return
864
865 elif str(MsgType)=="8702": # APS Data Confirm Fail
866 Domoticz.Debug("ZigateRead - MsgType 8702 - Reception APS Data confirm fail : " + Data)
867 Decode8702(self, MsgData)
868 return
869
870 else: # unknow or not dev function
871 Domoticz.Debug("ZigateRead - Unknow Message Type for : " + Data)
872 return
873
874 return
875
876def Decode004d(self, MsgData) : # Reception Device announce
877 MsgSrcAddr=MsgData[0:4]
878 MsgIEEE=MsgData[4:20]
879 MsgMacCapa=MsgData[20:22]
880 Domoticz.Debug("Decode004d - Reception Device announce : Source :" + MsgSrcAddr + ", IEEE : "+ MsgIEEE + ", Mac capa : " + MsgMacCapa)
881 # tester si le device existe deja dans la base domoticz
882 if DeviceExist(self, MsgSrcAddr)==False :
883 Domoticz.Debug("Decode004d - Looks like it is a new device sent by Zigate")
884 self.ListOfDevices[MsgSrcAddr]['MacCapa']=MsgMacCapa
885 self.ListOfDevices[MsgSrcAddr]['IEEE']=MsgIEEE
886 # Should we not force status to "004d" and reset Hearbeat , in order to start the processing from begining in onHeartbeat() ?
887 else :
888 Domoticz.Debug("Decode004d - Existing device")
889 # Should we not force status to "004d" and reset Hearbeat , in order to start the processing from begining in onHeartbeat() ?
890
891 return
892
893def Decode8000_v2(self, MsgData) : # Status
894 MsgLen=len(MsgData)
895 Domoticz.Debug("Decode8000_v2 - MsgData lenght is : " + str(MsgLen) + " out of 8")
896
897 if MsgLen != 8 :
898 return
899
900 Status=MsgData[0:2]
901 SEQ=MsgData[2:4]
902 PacketType=MsgData[4:8]
903
904 if Status=="00" : Status="Success"
905 elif Status=="01" : Status="Incorrect Parameters"
906 elif Status=="02" : Status="Unhandled Command"
907 elif Status=="03" : Status="Command Failed"
908 elif Status=="04" : Status="Busy"
909 elif Status=="05" : Status="Stack Already Started"
910 elif int(Status,16) >= 128 and int(Status,16) <= 244 : Status="ZigBee Error Code "+ DisplayStatusCode(Status)
911
912 Domoticz.Debug("Decode8000_v2 - status: " + Status + " SEQ: " + SEQ + " Packet Type: " + PacketType )
913
914 if PacketType=="0012" : Domoticz.Log("Erase Persistent Data cmd status : " + Status )
915 elif PacketType=="0014" : Domoticz.Log("Permit Join status : " + Status )
916 elif PacketType=="0024" : Domoticz.Log("Start Network status : " + Status )
917 elif PacketType=="0026" : Domoticz.Log("Remove Device cmd status : " + Status )
918 elif PacketType=="0044" : Domoticz.Log("request Power Descriptor status : " + Status )
919
920 if str(MsgData[0:2]) != "00" : Domoticz.Log("Decode8000_v2 - status: " + Status + " SEQ: " + SEQ + " Packet Type: " + PacketType )
921
922 return
923
924def Decode8000(self, MsgData) : # Reception status
925 MsgLen=len(MsgData)
926 Domoticz.Debug("Decode8000 - MsgData lenght is : " + str(MsgLen) + " out of 8")
927
928 MsgDataLenght=MsgData[0:4]
929 MsgDataStatus=MsgData[4:6]
930 if MsgDataStatus=="00" :
931 MsgDataStatus="Success"
932 elif MsgDataStatus=="01" :
933 MsgDataStatus="Incorrect Parameters"
934 elif MsgDataStatus=="02" :
935 MsgDataStatus="Unhandled Command"
936 elif MsgDataStatus=="03" :
937 MsgDataStatus="Command Failed"
938 elif MsgDataStatus=="04" :
939 MsgDataStatus="Busy"
940 elif MsgDataStatus=="05" :
941 MsgDataStatus="Stack Already Started"
942 else :
943 MsgDataStatus="ZigBee Error Code "+ MsgDataStatus
944 MsgDataSQN=MsgData[6:8]
945 #Correction Thiklop : MsgDataLenght n'est pas toujours un entier
946 #Encapsulation des 4 lignes dans un try except pour sortir proprement en testant le type de MsgDataLenght
947 try :
948 int(MsgDataLenght,16)
949 except :
950 Domoticz.Error("Decode8000 - Fonction Decode 8000 problème de MsgDataLenght, pas un int")
951 MsgDataMessage=""
952 else :
953 if int(MsgDataLenght,16) > 2 :
954 MsgDataMessage=MsgData[8:len(MsgData)]
955 else :
956 MsgDataMessage=""
957 #Fin de la correction
958 Domoticz.Debug("Decode8000 - Reception status : " + MsgDataStatus + ", SQN : " + MsgDataSQN + ", Message : " + MsgDataMessage)
959 return
960
961def Decode8001(self, MsgData) : # Reception log Level
962 MsgLen=len(MsgData)
963 Domoticz.Debug("Decode8001 - MsgData lenght is : " + str(MsgLen) + " out of 2" )
964
965 MsgLogLvl=MsgData[0:2]
966 MsgDataMessage=MsgData[2:len(MsgData)]
967 Domoticz.Debug("ZigateRead - MsgType 8001 - Reception log Level 0x: " + MsgLogLvl + "Message : " + MsgDataMessage)
968 return
969
970def Decode8009(self,MsgData) : # Network State response (Firm v3.0d)
971 MsgLen=len(MsgData)
972 Domoticz.Debug("Decode8009 - MsgData lenght is : " + str(MsgLen) + " out of 42")
973
974 addr=MsgData[0:4]
975 extaddr=MsgData[4:20]
976 PanID=MsgData[20:24]
977 extPanID=MsgData[24:40]
978 Channel=MsgData[40:42]
979 Domoticz.Debug("Decode8009: Network state - Address :" + addr + " extaddr :" + extaddr + " PanID : " + PanID + " Channel : " + Channel )
980 # from https://github.com/fairecasoimeme/ZiGate/issues/15 , if PanID == 0 -> Network is done
981 if str(PanID) == "0" :
982 Domoticz.Error("Decode8009: Network state DOWN ! " )
983 else :
984 Domoticz.Status("Decode8009: Network state UP - PAN Id = " + str(PanID) + " on Channel = " + Channel )
985
986 return
987
988def Decode8010(self,MsgData) : # Reception Version list
989 global FirmwareVersion
990 MsgLen=len(MsgData)
991 Domoticz.Debug("Decode8010 - MsgData lenght is : " + str(MsgLen) + " out of 8")
992
993
994 MajorVersNum=MsgData[0:4]
995 InstaVersNum=MsgData[4:8]
996 try :
997 Domoticz.Debug("Decode8010 - Reception Version list : " + MsgData)
998 Domoticz.Status("Major Version Num: " + MajorVersNum )
999 Domoticz.Status("Installer Version Number: " + InstaVersNum )
1000 except :
1001 Domoticz.Error("Decode8010 - Reception Version list : " + MsgData)
1002 else :
1003 FirmwareVersion = InstaVersNum
1004
1005 return
1006
1007def Decode8014(self,MsgData) : # "Permit Join" status response
1008 MsgLen=len(MsgData)
1009 Domoticz.Debug("Decode8014 - MsgData lenght is : " + str(MsgLen) + " out of 1")
1010
1011 Status=MsgData[0:1]
1012 if ( MsgData[0:1]== "0" ) : Domoticz.Status("Permit Join is Off")
1013 elif ( MsgData[0:1]== "1" ) : Domoticz.Status("Permit Join is On")
1014 else : Domoticz.Error("Decode8014 - Unexpected value "+str(MsgData))
1015 return
1016
1017
1018def Decode8015(self,MsgData) : # Get device list ( following request device list 0x0015 )
1019 # id: 2bytes
1020 # addr: 4bytes
1021 # ieee: 8bytes
1022 # power_type: 2bytes - 0 Battery, 1 AC Power
1023 # rssi : 2 bytes - Signal Strength between 1 - 255
1024 numberofdev=len(MsgData)
1025 Domoticz.Log("Decode8015 : Number of devices known in Zigate = " + str(round(numberofdev/26)) )
1026 idx=0
1027 while idx < (len(MsgData)):
1028 DevID=MsgData[idx:idx+2]
1029 saddr=MsgData[idx+2:idx+6]
1030 ieee=MsgData[idx+6:idx+22]
1031 power=MsgData[idx+22:idx+24]
1032 rssi=MsgData[idx+24:idx+26]
1033 Domoticz.Debug("Decode8015 : Dev ID = " + DevID + " addr = " + saddr + " ieee = " + ieee + " power = " + power + " RSSI = " + str(int(rssi,16)) )
1034 if saddr in self.ListOfDevices:
1035 Domoticz.Log("Decode8015 : [ " + str(round(idx/26)) + "] DevID = " + DevID + " Addr = " + saddr + " IEEE = " + ieee + " RSSI = " + str(int(rssi,16)) + " Power = " + power + " found in ListOfDevice")
1036 if rssi !="00" :
1037 self.ListOfDevices[saddr]['RSSI']= int(rssi,16)
1038 else :
1039 self.ListOfDevices[saddr]['RSSI']= 12
1040 Domoticz.Debug("Decode8015 : RSSI set to " + str( self.ListOfDevices[saddr]['RSSI']) + "/" + str(rssi) + " for " + str(saddr) )
1041 else:
1042 Domoticz.Log("Decode8015 : [ " + str(round(idx/26)) + "] DevID = " + DevID + " Addr = " + saddr + " IEEE = " + ieee + " not found in ListOfDevice")
1043 idx=idx+26
1044
1045 return
1046
1047def Decode8042(self, MsgData) : # Node Descriptor response
1048 MsgLen=len(MsgData)
1049 Domoticz.Debug("Decode8042 - MsgData lenght is : " + str(MsgLen) + " out of 34")
1050
1051 sequence=MsgData[0:2]
1052 status=MsgData[2:4]
1053 addr=MsgData[4:8]
1054 manufacturer=MsgData[8:12]
1055 max_rx=MsgData[12:16]
1056 max_tx=MsgData[16:20]
1057 server_mask=MsgData[20:24]
1058 descriptor_capability=MsgData[24:26]
1059 mac_capability=MsgData[26:28]
1060 max_buffer=MsgData[28:30]
1061 bit_field=MsgData[30:34]
1062 Domoticz.Debug("Decode8042 - Reception Node Descriptor : SEQ : " + sequence + " Status : " + status )
1063 return
1064
1065def Decode8043(self, MsgData) : # Reception Simple descriptor response
1066 MsgLen=len(MsgData)
1067 Domoticz.Debug("Decode8043 - MsgData lenght is : " + str(MsgLen) )
1068
1069 MsgDataSQN=MsgData[0:2]
1070 MsgDataStatus=MsgData[2:4]
1071 MsgDataShAddr=MsgData[4:8]
1072 MsgDataLenght=MsgData[8:10]
1073 Domoticz.Debug("Decode8043 - Reception Simple descriptor response : SQN : " + MsgDataSQN + ", Status : " + MsgDataStatus + ", short Addr : " + MsgDataShAddr + ", Lenght : " + MsgDataLenght)
1074 if self.ListOfDevices[MsgDataShAddr]['Status']!="inDB" :
1075 self.ListOfDevices[MsgDataShAddr]['Status']="8043"
1076 if int(MsgDataLenght,16)>0 :
1077 MsgDataEp=MsgData[10:12]
1078 MsgDataProfile=MsgData[12:16]
1079 self.ListOfDevices[MsgDataShAddr]['ProfileID']=MsgDataProfile
1080 MsgDataDeviceId=MsgData[16:20]
1081 self.ListOfDevices[MsgDataShAddr]['ZDeviceID']=MsgDataDeviceId
1082 MsgDataBField=MsgData[20:22]
1083 MsgDataInClusterCount=MsgData[22:24]
1084 Domoticz.Debug("Decode8043 - Reception Simple descriptor response : EP : " + MsgDataEp + ", Profile : " + MsgDataProfile + ", Device Id : " + MsgDataDeviceId + ", Bit Field : " + MsgDataBField)
1085 Domoticz.Debug("Decode8043 - Reception Simple descriptor response : In Cluster Count : " + MsgDataInClusterCount)
1086 i=1
1087 if int(MsgDataInClusterCount,16)>0 :
1088 while i <= int(MsgDataInClusterCount,16) :
1089 MsgDataCluster=MsgData[24+((i-1)*4):24+(i*4)]
1090 if MsgDataCluster not in self.ListOfDevices[MsgDataShAddr]['Ep'][MsgDataEp] :
1091 self.ListOfDevices[MsgDataShAddr]['Ep'][MsgDataEp][MsgDataCluster]={}
1092 Domoticz.Debug("Decode8043 - Reception Simple descriptor response : Cluster in: " + MsgDataCluster)
1093 MsgDataCluster=""
1094 i=i+1
1095
1096 MsgDataOutClusterCount=MsgData[24+(int(MsgDataInClusterCount,16)*4):26+(int(MsgDataInClusterCount,16)*4)]
1097 Domoticz.Debug("Decode8043 - Reception Simple descriptor response : Out Cluster Count : " + MsgDataOutClusterCount)
1098 i=1
1099 if int(MsgDataOutClusterCount,16)>0 :
1100 while i <= int(MsgDataOutClusterCount,16) :
1101 MsgDataCluster=MsgData[24+((i-1)*4):24+(i*4)]
1102 if MsgDataCluster not in self.ListOfDevices[MsgDataShAddr]['Ep'][MsgDataEp] :
1103 self.ListOfDevices[MsgDataShAddr]['Ep'][MsgDataEp][MsgDataCluster]={}
1104 Domoticz.Debug("Decode8043 - Reception Simple descriptor response : Cluster out: " + MsgDataCluster)
1105 MsgDataCluster=""
1106 i=i+1
1107 Domoticz.Debug("Decode8043 - Processed " + MsgDataShAddr + " end results is : " + str(self.ListOfDevices[MsgDataShAddr]) )
1108 return
1109
1110
1111def Decode8044(self, MsgData): # Power Descriptior response
1112 MsgLen=len(MsgData)
1113 SQNum=MsgData[0:2]
1114 Status=MsgData[2:4]
1115 PowerCode=MsgData[4:8]
1116 Domoticz.Debug("Decode8044 - SQNum = " +SQNum +" Status = " + Status + " Power Code = " + PowerCode )
1117 return
1118
1119def Decode8045(self, MsgData) : # Reception Active endpoint response
1120 MsgLen=len(MsgData)
1121 Domoticz.Debug("Decode8045 - MsgData lenght is : " + str(MsgLen) )
1122
1123 MsgDataSQN=MsgData[0:2]
1124 MsgDataStatus=MsgData[2:4]
1125 MsgDataShAddr=MsgData[4:8]
1126 MsgDataEpCount=MsgData[8:10]
1127 MsgDataEPlist=MsgData[10:len(MsgData)]
1128 Domoticz.Debug("Decode8045 - Reception Active endpoint response : SQN : " + MsgDataSQN + ", Status " + MsgDataStatus + ", short Addr " + MsgDataShAddr + ", EP count " + MsgDataEpCount + ", Ep list " + MsgDataEPlist)
1129 OutEPlist=""
1130 DeviceExist(self, MsgDataShAddr)
1131 #Correction Thiklop : MsgDataShAddr provoque un Keyerror (?)
1132 #Sortie propre par try except
1133 try :
1134 temp_sert_a_rien = self.ListOfDevices[MsgDataShAddr]['Status']!="inDB"
1135 except :
1136 Domoticz.Error("Decode8045 - KeyError : MsgDataShAddr = " + MsgDataShAddr)
1137 else :
1138 if self.ListOfDevices[MsgDataShAddr]['Status']!="inDB" :
1139 self.ListOfDevices[MsgDataShAddr]['Status']="8045"
1140 # PP: Does that mean that if we Device is already in the Database, we might overwrite 'EP' ?
1141 for i in MsgDataEPlist :
1142 OutEPlist+=i
1143 if len(OutEPlist)==2 :
1144 if OutEPlist not in self.ListOfDevices[MsgDataShAddr]['Ep'] :
1145 self.ListOfDevices[MsgDataShAddr]['Ep'][OutEPlist]={}
1146 OutEPlist=""
1147 #Fin de correction
1148 Domoticz.Debug("Decode8045 - Device : " + str(MsgDataShAddr) + " updated ListofDevices with " + str(self.ListOfDevices[MsgDataShAddr]['Ep']) )
1149 return
1150
1151def Decode8100(self, MsgData, MsgRSSI) : # Report Individual Attribute response
1152 try:
1153 MsgSQN=MsgData[0:2]
1154 MsgSrcAddr=MsgData[2:6]
1155 MsgSrcEp=MsgData[6:8]
1156 MsgClusterId=MsgData[8:12]
1157 MsgAttrID=MsgData[12:16]
1158 MsgAttType=MsgData[16:20]
1159 MsgAttSize=MsgData[20:24]
1160 MsgClusterData=MsgData[24:len(MsgData)]
1161 except:
1162 Domoticz.Error("Decode8100 - MsgData = " + MsgData)
1163
1164 else:
1165 Domoticz.Log("Decode8100 - reception data : " + MsgClusterData + " ClusterID : " + MsgClusterId + " Attribut ID : " + MsgAttrID + " Src Addr : " + MsgSrcAddr + " Scr Ep: " + MsgSrcEp + " RSSI: " + MsgRSSI)
1166 try :
1167 self.ListOfDevices[MsgSrcAddr]['RSSI']= int(MsgRSSI,16)
1168 except :
1169 self.ListOfDevices[MsgSrcAddr]['RSSI']= 0
1170 Domoticz.Debug("Decode8015 : RSSI set to " + str( self.ListOfDevices[MsgSrcAddr]['RSSI']) + "/" + str(MsgRSSI) + " for " + str(MsgSrcAddr) )
1171 ReadCluster(self, MsgData)
1172 return
1173
1174
1175def Decode8101(self, MsgData) : # Default Response
1176 MsgDataSQN=MsgData[0:2]
1177 MsgDataEp=MsgData[2:4]
1178 MsgClusterId=MsgData[4:8]
1179 MsgDataCommand=MsgData[8:10]
1180 MsgDataStatus=MsgData[10:12]
1181 Domoticz.Debug("Decode8101 - reception Default response : SQN : " + MsgDataSQN + ", EP : " + MsgDataEp + ", Cluster ID : " + MsgClusterId + " , Command : " + MsgDataCommand+ ", Status : " + MsgDataStatus)
1182 return
1183
1184def Decode8102(self, MsgData, MsgRSSI) : # Report Individual Attribute response
1185 MsgSQN=MsgData[0:2]
1186 MsgSrcAddr=MsgData[2:6]
1187 MsgSrcEp=MsgData[6:8]
1188 MsgClusterId=MsgData[8:12]
1189 MsgAttrID=MsgData[12:16]
1190 MsgAttType=MsgData[16:20]
1191 MsgAttSize=MsgData[20:24]
1192 MsgClusterData=MsgData[24:len(MsgData)]
1193 Domoticz.Debug("Decode8102 - reception data : " + MsgClusterData + " ClusterID : " + MsgClusterId + " Attribut ID : " + MsgAttrID + " Src Addr : " + MsgSrcAddr + " Scr Ep: " + MsgSrcEp + " RSSI = " + MsgRSSI )
1194 if MsgSrcAddr in self.ListOfDevices:
1195 try:
1196 self.ListOfDevices[MsgSrcAddr]['RSSI']= int(MsgRSSI,16)
1197 except:
1198 self.ListOfDevices[MsgSrcAddr]['RSSI']= 0
1199 Domoticz.Debug("Decode8015 : RSSI set to " + str( self.ListOfDevices[MsgSrcAddr]['RSSI']) + "/" + str(MsgRSSI) + " for " + str(MsgSrcAddr) )
1200 ReadCluster(self, MsgData)
1201 else :
1202 Domoticz.Error("Decode8102 - Receiving a message from unknown device : " + str(MsgSrcAddr) + " with Data : " +str(MsgData) )
1203 return
1204
1205def Decode8701(self, MsgData) : # Reception Router Disovery Confirm Status
1206 MsgLen=len(MsgData)
1207 Domoticz.Debug("Decode8701 - MsgLen = " + str(MsgLen))
1208
1209 if MsgLen==0 :
1210 return
1211 else:
1212 MsgStatus=MsgData[0:2]
1213 NwkStatus=MsgData[2:4]
1214 Domoticz.Debug("Decode8701 - Reception Router Discovery Confirm Status:" + MsgStatus + ", Nwk Status : "+ NwkStatus )
1215
1216 if NwkStatus != "00" : Domoticz.Error("Decode8701 - Reception Router Discovery Confirm Status:" + DisplayStatusCode( NwkStatus) + ", Nwk Status : "+ NwkStatus )
1217 return
1218
1219def Decode8702(self, MsgData) : # Reception APS Data confirm fail
1220 MsgLen=len(MsgData)
1221 Domoticz.Debug("Decode8702 - MsgLen = " + str(MsgLen))
1222 if MsgLen==0 :
1223 return
1224 else:
1225 MsgDataStatus=MsgData[0:2]
1226 MsgDataSrcEp=MsgData[2:4]
1227 MsgDataDestEp=MsgData[4:6]
1228 MsgDataDestMode=MsgData[6:8]
1229 MsgDataDestAddr=MsgData[8:12]
1230 MsgDataSQN=MsgData[12:14]
1231 Domoticz.Debug("Decode 8702 - " + DisplayStatusCode( MsgDataStatus ) + ", SrcEp : " + MsgDataSrcEp + ", DestEp : " + MsgDataDestEp + ", DestMode : " + MsgDataDestMode + ", DestAddr : " + MsgDataDestAddr + ", SQN : " + MsgDataSQN)
1232 return
1233
1234def Decode8401(self, MsgData) : # Reception Zone status change notification
1235 Domoticz.Debug("Decode8401 - Reception Zone status change notification : " + MsgData)
1236 MsgSrcAddr=MsgData[10:14]
1237 MsgSrcEp=MsgData[2:4]
1238 MsgClusterData=MsgData[16:18]
1239 MajDomoDevice(self, MsgSrcAddr, MsgSrcEp, "0006", MsgClusterData)
1240 return
1241
1242def CreateDomoDevice(self, DeviceID) :
1243 for Ep in self.ListOfDevices[DeviceID]['Ep'] :
1244 if self.ListOfDevices[DeviceID]['Type']== {} :
1245 Type=GetType(self, DeviceID, Ep).split("/")
1246 Domoticz.Log("CreateDomoDevice - Type via GetType: " + str(Type) + " Ep : " + str(Ep) )
1247 else :
1248 Type=self.ListOfDevices[DeviceID]['Type'].split("/")
1249 Domoticz.Log("CreateDomoDevice - Type : '" + str(Type) + "'")
1250
1251 if Type !="" :
1252 if "Humi" in Type and "Temp" in Type and "Baro" in Type:
1253 t="Temp+Hum+Baro" # Detecteur temp + Hum + Baro
1254 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=FreeUnit(self), TypeName=t, Options={"Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}).Create()
1255 if "Humi" in Type and "Temp" in Type :
1256 t="Temp+Hum"
1257 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=FreeUnit(self), TypeName=t, Options={"Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}).Create()
1258
1259 #For color Bulb
1260 if ("Switch" in Type) and ("LvlControl" in Type) and ("ColorControl" in Type):
1261 Type = ['ColorControl']
1262 elif ("Switch" in Type) and ("LvlControl" in Type):
1263 Type = ['LvlControl']
1264
1265
1266 for t in Type :
1267 Domoticz.Log("CreateDomoDevice - Device ID : " + str(DeviceID) + " Device EP : " + str(Ep) + " Type : " + str(t) )
1268 if t=="Temp" : # Detecteur temp
1269 self.ListOfDevices[DeviceID]['Status']="inDB"
1270 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=FreeUnit(self), TypeName="Temperature", Options={"Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}).Create()
1271
1272 if t=="Humi" : # Detecteur hum
1273 self.ListOfDevices[DeviceID]['Status']="inDB"
1274 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=FreeUnit(self), TypeName="Humidity", Options={"Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}).Create()
1275
1276 if t=="Baro" : # Detecteur Baro
1277 self.ListOfDevices[DeviceID]['Status']="inDB"
1278 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=FreeUnit(self), TypeName="Barometer", Options={"Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}).Create()
1279
1280 if t=="Door": # capteur ouverture/fermeture xiaomi
1281 self.ListOfDevices[DeviceID]['Status']="inDB"
1282 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=FreeUnit(self), Type=244, Subtype=73 , Switchtype=2 , Options={"Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}).Create()
1283
1284 if t=="Motion" : # detecteur de presence
1285 self.ListOfDevices[DeviceID]['Status']="inDB"
1286 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=FreeUnit(self), Type=244, Subtype=73 , Switchtype=8 , Options={"Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}).Create()
1287
1288 if t=="MSwitch" : # interrupteur multi lvl 86sw2 xiaomi
1289 self.ListOfDevices[DeviceID]['Status']="inDB"
1290 Options = {"LevelActions": "||||", "LevelNames": "Push|1 Click|2 Click|3 Click|4 Click", "LevelOffHidden": "false", "SelectorStyle": "0","Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}
1291 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=FreeUnit(self), Type=244, Subtype=62 , Switchtype=18, Options = Options).Create()
1292
1293 if t=="DSwitch" : # interrupteur double sur EP different
1294 self.ListOfDevices[DeviceID]['Status']="inDB"
1295 Options = {"LevelActions": "|||", "LevelNames": "Off|Left Click|Right Click|Both Click", "LevelOffHidden": "true", "SelectorStyle": "0","Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}
1296 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=FreeUnit(self), Type=244, Subtype=62 , Switchtype=18, Options = Options).Create()
1297
1298 if t=="DButton" : # interrupteur double sur EP different
1299 self.ListOfDevices[DeviceID]['Status']="inDB"
1300 Options = {"LevelActions": "|||", "LevelNames": "Off|Left Click|Right Click|Both Click", "LevelOffHidden": "true", "SelectorStyle": "0","Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}
1301 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=FreeUnit(self), Type=244, Subtype=62 , Switchtype=18, Options = Options).Create()
1302
1303 if t=="Smoke" : # detecteur de fumee
1304 self.ListOfDevices[DeviceID]['Status']="inDB"
1305 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=FreeUnit(self), Type=244, Subtype=73 , Switchtype=5 , Options={"Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}).Create()
1306
1307 if t=="Lux" : # Lux sensors
1308 self.ListOfDevices[DeviceID]['Status']="inDB"
1309 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=FreeUnit(self), Type=246, Subtype=1 , Switchtype=0 , Options={"Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}).Create()
1310
1311 if t=="Switch": # inter sans fils 1 touche 86sw1 xiaomi
1312 self.ListOfDevices[DeviceID]['Status']="inDB"
1313 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=FreeUnit(self), Type=244, Subtype=73 , Switchtype=0 , Options={"Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}).Create()
1314
1315 if t=="Button": # inter sans fils 1 touche 86sw1 xiaomi
1316 self.ListOfDevices[DeviceID]['Status']="inDB"
1317 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=FreeUnit(self), Type=244, Subtype=73 , Switchtype=9 , Options={"Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}).Create()
1318
1319 if t=="Aqara" or t=="XCube" : # Xiaomi Magic Cube
1320 self.ListOfDevices[DeviceID]['Status']="inDB"
1321 Options = {"LevelActions": "|||||||||", "LevelNames": "Off|Shake|Wakeup|Drop|90°|180°|Push|Tap", "LevelOffHidden": "true", "SelectorStyle": "0","Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}
1322 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=FreeUnit(self), Type=244, Subtype=62 , Switchtype=18, Options = Options).Create()
1323
1324 if t=="Water" : # detecteur d'eau
1325 self.ListOfDevices[DeviceID]['Status']="inDB"
1326 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=FreeUnit(self), Type=244, Subtype=73 , Switchtype=0 , Image=11 , Options={"Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}).Create()
1327
1328 if t=="Plug" : # prise pilote
1329 self.ListOfDevices[DeviceID]['Status']="inDB"
1330 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=FreeUnit(self), Type=244, Subtype=73 , Switchtype=0 , Image=1 , Options={"Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}).Create()
1331
1332 if t=="LvlControl" and self.ListOfDevices[DeviceID]['Model']=="shutter.Profalux" : # Volet Roulant / Shutter / Blinds, let's created blindspercentageinverted devic
1333 self.ListOfDevices[DeviceID]['Status']="inDB"
1334 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=FreeUnit(self), Type=244, Subtype=73, Switchtype=16 , Options={"Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}).Create()
1335
1336 if t=="LvlControl" and self.ListOfDevices[DeviceID]['Model']!="shutter.Profalux" : # variateur de luminosite + On/off
1337 self.ListOfDevices[DeviceID]['Status']="inDB"
1338 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=FreeUnit(self), Type=244, Subtype=73, Switchtype=7 , Options={"Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}).Create()
1339
1340 if t=="ColorControl" : # variateur de couleur/luminosite/on-off
1341 self.ListOfDevices[DeviceID]['Status']="inDB"
1342 # Type 0xF1 pTypeColorSwitch
1343
1344 # SubType 0x07 sTypeColor_RGB_CW_WW_Z
1345 # SubType 0x02 sTypeColor_RGB
1346 # SubType 0x08 sTypeColor_CW_WW
1347
1348 # Switchtype 7 STYPE_Dimmer
1349
1350 if self.ListOfDevices[DeviceID]['Model'] == "Ampoule.LED1624G9.Tradfri":
1351 Subtype_ = 2
1352 if self.ListOfDevices[DeviceID]['Model'] == "Ampoule.LED1545G12.Tradfri":
1353 Subtype_ = 8
1354 else:
1355 Subtype_ = 7
1356
1357 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=FreeUnit(self), Type=241, Subtype=Subtype_ , Switchtype=7 , Options={"Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}).Create()
1358
1359 #Ajout meter
1360 if t=="PowerMeter" : # Power Prise Xiaomi
1361 Domoticz.Debug("Ajout Meter")
1362 self.ListOfDevices[DeviceID]['Status']="inDB"
1363 Domoticz.Device(DeviceID=str(DeviceID),Name=str(t) + " - " + str(DeviceID), Unit=len(Devices)+1, TypeName="Usage" , Options={"Zigate":str(self.ListOfDevices[DeviceID]), "TypeName":t}).Create()
1364
1365#def UpdateDomoDevice(self, DeviceID) :
1366# IEEEexist=False
1367# x=0
1368# for x in Devices:
1369# DOptions = Devices[x].Options
1370# Dzigate=eval(DOptions['Zigate'])
1371# if Dzigate['IEEE']==self.ListOfDevices[DeviceID]['IEEE'] :
1372# Domoticz.Debug("HearBeat - Devices IEEE already exist. Unit=" + str(x))
1373# Devices[x].Update(nValue=Devices[x].nValue, sValue=str(Devices[x].sValue), DeviceID=str(DeviceID))
1374
1375
1376
1377def FreeUnit(self) :
1378 FreeUnit=""
1379 for x in range(1,256):
1380 Domoticz.Debug("FreeUnit - is device " + str(x) + " exist ?")
1381 if x not in Devices :
1382 Domoticz.Debug("FreeUnit - device " + str(x) + " not exist")
1383 FreeUnit=x
1384 return FreeUnit
1385 if FreeUnit =="" :
1386 FreeUnit=len(Devices)+1
1387 Domoticz.Debug("FreeUnit - Free Device Unit find : " + str(x))
1388 return FreeUnit
1389
1390def MajDomoDevice(self,DeviceID,Ep,clusterID,value,Color_='') :
1391 Domoticz.Log("MajDomoDevice - Device ID : " + str(DeviceID) + " - Device EP : " + str(Ep) + " - Type : " + str(clusterID) + " - Value : " + str(value) + " - Hue : " + str(Color_))
1392 x=0
1393 Type=TypeFromCluster(clusterID)
1394 Domoticz.Log("MajDomoDevice - Type = " + str(Type) )
1395 for x in Devices:
1396 if Devices[x].DeviceID == str(DeviceID) :
1397 DOptions = Devices[x].Options
1398 Dtypename=DOptions['TypeName']
1399 DOptions['Zigate']=str(self.ListOfDevices[DeviceID])
1400 SignalLevel = self.ListOfDevices[DeviceID]['RSSI']
1401
1402 Domoticz.Log("MajDomoDevice - Dtypename = " + str(Dtypename) )
1403
1404 if Dtypename=="Temp+Hum+Baro" : #temp+hum+Baro xiaomi
1405 Bar_forecast = '0' # Set barometer forecast to 0 (No info)
1406 if Type=="Temp" :
1407 CurrentnValue=Devices[x].nValue
1408 CurrentsValue=Devices[x].sValue
1409 Domoticz.Debug("MajDomoDevice temp CurrentsValue : " + CurrentsValue)
1410 SplitData=CurrentsValue.split(";")
1411 NewSvalue='%s;%s;%s;%s;%s' % (str(value), SplitData[1] , SplitData[2] , SplitData[3], Bar_forecast)
1412 Domoticz.Debug("MajDomoDevice temp NewSvalue : " + NewSvalue)
1413 #UpdateDevice(x,0,str(NewSvalue),DOptions)
1414 UpdateDevice_v2(x,0,str(NewSvalue),DOptions, SignalLevel)
1415 if Type=="Humi" :
1416 CurrentnValue=Devices[x].nValue
1417 CurrentsValue=Devices[x].sValue
1418 Domoticz.Debug("MajDomoDevice hum CurrentsValue : " + CurrentsValue)
1419 SplitData=CurrentsValue.split(";")
1420 NewSvalue='%s;%s;%s;%s;%s' % (SplitData[0], str(value) , SplitData[2] , SplitData[3], Bar_forecast)
1421 Domoticz.Debug("MajDomoDevice hum NewSvalue : " + NewSvalue)
1422 #UpdateDevice(x,0,str(NewSvalue),DOptions)
1423 UpdateDevice_v2(x,0,str(NewSvalue),DOptions, SignalLevel)
1424 if Type=="Baro" : # barometer
1425 CurrentnValue=Devices[x].nValue
1426 CurrentsValue=Devices[x].sValue
1427 Domoticz.Debug("MajDomoDevice baro CurrentsValue : " + CurrentsValue)
1428 SplitData=CurrentsValue.split(";")
1429 valueBaro='%s;%s;%s;%s;%s' % (SplitData[0], SplitData[1], str(value) , SplitData[3], Bar_forecast)
1430 #UpdateDevice(x,0,str(valueBaro),DOptions)
1431 UpdateDevice_v2(x,0,str(valueBaro),DOptions, SignalLevel)
1432 if Dtypename=="Temp+Hum" : #temp+hum xiaomi
1433 if Type=="Temp" :
1434 CurrentnValue=Devices[x].nValue
1435 CurrentsValue=Devices[x].sValue
1436 Domoticz.Debug("MajDomoDevice temp CurrentsValue : " + CurrentsValue)
1437 SplitData=CurrentsValue.split(";")
1438 NewSvalue='%s;%s;%s' % (str(value), SplitData[1] , SplitData[2])
1439 Domoticz.Debug("MajDomoDevice temp NewSvalue : " + NewSvalue)
1440 #UpdateDevice(x,0,str(NewSvalue),DOptions)
1441 UpdateDevice_v2(x,0,str(NewSvalue),DOptions, SignalLevel)
1442 if Type=="Humi" :
1443 CurrentnValue=Devices[x].nValue
1444 CurrentsValue=Devices[x].sValue
1445 Domoticz.Debug("MajDomoDevice hum CurrentsValue : " + CurrentsValue)
1446 SplitData=CurrentsValue.split(";")
1447 NewSvalue='%s;%s;%s' % (SplitData[0], str(value) , SplitData[2])
1448 Domoticz.Debug("MajDomoDevice hum NewSvalue : " + NewSvalue)
1449 #UpdateDevice(x,0,str(NewSvalue),DOptions)
1450 UpdateDevice_v2(x,0,str(NewSvalue),DOptions, SignalLevel)
1451 if Type==Dtypename=="Temp" : # temperature
1452 #UpdateDevice(x,0,str(value),DOptions)
1453 UpdateDevice_v2(x,0,str(value),DOptions, SignalLevel)
1454 if Type==Dtypename=="Humi" : # humidite
1455 #UpdateDevice(x,int(value),"0",DOptions)
1456 UpdateDevice_v2(x,int(value),"0",DOptions, SignalLevel)
1457 if Type==Dtypename=="Baro" : # barometre
1458 CurrentnValue=Devices[x].nValue
1459 CurrentsValue=Devices[x].sValue
1460 Domoticz.Debug("MajDomoDevice baro CurrentsValue : " + CurrentsValue)
1461 SplitData=CurrentsValue.split(";")
1462 valueBaro='%s;%s' % (value,SplitData[0])
1463 #UpdateDevice(x,0,str(valueBaro),DOptions)
1464 UpdateDevice_v2(x,0,str(valueBaro),DOptions, SignalLevel)
1465 if Type=="Switch" and Dtypename=="Door" : # porte / fenetre
1466 if value == "01" :
1467 state="Open"
1468 #Correction Thiklop : value n'est pas toujours un entier. Exécution de l'updatedevice dans le test
1469 #UpdateDevice(x,int(value),str(state),DOptions)
1470 UpdateDevice_v2(x,int(value),str(state),DOptions, SignalLevel)
1471 elif value == "00" :
1472 state="Closed"
1473 #Correction Thiklop : idem
1474 #UpdateDevice(x,int(value),str(state),DOptions)
1475 UpdateDevice_v2(x,int(value),str(state),DOptions, SignalLevel)
1476 #Fin de la correction
1477 if Type==Dtypename=="Switch" : # switch simple
1478 if value == "01" :
1479 state="On"
1480 elif value == "00" :
1481 state="Off"
1482 #UpdateDevice(x,int(value),str(state),DOptions)
1483 UpdateDevice_v2(x,int(value),str(state),DOptions, SignalLevel)
1484 if value == "01" :
1485 state="Open"
1486 elif value == "00" :
1487 state="Closed"
1488 UpdateDevice(x,int(value),str(state),DOptions)
1489 #UpdateDevice_v2(x,int(value),str(state),DOptions, SignalLevel)
1490 if Type=="Switch" and Dtypename=="Button": # boutton simple
1491 if value == "01" :
1492 state="On"
1493 #UpdateDevice(x,int(value),str(state),DOptions)
1494 UpdateDevice_v2(x,int(value),str(state),DOptions, SignalLevel)
1495 else:
1496 return
1497 if Type=="Switch" and Dtypename=="Water" : # detecteur d eau
1498 if value == "01" :
1499 state="On"
1500 elif value == "00" :
1501 state="Off"
1502 #UpdateDevice(x,int(value),str(state),DOptions)
1503 UpdateDevice_v2(x,int(value),str(state),DOptions, SignalLevel)
1504 if Type=="Switch" and Dtypename=="Smoke" : # detecteur de fume
1505 if value == "01" :
1506 state="On"
1507 elif value == "00" :
1508 state="Off"
1509 #UpdateDevice(x,int(value),str(state),DOptions)
1510 UpdateDevice_v2(x,int(value),str(state),DOptions, SignalLevel)
1511 if Type=="Switch" and Dtypename=="MSwitch" : # multi lvl switch
1512 if value == "00" :
1513 state="00"
1514 elif value == "01" :
1515 state="10"
1516 elif value == "02" :
1517 state="20"
1518 elif value == "03" :
1519 state="30"
1520 elif value == "04" :
1521 state="40"
1522 else :
1523 state="0"
1524 #UpdateDevice(x,int(value),str(state),DOptions)
1525 UpdateDevice_v2(x,int(value),str(state),DOptions, SignalLevel)
1526 if Type=="Switch" and Dtypename=="DSwitch" : # double switch avec EP different ====> a voir pour passer en deux switch simple ... a corriger/modifier
1527 if Ep == "01" :
1528 if value == "01" or value =="00" :
1529 state="10"
1530 data="01"
1531 elif Ep == "02" :
1532 if value == "01" or value =="00":
1533 state="20"
1534 data="02"
1535 elif Ep == "03" :
1536 if value == "01" or value =="00" :
1537 state="30"
1538 data="03"
1539 #UpdateDevice(x,int(data),str(state),DOptions)
1540 UpdateDevice_v2(x,int(data),str(state),DOptions, SignalLevel)
1541 if Type=="Switch" and Dtypename=="DButton" : # double bouttons avec EP different ====> a voir pour passer en deux bouttons simple ... idem DSwitch ???
1542 if Ep == "01" :
1543 if value == "01" or value =="00" :
1544 state="10"
1545 data="01"
1546 elif Ep == "02" :
1547 if value == "01" or value =="00":
1548 state="20"
1549 data="02"
1550 elif Ep == "03" :
1551 if value == "01" or value =="00" :
1552 state="30"
1553 data="03"
1554 #UpdateDevice(x,int(data),str(state),DOptions)
1555 UpdateDevice_v2(x,int(data),str(state),DOptions, SignalLevel)
1556
1557 if Type=="XCube" and Dtypename=="Aqara" and Ep == "02": #Magic Cube Acara
1558 Domoticz.Debug("MajDomoDevice - XCube update device with data = " + str(value) )
1559 UpdateDevice_v2( x, int(value), str(value), DOptions, SignalLevel )
1560 if Type=="XCube" and Dtypename=="Aqara" and Ep == "03": #Magic Cube Acara Rotation
1561 Domoticz.Debug("MajDomoDevice - XCube update device with data = " + str(value) )
1562 UpdateDevice_v2( x, int(value), str(value), DOptions, SignalLevel )
1563
1564 if Type==Dtypename=="XCube" and Ep == "02": # cube xiaomi
1565 if value == "0000" : #shake
1566 state="10"
1567 data="01"
1568 UpdateDevice(x,int(data),str(state),DOptions)
1569 elif value == "0204" or value == "0200" or value == "0203" or value == "0201" or value == "0202" or value == "0205": #tap
1570 state="50"
1571 data="05"
1572 UpdateDevice(x,int(data),str(state),DOptions)
1573 elif value == "0103" or value == "0100" or value == "0104" or value == "0101" or value == "0102" or value == "0105": #Slide
1574 state="20"
1575 data="02"
1576 UpdateDevice(x,int(data),str(state),DOptions)
1577 elif value == "0003" : #Free Fall
1578 state="70"
1579 data="07"
1580 UpdateDevice(x,int(data),str(state),DOptions)
1581 elif value >= "0004" and value <= "0059": #90°
1582 state="30"
1583 data="03"
1584 UpdateDevice(x,int(data),str(state),DOptions)
1585 elif value >= "0060" : #180°
1586 state="90"
1587 data="09"
1588 UpdateDevice(x,int(data),str(state),DOptions)
1589
1590 if Type==Dtypename=="Lux" :
1591 #UpdateDevice(x,0,str(value),DOptions)
1592 UpdateDevice_v2(x,0,str(value),DOptions, SignalLevel)
1593 if Type==Dtypename=="Motion" :
1594 #Correction Thiklop : value pas toujours un entier :
1595 #'onMessage' failed 'ValueError':'invalid literal for int() with base 10: '00031bd000''.
1596 # UpdateDevice dans le if
1597 if value == "01" :
1598 state="On"
1599 UpdateDevice(x,int(value),str(state),DOptions)
1600 #UpdateDevice_v2(x,int(value),str(state),DOptions, SignalLevel)
1601 elif value == "00" :
1602 state="Off"
1603 UpdateDevice(x,int(value),str(state),DOptions)
1604 #UpdateDevice_v2(x,int(value),str(state),DOptions, SignalLevel)
1605 #Fin de correction
1606
1607 if Type==Dtypename=="LvlControl" :
1608 try:
1609 sValue = round((int(value,16)/255)*100)
1610 except:
1611 Domoticz.Error("MajDomoDevice - value is not an int = " + str(value) )
1612 else:
1613 Domoticz.Debug("MajDomoDevice LvlControl - DvID : " + str(DeviceID) + " - Device EP : " + str(Ep) + " - Value : " + str(sValue) + " sValue : " + str(Devices[x].sValue) )
1614
1615 nValue = 2
1616
1617 if str(nValue) != str(Devices[x].nValue) or str(sValue) != str(Devices[x].sValue) :
1618 Domoticz.Debug("MajDomoDevice update DevID : " + str(DeviceID) + " from " + str(Devices[x].nValue) + " to " + str(nValue) )
1619 #UpdateDevice(x, str(nValue), str(sValue) ,DOptions)
1620 UpdateDevice_v2(x, str(nValue), str(sValue) ,DOptions, SignalLevel)
1621
1622 if Type==Dtypename=="ColorControl" :
1623 try:
1624 sValue = round((int(value,16)/255)*100)
1625 except:
1626 Domoticz.Error("MajDomoDevice - value is not an int = " + str(value) )
1627 else:
1628 Domoticz.Debug("MajDomoDevice ColorControl - DvID : " + str(DeviceID) + " - Device EP : " + str(Ep) + " - Value : " + str(sValue) + " sValue : " + str(Devices[x].sValue) )
1629
1630 nValue = 2
1631
1632 if str(nValue) != str(Devices[x].nValue) or str(sValue) != str(Devices[x].sValue) or str(Color_) != str(Devices[x].Color):
1633 Domoticz.Debug("MajDomoDevice update DevID : " + str(DeviceID) + " from " + str(Devices[x].nValue) + " to " + str(nValue))
1634 Domoticz.Debug("MajDomoDevice update DevID : " + str(DeviceID) + " from " + str(Devices[x].Color) + " to " + str(Color_))
1635 #UpdateDevice(x, str(nValue), str(sValue) ,DOptions)
1636 UpdateDevice_v2(x, str(nValue), str(sValue) ,DOptions, SignalLevel, Color_)
1637
1638
1639 #Modif Meter
1640 if clusterID=="000c" and Type != "XCube":
1641 # Problem with such value: Update Value Meter : 3247660071
1642 Domoticz.Log("Update Value Meter : "+str(int(value,16)))
1643 Domoticz.Log("Update Value Meter : "+str(round(struct.unpack('f',struct.pack('i',int(value,16)))[0])))
1644 UpdateDevice(x,0,str(round(struct.unpack('f',struct.pack('i',int(value,16)))[0])),DOptions)
1645 #UpdateDevice_v2(x,0,str(round(struct.unpack('f',struct.pack('i',int(value,16)))[0])),DOptions, SignalLevel)
1646
1647def ResetDevice(Type,HbCount) :
1648 x=0
1649 for x in Devices:
1650 try :
1651 LUpdate=Devices[x].LastUpdate
1652 LUpdate=time.mktime(time.strptime(LUpdate,"%Y-%m-%d %H:%M:%S"))
1653 current = time.time()
1654 DOptions = Devices[x].Options
1655 Dtypename=DOptions['TypeName']
1656 if (current-LUpdate)> 30 :
1657 if Dtypename=="Motion":
1658 value = "00"
1659 state="Off"
1660 #Devices[x].Update(nValue = int(value),sValue = str(state))
1661 UpdateDevice(x,int(value),str(state),DOptions)
1662 except :
1663 return
1664def IEEEExist(self, IEEE) :
1665 #check in ListOfDevices for an existing IEEE
1666 if IEEE :
1667 if IEEE in self.ListOfDevices and IEEE != '' :
1668 return True
1669 else:
1670 return False
1671
1672def DeviceExist(self, Addr) :
1673 #check in ListOfDevices
1674 if Addr in self.ListOfDevices and Addr != '' :
1675 if 'Status' in self.ListOfDevices[Addr] :
1676 return True
1677 else :
1678 initDeviceInList(self, Addr)
1679 return False
1680 else : # devices inconnu ds listofdevices et ds db
1681 initDeviceInList(self, Addr)
1682 return False
1683
1684def initDeviceInList(self, Addr) :
1685 if Addr != '' :
1686 self.ListOfDevices[Addr]={}
1687 self.ListOfDevices[Addr]['Ep']={}
1688 self.ListOfDevices[Addr]['Status']="004d"
1689 self.ListOfDevices[Addr]['Heartbeat']="0"
1690 self.ListOfDevices[Addr]['RIA']="0"
1691 self.ListOfDevices[Addr]['RSSI']={}
1692 self.ListOfDevices[Addr]['Battery']={}
1693 self.ListOfDevices[Addr]['Model']={}
1694 self.ListOfDevices[Addr]['MacCapa']={}
1695 self.ListOfDevices[Addr]['IEEE']={}
1696 self.ListOfDevices[Addr]['Type']={}
1697 self.ListOfDevices[Addr]['ProfileID']={}
1698 self.ListOfDevices[Addr]['ZDeviceID']={}
1699
1700def getChecksum(msgtype,length,datas) :
1701 temp = 0 ^ int(msgtype[0:2],16)
1702 temp ^= int(msgtype[2:4],16)
1703 temp ^= int(length[0:2],16)
1704 temp ^= int(length[2:4],16)
1705 for i in range(0,len(datas),2) :
1706 temp ^= int(datas[i:i+2],16)
1707 chk=hex(temp)
1708 Domoticz.Debug("getChecksum - Checksum : " + str(chk))
1709 return chk[2:4]
1710
1711def UpdateSignalLevel( DeviceID, SignalLvl) :
1712 x=0
1713 for x in Devices:
1714 if Devices[x].DeviceID == str(DeviceID):
1715 Domoticz.Debug("Update Signal Level for Devices Unit=" + str(x) + " DeviceID = " + str(DeviceID) + " with level = " + str(SignalLvl) )
1716 CurrentnValue=Devices[x].nValue
1717 CurrentsValue=Devices[x].sValue
1718 CurrentsOptions=Devices[x].Options
1719 rssi= round( (SignalLvl * 12 ) / 200) # Should be 255, but there is no chance to have 255 !
1720 Domoticz.Debug("Update Signal Level for Devices Unit=" + str(x) + " DeviceID = " + str(DeviceID) + " with level = " + str(SignalLvl) + " RSSI = " + str(rssi) )
1721 Devices[x].Update(nValue=int(CurrentnValue), sValue=str(CurrentsValue), Options=str(CurrentsOptions), SignalLevel=int(rssi) )
1722 return
1723
1724def UpdateBattery(DeviceID,BatteryLvl):
1725 x=0
1726 found=False
1727 for x in Devices:
1728 if Devices[x].DeviceID == str(DeviceID):
1729 found==True
1730 Domoticz.Log("Devices exist in DB. Unit=" + str(x))
1731 CurrentnValue=Devices[x].nValue
1732 Domoticz.Log("CurrentnValue = " + str(CurrentnValue))
1733 CurrentsValue=Devices[x].sValue
1734 Domoticz.Log("CurrentsValue = " + str(CurrentsValue))
1735 Domoticz.Log("BatteryLvl = " + str(BatteryLvl))
1736 Devices[x].Update(nValue = int(CurrentnValue),sValue = str(CurrentsValue), BatteryLevel = BatteryLvl )
1737 if found==False :
1738 self.ListOfDevices[DeviceID]['Status']="004d"
1739 self.ListOfDevices[DeviceID]['Battery']=BatteryLvl
1740
1741
1742def UpdateDevice_v2(Unit, nValue, sValue, Options, SignalLvl, Color_ = ''):
1743 # V2 update Domoticz with SignaleLevel/RSSI
1744 Domoticz.Debug("UpdateDevice_v2 - Options = " + str(Options))
1745 Dzigate=eval(Options['Zigate'])
1746
1747 Domoticz.Debug("UpdateDevice_v2 for : " + str(Unit) + " Signal Level = " + str(SignalLvl) )
1748 if isinstance(SignalLvl,int) :
1749 rssi= round( (SignalLvl * 12 ) / 255)
1750 Domoticz.Debug("UpdateDevice_v2 for : " + str(Unit) + " RSSI = " + str(rssi) )
1751 else:
1752 Domoticz.Debug("UpdateDevice_v2 for : " + str(Unit) + " SignalLvl is not an int" )
1753 rssi=12
1754
1755 BatteryLvl=str(Dzigate['Battery'])
1756 if BatteryLvl == '{}' :
1757 BatteryLvl=255
1758 Domoticz.Debug("UpdateDevice_v2 for : " + str(Unit) + " BatteryLvl = " + str(BatteryLvl))
1759
1760 # Make sure that the Domoticz device still exists (they can be deleted) before updating it
1761 if (Unit in Devices):
1762 if (Devices[Unit].nValue != nValue) or (Devices[Unit].sValue != sValue) or (Devices[Unit].Color != Color_):
1763
1764 if Color_:
1765 Devices[Unit].Update(nValue=int(nValue), sValue=str(sValue), Options=str(Options), SignalLevel=int(rssi), BatteryLevel=int(BatteryLvl) , Color = Color_)
1766 Domoticz.Log("Update v2 Color "+ str(Color_) +"' ("+Devices[Unit].Name+")")
1767 else:
1768 Devices[Unit].Update(nValue=int(nValue), sValue=str(sValue), Options=str(Options), SignalLevel=int(rssi), BatteryLevel=int(BatteryLvl))
1769
1770 Domoticz.Log("Update v2 "+str(nValue)+":'"+str(sValue)+"' ("+Devices[Unit].Name+")")
1771 return
1772
1773def UpdateDevice(Unit, nValue, sValue, Options):
1774 Dzigate=eval(Options['Zigate'])
1775 BatteryLvl=str(Dzigate['Battery'])
1776 if BatteryLvl == '{}' :
1777 BatteryLvl=255
1778 Domoticz.Debug("BatteryLvl = " + str(BatteryLvl))
1779 Domoticz.Debug("Options = " + str(Options))
1780 # Make sure that the Domoticz device still exists (they can be deleted) before updating it
1781 if (Unit in Devices):
1782 if (Devices[Unit].nValue != nValue) or (Devices[Unit].sValue != sValue):
1783 Devices[Unit].Update(nValue=int(nValue), sValue=str(sValue), Options=str(Options), BatteryLevel=int(BatteryLvl))
1784 Domoticz.Log("Update "+str(nValue)+":'"+str(sValue)+"' ("+Devices[Unit].Name+")")
1785 return
1786
1787def ReadCluster(self, MsgData):
1788 MsgLen=len(MsgData)
1789 Domoticz.Debug("ReadCluster - MsgData lenght is : " + str(MsgLen) + " out of 24+")
1790
1791 if MsgLen < 24 :
1792 Domoticz.Error("ReadCluster - MsgData lenght is too short: " + str(MsgLen) + " out of 24+")
1793 Domoticz.Error("ReadCluster - MsgData : '" +str(MsgData) + "'")
1794 return
1795
1796 MsgSQN=MsgData[0:2]
1797 MsgSrcAddr=MsgData[2:6]
1798 MsgSrcEp=MsgData[6:8]
1799 MsgClusterId=MsgData[8:12]
1800 MsgAttrID=MsgData[12:16]
1801 MsgAttType=MsgData[16:20]
1802 MsgAttSize=MsgData[20:24]
1803 MsgClusterData=MsgData[24:len(MsgData)]
1804 tmpEp=""
1805 tmpClusterid=""
1806 if DeviceExist(self, MsgSrcAddr)==False :
1807 #Correction Thiklop : MsgSrcEp n'est pas toujours dans la ListOfDevices (?)
1808 #Encapsulation dans un try except pour sortir proprement
1809 try :
1810 self.ListOfDevices[MsgSrcAddr]['Ep'][MsgSrcEp]={}
1811 self.ListOfDevices[MsgSrcAddr]['Ep'][MsgSrcEp][MsgClusterId]={}
1812 except :
1813 Domoticz.Error("ReadCluster - KeyError : MsgData = " + MsgData)
1814 # Si le Device n'existe pas . On recoit un cluster d'un device non identifié. Il faut alors le rejeté , non ?
1815 return
1816 #Fin de la correction
1817 else :
1818 self.ListOfDevices[MsgSrcAddr]['RIA']=str(int(self.ListOfDevices[MsgSrcAddr]['RIA'])+1)
1819 try :
1820 tmpEp=self.ListOfDevices[MsgSrcAddr]['Ep'][MsgSrcEp]
1821 try :
1822 tmpClusterid=self.ListOfDevices[MsgSrcAddr]['Ep'][MsgSrcEp][MsgClusterId]
1823 except :
1824 self.ListOfDevices[MsgSrcAddr]['Ep'][MsgSrcEp][MsgClusterId]={}
1825 except :
1826 self.ListOfDevices[MsgSrcAddr]['Ep'][MsgSrcEp]={}
1827 self.ListOfDevices[MsgSrcAddr]['Ep'][MsgSrcEp][MsgClusterId]={}
1828
1829 if MsgClusterId=="0000" : # (General: Basic)
1830 if MsgAttrID=="ff01" : # xiaomi battery lvl
1831 MsgBattery=MsgClusterData[4:8]
1832 try :
1833 ValueBattery='%s%s' % (str(MsgBattery[2:4]),str(MsgBattery[0:2]))
1834 ValueBattery=round(int(ValueBattery,16)/10/3.3)
1835 Domoticz.Debug("ReadCluster - ClusterId=0000 - MsgAttrID=ff01 - reception batteryLVL : " + str(ValueBattery) + " pour le device addr : " + MsgSrcAddr)
1836 #if self.ListOfDevices[MsgSrcAddr]['Status']=="inDB":
1837 # UpdateBattery(MsgSrcAddr,ValueBattery)
1838 self.ListOfDevices[MsgSrcAddr]['Battery']=ValueBattery
1839 except :
1840 Domoticz.Error("ReadCluster - ClusterId=0000 - MsgAttrID=ff01 - reception batteryLVL : erreur de lecture pour le device addr : " + MsgSrcAddr)
1841 return
1842 elif MsgAttrID=="0005" : # Model info Xiaomi
1843 try :
1844 MType=binascii.unhexlify(MsgClusterData).decode('utf-8')
1845 Domoticz.Debug("ReadCluster - ClusterId=0000 - MsgAttrID=0005 - reception Model de Device : " + MType)
1846 self.ListOfDevices[MsgSrcAddr]['Model']=MType
1847 if self.ListOfDevices[MsgSrcAddr]['Model']!= {} and self.ListOfDevices[MsgSrcAddr]['Model'] in self.DeviceConf : # verifie que le model existe ds le fichier de conf des models
1848 Modeltmp=str(self.ListOfDevices[MsgSrcAddr]['Model'])
1849 for Ep in self.DeviceConf[Modeltmp]['Ep'] :
1850 if Ep in self.ListOfDevices[MsgSrcAddr]['Ep'] :
1851 for cluster in self.DeviceConf[Modeltmp]['Ep'][Ep] :
1852 if cluster not in self.ListOfDevices[MsgSrcAddr]['Ep'][Ep] :
1853 self.ListOfDevices[MsgSrcAddr]['Ep'][Ep][cluster]={}
1854 else :
1855 self.ListOfDevices[MsgSrcAddr]['Ep'][Ep]={}
1856 for cluster in self.DeviceConf[Modeltmp]['Ep'][Ep] :
1857 self.ListOfDevices[MsgSrcAddr]['Ep'][Ep][cluster]={}
1858 self.ListOfDevices[MsgSrcAddr]['Type']=self.DeviceConf[Modeltmp]['Type']
1859 except:
1860 Domoticz.Error("ReadCluster - ClusterId=0000 - MsgAttrID=0005 - Model info Xiaomi : " + MsgSrcAddr)
1861 return
1862 else :
1863 Domoticz.Debug("ReadCluster - ClusterId=0000 - reception heartbeat - Message attribut inconnu : " + MsgData)
1864 return
1865
1866 elif MsgClusterId=="0006" : # (General: On/Off) xiaomi
1867 if MsgAttrID=="0000" or MsgAttrID=="8000":
1868 MajDomoDevice(self, MsgSrcAddr, MsgSrcEp, MsgClusterId, MsgClusterData)
1869 self.ListOfDevices[MsgSrcAddr]['Ep'][MsgSrcEp][MsgClusterId]=MsgClusterData
1870 Domoticz.Debug("ReadCluster - ClusterId=0006 - reception General: On/Off : " + str(MsgClusterData) )
1871 else :
1872 Domoticz.Error("ReadCluster - ClusterId=0006 - reception heartbeat - Message attribut inconnu : " + MsgData)
1873 return
1874
1875 elif MsgClusterId=="0008" : # (Cluster Level Control )
1876 Domoticz.Debug("ReadCluster - ClusterId=0008 - Level Control : " + str(MsgClusterData) )
1877 Domoticz.Debug("MsgSQN: " + MsgSQN )
1878 Domoticz.Debug("MsgSrcAddr: " + MsgSrcAddr )
1879 Domoticz.Debug("MsgSrcEp: " + MsgSrcEp )
1880 Domoticz.Debug("MsgAttrId: " + MsgAttrID )
1881 Domoticz.Debug("MsgAttType: " + MsgAttType )
1882 Domoticz.Debug("MsgAttSize: " + MsgAttSize )
1883 Domoticz.Debug("MsgClusterData: " + MsgClusterData )
1884 MajDomoDevice(self, MsgSrcAddr, MsgSrcEp, MsgClusterId, MsgClusterData)
1885 return
1886
1887 elif MsgClusterId=="0402" : # (Measurement: Temperature) xiaomi
1888 #MsgValue=Data[len(Data)-8:len(Data)-4]
1889 #Correction Thiklop : onMessage' failed 'IndexError':'string index out of range'.
1890 if MsgClusterData != "":
1891 if MsgClusterData[0] == "f" : # cas temperature negative
1892 MsgClusterData=-(int(MsgClusterData,16)^int("FFFF",16))
1893 MajDomoDevice(self, MsgSrcAddr, MsgSrcEp, MsgClusterId, round(MsgClusterData/100,1))
1894 self.ListOfDevices[MsgSrcAddr]['Ep'][MsgSrcEp][MsgClusterId]=round(MsgClusterData/100,1)
1895 Domoticz.Debug("ReadCluster - ClusterId=0402 - reception temp : " + str(MsgClusterData/100) )
1896 #Correction Thiklop 2 : cas des température > 1000°C
1897 #elif int(MsgClusterData,16) < 100000 : #1000 °C x 100
1898 else:
1899 MsgClusterData=int(MsgClusterData,16)
1900 MajDomoDevice(self, MsgSrcAddr, MsgSrcEp, MsgClusterId, round(MsgClusterData/100,1))
1901 self.ListOfDevices[MsgSrcAddr]['Ep'][MsgSrcEp][MsgClusterId]=round(MsgClusterData/100,1)
1902 Domoticz.Debug("ReadCluster - ClusterId=0402 - reception temp : " + str(MsgClusterData/100) )
1903 #else :
1904 # Domoticz.Log("Température > 1000°C")
1905 #Fin de correction 2
1906 else :
1907 Domoticz.Error("ReadCluster - ClusterId=0402 - MsgClusterData vide")
1908 #Fin de la correction
1909
1910 elif MsgClusterId=="0403" : # (Measurement: Pression atmospherique) xiaomi ### a corriger/modifier http://zigate.fr/xiaomi-capteur-temperature-humidite-et-pression-atmospherique-clusters/
1911 if MsgAttType=="0028":
1912 #MajDomoDevice(self, MsgSrcAddr,MsgSrcEp,"Barometer",round(int(MsgClusterData,8))
1913 self.ListOfDevices[MsgSrcAddr]['Ep'][MsgSrcEp][MsgClusterId]=MsgClusterData
1914 Domoticz.Debug("ReadCluster - ClusterId=0403 - reception atm : " + str(MsgClusterData) )
1915
1916 if MsgAttType=="0029" and MsgAttrID=="0000":
1917 #MsgValue=Data[len(Data)-8:len(Data)-4]
1918 MajDomoDevice(self, MsgSrcAddr, MsgSrcEp, MsgClusterId,round(int(MsgClusterData,16)/100,1))
1919 self.ListOfDevices[MsgSrcAddr]['Ep'][MsgSrcEp][MsgClusterId]=round(int(MsgClusterData,16)/100,1)
1920 Domoticz.Debug("ReadCluster - ClusterId=0403 - reception atm : " + str(round(int(MsgClusterData,16),1)))
1921
1922 if MsgAttType=="0029" and MsgAttrID=="0010":
1923 #MsgValue=Data[len(Data)-8:len(Data)-4]
1924 MajDomoDevice(self, MsgSrcAddr, MsgSrcEp, MsgClusterId,round(int(MsgClusterData,16)/10,1))
1925 self.ListOfDevices[MsgSrcAddr]['Ep'][MsgSrcEp][MsgClusterId]=round(int(MsgClusterData,16)/10,1)
1926 Domoticz.Debug("ReadCluster - ClusterId=0403 - reception atm : " + str(round(int(MsgClusterData,16)/10,1)))
1927
1928 elif MsgClusterId=="0405" : # (Measurement: Humidity) xiaomi
1929 #MsgValue=Data[len(Data)-8:len(Data)-4]
1930 #Correction Thiklop : le MsgClusterData n'est pas toujours un entier et est vide ?!
1931 #Encapsulation dans un try except pour gérer proprement le problème
1932 try :
1933 int(MsgClusterData,16)
1934 except :
1935 Domoticz.Error("ReadCluster -ClusterID=0405 - decapteur Xiamo humidité. La valeur n'est pas un entier : " + MsgClusterData)
1936 else :
1937 MajDomoDevice(self, MsgSrcAddr, MsgSrcEp, MsgClusterId,round(int(MsgClusterData,16)/100,1))
1938 self.ListOfDevices[MsgSrcAddr]['Ep'][MsgSrcEp][MsgClusterId]=round(int(MsgClusterData,16)/100,1)
1939 Domoticz.Debug("ReadCluster - ClusterId=0405 - reception hum : " + str(int(MsgClusterData,16)/100) )
1940 #Fin de correction
1941
1942 elif MsgClusterId=="0406" : # (Measurement: Occupancy Sensing) xiaomi
1943 MajDomoDevice(self, MsgSrcAddr, MsgSrcEp, MsgClusterId,MsgClusterData)
1944 self.ListOfDevices[MsgSrcAddr]['Ep'][MsgSrcEp][MsgClusterId]=MsgClusterData
1945 Domoticz.Debug("ReadCluster - ClusterId=0406 - reception Occupancy Sensor : " + str(MsgClusterData) )
1946
1947 elif MsgClusterId=="0400" : # (Measurement: LUX) xiaomi
1948 #Correction Thiklop : le MsgClusterData n'est pas un entier hexa (message vide dans certains cas ?)
1949 #Encapsulation dans un try except pour une sortie propre
1950 try :
1951 int(MsgClusterData,16)
1952 except :
1953 Domoticz.Error("readCluster - Problème de conversion int du capteur LUX xiaomi. MsgClusterData = " + MsgClusterData)
1954 else :
1955 MajDomoDevice(self, MsgSrcAddr, MsgSrcEp, MsgClusterId,str(int(MsgClusterData,16) ))
1956 self.ListOfDevices[MsgSrcAddr]['Ep'][MsgSrcEp][MsgClusterId]=int(MsgClusterData,16)
1957 Domoticz.Debug("ReadCluster - ClusterId=0400 - reception LUX Sensor : " + str(int(MsgClusterData,16)) )
1958 #Fin de la correction
1959
1960 elif MsgClusterId=="0012" : # Magic Cube Xiaomi
1961 # Thanks to : https://github.com/dresden-elektronik/deconz-rest-plugin/issues/138#issuecomment-325101635
1962 # +---+
1963 # | 2 |
1964 # +---+---+---+
1965 # | 4 | 0 | 1 |
1966 # +---+---+---+
1967 # | 5 |
1968 # +---+
1969 # | 3 |
1970 # +---+
1971 # Side 5 is with the MI logo; side 3 contains the battery door.
1972 #
1973 # Shake: 0x0000 (side on top doesn't matter)
1974 # 90º Flip from side x on top to side y on top: 0x0040 + (x << 3) + y
1975 # 180º Flip to side x on top: 0x0080 + x
1976 # Push while side x is on top: 0x0100 + x
1977 # Double Tap while side x is on top: 0x0200 + x
1978 # Push works in any direction.
1979 # For Double Tap you really need to lift the cube and tap it on the table twice.
1980 def cube_decode(value):
1981 value=int(value,16)
1982 if value == '' or value is None:
1983 return value
1984
1985 if value == 0x0000 :
1986 Domoticz.Log("cube action : " + 'Shake' )
1987 value='10'
1988 elif value == 0x0002 :
1989 Domoticz.Log("cube action : " + 'Wakeup' )
1990 value = '20'
1991 elif value == 0x0003 :
1992 Domoticz.Log("cube action : " + 'Drop' )
1993 value = '30'
1994 elif value & 0x0040 != 0 :
1995 face = value ^ 0x0040
1996 face1 = face >> 3
1997 face2 = face ^ (face1 << 3)
1998 Domoticz.Log("cube action : " + 'Flip90_{}{}'.format(face1, face2))
1999 value = '40'
2000 elif value & 0x0080 != 0:
2001 face = value ^ 0x0080
2002 Domoticz.Log("cube action : " + 'Flip180_{}'.format(face) )
2003 value = '50'
2004 elif value & 0x0100 != 0:
2005 face = value ^ 0x0100
2006 Domoticz.Log("cube action : " + 'Push/Move_{}'.format(face) )
2007 value = '60'
2008 elif value & 0x0200 != 0: # double_tap
2009 face = value ^ 0x0200
2010 Domoticz.Log("cube action : " + 'Double_tap_{}'.format(face) )
2011 value = '70'
2012 else:
2013 Domoticz.Log("cube action : Not expected value" + value )
2014 return value
2015
2016 MajDomoDevice(self, MsgSrcAddr, MsgSrcEp, MsgClusterId,cube_decode(MsgClusterData) )
2017 self.ListOfDevices[MsgSrcAddr]['Ep'][MsgSrcEp][MsgClusterId]=MsgClusterData
2018 Domoticz.Debug("ReadCluster - ClusterId=0012 - reception Xiaomi Magic Cube Value : " + str(MsgClusterData) )
2019 Domoticz.Log("ReadCluster - ClusterId=0012 - reception Xiaomi Magic Cube Value : " + str(cube_decode(MsgClusterData)) )
2020
2021
2022 elif MsgClusterId=="000c" : # Magic Cube Xiaomi rotation and Power Meter
2023 Domoticz.Debug("ReadCluster - ClusterID=000C - MsgAttrID = " +str(MsgAttrID) + " value = " + str(MsgClusterData) )
2024 if MsgAttrID=="0055" and MsgSrcEp == '02' : # Consomation Electrique
2025 Domoticz.Log("ReadCluster - ClusterId=000c - MsgAttrID=0055 - reception Conso Prise Xiaomi: " + str(round(struct.unpack('f',struct.pack('i',int(MsgClusterData,16)))[0])))
2026 self.ListOfDevices[MsgSrcAddr]['Ep'][MsgSrcEp][MsgClusterId]=MsgClusterData
2027 MajDomoDevice(self, MsgSrcAddr, MsgSrcEp, MsgClusterId,MsgClusterData)
2028 elif MsgAttrID=="ff05" and MsgSrcEp == '03' : # Rotation - horinzontal
2029 Domoticz.Log("ReadCluster - ClusterId=000c - Magic Cube Rotation: " + str(MsgClusterData) )
2030 self.ListOfDevices[MsgSrcAddr]['Ep'][MsgSrcEp][MsgClusterId]="80"
2031 MajDomoDevice(self, MsgSrcAddr, MsgSrcEp, MsgClusterId,"80")
2032 else :
2033 Domoticz.Log("ReadCluster - ClusterID=000c - unknown 000c message - EP = " + str( MsgSrcEp) + " MsgAttrID = " + str(MsgAttrID) + " Value = "+ str(MsgClusterData) )
2034
2035 else :
2036 Domoticz.Error("ReadCluster - Error/unknow Cluster Message : " + MsgClusterId + " for Device = " + str(MsgSrcAddr) + " Ep = " + MsgSrcEp )
2037 Domoticz.Error(" MsgAttrId = " + MsgAttrID + " MsgAttType = " + MsgAttType )
2038 Domoticz.Error(" MsgAttSize = " + MsgAttSize + " MsgClusterData = " + MsgClusterData )
2039 return
2040
2041def ReadAttributeRequest_0008(self, key) :
2042 # Cluster 0x0008 with attribute 0x0000
2043 # frame to be send is :
2044 # DeviceID 16bits / EPin 8bits / EPout 8bits / Cluster 16bits / Direction 8bits / Manufacturer_spec 8bits / Manufacturer_id 16 bits / Nb attributes 8 bits / List of attributes ( 16bits )
2045 EPin = "01"
2046 EPout= "01"
2047 for tmpEp in self.ListOfDevices[key]['Ep'] :
2048 if "0008" in self.ListOfDevices[key]['Ep'][tmpEp] : #switch cluster
2049 EPout=tmpEp
2050
2051 Domoticz.Debug("Request Control level of shutter via Read Attribute request : " + key + " EPout = " + EPout )
2052 sendZigateCmd("0100", "02" + str(key) + EPin + EPout + "0008" + "00" + "00" + "0000" + "01" + "0000" )
2053
2054
2055def CheckType(self, MsgSrcAddr) :
2056 Domoticz.Debug("CheckType of device : " + MsgSrcAddr)
2057 x=0
2058 found=False
2059 for x in Devices:
2060 if Devices[x].DeviceID == str(MsgSrcAddr) :
2061 found=True
2062
2063 if found==False :
2064 #check type with domoticz device type then add or del then re add device
2065 self.ListOfDevices[MsgSrcAddr]['Status']="inDB"
2066
2067def GetType(self, Addr, Ep) :
2068 if self.ListOfDevices[Addr]['Model']!={} and self.ListOfDevices[Addr]['Model'] in self.DeviceConf : # verifie si le model a ete detecte et est connu dans le fichier DeviceConf.txt
2069 Type = self.DeviceConf[self.ListOfDevices[Addr]['Model']]['Type']
2070 Domoticz.Debug("GetType - Type was set to : " + str(Type) )
2071 else :
2072 Domoticz.Log("GetType - Model not found in DeviceConf : " + str(self.ListOfDevices[Addr]['Model']) )
2073 Type=""
2074 for cluster in self.ListOfDevices[Addr]['Ep'][Ep] :
2075 Domoticz.Debug("GetType - Type will be set to : " + str(Type) )
2076 Domoticz.Debug("GetType - check Type for Cluster : " + str(cluster) )
2077 if Type != "" and Type[:1]!="/" :
2078 Type+="/"
2079 Type+=TypeFromCluster(cluster)
2080 #Type+=Type
2081 Type=Type.replace("/////","/")
2082 Type=Type.replace("////","/")
2083 Type=Type.replace("///","/")
2084 Type=Type.replace("//","/")
2085 if Type[:-1]=="/" :
2086 Type = Type[:-1]
2087 if Type[0:]=="/" :
2088 Type = Type[1:]
2089 if Type != "" :
2090 self.ListOfDevices[Addr]['Type']=Type
2091 Domoticz.Debug("GetType - Type is now set to : " + str(Type) )
2092 else :
2093 Domoticz.Log("GetType - WARNING - Not able to find a Type for Addr : " + str(Addr) + " Ep : " + str(Ep) + " Device Info : " + str(self.ListOfDevices[Addr]) )
2094 return Type
2095
2096def TypeFromCluster(cluster):
2097 if cluster=="0405" :
2098 TypeFromCluster="Humi"
2099 elif cluster=="0406" :
2100 TypeFromCluster="Motion"
2101 elif cluster=="0400" :
2102 TypeFromCluster="Lux"
2103 elif cluster=="0403" :
2104 TypeFromCluster="Baro"
2105 elif cluster=="0402" :
2106 TypeFromCluster="Temp"
2107 elif cluster=="0006" :
2108 TypeFromCluster="Switch"
2109 elif cluster=="0500" :
2110 TypeFromCluster="Door"
2111 elif cluster=="0012" :
2112 TypeFromCluster="XCube"
2113 elif cluster=="000c" :
2114 TypeFromCluster="XCube"
2115 elif cluster=="0008" :
2116 TypeFromCluster="LvlControl"
2117 elif cluster=="0300" :
2118 TypeFromCluster="ColorControl"
2119 else :
2120 TypeFromCluster=""
2121 return TypeFromCluster
2122
2123def WriteDeviceList(self, count):
2124 if self.HBcount>=count :
2125 with open(Parameters["HomeFolder"]+"DeviceList.txt", 'wt') as file:
2126 for key in self.ListOfDevices :
2127 file.write(key + " : " + str(self.ListOfDevices[key]) + "\n")
2128 Domoticz.Debug("Write DeviceList.txt = " + str(self.ListOfDevices))
2129 self.HBcount=0
2130 else :
2131 Domoticz.Debug("HB count = " + str(self.HBcount))
2132 self.HBcount=self.HBcount+1
2133
2134def returnlen(taille , value) :
2135 while len(value)<taille:
2136 value="0"+value
2137 return str(value)
2138
2139def Hex_Format(taille, value):
2140 value = hex(int(value))[2:]
2141 if len(value) > taille:
2142 return 'f' * taille
2143 while len(value)<taille:
2144 value="0"+value
2145 return str(value)
2146
2147def CheckDeviceList(self, key, val) :
2148 Domoticz.Debug("CheckDeviceList - Address search : " + str(key))
2149 Domoticz.Debug("CheckDeviceList - with value : " + str(val))
2150
2151 DeviceListVal=eval(val)
2152 if DeviceExist(self, key)==False :
2153 Domoticz.Debug("CheckDeviceList - Address will be add : " + str(key))
2154 self.ListOfDevices[key]['RIA']="10"
2155 self.ListOfDevices[key]['Ep']=DeviceListVal['Ep']
2156 if 'Type' in DeviceListVal :
2157 self.ListOfDevices[key]['Type']=DeviceListVal['Type']
2158 if 'Model' in DeviceListVal :
2159 self.ListOfDevices[key]['Model']=DeviceListVal['Model']
2160 if 'MacCapa' in DeviceListVal :
2161 self.ListOfDevices[key]['MacCapa']=DeviceListVal['MacCapa']
2162 if 'IEEE' in DeviceListVal :
2163 self.ListOfDevices[key]['IEEE']=DeviceListVal['IEEE']
2164 if 'ProfileID' in DeviceListVal :
2165 self.ListOfDevices[key]['ProfileID']=DeviceListVal['ProfileID']
2166 if 'ZDeviceID' in DeviceListVal :
2167 self.ListOfDevices[key]['ZDeviceID']=DeviceListVal['ZDeviceID']
2168 if 'Status' in DeviceListVal :
2169 self.ListOfDevices[key]['Status']=DeviceListVal['Status']
2170 return
2171
2172def DisplayStatusCode( StatusCode ) :
2173 # As described in https://www.nxp.com/docs/en/user-guide/JN-UG-3113.pdf section 10.2
2174
2175 StatusMsg=""
2176 if str(StatusCode)=="00" : StatusMsg="Success"
2177 elif str(StatusCode)=="c1" : StatusMsg="An invalid or out-of-range parameter has been passed"
2178 elif str(StatusCode)=="c2" : StatusMsg="Request cannot be processed"
2179 elif str(StatusCode)=="c3" : StatusMsg="NLME-JOIN.request not permitted"
2180 elif str(StatusCode)=="c4" : StatusMsg="NLME-NETWORK-FORMATION.request failed"
2181 elif str(StatusCode)=="c5" : StatusMsg="NLME-DIRECT-JOIN.request failure - device already present"
2182 elif str(StatusCode)=="c6" : StatusMsg="NLME-SYNC.request has failed"
2183 elif str(StatusCode)=="c7" : StatusMsg="NLME-DIRECT-JOIN.request failure - no space in Router table"
2184 elif str(StatusCode)=="c8" : StatusMsg="NLME-LEAVE.request failure - device not in Neighbour table"
2185 elif str(StatusCode)=="c9" : StatusMsg="NLME-GET/SET.request unknown attribute identified"
2186 elif str(StatusCode)=="ca" : StatusMsg="NLME-JOIN.request detected no networks"
2187 elif str(StatusCode)=="cb" : StatusMsg="Reserved"
2188 elif str(StatusCode)=="cc" : StatusMsg="Security processing has failed on outgoing frame due to maximum frame counter"
2189 elif str(StatusCode)=="cd" : StatusMsg="Security processing has failed on outgoing frame due to no key"
2190 elif str(StatusCode)=="ce" : StatusMsg="Security processing has failed on outgoing frame due CCM"
2191 elif str(StatusCode)=="cf" : StatusMsg="Attempt at route discovery has failed due to lack of table space"
2192 elif str(StatusCode)=="d0" : StatusMsg="Attempt at route discovery has failed due to any reason except lack of table space"
2193 elif str(StatusCode)=="d1" : StatusMsg="NLDE-DATA.request has failed due to routing failure on sending device"
2194 elif str(StatusCode)=="d2" : StatusMsg="Broadcast or broadcast-mode multicast has failed as there is no room in BTT"
2195 elif str(StatusCode)=="d3" : StatusMsg="Unicast mode multi-cast frame was discarded pending route discovery"
2196 elif str(StatusCode)=="d4" : StatusMsg="Unicast frame does not have a route available but it is buffered for automatic resend"
2197
2198 elif str(StatusCode)=="a0": StatusMsg="A transmit request failed since the ASDU is too large and fragmentation is not supported"
2199 elif str(StatusCode)=="a1": StatusMsg="A received fragmented frame could not be defragmented at the current time"
2200 elif str(StatusCode)=="a2": StatusMsg="A received fragmented frame could not be defragmented since the device does not support fragmentation"
2201 elif str(StatusCode)=="a3": StatusMsg="A parameter value was out of range"
2202 elif str(StatusCode)=="a4": StatusMsg="An APSME-UNBIND.request failed due to the requested binding link not existing in the binding table"
2203 elif str(StatusCode)=="a5": StatusMsg="An APSME-REMOVE-GROUP.request has been issued with a group identified that does not appear in the group table"
2204 elif str(StatusCode)=="a6": StatusMsg="A parameter value was invaid or out of range"
2205 elif str(StatusCode)=="a7": StatusMsg="An APSDE-DATA.request requesting ack transmission failed due to no ack being received"
2206 elif str(StatusCode)=="a8": StatusMsg="An APSDE-DATA.request with a destination addressing mode set to 0x00 failed due to there being no devices bound to this device"
2207 elif str(StatusCode)=="a9": StatusMsg="An APSDE-DATA.request with a destination addressing mode set to 0x03 failed due to no corresponding short address found in the address map table"
2208 elif str(StatusCode)=="aa": StatusMsg="An APSDE-DATA.request with a destination addressing mode set to 0x00 failed due to a binding table not being supported on the device"
2209 elif str(StatusCode)=="ab": StatusMsg="An ASDU was received that was secured using a link key"
2210 elif str(StatusCode)=="ac": StatusMsg="An ASDU was received that was secured using a network key"
2211 elif str(StatusCode)=="ad": StatusMsg="An APSDE-DATA.request requesting security has resulted in an error during the corresponding security processing"
2212
2213 else: StatusMsg="Unknown code : " + StatusCode
2214
2215
2216 return StatusMsg
2217
2218
2219def removeZigateDevice( self, key ) :
2220 # remove a device in Zigate
2221 # Key is the short address of the device
2222 # extended address is ieee address
2223
2224 if key in self.ListOfDevices:
2225 ieee = self.ListOfDevices[key]['IEEE']
2226 Domoticz.Log("Remove from Zigate Device = " + str(key) + " IEEE = " +str(ieee) )
2227 sendZigateCmd("0026", str(ieee) + str(ieee) )
2228 else :
2229 Domoticz.Log("Unknow device to be removed - Device = " + str(key))
2230
2231 return