summary refs log tree commit diff
path: root/nixos/modules/services/monitoring/prometheus/exporters/rtl_433.nix
blob: ef829a1b7d02e98e8a746dbdb439ceb1d7b69d8a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
{ config, lib, pkgs, options }:

let
  cfg = config.services.prometheus.exporters.rtl_433;
in
{
  port = 9550;

  extraOpts = let
    mkMatcherOptionType = field: description: with lib.types;
      listOf (submodule {
        options = {
          name = lib.mkOption {
            type = str;
            description = "Name to match.";
          };
          "${field}" = lib.mkOption {
            type = int;
            inherit description;
          };
          location = lib.mkOption {
            type = str;
            description = "Location to match.";
          };
        };
      });
  in
  {
    rtl433Flags = lib.mkOption {
      type = lib.types.str;
      default = "-C si";
      example = "-C si -R 19";
      description = ''
        Flags passed verbatim to rtl_433 binary.
        Having <literal>-C si</literal> (the default) is recommended since only Celsius temperatures are parsed.
      '';
    };
    channels = lib.mkOption {
      type = mkMatcherOptionType "channel" "Channel to match.";
      default = [];
      example = [
        { name = "Acurite"; channel = 6543; location = "Kitchen"; }
      ];
      description = ''
        List of channel matchers to export.
      '';
    };
    ids = lib.mkOption {
      type = mkMatcherOptionType "id" "ID to match.";
      default = [];
      example = [
        { name = "Nexus"; id = 1; location = "Bedroom"; }
      ];
      description = ''
        List of ID matchers to export.
      '';
    };
  };

  serviceOpts = {
    serviceConfig = {
      # rtl-sdr udev rules make supported USB devices +rw by plugdev.
      SupplementaryGroups = "plugdev";
      # rtl_433 needs rw access to the USB radio.
      PrivateDevices = lib.mkForce false;
      DeviceAllow = lib.mkForce "char-usb_device rw";
      RestrictAddressFamilies = [ "AF_NETLINK" ];

      ExecStart = let
        matchers = (map (m:
          "--channel_matcher '${m.name},${toString m.channel},${m.location}'"
        ) cfg.channels) ++ (map (m:
          "--id_matcher '${m.name},${toString m.id},${m.location}'"
        ) cfg.ids); in ''
        ${pkgs.prometheus-rtl_433-exporter}/bin/rtl_433_prometheus \
          -listen ${cfg.listenAddress}:${toString cfg.port} \
          -subprocess "${pkgs.rtl_433}/bin/rtl_433 -F json ${cfg.rtl433Flags}" \
          ${lib.concatStringsSep " \\\n  " matchers} \
          ${lib.concatStringsSep " \\\n  " cfg.extraFlags}
      '';
    };
  };
}