MQTT is a lightweight message protocol often used in IoT and home automation applications. It is very easy to get up and running. However once you have a larger number of devices communicating, it's easy to get in a pickle if you don't have a plan for how they will all communicate.
Here's the strategy I'm using at the moment.
Topics should be all lower case and contain only alphanumerics and hyphens. Whilst MQTT does support a wider set of characters in topic names than this, keeping it simple helps avoiding confusing errors in spacing and capitalisation.
Publishing status changes - Status topics
When a device changes state, it posts to a specific topic for that device and sensor. These are called status topics.
Other devices with interest in their status can monitor these topics.
Messages posted to these topics should be retained. This means that when a client connects to the broker it can receive information on the last known status of each device.
These topics have the following format.
Values posted to these topics should be simple text, boolean or integer values.
value -> home/s/<room-name>/<device-name>/<sensor-name>
Light is turned in the living room.
true -> home/s/living-room/light/on
Garage door is closed
false -> home/s/garage/door/open
Temperature changes to 19° in the study
19 -> home/s/study/temperature/value
Motion detected in the kitchen
true -> home/s/kitchen/motion/occupied
Issuing commands to devices - Command topics
We use the same protocol but substitute the
s for a
Turn on the living room light
true -> home/c/living-room/light/on
Examples using Node-RED, HomeBridge and a custom web app.
In my current setup I use Node-RED integrated with HomeBridge. I also have a web app that uses React and Redux that I use to monitor the house and turn devices on and off.
This describes the flow of messages and updates that make this work.
Example via Node-Red and HomeBridge
# Bedroom button pressed true -> home/c/bedroom/button/pressed # Node-Red receives command and issues update to HomeBridge # Node-Red receives state change update from HomeBridge and forwards to MQTT true -> home/s/bedroom/light/on # Web App monitors the channel and updates redux state # Light appears as on in the web app
Example via Web App and Node-Red
# Web App posts directly on command topic true -> home/c/living-room/lamp/on # Node-Red receives command and issues update to HomeBridge # Node-Red receives state change update from HomeBridge and forwards to MQTT true -> home/s/living-room/light/on # Web App monitors the channel and updates redux state # Light appears as on in the web app
I find this separation of command and status messages works well in managing the flow of messages and avoiding confusing deadlocks or infinte loops. The retained message feature of MQTT means that whenever a web client initialises the web app, they naturally get an up to date representation of the state of the house.