def tuya_smart_motion_all_in_one(self, Devices, _ModelName, NwkId, srcEp, ClusterID, dstNWKID, dstEP, dp, datatype, data): if dp == 0x6b: # Temperature self.log.logging( "Tuya", "Debug", "tuya_smart_motion_all_in_one - Temperature %s" % int(data, 16), NwkId) MajDomoDevice(self, Devices, NwkId, "02", "0402", (int(data, 16) / 10)) store_tuya_attribute(self, NwkId, "Temperature", data) elif dp == 0x6c: # Humidity self.log.logging( "Tuya", "Debug", "tuya_smart_motion_all_in_one - Humidity %s" % int(data, 16), NwkId) MajDomoDevice(self, Devices, NwkId, "02", "0405", (int(data, 16))) store_tuya_attribute(self, NwkId, "Humidity", data) else: self.log.logging( "Tuya", "Debug", "tuya_smart_motion_all_in_one - Model: %s Unknow Nwkid: %s/%s dp: %02x data type: %s data: %s" % (_ModelName, NwkId, srcEp, dp, datatype, data), NwkId, )
def tuya_dimmer_response(self, Devices, _ModelName, NwkId, srcEp, ClusterID, dstNWKID, dstEP, dp, datatype, data): # cmd | status | transId | dp | DataType | fn | len | Data # Dim Down: 01 00 01 02 02 00 04 00000334 # Dim Up: 01 00 01 02 02 00 04 0000005a # Switch Off: 01 00 01 01 01 00 01 00 # Dim Up : 01 00 01 01 01 00 01 01 if dp == 0x01: # Switch On/Off MajDomoDevice(self, Devices, NwkId, srcEp, "0006", data) self.log.logging( "Tuya", "Debug", "tuya_dimmer_response - Nwkid: %s/%s On/Off %s" % (NwkId, srcEp, data), NwkId) elif dp == 0x02: # Dim Down/Up # As MajDomoDevice expect a value between 0 and 255, and Tuya dimmer is on a scale from 0 - 1000. analogValue = int(data, 16) / 10 # This give from 1 to 100 level = int((analogValue * 255) / 100) self.log.logging( "Tuya", "Debug", "tuya_dimmer_response - Nwkid: %s/%s Dim up/dow %s %s" % (NwkId, srcEp, int(data, 16), level), NwkId, ) MajDomoDevice(self, Devices, NwkId, srcEp, "0008", "%02x" % level) else: attribute_name = "UnknowDp_0x%02x_Dt_0x%02x" % (dp, datatype) store_tuya_attribute(self, NwkId, attribute_name, data)
def legrand_remote_switch_8085(self, Devices, MsgSrcAddr, MsgEP, MsgClusterId, MsgCmd, unknown_, MsgData): TYPE_ACTIONS = { None: "", "01": "move", "02": "click", "03": "stop", } DIRECTION = {None: "", "00": "up", "01": "down"} step_mod, up_down, step_size, transition = extract_info_from_8085(MsgData) if TYPE_ACTIONS[step_mod] in ("click", "move"): selector = TYPE_ACTIONS[step_mod] + DIRECTION[up_down] elif TYPE_ACTIONS[step_mod] == "stop": selector = TYPE_ACTIONS[step_mod] else: Domoticz.Error("Decode8085 - Unknown state for %s step_mod: %s up_down: %s" % (MsgSrcAddr, step_mod, up_down)) return self.log.logging("Input", "Debug", "Decode8085 - Legrand selector: %s" % selector, MsgSrcAddr) if selector: if "Param" in self.ListOfDevices[MsgSrcAddr] and "netatmoReleaseButton" in self.ListOfDevices[MsgSrcAddr]["Param"] and self.ListOfDevices[MsgSrcAddr]["Param"]["netatmoReleaseButton"]: # self.log.logging( "Input", 'Log',"Receive: %s/%s %s" %(MsgSrcAddr,MsgEP,selector)) MajDomoDevice(self, Devices, MsgSrcAddr, MsgEP, MsgClusterId, selector) self.ListOfDevices[MsgSrcAddr]["Ep"][MsgEP][MsgClusterId]["0000"] = selector elif TYPE_ACTIONS[step_mod] != "stop": # self.log.logging( "Input", 'Log',"Receive: %s/%s %s REQUEST UPDATE" %(MsgSrcAddr,MsgEP,selector)) MajDomoDevice(self, Devices, MsgSrcAddr, MsgEP, MsgClusterId, selector) self.ListOfDevices[MsgSrcAddr]["Ep"][MsgEP][MsgClusterId]["0000"] = selector
def ikea_remote_switch_8085(self, Devices, MsgSrcAddr, MsgEP, MsgClusterId, MsgCmd, unknown_): if MsgClusterId == "0008": if MsgCmd == "05": # Push Up MajDomoDevice(self, Devices, MsgSrcAddr, MsgEP, "0006", "02") elif MsgCmd == "01": # Push Down MajDomoDevice(self, Devices, MsgSrcAddr, MsgEP, "0006", "03") elif MsgCmd == "07": # Release Up & Down MajDomoDevice(self, Devices, MsgSrcAddr, MsgEP, "0006", "04") self.ListOfDevices[MsgSrcAddr]["Ep"][MsgEP][MsgClusterId]["0000"] = MsgCmd
def ikea_openclose_remote(self, Devices, NwkId, Ep, command, Data, Sqn): if self.ListOfDevices[NwkId]["Status"] != "inDB": return updSQN(self, NwkId, Sqn) lastSeenUpdate(self, Devices, NwkId=NwkId) if command == "00": # Close/Down MajDomoDevice(self, Devices, NwkId, Ep, "0006", "00") elif command == "01": # Open/Up MajDomoDevice(self, Devices, NwkId, Ep, "0006", "01") elif command == "02": # Stop MajDomoDevice(self, Devices, NwkId, Ep, "0006", "02")
def ikea_remote_control_8085(self, Devices, MsgSrcAddr, MsgEP, MsgClusterId, MsgCmd, unknown_): TYPE_ACTIONS = { "01": "hold_down", "02": "click_down", "03": "release_down", "05": "hold_up", "06": "click_up", "07": "release_up", } if MsgClusterId == "0008" and MsgCmd in TYPE_ACTIONS: selector = TYPE_ACTIONS[MsgCmd] self.log.logging("Input", "Debug", "Decode8085 - Selector: %s" % selector, MsgSrcAddr) MajDomoDevice(self, Devices, MsgSrcAddr, MsgEP, "rmt1", selector) self.ListOfDevices[MsgSrcAddr]["Ep"][MsgEP][MsgClusterId][ "0000"] = selector else: self.log.logging( "Input", "Log", "Decode8085 - Addr: %s, Ep: %s, Cluster: %s, Cmd: %s, Unknown: %s" % (MsgSrcAddr, MsgEP, MsgClusterId, MsgCmd, unknown_), ) self.ListOfDevices[MsgSrcAddr]["Ep"][MsgEP][MsgClusterId][ "0000"] = "Cmd: %s, %s" % (MsgCmd, unknown_)
def legrand_motion_8095(self, Devices, MsgSrcAddr,MsgEP, MsgClusterId, MsgCmd, unknown_ ): self.log.logging( "Input", "Log", "Decode8095 - Legrand: %s/%s, Cmd: %s, Unknown: %s " % (MsgSrcAddr, MsgEP, MsgCmd, unknown_), MsgSrcAddr, ) MajDomoDevice(self, Devices, MsgSrcAddr, MsgEP, "0406", unknown_)
def orviboReadRawAPS(self, Devices, srcNWKID, srcEp, ClusterID, dstNWKID, dstEP, MsgPayload): # Domoticz.Log("OrviboReadRawAPS - Nwkid: %s Ep: %s, Cluster: %s, dstNwkid: %s, dstEp: %s, Payload: %s" \ # %(srcNWKID, srcEp, ClusterID, dstNWKID, dstEP, MsgPayload)) BUTTON_MAP = { # d0d2422bbf3a4982b31ea843bfedb559 "d0d2422bbf3a4982b31ea843bfedb559": { "01": 1, # Top "02": 2, # Middle "03": 3, # Bottom }, # Interupteur Autocolalant / "3c4e4fc81ed442efaf69353effcdfc5f": { "03": 10, # Top Left, "0b": 20, # Middle Left "07": 30, # Top Right "0f": 40, # Mddle Right }, } ACTIONS_MAP = { "00": 1, # Click "02": 2, # Long Click "03": 3, # Release } if srcNWKID not in self.ListOfDevices: Domoticz.Error("%s not found in Database") return if "Model" not in self.ListOfDevices[srcNWKID]: return _Model = self.ListOfDevices[srcNWKID]["Model"] if ClusterID != "0017": Domoticz.Error( "orviboReadRawAPS - unexpected ClusterId %s for NwkId: %s" % (ClusterID, srcNWKID)) return FrameControlFiled = MsgPayload[0:2] if FrameControlFiled == "19": sqn = MsgPayload[2:4] cmd = MsgPayload[4:6] data = MsgPayload[6:] if cmd == "08": button = data[0:2] action = data[4:6] # Domoticz.Log("button: %s, action: %s" %(button, action)) if action in ACTIONS_MAP and button in BUTTON_MAP[_Model]: selector = BUTTON_MAP[_Model][button] + ACTIONS_MAP[action] # Domoticz.Log("---> Selector: %s" %selector) MajDomoDevice(self, Devices, srcNWKID, "01", "0006", selector)
def tuya_watertimer_response(self, Devices, _ModelName, NwkId, srcEp, ClusterID, dstNWKID, dstEP, dp, datatype, data): self.log.logging( "Tuya", "Debug", "tuya_response - Model: %s Nwkid: %s/%s dp: %02x data type: %02x data: %s" % (_ModelName, NwkId, srcEp, dp, datatype, data), NwkId, ) if dp == 0x01: # Openned # tuya_response - Model: TS0601-Parkside-Watering-Timer Nwkid: a82e/01 dp: 06 data type: 2 data: 00000001 # tuya_response - Model: TS0601-Parkside-Watering-Timer Nwkid: a82e/01 dp: 01 data type: 1 data: 010502000400000001 # tuya_response - Model: TS0601-Parkside-Watering-Timer Nwkid: a82e/01 dp: 06 data type: 2 data: 00000001 # tuya_response - Model: TS0601-Parkside-Watering-Timer Nwkid: a82e/01 dp: 01 data type: 1 data: 010502000400000001 # Closing via Button # tuya_response - Model: TS0601-Parkside-Watering-Timer Nwkid: a82e/01 dp: 01 data type: 1 data: 000502000400000001 # tuya_response - Model: TS0601-Parkside-Watering-Timer Nwkid: a82e/01 dp: 06 data type: 2 data: 00000000 # tuya_response - Model: TS0601-Parkside-Watering-Timer Nwkid: a82e/01 dp: 01 data type: 1 data: 000502000400000001 store_tuya_attribute(self, NwkId, "Valve 0x01", data) elif dp == 0x05: # store_tuya_attribute(self, NwkId, "Valve 0x05", data) elif dp == 0x06 and datatype == 0x02: # Valve State state = "%02d" % int(data) store_tuya_attribute(self, NwkId, "Valve state", state) self.log.logging( "Tuya", "Debug", "tuya_response - ------ Request MajDomoDevice(self, Devices, %s, %s, '0006', %s)" % (NwkId, srcEp, state), ) MajDomoDevice(self, Devices, NwkId, srcEp, "0006", state) elif dp == 0x0B: store_tuya_attribute(self, NwkId, "Valve 0x0b", data) elif dp == 0x65: store_tuya_attribute(self, NwkId, "Valve 0x65", data) elif dp == 0x66: store_tuya_attribute(self, NwkId, "Valve 0x66", data) elif dp == 0x67: store_tuya_attribute(self, NwkId, "Valve 0x67", data) elif dp == 0x68: store_tuya_attribute(self, NwkId, "Valve 0x68", data) elif dp == 0x69: store_tuya_attribute(self, NwkId, "Valve 0x69", data) elif dp == 0x6A: store_tuya_attribute(self, NwkId, "Valve 0x6a", data) elif dp == 0x6B: store_tuya_attribute(self, NwkId, "Valve 0x6b", data)
def ikea_remote_control_8095(self, Devices, MsgSrcAddr, MsgEP, MsgClusterId, MsgCmd, unknown_): if MsgClusterId == "0006" and MsgCmd == "02": MajDomoDevice(self, Devices, MsgSrcAddr, MsgEP, "rmt1", "toggle") elif MsgClusterId == "0006" and MsgCmd == "00": MajDomoDevice(self, Devices, MsgSrcAddr, MsgEP, "rmt1", "click_down") elif MsgClusterId == "0006" and MsgCmd == "01": MajDomoDevice(self, Devices, MsgSrcAddr, MsgEP, "rmt1", "click_up") else: self.log.logging( "Input", "Log", "Decode8095 - Addr: %s, Ep: %s, Cluster: %s, Cmd: %s, Unknown: %s " % (MsgSrcAddr, MsgEP, MsgClusterId, MsgCmd, unknown_), ) self.ListOfDevices[MsgSrcAddr]["Ep"][MsgEP][MsgClusterId][ "0000"] = "Cmd: %s, %s" % (MsgCmd, unknown_)
def livolo_read_attribute_request(self, Devices, NwkId, Ep, Status): # What is expected on the Widget is: # Left Off: 00 # Left On: 01 # Right Off: 02 # Right On: 03 self.log.logging( "Livolo", "Debug", "Decode0100 - Livolo %s/%s Data: %s" % (NwkId, Ep, Status), NwkId) if Status == "00": # Left / Single - Off MajDomoDevice(self, Devices, NwkId, Ep, "0006", "00") elif Status == "01": # Left / Single - On MajDomoDevice(self, Devices, NwkId, Ep, "0006", "01") if Status == "02": # Right - Off MajDomoDevice(self, Devices, NwkId, Ep, "0006", "10") elif Status == "03": # Right - On MajDomoDevice(self, Devices, NwkId, Ep, "0006", "11") self.ListOfDevices[NwkId]["Ep"][Ep]["0006"]["0000"] = Status
def ikea_motion_sensor_8095(self, Devices, MsgSrcAddr, MsgEP, MsgClusterId, MsgCmd, unknown_): if MsgClusterId == "0006" and MsgCmd == "42": # Motion Sensor On MajDomoDevice(self, Devices, MsgSrcAddr, MsgEP, "0406", "01") else: self.log.logging( "Input", "Log", "Decode8095 - Addr: %s, Ep: %s, Cluster: %s, Cmd: %s, Unknown: %s " % (MsgSrcAddr, MsgEP, MsgClusterId, MsgCmd, unknown_), ) self.ListOfDevices[MsgSrcAddr]["Ep"][MsgEP][MsgClusterId][ "0000"] = "Cmd: %s, %s" % (MsgCmd, unknown_)
def tuya_garage_door_response(self, Devices, _ModelName, NwkId, srcEp, ClusterID, dstNWKID, dstEP, dp, datatype, data): if dp == 0x01: # Switch self.log.logging( "Tuya", "Debug", "tuya_garage_door_response - Switch %s" % int(data, 16), NwkId) MajDomoDevice(self, Devices, NwkId, "01", "0006", "%02x" % (int(data, 16))) store_tuya_attribute(self, NwkId, "Door", data) elif dp == 0x03: # Door: 0x00 => Closed, 0x01 => Open self.log.logging("Tuya", "Debug", "tuya_garage_door_response - Door %s" % int(data, 16), NwkId) MajDomoDevice(self, Devices, NwkId, "01", "0500", "%02x" % (int(data, 16))) store_tuya_attribute(self, NwkId, "Door", data) else: store_tuya_attribute(self, NwkId, "dp:%s-dt:%s" % (dp, datatype), data)
def legrand_remote_switch_8095(self, Devices, MsgSrcAddr,MsgEP, MsgClusterId, MsgCmd, unknown_ ): if MsgCmd == "01": # On self.log.logging( "Input", "Debug", "Decode8095 - Legrand: %s/%s, Cmd: %s, Unknown: %s " % (MsgSrcAddr, MsgEP, MsgCmd, unknown_), MsgSrcAddr, ) MajDomoDevice(self, Devices, MsgSrcAddr, MsgEP, MsgClusterId, MsgCmd) self.ListOfDevices[MsgSrcAddr]["Ep"][MsgEP][MsgClusterId]["0000"] = "Cmd: %s, %s" % (MsgCmd, unknown_) elif MsgCmd == "00": # Off MajDomoDevice(self, Devices, MsgSrcAddr, MsgEP, MsgClusterId, MsgCmd) self.ListOfDevices[MsgSrcAddr]["Ep"][MsgEP][MsgClusterId] = {} self.log.logging( "Input", "Debug", "Decode8095 - Legrand: %s/%s, Cmd: %s, Unknown: %s " % (MsgSrcAddr, MsgEP, MsgCmd, unknown_), MsgSrcAddr, ) elif MsgCmd == "02": # Toggle MajDomoDevice(self, Devices, MsgSrcAddr, MsgEP, MsgClusterId, "02") self.ListOfDevices[MsgSrcAddr]["Ep"][MsgEP][MsgClusterId]["0000"] = "Cmd: %s, %s" % (MsgCmd, unknown_)
def readLumiLock(self, Devices, MsgSQN, MsgSrcAddr, MsgSrcEp, MsgClusterId, MsgAttrID, MsgAttType, MsgAttSize, MsgClusterData): # 11 01 ff ffffffffff Clé non autorisée # # # 11 07 ff ffffffffff Anomalie (forçage de la serrure / clé mal introduit) # 12 01 01 ffffffffff Clé autorisée (clé numéro 1) # # # 12 01 02 ffffffffff Clé autorisée (clé numéro 2) # # # 12 11 01 ffffffffff Clé est restée dans la serrure (clé numéro 1) # 12 11 02 ffffffffff Clé est restée dans la serrure (clé numéro 2) # 13 11 01 ffffffffff Ajout d'une clé (clé numéro 1) # # # 13 11 02 ffffffffff Ajout d'une clé (clé numéro 2) # # # 16 01 ff ffffffffff Suppression des clés LUMI_LOCK = { "1101": "Unauthorized", "1107": "Bad Insert", "1207": "Unlock all to neutral", "1601": "All Key Removed", "1201": "Autorized Key", "1211": "Key in lock", "1311": "New Key", } LUMI_LOCK_KEY = ("1201", "1211") lumilockData = MsgClusterData[0:4] if lumilockData in LUMI_LOCK_KEY: lumilockData += MsgClusterData[4:6] self.log.logging( "Lumi", "Log", "ReadCluster - %s/%s LUMI LOCK %s lumilockData: %s" % (MsgSrcAddr, MsgSrcEp, MsgClusterData, lumilockData), ) MajDomoDevice(self, Devices, MsgSrcAddr, MsgSrcEp, "LumiLock", lumilockData) checkAndStoreAttributeValue(self, MsgSrcAddr, MsgSrcEp, MsgClusterId, MsgAttrID, MsgClusterData) store_lumi_attribute(self, MsgSrcAddr, "LumiLock", lumilockData)
def AqaraOppleDecoding0012(self, Devices, nwkid, Ep, ClusterId, AttributeId, Value): # Ep : 01 (left) # Value: 0x0001 - click # 0x0002 - Double click # 0x0003 - Tripple click # 0x0000 - Long Click # 0x00ff - Release OPPLE_MAPPING = { "0001": "01", "0002": "02", "0003": "03", "0000": "04", "00ff": "05" } if Value in OPPLE_MAPPING: MajDomoDevice(self, Devices, nwkid, Ep, "0006", OPPLE_MAPPING[Value])
def tuya_siren_response(self, Devices, _ModelName, NwkId, srcEp, ClusterID, dstNWKID, dstEP, dp, datatype, data): self.log.logging("Tuya", "Debug", "tuya_siren_response - Nwkid: %s dp: %02x data: %s" % (NwkId, dp, data)) if dp == 0x65: # Power Mode ( 0x00 Battery, 0x04 USB ) if data == "00": self.log.logging( "Tuya", "Log", "tuya_siren_response - Nwkid: %s/%s switch to Battery power" % (NwkId, srcEp), NwkId ) elif data == "01": # High self.ListOfDevices[NwkId]["Battery"] = 90 Update_Battery_Device(self, Devices, NwkId, 90) elif data == "02": # Medium self.ListOfDevices[NwkId]["Battery"] = 50 Update_Battery_Device(self, Devices, NwkId, 50) elif data == "03": # Low self.ListOfDevices[NwkId]["Battery"] = 25 Update_Battery_Device(self, Devices, NwkId, 25) elif data == "04": self.log.logging( "Tuya", "Log", "tuya_siren_response - Nwkid: %s/%s switch to USB power" % (NwkId, srcEp), NwkId ) store_tuya_attribute(self, NwkId, "PowerMode", data) elif dp == 0x66: self.log.logging("Tuya", "Debug", "tuya_siren_response - Alarm Melody 0x0473 %s" % int(data, 16), NwkId) MajDomoDevice(self, Devices, NwkId, srcEp, "0006", (int(data, 16))) store_tuya_attribute(self, NwkId, "SirenMelody", data) elif dp == 0x67: self.log.logging("Tuya", "Debug", "tuya_siren_response - Current Siren Duration %s" % int(data, 16), NwkId) store_tuya_attribute(self, NwkId, "SirenDuration", data) elif dp == 0x68: # Alarm set # Alarm store_tuya_attribute(self, NwkId, "Alarm", data) if data == "00": MajDomoDevice(self, Devices, NwkId, srcEp, "0006", "00", Attribute_="0168") else: MajDomoDevice(self, Devices, NwkId, srcEp, "0006", "01", Attribute_="0168") elif dp == 0x69: # Temperature self.log.logging("Tuya", "Debug", "tuya_siren_response - Temperature %s" % int(data, 16), NwkId) MajDomoDevice(self, Devices, NwkId, srcEp, "0402", (int(data, 16) / 10)) store_tuya_attribute(self, NwkId, "Temperature", data) elif dp == 0x6A: # Humidity self.log.logging("Tuya", "Debug", "tuya_siren_response - Humidity %s" % int(data, 16), NwkId) MajDomoDevice(self, Devices, NwkId, srcEp, "0405", (int(data, 16))) store_tuya_attribute(self, NwkId, "Humidity", data) elif dp == 0x6B: # Min Alarm Temperature self.log.logging("Tuya", "Debug", "tuya_siren_response - Current Min Alarm Temp %s" % int(data, 16), NwkId) store_tuya_attribute(self, NwkId, "MinAlarmTemp", data) elif dp == 0x6C: # Max Alarm Temperature self.log.logging("Tuya", "Debug", "tuya_siren_response - Current Max Alarm Temp %s" % int(data, 16), NwkId) store_tuya_attribute(self, NwkId, "MaxAlarmTemp", data) elif dp == 0x6D and _ModelName == "TS0601-sirene": # AMin Alarm Humidity self.log.logging("Tuya", "Debug", "tuya_siren_response - Current Min Alarm Humi %s" % int(data, 16), NwkId) store_tuya_attribute(self, NwkId, "MinAlarmHumi", data) elif dp == 0x6E: # Max Alarm Humidity self.log.logging("Tuya", "Debug", "tuya_siren_response - Current Max Alarm Humi %s" % int(data, 16), NwkId) store_tuya_attribute(self, NwkId, "MaxAlarmHumi", data) elif dp == 0x70: self.log.logging("Tuya", "Log", "tuya_siren_response - Temperature Unit: %s " % (int(data, 16)), NwkId) store_tuya_attribute(self, NwkId, "TemperatureUnit", data) elif dp == 0x71: # Alarm by Temperature self.log.logging("Tuya", "Log", "tuya_siren_response - Alarm by Temperature: %s" % (int(data, 16)), NwkId) MajDomoDevice(self, Devices, NwkId, srcEp, "0006", data, Attribute_="0171") store_tuya_attribute(self, NwkId, "AlarmByTemp", data) elif dp == 0x72: # Alarm by humidity self.log.logging("Tuya", "Log", "tuya_siren_response - Alarm by Humidity: %s" % (int(data, 16)), NwkId) MajDomoDevice(self, Devices, NwkId, srcEp, "0006", data, Attribute_="0172") store_tuya_attribute(self, NwkId, "AlarmByHumi", data) elif dp == 0x74: # Current Siren Volume self.log.logging("Tuya", "Debug", "tuya_siren_response - Current Siren Volume %s" % int(data, 16), NwkId) store_tuya_attribute(self, NwkId, "SirenVolume", data) else: self.log.logging( "Tuya", "Debug", "tuya_siren_response - Unknown attribut Nwkid: %s/%s decodeDP: %04x data: %s" % (NwkId, srcEp, dp, data), NwkId, ) attribute_name = "UnknowDp_0x%02x_Dt_0x%02x" % (dp, datatype) store_tuya_attribute(self, NwkId, attribute_name, data)
def ikea_wireless_dimer_8085(self, Devices, MsgSrcAddr, MsgEP, MsgClusterId, MsgCmd, unknown_, MsgData): TYPE_ACTIONS = { None: "", "01": "moveleft", "02": "click", "03": "stop", "04": "OnOff", "05": "moveright", "06": "Step 06", "07": "stop", } DIRECTION = {None: "", "00": "left", "ff": "right"} step_mod, up_down, step_size, transition = extract_info_from_8085(MsgData) selector = None if step_mod == "01": # Move left self.log.logging( "Input", "Debug", "Decode8085 - =====> turning left step_size: %s transition: %s" % (step_size, transition), MsgSrcAddr, ) self.ListOfDevices[MsgSrcAddr]["Ep"][MsgEP][MsgClusterId][ "0000"] = "moveup" MajDomoDevice(self, Devices, MsgSrcAddr, MsgEP, MsgClusterId, "moveup") elif step_mod == "04" and up_down == "00" and step_size == "00" and transition == "01": # Off self.log.logging( "Input", "Debug", "Decode8085 - =====> turning left step_size: %s transition: %s" % (step_size, transition), MsgSrcAddr, ) self.ListOfDevices[MsgSrcAddr]["Ep"][MsgEP][MsgClusterId][ "0000"] = "off" MajDomoDevice(self, Devices, MsgSrcAddr, MsgEP, MsgClusterId, "off") elif step_mod == "04" and up_down == "ff" and step_size == "00" and transition == "01": # On self.log.logging( "Input", "Debug", "Decode8085 - =====> turning right step_size: %s transition: %s" % (step_size, transition), MsgSrcAddr, ) self.ListOfDevices[MsgSrcAddr]["Ep"][MsgEP][MsgClusterId][ "0000"] = "on" MajDomoDevice(self, Devices, MsgSrcAddr, MsgEP, MsgClusterId, "on") elif step_mod == "05": # Move Right self.log.logging( "Input", "Debug", "Decode8085 - =====> turning Right step_size: %s transition: %s" % (step_size, transition), MsgSrcAddr, ) self.ListOfDevices[MsgSrcAddr]["Ep"][MsgEP][MsgClusterId][ "0000"] = "movedown" MajDomoDevice(self, Devices, MsgSrcAddr, MsgEP, MsgClusterId, "movedown") elif step_mod == "07": # Stop Moving self.log.logging( "Input", "Debug", "Decode8085 - =====> Stop moving step_size: %s transition: %s" % (step_size, transition), MsgSrcAddr, ) else: self.log.logging( "Input", "Log", "Decode8085 - =====> Unknown step_mod: %s up_down: %s step_size: %s transition: %s" % (step_mod, up_down, step_size, transition), MsgSrcAddr, )
def tuya_curtain_response(self, Devices, _ModelName, NwkId, srcEp, ClusterID, dstNWKID, dstEP, dp, datatype, data): # dp 0x01 closing -- Data can be 00 , 01, 02 - Opening, Stopped, Closing # dp 0x02 Percent control - Percent control # db 0x03 and data '00000000' - Percent state when arrived at position (report) # dp 0x05 and data - direction state # dp 0x07 and data 00, 01 - Opening, Closing # dp 0x69 and data '00000028' # 000104ef00010102 94fd 02 00000970020000 0202 0004 00000004 self.log.logging( "Tuya", "Debug", "tuya_curtain_response - Nwkid: %s/%s dp: %s data: %s" % (NwkId, srcEp, dp, data), NwkId) if dp == 0x01: # Open / Closing / Stopped self.log.logging( "Tuya", "Debug", "tuya_curtain_response - Open/Close/Stopped action Nwkid: %s/%s %s" % (NwkId, srcEp, data), NwkId, ) store_tuya_attribute(self, NwkId, "Action", data) elif dp == 0x02: # Percent Control self.log.logging( "Tuya", "Debug", "tuya_curtain_response - Percentage Control action Nwkid: %s/%s %s" % (NwkId, srcEp, data), NwkId, ) store_tuya_attribute(self, NwkId, "PercentControl", data) elif dp in (0x03, 0x07): # Curtain Percentage # We need to translate percentage into Analog value between 0 - 255 level = ((int(data, 16)) * 255) // 100 slevel = "%02x" % level self.log.logging( "Tuya", "Debug", "tuya_curtain_response - Curtain Percentage Nwkid: %s/%s Level %s -> %s" % (NwkId, srcEp, data, level), NwkId, ) store_tuya_attribute(self, NwkId, "PercentState", data) MajDomoDevice(self, Devices, NwkId, srcEp, "0008", slevel) elif dp == 0x05: self.log.logging( "Tuya", "Debug", "tuya_curtain_response - Direction state Nwkid: %s/%s Action %s" % (NwkId, srcEp, data), NwkId, ) store_tuya_attribute(self, NwkId, "DirectionState", data) elif dp in (0x67, 0x69): level = ((int(data, 16)) * 255) // 100 slevel = "%02x" % level self.log.logging( "Tuya", "Debug", "tuya_curtain_response - ?????? Nwkid: %s/%s data %s --> %s" % (NwkId, srcEp, data, level), NwkId, ) MajDomoDevice(self, Devices, NwkId, srcEp, "0008", slevel) store_tuya_attribute(self, NwkId, "dp_%s" % dp, data) else: attribute_name = "UnknowDp_0x%02x_Dt_0x%02x" % (dp, datatype) store_tuya_attribute(self, NwkId, attribute_name, data)
def tuya_switch_response(self, Devices, _ModelName, NwkId, srcEp, ClusterID, dstNWKID, dstEP, dp, datatype, data): if dp == 0x01: # Switch 1 ( Right in case of 2gangs) self.log.logging( "Tuya", "Debug", "tuya_switch_response - Dp 0x01 Nwkid: %s/%s decodeDP: %04x data: %s" % (NwkId, srcEp, dp, data), NwkId, ) MajDomoDevice(self, Devices, NwkId, "01", "0006", data) elif dp == 0x02: # Switch 2 (Left in case of 2 Gangs) self.log.logging( "Tuya", "Debug", "tuya_switch_response - Dp 0x02 Nwkid: %s/%s decodeDP: %04x data: %s" % (NwkId, srcEp, dp, data), NwkId, ) MajDomoDevice(self, Devices, NwkId, "02", "0006", data) elif dp == 0x03: # Switch 3 self.log.logging( "Tuya", "Debug", "tuya_switch_response - Dp 0x03 Nwkid: %s/%s decodeDP: %04x data: %s" % (NwkId, srcEp, dp, data), NwkId, ) MajDomoDevice(self, Devices, NwkId, "03", "0006", data) elif dp == 0x0D: # All switches self.log.logging( "Tuya", "Debug", "tuya_switch_response - Dp 0x03 Nwkid: %s/%s decodeDP: %04x data: %s" % (NwkId, srcEp, dp, data), NwkId, ) MajDomoDevice(self, Devices, NwkId, "01", "0006", data) MajDomoDevice(self, Devices, NwkId, "02", "0006", data) MajDomoDevice(self, Devices, NwkId, "03", "0006", data) elif dp == 0x0E: # Relay Status self.log.logging( "Tuya", "Debug", "tuya_switch_response - Dp 0x0e Nwkid: %s/%s decodeDP: %04x data: %s" % (NwkId, srcEp, dp, data), NwkId, ) store_tuya_attribute(self, NwkId, "RelayStatus", int(data, 16)) elif dp == 0x0F: # Light Indicator self.log.logging( "Tuya", "Debug", "tuya_switch_response - Dp 0x0f Nwkid: %s/%s decodeDP: %04x data: %s" % (NwkId, srcEp, dp, data), NwkId, ) store_tuya_attribute(self, NwkId, "LightIndicator", int(data, 16)) else: attribute_name = "UnknowDp_0x%02x_Dt_0x%02x" % (dp, datatype) store_tuya_attribute(self, NwkId, attribute_name, data) self.log.logging( "Tuya", "Debug", "tuya_switch_response - Unknown attribut Nwkid: %s/%s decodeDP: %04x data: %s" % (NwkId, srcEp, dp, data), NwkId, )
def AqaraOppleDecoding(self, Devices, nwkid, Ep, ClusterId, ModelName, payload): if "Model" not in self.ListOfDevices[nwkid]: return _ModelName = self.ListOfDevices[nwkid]["Model"] if ClusterId == "0006": # Top row Command = payload[14:16] self.log.logging( "Lumi", "Debug", "AqaraOppleDecoding - Nwkid: %s, Ep: %s, ON/OFF, Cmd: %s" % (nwkid, Ep, Command), nwkid) MajDomoDevice(self, Devices, nwkid, "01", "0006", Command) elif ClusterId == "0008": # Middle row StepMode = payload[14:16] StepSize = payload[16:18] TransitionTime = payload[18:22] unknown = payload[22:26] OPPLE_MAPPING_4_6_BUTTONS = { "click_left": "00", "click_right": "01", "long_left": "02", "long_right": "03", "release": "04", } action = opal_actionFromCluster0008( StepMode) + opal_buttonFromCluster0008(StepSize) self.log.logging( "Lumi", "Debug", "AqaraOppleDecoding - Nwkid: %s, Ep: %s, LvlControl, StepMode: %s, StepSize: %s, TransitionTime: %s, unknown: %s action: %s" % (nwkid, Ep, StepMode, StepSize, TransitionTime, unknown, action), nwkid, ) if action in OPPLE_MAPPING_4_6_BUTTONS: MajDomoDevice(self, Devices, nwkid, "02", "0006", OPPLE_MAPPING_4_6_BUTTONS[action]) elif ClusterId == "0300": # Botton row (need firmware) StepMode = payload[14:16] EnhancedStepSize = payload[16:20] TransitionTime = payload[20:24] ColorTempMinimumMired = payload[24:28] ColorTempMaximumMired = payload[28:32] unknown = payload[32:36] OPPLE_MAPPING_4_6_BUTTONS = {} if _ModelName == "lumi.remote.b686opcn01": # Ok OPPLE_MAPPING_4_6_BUTTONS = { "click_left": "00", "click_right": "01", "long_left": "02", "long_right": "03", "release": "04", } elif _ModelName in ( "lumi.remote.b486opcn01", "lumi.remote.b286opcn01"): # Not seen, just assumption OPPLE_MAPPING_4_6_BUTTONS = { "click_left": "02", "click_right": "03", } else: return action = opal_actionFromCluster0300(StepMode, EnhancedStepSize) self.log.logging( "Lumi", "Debug", "AqaraOppleDecoding - Nwkid: %s, Ep: %s, ColorControl, StepMode: %s, EnhancedStepSize: %s, TransitionTime: %s, ColorTempMinimumMired: %s, ColorTempMaximumMired: %s action: %s" % ( nwkid, Ep, StepMode, EnhancedStepSize, TransitionTime, ColorTempMinimumMired, ColorTempMaximumMired, action, ), nwkid, ) if action in OPPLE_MAPPING_4_6_BUTTONS: MajDomoDevice(self, Devices, nwkid, "03", "0006", OPPLE_MAPPING_4_6_BUTTONS[action]) return
def tuya_energy_response(self, Devices, _ModelName, NwkId, srcEp, ClusterID, dstNWKID, dstEP, dp, datatype, data): if dp == 0x01 and datatype == 0x01: # State On/Off self.log.logging( "Tuya", "Debug", "tuya_energy_response - Model: %s State Nwkid: %s/%s dp: %02x data type: %s data: %s" % (_ModelName, NwkId, srcEp, dp, datatype, data), NwkId, ) store_tuya_attribute(self, NwkId, "State", data) MajDomoDevice(self, Devices, NwkId, "01", "0006", data) elif dp == 0x09: # Countdown self.log.logging( "Tuya", "Debug", "tuya_energy_response - Model: %s State Nwkid: %s/%s dp: %02x data type: %s data: %s" % (_ModelName, NwkId, srcEp, dp, datatype, data), NwkId, ) store_tuya_attribute(self, NwkId, "Countdown", data) elif dp == 0x11: # Total Energy * 10 analogValue = int(data, 16) * 10 self.log.logging( "Tuya", "Debug", "tuya_energy_response - Model: %s Energy Nwkid: %s/%s dp: %02x data type: %s data: %s" % (_ModelName, NwkId, srcEp, dp, datatype, data), NwkId, ) MajDomoDevice(self, Devices, NwkId, "01", "0702", str(analogValue), Attribute_="0000") checkAndStoreAttributeValue(self, NwkId, "01", "0702", "0000", analogValue) # Store int store_tuya_attribute(self, NwkId, "Energy", str(analogValue)) elif dp == 0x12: # Current (Ampere) / 1000 analogValue = int(data, 16) / 1000 self.log.logging( "Tuya", "Debug", "tuya_energy_response - Model: %s Current Nwkid: %s/%s dp: %02x data type: %s data: %s" % (_ModelName, NwkId, srcEp, dp, datatype, data), NwkId, ) MajDomoDevice(self, Devices, NwkId, "01", "0b04", str(analogValue), Attribute_="0508") store_tuya_attribute(self, NwkId, "Current", str(analogValue)) elif dp == 0x13: # Power / 10 analogValue = int(data, 16) / 10 self.log.logging( "Tuya", "Debug", "tuya_energy_response - Model: %s Power Nwkid: %s/%s dp: %02x data type: %s data: %s" % (_ModelName, NwkId, srcEp, dp, datatype, data), NwkId, ) checkAndStoreAttributeValue(self, NwkId, "01", "0702", "0400", str(analogValue)) MajDomoDevice(self, Devices, NwkId, "01", "0702", str(analogValue)) store_tuya_attribute(self, NwkId, "InstantPower", str(analogValue)) # Store str elif dp == 0x14: # Voltage / 10 analogValue = int(data, 16) / 10 self.log.logging( "Tuya", "Debug", "tuya_energy_response - Model: %s Voltage Nwkid: %s/%s dp: %02x data type: %s data: %s" % (_ModelName, NwkId, srcEp, dp, datatype, data), NwkId, ) MajDomoDevice(self, Devices, NwkId, "01", "0001", str(analogValue)) store_tuya_attribute(self, NwkId, "Voltage", str(analogValue)) elif dp == 0x0E: # tuya_switch_relay_status store_tuya_attribute(self, NwkId, "RelayStatus", data) elif dp == 0x0F: # Led Indicator store_tuya_attribute(self, NwkId, "LedIndicator", data) elif dp == 0x1D: store_tuya_attribute(self, NwkId, "ChildLock", data) else: self.log.logging( "Tuya", "Debug", "tuya_energy_response - Model: %s Unknow Nwkid: %s/%s dp: %02x data type: %s data: %s" % (_ModelName, NwkId, srcEp, dp, datatype, data), NwkId, )
def AC201_read_AC_status_response(self, Devices, NwkId, Ep, payload): # Command 0x02 self.log.logging( "CasaIA", "Debug", "read_AC_status_response %s payload: %s" % (NwkId, payload), NwkId) status = payload[0:2] device_type = payload[2:4] device_id = payload[4:6] pairing_code = struct.unpack("H", struct.pack(">H", int(payload[6:10], 16)))[0] current_temp = struct.unpack("H", struct.pack(">H", int(payload[10:14], 16)))[0] system_mode = payload[14:16] heat_setpoint = struct.unpack("H", struct.pack(">H", int(payload[16:20], 16)))[0] cool_stepoint = struct.unpack("H", struct.pack(">H", int(payload[20:24], 16)))[0] fan_mode = payload[24:26] self.log.logging( "CasaIA", "Debug", "read_AC_status_response Status: %s device_type: %s device_id: %s pairing_code: %s current_temp: %s system_mode: %s heat_setpoint: %s cool_setpoint: %s fan_mode: %s" % ( status, device_type, device_id, pairing_code, current_temp, system_mode, heat_setpoint, cool_stepoint, fan_mode, ), NwkId, ) store_casaia_attribute(self, NwkId, "DeviceType", device_type) store_casaia_attribute(self, NwkId, "ModuleIRCode", str(pairing_code), device_id=device_id) store_casaia_attribute(self, NwkId, "DeviceStatus", status, device_id=device_id) store_casaia_attribute(self, NwkId, "CurrentTemp", current_temp, device_id=device_id) store_casaia_attribute(self, NwkId, "SystemMode", system_mode, device_id=device_id) store_casaia_attribute(self, NwkId, "HeatSetpoint", heat_setpoint, device_id=device_id) store_casaia_attribute(self, NwkId, "CoolSetpoint", cool_stepoint, device_id=device_id) store_casaia_attribute(self, NwkId, "FanMode", fan_mode, device_id=device_id) # Update Current Temperature Widget temp = round(current_temp / 100, 1) self.log.logging( "CasaIA", "Debug", "read_AC_status_response Status: %s request Update Temp: %s" % (NwkId, temp), NwkId) MajDomoDevice(self, Devices, NwkId, Ep, "0402", temp) # Update Fan Mode self.log.logging( "CasaIA", "Debug", "read_AC_status_response Status: %s request Update Fan Mode: %s" % (NwkId, fan_mode), NwkId) if system_mode == "00": MajDomoDevice(self, Devices, NwkId, Ep, "0202", "00") else: MajDomoDevice(self, Devices, NwkId, Ep, "0202", fan_mode) # Update SetPoint if str(check_hot_cold_setpoint(self, NwkId)) == "Heat": setpoint = str(round(heat_setpoint / 100, 1)) self.log.logging( "CasaIA", "Debug", "read_AC_status_response Status: %s request Update Setpoint: %s" % (NwkId, setpoint), NwkId, ) MajDomoDevice(self, Devices, NwkId, Ep, "0201", setpoint, Attribute_="0012") elif str(check_hot_cold_setpoint(self, NwkId)) == "Cool": setpoint = str(round(cool_stepoint / 100, 1)) self.log.logging( "CasaIA", "Debug", "read_AC_status_response Status: %s request Update Setpoint: %s" % (NwkId, setpoint), NwkId, ) MajDomoDevice(self, Devices, NwkId, Ep, "0201", setpoint, Attribute_="0012") # Update System Mode self.log.logging( "CasaIA", "Debug", "read_AC_status_response Status: %s request Update System Mode: %s" % (NwkId, system_mode), NwkId, ) MajDomoDevice(self, Devices, NwkId, Ep, "0201", system_mode, Attribute_="001c")
def readXiaomiCluster(self, Devices, MsgSQN, MsgSrcAddr, MsgSrcEp, MsgClusterId, MsgAttrID, MsgAttType, MsgAttSize, MsgClusterData): if "Model" not in self.ListOfDevices[MsgSrcAddr]: return model = self.ListOfDevices[MsgSrcAddr]["Model"] # Taging: https://github.com/dresden-elektronik/deconz-rest-plugin/issues/42#issuecomment-370152404 # 0x0624 might be the LQI indicator and 0x0521 the RSSI dB sBatteryLvl = retreive4Tag("0121", MsgClusterData) # 16BitUint sTemp2 = retreive4Tag("0328", MsgClusterData) # Device Temperature (int8) stag04 = retreive4Tag("0424", MsgClusterData) sRSSI = retreive4Tag("0521", MsgClusterData) # RSSI (16BitUint) sCountEvent = retreive4Tag("0541", MsgClusterData) sLQI = retreive4Tag("0624", MsgClusterData) # LQI sLighLevel = retreive4Tag("0b21", MsgClusterData) # 16BitUint sOnOff = retreive4Tag("6410", MsgClusterData)[0:2] # Bool sOnOff2 = retreive4Tag("6420", MsgClusterData)[ 0:2] # OnOff for Aqara Bulb / Current position lift for lumi.curtain sTemp = retreive4Tag("6429", MsgClusterData) sOnOff3 = retreive4Tag("6510", MsgClusterData) # On/off lumi.ctrl_ln2 EP 02 (Bool) sHumid = retreive4Tag("6521", MsgClusterData) # 16BitUint sHumid2 = retreive4Tag("6529", MsgClusterData) sLevel = retreive4Tag("6520", MsgClusterData)[0:2] # Dim level for Aqara Bulb sPress = retreive8Tag("662b", MsgClusterData) sConsumption = retreive8Tag("9539", MsgClusterData) # Cummulative Consumption sVoltage = retreive8Tag("9639", MsgClusterData) # Voltage sCurrent = retreive8Tag("9739", MsgClusterData) # Ampere sPower = retreive8Tag("9839", MsgClusterData) # Power Watt if sCountEvent != "": value = int(sCountEvent, 16) store_lumi_attribute(self, MsgSrcAddr, "EventCounter", value) self.log.logging( "Lumi", "Debug", "ReadCluster - %s/%s Saddr: %s Count of events sent %s/%s" % (MsgClusterId, MsgAttrID, MsgSrcAddr, sCountEvent, value), MsgSrcAddr, ) if sTemp2 != "": self.log.logging( "Lumi", "Debug", "ReadCluster - %s/%s Saddr: %s sTemp2 %s Temp2 %s" % (MsgClusterId, MsgAttrID, MsgSrcAddr, sTemp2, int(sTemp2, 16)), MsgSrcAddr, ) store_lumi_attribute(self, MsgSrcAddr, "DeviceTemperature", round(int(sTemp2, 16) / 100, 1)) if sConsumption != "": # Consumption/Summation consumption = (struct.unpack( "f", struct.pack(">I", int(sConsumption, 16)))[0]) * 1000 self.log.logging( "Lumi", "Debug", "ReadCluster - %s/%s Saddr: %s sConsumption %s Consumption %s" % (MsgClusterId, MsgAttrID, MsgSrcAddr, sConsumption, consumption), ) store_lumi_attribute(self, MsgSrcAddr, "Consumption", consumption) if model in XIAOMI_POWERMETER_EP: EPforMeter = XIAOMI_POWERMETER_EP[model] else: EPforMeter = MsgSrcEp checkAndStoreAttributeValue(self, MsgSrcAddr, EPforMeter, "0702", "0000", consumption) if sVoltage != "": voltage = struct.unpack("f", struct.pack(">I", int(sVoltage, 16)))[0] self.log.logging( "Lumi", "Debug", "ReadCluster - %s/%s Saddr: %s Voltage %s" % (MsgClusterId, MsgAttrID, MsgSrcAddr, voltage)) checkAndStoreAttributeValue(self, MsgSrcAddr, MsgSrcEp, "0001", "0000", voltage) store_lumi_attribute(self, MsgSrcAddr, "Voltage", voltage) # Update Voltage ( cluster 0001 ) MajDomoDevice(self, Devices, MsgSrcAddr, MsgSrcEp, "0001", voltage) if sCurrent != "": current = struct.unpack("f", struct.pack(">I", int(sCurrent, 16)))[0] self.log.logging( "Lumi", "Debug", "ReadCluster - %s/%s Saddr: %s Courant %s" % (MsgClusterId, MsgAttrID, MsgSrcAddr, current)) store_lumi_attribute(self, MsgSrcAddr, "Current", current) if sPower != "": # Instant Power power = struct.unpack("f", struct.pack(">I", int(sPower, 16)))[0] if power > 0x7FFFFFFFFFFFFFFF: self.log.logging( "Lumi", "Eror", "ReadCluster - %s/%s Saddr: %s sPower %s Power %s (Overflow)" % (MsgClusterId, MsgAttrID, MsgSrcAddr, sPower, power), ) return self.log.logging( "Lumi", "Debug", "ReadCluster - %s/%s Saddr: %s sPower %s Power %s" % (MsgClusterId, MsgAttrID, MsgSrcAddr, sPower, power), ) store_lumi_attribute(self, MsgSrcAddr, "Power", power) if model in XIAOMI_POWERMETER_EP: EPforPower = XIAOMI_POWERMETER_EP[model] else: EPforPower = MsgSrcEp checkAndStoreAttributeValue(self, MsgSrcAddr, EPforPower, "0702", "0400", str(power)) # Update Power Widget MajDomoDevice(self, Devices, MsgSrcAddr, EPforPower, "0702", str(power)) if sLighLevel != "": value = struct.unpack(">H", struct.pack("H", int(sLighLevel, 16)))[0] if model in ("lumi.sensor_motion", "lumi.sensor_motion.aq2"): # Lux store_lumi_attribute(self, MsgSrcAddr, "Lux", value) MajDomoDevice(self, Devices, MsgSrcAddr, MsgSrcEp, "0400", str(value)) else: self.log.logging( "Lumi", "Debug", "ReadCluster - %s/%s Saddr: %s Light Level: %s" % (MsgClusterId, MsgAttrID, MsgSrcAddr, value), MsgSrcAddr, ) if sRSSI != "": # RSSI = struct.unpack('>H',struct.pack('H',int(sRSSI,16)))[0] RSSI = int(sRSSI[0:2], 16) - 256 self.log.logging( "Lumi", "Debug", "ReadCluster - %s/%s Saddr: %s RSSI: %s/%s" % (MsgClusterId, MsgAttrID, MsgSrcAddr, sRSSI, RSSI), MsgSrcAddr, ) store_lumi_attribute(self, MsgSrcAddr, "RSSI dB", RSSI) if sLQI != "": LQI = int(sLQI, 16) self.log.logging( "Lumi", "Debug", "ReadCluster - %s/%s Saddr: %s LQI: %s/%s" % (MsgClusterId, MsgAttrID, MsgSrcAddr, sLQI, LQI), MsgSrcAddr, ) store_lumi_attribute(self, MsgSrcAddr, "LQI", sLQI) if (sBatteryLvl != "" and self.ListOfDevices[MsgSrcAddr]["MacCapa"] != "8e" and self.ListOfDevices[MsgSrcAddr]["MacCapa"] != "84" and self.ListOfDevices[MsgSrcAddr]["PowerSource"] != "Main"): voltage = "%s%s" % (str(sBatteryLvl[2:4]), str(sBatteryLvl[0:2])) voltage = int(voltage, 16) ValueBattery = voltage2batteryP(voltage, 3150, 2750) self.log.logging( "Lumi", "Debug", "ReadCluster - %s/%s Saddr: %s Battery: %s Voltage: %s MacCapa: %s PowerSource: %s" % ( MsgClusterId, MsgAttrID, MsgSrcAddr, ValueBattery, voltage, self.ListOfDevices[MsgSrcAddr]["MacCapa"], self.ListOfDevices[MsgSrcAddr]["PowerSource"], ), MsgSrcAddr, ) self.ListOfDevices[MsgSrcAddr]["Battery"] = ValueBattery self.ListOfDevices[MsgSrcAddr]["BatteryUpdateTime"] = int(time.time()) Update_Battery_Device(self, Devices, MsgSrcAddr, ValueBattery) checkAndStoreAttributeValue(self, MsgSrcAddr, MsgSrcEp, "0001", "0000", voltage) store_lumi_attribute(self, MsgSrcAddr, "BatteryVoltage", voltage) if sTemp != "": Temp = struct.unpack("h", struct.pack(">H", int(sTemp, 16)))[0] if Temp != -10000: ValueTemp = round(Temp / 100, 1) self.log.logging( "Lumi", "Debug", "ReadCluster - 0000/ff01 Saddr: " + str(MsgSrcAddr) + " Temperature : " + str(ValueTemp), MsgSrcAddr, ) MajDomoDevice(self, Devices, MsgSrcAddr, MsgSrcEp, "0402", ValueTemp) checkAndStoreAttributeValue(self, MsgSrcAddr, MsgSrcEp, "0402", "0000", Temp) if sHumid != "": ValueHumid = struct.unpack("H", struct.pack(">H", int(sHumid, 16)))[0] ValueHumid = round(ValueHumid / 100, 1) self.log.logging( "Lumi", "Debug", "ReadCluster - 0000/ff01 Saddr: " + str(MsgSrcAddr) + " Humidity : " + str(ValueHumid), MsgSrcAddr, ) MajDomoDevice(self, Devices, MsgSrcAddr, MsgSrcEp, "0405", ValueHumid) checkAndStoreAttributeValue(self, MsgSrcAddr, MsgSrcEp, "0405", "0000", ValueHumid) if sHumid2 != "": Humid2 = struct.unpack("h", struct.pack(">H", int(sHumid2, 16)))[0] ValueHumid2 = round(Humid2 / 100, 1) self.log.logging( "Lumi", "Debug", "ReadCluster - 0000/ff01 Saddr: " + str(MsgSrcAddr) + " Humidity2 : " + str(ValueHumid2), MsgSrcAddr, ) if sPress != "": Press = "%s%s%s%s" % (str(sPress[6:8]), str( sPress[4:6]), str(sPress[2:4]), str(sPress[0:2])) try: ValuePress = round( (struct.unpack("i", struct.pack("i", int(Press, 16)))[0]) / 100, 1) except Exception as e: self.log.logging( "Lumi", "Error", "ReadCluster - 0000/ff01 Saddr: %s Wrong Atmospheric Pressure: orig: %s, convert: %s Error: %s" % (MsgSrcAddr, sPress, Press, e), MsgSrcAddr, ) return self.log.logging( "Lumi", "Debug", "ReadCluster - 0000/ff01 Saddr: " + str(MsgSrcAddr) + " Atmospheric Pressure : " + str(ValuePress), MsgSrcAddr, ) MajDomoDevice(self, Devices, MsgSrcAddr, MsgSrcEp, "0403", ValuePress) checkAndStoreAttributeValue(self, MsgSrcAddr, MsgSrcEp, "0403", "0000", sPress) if sOnOff != "": if self.ListOfDevices[MsgSrcAddr]["Model"] == "lumi.sensor_wleak.aq1": self.log.logging( "Lumi", "Debug", " --- Do not process this sOnOff: %s because it is a leak sensor : %s" % (sOnOff, MsgSrcAddr), MsgSrcAddr, ) # Wleak send status via 0x8401 and Zone change. Looks like we get some false positive here. return self.log.logging( "Lumi", "Debug", "ReadCluster - 0000/ff01 Saddr: %s sOnOff: %s" % (MsgSrcAddr, sOnOff), MsgSrcAddr) MajDomoDevice(self, Devices, MsgSrcAddr, MsgSrcEp, "0006", sOnOff) checkAndStoreAttributeValue(self, MsgSrcAddr, MsgSrcEp, "0006", "0000", sOnOff) if sOnOff2 != "" and self.ListOfDevices[MsgSrcAddr][ "MacCapa"] == "8e": # Aqara Bulb / Lumi Curtain - Position if self.ListOfDevices[MsgSrcAddr]["Model"] == "lumi.sensor_wleak.aq1": self.log.logging( "Lumi", "Debug", " --- Do not process this sOnOff: %s because it is a leak sensor : %s" % (sOnOff, MsgSrcAddr), MsgSrcAddr, ) # Wleak send status via 0x8401 and Zone change. Looks like we get some false positive here. return self.log.logging( "Lumi", "Debug", "ReadCluster - 0000/ff01 Saddr: %s sOnOff2: %s" % (MsgSrcAddr, sOnOff2), MsgSrcAddr) MajDomoDevice(self, Devices, MsgSrcAddr, MsgSrcEp, "0006", sOnOff2) checkAndStoreAttributeValue(self, MsgSrcAddr, MsgSrcEp, "0006", "0000", sOnOff) if sLevel != "": self.log.logging( "Lumi", "Debug", "ReadCluster - 0000/ff01 Saddr: %s sLevel: %s" % (MsgSrcAddr, sLevel), MsgSrcAddr) MajDomoDevice(self, Devices, MsgSrcAddr, MsgSrcEp, "0008", sLevel) checkAndStoreAttributeValue(self, MsgSrcAddr, MsgSrcEp, "0008", "0000", sLevel)
def ikea_remote_switch_8095(self, Devices, MsgSrcAddr, MsgEP, MsgClusterId, MsgCmd, unknown_): MajDomoDevice(self, Devices, MsgSrcAddr, MsgEP, "0006", MsgCmd) self.ListOfDevices[MsgSrcAddr]["Ep"][MsgEP][MsgClusterId][ "0000"] = "Cmd: %s, %s" % (MsgCmd, unknown_)
def tuya_smartair_response(self, Devices, _ModelName, NwkId, srcEp, ClusterID, dstNWKID, dstEP, dp, datatype, data): # cmd | status | transId | dp | DataType | fn | len | Data # 01 00 00 12 02 00 04 00000101 257 --- Temperature # 01 00 00 13 02 00 04 0000018d 397 --- Humidity Confirmed # 01 00 01 16 02 00 04 00000002 2 --- 0.002 ppm Formaldéhyde détécté # 01 00 01 15 02 00 04 00000001 1 --- VOC 0.1 ppm - Confirmed # 01 00 01 02 02 00 04 00000172 370 --- CO2 - Confirmed # The device is flooding data every seconds. This could have the impact to flow the Domoticz database/ if ("Param" in self.ListOfDevices[NwkId] and "AcquisitionFrequency" in self.ListOfDevices[NwkId]["Param"] and self.ListOfDevices[NwkId]["Param"]["AcquisitionFrequency"] > 0): previous_ts = get_tuya_attribute(self, NwkId, "TimeStamp_%s" % dp) if previous_ts and (previous_ts + self.ListOfDevices[NwkId]["Param"] ["AcquisitionFrequency"]) > time.time(): return store_tuya_attribute(self, NwkId, "TimeStamp_%s" % dp, time.time()) # Temp/Humi/CarbonDioxyde/CH20/Voc if dp == 0x02: # CO2 ppm co2_Attribute = "0005" co2_ppm = int(data, 16) store_tuya_attribute( self, NwkId, "CO2 ppm", co2_ppm, ) MajDomoDevice(self, Devices, NwkId, srcEp, "0402", co2_ppm, Attribute_=co2_Attribute) elif dp == 0x12: # Temperature temp = int(data, 16) / 10 store_tuya_attribute(self, NwkId, "Temp", temp) MajDomoDevice(self, Devices, NwkId, srcEp, "0402", temp) elif dp == 0x13: # Humidity % humi = int(data, 16) // 10 store_tuya_attribute(self, NwkId, "Humi", humi) MajDomoDevice(self, Devices, NwkId, srcEp, "0405", humi) elif dp == 0x15: # VOC ppm voc_Attribute = "0003" voc_ppm = int(data, 16) / 10 store_tuya_attribute(self, NwkId, "VOC ppm", voc_ppm) MajDomoDevice(self, Devices, NwkId, srcEp, "0402", voc_ppm, Attribute_=voc_Attribute) elif dp == 0x16: # Formaldéhyde µg/m3 ( Méthanal / CH2O_ppm) ch2O_Attribute = "0004" CH2O_ppm = int(data, 16) store_tuya_attribute(self, NwkId, "CH2O ppm", CH2O_ppm) MajDomoDevice(self, Devices, NwkId, srcEp, "0402", CH2O_ppm, Attribute_=ch2O_Attribute)
def inRawAps( self, Devices, srcnwkid, srcep, cluster, dstnwkid, dstep, Sqn, GlobalCommand, ManufacturerCode, Command, Data, payload, ): """ This function is called by Decode8002 """ if srcnwkid not in self.ListOfDevices: return self.log.logging( "inRawAPS", "Debug", "inRawAps Nwkid: %s Ep: %s Cluster: %s ManufCode: %s Cmd: %s Data: %s" % (srcnwkid, srcep, cluster, ManufacturerCode, Command, Data), srcnwkid, ) if cluster == "0020": # Poll Control ( Not implemented in firmware ) # self.log.logging("inRawAPS","Log","Cluster 0020 -- POLL CLUSTER") receive_poll_cluster(self, srcnwkid, srcep, cluster, dstnwkid, dstep, Sqn, ManufacturerCode, Command, Data) return if cluster == "0019": # OTA Cluster # self.log.logging("inRawAPS","Log","Cluster 0019 -- OTA CLUSTER") if Command == "01": # Query Next Image Request self.log.logging("inRawAPS", "Log", "Cluster 0019 -- OTA CLUSTER Command 01") # fieldcontrol = Data[0:2] manufcode = "%04x" % struct.unpack( "H", struct.pack(">H", int(Data[2:6], 16)))[0] imagetype = "%04x" % struct.unpack( "H", struct.pack(">H", int(Data[6:10], 16)))[0] currentVersion = "%08x" % struct.unpack( "I", struct.pack(">I", int(Data[10:18], 16)))[0] self.log.logging( "inRawAPS", "Log", "Cluster 0019 -- OTA CLUSTER Command 01Device %s Request OTA with current ManufCode: %s ImageType: %s Version: %s" % (srcnwkid, manufcode, imagetype, currentVersion), ) if "OTA" not in self.ListOfDevices[srcnwkid]: self.ListOfDevices[srcnwkid]["OTA"] = {} self.ListOfDevices[srcnwkid]["OTA"]["ManufacturerCode"] = manufcode self.ListOfDevices[srcnwkid]["OTA"]["ImageType"] = imagetype self.ListOfDevices[srcnwkid]["OTA"][ "CurrentImageVersion"] = currentVersion return if cluster == "0500": # IAS Cluster # "00": # "01" # inRawAps 56ba/23 Cluster 0500 Manuf: None Command: 01 Data: 0d001510 Payload: 1922010d001510 # 0x00 Zone Enroll Response # 0x01 Initiate Normal Operation Mode # 0x02 Initiate Test Mode enroll_response_code = Data[:2] zone_id = Data[2:4] if Command == "00": pass elif Command == "01": pass elif Command == "02": pass return if cluster == "0501": # IAS ACE # "00" # "01" Arm Day (Home Zones Only) - Command Arm 0x00 - Payload 0x01 # "02" Emergency - Command Emergency 0x02 # "03" Arm All Zones - Command Arm 0x00 - Payload Arm all Zone 0x03 # "04" Disarm - Command 0x00 - Payload Disarm 0x00 if Command == "00" and Data[0:2] == "00": # Disarm MajDomoDevice(self, Devices, srcnwkid, srcep, "0006", "04") elif Command == "00" and Data[0:2] == "01": # Command Arm Day (Home Zones Only) MajDomoDevice(self, Devices, srcnwkid, srcep, "0006", "01") elif Command == "00" and Data[0:2] == "03": # Arm All Zones MajDomoDevice(self, Devices, srcnwkid, srcep, "0006", "03") elif Command == "02": # Emergency MajDomoDevice(self, Devices, srcnwkid, srcep, "0006", "02") return if cluster == "0300": # Color Control if Command == "0a": # Move to Color Temperature color_temp_mired = payload[8:10] + payload[6:8] transition_time = payload[12:14] + payload[10:12] # self.log.logging("inRawAPS","Log","Move to Color Temp - Command: %s Temp_Mired: %s TransitionTime: %s" %(Command, color_temp_mired, transition_time)) if "Model" in self.ListOfDevices[srcnwkid] and self.ListOfDevices[ srcnwkid]["Model"] == "tint-Remote-white": COLOR_SCENE_WHITE = { "022b": "09", "01dc": "10", "01a1": "11", "0172": "12", "00fa": "13", "00c8": "14", "0099": "15", } if color_temp_mired in COLOR_SCENE_WHITE: MajDomoDevice(self, Devices, srcnwkid, srcep, "0008", COLOR_SCENE_WHITE[color_temp_mired]) elif Command == "4b": # Move Color Temperature move_mode = payload[6:8] rate = payload[10:12] + payload[8:10] color_temp_min_mireds = payload[14:16] + payload[12:14] color_temp_max_mireds = payload[18:20] + payload[16:18] # self.log.logging("inRawAPS","Log","Move Color Temperature - Command: %s mode: %s rate: %s min_mired: %s max_mired: %s" %( # Command, move_mode, rate, color_temp_min_mireds, color_temp_max_mireds)) if "Model" in self.ListOfDevices[srcnwkid] and self.ListOfDevices[ srcnwkid]["Model"] == "tint-Remote-white": if move_mode == "01": # Down MajDomoDevice(self, Devices, srcnwkid, srcep, "0008", "16") elif move_mode == "03": # Up MajDomoDevice(self, Devices, srcnwkid, srcep, "0008", "17") elif Command == "47": # Stop Move Step # self.log.logging("inRawAPS","Log","Stop Move Step - Command: %s" %Command) if "Model" in self.ListOfDevices[srcnwkid] and self.ListOfDevices[ srcnwkid]["Model"] == "tint-Remote-white": MajDomoDevice(self, Devices, srcnwkid, srcep, "0008", "18") else: self.log.logging("inRawAPS", "Log", "Unknown Color Control Command: %s" % Command) return if cluster == "0102": # Window Covering if ("Model" in self.ListOfDevices[srcnwkid] and self.ListOfDevices[srcnwkid]["Model"] == "TRADFRI openclose remote"): ikea_openclose_remote(self, Devices, srcnwkid, srcep, Command, Data, Sqn) return if Command == "00": # Up/Open self.log.logging("inRawAPS", "Log", "Window Covering - Up/Open Command") elif Command == "01": # Down / Close self.log.logging("inRawAPS", "Log", "Window Covering - Down/Close Command") elif Command == "02": # Stop self.log.logging("inRawAPS", "Log", "Window Covering - Stop Command") elif Command == "04": # Go To Lift Value self.log.logging( "inRawAPS", "Log", "Window Covering - Go To Lift value Command %s" % Data[0:]) elif Command == "05": # Go To Lift Percentage self.log.logging( "inRawAPS", "Log", "Window Covering - Go To Lift percentage Command %s" % Data[0:]) elif Command == "07": # Go to Tilt Value self.log.logging( "inRawAPS", "Log", "Window Covering - Go To Tilt value Command %s" % Data[0:]) elif Command == "08": # Go to Tilt Percentage self.log.logging( "inRawAPS", "Log", "Window Covering - Go To Tilt percentage Command %s" % Data[0:]) else: self.log.logging("inRawAPS", "Log", "Unknown Window Covering Command: %s" % Command) if "Manufacturer" not in self.ListOfDevices[srcnwkid]: return manuf = manuf_name = "" if "Manufacturer Name" in self.ListOfDevices[srcnwkid]: manuf_name = self.ListOfDevices[srcnwkid]["Manufacturer Name"] manuf = str(self.ListOfDevices[srcnwkid]["Manufacturer"]) self.log.logging( "inRawAPS", "Debug", "inRawAps Nwkid: %s Ep: %s Cluster: %s ManufCode: %s manuf: %s manuf_name: %s Cmd: %s Data: %s" % (srcnwkid, srcep, cluster, ManufacturerCode, manuf, manuf_name, Command, Data), srcnwkid, ) func = None if manuf in CALLBACK_TABLE: # self.log.logging( "inRawAPS", 'Debug',"Found in CALLBACK_TABLE") func = CALLBACK_TABLE[manuf] # func( self, Devices, srcnwkid, srcep, cluster, dstnwkid, dstep, payload) elif manuf_name in CALLBACK_TABLE2: # self.log.logging( "inRawAPS", 'Debug',"Found in CALLBACK_TABLE2") func = CALLBACK_TABLE2[manuf_name] # func( self, Devices, srcnwkid, srcep, cluster, dstnwkid, dstep, payload) elif manuf_name in TUYA_MANUFACTURER_NAME: func = tuyaReadRawAPS else: self.log.logging( "inRawAPS", "Log", "inRawAps %s/%s Cluster %s Manuf: %s/%s Command: %s Data: %s Payload: %s not processed !!!" % (srcnwkid, srcep, cluster, manuf, manuf_name, Command, Data, payload), ) if func: func(self, Devices, srcnwkid, srcep, cluster, dstnwkid, dstep, payload)