Issue of the topic: ordering of scene commands when expanding groups is unexpected
When a scene has actions involving a group, actions upon the members of the group are delayed with respect to other actions in the scene. (I am migrating from js to scenes for ease of configuration. I was not using Groups before to group actions.)
Eg,
Setup:
Group: dummyGroup
String: dummyNested (member of dummyGroup)
String: dummyPlain
Scene:
send command to dummyGroup
send command to dummyPlain
Expectation:
dummyGroup is expanded [to dummyNested]
dummyNested receives command
[execution of scene resumes]
dummyPlain receives command
Reality:
[openhab.event.ItemCommandEvent ] - Item ‘dummyGroup’ received command foo
[openhab.event.ItemCommandEvent ] - Item ‘dummyPlain’ received command foo
[openhab.event.ItemCommandEvent ] - Item ‘dummyNested’ received command foo
It seems that there is a pipeline or parallel execution when groups are involved? It would be nice to see documentation of how this ordering should work (or maybe it’s truly unexpected).
Workaround: do not rely on group expansion when ordering of actions is required in a scene. This results in a more complicated scene, but it’s not terrible.
Here’s my little test rig that makes REST api calls (it should be apparent from the naming):
openhab_rest_item_create result ‘{ “name”: “dummyGroup”, “type”: “Group” }’
openhab_rest_item_create result ‘{ “name”: “dummyPlain”, “type”: “String” }’
openhab_rest_item_create result ‘{ “name”: “dummyNested”, “type”: “String”, “groupNames”:[“dummyGroup”] }’
RULE=‘{“uid”:“dummyRule”, “name”:“dummyRule”, “triggers”:,“tags”:[“Scene”],“actions”:[
{“id”:“1”,“type”:“core.ItemCommandAction”,“configuration”:{“itemName”:“dummyGroup”,“command”:“foo”}},
{“id”:“2”,“type”:“core.ItemCommandAction”,“configuration”:{“itemName”:“dummyPlain”,“command”:“foo”}}]}’
openhab_rest_rule_create result “$RULE”openhab_rest_rule_run result “dummyRule” ‘’
openhab_rest_rule_run result "dummyRule" ''
Commands are always processed in parallel. These three commands occur close enough together in time that order of processing of the commands is not guaranteed. This is true whether it’s from a scene or from a rule. Though scenes tend to be more efficient than rules so it’s possible there is enough lag when sending command after command in a rule that they mostly occur together.
The HAB part of openHAB stands for Home Automation Bus. the Bus referred to is the event bus. When you send a command to an Item, what you are really doing is placing that command on the event bus. Then the command, as far as the sender is concerned, is done. It doesn’t wait around for that command to actually be processed by anything.
So the first command goes to the Group. That may take a millisecond. One millisecond later the command is sent to dummyPlain. In that same millisecond the Group command handler received that first event. Then one millisecond after that it manages to forward that command to dummyNested.
-------0-------------------------1-------------------------2--------------
command to dummyGroup
Group event Handler
command to dummyPlain
command to dummyNested
I think it’s mentioned somewhere in the docs. But essentially order of events that occur very close together have no guarantee of the order of their processing. In other words, near simultaneous events can be processed in any order.
It could be anything. I’d expect to see the command to the Group first only because it’s in the list of commands first. After that, I’d expect to see the remaining Items receive commands in any order given how you’ve set this up.
OH is not a fault tolerant real time system. There are no guarantees of timeliness nor order of operations.
Darn. Ordering IS implied (the scene settings UI has a reorder button!), but it does not explicitly state whether that affects the ordering of the actions or simply the visual layout (okay, it’s the latter) . My hope was that the events would ‘under the hood’ be pulled out in FIFO order through the same callback/subscriber for ItemCommandEvent, but of course depending on implementation details is always a terrible idea anyways.
Mostly out of curiosity, do you know if there have been any discussions about providing a method for serializing events in a rule like this? I’ve tried to carefully make all of my commands atomic, but it would be a convenience to know that it’s not necessary to fall back to (eg) js or chaining rules.
Perhaps you can share how you would handle the problem of ordering actions - (eg, turn receiver on, change input, change volume - but only in that specific order)
Technically the commands will be sent to the Items (i.e. placed on the event bus) in order. If you didn’t have that Group, almost all of the time, the Items will get those commands and process them in order. Technically the Items did get the commands in order. But the commands sent to the members of the Group are handled by a different process in parallel.
No, it would require a fundamental re-architecting of the event bus and everything that depends on upon the event bus (which is pretty much everything).
If the order matters, the amount of time between the commands also matters. So you’d have to use a rule to sequence the commands with the proper spacing between them. The commands can certainly be sent in order using a scene, but even if they are processed in order, there will be a handful of milliseconds between them which, for all practical purposes is simultaneously.
If using JS or Blockly, this is one of the main uses of OHRT’s Gatekeeper.
The above will command the receiver to ON, wait five seconds, send the command to input ‘HDMI1’, wait half a second, and finally send command 25 to volume.
If the order matters, the amount of time between the commands also matters. So you’d have to use a rule to sequence the commands with the proper spacing between them. The commands can certainly be sent in order using a scene, but even if they are processed in order, there will be a handful of milliseconds between them which, for all practical purposes is simultaneously.
I don’t believe that to always be true - why would you think that? (checking my understanding) State machines don’t inherently have time requirements.
While I could conceive of scenarios where timing might matter (where subsequent commands might be lost, eg due to a device resetting or no-retry transport), I would guess that commands are typically serialized through either the bindings or the devices themselves. I’ve wondered whether they are only shallow queues though… I guess it boils down to: can commands to the same endpoint overflow?
Gatekeeper: nice, thanks! I’ve been using OHRT but hadn’t tried that one yet. I was just hoping to move away from JS in my scenes to much more UI-friendly scenes (eg, edit them from my phone rather than laptop), and avoid polluting my namespaces with more items and rules to sequence things.
No, it would require a fundamental re-architecting of the event bus and everything that depends on upon the event bus (which is pretty much everything).
I think I was envisioning something like “send event with future timestamp” as part of the event payload on the bus - ie, do X at time Y. Bus remains asynchronous; bus event subscribers would gain the ability to precisely schedule events if needed.
If you want a good laugh, last evening I migrated my TimeOfDay state-triggered JS ‘scenes’ to Scenes, each supposed to be triggered by tod_state=respective state. ALL of my TOD scenes fired at each time marker through the night, much to my partner’s annoyance…
What does a state machine have to do with anything. If you turn on the receiver and then send the volume change command before the receiver has fully come online, that volume change command doesn’t do anything.
It depends on the technology and the device. MQTT with QOS 0 on a busy network, messages may get lost. Zwave or Hue commands to half a dozen devices all at once, commands may get lost. But it’s not OH that’s dropping the commands, it’s overloading the technology causing messages to get lost.
But given the scenario you listed, and my experience with audio receivers, after being turned on, there is a second or more where the receiver is unresponsive as it boot up. Sending volume commands during this time will be ignored and the command lost.
Or maybe not. It all depends on the technology and the binding. You’ve given my no details what-so-ever as to that so . With the information provided I don’t even know that all these commands are going through the same binding. It could be smart plug to turn on the receiver, LIRC to change the input and MQTT to change the volume. I have to assume the worst.
I created Gatekeeper in the first place years ago because one of the bindings was notoriously prone to dropping commands, and it was a one way binding, so there was no way for OH to know if the message got there or not.
Most of OHRT is available for use in Blockly through the block library on the marketplace. That’s a bit more phone friendly.
If the order matters, the amount of time between the commands also matters.
I don’t believe that to always be true - why would you think that? (checking my understanding) State machines don’t inherently have time requirements.
What does a state machine have to do with anything. If you turn on the receiver and then send the volume change command before the receiver has fully come online, that volume change command doesn’t do anything.
(Sorry, I haven’t quite figured out how to quote with attribution!)
If I am sending to a single device with a simple state machine that requires ordering of commands through a reliable transport, there’s nothing there to indicate that the timing of the commands matters. If you complicate it by making it multiple devices or an unreliable transport, then yes, timing matters, but I was trying to understand your generalization. I think you were just making a broad statement taking complex scenarios into consideration, while I was trying to understand if there was something about the event bus that I was missing.
There was also nothing in the original post to tell me that. So I couldn’t assume that, I had to assume the worst or even the average case. It wasn’t even clear it was a single device.
But even so, depending on the technology messages sent that fast could become lost even for a single device.
Ultimately, what you mainly need to know is that a command is an event. Events are placed on the event bus. Sending a command only blocks only long enough for the event to be placed on the event bus. There is no waiting for the subscribers to that event to process it. Events are received by various processes and handled in parallel.
No part of OH goes out of it’s way to do stuff out of order, but because of the parallel processing, there is no guarantee of order. But most of the time stuff will happen in order.