jpmschweitzerandClaude Fable 5 f5df5049db
Test, Build and Push / test-gateway (push) Successful in 1m2s
Test, Build and Push / release (push) Skipped
Test, Build and Push / build-gateway (push) Skipped
Add rage table-flip state; wire gateway to live Speaches; add CI pipeline
- Face: new 'rage' state — 3-frame kaomoji loop (stare, flip the table,
  put it back) for in-flight request failures; 'error' stays the quiet
  persistent face for a dead link. Sim + artifact + design doc updated.
- Gateway: stt.py/tts.py are now pluggable backends. Default 'speaches'
  talks OpenAI-format HTTP to the live container on :8601
  (faster-whisper-small STT, Kokoro bm_george TTS with 24->16 kHz
  audioop resample); 'embedded' fallback kept behind the [speech] extra.
  Verified with a live TTS->STT round trip (warm: STT 0.27s, TTS 1.9s).
  Docker image is now slim (no CUDA/ML deps). Python pinned to 3.12
  (system 3.8 too old, audioop gone in 3.13).
- CI: .gitea/workflows/build.yml — lint+test on main pushes; on v* tags
  test, build gateway image, push to registry, release, and trigger
  Watchtower (tatlock pattern; needs REGISTRY_USER/REGISTRY_PASSWORD/
  WATCHTOWER_TOKEN secrets). Runtime stack in deploy/desklock-gateway.yml.
- architecture.md: measured speech latencies, deployed-Speaches status,
  CI & deployment section.

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

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

S
Description
No description provided
Readme
10 MiB
2026-07-19 12:32:13 +02:00
Languages
C 87.2%
C++ 8.5%
M4 1.6%
CMake 1%
Python 0.8%
Other 0.9%