homieiot / convention

🏡 The Homie Convention: a lightweight MQTT convention for the IoT
https://homieiot.github.io/
Other
715 stars 60 forks source link

QoS for non-retained properties #166

Closed ghost closed 4 years ago

ghost commented 5 years ago

Hi!

Would it make sense to specify QoS 2 for non-retained properties, or mention it as a option/reminder for those? For event based things (doorbell, ish, think more pushbutton) the amount of events might matter. In which case QoS 2 becomes significant.

kollokollo commented 4 years ago

Yes, that would make sense. Also think of a GUI, where the user presses a button, to trigger a specific action on a remote device. This should be triggered exactly once.

piegamesde commented 4 years ago

Let's continue the discussion from the PR review thread here, so it won't be hidden once the topic is resolved.

@Thalhammer wrote:

I get why the set command should be QoS 2 in some cases, but why the value ? Controllers should be able to handle the same value arriving twice just fine. The problem with mixing QoS values is that mqtt does not guarantee ordering for different QoS values, only for the same QoS value. See here. So if we mix QoS 1 and 2 for values sent by the device the $state ready message might arrive before the value of a property.

@mjcumming:

@Thalhammer thank you that link explaining message ordering. My prior understanding was there no guarantee on ordering.

The use case for a non retained properties is not clear to me.

For instance: door bell button, a device to controller event. This is a time sensitive event. If the controller/broker is offline, then there is really no need for the controller to get that message after more than a minute or so.

Or

For instance: a single command (brew coffee), a controller to device event. This is a time sensitive command. If the coffee maker doesn't get the command within a minute or so then it should probably never get the command.

piegamesde commented 4 years ago

@mjcumming You are making the assumption that all (or most) events are of a time critical nature. This may not be true for everything, but I also can't think of good counter examples.

This leads me to the idea to send non-retained properties with a QoS of 0 (at most once).

An alternative solution could be to ignore the fact that messages with QoS 2 may arrive at a later time. Handling that case for time-ciritical events would then be implementation defined, e.g. by passing some time stamps as value for the property.

mjcumming commented 4 years ago

Perhaps the logic for dealing with this should reside on the controller. The controller would know if the set command was not acted on/received as the value of the property would not change.

Thalhammer commented 4 years ago

How about an attribute similar to $settable to indicate if the controller should use retained or non retained set ?

mjcumming commented 4 years ago

I think that would work, but before we do that and change the protocol we need to understand the use case. I am trying to think of a scenario where a device reconnects to a broker and the set command is always valid - at some point in time acting on a delayed set command is not a desired behavior. Ie. if a set command is sent to change a light how long is that valid for? It might different for a set command to change a heat/cool setpoint. I can't think of a scenario where delivering a set command hours later would be a desired behavior.

We need to consider scenarios where the connection between the device and controller is broken and how they reconnect (ie new session, clean session) and expected behavior - as you mentioned in the PR.

Before we change anything lets brainstorm some more to think of the use case and desired behavior and where the logic (controller/device) for dealing with delayed set commands should reside.

Thalhammer commented 4 years ago

One example would be the way I use it in my homeautomation. My Controller always publishes the current state it thinks the world is in to the set command no matter if the device is online or not. Note that retained message can get overriden.

Example: Device is offline. Controller tries to turn on light by sending to set. If the device comes online now it will see the message and turn on the lights, which (while delayed) is what the user wants. If the user/controller turns the light back off it will publish to the set command again in retained mode (which overwrites the first message). If the device comes online now it will only see the message to turn off the light, which (again) is exactly what the user wanted. The first message to turn on the light will never reach the device as the broker only stores an forwards the latest retained message.

This is how I use it in my home and it worked fine so far.

IMHO the same goes for e.g. a thermostate. A controler would set what the user wants the temperature to be and if the device is offline nothing will happen. But that does not change the fact that the user wants the room to be of that temp and once the device reconnects it will be fullfilled. If the user decides that he wants a different temp before the device reconnects it will overwrite the old message

mjcumming commented 4 years ago

This is why we need to enumerate different situations. In your scenario, the controller is the source of "truth" about the state of the device. But this ignores the possibility of other controllers, most likely local control of a device. Consider the situation where I ask the controller to turn on light but for some reason that connection is broken. So, I manually turn the light on and then later turn it off when done. Then the light reconnects and gets turned on. Not a desired behavior from my perspective.

Its not that one behavior or scenario is right, we just need to understand them and discuss how to solve.

mjcumming commented 4 years ago

Also, this discussion is mixing the discussion about non-retained properties and the set command.

piegamesde commented 4 years ago

The more I think about it, the more I like the idea of using QoS 0 for all events where non-duplicated arrival and a certain time criticality are more important than reliable delivery:

mjcumming commented 4 years ago

@piegamesde your comments expand on the spec at 5.3.2 where properties update their value which notifies the controller, ie closes the loop.

This is keeps the logic on the device side to a minimum which is desirable since the protocol is designed to be lightweight.

Thalhammer commented 4 years ago

I think the real question is where you consider your truth to be. In my case the (single) controller is the single point of truth. While in @mjcumming 's case the point of truth is the device. This has a pretty big impact on the way you design and implement the convention.

mjcumming commented 4 years ago

@Thalhammer @piegamesde lets move the set issue to this thread

We do need to solve for the QoS issue for non-retained properties