Delay function in automations

Hi, quick basic question about the delay function. I have the following in one of my automations:

  • delay: 00:40:00

I want to delay for 40 minutes, but it seems to delay for 40 seconds.

I have another in the same for format:

  • delay: 00:15:00

That one delays for fifteen minutes.

Am I missing something obvious here?

Per the documentation:

# Waits 1 hour
- delay: '01:00'
# Waits 1 minute, 30 seconds
- delay: '00:01:30'

So it looks like your 40 minute delay should work. Do you have it in single quotes as the example above does?

There is an issue with using a delay in an automation that could possibly be re-triggered while the actions are still running from a previous trigger. Basically, if the automation triggers and starts running the actions, then hits a delay step, and while the delay is still pending the trigger happens again, the automation will actually immediately skip the rest of the delay and pick up with the next action step. As a concrete example:

trigger:
  platform: time
  minutes: '/5'
  seconds: 00
action:
  - service: switch.turn_on
    entity_id: switch.my_switch
  - delay:
      minutes: 10
  - service: switch.turn_off
    entity_id: switch.my_switch

This is triggered every 5 minutes. When triggered it turns a switch on, then starts a 10 minute delay. After 10 minutes it will turn the switch off. Now, of course you’d never write an automation like this! :slight_smile: It’s just for explanation purposes.

You’d think that since it’s triggered every 5 minutes and has a delay of 10 minutes it would never get to the step of turning off the switch. Actually, it would. The first time it’s triggered it turns on the switch and starts the 10 minute delay. Then 5 minutes later it’s triggered again. Immediately the 10 minute delay is “finished” and the automation goes on to the next step which turns off the switch. 5 minutes later the cycle repeats.

Anyway, the way to “fix” this is to move the actions of the automation to a script. Then in the action of the automation, add two steps: the first “cancels” the script (in case it was still running), and the second starts the script. This is assuming you want to restart the sequence for every trigger. It looks like this:

automation:
  - alias: Restart script if retriggered
    trigger:
      # Whatever
    action:
      - service: script.cancel
        entity_id: script.my_script
      - service: script.my_script
script:
  my_script:
    sequence:
      # Some steps
      - delay: xxx
      # Some more steps

Now let’s say you’d rather ignore triggers until the steps are done from the first trigger. The script would be the same, but the automation would look like this:

automation:
  - alias: Ignore triggers while script is running
    trigger:
      # Whatever
    condition:
      condition: state
      entity_id: script.my_script
      state: 'off'
    action:
      service: script.my_script

UPDATE: Starting with the 0.113 release this behavior has been fixed. Now you can do:

automation:
  - trigger:
      # Whatever
    mode: MODE
    action:
      # Some steps
      - delay: xxx
      # Some more steps

Where to get the “restart” behavior set MODE to restart, and to get the “ignore” behavior set MODE to single. There are also queued and parallel options.

27 Likes

Actually I do not! Perhaps that is reason (though I did set up the automaton via the HASSio interface. Thanks for the tip. I’ll give that a go.

Hey thanks for the advice guys. That is very useful.

FYI, although the docs seem to imply you need to put quotes around a time, you actually don’t have to. Either way YAML will parse it as a string, which will then get converted to a time.

Hi guys,

I’ve noticed my delay function, the first one in the code below, now seems to cause the script to exit. It was working fine until the last update was applied. Does anyone know if the function was changed during the last update?

id: ‘1547095903939’
alias: Morning Greeting
trigger:

  • entity_id: binary_sensor.downstairs_motion
    platform: state
    to: ‘on’
    condition:
  • condition: state
    entity_id: input_boolean.morning_greeting
    state: ‘off’
    action:
  • data:
    brightness: 200
    entity_id: light.kitchen_bench
    rgb_color:
    • 195
    • 216
    • 255
      service: light.turn_on
  • data:
    message: hey siri, whats the weather like today
    service: tts.google_say
  • delay: 00:00:30
  • data:
    message: Hey Siri, read me the news
    service: tts.google_say
  • data:
    entity_id: input_boolean.morning_greeting
    service: input_boolean.turn_on
  • delay: 00:40:00
  • data:
    entity_id: light.kitchen_bench
    service: light.turn_off

I still haven’t updated (still on 0.84.6), but I believe I heard something about the version of YAML changing. So maybe that’s the root cause.

In any case, I believe I also discovered there were some instances (can’t remember the details) where times in the HH:MM:SS format did need to be quoted. So I’d suggest either quoting them, or you can use one of these formats:

# Simple number means seconds
delay: 30
# Use a dictionary
delay:
  minutes: 40
# Use a template, again in seconds
delay: "{{ 40*60 }}"

I simply cannot get the delay function to work. I’ve tried quotes and no quotes, tried to run it in a script. It does not go post the first delay. Just cannot figure this out.

You’re using the editor in the frontend. I don’t know how that works; I’ve never really used it. What does the resultant YAML code (generated by the frontend) look like?

I think the problem lies with the media player / TTS function. It seems to cause the script / automation to terminate. I found that by moving them into their own scripts allows the delay function to work as expected.

No scrub that it. Worked when playing an mp3 file, doesn’t work with tts, even when the command is placed in individual scripts. It’s a complete mystery.

Here is the yaml code:

This is the automation:

- id: '1554597829610'
  alias: Good Morning
  trigger:
  - entity_id: binary_sensor.downstairs_motion
    platform: state
    to: 'on'
  condition:
  - condition: state
    entity_id: input_boolean.morning_greeting
    state: 'off'
  - after: 06:00
    before: '11:59'
    condition: time
  action:
  - data:
      entity_id: input_boolean.morning_greeting
    service: input_boolean.turn_on
  - data:
      brightness: 200
      entity_id: light.kitchen_bench
      rgb_color:
      - 195
      - 216
      - 255
    service: light.turn_on
  - data: {}
    service: script.1554787619500
  - delay: 00:00:25
  - service: script.1554787565117
  - delay: 00:30:00
  - data:
      entity_id: light.kitchen_bench
    service: light.turn_off

Here are the scripts:

'1554787619500':
  alias: tts Weather
  sequence:
  - data:
      message: hey siri, what is the weather like today
    service: tts.google_say
'1554787565117':
  alias: tts News
  sequence:
  - data:
      message: hey siri, read me the news
    service: tts.google_say

The automation terminates at, or before, the first delay. I’d love to get to the bottom of this.

I would make sure times are quoted:

- id: '1554597829610'
  alias: Good Morning
  trigger:
  - entity_id: binary_sensor.downstairs_motion
    platform: state
    to: 'on'
  condition:
  - condition: state
    entity_id: input_boolean.morning_greeting
    state: 'off'
  - after: '06:00'
    before: '11:59'
    condition: time
  action:
  - data:
      entity_id: input_boolean.morning_greeting
    service: input_boolean.turn_on
  - data:
      brightness: 200
      entity_id: light.kitchen_bench
      rgb_color:
      - 195
      - 216
      - 255
    service: light.turn_on
  - data: {}
    service: script.1554787619500
  - delay: '00:00:25'
  - service: script.1554787565117
  - delay: '00:30:00'
  - data:
      entity_id: light.kitchen_bench
    service: light.turn_off
  action:
  - service: automation.turn_off
    data:
      entity_id: automation.automation1
  - delay: 00:02:00
  - service: automation.turn_on
    data:
      entity_id: automation.automation1

1 Like

I went on a different route for something similar. I have an automation that turns on the backyard light if it’s already off when the patio door opens (HA is tied to my alarm system) at night. Within the action of that automation, I start a timer. When that timer expires, the light turns off, but if you turn off the light while the timer is counting down, the timer is canceled so the light will stay on if turned on again.

- id: '1577892099604'
  alias: Extérieur - Ouverture de la porte patio la nuit
  description: ''
  trigger:
  - entity_id: binary_sensor.porte_arriere
    platform: state
    to: 'on'
  condition:
  - condition: state
    entity_id: light.lumierecours
    state: 'off'
  - condition: state
    entity_id: binary_sensor.nuit
    state: 'on'
  action:
  - entity_id: light.lumierecours
    service: light.turn_on
  - entity_id: timer.porte_cours
    service: timer.start
- id: '1577892920536'
  alias: Extérieur - Ferme la lumière de la cours quand le timer de détection d'ouverture
    de la porte expire
  description: ''
  trigger:
  - event_data:
      entity_id: timer.porte_cours
    event_type: timer.finished
    platform: event
  condition: []
  action:
  - data:
      entity_id: light.lumierecours
    service: light.turn_off
- id: '1578421628857'
  alias: Extérieur - Annulation de l'ouverture de la porte patio la nuit
  description: ''
  trigger:
  - entity_id: light.lumierecours
    platform: state
    to: 'off'
  condition: []
  action:
  - entity_id: timer.porte_cours
    service: timer.cancel

I think the script is a better idea though because if I want to change the timer, I have to restart HA since timers are set in configuration.yaml while scripts can be reloaded at will.

You could always add an input_number to control the length of the timer, and use that when starting the timer. Then you can change the delay without restarting/reloading anything. Just change the value in the UI.

That’s a good idea, thanks.

I have an automation where a boolean change value.
It change value at 00:00, but I would trigger an action only 20 hours after that: it’s possible?
I tried to use delay option, but if I reboot HASSIO, I lose counter fo delay…
other solutions?

If you want an automation to trigger 20 hours after midnight, then why not just use a regular time trigger set at '20:00:00'?