Hello,
I’m trying to understand how the While Loop action is supposed to work. I use an automation that notifies me the wash is done and to move the clothes to the dryer. It will loop every 9 minutes until the washing machine door is opened, which sets an input boolean. This helper is then used as the condition to break the loop and continue with the rest of the automation.
In practice, the boolean is changed in between the next run of the loop (within the 9 minute window). The last loopwill run even though the while condition is broken, then move on to the next action. My preference would be for the last loop to start, the condition evaluates as false, then skips the sequence of actions within the loop and moves on to the next action.
The description for the While Loop from HA docs seems to support my expectations:
This form accepts a list of conditions that are evaluated before each time the sequence is run. The sequence will be run as long as the condition(s) evaluate to true.
Am I doing something wrong? Is my expectation on how the While Loop works wrong? Is there a better way of achieving what I’m after?
–
Here is the yaml for the actions in my automation.
description: "Wash is done alert"
mode: single
triggers: []
conditions: []
actions:
- data: {}
target:
entity_id: input_boolean.door_open
action: input_boolean.turn_off
- repeat:
sequence:
- delay:
hours: 0
minutes: 9
seconds: 0
milliseconds: 0
- metadata: {}
data:
message: Wet Clothes in the Washing Machine.
title: Laundry
action: script.mobile_notification_greg
while:
- condition: state
entity_id: input_boolean.door_open
state: "off"
- alias: Don't repeat more than 15 times
condition: template
value_template: "{{ repeat.index <= 15 }}"
enabled: true
- metadata: {}
data:
message: Good job moving the clothes.
title: Laundry
action: script.mobile_notification_greg
Where is your trigger? Using automations without a trigger can lead to unreliable function. If your intent is to fire the automation via a service call/action you should use a Script instead or an Automation.
Regarding the While loop…
I think have misunderstood the docs or structured your actions inappropriately. In your automation the flow is as follows:
Check conditions
Run Sequence
2a. Delay
2b. Run Notification Script
Go back to #1
The conditions are not checked while the loop is in the middle of a run… i.e. they are not checked after the delay.
There are a few options to have the conditions checked before the notification, the two easiest would be:
Add a condition between the delay and the notification so they are checked immediately before the notification.
Adding Conditions in the Run
description: "Wash is done alert"
mode: single
triggers: []
conditions: []
actions:
- data: {}
target:
entity_id: input_boolean.door_open
action: input_boolean.turn_off
- repeat:
sequence:
- delay:
hours: 0
minutes: 9
seconds: 0
milliseconds: 0
- condition: state
entity_id: input_boolean.door_open
state: "off"
- alias: Don't repeat more than 15 times
condition: template
value_template: "{{ repeat.index <= 16 }}"
- metadata: {}
data:
message: Wet Clothes in the Washing Machine.
title: Laundry
action: script.mobile_notification_greg
while:
- condition: state
entity_id: input_boolean.door_open
state: "off"
- alias: Don't repeat more than 15 times
condition: template
value_template: "{{ repeat.index <= 15 }}"
enabled: true
- metadata: {}
data:
message: Good job moving the clothes.
title: Laundry
action: script.mobile_notification_greg
Move the notification so it happens before the delay.
Rearrange the Run
description: "Wash is done alert"
mode: single
triggers: []
conditions: []
actions:
- data: {}
target:
entity_id: input_boolean.door_open
action: input_boolean.turn_off
- repeat:
sequence:
- metadata: {}
data:
message: Wet Clothes in the Washing Machine.
title: Laundry
action: script.mobile_notification_greg
- delay:
hours: 0
minutes: 9
seconds: 0
milliseconds: 0
while:
- condition: state
entity_id: input_boolean.door_open
state: "off"
- alias: Don't repeat more than 15 times
condition: template
value_template: "{{ repeat.index <= 15 }}"
enabled: true
- metadata: {}
data:
message: Good job moving the clothes.
title: Laundry
action: script.mobile_notification_greg
Thanks @Didgeridrew! - I removed the trigger from this post just to keep it simple to read. The automation triggers perfectly based on a power sensing outlet. If power drops below a certain threshold, this automation will trigger.
So I understand the looping logic better, you say…
When are the conditions checked within a loop?
Regardless, I’ll try your alternative suggestions!
Hi Greg, I’m doing exactly the same just by using the power draw from the plug.
When it goes below a certain value, that’s the trigger and you don’t need to loop anything.
Thanks @Nick4 - the loop is to nag me with a text alert until I actually move the clothes to the dryer. Otherwise, I’ll get the alert once and usually forget about it.
Only when you add them there. Neither the Repeat While or Repeat Until actions check the conditions within the sequence of the Repeat.
If you want a more immediate reaction you could add a trigger for the input boolean changing to “on” and set the automation mode to restart. It requires a bit more conditional logic, but it feels more responsive because it can break through the delay.
description: "Wash is done alert"
mode: restart
triggers:
- id: power
trigger: #Your original trigger
- id: door
trigger: state
state: "on"
entity_id: input_boolean.door_open
conditions:
- or:
- condition: trigger
id: power
- alias: Prevent actions based on the boolean trigger when automation isn't already active.
condition: template
value_template: "{{this.attributes.current > 0}}"
actions:
- if:
- condition: trigger
id: power
then:
- action: input_boolean.turn_off
data: {}
target:
entity_id: input_boolean.door_open
- repeat:
sequence:
- delay: "00:09:00"
- metadata: {}
data:
message: Wet Clothes in the Washing Machine.
title: Laundry
action: script.mobile_notification_greg
- alias: Kill Automation if washer isn't attended to
condition: template
value_template: "{{ repeat.index == 15 }}"
- stop: "No one took the clothes out of the washer"
while:
- condition: state
entity_id: input_boolean.door_open
state: "off"
- alias: Don't repeat more than 15 times
condition: template
value_template: "{{ repeat.index <= 15 }}"
- metadata: {}
data:
message: Good job moving the clothes.
title: Laundry
action: script.mobile_notification_greg