The quiet watcher of the airwaves.

An SDR-based RF baseline and anomaly detector. riotduck learns what's normal on your spectrum — and tells you the moment something appears or disappears.

Quick start View on GitHub →

Appearance

A new transmitter pops up where the band was quiet — a rogue beacon, a covert implant, an FPV drone, a wireless camera that wasn't there last week. riotduck flags it within sweeps.

Disappearance

The other half no one watches for. An emitter you've been tracking goes silent. A persistent signal loses power. A covert transmitter you placed gets removed. You hear about it.

Identification

On appearance, riotduck captures I/Q to .cf32 and hands it to rtl_433 for fingerprinting against ~250 device classes. URH demod and unknown-signal analysis sit on the same bus.

Try it without an SDR

A synthetic SDR backend ships with the project — real complex64 I/Q, real detections, no hardware. The full scanner → baseline → dedup → capture → fingerprint pipeline runs end-to-end.

git clone https://github.com/haxorthematrix/riotduck.git
cd riotduck
pip install -e .
riotduck scan --fake 1 --config config/default.yaml

Repeat detections at the same frequency share an event id — the dedup tracker working. Set RIOTDUCK_FAKE_DEVICES=2 to exercise multi-device discovery.

How it works

Five stages on an in-process async bus. Each stage is its own module and is unit-tested without hardware.

Sweep Baseline Detect Capture Identify

Hardware

SoapySDR-first, with a pyrtlsdr fallback. The synthetic backend is built in for hardware-free testing.

Supported today

  • RTL-SDR (R820T2 + variants)
  • HackRF One
  • Synthetic SDR (built-in)

Drops in next

  • Airspy / SDRplay / LimeSDR / USRP — via SoapySDR
  • HackRF sweep fast path for multi-GHz ranges
  • Multi-SDR orchestration: one sweeps while another analyzes

Notifications

  • stdout — terminal-friendly events
  • jsonl — durable, rotatable
  • webhook — POST JSON to anything