"The Homie convention defines a standardized way of how IoT devices and services announce themselves and their data on the MQTT broker."
This sentence improved my life.
If you are following my blog articles on home automation you might know that I am passionate about using Open Source solutions for operating these systems.
I have been configuring and modifying openHAB configuration files for my evolving home automation things and their many items. How I use MQTT topics has changed as I reinvented my own version of the wheel and created a buggy and hard to maintain mess for myself.
If my home was going to get smarter I needed to and copy evolved solutions and standards rather than invent my own again.
Example Homie Device with openHAB
How you implement Homie is up to you but your device needs to initialise (on start or communication error) and announce itself by describing its nodes and properties.
Here is an example of a device with a hot water tank node that has a thermostat and heater switch. The device also has a room sensor for temperature and humidity. It can describe itself and its properties by sending these MQTT Topics and Messages:
# Device description
homie/hotwatertank/$homie 4.0
homie/hotwatertank/$name Hot Water Tank Device
homie/hotwatertank/$state ready
homie/hotwatertank/$nodes watertank,sensor
homie/hotwatertank/watertank/$name Water Tank
homie/hotwatertank/watertank/$properties water,thermostat,heaterswitch
homie/hotwatertank/watertank/water/$name Water Temperature
homie/hotwatertank/watertank/water/$unit °C
homie/hotwatertank/watertank/water/$datatype float
homie/hotwatertank/watertank/water/$settable false
homie/hotwatertank/watertank/thermostat/$name Water Thermostat
homie/hotwatertank/watertank/thermostat/$unit °C
homie/hotwatertank/watertank/thermostat/$datatype float
homie/hotwatertank/watertank/thermostat/$settable true
homie/hotwatertank/watertank/heaterswitch/$name Heater Switch
homie/hotwatertank/watertank/heaterswitch/$datatype boolean
homie/hotwatertank/watertank/heaterswitch/$settable true
homie/hotwatertank/sensor/$name Room Sensor
homie/hotwatertank/sensor/$properties humidity,temperature
homie/hotwatertank/sensor/humidity/$name Humidity
homie/hotwatertank/sensor/humidity/$unit %
homie/hotwatertank/sensor/humidity/$datatype float
homie/hotwatertank/sensor/humidity/$settable false
homie/hotwatertank/sensor/temperature/$name Temperature
homie/hotwatertank/sensor/temperature/$unit °C
homie/hotwatertank/sensor/temperature/$datatype float
homie/hotwatertank/sensor/temperature/$settable false
This standard format allows openHAB to to auto-discover the new device.
The Homie properties are mapped into channels:
You can link these channels to your openHAB items. They will update their values when your device reports its state with MQTT Topics and Messages:
# Device state
homie/hotwatertank/$state ready
homie/hotwatertank/watertank/water 34.5
homie/hotwatertank/watertank/thermostat 20.0
homie/hotwatertank/watertank/heaterswitch false
homie/hotwatertank/sensor/humidity 76
homie/hotwatertank/sensor/temperature 18.8
The openHAB items can send command messages like this one to set the thermostat temperature to 18 degrees.
homie/hotwatertank/watertank/thermostat/set 18.0
Java Homie helper.
If you want to play along with Homie at home I have created a simple Homie Java project for use in IoT applications. Here is the code to generate the above messages to System.out:
// Init the device.
HomieDevice device = new HomieDevice("hotwatertank", "Hot Water Tank Device");
HomieNode tankNode = new HomieNode(device, "watertank", "Water Tank");
HomieTemperatureReadingProperty waterTemperature = new HomieTemperatureReadingProperty(tankNode, "water", "Water Temperature");
HomieTemperatureProperty thermostat = new HomieTemperatureProperty(tankNode, "thermostat", "Water Thermostat");
HomieSwitchProperty waterHeaterSwitch = new HomieSwitchProperty(tankNode, "heaterswitch", "Heater Switch");
HomieHumidityTemperatureReadingNode roomSensor = new HomieHumidityTemperatureReadingNode(device, "sensor", "Room Sensor");
// Send announcement messages to MQTT.
device.setState(DeviceState.ready);
for (Message message: device.getMessages()) {
System.out.println(message.toString());
}
// Handle control messages
tankNode.handleMessage(new Message("homie/hotwatertank/watertank/thermostat/set", "18.0"));
// Read sensors and perform logic...
waterTemperature.setValue(34.5);
waterHeaterSwitch.setValue(thermostat.getValue() > waterTemperature.getValue());
roomSensor.updateHumidityProperty(76);
roomSensor.updateTemperatureProperty(18.9);
// Report state
for (Message message: device.getStateMessages()) {
System.out.println(message.toString());
}
If you are interested in home automation then using MQTT with Homie standard messages is a great way to set up inter-device communication. If you think you have a good idea for your own MQTT topic convention then be warned that you may get very frustrated maintaining that idea...
I am always looking for better approaches to home automation and the adoption of the Homie convention was a simple and valuable improvement.