Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add implementation details and other things #200

Merged
merged 10 commits into from
May 6, 2020
39 changes: 36 additions & 3 deletions convention.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ The special character `$` is used and reserved for Homie *attributes*.

### 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**.
The nature of the Homie convention makes it safe about duplicate messages, so the recommended QoS for reliability is **At least once (1)**.
All messages MUST be sent as **retained**, UNLESS stated otherwise.

### Last will
Expand Down Expand Up @@ -152,8 +152,9 @@ The `$state` device attribute represents 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 state is optional, and may be sent if the device takes a long time to initialize, but wishes to announce to consumers that it is coming online.
* **`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. A Homie Controller can assume default values for all optional topics.
This state is optional, and may be sent if the device takes a long time to initialize, but wishes to announce to consumers that it is coming online.
A device may fall back into this state to do some reconfiguration.
* **`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. This implies that the value of every retained property must have been published during initialization. A Homie Controller can assume default values for all optional topics.
* **`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.
Expand All @@ -163,6 +164,12 @@ 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.

The following MQTT topics must remain unchanged when a device is in `ready`, `sleeping` or `alert` state:

* Any device attributes except `$name` and `$state`
* The `$properties` attribute of any node
* Any attribute of any property except `$name`

### Nodes

* `homie` / `device ID` / **`node ID`**: this is the base topic of a node.
Expand Down Expand Up @@ -204,6 +211,7 @@ Each property must have a unique property ID on a per-node basis which adhere to

* Properties can be **retained**.
A property is retained by default. A non-retained property would be useful for momentary events (door bell pressed).
Non-retained properties must be sent with a QoS of **Exactly once (2)** (this applies for both the value and the `/set`-command, but not for any of the attributes).
piegamesde marked this conversation as resolved.
Show resolved Hide resolved

A combination of those flags compiles into this list:

Expand Down Expand Up @@ -324,3 +332,28 @@ For example, an organization `example.org` wanting to add a feature `our-feature
Every extension must be published using a license.
The license can be chosen freely, even proprietary licenses are possible.
The recommended license is the [CCA 4.0](https://homieiot.github.io/license), since this is the license Homie itself uses.

## Implementation notes

### Device initialization

Some devices require knowledge of their settable retained properties to function properly.
The homie convention does not specify how to initialize/recover them e.g. after a power cycle.
A few common approaches are:

* A device can simply load default values from some configuration file.
* A device can restore its previous state from some local storage. This is the recommended way.
* A device may try to restore its state using MQTT. This can be done by subcribing to the respective channels.
An alternative way is to recover the state from other MQTT channels that are external to the Homie specification.
This is not a recommended approach though, because retained messages are only sent by the broker in response to a new subscription.
So if a device doesn't reconnect with a clean session, then the retained messages won't be resent.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a device connects with a non clean session it is assumed to "know" what happend in the last connection (mqtt kind of defines this). This means it should still know the retained values sent. If there is no persistence it should really be connecting with clean session set.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry, but I don't understand. What exactly is a "clean session"? What exactly is wrong about the paragraph and what should a more correct version?

My motivation behind this was to say that this approach at restoring state is a bad idea, and to explain why.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MQTT supports keeping sessions while the device is offline.
If you connect and request a clean session you will get one that looks as if you never connected before.
However if you dont request a clean session the broker will restore all subscriptions you had the last you where connected. It will also deliver all messages sent to a subscription with qos 1 or higher while the device was offline.

You would normally connect with a clean session if your device state is lost (like after a reboot without persistent storage, or after a reset) and connect to an existing session otherwise if you're device still knows what state its world is in (like a connection drop/reconnect).

The only difference is that with an existing session you dont get retained topics unless you unsubscribe and resubscribe them again or they changed while the device was offline. Also there is no need to subscribe if you have an existing session as the broker keeps subscriptions alive.

Copy link
Contributor

@mjcumming mjcumming Apr 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@homieiot/involved in my implementations, the Homie devices know their state ie on/off, dimmer percentage, temperature etc. Is there a situation where a device would not know it's own state and need to restore a value?

As part of other discussion regarding QoS, the Homie spec probably needs to address controller set messages that are not delivered in a timely fashion. Part of our discussion in #150

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mjcumming The section I wrote about this is limited to settable properties that can't easily be recovered. Think of music players for example. Or in my case, a light effects controller.

* If a property is not critical for correct function, there is no need to recover it.

### Device reconfiguration

If a device wishes to modify any of its nodes or properties, it can

* disconnect and reconnect with other values, or
* set `$state=init` and then modify any of the attributes.

Devices can remove old properties and nodes by publishing a zero-length payload on the respective topics.