# MQTTR MQTTR (named for "MQTT Router") is a MQTT router (duh) which lets you subscribe to MQTT topics and execute arbitrary programs when a message matching that topic arrives. It is the successor of [MQTTT](https://the-tk.com/cgit/mqttt/about/) which was the result of realising that using a filesystem hierarchy to represent the configuration did not appear to have any particular benefits over just storing the information in the already existing config file. ## Building and Installation Use `cargo build` as normal. The `SYSCONFDIR` environment variable controls the location of where `mqttr.toml` is searched. The default is `/usr/local/etc`. Once built, the `mqttr` program (found in `target/{debug,release}/mqttr`) should be located in some sensible place (e.g. `/usr/local/bin/mqttr`) and configured as a system service. `mqttr` does not have a way to double-fork, if you need this behaviour, use `daemon` or some equivalent utility. ## Configuration Create a `mqttr.toml` in the appropriate location. The file should contain at minimum a set of routes. The following is the default configuration: ```toml host = "localhost" # MQTT server host port = 1883 # MQTT server port # [credentials] # Uncomment to specify MQTT connection credentials # username = "username" # password = "password" id = "mqttr" # MQTT client identifier (combined as "${id}_$PID") ``` The routes follow the following format: ```toml [routes] "zigbee2mqtt/+/light" = [ ["/path/to/program"], ["/path/to/another/program", "with", "args"], ] "foo/bar/baz" = [ ... ] ``` On startup, `mqttr` will read the config file and subscribe to all the topics. When a message is received, `mqttr` will match the message topic against the routes and execute every program which is part of a matching route. Each program will have the message topic as well as the DUP, QoS, RETAIN and Packet Identifier (when applicable) appended as an additional arguments (in that order) and will receive the message on stdin. An example program is this script: ```bash #!/usr/bin/env bash topic=$1 dup=$2 qos=$3 retain=$4 ((qos == 1 || qos == 2)) && pkid=$5 action=$(jq --raw-output .action) [[ $action == "toggle" ]] || exit 0 mosquitto_pub --topic "zigbee2mqtt/light/set" --message '{"state":"TOGGLE"}' ``` This can be bound to a topic such as `zigbee2mqtt/light` which would result in it being ran every time a new MQTT message is published to this topic. ## Missing Features * Configurable timeouts (eventually configurable per process) * Configurable QoS for each subscription (default is 0 (at most once)) * Configurable logging * Ability to configure programs with non-UTF-8 in paths * Maybe config reloading on SIGHUP * TLS * mTLS