Files
desklock/README.md
T
jpmschweitzerandClaude Fable 5 42b988b7ef Add face design: ASCII expressions + matrix rain simulator, wait cues, fresh latency numbers
- sim/face/index.html: browser simulator of the 800x800 round panel with
  six states (idle/listening/pensive/effort/speaking/error), state-driven
  rain density, blink/talk/thought animations, idle clock
- effort state gets hard-required wait cues: orbiting bezel arc, elapsed
  counter, max rain (Tatlock turns run 10-25s)
- rain driven by setInterval, not rAF: renders under the screenshot
  tool's --virtual-time-budget and mirrors LVGL lv_timer
- architecture.md: Face design contract (state table, protocol mapping,
  LVGL port notes) + latency table updated to GPU-era benchmarks
  (Steward ~6s warm, full flow 11-25s; old CPU-era figures retired)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 17:32:16 +02:00

4.5 KiB
Raw Blame History

DeskLock

A living-room visual/audio endpoint for Tatlock, the homelab butler. DeskLock gives Tatlock a face and a voice on a Waveshare round touch display: you talk to it, it listens, thinks, and answers — the first line of contact with the butler backend running on tower-of-joy.

Hardware

Waveshare ESP32-P4-WIFI6-Touch-LCD-3.4C

Component Details
SoC ESP32-P4NRW32 — dual-core RISC-V @ 400 MHz + LP core
Memory 32 MB PSRAM (in-package), 32 MB NOR flash
Display 3.4" round IPS, 800×800, MIPI-DSI 2-lane, capacitive touch
Radio ESP32-C6-MINI-1 (Wi-Fi 6 + BLE 5) over SDIO via ESP-Hosted
Audio in Dual onboard microphones + ES7210 echo-cancellation ADC
Audio out ES8311 codec, PH2.0 2-pin speaker connector (8Ω 2W recommended)
Flashing USB-C (hold BOOT during reset for download mode)

The device is currently connected over USB-C directly to tower-of-joy, so build/flash happens on this server.

Architecture

┌──────────────────────┐  WebSocket: PCM audio + JSON events
│  DeskLock device     │◄───────────────────────────────────┐
│  (ESP32-P4)          │                                    │
│  • LVGL face         │     ┌──────────────────────────────┴───────────┐
│  • touch / wake word │     │  DeskLock Gateway  (container, :8600)    │
│  • mic capture + AEC │     │  thin orchestrator — no ML dependencies  │
│  • TTS playback      │     └───────┬──────────────────┬───────────────┘
└──────────────────────┘             │                  │  OpenAI-format HTTP
                                     │                  ▼
                          HTTP (LAN) │       ┌─────────────────────────────┐
                                     ▼       │  Speaches  (container, GPU) │
                     ┌────────────────────┐  │  • STT: faster-whisper      │
                     │  Tatlock (butler)  │  │  • TTS: Kokoro / Piper      │
                     │  tatlock.schweitz. │  │  also usable by Open WebUI, │
                     │  internal :8000    │  │  Home Assistant, …          │
                     └────────────────────┘  └─────────────────────────────┘

Tatlock stays a text-only brain. The gateway orchestrates speech-to-text, chat, and text-to-speech; the Speaches container owns the actual STT/TTS models on the GPU, shared homelab-wide. The device firmware stays thin: audio transport, wake word, and face rendering only. Everything runs on the LAN — no cloud in the voice path.

See docs/architecture.md for the full design.

Repository layout

  • firmware/ — ESP-IDF (C, LVGL 9) application for the ESP32-P4
  • gateway/ — Python FastAPI voice gateway, deployed as a container on tower-of-joy
  • sim/face/ — browser simulator of the face (design source of truth; serve with python3 -m http.server and open index.html, or use ?state=…&nochrome=1 for screenshots)
  • docs/ — architecture and design notes

Roadmap

  1. Bring-up — ESP-IDF toolchain, build/flash, BSP display + Wi-Fi working
  2. Face — LVGL face with idle/listening/thinking/speaking states, clock while idle
  3. Voice (touch-to-talk) — tap to talk → gateway → Tatlock → spoken reply
  4. Wake word — esp-sr WakeNet on-device, echo cancellation, barge-in
  5. Polish — Tatlock-initiated notifications, presence, OTA updates

References