From decb6ce7f369134cf19e1f5a0ec35aff15cfd91f Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 22 Dec 2024 09:17:22 +0100 Subject: [PATCH 01/16] Debug - full test-output --- plugwise/helper.py | 2 ++ scripts/tests_and_coverage.sh | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index 58e499e0c..5e3efa645 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -338,6 +338,7 @@ def _all_appliances(self) -> None: self._create_gw_entities(appl) if self.smile_type == "power": + LOGGER.debug("HOI home-loc: %s", self._home_location) self._get_p1_smartmeter_info() # Sort the gw_entities @@ -351,6 +352,7 @@ def _get_p1_smartmeter_info(self) -> None: """ appl = Munch() loc_id = next(iter(self._loc_data.keys())) + LOGGER.debug("HOI loc_id: %s", loc_id) if ( location := self._domain_objects.find(f'./location[@id="{loc_id}"]') ) is None: diff --git a/scripts/tests_and_coverage.sh b/scripts/tests_and_coverage.sh index 73be7e825..462744720 100755 --- a/scripts/tests_and_coverage.sh +++ b/scripts/tests_and_coverage.sh @@ -43,7 +43,8 @@ set +u if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "test_and_coverage" ] ; then # Python tests (rerun with debug if failures) - PYTHONPATH=$(pwd) pytest -qx tests/ --cov='.' --no-cov-on-fail --cov-report term-missing || PYTHONPATH=$(pwd) pytest -xrpP --log-level debug tests/ + # PYTHONPATH=$(pwd) pytest -qx tests/ --cov='.' --no-cov-on-fail --cov-report term-missing || + PYTHONPATH=$(pwd) pytest -xrpP --log-level debug tests/ handle_command_error "python code testing" fi From 4010e8c524bf5f33599bdb1a367857c887b12e78 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 22 Dec 2024 09:23:25 +0100 Subject: [PATCH 02/16] _get_p1_smartmeter_info(): use already known home-location --- plugwise/helper.py | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index 5e3efa645..e848a38fa 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -233,7 +233,8 @@ def __init__(self) -> None: self._elga: bool self._gw_allowed_modes: list[str] = [] self._heater_id: str - self._home_location: str + self._home_loc_id: str + self._home_location: etree self._is_thermostat: bool self._last_active: dict[str, str | None] self._last_modified: dict[str, str] = {} @@ -311,10 +312,10 @@ def _all_appliances(self) -> None: appl.location = None if (appl_loc := appliance.find("location")) is not None: appl.location = appl_loc.attrib["id"] - # Don't assign the _home_location to thermostat-devices without a location, + # Don't assign the _home_loc_id to thermostat-devices without a location, # they are not active elif appl.pwclass not in THERMOSTAT_CLASSES: - appl.location = self._home_location + appl.location = self._home_loc_id # Don't show orphaned thermostat-types if appl.pwclass in THERMOSTAT_CLASSES and appl.location is None: @@ -338,7 +339,6 @@ def _all_appliances(self) -> None: self._create_gw_entities(appl) if self.smile_type == "power": - LOGGER.debug("HOI home-loc: %s", self._home_location) self._get_p1_smartmeter_info() # Sort the gw_entities @@ -351,15 +351,8 @@ def _get_p1_smartmeter_info(self) -> None: switched to maintain backward compatibility with existing implementations. """ appl = Munch() - loc_id = next(iter(self._loc_data.keys())) - LOGGER.debug("HOI loc_id: %s", loc_id) - if ( - location := self._domain_objects.find(f'./location[@id="{loc_id}"]') - ) is None: - return - locator = MODULE_LOCATOR - module_data = self._get_module_data(location, locator) + module_data = self._get_module_data(self._home_location, locator) if not module_data["contents"]: LOGGER.error("No module data found for SmartMeter") # pragma: no cover return # pragma: no cover @@ -367,7 +360,7 @@ def _get_p1_smartmeter_info(self) -> None: appl.entity_id = self.gateway_id appl.firmware = module_data["firmware_version"] appl.hardware = module_data["hardware_version"] - appl.location = loc_id + appl.location = self._home_loc_id appl.mac = None appl.model = module_data["vendor_model"] appl.model_id = None # don't use model_id for SmartMeter @@ -377,8 +370,8 @@ def _get_p1_smartmeter_info(self) -> None: appl.zigbee_mac = None # Replace the entity_id of the gateway by the smartmeter location_id - self.gw_entities[loc_id] = self.gw_entities.pop(self.gateway_id) - self.gateway_id = loc_id + self.gw_entities[self._home_loc_id] = self.gw_entities.pop(self.gateway_id) + self.gateway_id = self._home_loc_id self._create_gw_entities(appl) @@ -400,10 +393,14 @@ def _all_locations(self) -> None: for location in locations: loc.name = location.find("name").text loc.loc_id = location.attrib["id"] - if loc.name == "Home": - self._home_location = loc.loc_id - self._loc_data[loc.loc_id] = {"name": loc.name} + if loc.name != "Home": + continue + + self._home_loc_id = loc.loc_id + self._home_location = self._domain_objects.find( + f"./location[@id='{loc.loc_id}']" + ) def _appliance_info_finder(self, appl: Munch, appliance: etree) -> Munch: """Collect info for all appliances found.""" @@ -772,7 +769,7 @@ def _get_gateway_outdoor_temp(self, entity_id: str, data: GwEntityData) -> None: """ if self._is_thermostat and entity_id == self.gateway_id: outdoor_temperature = self._object_value( - self._home_location, "outdoor_temperature" + self._home_loc_id, "outdoor_temperature" ) if outdoor_temperature is not None: data.update({"sensors": {"outdoor_temperature": outdoor_temperature}}) From 90527ed3f70ad098c93c4581611fff9e2ed2e06d Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 22 Dec 2024 09:51:51 +0100 Subject: [PATCH 03/16] Use the _home_location where applicable --- plugwise/helper.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index e848a38fa..37bdfdb7d 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -531,7 +531,7 @@ def _get_measurement_data(self, entity_id: str) -> GwEntityData: # !! DON'T CHANGE below two if-lines, will break stuff !! if self.smile_type == "power": if entity["dev_class"] == "smartmeter": - data.update(self._power_data_from_location(entity["location"])) + data.update(self._power_data_from_location()) return data @@ -573,18 +573,17 @@ def _get_measurement_data(self, entity_id: str) -> GwEntityData: return data - def _power_data_from_location(self, loc_id: str) -> GwEntityData: + def _power_data_from_location(self) -> GwEntityData: """Helper-function for smile.py: _get_entity_data(). - Collect the power-data based on Location ID, from LOCATIONS. + Collect the power-data from the Home location. """ data: GwEntityData = {"sensors": {}} loc = Munch() log_list: list[str] = ["point_log", "cumulative_log", "interval_log"] t_string = "tariff" - search = self._domain_objects - loc.logs = search.find(f'./location[@id="{loc_id}"]/logs') + loc.logs = self._home_location.find("./logs") for loc.measurement, loc.attrs in P1_MEASUREMENTS.items(): for loc.log_type in log_list: self._collect_power_values(data, loc, t_string) @@ -768,22 +767,19 @@ def _get_gateway_outdoor_temp(self, entity_id: str, data: GwEntityData) -> None: Available under the Home location. """ if self._is_thermostat and entity_id == self.gateway_id: - outdoor_temperature = self._object_value( - self._home_loc_id, "outdoor_temperature" - ) + outdoor_temperature = self._home_loc_value("outdoor_temperature") if outdoor_temperature is not None: data.update({"sensors": {"outdoor_temperature": outdoor_temperature}}) self._count += 1 - def _object_value(self, obj_id: str, measurement: str) -> float | int | None: + def _home_loc_value(self, measurement: str) -> float | int | None: """Helper-function for smile.py: _get_entity_data(). - Obtain the value/state for the given object from a location in DOMAIN_OBJECTS + Obtain the value/state for the given measurement from the Home location """ val: float | int | None = None - search = self._domain_objects - locator = f'./location[@id="{obj_id}"]/logs/point_log[type="{measurement}"]/period/measurement' - if (found := search.find(locator)) is not None: + locator = f'./logs/point_log[type="{measurement}"]/period/measurement' + if (found := self._home_location.find(locator)) is not None: val = format_measure(found.text, NONE) return val From 1ff847ecb43b991ec4a0e6a044d057b752f6e637 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 22 Dec 2024 10:01:47 +0100 Subject: [PATCH 04/16] Legacy: change to _home_loc_id --- plugwise/legacy/helper.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/plugwise/legacy/helper.py b/plugwise/legacy/helper.py index 832b6dd5a..ff143e2fe 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -66,7 +66,7 @@ def __init__(self) -> None: self._count: int self._domain_objects: etree self._heater_id: str - self._home_location: str + self._home_loc_id: str self._is_thermostat: bool self._last_modified: dict[str, str] = {} self._loc_data: dict[str, ThermoLoc] @@ -115,7 +115,7 @@ def _all_appliances(self) -> None: ): continue # pragma: no cover - appl.location = self._home_location + appl.location = self._home_loc_id appl.entity_id = appliance.attrib["id"] appl.name = appliance.find("name").text # Extend device_class name when a Circle/Stealth is type heater_central -- Pw-Beta Issue #739 @@ -161,7 +161,7 @@ def _all_locations(self) -> None: # Legacy Anna without outdoor_temp and Stretches have no locations, create fake location-data if not (locations := self._locations.findall("./location")): - self._home_location = FAKE_LOC + self._home_loc_id = FAKE_LOC self._loc_data[FAKE_LOC] = {"name": "Home"} return @@ -174,11 +174,11 @@ def _all_locations(self) -> None: continue if loc.name == "Home": - self._home_location = loc.loc_id + self._home_loc_id = loc.loc_id # Replace location-name for P1 legacy, can contain privacy-related info if self.smile_type == "power": loc.name = "Home" - self._home_location = loc.loc_id + self._home_loc_id = loc.loc_id self._loc_data[loc.loc_id] = {"name": loc.name} @@ -187,7 +187,7 @@ def _create_legacy_gateway(self) -> None: Use the home_location or FAKE_APPL as entity id. """ - self.gateway_id = self._home_location + self.gateway_id = self._home_loc_id if self.smile_type == "power": self.gateway_id = FAKE_APPL @@ -195,7 +195,7 @@ def _create_legacy_gateway(self) -> None: self._count += 1 for key, value in { "firmware": str(self.smile_fw_version), - "location": self._home_location, + "location": self._home_loc_id, "mac_address": self.smile_mac_address, "model": self.smile_model, "name": self.smile_name, @@ -298,7 +298,7 @@ def _get_measurement_data(self, entity_id: str) -> GwEntityData: # The outdoor_temperature present in APPLIANCES is a local sensor connected to the active device if self._is_thermostat and entity_id == self.gateway_id: outdoor_temperature = self._object_value( - self._home_location, "outdoor_temperature" + self._home_loc_id, "outdoor_temperature" ) if outdoor_temperature is not None: data.update({"sensors": {"outdoor_temperature": outdoor_temperature}}) From a1ebda8ba6f816a82414836de768ccdb61187e5c Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 22 Dec 2024 10:04:45 +0100 Subject: [PATCH 05/16] Improve comment --- 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 ff143e2fe..080613687 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -272,7 +272,7 @@ def _get_measurement_data(self, entity_id: str) -> GwEntityData: Collect the appliance-data based on entity_id. """ data: GwEntityData = {"binary_sensors": {}, "sensors": {}, "switches": {}} - # Get P1 smartmeter data from LOCATIONS or MODULES + # Get P1 smartmeter data from MODULES entity = self.gw_entities[entity_id] # !! DON'T CHANGE below two if-lines, will break stuff !! if self.smile_type == "power": From 35fbcd0387dbabda11e24ddde0cfa83729827b15 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 22 Dec 2024 10:08:06 +0100 Subject: [PATCH 06/16] Legacy: rename to _home_loc_value as well --- plugwise/legacy/helper.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/plugwise/legacy/helper.py b/plugwise/legacy/helper.py index 080613687..9c3c71411 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -297,9 +297,7 @@ def _get_measurement_data(self, entity_id: str) -> GwEntityData: # Adam & Anna: the Smile outdoor_temperature is present in DOMAIN_OBJECTS and LOCATIONS - under Home # The outdoor_temperature present in APPLIANCES is a local sensor connected to the active device if self._is_thermostat and entity_id == self.gateway_id: - outdoor_temperature = self._object_value( - self._home_loc_id, "outdoor_temperature" - ) + outdoor_temperature = self._home_loc_value("outdoor_temperature") if outdoor_temperature is not None: data.update({"sensors": {"outdoor_temperature": outdoor_temperature}}) self._count += 1 @@ -396,14 +394,14 @@ def _get_actuator_functionalities( act_item = cast(ActuatorType, item) data[act_item] = temp_dict - def _object_value(self, obj_id: str, measurement: str) -> float | int | None: + def _home_loc_value(self, measurement: str) -> float | int | None: """Helper-function for smile.py: _get_entity_data(). - Obtain the value/state for the given object from a location in DOMAIN_OBJECTS + Obtain the value/state for the given measurement from the Home location """ val: float | int | None = None search = self._domain_objects - locator = f'./location[@id="{obj_id}"]/logs/point_log[type="{measurement}"]/period/measurement' + locator = f"./location[@id='{self._home_loc_id}']/logs/point_log[type='{measurement}']/period/measurement" if (found := search.find(locator)) is not None: val = format_measure(found.text, NONE) return val From 353bf3eb6e4eb256060e3f96ca783f3248ccbca1 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 22 Dec 2024 10:12:23 +0100 Subject: [PATCH 07/16] Add clarifying comment --- plugwise/util.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugwise/util.py b/plugwise/util.py index e2d1a125a..e0613f5db 100644 --- a/plugwise/util.py +++ b/plugwise/util.py @@ -156,6 +156,7 @@ def format_measure(measure: str, unit: str) -> float | int: result: float | int = 0 try: result = int(measure) + # Return for instance 20 (degrees) as 20.0 if unit == TEMP_CELSIUS: result = float(measure) except ValueError: From f50b70bcd9e659090e8acb7744ad1b190e548111 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 22 Dec 2024 10:21:09 +0100 Subject: [PATCH 08/16] Simplify --- plugwise/helper.py | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index 37bdfdb7d..bc54f0387 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -762,28 +762,14 @@ def _get_gateway_mode( self._count += 1 def _get_gateway_outdoor_temp(self, entity_id: str, data: GwEntityData) -> None: - """Adam & Anna: the Smile outdoor_temperature is present in DOMAIN_OBJECTS and LOCATIONS. - - Available under the Home location. - """ + """Adam & Anna: the Smile outdoor_temperature is present in the Home location.""" if self._is_thermostat and entity_id == self.gateway_id: - outdoor_temperature = self._home_loc_value("outdoor_temperature") - if outdoor_temperature is not None: - data.update({"sensors": {"outdoor_temperature": outdoor_temperature}}) + locator = "./logs/point_log[type='outdoor_temperature']/period/measurement" + if (found := self._home_location.find(locator)) is not None: + val = format_measure(found.text, NONE) + data.update({"sensors": {"outdoor_temperature": val}}) self._count += 1 - def _home_loc_value(self, measurement: str) -> float | int | None: - """Helper-function for smile.py: _get_entity_data(). - - Obtain the value/state for the given measurement from the Home location - """ - val: float | int | None = None - locator = f'./logs/point_log[type="{measurement}"]/period/measurement' - if (found := self._home_location.find(locator)) is not None: - val = format_measure(found.text, NONE) - - return val - def _process_c_heating_state(self, data: GwEntityData) -> None: """Helper-function for _get_measurement_data(). From a09cf6c3f097b4fcfa776a81054cc58b27bacbd9 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 22 Dec 2024 10:27:59 +0100 Subject: [PATCH 09/16] Simplify legacy too --- plugwise/legacy/helper.py | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/plugwise/legacy/helper.py b/plugwise/legacy/helper.py index 9c3c71411..6e195493b 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -294,12 +294,13 @@ def _get_measurement_data(self, entity_id: str) -> GwEntityData: if appliance.find("type").text in ACTUATOR_CLASSES: self._get_actuator_functionalities(appliance, entity, data) - # Adam & Anna: the Smile outdoor_temperature is present in DOMAIN_OBJECTS and LOCATIONS - under Home - # The outdoor_temperature present in APPLIANCES is a local sensor connected to the active device + # Anna: the Smile outdoor_temperature is present in DOMAIN_OBJECTS or LOCATIONS - under Home + # Some Anna's have an empty LOCATIONS! if self._is_thermostat and entity_id == self.gateway_id: - outdoor_temperature = self._home_loc_value("outdoor_temperature") - if outdoor_temperature is not None: - data.update({"sensors": {"outdoor_temperature": outdoor_temperature}}) + locator = f"./location[@id='{self._home_loc_id}']/logs/point_log[type='outdoor_temperature']/period/measurement" + if (found := self._domain_objects.find(locator)) is not None: + value = format_measure(found.text, NONE) + data.update({"sensors": {"outdoor_temperature": value}}) self._count += 1 if "c_heating_state" in data: @@ -394,20 +395,6 @@ def _get_actuator_functionalities( act_item = cast(ActuatorType, item) data[act_item] = temp_dict - def _home_loc_value(self, measurement: str) -> float | int | None: - """Helper-function for smile.py: _get_entity_data(). - - Obtain the value/state for the given measurement from the Home location - """ - val: float | int | None = None - search = self._domain_objects - locator = f"./location[@id='{self._home_loc_id}']/logs/point_log[type='{measurement}']/period/measurement" - if (found := search.find(locator)) is not None: - val = format_measure(found.text, NONE) - return val - - return val - def _preset(self) -> str | None: """Helper-function for smile.py: _climate_data(). From 98be2b906b66d1c7fd14015618c35ed705d31151 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 22 Dec 2024 10:29:28 +0100 Subject: [PATCH 10/16] Full var name --- plugwise/helper.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index bc54f0387..db1a6d500 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -766,8 +766,8 @@ def _get_gateway_outdoor_temp(self, entity_id: str, data: GwEntityData) -> None: if self._is_thermostat and entity_id == self.gateway_id: locator = "./logs/point_log[type='outdoor_temperature']/period/measurement" if (found := self._home_location.find(locator)) is not None: - val = format_measure(found.text, NONE) - data.update({"sensors": {"outdoor_temperature": val}}) + value = format_measure(found.text, NONE) + data.update({"sensors": {"outdoor_temperature": value}}) self._count += 1 def _process_c_heating_state(self, data: GwEntityData) -> None: From ec36bd0cfdde7296bdaac9507c7db4887514fbb1 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 22 Dec 2024 10:30:54 +0100 Subject: [PATCH 11/16] Update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 294f7c4e3..c31c5bcea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Ongoing + +- Continuous improvements + ## v1.6.4 - Continuous improvements [#662](https://github.com/plugwise/python-plugwise/pull/662) From f2880b71c8a66729cf1624d3058f4edb24b1b885 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 22 Dec 2024 10:33:02 +0100 Subject: [PATCH 12/16] Back to normal test-output --- scripts/tests_and_coverage.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/tests_and_coverage.sh b/scripts/tests_and_coverage.sh index 462744720..73be7e825 100755 --- a/scripts/tests_and_coverage.sh +++ b/scripts/tests_and_coverage.sh @@ -43,8 +43,7 @@ set +u if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "test_and_coverage" ] ; then # Python tests (rerun with debug if failures) - # PYTHONPATH=$(pwd) pytest -qx tests/ --cov='.' --no-cov-on-fail --cov-report term-missing || - PYTHONPATH=$(pwd) pytest -xrpP --log-level debug tests/ + PYTHONPATH=$(pwd) pytest -qx tests/ --cov='.' --no-cov-on-fail --cov-report term-missing || PYTHONPATH=$(pwd) pytest -xrpP --log-level debug tests/ handle_command_error "python code testing" fi From 651688d6fadae33a5c0edcfd5939c560a477b02b Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 22 Dec 2024 10:37:58 +0100 Subject: [PATCH 13/16] Extend CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c31c5bcea..140caf057 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Ongoing -- Continuous improvements +- Continuous improvements [#678](https://github.com/plugwise/python-plugwise/pull/678) ## v1.6.4 From 5e817cd5ddc6acb329fd15b5195a2465c1d7d1a4 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 22 Dec 2024 11:03:07 +0100 Subject: [PATCH 14/16] Remove try-except from format_measure, exception never happens --- plugwise/util.py | 42 ++++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/plugwise/util.py b/plugwise/util.py index e0613f5db..03fab5729 100644 --- a/plugwise/util.py +++ b/plugwise/util.py @@ -20,7 +20,6 @@ SPECIAL_FORMAT, SPECIALS, SWITCHES, - TEMP_CELSIUS, UOM, BinarySensorType, GwEntityData, @@ -151,30 +150,25 @@ def escape_illegal_xml_characters(xmldata: str) -> str: return re.sub(r"&([^a-zA-Z#])", r"&\1", xmldata) -def format_measure(measure: str, unit: str) -> float | int: +def format_measure(measure: str, unit: str) -> float: """Format measure to correct type.""" - result: float | int = 0 - try: - result = int(measure) - # Return for instance 20 (degrees) as 20.0 - if unit == TEMP_CELSIUS: - result = float(measure) - except ValueError: - float_measure = float(measure) - if unit == PERCENTAGE and 0 < float_measure <= 1: - return int(float_measure * 100) - - if unit == ENERGY_KILO_WATT_HOUR: - float_measure = float_measure / 1000 - - if unit in SPECIAL_FORMAT: - result = float(f"{round(float_measure, 3):.3f}") - elif unit == ELECTRIC_POTENTIAL_VOLT: - result = float(f"{round(float_measure, 1):.1f}") - elif abs(float_measure) < 10: - result = float(f"{round(float_measure, 2):.2f}") - elif abs(float_measure) >= 10: - result = float(f"{round(float_measure, 1):.1f}") + result: float = 0.0 + + float_measure = float(measure) + if unit == PERCENTAGE and 0 < float_measure <= 1: + return int(float_measure * 100) + + if unit == ENERGY_KILO_WATT_HOUR: + float_measure = float_measure / 1000 + + if unit in SPECIAL_FORMAT: + result = float(f"{round(float_measure, 3):.3f}") + elif unit == ELECTRIC_POTENTIAL_VOLT: + result = float(f"{round(float_measure, 1):.1f}") + elif abs(float_measure) < 10: + result = float(f"{round(float_measure, 2):.2f}") + elif abs(float_measure) >= 10: + result = float(f"{round(float_measure, 1):.1f}") return result From 619e2d8dcc7c4f8491c4b1602deea166f0e483dd Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 22 Dec 2024 11:07:17 +0100 Subject: [PATCH 15/16] Return int-typing --- plugwise/util.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugwise/util.py b/plugwise/util.py index 03fab5729..e20bb5edb 100644 --- a/plugwise/util.py +++ b/plugwise/util.py @@ -150,9 +150,9 @@ def escape_illegal_xml_characters(xmldata: str) -> str: return re.sub(r"&([^a-zA-Z#])", r"&\1", xmldata) -def format_measure(measure: str, unit: str) -> float: +def format_measure(measure: str, unit: str) -> float | int: """Format measure to correct type.""" - result: float = 0.0 + result: float | int = 0 float_measure = float(measure) if unit == PERCENTAGE and 0 < float_measure <= 1: From 566f266b55ac106b805211858a2f5cc8d9121f3c Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 22 Dec 2024 11:46:26 +0100 Subject: [PATCH 16/16] Improve comment --- plugwise/legacy/helper.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugwise/legacy/helper.py b/plugwise/legacy/helper.py index 6e195493b..69c5abe7b 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -294,8 +294,8 @@ def _get_measurement_data(self, entity_id: str) -> GwEntityData: if appliance.find("type").text in ACTUATOR_CLASSES: self._get_actuator_functionalities(appliance, entity, data) - # Anna: the Smile outdoor_temperature is present in DOMAIN_OBJECTS or LOCATIONS - under Home - # Some Anna's have an empty LOCATIONS! + # Anna: the Smile outdoor_temperature is present in the Home location + # For some Anna's LOCATIONS is empty, falling back to domain_objects! if self._is_thermostat and entity_id == self.gateway_id: locator = f"./location[@id='{self._home_loc_id}']/logs/point_log[type='outdoor_temperature']/period/measurement" if (found := self._domain_objects.find(locator)) is not None: