# SDR toolbox Nix flake providing programs for exploring an RTL-SDR stick. ## Usage ```sh cd ~/projects/sdr nix develop # drops you into a shell with all tools rtl_test # verify the stick is detected ``` Or install the whole set into your profile: ```sh nix profile install .#sdr-tools ``` ## One-time NixOS setup The kernel's DVB-T driver grabs the stick, and you need udev rules to use it without root. On NixOS add this to your `configuration.nix`: ```nix hardware.rtl-sdr.enable = true; # udev rules + blacklists dvb_usb_rtl28xxu users.users.bender.extraGroups = [ "plugdev" ]; ``` then rebuild and re-plug the stick. ## What's included | Program | Try it for | | ------------- | ------------------------------------------------------------- | | `rtl_test` | Verify the dongle works | | `sdrpp` | Modern spectrum browser — tune around the FM band first | | `gqrx` | Classic waterfall receiver | | `rtl_433` | Neighborhood 433 MHz sensors: `rtl_433` | | `dump1090` | Aircraft tracking: `dump1090 --interactive` | | `multimon-ng` | Pagers etc.: `rtl_fm -f 466.230M -s 22050 \| multimon-ng -t raw -a POCSAG1200 -` | | `welle-io` | DAB+ digital radio | | `satdump` | Weather satellite images (NOAA APT, Meteor LRPT) | | `noaa-apt` | Simple NOAA APT decoding | | `wmbusmeters` | Decode wM-Bus / OMS smart meters (water, heat, gas, electric) | | `rtl_wmbus` | wM-Bus demodulator used under the hood by wmbusmeters | | `wmbus-listen`| Convenience wrapper: listen for OMS telegrams (see below) | ## Listening to OMS / wM-Bus meters OMS smart meters transmit wireless M-Bus on 868.95 MHz (T1/C1 link modes). `wmbus-listen` drives the stick via `rtl_sdr | rtl_wmbus` and hands frames to `wmbusmeters`. ```sh wmbus-listen # discovery: print the id/driver of every meter heard wmbus-listen Water multical21 12345678 00112233445566778899AABBCCDDEEFF # decode one meter (needs its id + AES key) ``` Discovery mode needs no keys — run it, note the ids and drivers that scroll by, then re-run with `NAME DRIVER ID KEY` to decode a meter you have the key for. Env overrides: `WMBUS_MODES` (default `c1,t1`), `WMBUS_FORMAT` (`json`/`fields`/`hr`). Both `wmbusmeters` and `rtl_wmbus` are built from source in the flake because they are no longer packaged in nixpkgs. ## `oms-tui` — full-screen OMS monitor A Textual TUI that wraps `wmbusmeters`: a live list of detected meters on the left, a detail view / live telegram stream on the right. ```sh oms-tui # live off the RTL-SDR (868.95 MHz, C1/T1) oms-tui --replay sample.msg # offline demo against the bundled capture oms-tui --import meters.csv # preload AES keys before listening ``` Keys: | Key | Action | | ------- | ---------------------------------------------------------------- | | `Enter` | select the highlighted device (show its details) | | `a` | deselect — show the live stream of *all* telegrams | | `k` | set/clear the AES key for the selected device (decrypts live) | | `e` | export the current device list to CSV (includes an `aes_key` col)| | `i` | import a CSV — loads keys and auto-decrypts those meters | | `q` | quit | Details include manufacturer, media/type, driver, version, RSSI, first/last seen, telegram count, the estimated **send interval** (median of the gaps between telegrams, so missed transmissions don't skew it — needs ≥2 telegrams), the encryption in use (OMS security mode 5 = AES-CBC, mode 7 = AES-CTR, or ELL AES-CTR), TPL/ELL layer info, and — once decoded — the latest measurement values with a timestamp. Unencrypted meters show as **open** (📖, readable without a key); encrypted ones are **locked** (🔒) until you add a key, then **decrypted** (🔓). The device list is in-memory and resets on each start; use `e`/`i` to persist. Both C1 and T1 link modes are listened to by default (`--listento=c1,t1`); add others (e.g. `--listento=c1,t1,s1`) if your meters use them. Workflow: run it, watch meters appear, select one and press `k` to paste its AES-128 key (32 hex chars) — it decrypts on the next telegram. Press `e` to save everything (keys included) to CSV, then `oms-tui --import that.csv` next time to come up already decrypting. > The CSV stores AES keys in plaintext — treat it like a password file.