1{
2 config,
3 lib,
4 pkgs,
5 options,
6 utils,
7}:
8
9let
10 inherit (lib)
11 mkIf
12 mkEnableOption
13 mkOption
14 types
15 ;
16 cfg = config.services.prometheus.exporters.mqtt;
17 toConfigBoolean = x: if x then "True" else "False";
18 toConfigList = builtins.concatStringsSep ",";
19in
20{
21 # https://github.com/kpetremann/mqtt-exporter/tree/master?tab=readme-ov-file#configuration
22 port = 9000;
23 extraOpts = {
24 keepFullTopic = mkEnableOption "Keep entire topic instead of the first two elements only. Usecase: Shelly 3EM";
25 logLevel = mkOption {
26 type = types.enum [
27 "CRITICAL"
28 "ERROR"
29 "WARNING"
30 "INFO"
31 "DEBUG"
32 ];
33 default = "INFO";
34 example = "DEBUG";
35 description = "Logging level";
36 };
37 logMqttMessage = mkEnableOption "Log MQTT original message, only if `LOG_LEVEL` is set to DEBUG.";
38 mqttIgnoredTopics = mkOption {
39 type = types.listOf types.str;
40 default = [ ];
41 description = "Lists of topics to ignore. Accepts wildcards.";
42 };
43 mqttAddress = mkOption {
44 type = types.str;
45 default = "127.0.0.1";
46 description = "IP or hostname of MQTT broker.";
47 };
48 mqttPort = mkOption {
49 type = types.port;
50 default = 1883;
51 description = "TCP port of MQTT broker.";
52 };
53 mqttTopic = mkOption {
54 type = types.str;
55 default = "#";
56 description = "Topic path to subscribe to.";
57 };
58 mqttKeepAlive = mkOption {
59 type = types.int;
60 default = 60;
61 example = 30;
62 description = "Keep alive interval to maintain connection with MQTT broker.";
63 };
64 mqttUsername = mkOption {
65 type = types.nullOr types.str;
66 default = null;
67 example = "mqttexporter";
68 description = "Username which should be used to authenticate against the MQTT broker.";
69 };
70 mqttV5Protocol = mkEnableOption "Force to use MQTT protocol v5 instead of 3.1.1.";
71 mqttClientId = mkOption {
72 type = types.nullOr types.str;
73 default = null;
74 description = "Set client ID manually for MQTT connection";
75 };
76 mqttExposeClientId = mkEnableOption "Expose the client ID as a label in Prometheus metrics.";
77 prometheusPrefix = mkOption {
78 type = types.str;
79 default = "mqtt_";
80 description = "Prefix added to the metric name.";
81 };
82 topicLabel = mkOption {
83 type = types.str;
84 default = "topic";
85 description = "Define the Prometheus label for the topic.";
86 };
87 zigbee2MqttAvailability = mkEnableOption "Normalize sensor name for device availability metric added by Zigbee2MQTT.";
88 zwaveTopicPrefix = mkOption {
89 type = types.str;
90 default = "zwave/";
91 description = "MQTT topic used for Zwavejs2Mqtt messages.";
92 };
93 esphomeTopicPrefixes = mkOption {
94 type = types.listOf types.str;
95 default = [ ];
96 description = "MQTT topic used for ESPHome messages.";
97 };
98 hubitatTopicPrefixes = mkOption {
99 type = types.listOf types.str;
100 default = [ "hubitat/" ];
101 description = "MQTT topic used for Hubitat messages.";
102 };
103 environmentFile = mkOption {
104 type = types.nullOr types.path;
105 default = null;
106 example = [ "/run/secrets/mqtt-exporter" ];
107 description = ''
108 File to load as environment file. Useful for e.g. setting `MQTT_PASSWORD`
109 without putting any secrets into the Nix store.
110 '';
111 };
112 };
113 serviceOpts = {
114 environment = {
115 KEEP_FULL_TOPIC = toConfigBoolean cfg.keepFullTopic;
116 LOG_LEVEL = cfg.logLevel;
117 LOG_MQTT_MESSAGE = toConfigBoolean cfg.logMqttMessage;
118 MQTT_IGNORED_TOPIC = toConfigList cfg.mqttIgnoredTopics;
119 MQTT_ADDRESS = cfg.mqttAddress;
120 MQTT_PORT = toString cfg.mqttPort;
121 MQTT_TOPIC = cfg.mqttTopic;
122 MQTT_KEEPALIVE = toString cfg.mqttKeepAlive;
123 MQTT_USERNAME = cfg.mqttUsername;
124 MQTT_V5_PROTOCOL = toConfigBoolean cfg.mqttV5Protocol;
125 MQTT_CLIENT_ID = mkIf (cfg.mqttClientId != null) cfg.mqttClientId;
126 PROMETHEUS_ADDRESS = cfg.listenAddress;
127 PROMETHEUS_PORT = toString cfg.port;
128 PROMETHEUS_PREFIX = cfg.prometheusPrefix;
129 TOPIC_LABEL = cfg.topicLabel;
130 ZIGBEE2MQTT_AVAILABILITY = toConfigBoolean cfg.zigbee2MqttAvailability;
131 ZWAVE_TOPIC_PREFIX = cfg.zwaveTopicPrefix;
132 ESPHOME_TOPIC_PREFIXES = toConfigList cfg.esphomeTopicPrefixes;
133 HUBITAT_TOPIC_PREFIXES = toConfigList cfg.hubitatTopicPrefixes;
134 };
135 serviceConfig = {
136 EnvironmentFile = mkIf (cfg.environmentFile != null) cfg.environmentFile;
137 ExecStart = lib.getExe pkgs.mqtt-exporter;
138 };
139 };
140}