{ description = "SDR toolbox — programs for exploring an RTL-SDR stick"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; }; outputs = { self, nixpkgs }: let system = "x86_64-linux"; pkgs = nixpkgs.legacyPackages.${system}; lib = pkgs.lib; # rtl_wmbus: demodulator that turns raw rtl_sdr I/Q into wM-Bus frames. # Not in nixpkgs, so build from source (tiny pure-C project). rtl_wmbus = pkgs.stdenv.mkDerivation { pname = "rtl-wmbus"; version = "1.1.0"; src = pkgs.fetchFromGitHub { owner = "xaelsouth"; repo = "rtl-wmbus"; rev = "1.1.0"; sha256 = "1f9psbakvi0ymqmlbbnn96cbvd3bfphc90hw6xwid6r184pnzac6"; }; enableParallelBuilding = true; installPhase = '' runHook preInstall install -Dm755 build/rtl_wmbus $out/bin/rtl_wmbus runHook postInstall ''; meta.description = "Software defined receiver for wireless M-Bus with RTL-SDR"; }; # wmbusmeters: reads/decodes wM-Bus (OMS) smart-meter telegrams. Dropped # from nixpkgs, so build from source. At runtime it shells out to # rtl_sdr | rtl_wmbus, so wrap those onto its PATH. wmbusmeters = pkgs.stdenv.mkDerivation { pname = "wmbusmeters"; version = "3.0.0"; src = pkgs.fetchFromGitHub { owner = "wmbusmeters"; repo = "wmbusmeters"; rev = "3.0.0"; sha256 = "1nnirlnb12zdadsvsybj8h2g6fy7hc7ih488i2qaxzinm1faxagp"; }; nativeBuildInputs = [ pkgs.pkg-config pkgs.makeWrapper ]; buildInputs = [ pkgs.rtl-sdr pkgs.libusb1 pkgs.libxml2 ]; enableParallelBuilding = true; postPatch = '' patchShebangs scripts ''; installPhase = '' runHook preInstall install -Dm755 build/wmbusmeters $out/bin/wmbusmeters ln -s wmbusmeters $out/bin/wmbusmetersd wrapProgram $out/bin/wmbusmeters \ --prefix PATH : ${lib.makeBinPath [ pkgs.rtl-sdr rtl_wmbus ]} runHook postInstall ''; meta.description = "Read wM-Bus / OMS smart meters (water, heat, gas, electricity)"; }; # oms-tui: full-screen TUI for monitoring OMS / wM-Bus meters. Wraps # wmbusmeters (put on PATH) and adds a live device list, detail view, # live AES-key entry, and CSV export/import. oms-tui = pkgs.python3Packages.buildPythonApplication { pname = "oms-tui"; version = "0.1.0"; pyproject = true; src = ./oms-tui; build-system = [ pkgs.python3Packages.setuptools ]; dependencies = [ pkgs.python3Packages.textual ]; nativeBuildInputs = [ pkgs.makeWrapper ]; nativeCheckInputs = [ pkgs.python3Packages.pytestCheckHook pkgs.python3Packages.pytest-asyncio wmbusmeters # exercises the real decode pipeline in the test suite ]; postFixup = '' wrapProgram $out/bin/oms-tui \ --prefix PATH : ${lib.makeBinPath [ wmbusmeters ]} ''; meta.description = "TUI monitor for OMS / wireless M-Bus smart meters"; }; # wmbus-listen: convenience wrapper around wmbusmeters for OMS discovery. wmbus-listen = pkgs.writeShellApplication { name = "wmbus-listen"; runtimeInputs = [ wmbusmeters ]; text = '' # Listen for wM-Bus / OMS smart-meter telegrams on 868.95 MHz via RTL-SDR. # # Usage: # wmbus-listen # discovery: show every telegram heard # wmbus-listen NAME DRIVER ID KEY # decode one meter's readings # e.g. wmbus-listen Water multical21 12345678 00112233445566778899AABBCCDDEEFF # # Env overrides: # WMBUS_MODES link modes to listen for (default: c1,t1 — typical OMS) # WMBUS_FORMAT output format: json | fields | hr (default: json) modes="''${WMBUS_MODES:-c1,t1}" format="''${WMBUS_FORMAT:-json}" if [ "$#" -eq 0 ]; then echo "Listening for OMS/wM-Bus telegrams (modes: $modes) on 868.95 MHz. Ctrl-C to stop." >&2 echo "Unknown meters are printed as they are heard — note their id/driver to decode them." >&2 exec wmbusmeters --format="$format" --listento="$modes" --verbose rtlwmbus else exec wmbusmeters --format="$format" --listento="$modes" rtlwmbus "$@" fi ''; }; sdrTools = (with pkgs; [ rtl-sdr # rtl_test, rtl_fm, rtl_power — verify the stick works first sdrpp # modern spectrum browser with waterfall (run: sdrpp) gqrx # classic beginner-friendly waterfall receiver rtl_433 # decode 433/868 MHz sensors: weather stations, doorbells, meters dump1090-fa # ADS-B aircraft tracking on 1090 MHz with a live web map multimon-ng # decode POCSAG pagers, AFSK, DTMF (pipe rtl_fm into it) welle-io # DAB+ digital radio satdump # NOAA/Meteor weather satellite images noaa-apt # simple NOAA APT satellite image decoder # Heavier options — uncomment if wanted: # sdrangel # kitchen-sink SDR app, many digital modes # gnuradio # build your own DSP flowgraphs ]) ++ [ rtl_wmbus # wM-Bus demodulator (rtl_sdr | rtl_wmbus) wmbusmeters # decode OMS smart meters wmbus-listen # convenience: listen for OMS telegrams (see below) oms-tui # full-screen OMS monitor TUI ]; in { devShells.${system}.default = pkgs.mkShell { packages = sdrTools; shellHook = '' echo "SDR shell ready. Start with: rtl_test (OMS meters: wmbus-listen)" ''; }; packages.${system} = { inherit rtl_wmbus wmbusmeters wmbus-listen oms-tui; default = oms-tui; # Also expose the whole toolbox as one installable package set: # nix profile install .#sdr-tools sdr-tools = pkgs.buildEnv { name = "sdr-tools"; paths = sdrTools; }; }; }; }