Evolution of Architecture (Part 1)

My first contact with home automation came via MySensors, an project that combines Arduino with various sensors and NRF24L01+ wireless 2.4Ghz module. Lots of example code for both sensors and transmitter relays can be found on their site and thus deploying working prototype was quite straightforward. In just few hours of work I was able to construct simple wireless temperature sensor and it’s counterpart, a relay hub that receives temperature information wirelessly. I first used Dallas DS18B20 temperature sensor, but then decided to swap it to DHT22 that also gathers humidity values.

MySensors architecture supports plethora of home automation hubs where you can program the actual rules and behaviour of the system. Hub gathers data from sensors, can react to certain values and conditions and then manipulate lights, switches and other devices in the network. Also data storing and charting is possible. I decided to try out Openhab, a quite mature software package that supports various devices and protocols and seems to be quite popular in the DIY home automation scene. It’s written in Java and thus speed isn’t its best feature, but many people are running it in RaspBerry Pi so I figured it can’t be that slow. In fact running it wasn’t that bad and response times to stimuli were so-so but starting and re-starting the server took several minutes. So trying different settings by modifying openhab.cfg made me pull not-insignificant amount of hair out of my head. I will blame Openhab for my baldness later. Luckily Raspberry Pi 2 was released just few months ago and with its faster processor running Openhab turned out to be much nicer for my scalp.

MQTT magic

After some research I decided to pursue the first prototype:

Home automation architecture #1

Home automation architecture #1

MySensors supports most hubs via MQTT and the same goes for Openhab. There are lots of great tutorials around so I won’t go into details, but let’s just say that if there’s one protocol to consider, it’s MQTT. It’s a lightweight messaging protocol that follows publish-subscribe principle and allows devices on different platforms to talk to each other. Sensors can publish sensor data to MQTT message bus and automation hubs can subscribe to those messages. For example sensor might publish it’s temperature with following message:

topic: "/home/sensors/node02/temperature" msg:"23.50"

It’s also possible to control the devices (switching relays or turning on/off the lights) by sending MQTT messages as long as the device can talk MQTT (or there’s a translating gateway sitting between the MQTT bus and the target device). It’s nice to also configure sensors via MQTT: For example if you want to change the sensor update interval, you can just send a message to MQTT bus instead of going through the hassle of deploying a separate configuration tool that talks to the device, or even re-flashing the firmware via direct physical connection (there are wireless flashing solutions but that’s a subject of different post). In a nut-shell, MQTT is the glue that in optimal situation allows us to avoid tinkering with cumbersome ad-hoc DIY protocols as well as to prevent reliance on monolithic systems in which direct support for each device platform and protocol is required.

Do electromagnetic waves talk MQTT?

Now, how to get the sensors talking to Openhab via MQTT? Actually it’s best to not transmit MQTT messages wirelessly, but instead use some even simpler, fixed message structure from sensors to Sensor Relay, which then converts these messages to actual MQTT messages to be sent to MQTT server. This requires little bit more coding on the Sensor Gateway side, but then makes it possible to off-load all the MQTT message parsing and publish/subscribe logic from sensors to the relay. MQTT is simple but not THAT simple, and these low-power and low-memory sensors are best to be kept as simple as possible for obvious reasons. MySensors has a published a simple Arduino MQTT Gateway Broker sketch that can work almost straight out-of-the box with minimal code changes. It is actually a small MQTT server itself, but is not as robust as I would’ve liked, so I decided to install Mosquitto MQTT server on Raspberry Pi that works as a main MQTT hub. Mosquitto was then configured to work as a bridge with Arduino Gateway, i.e. it connects to the Arduino gateway as any normal client, subscribes to all relevant topics (sent by sensors) and publishes then all the messages coming from other devices. Bridging can be done by modifying /etc/mosquitto.conf and adding following snippet:

connection mysensors_mqtt
topic # both MySensors/ /

This subscribes to all topics (#) and replaces ‘/’ with ‘MySensors/’ in topics coming from Arduino Sensor Gateway and vice-versa. This topic translation makes it easier to distinguish MySensors MQTT messages from other MQTT traffic.

Adding the sensors to Openhab is then pretty straightforward: First install and configure mqtt add-on, then add each sensor sub-device as a MQTT source by editing /opt/openhab/configuration/items/default.items like this:

Contact Bathroom_Motion_Sensor {mqtt="<[mosquitto:MySensors/20/0/V_TRIPPED:state:default]"}
Number Bathroom_Temperature "Bathroom temperature [%.1f C]" {mqtt="<[mosquitto:MySensors/20/1/V_TEMP:state:default]"}
Number Bathroom_Humidity "Bathroom humidity [%.1f %%]" {mqtt="<[mosquitto:MySensors/20/2/V_HUM:state:default]"}

Of course these are just examples, and you have the  modify the MQTT topics above to match those that your sensors are sending.  Sniffing the MQTT traffic is easy with mosquitto_pub:

pi@raspberrypi /home/pi $ mosquitto_sub -v -t MySensors/#

For some reason “-t #” is not accepted, but “-t /#” is, but the latter does match only messages beginning with ‘/’, so if you want to subscribe to absolutely all messages, the ‘#’ must be closed inside quotation marks:

pi@raspberrypi /home/pi $ mosquitto_sub -v -t "#"

Next topic: Actually doing something practical with the sensors. Stay tuned!

Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *