Need a way to add delay in automation using service_template for turn_on only

Is it possible to add a delay into this automation only for when the boiler turns on?

- alias: "Turn on/off Boiler"        
  trigger:
    platform: state
    entity_id: group.heating
  action:
    service_template: >
      {% if trigger.to_state.state == "on" %}
      homeassistant.turn_on
      {% elif trigger.to_state.state == "off" %}
      homeassistant.turn_off
      {% endif %}
    entity_id:
      - switch.boiler

Here’s one possible way to do it. Make the automation call scripts.

Automation:

- alias: "Turn on/off Boiler"        
  trigger:
    platform: state
    entity_id: group.heating
  condition:
    condition: template
    value_template: "{{ trigger.from_state.state != trigger.to_state.state }}"
  action:
    service_template: "script.boiler_{{trigger.to_state.state}}"

Scripts:

  boiler_on:
    sequence:
    - delay: '00:00:05'
    - service: switch.turn_on
      entity_id: switch.boiler

  boiler_off:
    sequence:
    - service: switch.turn_off
      entity_id: switch.boiler
1 Like

Thanks, I can see this method will be really useful too, where I have 2 separate automations to combine them into 1.

1 Like

What happens if the the boiler is waiting to turn on and a turn off is triggered? Will it turn on again after the delay?

Nothing. If it’s waiting to turn on then it’s already off. Sending an off command to a switch that’s already off changes nothing.

1 Like

I need to give some more info.

I am going to have a 3 minute delay whilst my radiator valves open. The heating group contains all the valves. The valves are all generic thermostat switches.

I think with your idea if the thermostat goes to heat, the heating group will turn on and after 3 minutes the boiler will come on. If the thermostat goes to idle (if it is turned back down quickly), the heating group will go off and the turn off script will turn the boiler off but it is already off as it is within 3 minutes.

Wont the boiler still turn on when the 3 minute delay has completed?

I suspect I need some kind of loop in the boiler on script to exit the delay if there is a boiler off run before the delay is completed.

Yes it will. It’s doing precisely what you requested, namely countdown from 3 minutes then turn on the boiler switch. It has no way of knowing you no longer want to do that during its countdown.

If you want the ability to cancel during the countdown, you may wish to consider using a timer instead of delay. A timer can be canceled.

1 Like

Great, thanks for the tip. I will look into the timer and use boiler off to cancel it if it is running. I guess I could also look into displaying the timer in the front end so I can see it working.

Just got something working using your script

I edited the boiler_off script to cancel the boiler_on script to stop it turning on the boiler after the delay

  boiler_on:
    sequence:
    - delay: '00:03:00'
    - service: switch.turn_on
      entity_id: switch.boiler

  boiler_off:
    sequence:
    - service: script.turn_off
      data:
        entity_id: script.boiler_on
    - service: switch.turn_off
      entity_id: switch.boiler

Because your script contains a delay, the service script.turn_off will work in a way you may have not anticipated. I wish to bring this to your attention just in case you ever experience any unusual behavior with this technique (i.e. using script.turn_off to stop delay).

When you call script.turn_off, while delay is counting down from 3 minutes, delay is paused, not eliminated.

Let’s say delay counts down to 1 minute and then script.turn_off is executed. The script is halted but delay remains. If you were to now call script.turn_on, the existing delay will start counting down from 3 minutes again.

You can prove it to yourself by turning off the script before delay expires then look at the script’s attributes in the States page. Here are the attributes for my test script (script.family_toggle). The script was turned off while it was counting down from 30 seconds. The attribute last_action contains delay 0:00:30.

script%20-%20off%20-%20delay

If I now call script.turn_on, it will restart delay and begin counting down from 30 seconds.

In contrast, when the script is not interrupted and allowed to run to completion, it will not have a last_action attribute.

script%20-%20off%20-%20normal

1 Like

I did wonder about that so it is useful to know but for this, I am not turning the script back on again with script.turn_on but HA is probably doing that for me looking in the logs.

I am not sure if it starts again at delay but as delay is the first command in the sequence it doesn’t matter in this case.

I did look for a way to cancel or reset the running script but didn’t find anything.