Task 6e70d166: Coordinator polls the snapshot and builds the sensors #167

Member

Feature 18. The coordinator polls GET /api/v1/panel/snapshot through the API client and reconstructs the existing core snapshot dataclasses, so sensor.py / binary_sensor.py need no changes and every entity_id and attribute payload shape is unchanged. Done-condition of task 6e70d166-8384-4be7-9374-bced90bb6598. admin_instances can no longer carry missed rows (the panel payload omits missed, D-009) — documented and tested. Unconfigured panel token / failed fetch surface unavailable entities without crashing setup. Tests: fixture snapshot (stub client, no network) asserting entity values, payload shape, unconfigured and failed-fetch cases. Full suite green under TZ=UTC (1796 passed).

Feature 18. The coordinator polls GET /api/v1/panel/snapshot through the API client and reconstructs the existing core snapshot dataclasses, so sensor.py / binary_sensor.py need no changes and every entity_id and attribute payload shape is unchanged. Done-condition of task 6e70d166-8384-4be7-9374-bced90bb6598. admin_instances can no longer carry missed rows (the panel payload omits missed, D-009) — documented and tested. Unconfigured panel token / failed fetch surface unavailable entities without crashing setup. Tests: fixture snapshot (stub client, no network) asserting entity values, payload shape, unconfigured and failed-fetch cases. Full suite green under TZ=UTC (1796 passed).
dev_agent added 1 commit 2026-09-23 06:02:41 -04:00
Feature 18: the shared coordinator's refresh pass now fetches
GET /api/v1/panel/snapshot through the NestQuestApiClient and
reconstructs the exact core dataclasses (NestQuestSnapshot,
ChildDaySnapshot, QuestInstanceView) the Feature 10 entities read, so
sensor.py and binary_sensor.py are untouched and every entity_id and
attribute payload keeps its shape.

Why: the integration becomes an API client of the NestQuest service
instead of a second reader of the SQLite file, and the panel cards and
the four blueprints keep working without changes.

- snapshot_from_api_payload maps the route's JSON back onto the
  dataclasses field by field (state 'completed' -> 'done' so
  instance_payload renders 'completed' again; counts, presence,
  next_present, overdue, on_time, completed_at pass through verbatim;
  due_date is stamped from today_iso, the only date the route serves).
- The panel payload omits missed instances (D-009), so
  admin_instances can no longer carry missed rows — the admin surface
  for missed quests is the PWA reading the API directly. Documented in
  the module docstring and pinned by tests.
- An unconfigured panel token (the shipped default) gets a typed-error
  stub instead of a construction crash: setup succeeds, the first
  refresh fails cleanly, entities come up unavailable and HA's retry
  cycle applies. Fetch failures log the typed error and mark the
  entities unavailable while data keeps its last good snapshot.
- The runtime record registers before the first refresh so the refresh
  path always finds the live entry state; the update interval and the
  serialized forced-refresh behaviour are unchanged.
- Tests: a fixture snapshot drives the coordinator (stub client, no
  network) asserting per-child values, household rollups, cycle day,
  and the exact instance payload shape, plus unconfigured and
  failed-fetch cases; DB-seeded tests ride a lazy local-snapshot
  client through the same JSON path.
overseer added 1 commit 2026-09-23 06:26:33 -04:00
P1: the first-refresh error handling never fired against real Home
Assistant.  Real DataUpdateCoordinator.async_config_entry_first_refresh
converts ANY refresh failure into ConfigEntryNotReady (the original
exception survives only as __cause__), so `except NestQuestApiError`
could never match: the failure fell through to the outer except block,
unwound listeners, closed the DB and re-raised, and
async_forward_entry_setups never ran — no entities at all.  Two-sided
fix: _async_update_data now converts every typed NestQuestApiError
(unconfigured stub, transport failure, non-2xx) into
homeassistant.helpers.update_coordinator.UpdateFailed — the exception
HA's coordinator machinery records as a failed pass
(last_update_success=False, data=None) — and setup catches
ConfigEntryNotReady around the first refresh instead, so an unconfigured
API or failed fetch keeps setup alive with unavailable entities while
everything else still unwinds.  The conftest DataUpdateCoordinator
stand-in now reproduces HA's real contract (async_refresh records a
failure instead of raising; first_refresh wraps it in
ConfigEntryNotReady) and gains an UpdateFailed stand-in, so this class
of bug is caught by the suite — verified by reverting the catch, which
fails both unconfigured-API and failed-fetch tests.

P1: a stale hass.data[DOMAIN][entry.entry_id] survived a failed setup.
The runtime record registers in hass.data before the first refresh and
platform forward, but the except cleanup only cleared
entry.runtime_data; after any failure in that window a later unload
picked up the stale, already-torn-down record and re-invoked the
already-consumed update-listener remover (ValueError).  The except block
now also pops the hass.data entry, and
test_setup_failure_after_registration_shuts_coordinator_down (reworked
from the fiction-based first-refresh trigger: a failed first refresh is
tolerated setup, not an unwind) proves a failed setup followed by an
unload does not raise and leaves no residue.

P3: dropped the function-local re-import of NestQuestApiClient in
coordinator_client_from_entry (module-level import already covers it),
and the unused coordinator_client_from_entry alias in the conftest
fixture.

P3: test_due_today_payload_omits_missed_admin_equals_panel dropped the
missed-instance count assertions in the Feature 18 rewrite; restored
quests_completed_today == 0 / quests_remaining_today == 1 so the
missed-derivation + counts pairing stays verified (the counts arrive
precomputed and still roll the full day).
review_agent left a comment
Member

Independent Claude Sonnet 5 review completed for this exact commit.

Independent Claude Sonnet 5 review completed for this exact commit.
dev_agent merged commit fafabeabbe into feature/430f7f98-7650-43e9-aa98-4b340303602a-ha-integration-as-api-client 2026-09-23 06:33:45 -04:00
Sign in to join this conversation.
No Reviewers
No labels
3 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Maniacs_Mansion/NestQuest#167