at 25.11-pre 7.3 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.services.mqtt2influxdb; 9 filterNull = lib.filterAttrsRecursive (n: v: v != null); 10 configFile = (pkgs.formats.yaml { }).generate "mqtt2influxdb.config.yaml" (filterNull { 11 inherit (cfg) mqtt influxdb; 12 points = map filterNull cfg.points; 13 }); 14 15 pointType = lib.types.submodule { 16 options = { 17 measurement = lib.mkOption { 18 type = lib.types.str; 19 description = "Name of the measurement"; 20 }; 21 topic = lib.mkOption { 22 type = lib.types.str; 23 description = "MQTT topic to subscribe to."; 24 }; 25 fields = lib.mkOption { 26 type = lib.types.submodule { 27 options = { 28 value = lib.mkOption { 29 type = lib.types.str; 30 default = "$.payload"; 31 description = "Value to be picked up"; 32 }; 33 type = lib.mkOption { 34 type = with lib.types; nullOr str; 35 default = null; 36 description = "Type to be picked up"; 37 }; 38 }; 39 }; 40 description = "Field selector."; 41 }; 42 tags = lib.mkOption { 43 type = with lib.types; attrsOf str; 44 default = { }; 45 description = "Tags applied"; 46 }; 47 }; 48 }; 49 50 defaultPoints = [ 51 { 52 measurement = "temperature"; 53 topic = "node/+/thermometer/+/temperature"; 54 fields.value = "$.payload"; 55 tags = { 56 id = "$.topic[1]"; 57 channel = "$.topic[3]"; 58 }; 59 } 60 { 61 measurement = "relative-humidity"; 62 topic = "node/+/hygrometer/+/relative-humidity"; 63 fields.value = "$.payload"; 64 tags = { 65 id = "$.topic[1]"; 66 channel = "$.topic[3]"; 67 }; 68 } 69 { 70 measurement = "illuminance"; 71 topic = "node/+/lux-meter/0:0/illuminance"; 72 fields.value = "$.payload"; 73 tags = { 74 id = "$.topic[1]"; 75 }; 76 } 77 { 78 measurement = "pressure"; 79 topic = "node/+/barometer/0:0/pressure"; 80 fields.value = "$.payload"; 81 tags = { 82 id = "$.topic[1]"; 83 }; 84 } 85 { 86 measurement = "co2"; 87 topic = "node/+/co2-meter/-/concentration"; 88 fields.value = "$.payload"; 89 tags = { 90 id = "$.topic[1]"; 91 }; 92 } 93 { 94 measurement = "voltage"; 95 topic = "node/+/battery/+/voltage"; 96 fields.value = "$.payload"; 97 tags = { 98 id = "$.topic[1]"; 99 }; 100 } 101 { 102 measurement = "button"; 103 topic = "node/+/push-button/+/event-count"; 104 fields.value = "$.payload"; 105 tags = { 106 id = "$.topic[1]"; 107 channel = "$.topic[3]"; 108 }; 109 } 110 { 111 measurement = "tvoc"; 112 topic = "node/+/voc-lp-sensor/0:0/tvoc"; 113 fields.value = "$.payload"; 114 tags = { 115 id = "$.topic[1]"; 116 }; 117 } 118 ]; 119in 120{ 121 options = { 122 services.mqtt2influxdb = { 123 enable = lib.mkEnableOption "BigClown MQTT to InfluxDB bridge"; 124 package = lib.mkPackageOption pkgs [ "python3Packages" "mqtt2influxdb" ] { }; 125 environmentFiles = lib.mkOption { 126 type = lib.types.listOf lib.types.path; 127 default = [ ]; 128 example = [ "/run/keys/mqtt2influxdb.env" ]; 129 description = '' 130 File to load as environment file. Environment variables from this file 131 will be interpolated into the config file using envsubst with this 132 syntax: `$ENVIRONMENT` or `''${VARIABLE}`. 133 This is useful to avoid putting secrets into the nix store. 134 ''; 135 }; 136 mqtt = { 137 host = lib.mkOption { 138 type = lib.types.str; 139 default = "127.0.0.1"; 140 description = "Host where MQTT server is running."; 141 }; 142 port = lib.mkOption { 143 type = lib.types.port; 144 default = 1883; 145 description = "MQTT server port."; 146 }; 147 username = lib.mkOption { 148 type = with lib.types; nullOr str; 149 default = null; 150 description = "Username used to connect to the MQTT server."; 151 }; 152 password = lib.mkOption { 153 type = with lib.types; nullOr str; 154 default = null; 155 description = '' 156 MQTT password. 157 158 It is highly suggested to use here replacement through 159 environmentFiles as otherwise the password is put world readable to 160 the store. 161 ''; 162 }; 163 cafile = lib.mkOption { 164 type = with lib.types; nullOr path; 165 default = null; 166 description = "Certification Authority file for MQTT"; 167 }; 168 certfile = lib.mkOption { 169 type = with lib.types; nullOr path; 170 default = null; 171 description = "Certificate file for MQTT"; 172 }; 173 keyfile = lib.mkOption { 174 type = with lib.types; nullOr path; 175 default = null; 176 description = "Key file for MQTT"; 177 }; 178 }; 179 influxdb = { 180 host = lib.mkOption { 181 type = lib.types.str; 182 default = "127.0.0.1"; 183 description = "Host where InfluxDB server is running."; 184 }; 185 port = lib.mkOption { 186 type = lib.types.port; 187 default = 8086; 188 description = "InfluxDB server port"; 189 }; 190 database = lib.mkOption { 191 type = lib.types.str; 192 description = "Name of the InfluxDB database."; 193 }; 194 username = lib.mkOption { 195 type = with lib.types; nullOr str; 196 default = null; 197 description = "Username for InfluxDB login."; 198 }; 199 password = lib.mkOption { 200 type = with lib.types; nullOr str; 201 default = null; 202 description = '' 203 Password for InfluxDB login. 204 205 It is highly suggested to use here replacement through 206 environmentFiles as otherwise the password is put world readable to 207 the store. 208 ''; 209 }; 210 ssl = lib.mkOption { 211 type = lib.types.bool; 212 default = false; 213 description = "Use SSL to connect to the InfluxDB server."; 214 }; 215 verify_ssl = lib.mkOption { 216 type = lib.types.bool; 217 default = true; 218 description = "Verify SSL certificate when connecting to the InfluxDB server."; 219 }; 220 }; 221 points = lib.mkOption { 222 type = lib.types.listOf pointType; 223 default = defaultPoints; 224 description = "Points to bridge from MQTT to InfluxDB."; 225 }; 226 }; 227 }; 228 229 config = lib.mkIf cfg.enable { 230 systemd.services.bigclown-mqtt2influxdb = 231 let 232 envConfig = cfg.environmentFiles != [ ]; 233 finalConfig = if envConfig then "$RUNTIME_DIRECTORY/mqtt2influxdb.config.yaml" else configFile; 234 in 235 { 236 description = "BigClown MQTT to InfluxDB bridge"; 237 wantedBy = [ "multi-user.target" ]; 238 wants = lib.mkIf config.services.mosquitto.enable [ "mosquitto.service" ]; 239 preStart = '' 240 umask 077 241 ${pkgs.envsubst}/bin/envsubst -i "${configFile}" -o "${finalConfig}" 242 ''; 243 serviceConfig = { 244 EnvironmentFile = cfg.environmentFiles; 245 ExecStart = "${lib.getExe cfg.package} -dc ${finalConfig}"; 246 RuntimeDirectory = "mqtt2influxdb"; 247 }; 248 }; 249 }; 250}