Homie: An MQTT Convention for IoT/M2M
Version: [develop] [v1.5.0] [v2.0.0] [v2.0.1] [v3.0.0] [v3.0.1] [v4.0.0]
Changes: [Diff to previous]
Release date: 25. March 2018
Frequently asked questions
How do I query/request a property?
You don’t. The MQTT protocol does not implement the request-reply but rather the publish-subscribe messaging pattern. The Homie convention follows the publish-subscribe principle by publishing data as retained messages on a regular basis. You might want to rethink the design of your application - in most scenarios a regularly updated information is sufficient.
Workaround: You are free to implement your own ideas on top of the basic structure of the Homie convention.
You could either implement a get
getter topic and its logic to trigger a value update, or you may exploit the concept of Homie properties and define a settable property to trigger a value update.
License
By exercising the Licensed Rights (defined on https://creativecommons.org/licenses/by/4.0/), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
Table of Contents
Table of Contents
Motivation
The Homie convention strives to be a communication definition on top of MQTT between IoT devices and controlling entities.
MQTT is a machine-to-machine (M2M)/“Internet of Things” connectivity protocol. It was designed as an extremely lightweight publish/subscribe messaging transport.
MQTT supports easy and unrestricted message-based communication. However, MQTT doesn’t define the structure and content of these messages and their relation. An IoT device publishes data and provides interaction possibilities but a controlling entity will need to be specifically configured to be able to interface with the device.
The Homie convention defines a standardized way of how IoT devices and services announce themselves and their data on the communication channel. The Homie convention is thereby a crucial aspect in the support of automatic discovery, configuration and usage of devices and services over the MQTT protocol.
MQTT Restrictions
Homie communicates through MQTT and is hence based on the basic principles of MQTT topic publication and subscription.
Topic IDs
An MQTT topic consists of one or more topic levels, separated by the slash character (/
).
A topic level ID MAY contain lowercase letters from a
to z
, numbers from 0
to 9
as well as the hyphen character (-
).
A topic level ID MUST NOT start or end with a hyphen (-
).
The special character $
is used and reserved for Homie attributes.
The underscore (_
) is used and reserved for Homie node arrays.
Payload
Every MQTT message payload MUST be sent as string. If a value is of a numeric data type, it MUST be converted to string. Booleans MUST be converted to “true” or “false”. All values MUST be encoded as UTF-8 strings.
QoS and retained messages
The nature of the Homie convention makes it safe about duplicate messages, so the recommended QoS for reliability is QoS 1. All messages MUST be sent as retained, UNLESS stated otherwise.
Topology
Devices: An instance of a physical piece of hardware is called a device. For example, a car, an Arduino/ESP8266 or a coffee machine.
Nodes:
A device can expose multiple nodes.
Nodes are independent or logically separable parts of a device.
For example, a car might expose a wheels
node, an engine
node and a lights
node.
Nodes can be arrays.
For example, instead of creating two lights
node to control front lights and back lights independently, we can set the lights
node to be an array with two elements.
Properties:
A node can have multiple properties.
Properties represent basic characteristics of the node/device, often given as numbers or finite states.
For example the wheels
node might expose an angle
property.
The engine
node might expose a speed
, direction
and temperature
property.
The lights
node might expose an intensity
and a color
property.
Properties can be settable.
For example, you don’t want your temperature
property to be settable in case of a temperature sensor (like the car example), but to be settable in case of a thermostat.
Attributes:
Devices, nodes and properties have specific attributes characterizing them.
Attributes are represented by topic identifier starting with $
.
The precise definition of attributes is important for the automatic discovery of devices following the Homie convention.
Examples: A device might have an IP
attribute, a node will have a name
attribute, and a property will have a unit
attribute.
Base Topic
The base topic you will see in the following convention will be homie/
.
If this base topic does not suit your needs (in case of, e.g., a public broker), you can choose another.
Be aware, that only the default base topic homie/
is eligible for automatic discovery by third party controllers.
Devices
homie
/device ID
: this is the base topic of a device. Each device must have a unique device ID which adhere to the ID format.
Device Attributes
homie
/device ID
/$device-attribute
: When the MQTT connection to the broker is established or re-established, the device MUST send its attributes to the broker immediately.
Topic | Direction | Description | Retained | Required |
---|---|---|---|---|
$homie | Device → Controller | Version of the Homie convention the device conforms to | Yes | Yes |
$name | Device → Controller | Friendly name of the device | Yes | Yes |
$state | Device → Controller | See Device behavior | Yes | Yes |
$localip | Device → Controller | IP of the device on the local network | Yes | Yes |
$mac | Device → Controller | Mac address of the device network interface. The format MUST be of the type A1:B2:C3:D4:E5:F6 |
Yes | Yes |
$fw/name | Device → Controller | Name of the firmware running on the device. Allowed characters are the same as the device ID | Yes | Yes |
$fw/version | Device → Controller | Version of the firmware running on the device | Yes | Yes |
$nodes | Device → Controller |
Nodes the device exposes, with format id separated by a , if there are multiple nodes.
To make a node an array, append [] to the ID.
|
Yes | Yes |
$implementation | Device → Controller | An identifier for the Homie implementation (example esp8266 ) |
Yes | Yes |
$implementation/# | Controller → Device or Device → Controller | You can use any subtopics of $implementation for anything related to your specific Homie implementation. |
Yes or No, depending of your implementation | No |
$stats | Device → Controller | Specify all optional stats that the device will announce, with format stats separated by a , if there are multiple stats. See next section for an example |
Yes | Yes |
$stats/interval | Device → Controller | Interval in seconds at which the device refreshes its $stats/+ : See next section for details about statistical attributes |
Yes | Yes |
For example, a device with an ID of super-car
that comprises off a wheels
, engine
and a lights
node would send:
homie/super-car/$homie → "2.1.0"
homie/super-car/$name → "Super car"
homie/super-car/$localip → "192.168.0.10"
homie/super-car/$mac → "DE:AD:BE:EF:FE:ED"
homie/super-car/$fw/name → "weatherstation-firmware"
homie/super-car/$fw/version → "1.0.0"
homie/super-car/$nodes → "wheels,engine,lights[]"
homie/super-car/$implementation → "esp8266"
homie/super-car/$stats/interval → "60"
homie/super-car/$state → "ready"
Device Behavior
The $state
device attribute represents, as the name suggests, the current state of the device.
There are 6 different states:
init
: this is the state the device is in when it is connected to the MQTT broker, but has not yet sent all Homie messages and is not yet ready to operate. This is the first message that must that must be sent.ready
: this is the state the device is in when it is connected to the MQTT broker, has sent all Homie messages and is ready to operate. You have to send this message after all other announcements message have been sent.disconnected
: this is the state the device is in when it is cleanly disconnected from the MQTT broker. You must send this message before cleanly disconnecting.sleeping
: this is the state the device is in when the device is sleeping. You have to send this message before sleeping.lost
: this is the state the device is in when the device has been “badly” disconnected. You must define this message as LWT.alert
: this is the state the device is when connected to the MQTT broker, but something wrong is happening. E.g. a sensor is not providing data and needs human intervention. You have to send this message when something is wrong.
Device Statistics
homie
/device ID
/$stats
/$device-statistic-attribute
: The$stats/
hierarchy allows to send device attributes that change over time. The device MUST send them every$stats/interval
seconds.
Topic | Direction | Description | Retained | Required |
---|---|---|---|---|
$stats/uptime | Device → Controller | Time elapsed in seconds since the boot of the device | Yes | Yes |
$stats/signal | Device → Controller | Signal strength in % | Yes | No |
$stats/cputemp | Device → Controller | CPU Temperature in °C | Yes | No |
$stats/cpuload | Device → Controller |
CPU Load in %.
Average of last $interval including all CPUs
|
Yes | No |
$stats/battery | Device → Controller | Battery level in % | Yes | No |
$stats/freeheap | Device → Controller | Free heap in bytes | Yes | No |
$stats/supply | Device → Controller | Supply Voltage in V | Yes | No |
For example, our super-car
device with $stats/interval
value “60” is supposed to send its current values every 60 seconds:
homie/super-car/$stats → "uptime,cputemp,signal,battery"
homie/super-car/$stats/uptime → "120"
homie/super-car/$stats/cputemp → "48"
homie/super-car/$stats/signal → "24"
homie/super-car/$stats/battery → "80"
Nodes
homie
/device ID
/node ID
: this is the base topic of a node. Each node must have a unique node ID on a per-device basis which adhere to the ID format.
Node Attributes
homie
/device ID
/node ID
/$node-attribute
: A node attribute MUST be one of these:
Topic | Direction | Description | Retained | Required |
---|---|---|---|---|
$name | Device → Controller | Friendly name of the Node | Yes | Yes |
$type | Device → Controller | Type of the node | Yes | Yes |
$properties | Device → Controller |
Properties the node exposes, with format id separated by a , if there are multiple nodes.
|
Yes | Yes |
$array | Device → Controller | Range separated by a - . e.g. 0-2 for an array with the indexes 0 , 1 and 2 |
Yes | Yes, if the node is an array |
For example, our engine
node would send:
homie/super-car/engine/$name → "Car engine"
homie/super-car/engine/$type → "V8"
homie/super-car/engine/$properties → "speed,direction,temperature"
Properties
-
homie
/device ID
/node ID
/property ID
: this is the base topic of a property. Each property must have a unique property ID on a per-node basis which adhere to the ID format. -
A property value (e.g. a sensor reading) is directly published to the property topic, e.g.:
homie/super-car/engine/temperature → "21.5"
Property Attributes
homie
/device ID
/node ID
/property ID
/$property-attribute
: A property attribute MUST be one of these:
Topic | Direction | Description | Valid values | Retained | Required (Default) |
---|---|---|---|---|---|
$name | Device → Controller | Friendly name of the property. | Any String | Yes | No ("") |
$settable | Device → Controller | Specifies whether the property is settable (true ) or readonly (false ) |
true or false |
Yes | No (false ) |
$unit | Device → Controller | A string containing the unit of this property. You are not limited to the recommended values, although they are the only well known ones that will have to be recognized by any Homie consumer. |
Recommended:°C Degree Celsius°F Degree Fahrenheit° DegreeL Litergal GalonV VoltsW WattA Ampere% Percentm Meterft FeetPa Pascalpsi PSI# Count or Amount
|
Yes | No ("") |
$datatype | Device → Controller | Describes the format of data. |
integer ,
float ,
boolean ,
string ,
enum ,
color
|
Yes | No (string ) |
$format | Device → Controller | Describes what are valid values for this property. |
|
Yes | Depends on $datatype |
For example, our temperature
property would send:
homie/super-car/engine/temperature/$name → "Engine temperature"
homie/super-car/engine/temperature/$settable → "false"
homie/super-car/engine/temperature/$unit → "°C"
homie/super-car/engine/temperature/$datatype → "float"
homie/super-car/engine/temperature/$format → "-20:120"
homie/super-car/engine/temperature → "21.5"
homie
/device ID
/node ID
/property ID
/set
: the device can subscribe to this topic if the property is settable from the controller, in case of actuators.
Homie is state-based.
You don’t tell your smartlight to turn on
, but you tell it to put its power
state to on
.
This especially fits well with MQTT, because of retained message.
For example, a kitchen-light
device exposing a light
node would subscribe to homie/kitchen-light/light/power/set
and it would receive:
homie/kitchen-light/light/power/set ← "on"
The device would then turn on the light, and update its power
state.
This provides pessimistic feedback, which is important for home automation.
homie/kitchen-light/light/power → "true"
Arrays
A node can be an array if you’ve added []
to its ID in the $nodes
device attribute, and if its $array
attribute is set to the range of the array.
Let’s consider we want to control independently the front lights and back lights of our super-car
. Our lights
node array would look like this. Note that the topic for an element of the array node is the name of the node followed by a _
and the index getting updated:
homie/super-car/$nodes → "lights[]"
homie/super-car/lights/$name → "Lights"
homie/super-car/lights/$properties → "intensity"
homie/super-car/lights/$array → "0-1"
homie/super-car/lights/intensity/$name → "Intensity"
homie/super-car/lights/intensity/$settable → "true"
homie/super-car/lights/intensity/$unit → "%"
homie/super-car/lights/intensity/$datatype → "integer"
homie/super-car/lights/intensity/$format → "0:100"
homie/super-car/lights_0/$name → "Back lights"
homie/super-car/lights_0/intensity → "0"
homie/super-car/lights_1/$name → "Front lights"
homie/super-car/lights_1/intensity → "100"
Note that you can name each element in your array individually (“Back lights”, etc.).
Broadcast Channel
Homie defines a broadcast channel, so a controller is able to broadcast a message to every Homie devices:
homie
/$broadcast
/level
:level
is an arbitrary broadcast identifier. It must adhere to the ID format.
For example, you might want to broadcast an alert
event with the alert reason as the payload.
Devices are then free to react or not.
In our case, every buzzer of your home automation system would start buzzing.
homie/$broadcast/alert ← "Intruder detected"
Any other topic is not part of the Homie convention.