What happens when an automation is triggered and then before it is done executing the trigger for the same automation fires again? I’ve been searching for an answer, but I can’t seem to find it anywhere in the forums or documentation.
The particular case for me where I encountered problems is if I leave home, and then quickly come back (because I forgot something etc.) and then leave again. I have a “leaving home” automation that has some delays in it (for turning on security related hardware), and sometimes if I pop back in for a second, it might not be done executing before it is called again. When this happened I saw strange behavior, so I’m trying to figure out what happens with the automation control flow so I can figure out how to prevent the incorrect behavior from the automatons. Thanks!
A script contains a sequence of actions that are executed in the order they are listed. If the sequence contains a delay, it will pause execution. While it is paused, a script cannot be called again (i.e. it blocks additional calls).
An automation’s action is like a script. If it contains a delay, it will pause and, I suspect, will block additional calls to execute it. I’m going to take a guess that automations may be queued. So if an automation is called in rapid succession, all instances are queued. So the automation’s action might get executed for each instance in the queue. To be clear, this is just a guess.
EDIT
My guess was wrong. There’s no queue, or blocking, and the actual behavior can indeed be “strange”.
The first test consisted of turning the input_boolean on/off and allowing the automation to run to completion. As expected it printed three messages, with delays of 30 seconds between them.
The second test turned the input_boolean on/off and then, ~10 seconds later, turned it on/off again. The result was unexpected. It had obviously printed the first message (it occurs immediately) but it also printed the second message (but not the third one). It appears to have cancelled the delay that was already underway, printed the second message, then cancelled the balance of the actions. This test was repeated a few time with identical results.
The third test turned the input_boolean on/off and then, ~10 seconds later, turned it on/off again and then, ~5 seconds later, turned it on/off yet again. The result was also unexpected. This time it printed all three messages. This test was repeated and the results were the same; three messages were printed.
A few things stand out:
There’s definitely none of the queuing I had hypothesized!
A re-trigger doesn’t simply terminate the previous running instance and ignore the balance of the actions. Some additional bits, beyond the terminated delay, may get executed!
My simple experiment confirms there may be “strange behavior”.
EDIT
Overlooked to mention these tests were perform with version 0.96.3.
Thank you for your responses everyone, and to @123 for testing out the different cases! Based on the results, I guess I should try my best to never trigger an automation again before it is done executing, since the behavior can be very hard to predict. I tried looking at the code in github to see why the actions would be executed in the way the tests showed, but I couldn’t figure it out.
I think you need to look at the problem from a different angle.
You get a strange behaviour if your automation is called several times.
So you need to avoid that.
The easiest way is to create a flag (input_boolean) that reflects the state of things and change your automations so that they pay attention to the flag and don’t run if it’s set, for example. It’s hard to give further guidance without code but I hope you get the idea.
And then you can forget about that “chicken or egg” question as it’s really complicated as we can see AND might easily change in the future so one just should not rely on the current state of things.
A way I have dealt with this scenario is to have two automations, each calling a script and the first item in each script is to cancel the other script. It sounds more complex than it is. Unfortunately I’m on my phone so can’t paste my actual code as an example.
Yeah, there are many ways to skin a cat.
The downside of “each script is to cancel the other script” approach is there are 2 dependencies. If you use a flag, there’s only one.
Less room for error etc, they call it KISS