Files

27 lines
2.9 KiB
Markdown

# SDR radio code on the Pi (/opt/pi/sdr/)
Stdlib only, Python 3.14 (numpy for classify/discover). Every Python entry script is started with
`python3 -I` and puts its parent dir (the package root) on sys.path itself, so `import radio` works.
| dir | what | systemd unit (user) | ExecStart |
|---|---|---|---|
| `radio/` | shared package: `config.py` (all paths, env vars, constants), `channels.py` (channels.json cache), `recordings.py` (DAY_RE/FILE_RE, per-day indexes, durations, scan/list/counts), `mp3.py`, `util.py` (JSON helpers) | - | - |
| `web/` | radio.home recordings UI | `sdr-recordings` (sdrweb) | `python3 -I /opt/pi/sdr/web/server.py` |
| `scanner/gen_config.py` | writes rtl_airband.conf + channels.json from one frequency table | `sdr-scanner` ExecStartPre (root) | `python3 -I /opt/pi/sdr/scanner/gen_config.py /etc/sdr-scanner` |
| `scanner/watchdog.sh` | restarts the scanner when the HackRF stream died | `sdr-scanner-watchdog` (timer, root) | `/opt/pi/sdr/scanner/watchdog.sh` |
| `classify/classify.py` | voice/noise post-filter loop (+ `audio.py` DSP, `adsb.py` aircraft context, `guard.py` stuck-channel squelch raise) | `sdr-classify` (sdr) | `python3 -I /opt/pi/sdr/classify/classify.py` |
| `discover/discover.py` | hackrf_sweep source discovery (stops the scanner via the unit) | `sdr-discover` (timer, root) | `python3 -I /opt/pi/sdr/discover/discover.py` |
| `archive/archive.py` | rsync old days to the home server, verify, delete local | `sdr-archive` (timer, sdr) | `python3 -I /opt/pi/sdr/archive/archive.py` |
| `archive/retention.sh` | delete noise/blips, emergency cleanup | `sdr-retention` (timer, sdr) | `/opt/pi/sdr/archive/retention.sh` |
| `transcribe/transcribe.py` | queue of voice recordings (since SDR_TR_START) -> Whisper on the owner desktop via https://whisper.home (Caddy, connects to 192.168.88.221); waits while the desktop is off; newest first | `sdr-transcribe` (sdr) | `python3 -I /opt/pi/sdr/transcribe/transcribe.py` |
| `speaker/speaker.py` | plays new voice recordings on the Pi jack (no `radio` import; own env names SPEAKER_*) | `sdr-speaker` (DynamicUser) | `python3 -I /opt/pi/sdr/speaker/speaker.py` |
| `patches/`, `readsb/` | rtl_airband local patch, readsb notes | - | - |
## Data paths (all in `radio/config.py`, env override in brackets)
- recordings `/srv/sdr/recordings/YYYY-MM-DD/*.mp3` [SDR_REC_DIR]; per day `.cls.json` (classifier), `.archived.json` (archive), `noise/`
- channels `/etc/sdr-scanner/channels.json` [SDR_CHANNELS] (written by gen_config)
- discovery `/srv/sdr/discovery/` [SDR_DISC_DIR]: `sources.json`, `promoted.json`, `adsb_latest.json`, `auto_snr.json`, `runs.jsonl`
- speaker state `/var/lib/sdr-speaker/state.json` (web: SDR_SPEAKER_STATE, speaker.py: SPEAKER_STATE - different names on purpose, kept as before)
- shares `/var/lib/sdr-web/shares.json` [SDR_SHARES]
- transcripts `/srv/sdr/transcripts/YYYY-MM-DD.json` + `status.json` [SDR_TR_DIR] (web: `tr` field, `/api/transcribe` 200/503 for the dashboard)