As you can see I am repeating the same condition in both the conditions section and the actions section.
As far as I can tell the only difference to placing the condition in the conditions section vs putting it as the first action is that when you run the automation manually - using the menu option âRun Actionsâ any conditions in the conditions block is skipped/not checked, where as âactionâ conditions are always checked.
Is there any other scenario where the location of the check has an effect?
The condition section houses conditions that will let stop the automation from doing anything.
This is the preferred method of preventing the automation from acting rather that turning the automation on and off which is not recommended.
The conditions in the action section are to control specific actions., as opposed to controlling all at once.
But putting a condition as the first action does the same thingâŚ
However in doing some experimentation, I have found a better answer:
The conditions block is evaluated at a different time to a condition set as the first action.
The easiest way to see this is if your automation is in queued mode.
For the first execution of your script, you probably wonât notice a difference
however if the first execution takes some time and a second trigger happens:
Any conditions in the conditions block are evaluated immediately after the trigger fires.
If the condition passes the action is queued.
If the condition fails the entire execution is dropped.
In contrast if the condition is the first one in the actions block the execution is always queued.
The condition is only evaluated once the script starts executing.
Therefore if your script checks that value of something that it also modifies, it is better to place your condition in the action block, so that you see the results of the first execution.
Edit:
Any variables you declare in the top level variables section are also evaluated/captured at the time the trigger fires - so if you want to memorize / use the state as of the time the trigger fires, you can do something like:
I use conditions in the action part as a show stopper if I manually trigger an automation.
The condition is if this automation is enabled.
It might seem odd but these automations are part of my ESL tags. And sometimes the hub stops working and all of the tags go out of sync.
So I have an automation that triggers when the hub stops working and reboots it, then it triggers all ESL automations manually.
And if I have one automation that is disabled it will still run so using a condition to know if I want it to run or not is quite handy
You can think of the first conditions section as global conditions to check to control whether the automations run the actions AT ALL.
If the conditions fail (return all false) then the actions section of the automation wonât even be run. And I also believe that the trace will show the automation as not being run but I could be wrong on that as things have changed and I honestly donât remember which is which now.
conditions in the actions section control the actions sequencing.
in your very simplistic example I agree that there is no technical difference in the result of the automation. But thatâs not the intended use case for allowing conditions in the actions section.
Letâs look at a very slightly more complex example.
in this case there is a functional difference between the three automations.
in your automation with the condition in the conditions section if the condition fails no actions will run. the automation never got started.
in your automation with the condition in the actions section the actions will run but the first action is to check the condition. if it fails no further actions are run. the automation stops.
in my automation the condition in the conditions section will act exactly as your first one.
But in my automation if the first condition in the conditions section passes then the actions will run. it tyhen performs the first action (toggle your light). then it checks the condition. if it fails then the next action isnât run. the automation stops. If the condition passes then the automation continues running actions.
you can also use conditions to conditionally control the execution of different sets of actions.
Itâs all about how you want to control the execution and flow of the automation.
One other difference is that an automation that stops at the Conditions block will not update its last_triggered attribute. For most cases this will have no consequence, but itâs useful if you want to throttle an automation. In order for the following to work, it and any other general conditions need to be in the Conditions block:
alias: Don't execute action more often than once every 5 minutes
condition: template
value_template: |
{{ now() >= this.attributes.last_triggered | default(as_datetime(0),1)
+ timedelta(minutes = 5) }}
I believe the conditions in the block are âandedâ together, so itâs sufficient for any of them to return false.
The combination of these two points is that there is extra processing that HA does after (at least) one trigger fires and all the conditions are met.
If any of the conditions are not met - itâs almost as if the trigger didnât happen at all - at least thatâs what it looks like, thank you.
I believe you would get the same result if you just placed your conditions (A and B) as the first two actions, at least from a functional standpoint.
As the other responses have identified the metadata effects (such as last_triggered) are controlled by the conditions block (so that would be different).
First Iâm not you if you realize it but not all conditions in the conditions section are âandâ. There are also âorâ conditions that can be used there too.
So yes, any false condition in an âandâ condition block or all conditions in an âorâ condition block (or any combination of those) will cause the conditions section to fail. Which is what I was trying to say but failed.
yes, the extra processing is that it will execute the actions section.
That goes back to the difference between the global conditions section and the local condition used in the actions section for executing action flow.
I donât see any point in debating the distinction if there is no difference unless you care about those other limited use aspects. (sorry not trying to argumentative so I apologize if comes across that way)
Most people just use the conditions section as intended. I donât see any benefit to not using it like that except again under very limited use cases that very few people need.
If the automationâs triggers section fires but does not pass conditions then it will stop and record a trace but not update its last_triggered value because it is not deemed to have been âofficially triggeredâ.
Itâs unfortunate that the word âtriggeredâ is used in last_triggered because it implies it only takes one of the automationâs triggers to fire in order to update last_triggered ⌠but thatâs not the case. That distinction is held exclusively by an automation that reaches the stage of executing its actions section.
So where you choose to locate your conditions depends on your application. Generally speaking, if I want to allow execution of actionsonly under the right circumstances then I use the conditions section.
Frankly that was the purpose of the thread - if there genuinely wasnât a difference my follow up would have been - why not remove the conditions block. When I was first learning HA it did confuse me why they were necessary.
Each of the distinctions has added an extra tool to the toolbox - there may be cases where they are needed.
Edit: Removed block about traces - I didnât verify that myself.
An automation that triggers but stops in the Conditions block still produces a Trace. Hereâs one from an automation that stopped upon failing the first condition in the Conditions block:
You know, I always felt like that was kind of a bug. I know itâs documented but just feels wrong outside of a conditional block.
Plus, thereâs also the stop action to make it explicit inside a control block, although Iâm not sure of a case where that is needed vs just using a block.
As in your example, the second action doesnât run:
actions:
- condition: template
value_template: "{{ false }}"
- action: system_log.write
data:
message: Ran second action
But, this one does:
actions:
- parallel:
- condition: template
value_template: "{{ false }}"
- action: system_log.write
data:
message: Ran second action
I guess itâs syntactic sugar, but makes the behavior a bit unclear without a block for grouping the actions.
I have been burnt by the behavior of conditions in the past too.
My current mental model for them is that they are roughly similar to a:
if (...) {
// No-op
} else
continue;
Block in other programming languages, except that you donât have to be inside a looping construct to use them (any sequence block will do). In that:
If the condition is true they do nothing.
If the condition is false they skip over the remainder of the containing sequence (note: the docs specifically mention sequences - I havenât tested parallel blocks).
I see the stop as being analogous to a return in other programming languages, I see the value in being able to completely stop an automation when heavily nested, however in practice I havenât had a need for the stop action, as I try to avoid heavy nesting.