Troubleshooting
Common issues and how to resolve them. Most problems can be diagnosed by checking service status and logs.
Checking logs
All logs are stored in the logs/ directory at the project root:
logs/
├── api/ # Flask backend (rotating, 8 MB max, 3 backups)
│ └── security-cam.log
├── update/ # Auto-update on boot
├── install/ # install_requirements.sh
├── mediamtx-install/ # setup/install_mediamtx.sh
├── ap-setup/ # setup/setup_ap.sh
└── bluetooth-pairing/ # setup/pair_bluetooth.sh
└── 2026-04-01_09-27-32.log (example)
Except for api/, each folder stores timestamped logs (one per run, last 20 kept).
API logs
The backend writes to a rotating log file at logs/api/security-cam.log (8 MB max, 3 backups kept). Each line includes a timestamp, level, and logger name that tells you which subsystem produced it:
2026-03-31 23:44:30 [INFO] bt.pair: Pairing device AA:BB:CC:DD:EE:FF ...
2026-03-31 23:45:19 [INFO] bt.pair: Device AA:BB:CC:DD:EE:FF paired and trusted
2026-03-31 23:45:19 [INFO] bt.api: Device added: My Phone (AA:BB:CC:DD:EE:FF)
Logger names use dot-separated namespaces, so you can filter by subsystem with grep:
# All Bluetooth activity
grep "bt\." /opt/security-cam/logs/api/security-cam.log
# Just pairing issues
grep "bt.pair" /opt/security-cam/logs/api/security-cam.log
# Only errors and warnings
grep -E "WARNING|ERROR" /opt/security-cam/logs/api/security-cam.log
# Follow live (useful while reproducing an issue)
tail -f /opt/security-cam/logs/api/security-cam.log | grep "bt\."
| Grep pattern | What you get |
|---|---|
grep "bt\." | All Bluetooth activity (scanning, pairing, discoverable) |
grep "sensor\." | All sensor activity (triggers, manager, individual drivers) |
grep "stream" | Camera capture + MediaMTX |
grep "system\." | System health + storage monitoring |
grep "api:" | HTTP requests and responses |
grep "archive:" | Video archive operations |
grep "presence:" | Presence detection gating |
Full logger list:
| Logger | What it logs |
|---|---|
api | HTTP requests/responses |
archive | Video file listing and deletion |
bt.api | Bluetooth endpoint layer |
bt.pair | Pairing, unpairing, discoverable mode |
bt.scan | Bluetooth scanning and presence checks |
events | Security and activity events |
presence | Presence-based recording gating |
sensor.mgr | Sensor lifecycle management |
sensor.<type> | Individual sensor drivers (e.g. sensor.pir, sensor.reed) |
settings | JSON settings reads/writes |
sse | Server-sent events |
stream | Camera capture, MJPEG, recording |
stream.mtx | MediaMTX configuration |
system.health | CPU temp, RAM, CPU load |
system.storage | Disk space, auto-delete |
wifi | WiFi/AP device scanning |
You can also check system service logs via journalctl:
journalctl -u security-cam --no-pager -n 50
Dashboard loads but no video feed
- Check MediaMTX is running:
sudo systemctl status mediamtx - Verify the stream directly: open
http://<pi-ip>:8889/camin a browser - Check camera is detected:
rpicam-vid --list-cameras
Cannot reach the dashboard
- Check the service is running:
sudo systemctl status security-cam - Make sure you're using port
3000 - Check firewall:
sudo nft list ruleset
API errors in the dashboard
- Check Flask is running:
curl http://localhost:5005/system_info - Check the application log:
tail -50 /opt/security-cam/logs/api/security-cam.log - Or filter to just API errors:
grep "api:" /opt/security-cam/logs/api/security-cam.log | grep -i "error\|warning"
Service fails on boot
Check the logs:
# systemd service output
journalctl -u security-cam --no-pager -n 50
# API log
tail -50 /opt/security-cam/logs/api/security-cam.log
# Auto-update log (shows git pull, dependency install, and frontend build)
ls -1t /opt/security-cam/logs/update/ | head -1 | xargs -I{} cat /opt/security-cam/logs/update/{}
Common causes:
- No internet -
git pullfails. The service continues with the current code, but if this is the first run and deps aren't installed, it will fail. Runinstall_requirements.shmanually once. - Build fails - check the update log for errors. The frontend build runs in a temp directory (
dist_new/) and only replacesdist/on success, so a failed build won't break a working dashboard. - OOM during build - the Pi Zero 2 W has limited RAM. If the build is killed, check
dmesg | grep -i killed. The previousdist/is preserved.
Sensor not triggering
- Verify wiring with the Test Wiring panel in Settings > Sensors - activate the sensor and check if the GPIO value changes
- Check the correct GPIO pin is configured (BCM numbering, not board pin)
- Try toggling Invert trigger - some sensors fire on LOW instead of HIGH
- Check the sensor is enabled (auto-recording toggle is on)
- If using presence detection, make sure no tracked device is nearby (the trigger may be suppressed)
Recording starts but no file appears
- Check the save location exists and is writable:
ls -la /path/to/recordings/ - Check disk space:
df -h - Check ffmpeg is installed:
ffmpeg -version - Check RTSP stream is accessible:
ffmpeg -i rtsp://localhost:8554/cam -t 5 -c copy /tmp/test.mp4