Phase 2: full LVGL face + Wi-Fi + gateway WebSocket + touch-to-talk
Test, Build and Push / test-gateway (push) Successful in 10s
Test, Build and Push / release (push) Skipped
Test, Build and Push / build-gateway (push) Skipped

The device now runs the complete face contract on glass: seven states
with glyph expressions (custom 140px face font), matrix rain as pooled
label streams (22px DejaVu+Noto katakana font), rage kaomoji frames
(64px), orbit arc + elapsed counter wait cues, blink/talk/thought
animations, idle clock (SNTP, Europe/Amsterdam), and the power ladder
(active/ambient 35%/dormant 5% with rain parked).

Voice path: ES7210 mic capture task streams 16k PCM over
esp_websocket_client to the gateway; reply PCM buffers to PSRAM and
plays via the audio task; touch-to-talk (tap to speak, tap to send).
Protocol mapping per docs: thinking->effort, audio->speaking,
error event->rage (auto-composes after 2 loops), WS loss->error face.

Bring-up fixes: 8MB factory partition (fonts overflowed 1.5M),
bsp_display_lock(0) is try-lock in this adapter (use UINT32_MAX),
gong synth yields to feed IDLE0, wifi scan diagnostics (found SSID
case mismatch), esp_websocket_client pinned ~1.3 (1.4 needs IDF>5.5).

Verified on hardware: boots, connects to Wi-Fi and holds an open
WebSocket to the gateway. Sauron (iMac TTY endpoint + ops console)
planned in architecture.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 21:42:51 +02:00
co-authored by Claude Fable 5
parent ae9f6e0abb
commit ed0e8221f1
17 changed files with 3073 additions and 145 deletions
+19
View File
@@ -301,6 +301,25 @@ it is the one contract between the two halves of the repo.
- **Monorepo**: the WS protocol couples firmware and gateway; versioning them together
avoids contract drift.
## Additional endpoints — sauron (planned)
**sauron** is an old iMac (Linux, text-only console) that will run the same UX as a
second butler endpoint plus an ops console. Because the gateway protocol is
endpoint-agnostic and each WS connection gets its own conversation, extra endpoints
are architecturally free.
- **Client**: a terminal UI (`clients/sauron/`, Python + curses/textual) — the face
design is already ASCII, so a TTY renders it natively: glyph face states,
character-cell matrix rain, green-on-black. Audio via ALSA (arecord/aplay-level,
16 kHz mono PCM), same WebSocket protocol, same state machine.
- **Screensaver model** (user-confirmed): the face+voice layer is the *idle mode*
full-screen butler when nobody's working. The *workspace mode* is an SSH ops console:
live stats and remote control of tower-of-joy and forge. Any keypress drops from face
to console; idle timeout (and wake word later) raises the face again. Voice stays
available in both modes.
- **Not started** — planned after the device reaches phase 4/5. No browser/kiosk stack
needed unless we later want the glow.
## CI & deployment
Gitea Actions (`.gitea/workflows/build.yml`), following the tatlock/tatlock-ui pattern: