Switching out my home automation messaging infrastructure for MQTT
I am re-vamping my home automation strategy from a home grown publish/subscribe messaging system to use MQTT instead. I was using Azure Service Bus to connect remote devices such as my phone with devices in my home such as my lawn irrigation system. This worked well as a messaging infrastructure for remote devices but I wanted to have a more standard messaging infrastructure that could work in my home network without connectivity to the outside world.
A few reasons why I switched to MQTT:
- Light weight
- Many Clients already exist for many platforms and languages
- Netduino
- Arduino
- C#
- Linux
- Windows
- Support for on-premise message broker
- Support for off-premise message broker
- Support for bridging brokers (on-premise to off-premise)
- Fast
- Used by companies like COSM (was Pachube) and Github
- Simple topic subscription model that is also powerful
- I don’t want to write a message broker
For the most part I am moving toward having devices in the home that are relatively dumb and having services running on a home server that add the smarts behind the devices. This will give me the flexibility to change the behavior of the system a lot quicker without the hassle of tearing apart a device to upgrade the software on it. This means I needed to have my services available all the time. Placing these services in the cloud for mission critical things would mean I am left with devices in the home that cannot function while my internet connectivity is down. This was the biggest reason I moved to an off the self pub/sub infrastructure like MQTT.
Like most messaging protocols, MQTT works on the notion of a topic and a message. The topic is just a unique way of addressing a message. I struggled a lot and I probably will continue to struggle on what my topic structure for my home automation should look like. One thing I wanted to do is try to make the topics readable so that troubleshooting message problems would be easier. Hear are a few standards I am trying to settle on:
- When a device or service changes state and wishes to notify interested parties the topic will end with /event
- When a device or service wants to know the status of another device or service the topic will end with /getstatus
- When a device or service receives a topic /getstatus the response topic it generates will end with /status
- When a device or service needs to set the state of another device or service the topic will end with /set
Here are a few examples of topics and messages for my irrigation system:
Description | Topic | Message |
Zone 1 turned on | irrigation/zone/event | z1 On |
Request the current schedule from the irrigation service. The service will respond to this request by publishing various status topics | irrigation/schedule/getstatus | |
Set the time that the irrigation service should start watering | irrigation/schedule/starttime/set | 09:00 AM |
Status of the schedule start time in response to the getstatus request | irrigation/schedule/starttime/status | 09:00 AM |
Set the days of the week that the irrigation system will water | irrigation/schedule/days/set | MON WED FRI |
Status of the scheduled days of the week in response to the getstatus request | irrigation/schedule/days/status | MON WED FRI |
Set the zones that the irrigation system will run and how long | irrigation/schedule/zones/set | z1 10 z2 8 z3 10 |
Status of the scheduled zones in response to the getstatus request | irrigation/schedule/zones/status | z1 10 z2 8 z3 10 |
Sets the zones to run on the irrigation device and how long | irrigation/zones/run | z1 10 z2 8 z3 10 |
MQTT does have a concept of publishing messages with a retain bit. This just tells the broker to hang onto the last message for a topic and when a new subscription arrives the client will receive the last message. I could have used this concept instead of the /getstatus standard that I have show above. I might change over to using the retain bit but for now the /getstatus works for me. I am also making my messages a little verbose as they tend to contain multiple values that could have been broken down into more granular topics.
Overall I really like how simple MQTT is and it is very easy to get a device like the Netduino to understand MQTT messages. I am sure I will make modifications on how I actually define my topics and message body over time as I develop more and more devices and services that do useful stuf in my home.