Skip to content

Commit 774426e

Browse files
committed
Track schedule freshness per control system again
Revert the single-timestamp simplification: with one shared timestamp, one system's successful fetch could mask another's failed one for the whole refresh interval. Keying the fetch times by system id keeps each control system's schedules independently fresh. https://claude.ai/code/session_01RcVkTvidSn9HgsFazrfdZW
1 parent 75343fd commit 774426e

3 files changed

Lines changed: 18 additions & 18 deletions

File tree

src/evohome_helper/evohome.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333

3434
# schedules rarely change; refetching them every cycle wastes the vendor's tight API rate limit
3535
_SCHEDULE_REFRESH_INTERVAL = timedelta(hours=1)
36-
_schedules_fetched_at: datetime | None = None
36+
_schedule_refresh_times: dict[str, datetime] = {}
3737

3838
_AWAY_MODE_MAP = {
3939
"auto": SystemMode.AUTO,
@@ -75,9 +75,9 @@ async def save_access_token(self) -> None:
7575

7676

7777
async def close() -> None:
78-
global _evohome_client, _websession, _schedules_fetched_at
78+
global _evohome_client, _websession
7979

80-
_schedules_fetched_at = None
80+
_schedule_refresh_times.clear()
8181
_evohome_client = None
8282

8383
if _websession is not None:
@@ -134,18 +134,12 @@ async def _update_location(location: Location) -> None:
134134
@_retry
135135
async def _fetch_schedules(system: ControlSystem) -> None:
136136
await system.get_schedules()
137+
_schedule_refresh_times[system.id] = datetime.now()
137138

138139

139-
async def _fetch_schedules_if_stale(location: Location) -> None:
140-
global _schedules_fetched_at
141-
142-
if _schedules_fetched_at is not None and datetime.now() - _schedules_fetched_at < _SCHEDULE_REFRESH_INTERVAL:
143-
return
144-
145-
await asyncio.gather(
146-
*[_fetch_schedules(system) for system in get_control_systems(location)],
147-
)
148-
_schedules_fetched_at = datetime.now()
140+
def _schedules_need_refresh(system: ControlSystem) -> bool:
141+
last_refresh = _schedule_refresh_times.get(system.id)
142+
return last_refresh is None or datetime.now() - last_refresh >= _SCHEDULE_REFRESH_INTERVAL
149143

150144

151145
async def get_location(location_name: str | None = None) -> Location:
@@ -156,7 +150,13 @@ async def get_location(location_name: str | None = None) -> Location:
156150
for location in client.locations:
157151
if location.name == location_name:
158152
await _update_location(location)
159-
await _fetch_schedules_if_stale(location)
153+
await asyncio.gather(
154+
*[
155+
_fetch_schedules(system)
156+
for system in get_control_systems(location)
157+
if _schedules_need_refresh(system)
158+
],
159+
)
160160
return location
161161

162162
raise LocationNotFound(location_name)

tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ async def reset_state():
168168

169169
presence.last_known_presence_state.clear()
170170
evohome._evohome_client = None
171-
evohome._schedules_fetched_at = None
171+
evohome._schedule_refresh_times.clear()
172172

173173
yield
174174

tests/test_evohome.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -391,16 +391,16 @@ async def test_get_location_refetches_schedules_after_refresh_interval(evohome_c
391391
state = evohome_client()
392392

393393
await evohome.get_location()
394-
evohome._schedules_fetched_at -= evohome._SCHEDULE_REFRESH_INTERVAL
394+
evohome._schedule_refresh_times[state.control_system.id] -= evohome._SCHEDULE_REFRESH_INTERVAL
395395
await evohome.get_location()
396396

397397
assert state.control_system.get_schedules.await_count == 2
398398

399399

400400
async def test_close_invalidates_schedule_cache(evohome_client):
401-
evohome_client()
401+
state = evohome_client()
402402
await evohome.get_location()
403403

404404
await evohome.close()
405405

406-
assert evohome._schedules_fetched_at is None
406+
assert evohome._schedule_refresh_times == {}

0 commit comments

Comments
 (0)