homieiot/convention

Homie: An MQTT Convention for IoT/M2M

License: CCA 4.0
Version: [develop] [v1.5.0] [v2.0.0] [v2.0.1] [v3.0.0] [v3.0.1]
Changes: [Diff to previous]
Release date: 27. October 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.

Abstract

The Homie convention defines a standardized way of how IoT devices and services announce themselves and their data on the MQTT broker. The Homie convention is thereby a crucial aspect on top of the MQTT protocol for automatic discovery, configuration and usage of devices and services."

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

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 a UTF-8 encoded string
  • The value published as payload MUST be valid for the respective property/attribute type as per the list below

String

  • String types are limited to 268,435,456 characters
  • An empty string (“”) is a valid payload

Integer

  • Integer types are UTF-8 encoded string literal representations of 64-bit signed whole numbers
  • Integers range from -9,223,372,036,854,775,808 (-263) to 9,223,372,036,854,775,807 (263-1)
  • The payload may only contain whole numbers and the negation character “-”. No other characters including spaces (” “) are permitted
  • A string with just a negation sign (“-”) is not a valid payload
  • An empty string (“”) is not a valid payload

Float

  • Float types are UTF-8 encoded string literal representations of 64-bit signed floating point numbers
  • Floats range from 2-1074 to (2-2-52)*21023
  • The payload may only contain whole numbers, the negation character “-”, the exponent character “e” or “E” and the decimal separator “.”, no other characters, including spaces (” “) are permitted
  • The dot character (“.”) is the decimal separator (used if necessary) and may only have a single instance present in the payload
  • Representations of numeric concepts such as “NaN” (Not a Number) and “Infinity” are not a valid payload
  • A string with just a negation sign (“-”) is not a valid payload
  • An empty string (“”) is not a valid payload

Boolean

  • Booleans must be converted to the string literals “true” or “false”
  • Representation is case sensitive, e.g. “TRUE” or “FALSE” are not valid payloads.
  • An empty string (“”) is not a valid payload

Enum

  • Enum payloads must be one of the values specified in the format definition of the property
  • Enum payloads are case sensitive, e.g. “Car” will not match a format definition of “car”
  • Payloads should have leading and trailing whitespace removed
  • An empty string (“”) is not a valid payload

Color

  • Color payload validity varies depending on the property format definition of either “rgb” or “hsv”
  • Both payload types contain comma separated whole numbers of differing restricted ranges
  • The encoded string may only contain whole numbers and the comma character “,”, no other characters are permitted, including spaces (” “)
  • Payloads for type “rgb” contains 3 comma separated values of numbers with a valid range between 0 and 255. e.g. 100,100,100
  • Payloads for type “hsv” contains 3 comma separated values of numbers. The first number has a range of 0 to 360, the second and third numbers have a range of 0 to 100. e.g. 300,50,75
  • An empty string (“”) is not a valid payload

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.

Last will

MQTT only allows one last will message per connection. Homie requires a last will for the homie / device ID / $ready attribute, see Device Behavior. As a consequence a new MQTT connection to the brocker is required per published device.

Base Topic

The root topic in this document is homie/. If this root topic does not suit your needs (in case of, e.g., a public broker or because of branding), you can choose another.

Homie controllers must by default perform auto-discovery on the wildcard topic “+/+/$homie”. Controllers are free to restrict discovery to a specific root topic, configurable by the user.

Timings

As soon as a device starts to publish any Homie related topic, it MUST finish with all topics within a timeframe of 500ms. Controllers should assume the default for topic values not received within this timeframe.

Extensions

This convention only covers discoverability of devices and its capabilities. The aim is to have standardized MQTT topics for all kind of complex scenarios. A Homie device may therefore support extensions, defined in separate documents. Every extension is identified by a unique ID and will be linked from this section.

The ID consists of the reverse domain name and a freely chosen suffix. The proper term homie is reserved and must not be used as the suffix or as part of the domain name.

For example, an organization example.org wanting to add a feature our-feature would choose the extension ID org.example.our-feature.

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.

Properties can be retained. A property is retained by default. A non-retained property would be useful for momentary events (door bell pressed).

A combination of those flags compiles into this list:

  • retained + non-settable: The node publishes a property state (temperature sensor)
  • retained + settable: The node publishes a property state, and can receive commands for the property (by controller or other party) (lamp power)
  • non-retained + non-settable: The node publishes momentary events (door bell pressed)
  • non-retained + settable: The node publishes momentary events, and can receive commands for the property (by controller or other party) (brew coffee)

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)
$retained Device → Controller Specifies whether the property is retained (true) or non-retained (false). Publishing to a non-retained property topic MUST always happen with the MQTT 'retain' flag off. true or false Yes No (true)
$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
° Degree
L Liter
gal Galon
V Volts
W Watt
A Ampere
% Percent
m Meter
ft Feet
Pa Pascal
psi PSI
# Count or Amount
YesNo ("")
$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.
  • from:to Describes a range of values e.g. 10:15.
    Valid for datatypes integer, float
  • value,value,value for enumerating all valid values. Escape , by using ,,. e.g. A,B,C or ON,OFF,PAUSE.
    Valid for datatypes enum
  • rgb to provide colors in RGB format e.g. 255,255,0 for yellow. hsv to provide colors in HSV format e.g. 60,100,100 for yellow.
    Valid for datatype color
Yes No for $datatype string,integer,float,boolean. Yes for enum,color

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  "true"

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.