From f141231a0f1a662e0f1909223caa538c3af432e4 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 09:02:10 +0100 Subject: [PATCH 01/18] Add Nous LZ3 zigbee device xml-data --- .../core.domain_objects.xml | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/userdata/adam_plus_anna_new/core.domain_objects.xml b/userdata/adam_plus_anna_new/core.domain_objects.xml index 71f3e293c..04e7c0be7 100644 --- a/userdata/adam_plus_anna_new/core.domain_objects.xml +++ b/userdata/adam_plus_anna_new/core.domain_objects.xml @@ -1,5 +1,74 @@ + + Aanvoer water afsluiter (nous lz3) + A device that communicates through the ZigBee protocol. + valve_actuator + 2024-11-11T20:31:49.734+01:00 + 2024-11-15T13:55:19.574+01:00 + + + + + + + + relay + + 2024-11-15T13:55:19.571+01:00 + 2024-11-15T13:55:19.571+01:00 + + + + off + + + + + + 2024-11-15T13:55:19.571+01:00 + false + off + + + + + + _TZ3000_abjodzas + TS0011 + + + + 2024-11-11T20:31:46.189+01:00 + 2024-11-11T20:31:49.706+01:00 + + + + + + + + + + + + A4C13862AF9917B1 + end_device + true + battery + + + + 221 + 1 + parent + + + 2024-11-15T14:07:23+01:00 + true + + + SmartPlug Floor 0 A device that communicates through the ZigBee protocol. From a94e0e1589d5ec6ae85999ffa7d1a19f7a203307 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 09:15:13 +0100 Subject: [PATCH 02/18] Improve appliance-module relation search --- plugwise/common.py | 11 +++++------ plugwise/helper.py | 4 +--- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/plugwise/common.py b/plugwise/common.py index b3a327bc3..f29811b8c 100644 --- a/plugwise/common.py +++ b/plugwise/common.py @@ -8,6 +8,7 @@ from plugwise.constants import ( ANNA, + LOGGER, SPECIAL_PLUG_TYPES, SWITCH_GROUP_TYPES, ApplianceType, @@ -277,8 +278,6 @@ def _get_lock_state(self, xml: etree, data: DeviceData, stretch_v2: bool = False def _get_module_data( self, xml_1: etree, - locator: str, - mod_type: str, xml_2: etree = None, legacy: bool = False, ) -> ModelData: @@ -295,12 +294,12 @@ def _get_module_data( "vendor_model": None, "zigbee_mac_address": None, } - # xml_1: appliance - if (appl_search := xml_1.find(locator)) is not None: + if (appl_search := xml_1.find("./logs/point_log/*[@id]")) is not None: + link_tag = appl_search.tag link_id = appl_search.attrib["id"] - loc = f".//services/{mod_type}[@id='{link_id}']...." + loc = f".//services/{link_tag}[@id='{link_id}']...." if legacy: - loc = f".//{mod_type}[@id='{link_id}']...." + loc = f".//{link_tag}[@id='{link_id}']...." # Not possible to walrus for some reason... # xml_2: self._modules for legacy, self._domain_objects for actual search = return_valid(xml_2, self._domain_objects) diff --git a/plugwise/helper.py b/plugwise/helper.py index 0c298471a..304b99aa0 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -396,9 +396,7 @@ def _appliance_info_finder(self, appl: Munch, appliance: etree) -> Munch: return appl case _ as s if s.endswith("_plug"): # Collect info from plug-types (Plug, Aqara Smart Plug) - locator = "./logs/interval_log/electricity_interval_meter" - mod_type = "electricity_interval_meter" - module_data = self._get_module_data(appliance, locator, mod_type) + module_data = self._get_module_data(appliance) # A plug without module-data is orphaned/ no present if not module_data["contents"]: return Munch() From c883f97166bdabba4721ef3ba608cb0d98e196de Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 10:11:23 +0100 Subject: [PATCH 03/18] Further adapt --- plugwise/common.py | 8 ++++---- plugwise/helper.py | 12 +++--------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/plugwise/common.py b/plugwise/common.py index f29811b8c..536e49faa 100644 --- a/plugwise/common.py +++ b/plugwise/common.py @@ -78,9 +78,9 @@ def _appl_heater_central_info( # xml_1: appliance # xml_3: self._modules for legacy, self._domain_objects for actual xml_3 = return_valid(xml_3, self._domain_objects) - module_data = self._get_module_data(xml_1, locator_1, mod_type, xml_3) - if not module_data["contents"]: - module_data = self._get_module_data(xml_1, locator_2, mod_type, xml_3) + module_data = self._get_module_data(xml_1, xml_3) + #if not module_data["contents"]: + # module_data = self._get_module_data(xml_1, xml_3) appl.vendor_name = module_data["vendor_name"] appl.hardware = module_data["hardware_version"] appl.model_id = module_data["vendor_model"] if not legacy else None @@ -97,7 +97,7 @@ def _appl_thermostat_info(self, appl: Munch, xml_1: etree, xml_2: etree = None) locator = "./logs/point_log[type='thermostat']/thermostat" mod_type = "thermostat" xml_2 = return_valid(xml_2, self._domain_objects) - module_data = self._get_module_data(xml_1, locator, mod_type, xml_2) + module_data = self._get_module_data(xml_1, xml_2) appl.vendor_name = module_data["vendor_name"] appl.model = module_data["vendor_model"] if appl.model != "ThermoTouch": # model_id for Anna not present as stand-alone device diff --git a/plugwise/helper.py b/plugwise/helper.py index 304b99aa0..a9a60efd3 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -356,9 +356,7 @@ def _p1_smartmeter_info_finder(self, appl: Munch) -> None: """Collect P1 DSMR SmartMeter info.""" loc_id = next(iter(self.loc_data.keys())) location = self._domain_objects.find(f'./location[@id="{loc_id}"]') - locator = "./logs/point_log/electricity_point_meter" - mod_type = "electricity_point_meter" - module_data = self._get_module_data(location, locator, mod_type) + module_data = self._get_module_data(location) if not module_data["contents"]: LOGGER.error("No module data found for SmartMeter") # pragma: no cover return None # pragma: no cover @@ -715,14 +713,10 @@ def _wireless_availability(self, appliance: etree, data: DeviceData) -> None: """ if self.smile(ADAM): # Try collecting for a Plug - locator = "./logs/interval_log/electricity_interval_meter" - mod_type = "electricity_interval_meter" - module_data = self._get_module_data(appliance, locator, mod_type) + module_data = self._get_module_data(appliance) if not module_data["contents"]: # Try collecting for a wireless thermostat - locator = "./logs/point_log[type='thermostat']/thermostat" - mod_type = "thermostat" - module_data = self._get_module_data(appliance, locator, mod_type) + module_data = self._get_module_data(appliance) if not module_data["contents"]: LOGGER.error("No module data found for Plug or wireless thermostat") # pragma: no cover return None # pragma: no cover From b53898de3b5dd2d3a7e43e2c46c13eecaf1e8d06 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 10:15:39 +0100 Subject: [PATCH 04/18] Update device-items assert for added device --- tests/test_adam.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_adam.py b/tests/test_adam.py index 4c2e812ff..3fc3a3f5e 100644 --- a/tests/test_adam.py +++ b/tests/test_adam.py @@ -36,7 +36,7 @@ async def test_connect_adam_plus_anna_new(self): assert smile.gateway_id == "da224107914542988a88561b4452b0f6" assert smile._last_active["f2bf9048bef64cc5b6d5110154e33c81"] == "Weekschema" assert smile._last_active["f871b8c4d63549319221e294e4f88074"] == "Badkamer" - assert self.device_items == 157 + assert self.device_items == 166 assert self.device_list == [ "da224107914542988a88561b4452b0f6", "056ee145a816487eaa69243c3280f8bf", From be7364fcf8682aa72eee1ab2333be4444c9d00bf Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 10:17:07 +0100 Subject: [PATCH 05/18] More assert-updates --- tests/test_adam.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_adam.py b/tests/test_adam.py index 3fc3a3f5e..f8448071a 100644 --- a/tests/test_adam.py +++ b/tests/test_adam.py @@ -40,6 +40,7 @@ async def test_connect_adam_plus_anna_new(self): assert self.device_list == [ "da224107914542988a88561b4452b0f6", "056ee145a816487eaa69243c3280f8bf", + "10016900610d4c7481df78c89606ef22", "67d73d0bd469422db25a618a5fb8eeb0", "e2f4322d57924fa090fbbc48b3a140dc", "29542b2b6a6a4169acecc15c72a599b8", From c964847e62b0002f6ac85b6e551a3b89f8abc399 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 10:19:32 +0100 Subject: [PATCH 06/18] Adapt @legacy --- plugwise/legacy/helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugwise/legacy/helper.py b/plugwise/legacy/helper.py index a82b7005b..3ba741991 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -232,7 +232,7 @@ def _energy_device_info_finder(self, appliance: etree, appl: Munch) -> Munch: locator = "./services/electricity_point_meter" mod_type = "electricity_point_meter" - module_data = self._get_module_data(appliance, locator, mod_type, self._modules, legacy=True) + module_data = self._get_module_data(appliance, self._modules, legacy=True) appl.zigbee_mac = module_data["zigbee_mac_address"] # Filter appliance without zigbee_mac, it's an orphaned device if appl.zigbee_mac is None and self.smile_type != "power": From b16ba06236d306872f71e8687a3e6ed3a4c1d5a8 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 11:18:05 +0100 Subject: [PATCH 07/18] Partly revert to handle both actual and legacy --- plugwise/common.py | 17 +++++++---------- plugwise/helper.py | 17 ++++++++--------- plugwise/legacy/helper.py | 4 +--- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/plugwise/common.py b/plugwise/common.py index 536e49faa..a1c0ee990 100644 --- a/plugwise/common.py +++ b/plugwise/common.py @@ -8,7 +8,6 @@ from plugwise.constants import ( ANNA, - LOGGER, SPECIAL_PLUG_TYPES, SWITCH_GROUP_TYPES, ApplianceType, @@ -74,13 +73,12 @@ def _appl_heater_central_info( appl.name = "OpenTherm" locator_1 = "./logs/point_log[type='flame_state']/boiler_state" locator_2 = "./services/boiler_state" - mod_type = "boiler_state" # xml_1: appliance # xml_3: self._modules for legacy, self._domain_objects for actual xml_3 = return_valid(xml_3, self._domain_objects) - module_data = self._get_module_data(xml_1, xml_3) - #if not module_data["contents"]: - # module_data = self._get_module_data(xml_1, xml_3) + module_data = self._get_module_data(xml_1, locator_1, xml_3) + if not module_data["contents"]: + module_data = self._get_module_data(xml_1, locator_2, xml_3) appl.vendor_name = module_data["vendor_name"] appl.hardware = module_data["hardware_version"] appl.model_id = module_data["vendor_model"] if not legacy else None @@ -95,9 +93,8 @@ def _appl_heater_central_info( def _appl_thermostat_info(self, appl: Munch, xml_1: etree, xml_2: etree = None) -> Munch: """Helper-function for _appliance_info_finder().""" locator = "./logs/point_log[type='thermostat']/thermostat" - mod_type = "thermostat" xml_2 = return_valid(xml_2, self._domain_objects) - module_data = self._get_module_data(xml_1, xml_2) + module_data = self._get_module_data(xml_1, locator, xml_2) appl.vendor_name = module_data["vendor_name"] appl.model = module_data["vendor_model"] if appl.model != "ThermoTouch": # model_id for Anna not present as stand-alone device @@ -278,6 +275,7 @@ def _get_lock_state(self, xml: etree, data: DeviceData, stretch_v2: bool = False def _get_module_data( self, xml_1: etree, + locator: str, xml_2: etree = None, legacy: bool = False, ) -> ModelData: @@ -294,12 +292,11 @@ def _get_module_data( "vendor_model": None, "zigbee_mac_address": None, } - if (appl_search := xml_1.find("./logs/point_log/*[@id]")) is not None: + + if (appl_search := xml_1.find(locator)) is not None: link_tag = appl_search.tag link_id = appl_search.attrib["id"] loc = f".//services/{link_tag}[@id='{link_id}']...." - if legacy: - loc = f".//{link_tag}[@id='{link_id}']...." # Not possible to walrus for some reason... # xml_2: self._modules for legacy, self._domain_objects for actual search = return_valid(xml_2, self._domain_objects) diff --git a/plugwise/helper.py b/plugwise/helper.py index a9a60efd3..ae4dcff68 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -356,7 +356,8 @@ def _p1_smartmeter_info_finder(self, appl: Munch) -> None: """Collect P1 DSMR SmartMeter info.""" loc_id = next(iter(self.loc_data.keys())) location = self._domain_objects.find(f'./location[@id="{loc_id}"]') - module_data = self._get_module_data(location) + locator = "./logs/point_log/*[@id]" + module_data = self._get_module_data(location, locator) if not module_data["contents"]: LOGGER.error("No module data found for SmartMeter") # pragma: no cover return None # pragma: no cover @@ -394,7 +395,8 @@ def _appliance_info_finder(self, appl: Munch, appliance: etree) -> Munch: return appl case _ as s if s.endswith("_plug"): # Collect info from plug-types (Plug, Aqara Smart Plug) - module_data = self._get_module_data(appliance) + locator = "./logs/point_log/*[@id]" + module_data = self._get_module_data(appliance, locator) # A plug without module-data is orphaned/ no present if not module_data["contents"]: return Munch() @@ -712,14 +714,11 @@ def _wireless_availability(self, appliance: etree, data: DeviceData) -> None: Collect the availability-status for wireless connected devices. """ if self.smile(ADAM): - # Try collecting for a Plug - module_data = self._get_module_data(appliance) + locator = "./logs/point_log/*[@id]" + module_data = self._get_module_data(appliance, locator) if not module_data["contents"]: - # Try collecting for a wireless thermostat - module_data = self._get_module_data(appliance) - if not module_data["contents"]: - LOGGER.error("No module data found for Plug or wireless thermostat") # pragma: no cover - return None # pragma: no cover + LOGGER.error("No module data found for Plug or wireless thermostat") # pragma: no cover + return None # pragma: no cover if module_data["reachable"] is not None: data["available"] = module_data["reachable"] diff --git a/plugwise/legacy/helper.py b/plugwise/legacy/helper.py index 3ba741991..ccd8abb03 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -230,9 +230,7 @@ def _energy_device_info_finder(self, appliance: etree, appl: Munch) -> Munch: """ if self.smile_type in ("power", "stretch"): locator = "./services/electricity_point_meter" - mod_type = "electricity_point_meter" - - module_data = self._get_module_data(appliance, self._modules, legacy=True) + module_data = self._get_module_data(appliance, locator, self._modules, legacy=True) appl.zigbee_mac = module_data["zigbee_mac_address"] # Filter appliance without zigbee_mac, it's an orphaned device if appl.zigbee_mac is None and self.smile_type != "power": From d66e82b4142a0161d766bf563890d467d728b423 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 11:24:11 +0100 Subject: [PATCH 08/18] Avoid model_id=model --- plugwise/util.py | 2 +- tests/test_adam.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugwise/util.py b/plugwise/util.py index 1012deee7..5798feb28 100644 --- a/plugwise/util.py +++ b/plugwise/util.py @@ -115,7 +115,7 @@ def check_model(name: str | None, vendor_name: str | None) -> str | None: if name is not None and "lumi.plug" in name: return "Aqara Smart Plug" - return name # pragma: no cover + return None def common_match_cases( diff --git a/tests/test_adam.py b/tests/test_adam.py index f8448071a..2a2f95116 100644 --- a/tests/test_adam.py +++ b/tests/test_adam.py @@ -36,7 +36,7 @@ async def test_connect_adam_plus_anna_new(self): assert smile.gateway_id == "da224107914542988a88561b4452b0f6" assert smile._last_active["f2bf9048bef64cc5b6d5110154e33c81"] == "Weekschema" assert smile._last_active["f871b8c4d63549319221e294e4f88074"] == "Badkamer" - assert self.device_items == 166 + assert self.device_items == 165 assert self.device_list == [ "da224107914542988a88561b4452b0f6", "056ee145a816487eaa69243c3280f8bf", From 4286586456cd3d73c974f12982a4bcf3441bf8fc Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 11:26:58 +0100 Subject: [PATCH 09/18] Save updated fixture --- fixtures/adam_plus_anna_new/all_data.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/fixtures/adam_plus_anna_new/all_data.json b/fixtures/adam_plus_anna_new/all_data.json index a318023fc..4727e8967 100644 --- a/fixtures/adam_plus_anna_new/all_data.json +++ b/fixtures/adam_plus_anna_new/all_data.json @@ -25,6 +25,18 @@ "dhw_cm_switch": false } }, + "10016900610d4c7481df78c89606ef22": { + "available": true, + "dev_class": "valve_actuator_plug", + "location": "d9786723dbcf4f19b5c629a54629f9c7", + "model_id": "TS0011", + "name": "Aanvoer water afsluiter (nous lz3)", + "switches": { + "relay": false + }, + "vendor": "_TZ3000_abjodzas", + "zigbee_mac_address": "A4C13862AF9917B1" + }, "1772a4ea304041adb83f357b751341ff": { "available": true, "binary_sensors": { @@ -266,7 +278,7 @@ "cooling_present": false, "gateway_id": "da224107914542988a88561b4452b0f6", "heater_id": "056ee145a816487eaa69243c3280f8bf", - "item_count": 157, + "item_count": 165, "notifications": {}, "reboot": true, "smile_name": "Adam" From 4df1fe29cc42449c70482ac798ba46a8b099a543 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 11:28:58 +0100 Subject: [PATCH 10/18] Try --- scripts/manual_fixtures.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/manual_fixtures.py b/scripts/manual_fixtures.py index 7e236b451..36c177a64 100755 --- a/scripts/manual_fixtures.py +++ b/scripts/manual_fixtures.py @@ -68,8 +68,9 @@ def json_writer(manual_name: str, all_data: dict) -> None: # Set cooling_present to true m_adam_cooling["gateway"]["cooling_present"] = True -# Remove device "67d73d0bd469422db25a618a5fb8eeb0" from anywhere +# Remove devices "67d73d0bd469422db25a618a5fb8eeb0" and "10016900610d4c7481df78c89606ef22" from anywhere m_adam_cooling["devices"].pop("67d73d0bd469422db25a618a5fb8eeb0") +m_adam_cooling["devices"].pop("10016900610d4c7481df78c89606ef22") # Correct setpoint for "ad4838d7d35c4d6ea796ee12ae5aedf8" m_adam_cooling["devices"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["thermostat"][ From cc45aeb965c3096a919ae3f2a59c43c527327af6 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 11:32:12 +0100 Subject: [PATCH 11/18] Save item_counts --- fixtures/m_adam_cooling/all_data.json | 2 +- fixtures/m_adam_heating/all_data.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fixtures/m_adam_cooling/all_data.json b/fixtures/m_adam_cooling/all_data.json index ffda247bb..90d9ab8d9 100644 --- a/fixtures/m_adam_cooling/all_data.json +++ b/fixtures/m_adam_cooling/all_data.json @@ -189,7 +189,7 @@ "cooling_present": true, "gateway_id": "da224107914542988a88561b4452b0f6", "heater_id": "056ee145a816487eaa69243c3280f8bf", - "item_count": 157, + "item_count": 89, "notifications": {}, "reboot": true, "smile_name": "Adam" diff --git a/fixtures/m_adam_heating/all_data.json b/fixtures/m_adam_heating/all_data.json index bc7fee930..7e6a5a103 100644 --- a/fixtures/m_adam_heating/all_data.json +++ b/fixtures/m_adam_heating/all_data.json @@ -193,7 +193,7 @@ "cooling_present": false, "gateway_id": "da224107914542988a88561b4452b0f6", "heater_id": "056ee145a816487eaa69243c3280f8bf", - "item_count": 157, + "item_count": 89, "notifications": {}, "reboot": true, "smile_name": "Adam" From 8095140fbb511b3f45d11a532ae3ff621c04c1ec Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 11:34:39 +0100 Subject: [PATCH 12/18] Set item_count in script --- scripts/manual_fixtures.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/manual_fixtures.py b/scripts/manual_fixtures.py index 36c177a64..1ec96d80d 100755 --- a/scripts/manual_fixtures.py +++ b/scripts/manual_fixtures.py @@ -65,8 +65,9 @@ def json_writer(manual_name: str, all_data: dict) -> None: m_adam_cooling = base.copy() -# Set cooling_present to true +# Set cooling_present to true, item_count to 89 m_adam_cooling["gateway"]["cooling_present"] = True +m_adam_cooling["gateway"]["item_count"] = 89 # Remove devices "67d73d0bd469422db25a618a5fb8eeb0" and "10016900610d4c7481df78c89606ef22" from anywhere m_adam_cooling["devices"].pop("67d73d0bd469422db25a618a5fb8eeb0") From c7eb40646b52edf8f4c9f3da568d3a551e81c3b7 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 11:37:11 +0100 Subject: [PATCH 13/18] Update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e0c55cfa..a6d3133e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## v1.5.2 + +- Bugfix for Adam: improve recognition of unknown zigbee devices. + ## v1.5.1 - Fix typing and rounding of P1 and thermostat sensors, energy-device-related code improvements. From 5174bed43913facd4e611749f10eba2a6ffa5e3d Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 11:37:53 +0100 Subject: [PATCH 14/18] Bump to v1.5.2a0 test-version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c726b8ca9..a83376501 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "1.5.1" +version = "1.5.2a0" license = {file = "LICENSE"} description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md" From 9fec5a8ae2ee6fbbc6834b03c254d58e2d3aae06 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 11:48:21 +0100 Subject: [PATCH 15/18] Define MODULE_LOCATOR constant and implement --- plugwise/constants.py | 1 + plugwise/helper.py | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/plugwise/constants.py b/plugwise/constants.py index da9cfe6e0..3830e5d45 100644 --- a/plugwise/constants.py +++ b/plugwise/constants.py @@ -81,6 +81,7 @@ MAX_SETPOINT: Final[float] = 30.0 MIN_SETPOINT: Final[float] = 4.0 +MODULE_LOCATOR: Final = "./logs/point_log/*[@id]" NONE: Final = "None" OFF: Final = "off" diff --git a/plugwise/helper.py b/plugwise/helper.py index ae4dcff68..d8ac5f7d8 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -24,6 +24,7 @@ LIMITS, LOCATIONS, LOGGER, + MODULE_LOCATOR, NONE, OFF, P1_MEASUREMENTS, @@ -356,7 +357,7 @@ def _p1_smartmeter_info_finder(self, appl: Munch) -> None: """Collect P1 DSMR SmartMeter info.""" loc_id = next(iter(self.loc_data.keys())) location = self._domain_objects.find(f'./location[@id="{loc_id}"]') - locator = "./logs/point_log/*[@id]" + locator = MODULE_LOCATOR module_data = self._get_module_data(location, locator) if not module_data["contents"]: LOGGER.error("No module data found for SmartMeter") # pragma: no cover @@ -395,7 +396,7 @@ def _appliance_info_finder(self, appl: Munch, appliance: etree) -> Munch: return appl case _ as s if s.endswith("_plug"): # Collect info from plug-types (Plug, Aqara Smart Plug) - locator = "./logs/point_log/*[@id]" + locator = MODULE_LOCATOR module_data = self._get_module_data(appliance, locator) # A plug without module-data is orphaned/ no present if not module_data["contents"]: @@ -714,7 +715,7 @@ def _wireless_availability(self, appliance: etree, data: DeviceData) -> None: Collect the availability-status for wireless connected devices. """ if self.smile(ADAM): - locator = "./logs/point_log/*[@id]" + locator = MODULE_LOCATOR module_data = self._get_module_data(appliance, locator) if not module_data["contents"]: LOGGER.error("No module data found for Plug or wireless thermostat") # pragma: no cover From e9717e05ce1ff4a1cac37f54a40b976d736df31f Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 12:17:43 +0100 Subject: [PATCH 16/18] Simplify availability collection --- plugwise/common.py | 2 ++ plugwise/helper.py | 21 ++------------------- plugwise/legacy/helper.py | 2 ++ 3 files changed, 6 insertions(+), 19 deletions(-) diff --git a/plugwise/common.py b/plugwise/common.py index a1c0ee990..ee6c22e99 100644 --- a/plugwise/common.py +++ b/plugwise/common.py @@ -101,6 +101,7 @@ def _appl_thermostat_info(self, appl: Munch, xml_1: etree, xml_2: etree = None) appl.model_id = appl.model appl.model = check_model(appl.model, appl.vendor_name) + appl.available = module_data["reachable"] appl.hardware = module_data["hardware_version"] appl.firmware = module_data["firmware_version"] appl.zigbee_mac = module_data["zigbee_mac_address"] @@ -190,6 +191,7 @@ def _create_gw_devices(self, appl: Munch) -> None: self.gw_devices[appl.dev_id] = {"dev_class": appl.pwclass} self._count += 1 for key, value in { + "available": appl.available, "firmware": appl.firmware, "hardware": appl.hardware, "location": appl.location, diff --git a/plugwise/helper.py b/plugwise/helper.py index d8ac5f7d8..67a123887 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -300,6 +300,7 @@ def _all_appliances(self) -> None: if appl.pwclass in THERMOSTAT_CLASSES and appl.location is None: continue + appl.available = None appl.dev_id = appliance.attrib["id"] appl.name = appliance.find("name").text appl.model = None @@ -402,6 +403,7 @@ def _appliance_info_finder(self, appl: Munch, appliance: etree) -> Munch: if not module_data["contents"]: return Munch() + appl.available = module_data["reachable"] appl.firmware = module_data["firmware_version"] appl.hardware = module_data["hardware_version"] appl.model_id = module_data["vendor_model"] @@ -514,9 +516,6 @@ def _get_measurement_data(self, dev_id: str) -> DeviceData: if appliance.find("type").text in ACTUATOR_CLASSES: self._get_actuator_functionalities(appliance, device, data) - # Collect availability-status for wireless connected devices to Adam - self._wireless_availability(appliance, data) - if dev_id == self.gateway_id and self.smile(ADAM): self._get_regulation_mode(appliance, data) self._get_gateway_mode(appliance, data) @@ -709,22 +708,6 @@ def _get_actuator_functionalities( act_item = cast(ActuatorType, item) data[act_item] = temp_dict - def _wireless_availability(self, appliance: etree, data: DeviceData) -> None: - """Helper-function for _get_measurement_data(). - - Collect the availability-status for wireless connected devices. - """ - if self.smile(ADAM): - locator = MODULE_LOCATOR - module_data = self._get_module_data(appliance, locator) - if not module_data["contents"]: - LOGGER.error("No module data found for Plug or wireless thermostat") # pragma: no cover - return None # pragma: no cover - - if module_data["reachable"] is not None: - data["available"] = module_data["reachable"] - self._count += 1 - def _get_regulation_mode(self, appliance: etree, data: DeviceData) -> None: """Helper-function for _get_measurement_data(). diff --git a/plugwise/legacy/helper.py b/plugwise/legacy/helper.py index ccd8abb03..a9a62cb88 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -125,6 +125,7 @@ def _all_appliances(self) -> None: appl.pwclass = "heater_central_plug" appl.model = appl.pwclass.replace("_", " ").title() + appl.available = None appl.model_id = None appl.firmware = None appl.hardware = None @@ -251,6 +252,7 @@ def _energy_device_info_finder(self, appliance: etree, appl: Munch) -> Munch: def _p1_smartmeter_info_finder(self, appl: Munch) -> None: """Collect P1 DSMR Smartmeter info.""" loc_id = next(iter(self.loc_data.keys())) + appl.available = None appl.dev_id = loc_id appl.location = loc_id appl.mac = None From 853b0943600e4d8d3192a204b78ed960d00e76c7 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 12:24:50 +0100 Subject: [PATCH 17/18] Bump to a1 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a83376501..156427ef1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "1.5.2a0" +version = "1.5.2a1" license = {file = "LICENSE"} description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md" From e706c47738bba6035b7de59dd9a1f0ba8ab4e7fd Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 12:29:13 +0100 Subject: [PATCH 18/18] Bump to release-version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 156427ef1..ebc2b3cde 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "1.5.2a1" +version = "1.5.2" license = {file = "LICENSE"} description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md"