Replaces the hardcoded CAMERA_NAME with a CAMERAS list. The page renders a dropdown when more than one camera is configured and remembers the choice in localStorage; switching tears down and reopens the WebRTC connection. https://claude.ai/code/session_013XZ1vmgk78k2PEQ5DmJhF3
108 lines
3.1 KiB
Markdown
108 lines
3.1 KiB
Markdown
# Pi doorbell PTT
|
|
|
|
Turns a Raspberry Pi into a network speaker so a phone hitting
|
|
`https://doorbell.yourdomain.com` can see/hear the front-door Frigate feed
|
|
and hold a button to talk through a speaker mounted at the door.
|
|
|
|
## Hardware
|
|
|
|
- Any Raspberry Pi (Zero W 1st gen is enough; Zero 2 W is better for live
|
|
two-way; Pi 3A+ has a 3.5mm jack onboard and skips the OTG adapter)
|
|
- Audio output, one of:
|
|
- USB speaker + micro-USB-to-USB-A OTG adapter (simplest)
|
|
- 3.5mm powered speaker (Pi 3A+ has the jack; Zero W does not)
|
|
- I2S DAC HAT (best quality, requires GPIO header)
|
|
- microSD card, power supply, WiFi or USB ethernet
|
|
|
|
## Install on the Pi
|
|
|
|
```bash
|
|
# From your laptop/desktop:
|
|
scp -r pi/ pi@PI_LAN_IP:~/doorbell-src
|
|
|
|
# SSH to the Pi:
|
|
ssh pi@PI_LAN_IP
|
|
cd ~/doorbell-src
|
|
chmod +x install.sh
|
|
./install.sh
|
|
```
|
|
|
|
The installer apt-installs ffmpeg + alsa-utils + Python deps, creates a
|
|
virtualenv, drops `server.py` into `~/doorbell/`, installs and enables the
|
|
systemd service, runs `speaker-test` to confirm ALSA output works, and
|
|
starts the service.
|
|
|
|
## Verify
|
|
|
|
```bash
|
|
curl http://127.0.0.1:5555/healthz # -> ok
|
|
sudo journalctl -u doorbell -f # live logs
|
|
```
|
|
|
|
## Wire it up
|
|
|
|
1. On the Caddy host, add the `doorbell.yourdomain.com` block from
|
|
`../caddy/Caddyfile` and reload Caddy.
|
|
2. DNS: point `doorbell.yourdomain.com` at the Caddy host's public IP.
|
|
3. Open `https://doorbell.yourdomain.com` on an Android phone.
|
|
4. Grant the one-time microphone permission.
|
|
5. Tap **Unmute camera** if browser autoplay swallowed the audio.
|
|
6. Hold the big green button to talk.
|
|
|
|
Add to home screen (Chrome menu -> Add to home screen) for an app-like
|
|
experience.
|
|
|
|
## Choosing the camera
|
|
|
|
`server.py` near the top has the list of cameras the page offers:
|
|
```python
|
|
CAMERAS = ["front_door"]
|
|
```
|
|
|
|
Each name must match a `go2rtc.streams` entry in
|
|
`frigate_config/config.yml` and the camera must be `enabled: true` in
|
|
Frigate. With more than one entry the page shows a dropdown above the
|
|
talk button; the choice is remembered per-browser in `localStorage`. The
|
|
first entry is the default for new visitors.
|
|
|
|
After editing:
|
|
```bash
|
|
sudo systemctl restart doorbell
|
|
```
|
|
|
|
## Audio stack
|
|
|
|
ALSA-only -- no PipeWire/PulseAudio. Lighter on the Pi Zero. If you ever
|
|
need PipeWire (e.g., to share the speaker with another app), change
|
|
`'-f', 'alsa'` to `'-f', 'pulse'` in `server.py` and install the
|
|
PipeWire/Pulse compatibility shim.
|
|
|
|
## Troubleshooting
|
|
|
|
### speaker-test fails
|
|
|
|
USB/3.5mm output isn't the default ALSA card. Check:
|
|
```bash
|
|
aplay -l
|
|
```
|
|
If your speaker isn't card 0, create `/etc/asound.conf`:
|
|
```
|
|
defaults.pcm.card 1
|
|
defaults.ctl.card 1
|
|
```
|
|
(Replace `1` with whatever card your speaker is.)
|
|
|
|
### Video plays but talk button stuck on "Disconnected"
|
|
|
|
The WebSocket isn't reaching the Pi. Most common: Caddy not proxying
|
|
`doorbell.yourdomain.com` -> Pi correctly. From the Caddy host:
|
|
```bash
|
|
curl -i http://PI_LAN_IP:5555/healthz # should return 200 ok
|
|
```
|
|
|
|
### Feedback loop when talking
|
|
|
|
The page auto-mutes the camera while the PTT button is held, so this
|
|
should not happen. If it does, increase distance between Pi speaker and
|
|
camera mic, or turn the speaker volume down.
|