Part 2 of 2: Wireless Arduino sensors for Home Automation w/ OpenHAB – details on data structs
Post 2 of 2 on the topic of Arduino and openHAB for home automation and wireless sensors. Click here to see the first post for the general background information, and also for the actual Arduino sketches that implements this setup. This second post gives more detail regarding MQTT binding between my wireless Arduino sensor and OpenHAB. Read up on how to install Mosquitto here, and the basics of the MQTT protocol here.
Goal: We want the Arduino Gateways (both the RFM Gateway and the Ethernet Gateway) to just work. We don’t want to have to constantly change the sketches on the gateway Arduinos just because we add a new sensor node or add a new device on an existing sensor node. We also don’t want to double manage things. I hope to explain how this double management problem occurs and how to minimize it.
I’ll reuse the communication diagram from the previous post, and reiterate that the “Arduino Gateway” is actually composed of two Arduinos (RFM gateway and Ethernet gateway).
MQTT Message = <topic name> & <data>
topic name = “Topic_Garage_Temperature”
data = 75.2
A MQTT message is composed of two parts: the topic name, and the data itself. With MQTT, there does not seem to be any data types like int and float. On the Ethernet Arduino, you take the floats and ints you get from the sensors, convert them to strings, and send the string off to the MQTT library to be magically sent via ethernet to Mosquitto. Here is a very simplified setup. Click to enlarge.
But this method might be too simple. Using this setup, every time you add a field node, you’ll have to reprogram the two gateway Arduinos in order to account for the new topic name. It’s a pain to have the gateway Arduino sketches identify and convert each field node’s transmission into a unique topic name. You’re managing topic names in both gateway Arduinos and also in OpenHAB. Too many things to go wrong.
Using the RFM69 library, each Arduino is assigned unique Node ID. The Node ID doesn’t have to be an integer, but let’s stick with integers for now.
#define NODEID 40 //unique for each node on same network
You’re responsible for making sure your Node ID’s are unique, so keep a spread sheet of which Arduinos are using which Node ID’s. I’m taking advantage of this unique node ID in order to form parts of the topic name. Hopefully this picture explains a thousand words.
Since each field node knows its own node ID (because you assigned it), we’ll embed the unique Node ID into the data structure we defined for wireless transmission. The field Arduino also knows how many sensor devices are connected to it, so we might as well also embed an integer to capture this arbitrarily assigned Device ID. And because we have the freedom to define the wireless transmission structure, we can capture more than one piece of data per transmission, and determine what each data type means on a field node to field node basis. So there’s Var1 (unsigned long int) that can be the millisecond counter, Var2 (float) that can hold the temperature data or whatever, and Var3 (also a float) that can be used eventually for battery power of the field node.
Each time the Arduino Ethernet Gateway receives new data, it actually sends several MQTT messages, one for each of the variables we’re interested in. You’ll notice that not all the data from the wireless transmission struct is actually being sent to MQTT. Only Var2 and Var3 (both floats) are sent to MQTT. Partly because I got lazy. I initially thought I’d care about the millisecond count, but it turned out not to be the case.
The RSSI variable is the wireless transmission strength. See this image. Only the Arduino RFM Gateway knows this information, which is why it injects a new data type, int, to capture the RSSI.
Here’s an example of how I keep track of all the ID’s and topic names.