An IoT sound-detection service that runs continuously on a Raspberry Pi, listening for passing trains and automatically logging each event to a cloud backend. When a train passes, the service captures a WAV recording and sends it — along with the timestamp, duration, and peak decibel level — to a backend API that stores the data for later analysis.
The Pi lives near the tracks and runs headlessly overnight. This repo is the Python service that powers it.
- Runs as a long-lived Python service on a Raspberry Pi
- Listens to a USB microphone and calculates estimated dB SPL once per second
- When audio exceeds 65 dB SPL, starts capturing a sound event
- When audio drops below 65 dB SPL for 2+ seconds, ends the event and:
- Saves a WAV clip to
recordings/ - POSTs the detection (timestamp, duration, peak dB, source label, WAV clip) to the backend API for persistent storage
- Saves a WAV clip to
- Python 3.11+
- PortAudio (required by
sounddevice) - A Logitech BRIO (or other USB microphone — configurable via
--device-keyword)
Install Python dependencies:
uv syncOn Debian/Ubuntu, install PortAudio with:
sudo apt install portaudio19-devuv run train.pyBy default, connects to the dev API at http://localhost:3000. Set BACKEND_SERVER_API_URL to point at the production API:
export BACKEND_SERVER_API_URL=https://your-api-url
uv run train.pyOr pass it directly:
uv run train.py --api https://your-api-url| Flag | Default | Description |
|---|---|---|
--api |
$BACKEND_SERVER_API_URL or dev URL |
API base URL |
--source |
pi-north |
Sensor source label sent with detections |
--calibration-offset |
101.5 |
dBFS → dB SPL offset (recalibrate against a reference meter) |
--threshold-db |
65.0 |
dB SPL level that starts a sound event |
--window-seconds |
1.0 |
Volume measurement window size in seconds |
--device-keyword |
BRIO |
Substring to match against audio input device names |
To keep the script running after you disconnect, use screen:
# Start a named session
screen -S train
# Run the script
BACKEND_SERVER_API_URL=https://your-api-url uv run train.py
# Detach: Ctrl+A then DTo reattach later:
screen -r trainOther useful commands:
screen -ls # list sessions
screen -X -S train quit # kill the session- Install the Remote - SSH extension in VS Code.
- Open the Command Palette (
Ctrl+Shift+P) and run Remote-SSH: Add New SSH Host. - Enter your SSH connection string (e.g.
ssh pi@raspberrypi.local), and save it to your SSH config. - Open the Command Palette again and run Remote-SSH: Connect to Host, then select your host.
- Once connected, open the project folder via File → Open Folder.
VS Code will install its server on the remote machine automatically. You can then edit files, use the integrated terminal, and manage screen sessions — all from your local machine.