Automation loop on/off

Hi everybody,

I currently need to turn on an infrared heater every x minutes, then turn it off for y minutes, then turn it back on for x minutes, and so forth.

As I haven’t changed my Home Assistant configuration in quite a while, I don’t know what’s currently the best way to do this (as some things that used to be difficult have seemed to improve a lot!).

I thought of creating

  • input_boolean.onofftimer => use this entity’s state to trigger the automation
  • input_datetime.onoff_durationon => how long should the switch be on off
  • input_datetime.onoff_durationoff => how long should the switch be off for

Whether or not the switch is currently off can be determined via switch.onofftimer. This is the tasmota smart outlet I use to control the infrared heater.

I just don’t know how to write the automation in order to

  • IF input_boolean.onofftimer is on, then
  • turn on switch.onofftimer
  • delay for time defined via input_datetime.onoff_durationon
  • turn off switch.onofftimer
  • delay for time defined via input_datetime.onoff_durationoff
  • repeat until input_boolean.onofftimer is switched off

The automation itself is easy, but I don’t know how to loop it until input_boolean.onofftimer is switched off.

I thought of calling the automation itself at the very end (after the “off” delay)… but if I do this, it will constantly run, even when input_boolean.onofftimer is switched off, correct? Because once the loop starts, it will no longer check whether or not the boolean is still switched on.

Can you please help me create this automation? There is moisture in a brick wall in my house and I need to manually do this at the moment. Which is fine, but automating it without having to worry that I leave it on too long (or forgot to turn it back on at all) would be really nice.

Thank you in advance for your ideas :slight_smile:

The simplest way is with two input numbers that hold the on/off durations you want and two automations:

- alias: heater_on
  trigger: 
    platform: state
    entity_id: switch.onofftimer
    state: 'off'
    for:
      minutes: input_number.off_time
  action:
    service: switch.turn_on
    entity_id: switch.onofftimer

- alias: heater_off
  trigger: 
    platform: state
    entity_id: switch.onofftimer
    state: 'on'
    for:
      minutes: input_number.on_time
  action:
    service: switch.turn_off
    entity_id: switch.onofftimer

This will repeat for ever. To disable it from running, turn off automation.heater_on, no need for an input boolean. You can schedule the automation state a number of ways if you have known times you want this to run. Or just do it manually from a Lovelace card.

Put automation.heater_on and the two input numbers in an entities card. You can make it pretty with icons and friendly names directly in the Lovelace card, or the entity configuration (for the input numbers) or by using customize.

1 Like

I created something similar for another community member. You may want to adapt it for your requirements.

It operates a towel warmer during two time periods: 06:00-9:00 and 19:00-00:00. It turns on the towel warmer for 15 minutes and then turns it off for 10 minutes. It repeats this pattern continuously during each of the two time periods.

- alias: Towel_warmer_morning_and_evening
  trigger:
  - platform: time
    at:
    - 06:00:00
    - 09:00:00
    - 19:00:00
    - 00:00:00
  action:
  - choose:
    - conditions: '{{ trigger.now.hour == 6 or trigger.now.hour == 19 }}'
      sequence:
      - repeat:
          while: '{{ 6 <= now().hour < 9 or 19 <= now().hour <= 23 }}'
          sequence:
          - service: switch.turn_on
            entity_id: switch.towel_warmer
          - delay: 00:15:00
          - service: switch.turn_on
            entity_id: switch.towel_warmer
          - delay: 00:10:00
    default:
    - service: switch.turn_off
      entity_id: switch.towel_warmer

Let me know if you need help modifying it.

1 Like

Thank you both for your solutions @tom_l @123 :100:

I will test the first solution, because it is easier. I always have trouble with the jinja2 scripting, but will take the second solution as an opportunity to understand the syntax better :slight_smile:

Go with what works for you.

The automation I posted not only cycles the heater on/off but also schedules when this cycling should occur. Let me know if you need any part of it explained.

1 Like

Could someone please help me with this automation. I can’t figure out where the “service: switch.turn_off” is coming from and also the “state: ‘off’” is confusing me, since there is only From and To available in the state trigger type?
This is what I have from creating via gui:

- id: '1628182722088'
  alias: 'on'
  description: ''
  trigger:
  - platform: state
    entity_id: switch.bugzap
    to: 'off'
    for: 'minutes: input_number.on_time'
  condition: []
  action:
  - type: turn_on
    device_id: fa3c9776825c102e498a58625a406253
    entity_id: switch.bugzap
    domain: switch
  mode: single

It’s a typo. state should be to.

For some reason I couldn’t get tom_l’s code to work with input_number.on_time and input_number.off_time . I had to use jinja variable format. I’m posting my code below if anyone runs into the same issue.

- id: '0000000000002'
  alias: heater_on
  trigger:
  - platform: state
    entity_id: switch.onofftimer
    to: 'off'
    for: 
      minutes:  "{{ states('input_number.off_time')|int }}"    
  condition: []
  action:
  - service: switch.turn_on
    target:
      entity_id: switch.onofftimer
  mode: single
- id: '0000000000001'
  alias: heater_off
  trigger:
  - platform: state
    entity_id: switch.onofftimer
    to: 'on'
    for: 
      minutes:  "{{ states('input_number.on_time')|int }}"
  condition: []
  action:
  - service: switch.turn_off
    target:
      entity_id: switch.onofftimer
  mode: single

The only issue I have now is that this loop doesn’t start until I manually toggle the switch. Once the switch is toggled it runs fine.

Actually, the simplest solution is to sit there with a stopwatch. The next simplest … that actually worked for me … was to build a couple of timers (ucontroller, opto-isolator and triac) and connect this to a standard Zigbee power switch.

This lets me keep a light bulb on under my hummingbird feeders without the feeder getting too hot. (Without the heat source, the sugar water will freeze and the little guys will starve.)

I surely didn’t want to go this route. After all, I already have a running microcontroller here … a Raspberry PI! SURELY, I thought, I can use the timers inherent in HA.

Only I was never able to.

I copied and pasted all the various “solutions” in this thread, substituting my device names for the ones in the suggestions. Then I went so far as to systematically removing a device and adding it back using the names in the suggestions. I also removed the “input_number.on_time” variable and replaced it with a simple value.

Every change was followed by a reboot, as that’s the only reliable way that I’ve discovered of getting a manually changed automation to run. (It’s a pretty frustrating process, BTW, waiting many many minutes for HA to come back.)

Universally, one of two things would happen. HA would choose to run in safe mode, or (much more commonly), HA would declare “This entity is currently unavailable and is an orphan to a removed, changed or dysfunctional integration or device.”

So I just built some timers using an ESP8266 and using the update over WiFi feature, I can change the timer values without going outside.

I think it’s NUTS that it’s so hard hard to get a computer to go “On for 10 minutes, Off for 20, On for 10 minutes, Off for 20”, but with HA, that seems to be the case.