diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6f0f82f3e..d2e640ddc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog
+## v1.8.3
+
+- Remove storing the last active schedule(s) via PR [#806](https://github.com/plugwise/python-plugwise/pull/806), to be handled by the HA Integration
+
## v1.8.2
- Add support for Emma Pro wired, rename wireless Emma to Emma Pro via PR [#804](https://github.com/plugwise/python-plugwise/pull/804)
diff --git a/plugwise/__init__.py b/plugwise/__init__.py
index 47abbd837..2b89b065f 100644
--- a/plugwise/__init__.py
+++ b/plugwise/__init__.py
@@ -67,7 +67,6 @@ def __init__(
self._cooling_present = False
self._elga = False
self._is_thermostat = False
- self._last_active: dict[str, str | None] = {}
self._loc_data: dict[str, ThermoLoc] = {}
self._on_off_device = False
self._opentherm_device = False
@@ -156,7 +155,6 @@ async def connect(self) -> Version:
self._cooling_present,
self._elga,
self._is_thermostat,
- self._last_active,
self._loc_data,
self._on_off_device,
self._opentherm_device,
diff --git a/plugwise/helper.py b/plugwise/helper.py
index 4ed5347d6..0d7355ee0 100644
--- a/plugwise/helper.py
+++ b/plugwise/helper.py
@@ -5,7 +5,6 @@
from __future__ import annotations
-import datetime as dt
from typing import cast
from plugwise.common import SmileCommon
@@ -50,9 +49,6 @@
skip_obsolete_measurements,
)
-# Time related
-from dateutil import tz
-from dateutil.parser import parse
from defusedxml import ElementTree as etree
from munch import Munch
from packaging import version
@@ -78,7 +74,6 @@ def __init__(self) -> None:
self._endpoint: str
self._elga: bool
self._is_thermostat: bool
- self._last_active: dict[str, str | None]
self._loc_data: dict[str, ThermoLoc]
self._schedule_old_states: dict[str, dict[str, str]]
self._gateway_id: str = NONE
@@ -871,7 +866,7 @@ def _rule_ids_by_name(self, name: str, loc_id: str) -> dict[str, dict[str, str]]
return schedule_ids
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().
+ """Helper-function for _presets() and _schedules().
Obtain the rule_id from the given template_tag and provide the location_id, when present.
"""
@@ -906,11 +901,6 @@ def _schedules(self, location: str) -> tuple[list[str], str]:
available: list[str] = [NONE]
rule_ids: dict[str, dict[str, str]] = {}
selected = NONE
- # Adam schedules, one schedule can be linked to various locations
- # self._last_active contains the locations and the active schedule name per location, or None
- if location not in self._last_active:
- self._last_active[location] = None
-
tag = "zone_preset_based_on_time_and_presence_with_override"
if not (rule_ids := self._rule_ids_by_tag(tag, location)):
return available, selected
@@ -927,7 +917,6 @@ def _schedules(self, location: str) -> tuple[list[str], str]:
available.append(name)
if location == data["location"] and active:
selected = name
- self._last_active[location] = selected
schedules.append(name)
if schedules:
@@ -935,26 +924,9 @@ def _schedules(self, location: str) -> tuple[list[str], str]:
available.append(OFF)
if selected == NONE:
selected = OFF
- if self._last_active.get(location) is None:
- self._last_active[location] = self._last_used_schedule(schedules)
-
- return available, selected
- def _last_used_schedule(self, schedules: list[str]) -> str:
- """Helper-function for _schedules().
- Determine the last-used schedule based on the modified date.
- """
- epoch = dt.datetime(1970, 1, 1, tzinfo=tz.tzutc())
- schedules_dates: dict[str, float] = {}
-
- for name in schedules:
- result = self._domain_objects.find(f'./rule[name="{name}"]')
- schedule_date = result.find("modified_date").text
- schedule_time = parse(schedule_date)
- schedules_dates[name] = (schedule_time - epoch).total_seconds()
-
- return sorted(schedules_dates.items(), key=lambda kv: kv[1])[-1][0]
+ return available, selected
def _thermostat_uri(self, loc_id: str) -> str:
"""Helper-function for smile.py: set_temperature().
diff --git a/plugwise/smile.py b/plugwise/smile.py
index 970181ca1..bfeb61817 100644
--- a/plugwise/smile.py
+++ b/plugwise/smile.py
@@ -68,7 +68,6 @@ def __init__(
_cooling_present: bool,
_elga: bool,
_is_thermostat: bool,
- _last_active: dict[str, str | None],
_loc_data: dict[str, ThermoLoc],
_on_off_device: bool,
_opentherm_device: bool,
@@ -81,7 +80,6 @@ def __init__(
self._cooling_present = _cooling_present
self._elga = _elga
self._is_thermostat = _is_thermostat
- self._last_active = _last_active
self._loc_data = _loc_data
self._on_off_device = _on_off_device
self._opentherm_device = _opentherm_device
@@ -325,14 +323,12 @@ async def set_schedule_state(
if name == OFF:
new_state = STATE_OFF
- # Handle no schedule-name / Off-schedule provided
+ # Handle no schedule-name / schedule-off requested: find the active schedule
if name is None or name == OFF:
- if schedule_name := self._last_active[loc_id]:
- name = schedule_name
- else:
+ _, name = self._schedules(loc_id)
+ if name == OFF: # no active schedule found, nothing to do
return
- assert isinstance(name, str)
schedule_rule = self._rule_ids_by_name(name, loc_id)
# Raise an error when the schedule name does not exist
if not schedule_rule or schedule_rule is None:
@@ -351,7 +347,7 @@ async def set_schedule_state(
template_id = self._domain_objects.find(locator).attrib["id"]
template = f''
- contexts = self.determine_contexts(loc_id, name, new_state, schedule_rule_id)
+ contexts = self.determine_contexts(loc_id, new_state, schedule_rule_id)
data = (
""
f""
@@ -366,7 +362,7 @@ async def set_schedule_state(
self._schedule_old_states[loc_id][name] = new_state
def determine_contexts(
- self, loc_id: str, name: str, state: str, sched_id: str
+ self, loc_id: str, state: str, sched_id: str
) -> str:
"""Helper-function for set_schedule_state()."""
locator = f'.//*[@id="{sched_id}"]/contexts'
@@ -377,7 +373,6 @@ def determine_contexts(
subject = etree.fromstring(subject)
if state == STATE_OFF:
- self._last_active[loc_id] = name
contexts.remove(subject)
if state == STATE_ON:
contexts.append(subject)
diff --git a/pyproject.toml b/pyproject.toml
index 34bb89e09..c1268f779 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "plugwise"
-version = "1.8.2"
+version = "1.8.3"
license = "MIT"
description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3."
readme = "README.md"
diff --git a/tests/test_adam.py b/tests/test_adam.py
index dac24e17f..df99647e4 100644
--- a/tests/test_adam.py
+++ b/tests/test_adam.py
@@ -34,10 +34,6 @@ async def test_connect_adam_plus_anna_new(self):
await self.device_test(api, "2025-10-12 00:00:01", testdata)
assert api.gateway_id == "da224107914542988a88561b4452b0f6"
- assert api._last_active["f2bf9048bef64cc5b6d5110154e33c81"] == "Weekschema"
- assert (
- api._last_active["f871b8c4d63549319221e294e4f88074"] == "Weekschema"
- ) # Badkamer
assert self.entity_items == 216
assert self.entity_list == [
"da224107914542988a88561b4452b0f6",
@@ -216,11 +212,6 @@ async def test_connect_adam_zone_per_device(self):
await self.device_test(api, "2022-05-16 00:00:01", testdata)
assert api.gateway_id == "fe799307f1624099878210aa0b9f1475"
- assert api._last_active["12493538af164a409c6a1c79e38afe1c"] == BADKAMER_SCHEMA
- assert api._last_active["c50f167537524366a5af7aa3942feb1e"] == GF7_WOONKAMER
- assert api._last_active["82fa13f017d240daa0d0ea1775420f24"] == CV_JESSIE
- assert api._last_active["08963fec7c53423ca5680aa4cb502c63"] == BADKAMER_SCHEMA
- assert api._last_active["446ac08dd04d4eff8ac57489757b7314"] == BADKAMER_SCHEMA
assert self.entity_items == 379
assert "af82e4ccf9c548528166d38e560662a4" in self.notifications
@@ -294,11 +285,6 @@ async def test_connect_adam_multiple_devices_per_zone(self):
)
await self.device_test(api, "2022-05-16 00:00:01", testdata)
- assert api._last_active["12493538af164a409c6a1c79e38afe1c"] == BADKAMER_SCHEMA
- assert api._last_active["c50f167537524366a5af7aa3942feb1e"] == GF7_WOONKAMER
- assert api._last_active["82fa13f017d240daa0d0ea1775420f24"] == CV_JESSIE
- assert api._last_active["08963fec7c53423ca5680aa4cb502c63"] == BADKAMER_SCHEMA
- assert api._last_active["446ac08dd04d4eff8ac57489757b7314"] == BADKAMER_SCHEMA
assert self.entity_items == 385
assert "af82e4ccf9c548528166d38e560662a4" in self.notifications
@@ -335,16 +321,6 @@ async def test_adam_heatpump_cooling(self):
server, api, client = await self.connect_wrapper()
await self.device_test(api, "2022-01-02 00:00:01", testdata)
- assert api._last_active["b52908550469425b812c87f766fe5303"] == WERKDAG_SCHEMA
- assert api._last_active["20e735858f8146cead98b873177a4f99"] == WERKDAG_SCHEMA
- assert api._last_active["e39529c79ab54fda9bed26cfc0447546"] == WERKDAG_SCHEMA
- assert api._last_active["9a27714b970547ee9a6bdadc2b815ad5"] == WERKDAG_SCHEMA
- assert api._last_active["93ac3f7bf25342f58cbb77c4a99ac0b3"] == WERKDAG_SCHEMA
- assert api._last_active["fa5fa6b34f6b40a0972988b20e888ed4"] == WERKDAG_SCHEMA
- assert api._last_active["04b15f6e884448288f811d29fb7b1b30"] == WERKDAG_SCHEMA
- assert api._last_active["a562019b0b1f47a4bde8ebe3dbe3e8a9"] == WERKDAG_SCHEMA
- assert api._last_active["8cf650a4c10c44819e426bed406aec34"] == WERKDAG_SCHEMA
- assert api._last_active["5cc21042f87f4b4c94ccb5537c47a53f"] == WERKDAG_SCHEMA
assert self.entity_items == 518
assert self.cooling_present
assert self._cooling_enabled
@@ -392,7 +368,6 @@ async def test_connect_adam_plus_anna(self):
await self.device_test(api, "2020-03-22 00:00:01", testdata)
assert api.gateway_id == "b128b4bbbd1f47e9bf4d756e8fb5ee94"
- assert api._last_active["009490cc2f674ce6b576863fbb64f867"] == "Weekschema"
assert self.entity_items == 82
assert "6fb89e35caeb4b1cb275184895202d84" in self.notifications
@@ -433,10 +408,6 @@ async def test_adam_plus_jip(self):
await self.device_test(api, "2021-06-20 00:00:01", testdata)
assert api.gateway_id == "b5c2386c6f6342669e50fe49dd05b188"
- assert api._last_active["d58fec52899f4f1c92e4f8fad6d8c48c"] is None
- assert api._last_active["06aecb3d00354375924f50c47af36bd2"] is None
- assert api._last_active["d27aede973b54be484f6842d1b2802ad"] is None
- assert api._last_active["13228dab8ce04617af318a2888b3c548"] is None
assert self.entity_items == 261
# Negative test
diff --git a/tests/test_anna.py b/tests/test_anna.py
index f577a0bc0..6b5c65729 100644
--- a/tests/test_anna.py
+++ b/tests/test_anna.py
@@ -29,7 +29,6 @@ async def test_connect_anna_v4(self):
await self.device_test(api, "2020-04-05 00:00:01", testdata)
assert api.gateway_id == "0466eae8520144c78afb29628384edeb"
- assert api._last_active["eb5309212bf5407bb143e5bfa3b18aee"] == "Standaard"
assert self.entity_items == 60
assert not self.notifications
@@ -102,7 +101,6 @@ async def test_connect_anna_v4_dhw(self):
)
await self.device_test(api, "2020-04-05 00:00:01", testdata)
- assert api._last_active["eb5309212bf5407bb143e5bfa3b18aee"] == "Standaard"
assert self.entity_items == 60
assert not self.notifications
@@ -160,7 +158,6 @@ async def test_connect_anna_without_boiler_fw441(self):
)
await self.device_test(api, "2022-05-16 00:00:01", testdata)
- assert api._last_active["c34c6864216446528e95d88985e714cc"] == "Normaal"
assert self.entity_items == 41
assert not self.notifications
@@ -189,7 +186,6 @@ async def test_connect_anna_heatpump_heating(self):
await self.device_test(api, "2020-04-12 00:00:01", testdata)
assert api.gateway_id == "015ae9ea3f964e668e490fa39da3870b"
- assert api._last_active["c784ee9fdab44e1395b8dee7d7a497d5"] == "standaard"
assert self.entity_items == 69
assert not self.notifications
assert self.cooling_present
@@ -245,7 +241,6 @@ async def test_connect_anna_heatpump_cooling(self):
)
await self.device_test(api, "2020-04-19 00:00:01", testdata)
- assert api._last_active["c784ee9fdab44e1395b8dee7d7a497d5"] == "standaard"
assert self.entity_items == 66
assert self.cooling_present
assert not self.notifications
@@ -318,7 +313,6 @@ async def test_connect_anna_elga_no_cooling(self):
await self.device_test(api, "2020-04-12 00:00:01", testdata)
assert api.gateway_id == "015ae9ea3f964e668e490fa39da3870b"
- assert api._last_active["c784ee9fdab44e1395b8dee7d7a497d5"] == "standaard"
assert self.entity_items == 65
assert not self.notifications
assert not self.cooling_present
@@ -342,9 +336,6 @@ async def test_connect_anna_elga_2(self):
)
await self.device_test(api, "2022-03-13 00:00:01", testdata)
- assert (
- api._last_active["d3ce834534114348be628b61b26d9220"] == THERMOSTAT_SCHEDULE
- )
assert self.entity_items == 61
assert api.gateway_id == "fb49af122f6e4b0f91267e1cf7666d6f"
assert self.cooling_present
@@ -364,13 +355,13 @@ async def test_connect_anna_elga_2_schedule_off(self):
assert api.smile.hostname == "smile000000"
await self.device_test(api, "2022-03-13 00:00:01", testdata)
- assert (
- api._last_active["d3ce834534114348be628b61b26d9220"] == THERMOSTAT_SCHEDULE
- )
- assert self.cooling_present
assert not self._cooling_enabled
assert self.entity_items == 65
+ result = await self.tinker_thermostat(
+ api, "d3ce834534114348be628b61b26d9220", good_schedules=["Thermostat schedule", "off"]
+ )
+ assert result
await api.close_connection()
await self.disconnect(server, client)
@@ -394,9 +385,6 @@ async def test_connect_anna_elga_2_cooling(self):
)
await self.device_test(api, "2022-03-10 00:00:01", testdata)
- assert (
- api._last_active["d3ce834534114348be628b61b26d9220"] == THERMOSTAT_SCHEDULE
- )
assert self.entity_items == 65
assert not self.notifications
@@ -450,7 +438,6 @@ async def test_connect_anna_loria_heating_idle(self):
)
await self.device_test(api, "2022-05-16 00:00:01", testdata)
- assert api._last_active["15da035090b847e7a21f93e08c015ebc"] == "Winter"
assert self.entity_items == 68
assert self.cooling_present
assert not self._cooling_enabled
@@ -516,7 +503,6 @@ async def test_connect_anna_loria_cooling_active(self):
)
await self.device_test(api, "2022-05-16 00:00:01", testdata)
- assert api._last_active["15da035090b847e7a21f93e08c015ebc"] == "Winter"
assert self.entity_items == 68
assert self.cooling_present
assert self._cooling_enabled