Skip to content

Adapter: controller, config flow, entities, e2e tests - #3

Merged
leiklier merged 3 commits into
mainfrom
feat/adapter
Jul 23, 2026
Merged

Adapter: controller, config flow, entities, e2e tests#3
leiklier merged 3 commits into
mainfrom
feat/adapter

Conversation

@leiklier

Copy link
Copy Markdown
Owner

What

Everything between Home Assistant and the core:

  • controller.py — domain-aware normalization (zone counts, person/tracker home, media_player playing-ish, on/off, numeric fallback; unknown → None for rule 1.8), single-writer reconciliation of the physical switch (immediate on decision change and external flips), armed only after entity restores land so startup can't flash the light, one next_review timer tightened to a 6-min publish cadence while burning.
  • Entities (one device per light): number.…_target_hours (restorable 0–20 h knob), switch.…_enabled (standby escape hatch, rule 4.3), enum sensor.…_state with reason attribute, sensor.…_lit_today (duration, state_class total + last_reset at the anchor, 0.1 h quantized, publish-gated; persists exact ledger attrs for rule 5.1 restore).
  • Config flow — name + light, then visibility signals with plain-language descriptions; options flow menu (signals / timing). Unique-id on the light entity prevents two conductors fighting over one switch.
  • en + nb translations, icons, docs/MIGRATION.md with concrete per-light values for the live instance (incl. shadow-period procedure and rollback).

Tests (23; suite total 56, 99 % cov)

Config-flow contract + duplicate guard + options roundtrips, normalization table, lifecycle/reload, full-day e2e on a real input_boolean (sleep/wake/night movement, veto+refuge, budget cap & lit-today reset at anchor, manual flip reconciled, standby accounting, restore across reload), and a recorder-discipline sweep asserting zero state writes across all four entities during 24 rounds of input churn.

Part 3 of 3, stacked on #2.

🤖 Generated with Claude Code

@leiklier
leiklier force-pushed the feat/core branch 2 times, most recently from cb2a6c0 to ba47c96 Compare July 23, 2026 19:10
@leiklier

Copy link
Copy Markdown
Owner Author

Follow-up commit: trigger_entities option wired through controller (transition-only subscription, unknown/unavailable flaps filtered), config flow, en+nb translations, README, and MIGRATION.md (binary_sensor.soverom_dor as trigger for both lights). e2e test proves the differentiator: cut on door-open, relight after the hold while the door is still open. Suite now 59 tests.

leiklier and others added 3 commits July 23, 2026 19:28
Controller normalizes HA entities into input snapshots (domain-aware:
zones count occupants, media players are truthy while playing), feeds
physical light reports to the ledger, reconciles the switch as single
writer (armed only after entity restores land), and keeps one timer for
next_review tightened to a publish cadence while burning.

Per-light device with number.target_hours (restorable knob),
switch.enabled (standby escape hatch), an enum state sensor with reason
attribute, and a lit-today duration sensor (0.1 h quantized, publish-
gated for recorder discipline, persists the exact ledger for rule 5.1
restore). Config flow: light + visibility signals; options flow adds
timing tunables. en + nb translations, icons, migration guide for the
live instance. 23 adapter tests including full-day e2e scenarios and a
zero-writes-under-churn recorder sweep.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
New trigger_entities option: the controller subscribes to their
transitions separately (their level never enters the snapshot) and
pulses the engine's activity clock on every real state change —
unknown/unavailable flaps and attribute-only writes are filtered.
Config-flow field, en+nb translations, README; migration guide now maps
binary_sensor.soverom_dor as a trigger for both lights, reproducing the
legacy instant cut on door-open without an open door ever blocking the
schedule. e2e test: night cut, relight-while-open, unavailable flap.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Options → Timing gains refuge_hold_seconds and exposure_grace_seconds;
en+nb translations, README. e2e test: a coffee run (kitchen viewer
firing while the office sensor decays) never toggles the WFH block, a
door pulse during refuge is ignored, and someone settling within sight
still cuts after the grace.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@leiklier

Copy link
Copy Markdown
Owner Author

Follow-up commit: refuge_hold_seconds + exposure_grace_seconds in Options → Timing (en+nb), README; e2e proves a coffee run (kitchen viewer + office decay simultaneously) never toggles the WFH block while settling in view still cuts after the grace. Suite now 67 tests.

@leiklier
leiklier changed the base branch from feat/core to main July 23, 2026 19:36
@leiklier
leiklier merged commit 763462b into main Jul 23, 2026
8 checks passed
@leiklier
leiklier deleted the feat/adapter branch July 23, 2026 19:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant