SmartestHome/hosts/door-panel/README.md

7.3 KiB

Sway door panel

Phase 18 of docs/project-plan.md. Builds a Debian 12 live ISO for a wall panel by the door/wardrobe: weather and what to wear on the way out, who's home, groceries running low, and — the household's actual registration point — "register me as <name>" by voice.

Structurally this is ../kitchen-display/'s twin, not a new shape: one Sway workspace, one Chromium kiosk window, a thin agent that only ever switches which page is showing. The differences are what it shows by default (identity's dashboard.html instead of pantry-vision's scan/inventory/recipes) and that its microphone is expected to actually be used, not an edge-case opt-in.

The actual logic does not live in this directory../../identity/ owns person/presence data and the registration flow; ../../pantry-vision/ owns the "running low" data. This host is deliberately thin: Sway, one kiosk window, and door-panel-agent, which only controls which screen is showing — the same split every other kiosk host in this project already uses.

Compositor Sway, one workspace, one Chromium kiosk window
Autologin greetd, straight into /usr/local/bin/kiosk-session
Touch input Native Wayland wl_touch, same assumption as ../touch-panel//../kitchen-display/
Default screen identity's dashboard.html — weather + clothing suggestion, who's home, groceries running low
Registration identity's register.html — voice ("register me as <name>") or the touchscreen form
Voice wyoming-satellite + openWakeWord — opt-in like every other host's mic, but this device's actual purpose, so the build script defaults it to on
Remote control (HA/LLM) door-panel-agentShow home / Show registration buttons only
Remote control (human) SSH only — no wayvnc, same scope decision as ../touch-panel/

Hardware

No specific unit has been chosen. What's assumed: a touchscreen (native wl_touch, same caveat as every other touch host in this project) mounted by the door or wardrobe, with a microphone and speaker for voice registration/Assist playback. Unlike ../kitchen-display/, no camera is strictly required — the photo captured during registration (identity's profile-picture feature) is a nice- to-have audit artifact, not load-bearing, since identity resolution here is BLE/IRK- based, not camera-based. See docs/project-plan.md §1.16 for the (unverified, non-specific) hardware line item.

Before you build

Deploy identity/identity-web first (ENABLE_IDENTITY in hosts/container-host/scripts/setup-container-host.sh) — this image builds and boots fine without it, but the dashboard will show connection errors until it exists. pantry-vision is optional (only "Running low" needs it). Then edit the # CONFIGURATION block at the top of scripts/build-door-panel-iso.sh:

Variable What to put in it
MQTT_BROKER_HOST LAN IP of the container host running Mosquitto
IDENTITY_WEB_URL / IDENTITY_URL / IDENTITY_TOKEN identity's static-serving and API URLs; token must match identity/identity.env's own
PANTRY_VISION_URL / PANTRY_VISION_TOKEN Optional — only "Running low" needs these; must match pantry-vision/pantry-vision.env's own token
ENABLE_VOICE_SATELLITE Defaults to true here (unlike every other host's identical flag) — this device's whole point is voice registration, but it still needs a real mic on the specific unit before flashing it
KIOSK_USERNAME / IMAGE_HOSTNAME / DOOR_PANEL_NAME Per-device identity
SSH_AUTHORIZED_KEY Optional — password auth is disabled and there is no wayvnc

Build

sudo ./scripts/build-door-panel-iso.sh

Same directory-split convention as every other host: configs/ and agent/ are human-edited and git-tracked; live-build/config/includes.chroot/ is generated, gitignored, never hand-edited.

Why one workspace, two kiosk destinations, not three

../touch-panel/ juggles three real apps (Spotify, Home Assistant, a browser) and needs a persistent touch dock to switch between them. This device only ever shows one of two pages — the everyday dashboard, or the registration form — and switches between them rarely (on an MQTT command or a voice trigger), so a dock would be overhead with nothing to navigate day-to-day. configs/sway/home-kiosk and configs/sway/identity-kiosk are separate scripts on separate Chromium profiles, same shape as ../kitchen-display/'s pantry-kiosk/identity-kiosk pair — see that host's README for why both scripts kill any Chromium instance before launching (this device also has only one workspace).

Home Assistant entities

door-panel-agent publishes two buttons on connect: Show home, Show registration — each kills and relaunches the kiosk Chromium window at the corresponding page. That's the entire MQTT surface. Reading presence/weather/ groceries, or registering a person, is a separate path — Home Assistant/the LLM calling identity's or pantry-vision's own published APIs directly, not through this agent. Voice registration in particular never touches this agent at all — see ../../identity/README.md's worked HA intent-script example.

Security boundary

Same shape and reasoning as every other host's agent in this project: door_panel_agent/mqtt_discovery.py is the entire inbound MQTT control surface of this machine — LLM tool call → HA service call → MQTT → this agent, no HTTP listener, no websocket, no exposed Sway IPC socket, no VNC. identity and pantry-vision are separate, deliberately published services with their own bearer-token boundaries — see their own READMEs' "A real network listener, unlike admin-canvas" sections for why that trust model is different on purpose.

Manual verification still outstanding

None of this has been run on hardware. In rough order — on top of everything already flagged as unverified in ../../identity/README.md (TRUSTED_ENTITY_PREFIXES above all):

  1. The ISO builds at all.
  2. greetd lands in Sway with no login prompt.
  3. Touch input as native wl_touch — same open item as every other touch host.
  4. door-panel-agent connects to Mosquitto and the device appears in HA.
  5. Register via the touchscreen form (Show registration) first, before trying voice — this exercises the whole identity path without needing HA's intent-script wiring set up. See identity/README.md's worked example for that next step.
  6. Voice registration end-to-end: wake word → "register me as <name>" → a spoken confirmation. This is the number of moving pieces (wyoming-satellite, HA's Assist pipeline, the custom sentence/intent script, identity's /register) that has the most to go wrong and the least individual testing so far.
  7. The dashboard's clothing suggestion (identity/frontend/dashboard.js's clothingSuggestion()) is a plain lookup table, untuned against real weather payloads or real household clothing preferences — reasonable starting thresholds, not measured.
  8. Switching between home-kiosk and identity-kiosk actually replaces the window rather than leaving two Chromium instances up — same untested assumption as ../kitchen-display/'s identical pair.
  9. Idle-blank timeout (20 minutes, configs/sway/config) and touch-resume — untested.