Skip to content

Commit 75343fd

Browse files
committed
Simplify schedule caching to a single staleness check
The per-control-system timestamp dict was more bookkeeping than the job needs: the app handles one location and fetches all its schedules together. Track a single fetched-at timestamp instead, set only after every system fetched successfully. https://claude.ai/code/session_01RcVkTvidSn9HgsFazrfdZW
1 parent f175925 commit 75343fd

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-
_schedule_refresh_times: dict[str, datetime] = {}
36+
_schedules_fetched_at: datetime | None = None
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
78+
global _evohome_client, _websession, _schedules_fetched_at
7979

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

8383
if _websession is not None:
@@ -134,12 +134,18 @@ 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()
138137

139138

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
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()
143149

144150

145151
async def get_location(location_name: str | None = None) -> Location:
@@ -150,13 +156,7 @@ async def get_location(location_name: str | None = None) -> Location:
150156
for location in client.locations:
151157
if location.name == location_name:
152158
await _update_location(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-
)
159+
await _fetch_schedules_if_stale(location)
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._schedule_refresh_times.clear()
171+
evohome._schedules_fetched_at = None
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._schedule_refresh_times[state.control_system.id] -= evohome._SCHEDULE_REFRESH_INTERVAL
394+
evohome._schedules_fetched_at -= 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-
state = evohome_client()
401+
evohome_client()
402402
await evohome.get_location()
403403

404404
await evohome.close()
405405

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

0 commit comments

Comments
 (0)