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

77 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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](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
- [Waveshare wiki: ESP32-P4-WIFI6-Touch-LCD-3.4C](https://www.waveshare.com/wiki/ESP32-P4-WIFI6-Touch-LCD-3.4C)
- [Official examples repo (waveshareteam/ESP32-P4-WIFI6-Touch-LCD-XC)](https://github.com/waveshareteam/ESP32-P4-WIFI6-Touch-LCD-XC)
- [BSP component: waveshare/esp32_p4_wifi6_touch_lcd_xc](https://components.espressif.com/components/waveshare/esp32_p4_wifi6_touch_lcd_xc)
- [Speaches — self-hosted OpenAI-compatible speech server](https://github.com/speaches-ai/speaches)
- Tatlock backend: `/mnt/media/Projects/tatlock` — https://tatlock.schweitz.net