fork with docker support and enhanced configuration possibilities
version: '3'
services:
mqtt-launcher:
container_name: mqtt-launcher
image: ilmlv/mqtt-launcher:latest
volumes:
- ./mqtt-launcher/launcher.conf:/mqtt-launcher/launcher.conf
#- /var/log/mqtt-launcher.log:/mqtt-launcher/logfile # create local file before enabling it
#environment:
# APT_INSTALL: <all linux packages> # default: none
# PIP_INSTALL: <all necessary python packages> # default: none
# APT_UPDATE: true # default: false
# PIP_UPDATE: true # default: false
#devices:
# - /dev/snd:/dev/snd # enable if sound output is necessary
restart: unless-stopped
docker run -ti --rm -v ./launcher.conf:/mqtt-launcher/launcher.conf ilmlv/mqtt-launcher:latest
mqtt-launcher is a Python program which subscribes to a set of MQTT topics and executes processes on the host it's running on. Launchable processes are configured on a per/wildcard basis, and they can be constrained to run only if a particular text payload is contained in the message.
For example, I can publish a message to my MQTT broker requesting mqtt-launcher create a particular semaphore file for me:
mosquitto_pub -t prefix/sys/file -m create
The configuration file must be valid Python and it is loaded once. It contains the topic / process associations. MQTT topic prefix will be automatically added.
# topic payload value program & arguments
"sys/file" : {
'create' : [ '/usr/bin/touch', '/tmp/file.one' ],
'false' : [ '/bin/rm', '-f', '/tmp/file.one' ],
'info' : [ '/bin/ls', '-l', '/tmp/file.one' ],
},
'play-sound/doorbell' : {
None : [ '/bin/bash', '-c', 'nohup mpg123 -q -f -2000 /mqtt-launcher/files/doorbell.mp3 &>/dev/null &' ],
},
Above snippet instructs mqtt-launcher to:
- subscribe to the MQTT topic
prefix/sys/file
- look up the payload string and launch the associated programs:
- if the payload is
create
, then touch a file - if the payload is the string
false
, remove a file - if the payload is
info
, return information on the file
- if the payload is
The payload value may be None
in which case the eacho of the list elements
defining the program and arguments are checked for the magic string @!@
which
is replaced by the payload contents. (See example published at prefix/dev/2
, prefix/dev/3
and prefix/dev/4
below.)
mqtt-launcher publishes stdout and stderr of the launched program
to the configured topic with /report
added to it. So, in the example
above, a non-retained message will be published to prefix/sys/file/report
.
(Note that this message contains whatever the command outputs; trailing
white space is truncated.)
Here's the obligatory "screenshot".
Publishes Subscribes
----------------------- ------------------------------------------------------------------
$ mosquitto_sub -v -t 'prefix/dev/#' -t 'prefix/sys/file/#' -t 'prefix/prog/#'
mosquitto_pub -t prefix/prog/pwd -n
prefix/prog/pwd (null)
prefix/prog/pwd/report /private/tmp
mosquitto_pub -t prefix/sys/file -m create
prefix/sys/file create
prefix/sys/file/report (null) # command has no output
mosquitto_pub -t prefix/sys/file -m info
prefix/sys/file info
prefix/sys/file/report -rw-r--r-- 1 jpm wheel 0 Jan 22 16:10 /tmp/file.one
mosquitto_pub -t prefix/sys/file -m remove
prefix/sys/file remove
# report not published: subcommand ('remove') doesn't exist
# log file says:
2014-01-22 16:11:30,393 No matching param (remove) for sys/file
mosquitto_pub -t prefix/dev/1 -m hi
prefix/dev/1 hi
prefix/dev/1/report total 16231
drwxrwxr-x+ 157 root admin 5338 Jan 20 10:48 Applications
drwxrwxr-x@ 8 root admin 272 Jan 25 2013 Developer
drwxr-xr-x+ 72 root wheel 2448 Oct 14 10:54 Library
...
mosquitto_pub -t prefix/dev/2 -m 'Hi Jane!'
prefix/dev/2 Hi Jane!
prefix/dev/2/report 111 * Hi Jane! 222 Hi Jane! 333
mosquitto_pub -t prefix/dev/3 -m 'foo-bar'
prefix/dev/3 foo-bar
prefix/dev/3/report foo-bar
mosquitto_pub -t prefix/dev/4 -m 'foo/bar'
prefix/dev/4 foo/bar
prefix/dev/4/report var1=foo var2=bar
mqtt-launcher loads a Python configuration from the path contained in
the environment variable $MQTTLAUNCHERCONFIG
; if unset, the path
defaults to launcher.conf
. See the provided launcher.conf.example
.
mqtt-launcher logs its operation in the file configured as logfile
.
- Python
- paho-mqtt
This program was inspired by two related tools:
- Peter van Dijk's mqtt-spawn
- Dennis Schulte's mqtt-exec. (I'm not terribly comfortable running NodeJS programs, so I implemented the idea in Python.)