The RF spectrum, fused onto one map.

Crewed aircraft on 1090 MHz. Drones broadcasting ASTM F3411 RemoteID. Vessels on AIS. Amateur stations on APRS. Voice traffic on Marine VHF, NOAA weather radio, CB, GMRS-FRS, and MURS. VoltGrid wraps proven demodulators — readsb, dump978, rtl_ais, rx_fm, multimon-ng, rtl_433 — and folds every decoded track, packet, and alert into a single common operating picture. Receive-only by design.

ADS-B 1090 MHzUAT 978 MHzASTM F3411 RemoteID AIS NMEA VDM/VDOAPRS 144.390 MHzNOAA SAME/EAS rtl_433 IoTDuckDB hub
Passive collection, active picture

Wrap the demodulator. Own the picture.

Purpose-built for UAS operations and wildland fire, where seeing crewed aircraft, FAA TIS-B re-broadcasts, and drone RemoteID on one screen is safety-critical. The app owns the demodulator lifecycle, fans decoded tracks to the map over SSE, and persists rolling history to DuckDB.

  • ADS-B + TIS-B + RemoteID on 1090 MHz — decoded by readsb (wiedehopf fork); UAT 978 MHz via dump978. RemoteID drones render as orange-red diamonds with operator ID and serial in the label.
  • Four ingest topologies — local HackRF spawn, remote Beast (TCP 30005), remote SBS1 (TCP 30003), or firewall-friendly aircraft.json polling from a field Pi.
  • AIS vessel tracking — rtl_ais with an NMEA VDM/VDO decoder puts maritime traffic on the same map.
  • Live + history — SSE streams drive the overlay; every track lands in DuckDB for replay and analytics.
http://localhost:5059
// one workstation → every RF source, one API
GET /api/sdr/tracks/events      → SSE: live ADS-B / RemoteID
GET /api/aprs/stations/events   → SSE: APRS positions
GET /api/aprs/messages/events   → SSE: bulletins + messages
GET /api/audio/stream           → chunked audio/mpeg (live MP3)
GET /api/audio/alerts/events    → SSE: decoded SAME/EAS alerts
GET /api/spatial/sdr/collections → OGC API Features (QGIS/Pro)

● receiving  bands 1090 · 978 · 144.39 · 156–162 MHz  · rx-only
The sensing stack

Six passive sources, one operating picture

Each source is a saved receiver you start and stop from an in-map panel — status dots, message counts, and errors refresh live.

✈️

ADS-B aircraft & RemoteID drones

readsb / dump978 decode 1090 and 978 MHz; ASTM F3411 OpenDroneID rides the 1090 extended squitter, so one receiver covers airliners, GA, and UAS deconfliction. Trails show the last 30 positions; stale tracks prune at 60 s.

🚢

AIS vessels

Marine vessel tracking via rtl_ais with an NMEA VDM/VDO decoder — maritime traffic joins aircraft and drones on the same 3D scene.

📻

APRS — RF + APRS-IS

144.390 MHz (US) / 144.800 MHz (EU) at 1200 baud AFSK via rx_fm + multimon-ng, plus a global APRS-IS internet feed that never competes for the tuner. Decodes positions, weather stations, operator-placed objects, and messages with bulletin alerting.

🔊

Audio scanners

Marine VHF (Ch 16 distress), NOAA Weather Radio WX-1..7 with SAME/EAS decode, CB (Ch 9 emergency), GMRS-FRS, and MURS. One HackRF priority-scans the watchlist and streams live MP3 straight to the browser.

📟

IoT sensing — rtl_433

Weather stations, TPMS, ERT, and alarm/motion sensors captured passively from the ISM bands and folded into the sensor picture.

🌦️

Weather & feed subscriptions

Regional conditions, forecasts, and NWS alerts, alongside OGC SensorThings / SOS / GTFS / MovingFeatures feed subscriptions for non-RF live sources.

One SDR is one tuner: ADS-B, APRS RF, and audio scanning share a single HackRF, so run one RF module at a time per device (or add a second SDR). APRS-IS runs tuner-free. All modules are receive-only — no transmit capability exists in the product.

The DuckDB hub

Every packet becomes a queryable layer

Each module persists rolling history to its own DuckDB file — sdr.duckdb, aprs.duckdb — registered with the embedded server, so the existing OGC API Features, vector-tile, and ESRI FeatureServer facades serve RF history with no extra code.

  • Latest + history tables — tracks_1090 / tracks_978 upserted per track with append-only history (24 h default retention); APRS keeps stations, weather_observations, messages, and objects for 168 h.
  • QGIS / ArcGIS Pro ready — point either at /api/spatial/sdr/collections or the /api/spatial/sdr/FeatureServer facade.
  • Vector tiles…/collections/tracks_1090/tiles/{z}/{x}/{y}.mvt for fast rendering of dense track history.
  • Discoverable — the Connect-to-GIS panel lists both the live SSE feeds and the history facades.
  • SAME/EAS alerting — NOAA broadcasts decode at 520.83 baud; critical codes (TOR, FFW, FWW, RFW, EVI, and more) fire map toasts with the alert area as FIPS codes.
sdr.duckdb · aprs.duckdb
-- rolling RF history, served through standard facades
SELECT * FROM sdr.tracks_1090_history   -- append-only
UNION SELECT * FROM sdr.tracks_978_history; -- UAT band

GET /api/spatial/sdr/FeatureServer      → ArcGIS Pro
GET /api/spatial/aprs/collections       → QGIS (OGC API)
GET /api/spatial/sdr/collections/tracks_1090
    /tiles/{z}/{x}/{y}.mvt              → vector tiles

● registered  dbId sdr, aprs  · retention 24h / 168h

Hear the spectrum. See the picture.

Plug in an SDR, add a receiver from the in-map panel, and watch aircraft, drones, vessels, and radio traffic populate the same 3D scene your mission data lives on.