diff --git a/Classes/ZigpyTransport/AppBellows.py b/Classes/ZigpyTransport/AppBellows.py index e889497c4..70fc55b93 100644 --- a/Classes/ZigpyTransport/AppBellows.py +++ b/Classes/ZigpyTransport/AppBellows.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python3btt. # coding: utf-8 -*- # # Author: deufo, badz & pipiche38 @@ -8,6 +8,7 @@ import bellows.config as bellows_conf import bellows.types as t +import zigpy.types as zigpy_t import bellows.zigbee.application import zigpy.config as zigpy_conf import zigpy.device @@ -148,6 +149,9 @@ def handle_leave(self, nwk, ieee): def get_zigpy_version(self): return Classes.ZigpyTransport.AppGeneric.get_zigpy_version(self) + def packet_received(self, packet: zigpy_t.ZigbeePacket) -> None: + return Classes.ZigpyTransport.AppGeneric.packet_received(self,packet) + def handle_message( self, sender: zigpy.device.Device, @@ -160,7 +164,7 @@ def handle_message( dst_addressing=None, )->None: return Classes.ZigpyTransport.AppGeneric.handle_message(self,sender,profile,cluster,src_ep,dst_ep,message, dst_addressing=dst_addressing) - + async def set_zigpy_tx_power(self, power): # EmberConfigTxPowerMode - EZSP_CONFIG_TX_POWER_MODE in EzspConfigId # 0x00: Normal mode diff --git a/Classes/ZigpyTransport/AppDeconz.py b/Classes/ZigpyTransport/AppDeconz.py index 4b109fd8d..1f4c6a39e 100644 --- a/Classes/ZigpyTransport/AppDeconz.py +++ b/Classes/ZigpyTransport/AppDeconz.py @@ -142,6 +142,9 @@ def get_device_ieee(self, nwk): def handle_leave(self, nwk, ieee): Classes.ZigpyTransport.AppGeneric.handle_leave(self, nwk, ieee) + def packet_received(self, packet: t.ZigbeePacket) -> None: + return Classes.ZigpyTransport.AppGeneric.packet_received(self,packet) + def handle_message( self, sender: zigpy.device.Device, diff --git a/Classes/ZigpyTransport/AppGeneric.py b/Classes/ZigpyTransport/AppGeneric.py index 855f2daa2..12cee00f2 100644 --- a/Classes/ZigpyTransport/AppGeneric.py +++ b/Classes/ZigpyTransport/AppGeneric.py @@ -26,6 +26,7 @@ LOGGER = logging.getLogger(__name__) + async def _load_db(self) -> None: pass @@ -34,7 +35,7 @@ async def initialize(self, *, auto_form: bool = False, force_form: bool = False) Starts the network on a connected radio, optionally forming one with random settings if necessary. """ - self.log.logging("TransportZigpy", "Debug", "AppGeneric:initialize auto_form: %s force_form: %s Class: %s" %( auto_form, force_form, type(self))) + self.log.logging("TransportZigpy", "Log", "AppGeneric:initialize auto_form: %s force_form: %s Class: %s" %( auto_form, force_form, type(self))) _retreived_backup = None if "autoRestore" in self.pluginconf.pluginConf and self.pluginconf.pluginConf["autoRestore"]: @@ -45,7 +46,7 @@ async def initialize(self, *, auto_form: bool = False, force_form: bool = False) if _retreived_backup: if self.pluginconf.pluginConf[ "OverWriteCoordinatorIEEEOnlyOnce"]: - LOGGER.debug("Allow eui64 overwrite only once !!!") + LOGGER.debug("Allow eui64 overwrite only once !!!") _retreived_backup.network_info.stack_specific.setdefault("ezsp", {})[ "i_understand_i_can_update_eui64_only_once_and_i_still_want_to_do_it"] = True LOGGER.debug("Last backup retreived: %s" % _retreived_backup ) @@ -122,30 +123,30 @@ def handle_join(self, nwk: t.NWK, ieee: t.EUI64, parent_nwk: t.NWK) -> None: """ Called when a device joins or announces itself on the network. """ + self.log.logging("TransportZigpy", "Debug","handle_join (0x%04x %s)" %(nwk, ieee)) + if str(ieee) in {"00:00:00:00:00:00:00:00", "ff:ff:ff:ff:ff:ff:ff:ff"}: # invalid ieee, drop - LOGGER.debug("ignoring invalid neighbor: %s", ieee) + self.log.logging("TransportZigpy", "Log", "ignoring invalid neighbor: %s", ieee) return ieee = t.EUI64(ieee) try: dev = self.get_device(ieee) - time.sleep(1.0) - LOGGER.info("Device 0x%04x (%s) joined the network", nwk, ieee) + #time.sleep(2.0) + self.log.logging("TransportZigpy", "Debug", "Device 0x%04x (%s) joined the network" %(nwk, ieee)) except KeyError: - time.sleep(1.0) dev = self.add_device(ieee, nwk) - LOGGER.debug("New device 0x%04x (%s) joined the network", nwk, ieee) + #time.sleep(2.0) + self.log.logging("TransportZigpy", "Debug", "New device 0x%04x (%s) joined the network" %(nwk, ieee)) if dev.nwk != nwk: dev.nwk = nwk _update_nkdids_if_needed(self, ieee, dev.nwk ) - LOGGER.debug("Device %s changed id (0x%04x => 0x%04x)", ieee, dev.nwk, nwk) + self.log.logging("TransportZigpy", "Debug", "Device %s changed id (0x%04x => 0x%04x)" %(ieee, dev.nwk, nwk)) + + super(type(self),self).handle_join(nwk, ieee, parent_nwk) -def _update_nkdids_if_needed( self, ieee, new_nwkid ): - _ieee = "%016x" % t.uint64_t.deserialize(ieee.serialize())[0] - _nwk = new_nwkid.serialize()[::-1].hex() - self.callBackUpdDevice(_ieee, _nwk) def get_device_ieee(self, nwk): # Call from the plugin to retreive the ieee @@ -153,9 +154,11 @@ def get_device_ieee(self, nwk): try: dev = super(type(self),self).get_device( nwk=int(nwk,16)) LOGGER.debug("AppZnp get_device nwk: %s returned %s" %( nwk, dev)) + except KeyError: LOGGER.debug("AppZnp get_device raise KeyError nwk: %s !!" %( nwk)) return None + if dev.ieee: return "%016x" % t.uint64_t.deserialize(dev.ieee.serialize())[0] return None @@ -166,94 +169,84 @@ def handle_leave(self, nwk, ieee): self.callBackFunction(plugin_frame) super(type(self),self).handle_leave(nwk, ieee) -def get_zigpy_version(self): - # This is a fake version number. This is just to inform the plugin that we are using ZNP over Zigpy - LOGGER.debug("get_zigpy_version ake version number. !!") - return self.version - -def handle_message( - self, - sender: zigpy.device.Device, - profile: int, - cluster: int, - src_ep: int, - dst_ep: int, - message: bytes, - dst_addressing=None, -) -> None: - +def packet_received( + self, + packet: t.ZigbeePacket + ) -> None: + + """Notify zigpy of a received Zigbee packet.""" + self.log.logging("TransportZigpy", "Debug", "packet_received %s" %(packet)) + + sender = packet.src.address.serialize()[::-1].hex() + addr_mode = int(packet.src.addr_mode) if packet.src.addr_mode is not None else None + profile = int(packet.profile_id) if packet.profile_id is not None else None + cluster = int(packet.cluster_id) if packet.cluster_id is not None else None + src_ep = int(packet.src_ep) if packet.src_ep is not None else None + dst_ep = int(packet.dst_ep) if packet.dst_ep is not None else None + + # self.log.logging("TransportZigpy", "Log", " Src : %s (%s)" %(sender,type(sender))) + # self.log.logging("TransportZigpy", "Log", " AddrMod : %02X" %(addr_mode)) + # self.log.logging("TransportZigpy", "Log", " src Ep : %02X" %(dst_ep)) + # self.log.logging("TransportZigpy", "Log", " dst Ep : %02x" %(dst_ep)) + # self.log.logging("TransportZigpy", "Log", " Profile : %04X" %(profile)) + # self.log.logging("TransportZigpy", "Log", " Cluster : %04X" %(cluster)) + + message = packet.data.serialize() + hex_message = binascii.hexlify(message).decode("utf-8") + dst_addressing = packet.dst.addr_mode if packet.dst else None + + self.log.logging("TransportZigpy", "Debug", "packet_received - %s %s %s %s %s %s %s %s" %( + packet.src, profile, cluster, src_ep, dst_ep, message, hex_message, dst_addressing)) - write_capture_rx_frames( self, sender, profile, cluster, src_ep, dst_ep, message, binascii.hexlify(message).decode("utf-8"), dst_addressing) + hex_message = binascii.hexlify(message).decode("utf-8") + write_capture_rx_frames( self, packet.src, profile, cluster, src_ep, dst_ep, message, hex_message, dst_addressing) - if sender.nwk == 0x0000: + if sender is None or profile is None or cluster is None: + super(type(self),self).packet_received(packet) + + if sender == 0x0000 or ( zigpy.zdo.ZDO_ENDPOINT in (packet.src_ep, packet.dst_ep)): self.log.logging("TransportZigpy", "Debug", "handle_message from Controller Sender: %s Profile: %04x Cluster: %04x srcEp: %02x dstEp: %02x message: %s" %( - str(sender.nwk), profile, cluster, src_ep, dst_ep, binascii.hexlify(message).decode("utf-8"))) - #self.super().handle_message(sender, profile, cluster, src_ep, dst_ep, message) - super(type(self),self).handle_message(sender, profile, cluster, src_ep, dst_ep, message) + sender, profile, cluster, src_ep, dst_ep, hex_message)) + super(type(self),self).packet_received(packet) if cluster == 0x8036: # This has been handle via on_zdo_mgmt_permitjoin_rsp() self.log.logging("TransportZigpy", "Debug", "handle_message 0x8036: %s Profile: %04x Cluster: %04x srcEp: %02x dstEp: %02x message: %s" %( - str(sender.nwk), profile, cluster, src_ep, dst_ep, binascii.hexlify(message).decode("utf-8"))) - self.callBackFunction( build_plugin_8014_frame_content(self, str(sender), binascii.hexlify(message).decode("utf-8") ) ) - super(type(self),self).handle_message(sender, profile, cluster, src_ep, dst_ep, message) + sender, profile, cluster, src_ep, dst_ep, hex_message)) + self.callBackFunction( build_plugin_8014_frame_content(self, sender, hex_message ) ) + super(type(self),self).packet_received(packet) return if cluster == 0x8034: # This has been handle via on_zdo_mgmt_leave_rsp() self.log.logging("TransportZigpy", "Debug", "handle_message 0x8036: %s Profile: %04x Cluster: %04x srcEp: %02x dstEp: %02x message: %s" %( - str(sender.nwk), profile, cluster, src_ep, dst_ep, binascii.hexlify(message).decode("utf-8"))) - self.callBackFunction( build_plugin_8047_frame_content(self, str(sender), binascii.hexlify(message).decode("utf-8")) ) + sender, profile, cluster, src_ep, dst_ep, hex_message)) + self.callBackFunction( build_plugin_8047_frame_content(self, sender, hex_message) ) return - addr = None - if sender.nwk is not None: - addr_mode = 0x02 - addr = sender.nwk.serialize()[::-1].hex() - if profile and cluster: - self.log.logging( - "TransportZigpy", - "Debug", - "handle_message device 1: %s Profile: %04x Cluster: %04x sEP: %s dEp: %s message: %s lqi: %s" % ( - str(sender), profile, cluster, src_ep, dst_ep, binascii.hexlify(message).decode("utf-8"), sender.lqi)), - - elif sender.ieee is not None: - addr = "%016x" % t.uint64_t.deserialize(sender.ieee.serialize())[0] - addr_mode = 0x03 - if profile and cluster: - self.log.logging( - "TransportZigpy", - "Debug", - "handle_message device 1: %s Profile: %04x Cluster: %04x sEP: %s dEp: %s message: %s lqi: %s" % ( - str(sender), profile, cluster, src_ep, dst_ep, binascii.hexlify(message).decode("utf-8"), sender.lqi)), - - if sender.lqi is None: - sender.lqi = 0x00 - - if src_ep == dst_ep == 0x00: - profile = 0x0000 + packet.lqi = 0x00 if packet.lqi is None else packet.lqi + profile = 0x0000 if src_ep == dst_ep == 0x00 else profile if profile and cluster: - self.log.logging( - "TransportZigpy", - "Debug", - "handle_message device 2: %s Profile: %04x Cluster: %04x sEP: %s dEp: %s message: %s lqi: %s" % ( - str(addr), profile, cluster, src_ep, dst_ep, binascii.hexlify(message).decode("utf-8"), sender.lqi), - ) + self.log.logging( "TransportZigpy", "Debug", "handle_message device 2: %s Profile: %04x Cluster: %04x sEP: %s dEp: %s message: %s lqi: %s" %( + sender, profile, cluster, src_ep, dst_ep, hex_message, packet.lqi), ) - if addr: - plugin_frame = build_plugin_8002_frame_content(self, addr, profile, cluster, src_ep, dst_ep, message, sender.lqi, src_addrmode=addr_mode) - self.log.logging("TransportZigpy", "Debug", "handle_message Sender: %s frame for plugin: %s" % (addr, plugin_frame)) - self.callBackFunction(plugin_frame) - else: - self.log.logging( - "TransportZigpy", - "Error", - "handle_message - Issue with sender is %s %s" % (sender.nwk, sender.ieee), - ) + plugin_frame = build_plugin_8002_frame_content(self, sender, profile, cluster, src_ep, dst_ep, message, packet.lqi, src_addrmode=addr_mode) + self.log.logging("TransportZigpy", "Debug", "handle_message Sender: %s frame for plugin: %s" % (sender, plugin_frame)) + self.callBackFunction(plugin_frame) return +def _update_nkdids_if_needed( self, ieee, new_nwkid ): + _ieee = "%016x" % t.uint64_t.deserialize(ieee.serialize())[0] + _nwk = new_nwkid.serialize()[::-1].hex() + self.callBackUpdDevice(_ieee, _nwk) + +def get_zigpy_version(self): + # This is a fake version number. This is just to inform the plugin that we are using ZNP over Zigpy + LOGGER.debug("get_zigpy_version ake version number. !!") + return self.version + async def register_specific_endpoints(self): """ Registers all necessary endpoints. diff --git a/Classes/ZigpyTransport/AppZnp.py b/Classes/ZigpyTransport/AppZnp.py index 609437e55..84d53fa20 100644 --- a/Classes/ZigpyTransport/AppZnp.py +++ b/Classes/ZigpyTransport/AppZnp.py @@ -14,6 +14,7 @@ import zigpy_znp.commands.util import zigpy_znp.config as znp_conf import zigpy_znp.types as t +import zigpy.types as zigpy_t import zigpy_znp.zigbee.application from Classes.ZigpyTransport.firmwareversionHelper import \ znp_extract_versioning_for_plugin @@ -96,9 +97,9 @@ async def register_endpoints(self): self.log.logging("TransportZigpy", "Status", "ZNP Radio register any additional/specific Ep") await Classes.ZigpyTransport.AppGeneric.register_specific_endpoints(self) - def device_initialized(self, device): - self.log.logging("TransportZigpy", "Log","device_initialized (0x%04x %s)" %(device.nwk, device.ieee)) - super().device_initialized(device) + #def device_initialized(self, device): + # self.log.logging("TransportZigpy", "Log","device_initialized (0x%04x %s)" %(device.nwk, device.ieee)) + # super().device_initialized(device) def get_device(self, ieee=None, nwk=None): @@ -116,6 +117,9 @@ def handle_leave(self, nwk, ieee): def get_zigpy_version(self): return Classes.ZigpyTransport.AppGeneric.get_zigpy_version(self) + def packet_received(self, packet: zigpy_t.ZigbeePacket) -> None: + return Classes.ZigpyTransport.AppGeneric.packet_received(self,packet) + def handle_message( self, sender: zigpy.device.Device, diff --git a/Modules/input.py b/Modules/input.py index 0f431a9de..e1939d229 100644 --- a/Modules/input.py +++ b/Modules/input.py @@ -2037,17 +2037,14 @@ def Decode8042(self, Devices, MsgData, MsgLQI): # Node Descriptor response def Decode8043(self, Devices, MsgData, MsgLQI): # Reception Simple descriptor response - # MsgLen = len(MsgData) + """Decode and process 0x8043 message.""" MsgDataSQN = MsgData[:2] MsgDataStatus = MsgData[2:4] MsgDataShAddr = MsgData[4:8] MsgDataLenght = MsgData[8:10] - self.log.logging( - "Input", - "Debug", - "Decode8043 - Received SQN: %s Addr: %s Len: %s Status: %s Data: %s" % (MsgDataSQN, MsgDataShAddr, MsgDataLenght, MsgDataStatus, MsgData), - ) + self.log.logging( "Input", "Debug", "Decode8043 - Received SQN: %s Addr: %s Len: %s Status: %s Data: %s" % ( + MsgDataSQN, MsgDataShAddr, MsgDataLenght, MsgDataStatus, MsgData), ) if MsgDataShAddr not in self.ListOfDevices: self.log.logging( "Input", "Log", "Decode8043 receives a message from a non existing device %s" % MsgDataShAddr, ) return @@ -2055,6 +2052,8 @@ def Decode8043(self, Devices, MsgData, MsgLQI): # Reception Simple descriptor r if "SQN" in self.ListOfDevices[MsgDataShAddr] and MsgDataSQN == self.ListOfDevices[MsgDataShAddr]["SQN"]: return + inDB_status = self.ListOfDevices[MsgDataShAddr].get("Status", None) == "inDB" + if int(MsgDataLenght, 16) == 0: return if MsgDataStatus != '00': @@ -2085,13 +2084,13 @@ def Decode8043(self, Devices, MsgData, MsgLQI): # Reception Simple descriptor r MsgDataProfile, MsgDataDeviceId), ) if MsgDataEp in self.ListOfDevices[MsgDataShAddr]["Ep"]: del self.ListOfDevices[MsgDataShAddr]["Ep"][MsgDataEp] - if "NbEp" in self.ListOfDevices[MsgDataShAddr]: - if self.ListOfDevices[MsgDataShAddr]["NbEp"] > "1": - self.ListOfDevices[MsgDataShAddr]["NbEp"] = int(self.ListOfDevices[MsgDataShAddr]["NbEp"]) - 1 + if "NbEp" in self.ListOfDevices[MsgDataShAddr] and self.ListOfDevices[MsgDataShAddr]["NbEp"] > "1": + self.ListOfDevices[MsgDataShAddr]["NbEp"] = int(self.ListOfDevices[MsgDataShAddr]["NbEp"]) - 1 return - self.log.logging( "Input", "Status", "[%s] NEW OBJECT: %s Simple Descriptor Response EP: 0x%s LQI: %s" % ( - "-", MsgDataShAddr, MsgDataEp, int(MsgLQI, 16)), ) + if not inDB_status: + self.log.logging( "Input", "Status", "[%s] NEW OBJECT: %s Simple Descriptor Response EP: 0x%s LQI: %s" % ( + "-", MsgDataShAddr, MsgDataEp, int(MsgLQI, 16)), ) # Endpoint V2 (ProfileID and ZDeviceID) if "Epv2" not in self.ListOfDevices[MsgDataShAddr]: @@ -2109,32 +2108,36 @@ def Decode8043(self, Devices, MsgData, MsgLQI): # Reception Simple descriptor r if self.ListOfDevices[MsgDataShAddr]["ProfileID"] != MsgDataProfile: pass self.ListOfDevices[MsgDataShAddr]["ProfileID"] = MsgDataProfile - self.log.logging( "Input", "Status", "[%s] NEW OBJECT: %s ProfileID %s" % ( - "-", MsgDataShAddr, MsgDataProfile), ) + if not inDB_status: + self.log.logging( "Input", "Status", "[%s] NEW OBJECT: %s ProfileID %s" % ( + "-", MsgDataShAddr, MsgDataProfile), ) if "ZDeviceID" in self.ListOfDevices[MsgDataShAddr]: if self.ListOfDevices[MsgDataShAddr]["ZDeviceID"] != MsgDataDeviceId: pass + self.ListOfDevices[MsgDataShAddr]["ZDeviceID"] = MsgDataDeviceId - self.log.logging( "Input", "Status", "[%s] NEW OBJECT: %s ZDeviceID %s" % ( - "-", MsgDataShAddr, MsgDataDeviceId), ) + if not inDB_status: + self.log.logging( "Input", "Status", "[%s] NEW OBJECT: %s ZDeviceID %s" % ( + "-", MsgDataShAddr, MsgDataDeviceId), ) # Decode Bit Field # Device version: 4 bits (bits 0-4) # eserved: 4 bits (bits4-7) DeviceVersion = int(MsgDataBField, 16) & 0x00001111 self.ListOfDevices[MsgDataShAddr]["ZDeviceVersion"] = "%04x" % DeviceVersion - self.log.logging( "Input", "Status", "[%s] NEW OBJECT: %s Application Version %s" % ( - "-", MsgDataShAddr, self.ListOfDevices[MsgDataShAddr]["ZDeviceVersion"]), ) + if not inDB_status: + self.log.logging( "Input", "Status", "[%s] NEW OBJECT: %s Application Version %s" % ( + "-", MsgDataShAddr, self.ListOfDevices[MsgDataShAddr]["ZDeviceVersion"]), ) configSourceAvailable = False - if "ConfigSource" in self.ListOfDevices[MsgDataShAddr]: - if self.ListOfDevices[MsgDataShAddr]["ConfigSource"] == "DeviceConf": - configSourceAvailable = True + if "ConfigSource" in self.ListOfDevices[MsgDataShAddr] and self.ListOfDevices[MsgDataShAddr]["ConfigSource"] == "DeviceConf": + configSourceAvailable = True # Decoding Cluster IN - self.log.logging( "Input", "Status", "[%s] NEW OBJECT: %s Cluster IN Count: %s" % ( - "-", MsgDataShAddr, MsgDataInClusterCount), ) + if not inDB_status: + self.log.logging( "Input", "Status", "[%s] NEW OBJECT: %s Cluster IN Count: %s" % ( + "-", MsgDataShAddr, MsgDataInClusterCount), ) idx = 24 i = 1 if int(MsgDataInClusterCount, 16) > 0: @@ -2161,23 +2164,25 @@ def Decode8043(self, Devices, MsgData, MsgLQI): # Reception Simple descriptor r if MsgDataCluster not in self.ListOfDevices[MsgDataShAddr]["Epv2"][MsgDataEp]["ClusterIn"]: self.ListOfDevices[MsgDataShAddr]["Epv2"][MsgDataEp]["ClusterIn"][MsgDataCluster] = {} - if MsgDataCluster in ZCL_CLUSTERS_LIST: - self.log.logging( "Input", "Status", "[%s] NEW OBJECT: %s Cluster In %s: %s (%s)" % ( - "-", MsgDataShAddr, i, MsgDataCluster, ZCL_CLUSTERS_LIST[MsgDataCluster], ), ) - else: - self.log.logging( "Input", "Status", "[%s] NEW OBJECT: %s Cluster In %s: %s" % ( - "-", MsgDataShAddr, i, MsgDataCluster), ) - i = i + 1 + if not inDB_status: + if MsgDataCluster in ZCL_CLUSTERS_LIST: + self.log.logging( "Input", "Status", "[%s] NEW OBJECT: %s Cluster In %s: %s (%s)" % ( + "-", MsgDataShAddr, i, MsgDataCluster, ZCL_CLUSTERS_LIST[MsgDataCluster], ), ) + else: + self.log.logging( "Input", "Status", "[%s] NEW OBJECT: %s Cluster In %s: %s" % ( + "-", MsgDataShAddr, i, MsgDataCluster), ) + i += 1 # Decoding Cluster Out idx = 24 + int(MsgDataInClusterCount, 16) * 4 MsgDataOutClusterCount = MsgData[idx : idx + 2] - self.log.logging( "Input", "Status", "[%s] NEW OBJECT: %s Cluster OUT Count: %s" % ( - "-", MsgDataShAddr, MsgDataOutClusterCount), ) + if not inDB_status: + self.log.logging( "Input", "Status", "[%s] NEW OBJECT: %s Cluster OUT Count: %s" % ( + "-", MsgDataShAddr, MsgDataOutClusterCount), ) + idx += 2 i = 1 - if int(MsgDataOutClusterCount, 16) > 0: while i <= int(MsgDataOutClusterCount, 16): MsgDataCluster = MsgData[idx + ((i - 1) * 4) : idx + (i * 4)] @@ -2198,21 +2203,21 @@ def Decode8043(self, Devices, MsgData, MsgLQI): # Reception Simple descriptor r if MsgDataCluster not in self.ListOfDevices[MsgDataShAddr]["Epv2"][MsgDataEp]["ClusterOut"]: self.ListOfDevices[MsgDataShAddr]["Epv2"][MsgDataEp]["ClusterOut"][MsgDataCluster] = {} - if MsgDataCluster in ZCL_CLUSTERS_LIST: - self.log.logging("Input","Status","[%s] NEW OBJECT: %s Cluster Out %s: %s (%s)"% ( - "-",MsgDataShAddr,i,MsgDataCluster,ZCL_CLUSTERS_LIST[MsgDataCluster],),) - else: - self.log.logging("Input","Status","[%s] NEW OBJECT: %s Cluster Out %s: %s" % ( - "-", MsgDataShAddr, i, MsgDataCluster),) + if not inDB_status: + if MsgDataCluster in ZCL_CLUSTERS_LIST: + self.log.logging("Input","Status","[%s] NEW OBJECT: %s Cluster Out %s: %s (%s)"% ( + "-",MsgDataShAddr,i,MsgDataCluster,ZCL_CLUSTERS_LIST[MsgDataCluster],),) + else: + self.log.logging("Input","Status","[%s] NEW OBJECT: %s Cluster Out %s: %s" % ( + "-", MsgDataShAddr, i, MsgDataCluster),) MsgDataCluster = "" - i = i + 1 + i += 1 # Let's check if there is any other Ep to be disxcovered - if request_next_Ep(self, MsgDataShAddr): - if self.ListOfDevices[MsgDataShAddr]["Status"] != "inDB": - self.ListOfDevices[MsgDataShAddr]["Status"] = "8043" - self.ListOfDevices[MsgDataShAddr]["Heartbeat"] = "0" + if request_next_Ep(self, MsgDataShAddr) and not inDB_status: + self.ListOfDevices[MsgDataShAddr]["Status"] = "8043" + self.ListOfDevices[MsgDataShAddr]["Heartbeat"] = "0" self.log.logging("Pairing","Debug","Decode8043 - Processed " + MsgDataShAddr + " end results is: " + str(self.ListOfDevices[MsgDataShAddr]),) @@ -2406,7 +2411,7 @@ def Decode8048(self, Devices, MsgData, MsgLQI): # Leave indication # Will set to Leave in order to protect Domoticz Widget, Just need to make sure that we can reconnect at a point of time self.ListOfDevices[sAddr]["Status"] = "Leave" self.ListOfDevices[sAddr]["Heartbeat"] = 0 - self.log.logging("Input", "Error", "Receiving a leave from %s/%s while device is %s status" % ( + self.log.logging("Input", "Error", "Receiving a leave from %s/%s while device is '%s' status." % ( sAddr, MsgExtAddress, self.ListOfDevices[sAddr]["Status"])) zdevname = "" diff --git a/Modules/pairingProcess.py b/Modules/pairingProcess.py index 3ba8f5bbc..5de8b4c07 100644 --- a/Modules/pairingProcess.py +++ b/Modules/pairingProcess.py @@ -210,19 +210,13 @@ def interview_state_8043(self, NWKID, RIA, knownModel, status): def request_node_descriptor(self, NWKID, RIA=None, status=None): + """ Trigger a Req Node Descriptor if Manufacturer not found""" - if "Manufacturer" in self.ListOfDevices[NWKID]: - if self.ListOfDevices[NWKID]["Manufacturer"] in ({}, ""): - self.log.logging("Pairing", "Status", "[%s] NEW OBJECT: %s Request Node Descriptor" % (RIA, NWKID)) - zdp_node_descriptor_request(self, NWKID) - return True - - self.log.logging( - "Pairing", - "Debug", - "[%s] NEW OBJECT: %s Manufacturer: %s" % (RIA, NWKID, self.ListOfDevices[NWKID]["Manufacturer"]), - NWKID, - ) + manufacturer = self.ListOfDevices[NWKID].get("Manufacturer", "") + model = self.ListOfDevices[NWKID].get("Model", "") + + if model in ( "lumi.sensor_switch",) or manufacturer not in ( "", {} ): + self.log.logging( "Pairing", "Debug", "[%s] NEW OBJECT: %s Manufacturer: %s Model: %s" % (RIA, NWKID, manufacturer, model), NWKID, ) return False self.log.logging("Pairing", "Status", "[%s] NEW OBJECT: %s Request Node Descriptor" % (RIA, NWKID)) diff --git a/Modules/pluginModels.py b/Modules/pluginModels.py index c94b55a8c..e454dcaee 100644 --- a/Modules/pluginModels.py +++ b/Modules/pluginModels.py @@ -26,7 +26,7 @@ def plugin_self_identifier( self, model, manufacturer): return None def check_found_plugin_model( self, model, manufacturer_name=None, manufacturer_code=None, device_id=None): - self.log.logging( "Pairing", "Log", "check_found_plugin_model - %s %s %s %s" % ( + self.log.logging( "Pairing", "Debug", "check_found_plugin_model - %s %s %s %s" % ( model, manufacturer_name, manufacturer_code, device_id)) # Let's check if @@ -40,10 +40,10 @@ def check_found_plugin_model( self, model, manufacturer_name=None, manufacturer_ ): continue - self.log.logging( "Pairing", "Log", "check_found_plugin_model - Found %s" % x) + self.log.logging( "Pairing", "Debug", "check_found_plugin_model - Found %s" % x) if "PluginModelName" in x: - self.log.logging( "Pairing", "Log", "check_found_plugin_model - return %s" % ( + self.log.logging( "Pairing", "Debug", "check_found_plugin_model - return %s" % ( x["PluginModelName"])) return x["PluginModelName"] diff --git a/Modules/readClusters.py b/Modules/readClusters.py index af512a893..310a27083 100644 --- a/Modules/readClusters.py +++ b/Modules/readClusters.py @@ -787,7 +787,7 @@ def Cluster0012(self, Devices, MsgSQN, MsgSrcAddr, MsgSrcEp, MsgClusterId, MsgAt checkAndStoreAttributeValue(self, MsgSrcAddr, MsgSrcEp, MsgClusterId, MsgAttrID, value) checkAndStoreAttributeValue(self, MsgSrcAddr, MsgSrcEp, "0006", "0000", value) - elif _modelName in ("lumi.sensor_switch.aq3", "lumi.sensor_switch.aq3"): + elif _modelName in ("lumi.sensor_switch.aq3", "lumi.sensor_switch.aq3t"): value = int(decodeAttribute(self, MsgAttType, MsgClusterData)) self.log.logging( "Cluster", diff --git a/plugin.py b/plugin.py index 42920406a..58c09d6b1 100644 --- a/plugin.py +++ b/plugin.py @@ -1502,10 +1502,10 @@ def update_DB_device_status_to_reinit( self ): def check_python_modules_version( self ): MODULES_VERSION = { - "zigpy": "0.56.1", - "zigpy_znp": "0.11.2", + "zigpy": "0.59.0", + "zigpy_znp": "0.11.6", "zigpy_deconz": "0.21.1", - "bellows": "0.35.8", + "bellows": "0.36.8", } flag = True diff --git a/requirements.txt b/requirements.txt index 468fdd798..ddf66b1c6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ -zigpy==0.56.1 +zigpy==0.59.0 +zigpy_znp==0.11.6 zigpy_deconz==0.21.1 +bellows==0.36.8 zigpy-cli==1.0.4 -zigpy_znp==0.11.2 -bellows==0.35.8 dnspython==2.3.0 pyserial>=3.5 z4d-certified-devices