From 7d3fc05cc0b2fc0c969a81291d90aece88df55ed Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Tue, 14 May 2024 08:28:41 +0200 Subject: [PATCH 01/14] Start adding set_select() function --- plugwise/__init__.py | 4 +++ plugwise/smile.py | 78 +++++++++++++++++++++++++------------------- 2 files changed, 49 insertions(+), 33 deletions(-) diff --git a/plugwise/__init__.py b/plugwise/__init__.py index 9ccbf8335..04b62b4cf 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -306,6 +306,10 @@ async def async_update(self) -> PlugwiseData: ### API Set and HA Service-related Functions ### ######################################################################################################## + async def set_select(self, key: str, loc_id: str, option: str, name: str) -> None: + """Set the selected option for the applicable Select.""" + await self._smile_api.set_select(loc_id, option) + async def set_schedule_state( self, loc_id: str, diff --git a/plugwise/smile.py b/plugwise/smile.py index e1cbdc359..96f5bf8b3 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -149,39 +149,6 @@ async def delete_notification(self) -> None: """Delete the active Plugwise Notification.""" await self._request(NOTIFICATIONS, method="delete") - async def set_dhw_mode(self, mode: str) -> None: - """Set the domestic hot water heating regulation mode.""" - if mode not in self._dhw_allowed_modes: - raise PlugwiseError("Plugwise: invalid dhw mode.") - - uri = f"{APPLIANCES};type=heater_central/domestic_hot_water_mode_control" - data = f"{mode}" - - await self._request(uri, method="put", data=data) - - async def set_gateway_mode(self, mode: str) -> None: - """Set the gateway mode.""" - if mode not in self._gw_allowed_modes: - raise PlugwiseError("Plugwise: invalid gateway mode.") - - end_time = "2037-04-21T08:00:53.000Z" - valid = "" - if mode == "away": - time_1 = self._domain_objects.find("./gateway/time").text - away_time = dt.datetime.fromisoformat(time_1).astimezone(dt.UTC).isoformat(timespec="milliseconds").replace("+00:00", "Z") - valid = ( - f"{away_time}{end_time}" - ) - if mode == "vacation": - time_2 = str(dt.date.today() - dt.timedelta(1)) - vacation_time = time_2 + "T23:00:00.000Z" - valid = f"{vacation_time}{end_time}" - - uri = f"{APPLIANCES};id={self.gateway_id}/gateway_mode_control" - data = f"{mode}{valid}" - - await self._request(uri, method="put", data=data) - async def set_number( self, dev_id: str, @@ -241,6 +208,51 @@ async def set_preset(self, loc_id: str, preset: str) -> None: await self._request(uri, method="put", data=data) + async def set_select(self, key: str, loc_id: str, option: str, name: str) -> None: + """Set a dhw/gateway/regulation mode or the thermostat schedule option.""" + match key: + case "select_dhw_mode": + await set_dhw_mode(option) + case: "select_gateway_mode": + await set_gateway_mode(option) + case "select_regulation_mode": + await set_regulation_mode(option) + case "select_schedule": + await set_schedule_state(loc_id, option, name) + + async def set_dhw_mode(self, mode: str) -> None: + """Set the domestic hot water heating regulation mode.""" + if mode not in self._dhw_allowed_modes: + raise PlugwiseError("Plugwise: invalid dhw mode.") + + uri = f"{APPLIANCES};type=heater_central/domestic_hot_water_mode_control" + data = f"{mode}" + + await self._request(uri, method="put", data=data) + + async def set_gateway_mode(self, mode: str) -> None: + """Set the gateway mode.""" + if mode not in self._gw_allowed_modes: + raise PlugwiseError("Plugwise: invalid gateway mode.") + + end_time = "2037-04-21T08:00:53.000Z" + valid = "" + if mode == "away": + time_1 = self._domain_objects.find("./gateway/time").text + away_time = dt.datetime.fromisoformat(time_1).astimezone(dt.UTC).isoformat(timespec="milliseconds").replace("+00:00", "Z") + valid = ( + f"{away_time}{end_time}" + ) + if mode == "vacation": + time_2 = str(dt.date.today() - dt.timedelta(1)) + vacation_time = time_2 + "T23:00:00.000Z" + valid = f"{vacation_time}{end_time}" + + uri = f"{APPLIANCES};id={self.gateway_id}/gateway_mode_control" + data = f"{mode}{valid}" + + await self._request(uri, method="put", data=data) + async def set_regulation_mode(self, mode: str) -> None: """Set the heating regulation mode.""" if mode not in self._reg_allowed_modes: From d446c645c2af7411882cff264d71825e8e94d210 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 16 May 2024 19:10:30 +0200 Subject: [PATCH 02/14] Add pragma: no cover's --- plugwise/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugwise/__init__.py b/plugwise/__init__.py index 04b62b4cf..94a2154fc 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -348,15 +348,15 @@ async def set_switch_state( async def set_gateway_mode(self, mode: str) -> None: """Set the gateway mode.""" - await self._smile_api.set_gateway_mode(mode) + await self._smile_api.set_gateway_mode(mode) # pragma: no cover async def set_regulation_mode(self, mode: str) -> None: """Set the heating regulation mode.""" - await self._smile_api.set_regulation_mode(mode) + await self._smile_api.set_regulation_mode(mode) # pragma: no cover async def set_dhw_mode(self, mode: str) -> None: """Set the domestic hot water heating regulation mode.""" - await self._smile_api.set_dhw_mode(mode) + await self._smile_api.set_dhw_mode(mode) # pragma: no cover async def delete_notification(self) -> None: """Delete the active Plugwise Notification.""" From d4d04747a67ff3bfda31d3e9b36c421f2acae4a6 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 16 May 2024 19:26:10 +0200 Subject: [PATCH 03/14] Further updates --- plugwise/__init__.py | 10 ++++++++-- plugwise/smile.py | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/plugwise/__init__.py b/plugwise/__init__.py index 94a2154fc..245aadae1 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -306,9 +306,15 @@ async def async_update(self) -> PlugwiseData: ### API Set and HA Service-related Functions ### ######################################################################################################## - async def set_select(self, key: str, loc_id: str, option: str, name: str) -> None: + async def set_select( + self, + key: str, + loc_id: str, + option: str, + name: str | None = None, + ) -> None: """Set the selected option for the applicable Select.""" - await self._smile_api.set_select(loc_id, option) + await self._smile_api.set_select(key, loc_id, option, name) async def set_schedule_state( self, diff --git a/plugwise/smile.py b/plugwise/smile.py index 96f5bf8b3..676b20aec 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -208,7 +208,7 @@ async def set_preset(self, loc_id: str, preset: str) -> None: await self._request(uri, method="put", data=data) - async def set_select(self, key: str, loc_id: str, option: str, name: str) -> None: + async def set_select(self, key: str, loc_id: str, option: str, name: str | None) -> None: """Set a dhw/gateway/regulation mode or the thermostat schedule option.""" match key: case "select_dhw_mode": @@ -270,7 +270,7 @@ async def set_schedule_state( self, loc_id: str, new_state: str, - name: str | None = None, + name: str | None, ) -> None: """Activate/deactivate the Schedule, with the given name, on the relevant Thermostat. From 24b00cc068b332ff1c7331e53743992bbdf7e284 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 20 May 2024 10:40:49 +0200 Subject: [PATCH 04/14] Also implement for legacy Anna --- plugwise/legacy/smile.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugwise/legacy/smile.py b/plugwise/legacy/smile.py index 293f0dfb3..bfeef062c 100644 --- a/plugwise/legacy/smile.py +++ b/plugwise/legacy/smile.py @@ -182,6 +182,10 @@ async def set_preset(self, _: str, preset: str) -> None: 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, name: str | None) -> None: + """Set the thermostat schedule option.""" + await set_schedule_state("dummy", option, name) + async def set_schedule_state(self, _: str, state: str, name: str | None) -> None: """Activate/deactivate the Schedule. From a7e4850ec1ecf2c7cc404240b8538ee80a2817c4 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 20 May 2024 15:21:02 +0200 Subject: [PATCH 05/14] Add test-cases I --- tests/test_init.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_init.py b/tests/test_init.py index fbc6cc727..fffb179ae 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -733,7 +733,7 @@ async def tinker_thermostat_schedule( new_schedule = new_schedule[1:] _LOGGER.info("- Adjusting schedule to %s", f"{new_schedule}{warning}") try: - await smile.set_schedule_state(loc_id, state, new_schedule) + await smile.set_select("select_schedule", loc_id, state, new_schedule) tinker_schedule_passed = True _LOGGER.info(" + working as intended") except pw_exceptions.PlugwiseError: @@ -763,7 +763,7 @@ async def tinker_legacy_thermostat_schedule(self, smile, unhappy=False): for state in states: _LOGGER.info("- Adjusting schedule to state %s", state) try: - await smile.set_schedule_state(None, state) + await smile.set_select("select_schedule", "dummy", state) tinker_schedule_passed = True _LOGGER.info(" + working as intended") except pw_exceptions.PlugwiseError: From c1b2c0c33eeb297047a79d55a023f14b4749a184 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 20 May 2024 15:21:50 +0200 Subject: [PATCH 06/14] Fix typo --- plugwise/smile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugwise/smile.py b/plugwise/smile.py index 676b20aec..ea05f6354 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -213,7 +213,7 @@ async def set_select(self, key: str, loc_id: str, option: str, name: str | None) match key: case "select_dhw_mode": await set_dhw_mode(option) - case: "select_gateway_mode": + case "select_gateway_mode": await set_gateway_mode(option) case "select_regulation_mode": await set_regulation_mode(option) From b14fc4ac425ab1c95e9beefa73e44856cd8e7d50 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 20 May 2024 15:23:51 +0200 Subject: [PATCH 07/14] Fix selfs --- plugwise/legacy/smile.py | 2 +- plugwise/smile.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plugwise/legacy/smile.py b/plugwise/legacy/smile.py index bfeef062c..64b5f6831 100644 --- a/plugwise/legacy/smile.py +++ b/plugwise/legacy/smile.py @@ -184,7 +184,7 @@ async def set_regulation_mode(self, mode: str) -> None: async def set_select(self, key: str, loc_id: str, option: str, name: str | None) -> None: """Set the thermostat schedule option.""" - await set_schedule_state("dummy", option, name) + await self.set_schedule_state("dummy", option, name) async def set_schedule_state(self, _: str, state: str, name: str | None) -> None: """Activate/deactivate the Schedule. diff --git a/plugwise/smile.py b/plugwise/smile.py index ea05f6354..607da9467 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -212,13 +212,13 @@ async def set_select(self, key: str, loc_id: str, option: str, name: str | None) """Set a dhw/gateway/regulation mode or the thermostat schedule option.""" match key: case "select_dhw_mode": - await set_dhw_mode(option) + await self.set_dhw_mode(option) case "select_gateway_mode": - await set_gateway_mode(option) + await self.set_gateway_mode(option) case "select_regulation_mode": - await set_regulation_mode(option) + await self.set_regulation_mode(option) case "select_schedule": - await set_schedule_state(loc_id, option, name) + await self.set_schedule_state(loc_id, option, name) async def set_dhw_mode(self, mode: str) -> None: """Set the domestic hot water heating regulation mode.""" From 2a8b58928181ae8615c537c2121132d5de402584 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 20 May 2024 15:27:35 +0200 Subject: [PATCH 08/14] Adapt test-cases II --- tests/test_init.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_init.py b/tests/test_init.py index fffb179ae..45fc05469 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -847,7 +847,7 @@ async def tinker_dhw_mode(smile): mode = mode[1:] _LOGGER.info("%s", f"- Adjusting dhw mode to {mode}{warning}") try: - await smile.set_dhw_mode(mode) + await smile.set_select("select_dhw_mode", "dummy", mode) _LOGGER.info(" + tinker_dhw_mode worked as intended") except pw_exceptions.PlugwiseError: _LOGGER.info(" + tinker_dhw_mode found invalid mode, as expected") @@ -862,7 +862,7 @@ async def tinker_regulation_mode(smile): mode = mode[1:] _LOGGER.info("%s", f"- Adjusting regulation mode to {mode}{warning}") try: - await smile.set_regulation_mode(mode) + await smile.set_select("select_regulation_mode", "dummy", mode) _LOGGER.info(" + tinker_regulation_mode worked as intended") except pw_exceptions.PlugwiseError: _LOGGER.info( @@ -904,7 +904,7 @@ async def tinker_gateway_mode(smile): mode = mode[1:] _LOGGER.info("%s", f"- Adjusting gateway mode to {mode}{warning}") try: - await smile.set_gateway_mode(mode) + await smile.set_select("select_gateway_mode", "dummy", mode) _LOGGER.info(" + worked as intended") except pw_exceptions.PlugwiseError: _LOGGER.info(" + found invalid mode, as expected") From 77854a933c1b95769b402c941b2cda291ce6d24a Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 20 May 2024 15:42:15 +0200 Subject: [PATCH 09/14] Update CHANGELOG --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8e70aabc..d9bd6c50a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Ongoing + +- Create a set_select() function, combining the set_dhw_mode(), set_gateway_mode(), set_regulation_mode() and set_schedule_state() functions. + ## v0.37.7 - Don't output schedule-related data when no valid schedule(s) found. @@ -17,6 +21,8 @@ ## v0.37.4 - not released +- Create a set_number() function, combining the set_number_setpoint() and set_temperature_offset() functions. + ## v0.37.3 - Fix for [plugwise-beta #620](https://github.com/plugwise/plugwise-beta/issues/620). From 1c0c1988395b9e83967bd6f4ddb34d7ddf5f1b2b Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 20 May 2024 15:42:42 +0200 Subject: [PATCH 10/14] Bump to v0.37.8a0 test-version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ada21a99a..5bd06bdb6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "0.37.7" +version = "0.37.8.a0" license = {file = "LICENSE"} description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md" From 953b77f6c0b3d0cf0cd440b0ce632e9a0580f838 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 20 May 2024 19:47:35 +0200 Subject: [PATCH 11/14] Add explaining comments --- plugwise/legacy/smile.py | 2 ++ plugwise/smile.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/plugwise/legacy/smile.py b/plugwise/legacy/smile.py index 64b5f6831..bc20c2e2c 100644 --- a/plugwise/legacy/smile.py +++ b/plugwise/legacy/smile.py @@ -184,6 +184,8 @@ async def set_regulation_mode(self, mode: str) -> None: async def set_select(self, key: str, loc_id: str, option: str, name: str | None) -> None: """Set the thermostat schedule option.""" + # schedule-state = select-option + # schedule-name = select-name await self.set_schedule_state("dummy", option, name) async def set_schedule_state(self, _: str, state: str, name: str | None) -> None: diff --git a/plugwise/smile.py b/plugwise/smile.py index 607da9467..aaddf9e56 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -218,6 +218,8 @@ async def set_select(self, key: str, loc_id: str, option: str, name: str | None) case "select_regulation_mode": await self.set_regulation_mode(option) case "select_schedule": + # schedule-state = select-option + # schedule-name = select-name await self.set_schedule_state(loc_id, option, name) async def set_dhw_mode(self, mode: str) -> None: From 0925acdb5717f7f60c9569496c5d9e4ec9619035 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 20 May 2024 19:55:24 +0200 Subject: [PATCH 12/14] Update CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9bd6c50a..a3cbe5d53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Ongoing +## v0.37.8 - Create a set_select() function, combining the set_dhw_mode(), set_gateway_mode(), set_regulation_mode() and set_schedule_state() functions. From 081e2dd36d8b9ba7520a41c0f1b1f47c57adf43b Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 20 May 2024 19:58:04 +0200 Subject: [PATCH 13/14] Fix up comments --- plugwise/legacy/smile.py | 4 ++-- plugwise/smile.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugwise/legacy/smile.py b/plugwise/legacy/smile.py index bc20c2e2c..6bb8f6854 100644 --- a/plugwise/legacy/smile.py +++ b/plugwise/legacy/smile.py @@ -184,8 +184,8 @@ async def set_regulation_mode(self, mode: str) -> None: async def set_select(self, key: str, loc_id: str, option: str, name: str | None) -> None: """Set the thermostat schedule option.""" - # schedule-state = select-option - # schedule-name = select-name + # schedule state corresponds to select option + # schedule name corresponds to select name await self.set_schedule_state("dummy", option, name) async def set_schedule_state(self, _: str, state: str, name: str | None) -> None: diff --git a/plugwise/smile.py b/plugwise/smile.py index aaddf9e56..e26d90ab7 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -218,8 +218,8 @@ async def set_select(self, key: str, loc_id: str, option: str, name: str | None) case "select_regulation_mode": await self.set_regulation_mode(option) case "select_schedule": - # schedule-state = select-option - # schedule-name = select-name + # schedule state corresponds to select option + # schedule name corresponds to select name await self.set_schedule_state(loc_id, option, name) async def set_dhw_mode(self, mode: str) -> None: From e1dcc50760154ef47e8deb7b0ea3d255a72a1390 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 20 May 2024 20:09:10 +0200 Subject: [PATCH 14/14] Bump to v0.37.8 release-version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 5bd06bdb6..295d235b9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "0.37.8.a0" +version = "0.37.8" license = {file = "LICENSE"} description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md"