From dab4b28a25bd6f90343107e4cd2f363a6c459565 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 13 Jul 2026 20:15:11 +0200 Subject: [PATCH 01/21] Correct m_adam_heating water_temperature --- scripts/manual_fixtures.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/manual_fixtures.py b/scripts/manual_fixtures.py index a62d9cf3b..4c0c30b7e 100755 --- a/scripts/manual_fixtures.py +++ b/scripts/manual_fixtures.py @@ -131,6 +131,9 @@ def json_writer(manual_name: str, output: dict) -> None: m_adam_cooling["056ee145a816487eaa69243c3280f8bf"]["sensors"][ "intended_boiler_temperature" ] = 17.5 +m_adam_cooling["056ee145a816487eaa69243c3280f8bf"]["sensors"][ + "water_temperature" +] = 19.0 json_writer("m_adam_cooling", m_adam_cooling) From aebdaa9694911a43adce232c2e9406a9b572a506 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 13 Jul 2026 20:18:55 +0200 Subject: [PATCH 02/21] Correct m_anna_heatpump_cooling fixture --- scripts/manual_fixtures.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/manual_fixtures.py b/scripts/manual_fixtures.py index 4c0c30b7e..fd25e76df 100755 --- a/scripts/manual_fixtures.py +++ b/scripts/manual_fixtures.py @@ -255,6 +255,9 @@ def json_writer(manual_name: str, output: dict) -> None: m_anna_heatpump_cooling["1cbf783bb11e4a7c8a6843dee3a86927"]["maximum_boiler_temperature"]["current"] = 22.7 m_anna_heatpump_cooling["1cbf783bb11e4a7c8a6843dee3a86927"]["max_dhw_temperature"]["current"] = 41.5 +m_anna_heatpump_cooling["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ + "dhw_temperature" +] = 41.5 m_anna_heatpump_cooling["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "intended_boiler_temperature" ] = 0.0 @@ -267,6 +270,9 @@ def json_writer(manual_name: str, output: dict) -> None: m_anna_heatpump_cooling["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "outdoor_air_temperature" ] = 28.0 +m_anna_heatpump_cooling["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ + "water_temperature" +] = 22.7 # Go for 015a m_anna_heatpump_cooling["015ae9ea3f964e668e490fa39da3870b"]["sensors"][ From 9cf82822438249abbcd315f52ce9d64ae58383ec Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 15 Jul 2026 19:40:23 +0200 Subject: [PATCH 03/21] Optimize set_dhw_mode(), set_select(), set_schedule_state() functions --- plugwise/smile.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugwise/smile.py b/plugwise/smile.py index 39deea4ce..b1a482a3a 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -232,7 +232,7 @@ async def set_preset(self, loc_id: str, preset: str) -> None: await self.call_request(uri, method="put", data=data) async def set_select( - self, key: str, appl_or_loc_id: str, option: str, state: str | None + self, key: str, appl_or_loc_id: str, option: str, ) -> None: """Set a dhw/gateway/regulation mode or the thermostat schedule option.""" match key: @@ -247,13 +247,13 @@ async def set_select( case "select_schedule": # The schedule name corresponds to the select option # Location id is passed - await self.set_schedule_state(appl_or_loc_id, state, option) + await self.set_schedule_state(appl_or_loc_id, option) case "select_zone_profile": # Location id is passed await self.set_zone_profile(appl_or_loc_id, option) async def set_dhw_mode( - self, key: str, appl_id: str, length: int, mode: str + self, key: str, appl_id: str, mode: str, length: int ) -> None: """Set the domestic hot water mode. @@ -266,7 +266,7 @@ async def set_dhw_mode( match length: case 2: - await self.set_select(key, appl_id, mode, None) + await self.set_select(key, appl_id, mode) case _: data = ( "" @@ -344,8 +344,8 @@ async def set_zone_profile(self, loc_id: str, profile: str) -> None: async def set_schedule_state( self, loc_id: str, - new_state: str | None, name: str | None, + new_state: str | None, ) -> None: """Activate/deactivate the Schedule, with the given name, on the relevant Thermostat. From 8900a2c4be1244920c7606597574f1ffce54eae7 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 15 Jul 2026 19:47:24 +0200 Subject: [PATCH 04/21] Also optimize the legacy set-functions --- plugwise/legacy/smile.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugwise/legacy/smile.py b/plugwise/legacy/smile.py index 419f2fde9..897555401 100644 --- a/plugwise/legacy/smile.py +++ b/plugwise/legacy/smile.py @@ -132,7 +132,7 @@ async def reboot_gateway(self) -> None: """Set-function placeholder for legacy devices.""" async def set_dhw_mode( - self, key: str, location: str, length: int, mode: str + self, key: str, location: str, mode: str, length: int, ) -> None: """Set-function placeholder for legacy devices.""" @@ -170,14 +170,14 @@ async def set_regulation_mode(self, mode: str) -> None: """Set-function placeholder for legacy devices.""" async def set_select( - self, key: str, loc_id: str, option: str, state: str | None + self, key: str, loc_id: str, option: str, ) -> None: """Set the thermostat schedule option.""" # schedule name corresponds to select option - await self.set_schedule_state("dummy", state, option) + await self.set_schedule_state("dummy", option) async def set_schedule_state( - self, _: str, state: str | None, name: str | None + self, _: str, name: str | None, state: str | None = None, ) -> None: """Activate/deactivate the Schedule. From 8b1c9394ba1c385c41803aafcc890dfc5c064a05 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 15 Jul 2026 19:54:41 +0200 Subject: [PATCH 05/21] Fix test set_select() call --- tests/test_init.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_init.py b/tests/test_init.py index b7947ba4a..3a1e7b408 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -744,7 +744,7 @@ async def tinker_thermostat_schedule( new_schedule = new_schedule[1:] _LOGGER.info("- Adjusting schedule to %s", f"{new_schedule}{warning}") try: - await api.set_select("select_schedule", loc_id, new_schedule, state) + await api.set_select("select_schedule", loc_id, new_schedule) tinker_schedule_passed = True _LOGGER.info(" + working as intended") except pw_exceptions.PlugwiseError: From 20fdf79b4d92a1bd0e0b690fa826863edfa6f756 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 15 Jul 2026 19:59:36 +0200 Subject: [PATCH 06/21] Update set-function in __init__.py --- plugwise/__init__.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/plugwise/__init__.py b/plugwise/__init__.py index fe8a9470e..30fac7404 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -358,11 +358,10 @@ async def set_select( key: str, loc_id: str, option: str, - state: str | None = None, ) -> None: """Set the selected option for the applicable Select.""" try: - await self._smile_api.set_select(key, loc_id, option, state) + await self._smile_api.set_select(key, loc_id, option) except ConnectionFailedError as exc: raise ConnectionFailedError( f"Failed to set select option '{option}': {str(exc)}" @@ -371,12 +370,12 @@ async def set_select( async def set_schedule_state( self, loc_id: str, - state: str | None, name: str | None = None, + state: str | None = None ) -> None: """Activate/deactivate the Schedule, with the given name, on the relevant Thermostat.""" try: - await self._smile_api.set_schedule_state(loc_id, state, name) + await self._smile_api.set_schedule_state(loc_id, name, state) except ConnectionFailedError as exc: # pragma no cover raise ConnectionFailedError( f"Failed to set schedule state: {str(exc)}" @@ -462,12 +461,12 @@ async def set_regulation_mode(self, mode: str) -> None: ) from exc # pragma no cover async def set_dhw_mode( - self, key: str, location: str, length: int, mode: str + self, key: str, location: str, mode: str, length: int, ) -> None: """Set the domestic hot water heating regulation mode.""" try: # pragma no cover await self._smile_api.set_dhw_mode( - key, location, length, mode + key, location, mode, length, ) # pragma: no cover except ConnectionFailedError as exc: # pragma no cover raise ConnectionFailedError( From c1c9cadc290f166f390279f6fe578426396819a2 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 15 Jul 2026 20:13:21 +0200 Subject: [PATCH 07/21] Try different approach for state --- plugwise/__init__.py | 2 +- plugwise/legacy/smile.py | 6 +++--- plugwise/smile.py | 14 ++++++++------ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/plugwise/__init__.py b/plugwise/__init__.py index 30fac7404..27c13fdde 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -371,7 +371,7 @@ async def set_schedule_state( self, loc_id: str, name: str | None = None, - state: str | None = None + state: str | None = None, ) -> None: """Activate/deactivate the Schedule, with the given name, on the relevant Thermostat.""" try: diff --git a/plugwise/legacy/smile.py b/plugwise/legacy/smile.py index 897555401..337b4a648 100644 --- a/plugwise/legacy/smile.py +++ b/plugwise/legacy/smile.py @@ -170,14 +170,14 @@ async def set_regulation_mode(self, mode: str) -> None: """Set-function placeholder for legacy devices.""" async def set_select( - self, key: str, loc_id: str, option: str, + self, key: str, loc_id: str, option: str, state: str | None = None, ) -> None: """Set the thermostat schedule option.""" # schedule name corresponds to select option - await self.set_schedule_state("dummy", option) + await self.set_schedule_state("loc_id", option, state=state) async def set_schedule_state( - self, _: str, name: str | None, state: str | None = None, + self, _: str, name: str | None = None, state: str | None = None, ) -> None: """Activate/deactivate the Schedule. diff --git a/plugwise/smile.py b/plugwise/smile.py index b1a482a3a..ca7cc9779 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -345,7 +345,7 @@ async def set_schedule_state( self, loc_id: str, name: str | None, - new_state: str | None, + state: str | None = None ) -> None: """Activate/deactivate the Schedule, with the given name, on the relevant Thermostat. @@ -353,12 +353,14 @@ async def set_schedule_state( Used in HA Core to set the hvac_mode: in practice switch between schedule on - off. """ # Input checking - if new_state not in (STATE_OFF, STATE_ON): + if state is None: + state = STATE_ON + elif state not in (STATE_OFF, STATE_ON): raise PlugwiseError("Plugwise: invalid schedule state.") # Translate selection of Off-schedule-option to disabling the active schedule if name == OFF: - new_state = STATE_OFF + state = STATE_OFF # Handle no schedule-name / schedule-off requested: find the active schedule if name is None or name == OFF: @@ -372,7 +374,7 @@ async def set_schedule_state( raise PlugwiseError("Plugwise: no schedule with this name available.") # If no state change is requested, do nothing - if new_state == self._schedule_old_states[loc_id][name]: + if state == self._schedule_old_states[loc_id][name]: return schedule_rule_id: str = next(iter(schedule_rule)) @@ -384,7 +386,7 @@ async def set_schedule_state( template_id = self._domain_objects.find(locator).get("id") template = f'