How do I create reliable working timers

Hi,

I use the generic thermostat to control my central heating.

One of the functions of the central heating is to heat my floor and for this I have designed an automation that uses climate.turn_on/off function, which control the gas burner and turns the burner on for 20 minutes and turns it off after 20 minutes, until the set room temperature is reached.
Often this works fine, but there are times when it doesn’t work. E.g. the burner does not switch off after 20 minutes and stays on or does not switch on and everything cools down.

As a timer I use the delay function, but these timers are reset if e.g. Home Assistant restarts, etc.

My question is, is there a (more) reliable solution so that the initiated delays keep their value.

Thank you.


alias: CV Heater Control
description: ''
trigger:
  - platform: state
    entity_id: climate.kamerthermostaat
    attribute: hvac_action
    to: heating
    for: '00:20:00'
    id: heating
  - platform: state
    entity_id: binary_sensor.tuindeur_contact
    from: 'on'
    to: 'off'
    for: '00:10:00'
    id: door_closed
  - platform: state
    entity_id: binary_sensor.tuindeur_contact
    from: 'off'
    to: 'on'
    for: '00:00:45'
    id: door_open
  - platform: homeassistant
    event: start
    id: door_closed
condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - door_open
              - heating
        sequence:
          - service: climate.turn_off
            target:
              entity_id: climate.kamerthermostaat
    default: []
  - choose:
      - conditions:
          - condition: trigger
            id: heating
        sequence:
          - delay: '00:20:00'
    default: []
  - choose:
      - conditions:
          - condition: trigger
            id:
              - door_closed
              - heating
        sequence:
          - service: climate.turn_on
            target:
              entity_id: climate.kamerthermostaat
    default: []
mode: single

None of the time-based concepts in Home Assistant can survive a restart or Reload Automations (delay, for, wait_template, wait_for_trigger, repeat, etc) and timers don’t survive a restart or Reload Timers.

To make active, or paused, timers survive a restart, I created this system to restore them:

Otherwise, there’s a programming technique where instead of using a delay you compute the time when the automation should be triggered. For example, if you want to delay for 20 minutes, before executing the next step, you add 20 minutes to the current time and assign it to an input_datetime. That input_datetime is used by the automation in a Time Trigger.

When the automation’s Time Trigger fires, the automation uses a choose to direct execution to the next step.

A Time Trigger is unaffected by restart/reload because unless it happens at the precise time when the Time Trigger occurs (and there are ways to mitigate that as well).

The technique I described makes the automation more robust but it also makes it more complex because it requires an input_datetime (to hold the future time), a Time Trigger, and the use of choose to determine which trigger fired in order to direct execution flow to the proper step.

FWIW, several of my automations use the described programming technique and a few others (that employ timers) use the timer-restoration system. I can freely restart/reload the system without concern that it will derail an (important) automation.

Thank you for your reply.
I have read the link you provide and understand what you are saying.

I’ve read almost all your replies in other threads, and these replies inspire my to change or to create my automations.
You are talking about using input_datetime, and I think I like that solution, but till now I have never used this feature before.
Can you please give me an example how to start?

Thank you for your time to help me.

I think I’m on the right way.
For now, to test, I’ve created 3 automations which work nearly well.

There is still one thing to solve.
{{ now().strftime("%s")|int + 1200 }} create a waiting time of 1h20 instead of 20m.
Somehow it adds 1 hour extra.

configuration:
input_datetime:
  only_time:
    name: CV Heater
    has_time: true

automation:
trigger:
  - platform: state
    entity_id: climate.kamerthermostaat
    attribute: hvac_action
    to: heating
condition: []
action:
  - service: input_datetime.set_datetime
    target:
      entity_id: input_datetime.only_time
    data:
      timestamp: '{{ now().strftime("%s")|int + 1200 }}'

# Turns off burner at the time specified.
trigger:
  - platform: time
    at: input_datetime.only_time
condition: []
action:
  - service: climate.turn_off
    target:
      entity_id: climate.kamerthermostaat
  - service: input_datetime.set_datetime
    target:
      entity_id: input_datetime.only_time
    data:
      timestamp: '{{ now().strftime("%s")|int + 1200 }}'

# Turns on burner at the time specified.
trigger:
  - platform: time
    at: input_datetime.only_time
condition: []
action:
  - service: climate.turn_on
    target:
      entity_id: climate.kamerthermostaat

What you created there has a few syntax errors but the most crucial problem is that it’s not a functional replacement for a State Trigger’s for option.

Given this:

trigger:
  - platform: state
    entity_id: climate.kamerthermostaat
    attribute: hvac_action
    to: heating
    for: '00:20:00'

it means to trigger when the value of hvac_action changes to heating and remains that way for at least 20 minutes. That means it must be heating for a continuous 20 minutes before it triggers.

What you created behaves differently; it simply sets a future trigger time. That behaves like a delay and nothing else. It doesn’t confirm that the value of hvac_action actually remained heating throughout the 20 minutes.

The for option behaves like a timer. The instant that the value of hvac_action changes to heating, the 20-minute countdown begins. When it expires, the trigger fires. If the value of hvac_action changes from heating to something else like idle during the 20-minute countdown, the countdown timer is reset. It starts again when the value of hvac_action changes to heating.

I think this automation catch it all.
What do you think?

alias: CV-4
description: ''
trigger:
  - platform: state
    entity_id: climate.kamerthermostaat
    attribute: hvac_action
    to: heating
    id: start
  - platform: time
    at: input_datetime.turn_off
    id: 'off'
  - platform: time
    at: input_datetime.turn_on
    id: 'on'
  - platform: homeassistant
    event: start
    id: 'on'
condition: []
action:
  - choose:
      - conditions:
          - condition: template
            value_template: '{{ trigger.id == "start" }}'
        sequence:
          - service: input_datetime.set_datetime
            target:
              entity_id: input_datetime.turn_off
            data:
              timestamp: '{{ now().strftime("%s")|int + 1200 - 3600 }}'
    default: []
  - choose:
      - conditions:
          - condition: template
            value_template: >-
              {{ trigger.id == "off" and state_attr("climate.kamerthermostaat",
              "hvac_action") == "heating" }}
        sequence:
          - service: input_datetime.set_datetime
            target:
              entity_id: input_datetime.turn_on
            data:
              timestamp: '{{ now().strftime("%s")|int + 1200 - 3600 }}'
    default: []
  - choose:
      - conditions:
          - condition: template
            value_template: >-
              {{ trigger.id == "on" or (trigger.id == "off" and
              state_attr("climate.kamerthermostaat", "hvac_action") != "idle")
              }}
        sequence:
          - service: climate.turn_{{ trigger.id }}
            target:
              entity_id: climate.kamerthermostaat
    default: []
mode: single

Like I explained in my previous post, that doesn’t behave like a State Trigger’s for option does. However, if you don’t mind that it doesn’t, then use that.