Skip to content

Commit 712dea7

Browse files
authored
Merge pull request #431 from plugwise/impr_set_schedule
Improve set_schedule_state()
2 parents ba51e2b + 4a28b46 commit 712dea7

File tree

4 files changed

+37
-22
lines changed

4 files changed

+37
-22
lines changed

.github/workflows/verify.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
name: Latest commit
55

66
env:
7-
CACHE_VERSION: 2
7+
CACHE_VERSION: 3
88
DEFAULT_PYTHON: "3.11"
99
PRE_COMMIT_HOME: ~/.cache/pre-commit
1010

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Ongoing
44

5+
- Bugfix for [Core Issue #102204](https://github.com/home-assistant/core/issues/102204)
56
- Add item-count to output
67
- Support python 3.12
78

plugwise/__init__.py

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -602,22 +602,47 @@ async def _set_schedule_state_legacy(
602602
await self._request(uri, method="put", data=data)
603603
self._schedule_old_states[loc_id][name] = new_state
604604

605+
def determine_contexts(
606+
self, loc_id: str, name: str, state: str, sched_id: str
607+
) -> etree:
608+
"""Helper-function for set_schedule_state()."""
609+
locator = f'.//*[@id="{sched_id}"]/contexts'
610+
contexts = self._domain_objects.find(locator)
611+
locator = f'.//*[@id="{loc_id}"].../...'
612+
if (subject := contexts.find(locator)) is None:
613+
subject = f'<context><zone><location id="{loc_id}" /></zone></context>'
614+
subject = etree.fromstring(subject)
615+
616+
if state == "off":
617+
self._last_active[loc_id] = name
618+
contexts.remove(subject)
619+
if state == "on":
620+
contexts.append(subject)
621+
622+
return etree.tostring(contexts, encoding="unicode").rstrip()
623+
605624
async def set_schedule_state(
606-
self, loc_id: str, name: str | None, new_state: str
625+
self,
626+
loc_id: str,
627+
new_state: str,
628+
name: str | None = None,
607629
) -> None:
608630
"""Activate/deactivate the Schedule, with the given name, on the relevant Thermostat.
609631
610632
Determined from - DOMAIN_OBJECTS.
611-
In HA Core used to set the hvac_mode: in practice switch between schedule on - off.
633+
Used in HA Core to set the hvac_mode: in practice switch between schedule on - off.
612634
"""
613635
# Input checking
614636
if new_state not in ["on", "off"]:
615637
raise PlugwiseError("Plugwise: invalid schedule state.")
616638
if name is None:
617-
raise PlugwiseError(
618-
"Plugwise: cannot change schedule-state: no schedule name provided"
619-
)
639+
for device in self.gw_devices.values():
640+
if device["location"] == loc_id and device["last_used"]:
641+
name = device["last_used"]
642+
else:
643+
return
620644

645+
assert isinstance(name, str)
621646
if self._smile_legacy:
622647
await self._set_schedule_state_legacy(loc_id, name, new_state)
623648
return
@@ -641,21 +666,7 @@ async def set_schedule_state(
641666
template_id = self._domain_objects.find(locator).attrib["id"]
642667
template = f'<template id="{template_id}" />'
643668

644-
locator = f'.//*[@id="{schedule_rule_id}"]/contexts'
645-
contexts = self._domain_objects.find(locator)
646-
locator = f'.//*[@id="{loc_id}"].../...'
647-
if (subject := contexts.find(locator)) is None:
648-
subject = f'<context><zone><location id="{loc_id}" /></zone></context>'
649-
subject = etree.fromstring(subject)
650-
651-
if new_state == "off":
652-
self._last_active[loc_id] = name
653-
contexts.remove(subject)
654-
if new_state == "on":
655-
contexts.append(subject)
656-
657-
contexts = etree.tostring(contexts, encoding="unicode").rstrip()
658-
669+
contexts = self.determine_contexts(loc_id, name, new_state, schedule_rule_id)
659670
uri = f"{RULES};id={schedule_rule_id}"
660671
data = (
661672
f'<rules><rule id="{schedule_rule_id}"><name><![CDATA[{name}]]></name>'

tests/test_smile.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ async def tinker_thermostat_schedule(
553553
new_schedule = new_schedule[1:]
554554
_LOGGER.info("- Adjusting schedule to %s", f"{new_schedule}{warning}")
555555
try:
556-
await smile.set_schedule_state(loc_id, new_schedule, state)
556+
await smile.set_schedule_state(loc_id, state, new_schedule)
557557
tinker_schedule_passed = True
558558
_LOGGER.info(" + working as intended")
559559
except pw_exceptions.PlugwiseError:
@@ -1953,6 +1953,9 @@ async def test_connect_adam_plus_anna_new(self):
19531953
)
19541954
assert result
19551955

1956+
# special test-case for turning a schedule back on based on the last_used schedule
1957+
await smile.set_schedule_state("f2bf9048bef64cc5b6d5110154e33c81", "off")
1958+
19561959
# bad schedule-state test
19571960
result = await self.tinker_thermostat_schedule(
19581961
smile,

0 commit comments

Comments
 (0)