I’ve been thinking about trying to sort out some home automation bits. I’ve moved from having a 7 day heating timer to a 24 hour timer and I’d forgotten how annoying that is at weekends. I’d like to monitor temperatures in various rooms and use that, along with presence detection, to be a bit more intelligent about turning the heat on. Equally I wouldn’t mind tying my Alexa in to do some voice control of lighting (eventually maybe even using DeepSpeech to keep everything local).
Before all of that I need to get the basics in place. This is the first in a series of posts about putting together the right building blocks to allow some useful level of home automation / central control. The first step is working out how to glue everything together. A few years back someone told me MQTT was the way forward for IoT applications, being more lightweight than a RESTful interface and thus better suited to small devices. At the time I wasn’t convinced, but it seems they were right and MQTT is one of the more popular ways of gluing things together.
I found the HiveMQ series on MQTT Essentials to be a pretty good intro; my main takeaway was that MQTT allows for a single message broker to enable clients to publish data and multiple subscribers to consume that data. TLS is supported for secure data transfer and there’s a whole bunch of different brokers and client libraries available. The use of a broker is potentially helpful in dealing with firewalling; clients and subscribers only need to talk to the broker, rather than requiring any direct connection.
With all that in mind I decided to set up a broker to play with the basics. I made the decision that it should run on my OpenWRT router - all the devices I want to hook up can easily see that device, and if it’s down then none of them are going to be able to get to a broker hosted anywhere else anyway. I’d seen plenty of info about Mosquitto and it’s already in the OpenWRT package repository. So I sorted out a Let’s Encrypt cert, installed Moquitto and created a couple of test users:
opkg install mosquitto-ssl mosquitto_passwd -b /etc/mosquitto/mosquitto.users user1 foo mosquitto_passwd -b /etc/mosquitto/mosquitto.users user2 bar chown mosquitto /etc/mosquitto/mosquitto.users chmod 600 /etc/mosquitto/mosquitto.users
I then edited
/etc/mosquitto/mosquitto.conf and made sure the following are set. In particular you need
cafile set in order to enable TLS:
port 8883 cafile /etc/ssl/lets-encrypt-x3-cross-signed.pem certfile /etc/ssl/mqtt.crt keyfile /etc/ssl/mqtt.key log_dest syslog allow_anonymous false password_file /etc/mosquitto/mosquitto.users acl_file /etc/mosquitto/mosquitto.acl
Finally I created
/etc/mosquitto/mosquitto.acl with the following:
user user1 topic readwrite # user user2 topic read ro/# topic readwrite test/#
That gives me
user1 who has full access to everything, and
user2 with readonly access to the
ro/ tree and read/write access to the
To test everything was working I installed
mosquitto-clients on a Debian test box and in one window ran:
mosquitto_sub -h mqtt-host -p 8883 --capath /etc/ssl/certs/ -v -t '#' -u user1 -P foo
and in another:
mosquitto_pub -h mqtt-host -p 8883 --capath /etc/ssl/certs/ -t 'test/message' -m 'Hello World!' -u user2 -P bar
--capath it’ll try a plain TCP connection rather than TLS, and not produce a useful error message) which resulted in the
mosquitto_sub instance outputting:
test/message Hello World!
mosquitto_pub -h mqtt-host -p 8883 --capath /etc/ssl/certs/ -t 'test2/message' -m 'Hello World!' -u user2 -P bar
resulted in no output due to the ACL preventing it. All good and ready to actually make use of - of which more later.