lol

nixos/mqtt2influxdb: init module

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