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 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:
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:
[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:
#!/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 2 (exactly once))
- Configurable logging
- Ability to configure programs with non-UTF-8 in paths
- Maybe config reloading on SIGHUP
- TLS
- mTLS