From d8c46766dd1aa6b30b393aec3eb5b77e2fcf8e54 Mon Sep 17 00:00:00 2001 From: Bouwe Date: Tue, 16 Jan 2024 20:28:06 +0100 Subject: [PATCH 01/21] Fix set_gateway_mode away timestamp --- plugwise/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugwise/__init__.py b/plugwise/__init__.py index 2b292fb30..b7000829c 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -871,7 +871,7 @@ async def set_gateway_mode(self, mode: str) -> None: if mode not in self._gw_allowed_modes: raise PlugwiseError("Plugwise: invalid gateway mode.") - time_1 = dt.datetime.now(dt.UTC) + time_1 = dt.datetime.now() away_time = time_1.isoformat(timespec="milliseconds") + "Z" time_2 = str(dt.date.today() - dt.timedelta(1)) vacation_time = time_2 + "T23:00:00.000Z" From f2184f26cd374f92eb553c2e71a707c38d6ae995 Mon Sep 17 00:00:00 2001 From: Bouwe Date: Tue, 16 Jan 2024 20:29:26 +0100 Subject: [PATCH 02/21] Bump to v0.36.3a0 test-version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 483206e0e..a3a156be4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "0.36.2" +version = "0.36.3a0" license = {file = "LICENSE"} description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md" From 2fbe89a5bd6b00fa9e5129fe3e68f0c4afe87273 Mon Sep 17 00:00:00 2001 From: Bouwe Date: Wed, 17 Jan 2024 19:13:54 +0100 Subject: [PATCH 03/21] Correct set_gateway_mode() URI --- plugwise/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugwise/__init__.py b/plugwise/__init__.py index b7000829c..ba28e023c 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -884,7 +884,7 @@ async def set_gateway_mode(self, mode: str) -> None: if mode == "vacation": valid = f"{vacation_time}{end_time}" - uri = f"{APPLIANCES};type=gateway/gateway_mode_control" + uri = f"{APPLIANCES};id={self.gateway_id}/gateway_mode_control" data = f"{mode}{valid}" await self._request(uri, method="put", data=data) From b429751d83dd577a55916144299f50ec30d3e5ae Mon Sep 17 00:00:00 2001 From: Bouwe Date: Wed, 17 Jan 2024 19:16:49 +0100 Subject: [PATCH 04/21] Bump to a1 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a3a156be4..b97ca5781 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "0.36.3a0" +version = "0.36.3a1" license = {file = "LICENSE"} description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md" From 62cc40b111845bd8e97f59e52ed5dd486e41d16e Mon Sep 17 00:00:00 2001 From: Bouwe Date: Wed, 17 Jan 2024 19:45:47 +0100 Subject: [PATCH 05/21] In gateway_mode = vacation the schedule is turned off via the active-key --- plugwise/helper.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index 0f773bf2b..1651d6f84 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -1496,14 +1496,21 @@ def _schedules(self, location: str) -> tuple[list[str], str]: schedules: list[str] = [] for rule_id, loc_id in rule_ids.items(): - name = self._domain_objects.find(f'./rule[@id="{rule_id}"]/name').text + active = False + name = self._domain_objects.find(f'rule[@id="{rule_id}"]/name').text + if ( + self._domain_objects.find(f'rule[@id="{rule_id}"]/active').text + == "true" + ): + active = True + locator = f'./rule[@id="{rule_id}"]/directives' # Show an empty schedule as no schedule found if self._domain_objects.find(locator) is None: continue # pragma: no cover available.append(name) - if location == loc_id: + if location == loc_id and active: selected = name self._last_active[location] = selected schedules.append(name) From 8c25f0729eff993665c6da833b3f7ea39e0a3744 Mon Sep 17 00:00:00 2001 From: Bouwe Date: Wed, 17 Jan 2024 19:46:46 +0100 Subject: [PATCH 06/21] Bump to a2 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b97ca5781..162bda25c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "0.36.3a1" +version = "0.36.3a2" license = {file = "LICENSE"} description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md" From a89265bfdf11b9614557991538a2148f7b6d8774 Mon Sep 17 00:00:00 2001 From: Bouwe Date: Wed, 17 Jan 2024 20:07:16 +0100 Subject: [PATCH 07/21] str() away_time --- plugwise/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugwise/__init__.py b/plugwise/__init__.py index ba28e023c..9b87f23cb 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -872,7 +872,7 @@ async def set_gateway_mode(self, mode: str) -> None: raise PlugwiseError("Plugwise: invalid gateway mode.") time_1 = dt.datetime.now() - away_time = time_1.isoformat(timespec="milliseconds") + "Z" + away_time = str(time_1.isoformat(timespec="milliseconds")) + "Z" time_2 = str(dt.date.today() - dt.timedelta(1)) vacation_time = time_2 + "T23:00:00.000Z" end_time = "2037-04-21T08:00:53.000Z" From 36d1760624c0f05ab3479331de790d0bee09addd Mon Sep 17 00:00:00 2001 From: Bouwe Date: Wed, 17 Jan 2024 20:07:38 +0100 Subject: [PATCH 08/21] Bump to a3 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 162bda25c..c26f4d449 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "0.36.3a2" +version = "0.36.3a3" license = {file = "LICENSE"} description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md" From 7c7895a5f098ba15bab6f7dfbe8699b290d3ce3b Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 18 Jan 2024 12:33:51 +0100 Subject: [PATCH 09/21] Fix away_time representation, improve --- plugwise/__init__.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/plugwise/__init__.py b/plugwise/__init__.py index 9b87f23cb..d4efaff70 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -871,17 +871,20 @@ async def set_gateway_mode(self, mode: str) -> None: if mode not in self._gw_allowed_modes: raise PlugwiseError("Plugwise: invalid gateway mode.") - time_1 = dt.datetime.now() - away_time = str(time_1.isoformat(timespec="milliseconds")) + "Z" - time_2 = str(dt.date.today() - dt.timedelta(1)) - vacation_time = time_2 + "T23:00:00.000Z" end_time = "2037-04-21T08:00:53.000Z" valid = "" if mode == "away": + time_1 = self._domain_objects("./gateway/time").text + away_time = dt.datetime.fromisoformat(time_1) + .astimezone(dt.timezone.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" From 595b543dd20a5fd1224319e407f465d67c3a5208 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 18 Jan 2024 12:37:13 +0100 Subject: [PATCH 10/21] Fix format --- plugwise/__init__.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/plugwise/__init__.py b/plugwise/__init__.py index d4efaff70..fa675d864 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -875,10 +875,7 @@ async def set_gateway_mode(self, mode: str) -> None: valid = "" if mode == "away": time_1 = self._domain_objects("./gateway/time").text - away_time = dt.datetime.fromisoformat(time_1) - .astimezone(dt.timezone.utc) - .isoformat(timespec="milliseconds") - .replace("+00:00", "Z") + away_time = dt.datetime.fromisoformat(time_1).astimezone(dt.timezone.utc).isoformat(timespec="milliseconds").replace("+00:00", "Z") valid = ( f"{away_time}{end_time}" ) From 3f2b5d7e304cde66db23da00aa263eb496819edf Mon Sep 17 00:00:00 2001 From: autoruff Date: Thu, 18 Jan 2024 11:38:36 +0000 Subject: [PATCH 11/21] fixup: gateway_away Python code fixed using ruff --- plugwise/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugwise/__init__.py b/plugwise/__init__.py index fa675d864..1ddbecdba 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -875,7 +875,7 @@ async def set_gateway_mode(self, mode: str) -> None: valid = "" if mode == "away": time_1 = self._domain_objects("./gateway/time").text - away_time = dt.datetime.fromisoformat(time_1).astimezone(dt.timezone.utc).isoformat(timespec="milliseconds").replace("+00:00", "Z") + away_time = dt.datetime.fromisoformat(time_1).astimezone(dt.UTC).isoformat(timespec="milliseconds").replace("+00:00", "Z") valid = ( f"{away_time}{end_time}" ) From 14ec8b4a874c158f1e0893015fbbea5aa5b64fae Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 18 Jan 2024 12:46:23 +0100 Subject: [PATCH 12/21] Add missing .find() --- plugwise/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugwise/__init__.py b/plugwise/__init__.py index 1ddbecdba..e1d96e0de 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -874,7 +874,7 @@ async def set_gateway_mode(self, mode: str) -> None: end_time = "2037-04-21T08:00:53.000Z" valid = "" if mode == "away": - time_1 = self._domain_objects("./gateway/time").text + 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}" From 23f6dd6fcc08762c41c072c786553a5e6cbea639 Mon Sep 17 00:00:00 2001 From: Bouwe Date: Thu, 18 Jan 2024 18:02:44 +0100 Subject: [PATCH 13/21] Bump to a4 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c26f4d449..8dc927cdf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "0.36.3a3" +version = "0.36.3a4" license = {file = "LICENSE"} description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md" From eace9b3cea32fb8b6109d667ea72a28c5cf6e343 Mon Sep 17 00:00:00 2001 From: Bouwe Date: Thu, 18 Jan 2024 19:00:31 +0100 Subject: [PATCH 14/21] Extend output of _rule_ids_by_tag() --- plugwise/helper.py | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index 1651d6f84..2a08d3bf0 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -767,7 +767,7 @@ def _presets(self, loc_id: str) -> dict[str, list[float]]: return presets - def _rule_ids_by_name(self, name: str, loc_id: str) -> dict[str, str]: + def _rule_ids_by_name(self, name: str, loc_id: str) -> dict[str, dict[str, str]]: """Helper-function for _presets(). Obtain the rule_id from the given name and and provide the location_id, when present. @@ -782,20 +782,22 @@ def _rule_ids_by_name(self, name: str, loc_id: str) -> dict[str, str]: return schedule_ids - def _rule_ids_by_tag(self, tag: str, loc_id: str) -> dict[str, str]: + def _rule_ids_by_tag(self, tag: str, loc_id: str) -> dict[str, dict[str, str]]: """Helper-function for _presets(), _schedules() and _last_active_schedule(). Obtain the rule_id from the given template_tag and provide the location_id, when present. """ - schedule_ids: dict[str, str] = {} + schedule_ids: dict[str, dict[str, str]] = {} locator1 = f'./template[@tag="{tag}"]' locator2 = f'./contexts/context/zone/location[@id="{loc_id}"]' for rule in self._domain_objects.findall("./rule"): if rule.find(locator1) is not None: + name = rule.find("name").text + active = rule.find("active").text == "true" if rule.find(locator2) is not None: - schedule_ids[rule.attrib["id"]] = loc_id + schedule_ids[rule.attrib["id"]] = {"location": loc_id, "name": name, "active": active} else: - schedule_ids[rule.attrib["id"]] = NONE + schedule_ids[rule.attrib["id"]] = {"location": NONE, "name": name, "active": active} return schedule_ids @@ -1495,22 +1497,16 @@ def _schedules(self, location: str) -> tuple[list[str], str]: return available, selected schedules: list[str] = [] - for rule_id, loc_id in rule_ids.items(): - active = False - name = self._domain_objects.find(f'rule[@id="{rule_id}"]/name').text - if ( - self._domain_objects.find(f'rule[@id="{rule_id}"]/active').text - == "true" - ): - active = True - + for rule_id, data in rule_ids.items(): + active = data["active"] + name = data["name"] locator = f'./rule[@id="{rule_id}"]/directives' # Show an empty schedule as no schedule found if self._domain_objects.find(locator) is None: continue # pragma: no cover available.append(name) - if location == loc_id and active: + if location == data["location"] and active: selected = name self._last_active[location] = selected schedules.append(name) From 18c6c200d8312dd3d2e2a0c341875f33742ab7ef Mon Sep 17 00:00:00 2001 From: Bouwe Date: Thu, 18 Jan 2024 19:02:16 +0100 Subject: [PATCH 15/21] Fix --- plugwise/helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index 2a08d3bf0..e902eeda4 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -767,7 +767,7 @@ def _presets(self, loc_id: str) -> dict[str, list[float]]: return presets - def _rule_ids_by_name(self, name: str, loc_id: str) -> dict[str, dict[str, str]]: + def _rule_ids_by_name(self, name: str, loc_id: str) -> dict[str, str]: """Helper-function for _presets(). Obtain the rule_id from the given name and and provide the location_id, when present. From e70deda8bd1f3cc3dd1882ea837b08d8fb7dafe3 Mon Sep 17 00:00:00 2001 From: Bouwe Date: Thu, 18 Jan 2024 19:09:55 +0100 Subject: [PATCH 16/21] Also adapt _rule_ids_by_name() to avoid typing issues --- plugwise/helper.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index e902eeda4..3a08989c2 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -751,6 +751,7 @@ def _presets(self, loc_id: str) -> dict[str, list[float]]: return self._presets_legacy() if not (rule_ids := self._rule_ids_by_tag(tag_1, loc_id)): + rule_ids = None if not (rule_ids := self._rule_ids_by_name(tag_2, loc_id)): return presets # pragma: no cover @@ -767,18 +768,19 @@ def _presets(self, loc_id: str) -> dict[str, list[float]]: return presets - def _rule_ids_by_name(self, name: str, loc_id: str) -> dict[str, str]: + def _rule_ids_by_name(self, name: str, loc_id: str) -> dict[str, dict[str, str]]: """Helper-function for _presets(). Obtain the rule_id from the given name and and provide the location_id, when present. """ - schedule_ids: dict[str, str] = {} + schedule_ids: dict[str, dict[str, str]] = {} locator = f'./contexts/context/zone/location[@id="{loc_id}"]' for rule in self._domain_objects.findall(f'./rule[name="{name}"]'): + active = rule.find("active").text if rule.find(locator) is not None: - schedule_ids[rule.attrib["id"]] = loc_id + schedule_ids[rule.attrib["id"]] = {"location": loc_id, "name": name, "active": active} else: - schedule_ids[rule.attrib["id"]] = NONE + schedule_ids[rule.attrib["id"]] = {"location": NONE, "name": name, "active": active} return schedule_ids @@ -793,7 +795,7 @@ def _rule_ids_by_tag(self, tag: str, loc_id: str) -> dict[str, dict[str, str]]: for rule in self._domain_objects.findall("./rule"): if rule.find(locator1) is not None: name = rule.find("name").text - active = rule.find("active").text == "true" + active = rule.find("active").text if rule.find(locator2) is not None: schedule_ids[rule.attrib["id"]] = {"location": loc_id, "name": name, "active": active} else: @@ -1498,7 +1500,7 @@ def _schedules(self, location: str) -> tuple[list[str], str]: schedules: list[str] = [] for rule_id, data in rule_ids.items(): - active = data["active"] + active = data["active"] == "true" name = data["name"] locator = f'./rule[@id="{rule_id}"]/directives' # Show an empty schedule as no schedule found From 272bcc98852ca372cd96397979cf8aa877fc4707 Mon Sep 17 00:00:00 2001 From: Bouwe Date: Thu, 18 Jan 2024 19:12:54 +0100 Subject: [PATCH 17/21] Fix another typing definition --- plugwise/helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index 3a08989c2..6e8a6bf8b 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -1482,7 +1482,7 @@ def _schedules(self, location: str) -> tuple[list[str], str]: NEW: when a location_id is present then the schedule is active. Valid for both Adam and non-legacy Anna. """ available: list[str] = [NONE] - rule_ids: dict[str, str] = {} + rule_ids: dict[str, dict[str, str]] = {} selected = NONE # Legacy Anna schedule, only one schedule allowed From 7df889b438af5e879c8a990bdb0cb37b14e7a09e Mon Sep 17 00:00:00 2001 From: Bouwe Date: Thu, 18 Jan 2024 19:19:10 +0100 Subject: [PATCH 18/21] Bump to a5 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8dc927cdf..0b7845b25 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "0.36.3a4" +version = "0.36.3a5" license = {file = "LICENSE"} description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md" From 718ab99e8a58e7fc42996866f60c26ad5d04494f Mon Sep 17 00:00:00 2001 From: Bouwe Date: Thu, 18 Jan 2024 19:30:29 +0100 Subject: [PATCH 19/21] Update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51ead928c..d48b59969 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## v0.36.3 + +- Bugfixes for [#558](https://github.com/plugwise/plugwise-beta/issues/558) and [#559](https://github.com/plugwise/plugwise-beta/issues/559). + ## v0.36.2 - Improve support for Anna+Elga systems that do not support cooling (fix for [#547](https://github.com/plugwise/plugwise-beta/issues/547)). From 35d2862b615cd4d8c4fd62c0abd9dd23627f2251 Mon Sep 17 00:00:00 2001 From: Bouwe Date: Thu, 18 Jan 2024 19:30:59 +0100 Subject: [PATCH 20/21] V0.36.3 release-version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0b7845b25..e4e245d86 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "0.36.3a5" +version = "0.36.3" license = {file = "LICENSE"} description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md" From ef5500ad436e6fa1ec7045854ac6cedf622509ec Mon Sep 17 00:00:00 2001 From: Bouwe Date: Thu, 18 Jan 2024 19:35:40 +0100 Subject: [PATCH 21/21] Fix CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d48b59969..b582165fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## v0.36.3 -- Bugfixes for [#558](https://github.com/plugwise/plugwise-beta/issues/558) and [#559](https://github.com/plugwise/plugwise-beta/issues/559). +- Bugfixes for [#558](https://github.com/plugwise/plugwise-beta/issues/558) and [#559](https://github.com/plugwise/plugwise-beta/issues/559). ## v0.36.2