istrain-public: from-scratch build of a passive RF train detector

Public community release. The complete working system — DSP + decoders (scripts/),
web dashboard + API (dashboard/), container stack (docker/), config templates (config/) —
plus APOCALYPSE-EDITION.md, the full build guide for a human or a coding agent. GPLv3
(PyEOT dependency). Scrubbed of all secrets, internal IPs, hostnames, and location detail.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
istrain
2026-07-24 23:19:16 -04:00
commit 559caead36
41 changed files with 6740 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
# istrain — keep the kernel DVB-T driver off the RTL-SDR dongles so SDR apps (rtl_airband, rtl_fm) own
# them via libusb. Without this, dvb_usb_rtl28xxu claims a dongle at boot and rtl_airband hangs on
# "Allocating zero-copy buffers" (rtl_fm auto-detaches, rtl_airband does not). These dongles are SDR-only.
#
# Deploy (sudo): sudo cp blacklist-rtl-sdr.conf /etc/modprobe.d/ && sudo modprobe -r dvb_usb_rtl28xxu
# (the modprobe -r frees it for THIS session without a reboot; the file keeps it off after reboot)
blacklist dvb_usb_rtl28xxu
+70
View File
@@ -0,0 +1,70 @@
# RTLSDR-Airband — istrain: an example voice-channel cluster (replace with YOUR subdivision — see APOCALYPSE-EDITION.md §3)
#
# Run in the foreground with live per-channel waterfalls:
# rtl_airband -f -e -c config/istrain.conf
# (-f = foreground + textual waterfalls · -e = errors to stderr · Ctrl-C to stop)
#
# One dongle (1002, Blog V4, TCXO). Five rail-voice channels demodulated SIMULTANEOUSLY (no
# scanning/camping — unlike the rtl_fm scan). The span 160.86161.19 = 330 kHz fits inside a
# 1.024 MS/s window, which stays UNDER the USB sample-loss ceiling that bit the full 2 MS/s scan.
# Each channel records to its own file in /tmp/airband, and ONLY when squelch opens (continuous=false)
# — so the files stay small and hold real audio, not hiss.
#
# Primary (example) = 160.980 (AAR ch58), the road channel + the CJ 144.7 / 157.8 detectors. See CHANNELS.md.
# Tune squelch_snr_threshold up if it records noise, down if it misses weak transmissions.
fft_size = 1024;
localtime = true;
devices:
({
type = "rtlsdr";
serial = "1002";
gain = 40;
centerfreq = 161.025;
sample_rate = 1.024;
correction = 0;
channels:
(
{
freq = 160.980;
label = "NS Dayton Rd 160.980 ch58 *MISSION*";
modulation = "nfm";
bandwidth = 12500;
squelch_snr_threshold = 4.0;
outputs: ( { type = "file"; directory = "/tmp/airband"; filename_template = "ns_dayton_road_160980"; continuous = false; split_on_transmission = true; } );
},
{
freq = 160.920;
label = "NS Buckeye Yard 160.920 ch54";
modulation = "nfm";
bandwidth = 12500;
squelch_snr_threshold = 4.0;
outputs: ( { type = "file"; directory = "/tmp/airband"; filename_template = "ns_buckeye_yard_160920"; continuous = false; split_on_transmission = true; } );
},
{
freq = 161.190;
label = "NS Col+Sandusky 161.190 ch72";
modulation = "nfm";
bandwidth = 12500;
squelch_snr_threshold = 4.0;
outputs: ( { type = "file"; directory = "/tmp/airband"; filename_template = "ns_col_sandusky_161190"; continuous = false; split_on_transmission = true; } );
},
{
freq = 160.860;
label = "CSX Scottslawn 160.860 ch50";
modulation = "nfm";
bandwidth = 12500;
squelch_snr_threshold = 4.0;
outputs: ( { type = "file"; directory = "/tmp/airband"; filename_template = "csx_scottslawn_160860"; continuous = false; split_on_transmission = true; } );
},
{
freq = 161.085;
label = "NS Col area 161.085 ch65";
modulation = "nfm";
bandwidth = 12500;
squelch_snr_threshold = 4.0;
outputs: ( { type = "file"; directory = "/tmp/airband"; filename_template = "ns_col_area_161085"; continuous = false; split_on_transmission = true; } );
}
);
});