Files
jpmschweitzerandClaude Fable 5 014c86f51e
Test, Build and Push / test-gateway (push) Successful in 11s
Test, Build and Push / release (push) Skipped
Test, Build and Push / build-gateway (push) Skipped
chore(gateway): drop schweitz.internal, default to http://tatlock:8000
The homelab is retiring the *.schweitz.internal domain; in-network
machine-to-machine traffic uses docker container names on the
docker-dataplane network. The deployed tatlock-ui stack already overrides
DESKLOCK_TATLOCK_BASE_URL (Tatlock runs on the host), so only the
fallback default changes.

Docs follow: AGENTS.md M2M guidance now points at container names with
*.schweitz.net reserved for browsers, architecture.md drops the retired
domain (the registry name now matches what CI actually pushes since
c477019), and the README diagram loses the stale hostname.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 12:22:25 +02:00

77 lines
4.6 KiB
Markdown
Raw Permalink 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 │
│ http://tatlock │ │ also usable by Open WebUI, │
│ :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**~~ ✅ — display, touch, audio, 200 MHz PSRAM, cathedral gong
2. **Face + voice loop** (in hardware test) — full LVGL face (7 states, rain, orbit, power ladder), Wi-Fi, WebSocket, touch-to-talk
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