4.9 KiB
Screens → HA entities, services and events
Planned surface from CTXD CONTEXT.MD, adjusted for the design decisions in
DESIGN-HANDOFF.md. Names use the quest_* model.
1. Entities the cards read
| Entity | Type | Used by |
|---|---|---|
sensor.nestquest_<child>_quests_due_today |
int | 1a plate progress, 1b counts, 1d stats |
sensor.nestquest_<child>_quests_completed_today |
int | 1a, 1b, 1c, 1d, 1h |
sensor.nestquest_<child>_quests_remaining_today |
int | 1b remaining block, 1d |
sensor.nestquest_<child>_completion_pct_today |
float | progress bars |
sensor.nestquest_<child>_next_quest |
str + attrs | optional panel hint |
binary_sensor.nestquest_<child>_all_done |
bool | 1c trigger, 1d "all done" |
binary_sensor.nestquest_<child>_present_today |
bool | 1a away plate, 1d away row |
sensor.nestquest_household_quests_due_today |
int | 1b party line, 1c party stat |
sensor.nestquest_household_quests_completed_today |
int | same |
sensor.nestquest_cycle_day |
int | 1d sub-line, 1f header |
configured weather.<entity> |
HA core | panel dock |
Per-instance data is too granular for entity state. The cards read the day's instance list from an attribute payload on the per-child sensor (or a websocket command — implementer's call), shaped:
{
"instances": [
{ "id": 4821, "definition_id": 12, "child_id": 3, "title": "Fill bird feeder",
"icon": "bird", "window": "afternoon", "due_time": "17:00",
"state": "open", "overdue": true, "completed_at": null, "on_time": null }
]
}
state ∈ open | completed. Missed instances are omitted from panel payloads
(decision 5) and included in admin payloads.
2. Services the cards call
| Service | Admin only | Called from |
|---|---|---|
nestquest.complete_quest |
no (panel allowed) | 1j confirm |
nestquest.uncomplete_quest |
yes | 1d Undo |
nestquest.create_quest_definition |
yes | 1e New |
nestquest.update_quest_definition |
yes | 1e sheet Save changes |
nestquest.set_quest_definition_active |
yes | 1e row action |
nestquest.set_presence_pattern |
yes | 1f presence card |
nestquest.create_presence_override |
yes | 1i Save override |
nestquest.delete_presence_override |
yes | 1f override row trash-2 |
nestquest.export_history_csv |
yes | 1g CSV |
nestquest.manage_child |
yes | settings |
complete_quest payload from the panel:
service: nestquest.complete_quest
data:
instance_id: 4821
actor: panel # kiosk user context
actor_child_id: 3 # the tapped profile (decision 9)
Every service resolves call.context.user_id against the admin allowlist and fails
closed with no user context (D-003). The panel's kiosk user is never allowlisted, so
uncomplete_quest is unreachable from the wall even though the card never renders the
control.
3. Events the cards listen for
| Event | Effect |
|---|---|
nestquest_quest_completed |
stamp the seal, re-sort the column, refresh counts |
nestquest_quest_uncompleted |
un-seal, restore the card (admin action, panel must reflect it) |
nestquest_quest_missed |
remove the instance from the panel; add a history row |
nestquest_child_day_complete |
show screen 1c |
All four come off the DataUpdateCoordinator; cards should also refresh on
state_changed for their sensors so they recover if an event is dropped.
4. Card configuration
# kids' panel, view 1
type: custom:nestquest-party-board-card
weather_entity: weather.home # optional; dock falls back to date/time
quest_log_path: /nestquest/log # view the crest tap navigates to
child_order: [declan, jordyn, chloe]
# kids' panel, view 2
type: custom:nestquest-quest-log-card
board_path: /nestquest/board
weather_entity: weather.home # optional; dock falls back to date/time
idle_return_seconds: 40 # must be shorter than TouchHub Auto-Return
confirm_timeout_seconds: 15
complete_screen_seconds: 12
# parent phone
type: custom:nestquest-admin-card
density: compact # compact | roomy
default_tab: today
The quest log reads the selected child from the view's URL/hass path parameter so the
board → log hop is a plain Lovelace navigation (decision 6).
5. Data-shape consequences of the design
- Instance key is
(definition_id, child_id, due_date, window)— the schema'stask_instancesunique index must widen. quest_definitionsneeds an assignees join table, replacing the singlechild_idcolumn.quest_definitionsneeds a windows set (morning/afternoon/evening) plus an optional due time per window.- The materialiser emits one instance per (assignee × window × firing date), still idempotent on the widened key, still only when the child is present.
completion_eventsgainsactor_child_idso a panel completion records which profile was tapped, whileactorstayspanel.