Is there a graceful way to terminate (exit) from a script before reaching the end, on a given condition?
Can i.e. the service: script.turn_off
be used in a script to turn itself off ?
Or is there some kind of exit
statement that can be used ?
You can use conditions in the action section of scripts and automations. When it reaches the condition it checks for true and continues. If false the actions terminate at that point.
You could use any of these: https://www.home-assistant.io/docs/scripts#repeat-a-group-of-actions
They all have an exit loop condition option.
Thanks @tom_l for stepping in, but I’m not sure I understand how to make those group actions serve my purpose. All I want is a simple;
If (so,and so_1)
Do something_1
elseif (so, and so_2)
Do something_2
elseif .......
.........
else
exit
endif
It’s the exit
statement (or something similar) that I’m looking for.
Don’t pay attention to the syntax above. It’s just to illustrate my purpose. I know this isn’t proper YAML.
Do while…
Or
Repeat until…
Sorry, you lost me.
I don’t have a condition for Do while
… or Repeat until.
What I do is assigning values to variables based on a set of tests (criteria’s), and if none match, then it should exit and not continue without any data. There’s no need to loop or repeat things.
Then finity’s suggestion should work best. Execution of the sequence will stop when a condition resolves to false.
script:
your_script:
sequence:
- service: blah...
- condition: state
entity_id: input_boolean.test
state: 'on' # if the state is 'off' the script stops here.
- service: blah...
The equivalent in Scripting would be this:
- choose:
- conditions: "{{ so and so }}"
sequence:
... do something here 1 ...
- conditions: "{{ this and that }}"
sequence:
... do something here 2 ...
- conditions: "{{ those and these }}"
sequence:
... do something here 3 ...
If none of the three conditions
evaluates to true
then the choose
is exited (much like the else exit
in your pseudo-code example) without doing anything.
Exactly, but then it will continue to the rest of the script.
That’s what I want to avoid.
If none of the conditions are met, it should exit completely from the script.
(Or, one could turn the whole thing around and say that if a specific condition exist, then exit)
You can just leave blank the default
action from the Choose Action. If none of the condition is met, it will do nothing.
Just an example-
action:
- choose:
- conditions:
- condition: numeric_state
entity_id: weather.home
attribute: temperature
above: '30'
sequence:
- service: light.turn_on
target:
entity_id: light.your_entity
- conditions:
- condition: numeric_state
entity_id: weather.home
attribute: temperature
below: '0'
sequence:
- service: light.turn_on
target:
entity_id: light.your_entity
default: []
Just an example-
Thanks, I will try this and report back
A blank default
is equivalent to no default
statement. If none of the conditions
are met it exits choose
and continues to process any code beyond the choose
(that’s what Viking is trying to avoid).
Only if there is more code beyond the choose
statement. All of the script’s logic can be contained within the three conditions
of the choose
.
If there’s more code beyond the choose
, a condition
statement can determine if execution should continue (that’s what finity explained).
Long story short, an explicit exit
statement simply doesn’t exist in Scripting but its behavior can be duplicated by structuring the execution flow correctly (using the techniques presented).
Thank you so much!!
I must have become a very bad “story teller”. Just see how much it took before I finally found someone who understood my question. I am so happy you stepped in. Now I know that there is no such thing as a simple ‘exit’ statement (or anything similar).
But I do think that there should be one. That, is perhaps something for the feature list
Correct. An explicit exit
statement doesn’t exist because it isn’t needed.
Feel free to request it but don’t expect it to be implemented.
An explicit exit
statement is an artifact from a bygone programming era (like a goto
statement). As has already been demonstrated, if the execution flow is structured properly it will “exit gracefully” without the use of an exit
statement.
you’re welcome…
Resurfacing this thread as this is what I’m looking for. I have an automation that I want to gracefully terminate, if a message containing some important values is sent to my phone, and I consider risky, allowing the automation to fully execute. Is there any way I can terminate an automation midway its execution?
yes. look at ‘stop’
Is there a reason why you can’t simply use choose
or if
to either exclude the “risky value” or “deadend” the actions when it is received?
stop
is useful if you want to terminate and return a value. To simply terminate, you can also use stop
or just structure the logic as I described.
Hey there! thanks for your answer. No, there is no specific reason other than my coding expertise. I will give it a try next weekend and see if I can get away with a choose
structure.
Thanks everyone. I will update this thread in a few days.