Wait for trigger won't proceed

Hi all,

Have a bit of a brain scratcher that I can’t quite figure out. I have an automation that has a wait for trigger, in this case waiting from a door to go from on to off (open then close).

The trigger does in fact change from on to off but the automation does not proceed. It was working but now it isn’t and I don’t understand why…

Here’s a trace.

And here’s the state (if was on)… now its off

The automation should proceed to the next step shouldn’t it?

continue_on_timeout: false

If you tell it not to, why would it ?

OP said it does change from on to off, so they’re not expecting it to timeout, in which case it should proceed.

@currest2620 could it be that it’s already off when it reaches that point? In that case, you need to do it differently, which is to check the current state, not just wait for the change. Ons way would be to make it a wait template which just uses {{ is_state('binary_sensor.front_door', 'off') }}. This will catch both scenarios.

1 Like

You have a time-out of 0 seconds. That is going to go off right away then not continue.

2 Likes

It has a zero-time timeout and is configured not to continue after the timeout.

So wait for the trigger but give up immediately and go no further. It’s doing what it’s told.

Edit: beaten by Tom. Great minds etc

2 Likes

In other words, remove the timeout: section from your automation using Yaml mode.

Not 100% sure, but I think I’ve seen it happen to me before when I enabled continue_on_timeout temporarily and disabled it again. The timeout section was populated in the Yaml version of the automation and didn’t get removed when setting continue_on_timeout back to false.

It could be a bug, but I’m not sure. Can anyone else reproduce this?

  • Set continue_on_timeout: false & check Yaml. No timeout section will be present.
  • Switch back to UI mode and enable the Continue on Timeout boolean. Switch back to Yaml mode & check. Timeout section will be present and populated as all 0s.
  • Switch back to UI mode and disable the Continue on Timeout boolean. Switch back to Yaml mode & check. Timeout section will still be present and populated as all 0s.

Note that you might need to save in between each step, just to rule out any parsing of the offending section on save.

continue_on_timeout: false

But I don’t want it to time out. I only want it to continue after the state changes.

It may not be what you want but that’s what happened.

Screenshot_20240504-180234~2

Why? Because it’s doing exactly what you told it to do. Wait for the door to close. How long should it wait? You specified it should timeout after 0 seconds. What should it do after timing out? You specified continue_on_timeout: false so it stops immediately.

Increase the timeout value to the maximum amount of time you want it to wait for the door to close.

I removed the timeout from the YAML and it is now working as intended. I noticed that when I removed the timeout from YAML and went back to the GUI the timeout was switched on.

Now the YAML reads:

alias: Wait until the front door is closed
wait_for_trigger:
  - platform: state
    entity_id:
      - binary_sensor.front_door
    from: "on"
    to: "off"
continue_on_timeout: false

I don’t recall adding the the time outs as zero though, so it might be been put there by the GUI.

In any event the solution works so thanks for the advice. I wouldn’t have reached that conclusion myself, so thanks again for pointing that out.

Now put it back and

Waiting forever for a trigger is a bad idea. Even if you wait for an hour it is better than the automation never ending.

1 Like

The purpose of the timeout option is to prevent the wait_for_trigger from waiting forever. In other words, what should happen if the front door is left open? Should the trigger wait indefinitely for it to close? Or should it only wait for as long as timeout and then either stop or proceed? If it proceeds you can test if it timed out (meaning the door was never closed) and decide if some other action should be taken (like notify you that something is wrong because the door was never closed).

1 Like

Thanks, great points. I’ll add those ideas into my automation. Thanks for the advice.

Just curious to know if there is a way to determine if the wait_for_trigger is triggered by a state change or by the time out timer so it can be used in an if: statement.

yes:

Oh Great, cool. That looks very useful. Thanks.

Thanks for the heads up armedad. I am a little (actually a lot) stumped as to how to use this to determined if the event was triggered or the timeout occurred.

As I am using a wait_for_trigger, I gather I need to use the variable wait.trigger which says it will …

be none if no trigger happened before timeout expired.

I have the following code as a test script. But it always indicates a timeout regardless of whether the door state has changed or not. Have I done this right?

alias: Test wait trigger
sequence:
  - alias: Wait until the front door is closed
    wait_for_trigger:
      - platform: state
        entity_id:
          - binary_sensor.front_door
        from: "on"
        to: "off"
    continue_on_timeout: true
    timeout:
      hours: 0
      minutes: 5
      seconds: 0
      milliseconds: 0
  - if:
      - condition: template
        value_template: "{{ is_state('trigger.to_state'), 'none'}}"
    then:
      - service: notify.persistent_notification
        data:
          message: door is closed
          title: notification
    else:
      - service: notify.persistent_notification
        data:
          message: wait timed out
          title: notification
mode: single
icon: mdi:test-tube

this is correct, however you’ve confused me because your code doesn’t do what you just said you needed to do.

1 Like
alias: Test wait trigger
sequence:
  - alias: Wait until the front door is closed
    wait_for_trigger:
      - platform: state
        entity_id:
          - binary_sensor.front_door
        from: "on"
        to: "off"
    continue_on_timeout: true
    timeout:
      hours: 0
      minutes: 5
      seconds: 0
      milliseconds: 0
  - if:
      - condition: template
        value_template: "{{ wait.trigger == none }}"
    then:
      - service: notify.persistent_notification
        data:
          message: wait timed out
          title: notification
    else:
      - service: notify.persistent_notification
        data:
          message: door is closed
          title: notification
mode: single
icon: mdi:test-tube

Thanks that seems to be working now. Wasn’t sure of the syntax. The condition returns true if the wait trigger is none, which seems obvious now I re-read it.

Many thanks for your advice.