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

QoS for non-retained properties #166

Closed
ghost opened this issue Jun 9, 2019 · 13 comments
Closed

QoS for non-retained properties #166

ghost opened this issue Jun 9, 2019 · 13 comments

Comments

@ghost
Copy link

ghost commented Jun 9, 2019

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
Copy link

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
Copy link
Contributor

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
Copy link
Contributor

@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 mjcumming reopened this Apr 30, 2020
@mjcumming
Copy link
Contributor

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
Copy link
Member

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

@mjcumming
Copy link
Contributor

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
Copy link
Member

Thalhammer commented May 4, 2020

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
Copy link
Contributor

mjcumming commented May 4, 2020

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
Copy link
Contributor

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

@piegamesde
Copy link
Contributor

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:

  • With QoS 0 there won't be any duplicate messages arriving.
  • Messages already have an implicit timeout through the transport layer. No need to worry about that. No need for time stamping and other stuff.
  • Because every successful /set command results in an updated property, there is a feedback loop for the controller to know if an event was delivered successfully.
  • If the message did not arrive, the controller can decide to re-send it if desired.

@mjcumming
Copy link
Contributor

@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
Copy link
Member

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
Copy link
Contributor

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

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants