Using While Condition in Automation

I am configuring an automation to alert me if the garage door left open. I am using the while repeat with the condition if the garage opener device is open for 5 minutes.

The automation trigger with no issue but the wile condition doesn’t stop when I close the garage door. The trace mention unknown status twice then stop.

Not sure what I am missing. When I test the condition it test successfully with no issues.

Have a look at the Alert integration instead of an automation - it does a lot of neat stuff out of the box:
Alert - Home Assistant (home-assistant.io)

1 Like

Thanks for that, but I am wondering why the condition doesn’t work as expected in the automation.

When I test the condition it is successful, however it is not working as expected.

What If i need to get something elase to work based on the while condition ?

Paste in the YAML, correctly formatted with the </> button; and the full automation trace similarly formatted.

1 Like

Here you are the automation yaml (couldn’t find the </> button, also I am not quite sure how to get the text formatted log for the trace ?

- id: '1659482300750'
  alias: Garage Door Open
  description: ''
  trigger:
  - platform: device
    device_id: e9b6b10ff2fd2b02a0e33ad89d75aef4
    domain: cover
    entity_id: cover.msg100_18f8
    type: opened
    for:
      hours: 0
      minutes: 5
      seconds: 0
    id: open_5
  condition: []
  action:
  - service: notify.outlook
    data:
      message: Door left open
      title: Garage Door
  - repeat:
      while:
      - condition: device
        device_id: e9b6b10ff2fd2b02a0e33ad89d75aef4
        domain: cover
        entity_id: cover.msg100_18f8
        type: is_open
      sequence:
      - delay:
          hours: 0
          minutes: 10
          seconds: 0
          milliseconds: 0
      - service: notify.outlook
        data:
          message: Door left open
          title: Garage Door
  mode: single

I don’t know what the “unknown” is all about, but if you close the door after the 10 minute delay has started, you’ll still get the notification. You should remove the first notification (the one before the repeat) and move the other one ahead of the delay.

See if that does the job.

Why I should get the alert after the 10 minutes if the door is closed ? if the condition will not be met of the repeat ?

I try to separate the logic, here’s how I approach it.

First I have a binary sensor that is true if the garage door has been open more than 30 minutes

binary_sensor:
  - platform: template
    sensors:
      garage_door_1_alert:
        value_template: '{{ is_state("binary_sensor.garage_door_1_sensor", "on") and is_state("binary_sensor.garage_door_1_any", "on") }}'
        delay_on: "00:30:00"
        device_class: door

Second, use an alert


alert:
  garage_door_1:
    name: garage_door_1 alert
    message: garage_door_1 is open more than 30 minutes
    done_message: garage_door_1 is closed
    entity_id: binary_sensor.garage_door_1_alert
    state: "on"
    repeat: 30
    can_acknowledge: true
    skip_first: false
    notifiers:
      - sms_notifiers_all

Hence there is no automation involved, so it is simpler and works out of the box.

Because the notify is at the end of the sequence, but the check is done at the beginning.

thanks for the details. Is the binary_sensor entry in the configuration.yaml as well ?

If you are interested, this is how I would have composed the automation.

The repeat - while uses a wait_template with a timeout instead of a delay. This allows the repeat to terminate immediately when the door is closed (as opposed to waiting for the delay to finish).

- id: '1659482300750'
  alias: Garage Door Open
  description: ''
  trigger:
  - platform: state
    entity_id: cover.msg100_18f8
    from: 'closed'
    to: 'open'
    for:
      minutes: 5
  condition: []
  action:
  - repeat:
      while: "{{ is_state('cover.msg100_18f8', 'open') }}"
      sequence:
      - service: notify.outlook
        data:
          message: Door left open
          title: Garage Door
      - wait_template: "{{ is_state('cover.msg100_18f8', 'closed') }}"
        timeout: '00:10:00'
  mode: single

Thanks, Will give it a try, what I was about to test is something like this but I put another condition to check the state after firing the alert… so it looks like this:

action:
  - repeat:
      while:
        - condition: device
          device_id: e9b6b10ff2fd2b02a0e33ad89d75aef4
          domain: cover
          entity_id: cover.msg100_18f8
          type: is_open
      sequence:
        - delay:
            hours: 0
            minutes: 5
            seconds: 0
            milliseconds: 0
        - condition: device
          device_id: e9b6b10ff2fd2b02a0e33ad89d75aef4
          domain: cover
          entity_id: cover.msg100_18f8
          type: is_open
        - service: notify.gw_outlook
          data:
            message: Door left open
            title: Garage
mode: single

Your latest example still uses a delay so even if the door were to close seconds after the delay begins, the repeat is obligated to wait until the delay finishes counting down the full 5 minutes.

Also, I am not sure why you put the notification after the delay. It’s customary to perform the notification immediately upon entering the repeat then waiting for a period of time to pass before iterating.

Yes, you could put it there.

Actually your comment about moving the notification before the delay fixed the whole cycle, and fixed my issue. Thanks.

You’re welcome! However if you are still using a delay, the repeat won’t terminate as promptly as thewait_template I posted above.

1 Like