From f94c8c596b633528f6895fc55ca173d57e8b18d3 Mon Sep 17 00:00:00 2001 From: Patrick Pichon Date: Sun, 3 Dec 2023 13:41:31 +0100 Subject: [PATCH] fixing reporting of Firmware version --- Classes/WebServer/WebServer.py | 62 ++++--- Classes/ZigpyTransport/AppZnp.py | 12 +- .../ZigpyTransport/firmwareversionHelper.py | 41 +++-- Modules/zigbeeVersionTable.py | 14 +- .../z4d_decoder_Zigate_Firmware_Version.py | 170 ++++++++++-------- plugin.py | 4 +- 6 files changed, 166 insertions(+), 137 deletions(-) diff --git a/Classes/WebServer/WebServer.py b/Classes/WebServer/WebServer.py index abc7d5c81..ca9ad6085 100644 --- a/Classes/WebServer/WebServer.py +++ b/Classes/WebServer/WebServer.py @@ -279,34 +279,7 @@ def rest_zigate(self, verb, data, parameters): _response = prepResponseMessage(self, setupHeadersResponse()) _response["Headers"]["Content-Type"] = "application/json; charset=utf-8" if verb == "GET": - - if self.ControllerData: - coordinator_infos = {} - coordinator_infos["Firmware Version"] = self.ControllerData["Firmware Version"] - coordinator_infos["IEEE"] = self.ControllerData["IEEE"] - coordinator_infos["Short Address"] = self.ControllerData["Short Address"] - coordinator_infos["Channel"] = self.ControllerData["Channel"] - coordinator_infos["PANID"] = self.ControllerData["PANID"] - coordinator_infos["Extended PANID"] = self.ControllerData["Extended PANID"] - coordinator_infos["Branch Version"] = self.ControllerData["Branch Version"] - coordinator_infos["Major Version"] = self.ControllerData["Major Version"] - coordinator_infos["Minor Version"] = self.ControllerData["Minor Version"] - if "Network key" in self.ControllerData: - coordinator_infos[ "Network Key"] = self.ControllerData["Network key"] - - if 0 <= int(self.ControllerData["Branch Version"]) < 20: - coordinator_infos["Display Firmware Version"] = "Zig - %s" % self.ControllerData["Minor Version"] - elif 20 <= int(self.ControllerData["Branch Version"]) < 30: - # ZNP - coordinator_infos["Display Firmware Version"] = "Znp - %s" % self.ControllerData["Minor Version"] - - elif 30 <= int(self.ControllerData["Branch Version"]) < 40: - # Silicon Labs - coordinator_infos["Display Firmware Version"] = "Ezsp - %s" %(self.ControllerData["Minor Version"] ) - else: - coordinator_infos["Display Firmware Version"] = "UNK - %s" % self.ControllerData["Minor Version"] - _response["Data"] = json.dumps(coordinator_infos, sort_keys=True) - else: + if self.ControllerData is None: fake_zigate = { "Firmware Version": "fake - 0310", "IEEE": "00158d0001ededde", @@ -315,8 +288,39 @@ def rest_zigate(self, verb, data, parameters): "PANID": "51cf", "Extended PANID": "bd1247ec9d358634", } - _response["Data"] = json.dumps(fake_zigate, sort_keys=True) + return _response + + coordinator_infos = { + "Firmware Version": self.ControllerData["Firmware Version"], + "IEEE": self.ControllerData["IEEE"], + "Short Address": self.ControllerData["Short Address"], + "Channel": self.ControllerData["Channel"], + "PANID": self.ControllerData["PANID"], + "Extended PANID": self.ControllerData["Extended PANID"], + "Branch Version": self.ControllerData["Branch Version"], + "Major Version": self.ControllerData["Major Version"], + "Minor Version": self.ControllerData["Minor Version"], + } + if "Network key" in self.ControllerData: + coordinator_infos[ "Network Key"] = self.ControllerData["Network key"] + + if 0 <= int(self.ControllerData["Branch Version"]) < 20: + coordinator_infos["Display Firmware Version"] = "Zig - %s" % self.ControllerData["Minor Version"] + + elif 20 <= int(self.ControllerData["Branch Version"]) < 30: + # ZNP + coordinator_infos["Display Firmware Version"] = "Znp - %s" % self.ControllerData["Minor Version"] + + elif 30 <= int(self.ControllerData["Branch Version"]) < 40: + # Silicon Labs + coordinator_infos["Display Firmware Version"] = "Ezsp - %s" %(self.ControllerData["Minor Version"] ) + + else: + coordinator_infos["Display Firmware Version"] = "UNK - %s" % self.ControllerData["Minor Version"] + + _response["Data"] = json.dumps(coordinator_infos, sort_keys=True) + return _response def rest_domoticz_env(self, verb, data, parameters): diff --git a/Classes/ZigpyTransport/AppZnp.py b/Classes/ZigpyTransport/AppZnp.py index 84d53fa20..9027bafd2 100644 --- a/Classes/ZigpyTransport/AppZnp.py +++ b/Classes/ZigpyTransport/AppZnp.py @@ -73,14 +73,16 @@ async def startup(self, HardwareID, pluginconf, callBackHandleMessage, callBackU self.callBackFunction(build_plugin_8015_frame_content( self, network_info)) # Trigger Version payload to plugin - znp_model = self.get_device(nwk=t.NWK(0x0000)).model - znp_manuf = self.get_device(nwk=t.NWK(0x0000)).manufacturer + version = self.state.node_info.version + znp_model = self.state.node_info.model + znp_manuf = self.state.node_info.manufacturer + self.log.logging("TransportZigpy", "Status", "ZNP Radio manufacturer: %s" %znp_manuf) self.log.logging("TransportZigpy", "Status", "ZNP Radio board model: %s" %znp_model) - self.log.logging("TransportZigpy", "Status", "ZNP Radio version: %s" %self._znp.version) + self.log.logging("TransportZigpy", "Status", "ZNP Radio version: %s" %version) - FirmwareBranch, FirmwareMajorVersion, FirmwareVersion, build = znp_extract_versioning_for_plugin( self, znp_model, znp_manuf) - self.callBackFunction(build_plugin_8010_frame_content(FirmwareBranch, FirmwareMajorVersion, FirmwareVersion, build )) + FirmwareBranch, FirmwareVersion, build = znp_extract_versioning_for_plugin( self, znp_model, znp_manuf, version) + self.callBackFunction(build_plugin_8010_frame_content(FirmwareBranch, "0000", FirmwareVersion, "" )) async def shutdown(self) -> None: diff --git a/Classes/ZigpyTransport/firmwareversionHelper.py b/Classes/ZigpyTransport/firmwareversionHelper.py index b79135bc2..f92910268 100644 --- a/Classes/ZigpyTransport/firmwareversionHelper.py +++ b/Classes/ZigpyTransport/firmwareversionHelper.py @@ -4,21 +4,32 @@ # ZNP -def znp_extract_versioning_for_plugin(self, znp_model, znp_manuf): - # CC1352/CC2652, Z-Stack 3.30+ (build 20211217) - ZNP_330 = "CC1352/CC2652, Z-Stack 3.30+" - ZNP_30X = "CC2531, Z-Stack 3.0.x" - - self.log.logging("TransportZigpy", "Debug", "extract_versioning_for_plugin Model: %s Manuf: %s" % (znp_model, znp_manuf)) - - firmware_branch = next((ZNP_MODEL[x] for x in ZNP_MODEL if znp_model[:len(x)] == x), "99") - - firmware_major_version = znp_model[znp_model.find("build") + 8: -5] - firmware_version = znp_model[znp_model.find("build") + 10: -1] - build = znp_model[znp_model.find("Z-Stack"):] - - self.log.logging("TransportZigpy", "Debug", "extract_versioning_for_plugin %s %s %s %s" % (firmware_branch, firmware_major_version, firmware_version, build)) - return firmware_branch, firmware_major_version, firmware_version, build +def znp_extract_versioning_for_plugin(self, znp_model, znp_manuf, version): + #NodeInfo(nwk=0x0000, + # ieee=00:12:4b:00:2a:1a:a7:35, + # logical_type=, + # model='CC2652', + # manufacturer='Texas Instruments', + # version='Z-Stack 20210708') + + self.log.logging("TransportZigpy", "Log", "extract_versioning_for_plugin Model: %s Manuf: %s Version: %s" % (znp_model, znp_manuf, version)) + + # It is assumed that the build is always on the right side in version + build = (''.join(char for char in reversed(version) if char.isdigit()))[::-1] + if "Z-Stack Home" in version: + firmware_branch = firmware_major_version = 22 + firmware_version = "Z-Stack Home " + "( build %s)" %build + + if "Z-Stack 3.0.x" in version: + firmware_branch = firmware_major_version = 21 + firmware_version = "Z-Stack 3.0.x " + "( build %s)" %build + else: + firmware_branch = firmware_major_version = ZNP_MODEL[ znp_model ] + firmware_version = "Z-Stack 3.30+ " + "( build %s)" %build + + self.log.logging("TransportZigpy", "Log", "extract_versioning_for_plugin %s %s %s %s" % ( + firmware_branch, firmware_major_version, firmware_version, build)) + return firmware_branch, firmware_version, build # Bellows diff --git a/Modules/zigbeeVersionTable.py b/Modules/zigbeeVersionTable.py index 5110a3306..ff8f7240d 100644 --- a/Modules/zigbeeVersionTable.py +++ b/Modules/zigbeeVersionTable.py @@ -21,6 +21,9 @@ "CC1352/CC2652, Z-Stack 3.30+": "20", "CC2531, Z-Stack 3.0.x": "21", "CC2531, Z-Stack Home 1.2": "22", + "CC2652": "20", + "CC2531": "21", + "CC2538": "23", "ConBee II": "40", "Conbee II": "40", "Raspbee II": "41", @@ -28,23 +31,22 @@ "Elelabs, ELU01x": "31", } - def set_display_firmware_version( self ): if 0 <= int(self.ControllerData["Branch Version"]) < 20: - self.pluginParameters["Firmware Version"] = "Zigate - %s" % self.ControllerData["Minor Version"] + self.pluginParameters["DisplayFirmwareVersion"] = "Zigate - %s" % self.ControllerData["Minor Version"] elif 20 <= int(self.ControllerData["Branch Version"]) < 30: # ZNP - self.pluginParameters["Firmware Version"] = "Znp - %s" % self.ControllerData["Minor Version"] + self.pluginParameters["DisplayFirmwareVersion"] = "Znp - %s" % self.ControllerData["Minor Version"] elif 30 <= int(self.ControllerData["Branch Version"]) < 40: # Silicon Labs - self.pluginParameters["Firmware Version"] = "Ezsp - %s" %self.ControllerData["Minor Version"] + self.pluginParameters["DisplayFirmwareVersion"] = "Ezsp - %s" %self.ControllerData["Minor Version"] elif 40 <= int(self.ControllerData["Branch Version"]) < 50: # deCONZ - self.pluginParameters["Firmware Version"] = "deCONZ - %s" %self.ControllerData["Minor Version"] + self.pluginParameters["DisplayFirmwareVersion"] = "deCONZ - %s" %self.ControllerData["Minor Version"] else: - self.pluginParameters["Firmware Version"] = "UNK - %s" % self.ControllerData["Minor Version"] + self.pluginParameters["DisplayFirmwareVersion"] = "UNK - %s" % self.ControllerData["Minor Version"] diff --git a/Z4D_decoders/z4d_decoder_Zigate_Firmware_Version.py b/Z4D_decoders/z4d_decoder_Zigate_Firmware_Version.py index 194e3b89c..2f0240e87 100644 --- a/Z4D_decoders/z4d_decoder_Zigate_Firmware_Version.py +++ b/Z4D_decoders/z4d_decoder_Zigate_Firmware_Version.py @@ -2,57 +2,105 @@ from Modules.zigbeeVersionTable import (FIRMWARE_BRANCH, set_display_firmware_version) - - -def Decode8010(self, Devices, MsgData, MsgLQI): +def Decode8010(self, Devices, MsgData, MsgLQI): # Reception Firmware Version MsgLen = len(MsgData) - self.FirmwareBranch = MsgData[:2] - - if MsgLen == 8: + self.FirmwareBranch = MsgData[:2] + if len(MsgData) == 8: + # Zigate Firmware self.FirmwareMajorVersion = MsgData[2:4] self.FirmwareVersion = MsgData[4:8] - else: - self.log.logging('Input', 'Debug', f'Decode8010 {MsgData}') + # Zigpy 20/21/1217/20211217 + self.log.logging("Input", "Log", "Decode8010 %s" %MsgData) self.FirmwareMajorVersion = MsgData[:2] FirmwareMinorVersion = MsgData[4:8] self.FirmwareVersion = MsgData[8:] - self.log.logging('Input', 'Debug', f'Decode8010 Major: {self.FirmwareMajorVersion} Minor: {FirmwareMinorVersion} Full: {self.FirmwareVersion}') - - default_device_key = '0000' - if default_device_key not in self.ListOfDevices: - self.ListOfDevices[default_device_key] = {'Model': {}} - - self.log.logging('Input', 'Debug', f'Decode8010 - Reception Version list: {MsgData} len: {MsgLen} Branch: {self.FirmwareBranch} Major: {self.FirmwareMajorVersion} Version: {self.FirmwareVersion}') - - if self.FirmwareBranch in FIRMWARE_BRANCH: - firmware_branch_int = int(self.FirmwareBranch) - - if firmware_branch_int in {98, 99}: - self.log.logging('Input', 'Status', 'Untested Zigbee adapter model. If this is a Sonoff USB Dongle E that is a known issue, otherwise, please report to the Zigbee for Domoticz team') - self.pluginParameters['CoordinatorModel'] = FIRMWARE_BRANCH[self.FirmwareBranch] - - elif firmware_branch_int == 11: - HandleFirmwareBranch11(self) - - elif firmware_branch_int >= 20: - HandleFirmwareBranch20(self) - - else: - self.log.logging('Input', 'Status', f'{FIRMWARE_BRANCH[self.FirmwareBranch]}') - version = '' - - self.log.logging('Input', 'Status', f'Installer Version Number: {self.FirmwareVersion}') - self.log.logging('Input', 'Status', f'Branch Version: ==> {FIRMWARE_BRANCH[self.FirmwareBranch]} <==') - UpdateControllerData(self) + self.log.logging("Input", "Log", "Decode8010 Major: %s Minor: %s Full: %s" %( + self.FirmwareMajorVersion, FirmwareMinorVersion, self.FirmwareVersion )) - set_display_firmware_version( self ) - update_firmware_version_to_objects( self ) - self.PDMready = True + if '0000' not in self.ListOfDevices: + self.ListOfDevices['0000'] = {} + if 'Model' not in self.ListOfDevices[ '0000' ]: + self.ListOfDevices[ '0000' ]['Model'] = {} - -def update_firmware_version_to_objects( self ): + self.log.logging("Input", "Log", "Decode8010 - Reception Version list:%s len: %s Branch: %s Major: %s Version: %s" % ( + MsgData, MsgLen, self.FirmwareBranch, self.FirmwareMajorVersion, self.FirmwareVersion)) + if self.FirmwareBranch in FIRMWARE_BRANCH: + if int(self.FirmwareBranch) in ( 98, 99): + self.log.logging( + "Input", + "Status", + "Untested Zigbee adaptater model. If this is a Sonoff USB Dongle E that is known issue, otherwise please report to the Zigbee for Domoticz team") + self.pluginParameters["CoordinatorModel"] = FIRMWARE_BRANCH[ self.FirmwareBranch ] + self.pluginParameters["CoordinatorFirmwareVersion"] = self.FirmwareVersion + + elif int(self.FirmwareBranch) == 11: + #Zigpy-Zigate + self.log.logging("Input", "Status", "%s" %FIRMWARE_BRANCH[ self.FirmwareBranch ]) + self.ControllerData["Controller firmware"] = FIRMWARE_BRANCH[ self.FirmwareBranch ] + # the Build date is coded into "20" + "%02d" %int(FirmwareMajorVersion,16) + "%04d" %int(FirmwareVersion,16) + if int(self.FirmwareMajorVersion,16) == 0x03: + version = "Zigpy-zigate, Zigate V1 (legacy) %04x" %( int(self.FirmwareVersion,16)) + self.pluginParameters["CoordinatorModel"] = "Zigate V1 (legacy)" + self.pluginParameters["CoordinatorFirmwareVersion"] = "%04x" %( int(self.FirmwareVersion,16)) + + elif int(self.FirmwareMajorVersion,16) == 0x04: + version = "Zigpy-zigate, Zigate V1 (OptiPDM) %04x" %( int(self.FirmwareVersion,16)) + self.pluginParameters["CoordinatorModel"] = "Zigate V1 (OptiPDM)" + self.pluginParameters["CoordinatorFirmwareVersion"] = "%04x" %( int(self.FirmwareVersion,16)) + + elif int(self.FirmwareMajorVersion,16) == 0x05: + version = "Zigpy-zigate, Zigate V2 %04x" %( int(self.FirmwareVersion,16)) + self.pluginParameters["CoordinatorModel"] = "Zigate V2" + self.pluginParameters["CoordinatorFirmwareVersion"] = "%04x" %( int(self.FirmwareVersion,16)) + + else: + self.log.logging("Input", "Status", "%04x" %int(self.FirmwareMajorVersion,16)) + version ="" + + elif int(self.FirmwareBranch) >= 20: + # Zigpy-Znp + self.log.logging("Input", "Status", "%s" %FIRMWARE_BRANCH[ self.FirmwareBranch ]) + self.ListOfDevices[ '0000' ]['Model'] = FIRMWARE_BRANCH[ self.FirmwareBranch ] + self.pluginParameters["CoordinatorModel"] = FIRMWARE_BRANCH[ self.FirmwareBranch ] + self.pluginParameters["CoordinatorFirmwareVersion"] = self.FirmwareVersion + + # Zigate Native version + elif self.FirmwareMajorVersion == "03": + self.log.logging("Input", "Status", "ZiGate Classic PDM (legacy)") + self.ZiGateModel = 1 + self.ListOfDevices[ '0000' ]['Model'] = 'ZiGate Classic PDM (legacy)' + self.pluginParameters["CoordinatorModel"] = 'ZiGate Classic PDM (legacy)' + self.pluginParameters["CoordinatorFirmwareVersion"] = "%04x" %( int(self.FirmwareVersion,16)) + + elif self.FirmwareMajorVersion == "04": + self.log.logging("Input", "Status", "ZiGate Classic PDM (OptiPDM)") + self.ZiGateModel = 1 + self.ListOfDevices[ '0000' ]['Model'] = 'ZiGate Classic PDM (OptiPDM)' + self.pluginParameters["CoordinatorModel"] = 'ZiGate Classic PDM (OptiPDM)' + self.pluginParameters["CoordinatorFirmwareVersion"] = "%04x" %( int(self.FirmwareVersion,16)) + + elif self.FirmwareMajorVersion == "05": + self.log.logging("Input", "Status", "ZiGate+ (V2)") + self.ListOfDevices[ '0000' ]['Model'] = 'ZiGate+ (V2)' + self.ZiGateModel = 2 + self.pluginParameters["CoordinatorModel"] = 'ZiGate+ (V2)' + self.pluginParameters["CoordinatorFirmwareVersion"] = "%04x" %( int(self.FirmwareVersion,16)) + + self.log.logging("Input", "Status", "Installer Version Number: %s" % self.FirmwareVersion) + self.log.logging("Input", "Status", "Branch Version: ==> %s <==" % FIRMWARE_BRANCH[self.FirmwareBranch]) + self.ControllerData["Firmware Version"] = "Branch: %s Major: %s Version: %s" % ( + self.FirmwareBranch, + self.FirmwareMajorVersion, + self.FirmwareVersion, + ) + self.ControllerData["Branch Version"] = self.FirmwareBranch + self.ControllerData["Major Version"] = self.FirmwareMajorVersion + self.ControllerData["Minor Version"] = self.FirmwareVersion + + set_display_firmware_version( self ) + if self.webserver: self.webserver.update_firmware(self.FirmwareVersion) self.ControllerLink.update_ZiGate_HW_Version(self.ZiGateModel) @@ -65,45 +113,9 @@ def update_firmware_version_to_objects( self ): if self.networkmap: self.networkmap.update_firmware(self.FirmwareVersion) - + if self.log: self.log.loggingUpdateFirmware(self.FirmwareVersion, self.FirmwareMajorVersion) -def HandleFirmwareBranch11(self): - self.log.logging('Input', 'Status', f'{FIRMWARE_BRANCH[self.FirmwareBranch]}') - self.ControllerData['Controller firmware'] = FIRMWARE_BRANCH[self.FirmwareBranch] - - major_version_int = int(self.FirmwareMajorVersion, 16) - version = '' - - if major_version_int == 3: - version = self.HandleVersion('Zigpy-zigate, Zigate V1 (legacy)') - elif major_version_int == 4: - version = self.HandleVersion('Zigpy-zigate, Zigate V1 (OptiPDM)') - elif major_version_int == 5: - version = self.HandleVersion('Zigpy-zigate, Zigate V2') - - self.log.logging('Input', 'Status', f'{self.FirmwareMajorVersion}') - self.log.logging('Input', 'Status', f'{version}') - - -def HandleVersion(self, model): - version = f'{model} %04x' % int(self.FirmwareVersion, 16) - self.pluginParameters['CoordinatorModel'] = model - self.pluginParameters['CoordinatorFirmwareVersion'] = '%04x' % int( self.FirmwareVersion, 16 ) - return version - - -def HandleFirmwareBranch20(self): - self.log.logging('Input', 'Status', f'{FIRMWARE_BRANCH[self.FirmwareBranch]}') - self.ListOfDevices['0000']['Model'] = FIRMWARE_BRANCH[self.FirmwareBranch] - self.pluginParameters['CoordinatorModel'] = FIRMWARE_BRANCH[self.FirmwareBranch] - self.pluginParameters['CoordinatorFirmwareVersion'] = self.FirmwareVersion - - -def UpdateControllerData(self): - self.ControllerData['Firmware Version'] = f'Branch: {self.FirmwareBranch} Major: {self.FirmwareMajorVersion} Version: {self.FirmwareVersion}' - self.ControllerData['Branch Version'] = self.FirmwareBranch - self.ControllerData['Major Version'] = self.FirmwareMajorVersion - self.ControllerData['Minor Version'] = self.FirmwareVersion + self.PDMready = True \ No newline at end of file diff --git a/plugin.py b/plugin.py index 321a8a94a..4ba8f6489 100644 --- a/plugin.py +++ b/plugin.py @@ -1307,9 +1307,7 @@ def zigateInit_Phase3(self): elif int(self.FirmwareBranch) >= 20: self.log.logging( "Plugin", "Status", "Plugin with Zigpy, Coordinator %s firmware %s correctly initialized" % ( - self.pluginParameters["CoordinatorModel"], self.pluginParameters["Firmware Version"])) - - + self.pluginParameters["CoordinatorModel"], self.pluginParameters["CoordinatorFirmwareVersion"])) # If firmware above 3.0d, Get Network State if (self.HeartbeatCount % (3600 // HEARTBEAT)) == 0 and self.transport != "None":