homieiot/convention

Changes

Changes from v2.0.1 to v3.0.0

Commits

Differences


v2.0.1
v3.0.0
n2path: https://github.com/homieiot/convention/tree/v2.0.1n2path: https://github.com/homieiot/convention/tree/v3.0.0
n4version: v2.0.1n4version: v3.0.0
5releasedate: 24. March 20185releasedate: 25. March 2018
n9## Conventionn9## Topology
n11To efficiently parse messages, Homie defines a few rules related to topic names. The base topic you will see in the following convention will be `homie/`. You can however choose whatever base topic you want.n11**Devices:**
12An instance of a physical piece of hardware is called a *device*.
13For example, a car, an Arduino/ESP8266 or a coffee machine.
n13* `homie` / **`device ID`**: this is the base topic of a device. Each device must have an unique device ID which adhere to the [ID format](#id-format).n15**Nodes:**
16A *device* can expose multiple *nodes*.
17Nodes are independent or logically separable parts of a device.
18For example, a car might expose a `wheels` node, an `engine` node and a `lights` node.
n15### Device propertiesn20Nodes can be **arrays**.
21For 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.
n17* `homie` / **`device ID`** / `$` **`device property`**: a topic starting with a `$` after the base topic of a device represents a device property. A device property MUST be one of these:n23**Properties:**
24A *node* can have multiple *properties*.
25Properties represent basic characteristics of the node/device, often given as numbers or finite states.
26For example the `wheels` node might expose an `angle` property.
27The `engine` node might expose a `speed`, `direction` and `temperature` property.
28The `lights` node might expose an `intensity` and a `color` property.
29
30Properties can be **settable**.
31For 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.
32
33**Attributes:**
34*Devices, nodes and properties* have specific *attributes* characterizing them.
35Attributes are represented by topic identifier starting with `$`.
36The precise definition of attributes is important for the automatic discovery of devices following the Homie convention.
37
38Examples: A device might have an `IP` attribute, a node will have a `name` attribute, and a property will have a `unit` attribute.
39
40----
41
42### Base Topic
43
44The base topic you will see in the following convention will be `homie/`.
45If this base topic does not suit your needs (in case of, e.g., a public broker), you can choose another.
46
47Be aware, that only the default base topic `homie/` is eligible for automatic discovery by third party controllers.
48
49----
50
51### Devices
52
53* `homie` / **`device ID`**: this is the base topic of a device.
54Each device must have a unique device ID which adhere to the [ID format](#topic-ids).
55
56#### Device Attributes
57
58* `homie` / `device ID` / **`$device-attribute`**:
59When the MQTT connection to the broker is established or re-established, the device MUST send its attributes to the broker immediately.
n21 <th>Property</th>n63 <th>Topic</th>
n35 <td>$online</td>n
36 <td>Device → Controller</td>
37 <td><code>true</code> when the device is online, <code>false</code> when the device is offline (through LWT). When sending the device is online, this message must be sent last, to indicate every other required messages are sent and the device is ready</td>
38 <td>Yes</td>
39 <td>Yes</td>
40 </tr>
41 <tr>
nn84 <td>$state</td>
85 <td>Device → Controller</td>
86 <td>
87 See <a href="#device-behavior">Device behavior</a>
88 </td>
89 <td>Yes</td>
90 <td>Yes</td>
91 </tr>
92 <tr>
n63 <td>$stats/uptime</td>n
64 <td>Device → Controller</td>
65 <td>Time elapsed in seconds since the boot of the device</td>
66 <td>Yes</td>
67 <td>Yes</td>
68 </tr>
69 <tr>
70 <td>$stats/signal</td>
71 <td>Device → Controller</td>
72 <td>Integer representing the Wi-Fi signal quality in percentage if applicable</td>
73 <td>Yes</td>
74 <td>No, this is not applicable to an Ethernet connected device for example</td>
75 </tr>
76 <tr>
77 <td>$stats/interval</td>
78 <td>Device → Controller</td>
79 <td>Interval in seconds at which the <code>$stats/uptime</code> and <code>$stats/signal</code> are refreshed</td>
80 <td>Yes</td>
81 <td>Yes</td>
82 </tr>
83 <tr>
n98 <td>$fw/checksum</td>n
99 <td>Device → Controller</td>
100 <td>MD5 checksum of the firmware running on the device</td>
101 <td>Yes</td>121 <td>$nodes</td>
102 <td>No, depending of your implementation</td>122 <td>Device → Controller</td>
123 <td>
124 Nodes the device exposes, with format <code>id</code> separated by a <code>,</code> if there are multiple nodes.
125 To make a node an array, append <code>[]</code> to the ID.
126 </td>
127 <td>Yes</td>
128 <td>Yes</td>
nn145 <td>$stats</td>
146 <td>Device → Controller</td>
147 <td>Specify all optional stats that the device will announce, with format <code>stats</code> separated by a <code>,</code> if there are multiple stats. See next section for an example</td>
119 <td>$nodes</td>148 <td>Yes</td>
149 <td>Yes</td>
150 </tr>
151 <tr>
152 <td>$stats/interval</td>
n121 <td>Nodes the device exposes, with format <code>id</code> separated by a <code>,</code> if there are multiple nodes.</td>n154 <td>Interval in seconds at which the device refreshes its <code>$stats/+</code>: See next section for details about statistical attributes</td>
n127For example, a device with an ID of `686f6d6965` with a temperature and an humidity sensor would send:n160For example, a device with an ID of `super-car` that comprises off a `wheels`, `engine` and a `lights` node would send:
nn162```java
163homie/super-car/$homie → "2.1.0"
164homie/super-car/$name → "Super car"
165homie/super-car/$localip → "192.168.0.10"
166homie/super-car/$mac → "DE:AD:BE:EF:FE:ED"
167homie/super-car/$fw/name → "weatherstation-firmware"
168homie/super-car/$fw/version → "1.0.0"
169homie/super-car/$nodes → "wheels,engine,lights[]"
170homie/super-car/$implementation → "esp8266"
171homie/super-car/$stats/interval → "60"
172homie/super-car/$state → "ready"
n130homie/686f6d6965/$online → truen
131homie/686f6d6965/$name → Bedroom temperature sensor
132homie/686f6d6965/$localip → 192.168.0.10
133homie/686f6d6965/$signal → 72
134homie/686f6d6965/$fw/name → 1.0.0
135homie/686f6d6965/$fw/version → 1.0.0
136```
n138### Node propertiesn175#### Device Behavior
n140* `homie` / **`device ID`** / **`node ID`** / **`property`**: `node ID` is the ID of the node, which must be unique on a per-device basis, and which adhere to the [ID format](#id-format). `property` is the property of the node that is getting updated, which must be unique on a per-node basis, and which adhere to the [ID format](#id-format).n177The `$state` device attribute represents, as the name suggests, the current state of the device.
178There are 6 different states:
n142Properties starting with a `$` are special properties. It must be one of the following:n180* **`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.
181This is the first message that must that must be sent.
182* **`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.
183You have to send this message after all other announcements message have been sent.
184* **`disconnected`**: this is the state the device is in when it is cleanly disconnected from the MQTT broker.
185You must send this message before cleanly disconnecting.
186* **`sleeping`**: this is the state the device is in when the device is sleeping.
187You have to send this message before sleeping.
188* **`lost`**: this is the state the device is in when the device has been "badly" disconnected.
189You must define this message as LWT.
190* **`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.
191You have to send this message when something is wrong.
192
193#### Device Statistics
194
195* `homie` / `device ID` / `$stats`/ **`$device-statistic-attribute`**:
196The `$stats/` hierarchy allows to send device attributes that change over time. The device MUST send them every `$stats/interval` seconds.
n146 <th>Property</th>n200 <th>Topic</th>
nn207 <td>$stats/uptime</td>
208 <td>Device → Controller</td>
209 <td>Time elapsed in seconds since the boot of the device</td>
210 <td>Yes</td>
211 <td>Yes</td>
212 </tr>
213 <tr>
214 <td>$stats/signal</td>
215 <td>Device → Controller</td>
216 <td>Signal strength in %</td>
217 <td>Yes</td>
218 <td>No</td>
219 </tr>
220 <tr>
221 <td>$stats/cputemp</td>
222 <td>Device → Controller</td>
223 <td>CPU Temperature in °C</td>
224 <td>Yes</td>
225 <td>No</td>
226 </tr>
227 <tr>
228 <td>$stats/cpuload</td>
229 <td>Device → Controller</td>
230 <td>
231 CPU Load in %.
232 Average of last <code>$interval</code> including all CPUs
233 </td>
234 <td>Yes</td>
235 <td>No</td>
236 </tr>
237 <tr>
238 <td>$stats/battery</td>
239 <td>Device → Controller</td>
240 <td>Battery level in %</td>
241 <td>Yes</td>
242 <td>No</td>
243 </tr>
244 <tr>
245 <td>$stats/freeheap</td>
246 <td>Device → Controller</td>
247 <td>Free heap in bytes</td>
248 <td>Yes</td>
249 <td>No</td>
250 </tr>
251 <tr>
252 <td>$stats/supply</td>
253 <td>Device → Controller</td>
254 <td>Supply Voltage in V</td>
255 <td>Yes</td>
256 <td>No</td>
257 </tr>
258</table>
259
260For example, our `super-car` device with `$stats/interval` value "60" is supposed to send its current values every 60 seconds:
261
262```java
263homie/super-car/$stats → "uptime,cputemp,signal,battery"
264homie/super-car/$stats/uptime → "120"
265homie/super-car/$stats/cputemp → "48"
266homie/super-car/$stats/signal → "24"
267homie/super-car/$stats/battery → "80"
268```
269
270----
271
272### Nodes
273
274* `homie` / `device ID` / **`node ID`**: this is the base topic of a node.
275Each node must have a unique node ID on a per-device basis which adhere to the [ID format](#topic-ids).
276
277#### Node Attributes
278
279* `homie` / `device ID` / `node ID` / **`$node-attribute`**:
280A node attribute MUST be one of these:
281
282<table>
283 <tr>
284 <th>Topic</th>
285 <th>Direction</th>
286 <th>Description</th>
287 <th>Retained</th>
288 <th>Required</th>
289 </tr>
290 <tr>
291 <td>$name</td>
292 <td>Device → Controller</td>
293 <td>Friendly name of the Node</td>
294 <td>Yes</td>
295 <td>Yes</td>
296 </tr>
297 <tr>
n162 <td>Properties the node exposes, with format <code>id</code> separated by a <code>,</code> if there are multiple nodes. For ranges, define the range after the <code>id</code>, within <code>[]</code> and separated by a <code>-</code>. For settable properties, add <code>:settable</code> to the <code>id</code></td>n307 <td>
308 Properties the node exposes, with format <code>id</code> separated by a <code>,</code> if there are multiple nodes.
309 </td>
310 <td>Yes</td>
311 <td>Yes</td>
312 </tr>
313 <tr>
314 <td>$array</td>
315 <td>Device → Controller</td>
316 <td>Range separated by a <code>-</code>. e.g. <code>0-2</code> for an array with the indexes <code>0</code>, <code>1</code> and <code>2</code></td>
163 <td>Yes</td>317 <td>Yes</td>
164 <td>Yes</td>318 <td>Yes, if the node is an array</td>
165 </tr>319 </tr>
n168For example, our `686f6d6965` above would send:n322For example, our `engine` node would send:
nn324```java
325homie/super-car/engine/$name → "Car engine"
326homie/super-car/engine/$type → "V8"
327homie/super-car/engine/$properties → "speed,direction,temperature"
328```
329
330----
331
332### Properties
333
334* `homie` / `device ID` / `node ID` / **`property ID`**: this is the base topic of a property.
335Each property must have a unique property ID on a per-node basis which adhere to the [ID format](#topic-ids).
336
337* A property value (e.g. a sensor reading) is directly published to the property topic, e.g.:
338 ```java
339 homie/super-car/engine/temperature → "21.5"
170```340 ```
171homie/686f6d6965/temperature/$type → temperature
172homie/686f6d6965/temperature/$properties → degrees,unit
173homie/686f6d6965/temperature/unit → c
174homie/686f6d6965/temperature/degrees → 12.07
n176homie/686f6d6965/humidity/$type → humidityn342#### Property Attributes
177homie/686f6d6965/humidity/$properties → percentage
178homie/686f6d6965/humidity/percentage → 79
179```
n181A LED strip would look like this. Note that the topic for a range properties is the name of the property followed by a `_` and the index getting updated:n344* `homie` / `device ID` / `node ID` / `property ID` / **`$property-attribute`**:
345A property attribute MUST be one of these:
n183```n347<table>
184homie/ledstrip-device/ledstrip/$type → ledstrip348 <tr>
185homie/ledstrip-device/ledstrip/$properties → led[1-3]:settable349 <th>Topic</th>
186homie/ledstrip-device/ledstrip/led_1 → on350 <th>Direction</th>
187homie/ledstrip-device/ledstrip/led_2 → off351 <th>Description</th>
188homie/ledstrip-device/ledstrip/led_3 → on352 <th>Valid values</th>
189```353 <th>Retained</th>
354 <th>Required (Default)</th>
355 </tr>
356 <tr>
357 <td>$name</td>
358 <td>Device → Controller</td>
359 <td>Friendly name of the property.</td>
360 <td>Any String</td>
361 <td>Yes</td>
362 <td>No ("")</td>
363 </tr>
364 <tr>
365 <td>$settable</td>
366 <td>Device → Controller</td>
367 <td>Specifies whether the property is settable (<code>true</code>) or readonly (<code>false</code>)</td>
368 <td><code>true</code> or <code>false</code></td>
369 <td>Yes</td>
370 <td>No (<code>false</code>)</td>
371 </tr>
372 <tr>
373 <td>$unit</td>
374 <td>Device → Controller</td>
375 <td>
376 A string containing the unit of this property.
377 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.
378 </td>
379 <td>
380 Recommended:<br>
381 <code>°C</code> Degree Celsius<br>
382 <code>°F</code> Degree Fahrenheit<br>
383 <code>°</code> Degree<br>
384 <code>L</code> Liter<br>
385 <code>gal</code> Galon<br>
386 <code>V</code> Volts<br>
387 <code>W</code> Watt<br>
388 <code>A</code> Ampere<br>
389 <code>%</code> Percent<br>
390 <code>m</code> Meter<br>
391 <code>ft</code> Feet<br>
392 <code>Pa</code> Pascal<br>
393 <code>psi</code> PSI<br>
394 <code>#</code> Count or Amount
395 </td>
396 <td>Yes</td>
397        <td>No ("")</td>
398 </tr>
399 <tr>
400 <td>$datatype</td>
401 <td>Device → Controller</td>
402 <td>Describes the format of data.</td>
403 <td>
404 <code>integer</code>,
405 <code>float</code>,
406 <code>boolean</code>,
407 <code>string</code>,
408 <code>enum</code>,
409 <code>color</code>
410 </td>
411 <td>Yes</td>
412 <td>No (<code>string</code>)</td>
413 </tr>
414 <tr>
415 <td>$format</td>
416 <td>Device → Controller</td>
417 <td>
418 Describes what are valid values for this property.
419 </td>
420 <td>
421 <ul>
422 <li>
423 <code>from:to</code> Describes a range of values e.g. <code>10:15</code>.
424 <br>Valid for datatypes <code>integer</code>, <code>float</code>
425 </li>
426 <li>
427 <code>value,value,value</code> for enumerating all valid values.
428 Escape <code>,</code> by using <code>,,</code>. e.g. <code>A,B,C</code> or <code>ON,OFF,PAUSE</code>.
429 <br>Valid for datatypes <code>enum</code>
430 </li>
431 <li>
432 <code>regex:pattern</code> to provide a regex that can be used to match the value. e.g. <code>regex:[A-Z][0-9]+</code>.
433 <br>Valid for datatype <code>string</code>
434 </li>
435 <li>
436 <code>rgb</code> to provide colors in RGB format e.g. <code>255,255,0</code> for yellow.
437 <code>hsv</code> to provide colors in HSV format e.g. <code>60,100,100</code> for yellow.
438 <br>Valid for datatype <code>color</code>
439 </li>
440 </ul>
441 </td>
442 <td>Yes</td>
443 <td>Depends on $datatype</td>
444 </tr>
445</table>
nn447For example, our `temperature` property would send:
448
449```java
450homie/super-car/engine/temperature/$name → "Engine temperature"
451homie/super-car/engine/temperature/$settable → "false"
452homie/super-car/engine/temperature/$unit → "°C"
453homie/super-car/engine/temperature/$datatype → "float"
454homie/super-car/engine/temperature/$format → "-20:120"
455homie/super-car/engine/temperature → "21.5"
456```
457
191* `homie` / **`device ID`** / **`node ID`** / **`property`** / `set`: the device can subscribe to this topic if the property is **settable** from the controller, in case of actuators.458* `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.
n193Homie is state-based. You don't tell your smartlight to `turn on`, but you tell it to put it's `on` state to `true`. This especially fits well with MQTT, because of retained message.n460Homie is state-based.
461You don't tell your smartlight to `turn on`, but you tell it to put its `power` state to `on`.
462This especially fits well with MQTT, because of retained message.
n195For example, a `kitchen-light` device exposing a `light` node would subscribe to `homie/kitchen-light/light/on/set` and it would receive:n464For example, a `kitchen-light` device exposing a `light` node would subscribe to `homie/kitchen-light/light/power/set` and it would receive:
n197```n466```java
198homie/kitchen-light/light/on/set ← true467homie/kitchen-light/light/power/set ← "on"
n201The device would then turn on the light, and update its `on` state. This provides pessimistic feedback, which is important for home automation.n470The device would then turn on the light, and update its `power` state.
471This provides pessimistic feedback, which is important for home automation.
n203```n473```java
204homie/kitchen-light/light/on → true474homie/kitchen-light/light/power"true"
nn477### Arrays
478
479A 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.
480Let'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:
481
482```java
483homie/super-car/$nodes → "lights[]"
484
485homie/super-car/lights/$name → "Lights"
486homie/super-car/lights/$properties → "intensity"
487homie/super-car/lights/$array → "0-1"
488
489homie/super-car/lights/intensity/$name → "Intensity"
490homie/super-car/lights/intensity/$settable → "true"
491homie/super-car/lights/intensity/$unit → "%"
492homie/super-car/lights/intensity/$datatype → "integer"
493homie/super-car/lights/intensity/$format → "0:100"
494
495homie/super-car/lights_0/$name → "Back lights"
496homie/super-car/lights_0/intensity → "0"
497homie/super-car/lights_1/$name → "Front lights"
498homie/super-car/lights_1/intensity → "100"
499```
500
501Note that you can name each element in your array individually ("Back lights", etc.).
502
503----
504
207### Broadcast channel505### Broadcast Channel
n211* `homie` / `$broadcast` / **`level`**: `level` is an arbitrary broadcast identifier. It must adhere to the [ID format](#id-format).n509* `homie` / `$broadcast` / **`level`**: `level` is an arbitrary broadcast identifier.
510It must adhere to the [ID format](#topic-ids).
n213For 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.n512For example, you might want to broadcast an `alert` event with the alert reason as the payload.
513Devices are then free to react or not.
514In our case, every buzzer of your home automation system would start buzzing.
t215```t516```java
216homie/$broadcast/alert ← Intruder detected517homie/$broadcast/alert ← "Intruder detected"