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-agent — Show 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):
- The ISO builds at all.
- greetd lands in Sway with no login prompt.
- Touch input as native
wl_touch— same open item as every other touch host. door-panel-agentconnects to Mosquitto and the device appears in HA.- 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. Seeidentity/README.md's worked example for that next step. - 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. - The dashboard's clothing suggestion (
identity/frontend/dashboard.js'sclothingSuggestion()) is a plain lookup table, untuned against real weather payloads or real household clothing preferences — reasonable starting thresholds, not measured. - Switching between
home-kioskandidentity-kioskactually replaces the window rather than leaving two Chromium instances up — same untested assumption as../kitchen-display/'s identical pair. - Idle-blank timeout (20 minutes,
configs/sway/config) and touch-resume — untested.