Activate automation as long as device is turned on

Hey there,
I have been using home automation for several years now using another platform (pimatic). Now I decided to migrate my setup over to HA as here is a way more active development going on.
I have a bunch of simple switches controlling all lights in my house and also for the underfloorheating in every room.
I also use MQTT to controll al this and also a electric bathroom heater. In my old software I had to use multiple rules to automate it, but I think with the scripting ability of HA there might be a much simpler way.
I want to create a simple switch to enable or disable that specific bathroom heater. In case it gets activated it should first close the heating valve (to avoid dissipating that heat throughout the entire house) and activate a kind of loop, e.g. 10min activating the heater and 10min waiting (to avoid too high temps at the surface) for let’s say 2 hours (or 6 loops). After that it should stop and open the valve again another hour later and disable the controlling switch again. In case the switch get’s disabled inbetween by a user it should stop the heating loop and also open the valve one hour later.
Is that possible with a single or maybe 2 automation rules? In my old setup I used something like 5 rules to get this behaviour.

Thanks in advance,
4nduril

Hi @4nduril ,
It’s challenging to give you an easy answer.
For as far as I understand your question, it’s very likely possible.

You can just create an automation with multiple triggers and in your actions you can link one or more actions to a trigger using choose.

So one trigger could be a click on a switch button, the other trigger could be a “heater on for 1hr”.

I’d suggest to start with a simple automation and work from that point forward. It’s easier to help if you post the YAML code of your automation if you have any question.

Hi @Recte
thank you four your tips. I could not completely follow, as my understanding on the advanced automation tricks is very limited. I just tried to build it as close to my wishes as possible to discuss.

alias: Heizungskörpersteuerung oben
description: ''
trigger:
  - platform: state
    entity_id: switch.flur_keller
    to: 'on'
condition: []
action:
  - service: switch.turn_off
    target:
      entity_id: switch.hv_handtuchheizung_og
  - repeat:
      while:
        - condition: state
          entity_id: switch.flur_keller
          state: 'on'
      sequence:
        - service: switch.turn_on
          target:
            entity_id: switch.arbeitszimmer_matthias
        - delay:
            hours: 0
            minutes: 0
            seconds: 10
            milliseconds: 0
        - service: switch.turn_off
          target:
            entity_id: switch.arbeitszimmer_matthias
        - delay:
            hours: 0
            minutes: 0
            seconds: 10
            milliseconds: 0
  - delay:
      hours: 0
      minutes: 5
      seconds: 0
      milliseconds: 0
  - service: switch.turn_on
    target:
      entity_id: switch.hv_handtuchheizung_og
  - service: switch.turn_off
    target:
      entity_id: switch.flur_keller
mode: single

I just changed the heating switch to a light switch for me to be able to see it working. The option I could not yet reproduce is that it should disable the loop after a few cycles, so maybe a counter variable or time might be a solution. Can someone help with that?

edit:
I did some further testing with your idea of using choose. I did end up using 3 choose conditions, one for activation, one for deactivation and one for long running
 the first of these two work as expected, but the last one does not trigger. Any tips?
Also I changed the mode to restart, is that correct? I think that better suits my needs.

alias: Heizungskörpersteuerung oben
description: ''
trigger:
  - platform: state
    entity_id: switch.heizkorpersteuerung_oben
condition: []
action:
  - choose:
      - conditions:
          - condition: state
            entity_id: switch.heizkorpersteuerung_oben
            state: 'on'
        sequence:
          - service: switch.turn_off
            target:
              entity_id: switch.hv_handtuchheizung_og
          - repeat:
              while:
                - condition: state
                  entity_id: switch.heizkorpersteuerung_oben
                  state: 'on'
              sequence:
                - service: switch.turn_on
                  target:
                    entity_id: switch.arbeitszimmer_matthias
                - delay:
                    hours: 0
                    minutes: 0
                    seconds: 10
                    milliseconds: 0
                - service: switch.turn_off
                  target:
                    entity_id: switch.arbeitszimmer_matthias
                - delay:
                    hours: 0
                    minutes: 0
                    seconds: 10
                    milliseconds: 0
      - conditions:
          - condition: state
            entity_id: automation.heizungskorpersteuerung_oben
            state: 'on'
            for: '3:00'
        sequence:
          - service: notify.mobile_app_matthias_handy
            data:
              message: Heizkörpersteueung ist zu lange an
              title: HA
          - service: switch.turn_off
            target:
              entity_id: switch.heizkorpersteuerung_oben
      - conditions:
          - condition: state
            entity_id: automation.heizungskorpersteuerung_oben
            state: 'off'
        sequence:
          - service: switch.turn_off
            target:
              entity_id: switch.handtuchhalter
          - delay:
              hours: 1
              minutes: 0
              seconds: 0
              milliseconds: 0
          - service: switch.turn_on
            target:
              entity_id: switch.hv_handtuchheizung_og
          - service: notify.mobile_app_matthias_handy
            data:
              title: HA
              message: Heizkörpersteuerung ist jetzt aus
    default: []
mode: restart

Regards,
4nduril

Use the state of the switch as a trigger for the automation, but don’t use from or to.

Use choose to find out if the switch is on or off.

If on -
Instead of using repeat while, use repeat count. Then at the start of the repeat sequence, you use a choose to check whether the state of the switch is still on. You only run the cycle again in the event that the switch is still on. (This is probably unnecessary with the mode set to restart though)
Then finally outside the repeat cycle, you use call service to turn the switch off. That will of course re-trigger the automation.

Now the automation will follow the other choose branch because the state of the switch is now off. Personally I would use a timer helper at this point, but you can just use a delay if you want to wait an hour and then open the valve.

Hope that helps you.

(Using timer helpers - means that you can have timers in an entity card, so you can see that things are actually working when you have it “in production”. If you use timer helpers, instead of using delays, you would use wait_for_trigger, and listen for the platform event of timer.finished
At the very start of the automation whether the switch is turned on or off (so before the choose) cancel all the timers you will use. That way if the switch is turned off, it will cancel all the timers.)

I started doing this a month back and it helped consolidate a large number of ON → OFF and OFF → ON automations.

The problem I discovered is that if you ever reboot a switch, and the HA state goes from OFF → UNAVAILABLE → OFF then you trigger the automation. This was undesirable.

Therefore modifying the state trigger to include from:off to:on and vice-versa with two state triggers. I was able to retain the choose action while avoiding triggering on unknown or unavailable states.

Hope this helps.

It shouldn’t really matter if you are checking the state of the switch in the choose block. If it isn’t on or off then the automation will execute the default block, which if it’s empty, will mean the automation runs and does nothing.

This statement is true for any OFF → UNAVAILBLE transition. The problem tends to occur when the device/sensor comes back and goes UNAVAILBLE → OFF.

I noticed this for a Tasmota light switch that was dropping off wifi. When it came back on wifi, it triggered the “off automation”. Which was undesirable. Think three-way switch that magically says, “hey I’m off, so you should be on!”

So I began ensuring that any state-based automation had to include ON → OFF and OFF → ON triggers in order to avoid any transition based on none/unknown/unavailable/etc.

You could of course also use a template condition:

{{ trigger.from_state.state != 'unavailable' and trigger.to_state.state != 'unavailable' }}

That would stop the automation from doing anything at all, if the previous or current state is unavailable.

Absolutely. I also include none and unknown in that list.

Wanted to make sure OP had considered this somewhat innocent, yet relevant scenario, when using a blank state trigger.

[edit] suppose it is also handy to link this as another consideration; 2021.12: New configuration menu, the button entity, and gorgeous area cards! - Home Assistant

1 Like

Absolutely, we all start somewhere. And I am still in awe on an almost daily basis when some of the really knowledgeable members come along and reduce complex automations with multiple choose statements down to really elegant small automations with no choose statements.

1 Like

Thank you all for your great help.
@mobile.andrew.jones I did the automation as you suggested and it tested fine. I will change that to the productive switches and test it in real life - hope it works
 my wife will get angry if I ‘brake’ the heater algorithm :cold_face:
@crlogic thanks also for your hint. As those switches are just my own python script connecting mqtt to the physical device I know it will be no problem in this case, but being aware of that is always good.

2 Likes

Hmmmm
 I have to be honest and only scanned your automation quickly. If I am right, you are basically running your automation 24x7 and rely on one or more delays and state timers. That’s a risk and this is why.

Every automation you save will shortly disable → enable all automations that are enabled at that moment. As a result, your delay and state timer is killed and your automation isn’t running anymore. I believe I once reported it as a bug, but lost track of it and believe it’s still there.

So
 I’d consider/suggest a more reliable construction two using automations.
Automation 1 is the 10 second loop (automation.heizungskorpersteuerung_oben), using a time pattern trigger.
Automation 2 toggles the ‘automation.heizungskorpersteuerung_oben’ (on <-> off)

Automation 1 could look like:

alias: Heizungskörpersteuerung oben
description: ''
trigger:
  - platform: time_pattern
    seconds: /10
    id: Every 10 sec
condition: []
action:
  - service: switch.toggle
    target:
      entity_id: switch.hv_handtuchheizung_og
mode: single

Automation 2 is a bit more challenging since there are scenario’s like reboots and other stuff that could cause surprises in your schedule. I expect a reboot resets your state timers and you somehow need to catch that scenario. I’ve choose to use a datetime helper that triggers. That could look like this:

alias: Heizungskörpersteuerung automation manager
description: ''
trigger:
  - platform: homeassistant
    event: start
    id: Reboot
  - platform: time
    id: Time 2 Toggle
    at: input_datetime.heizungskorpersteuerung_toggle
condition: []
action:
  - choose:
      - conditions:
          - condition: or
            conditions:
              - condition: trigger
                id: Time 2 Toggle
              - condition: and
                conditions:
                  - condition: trigger
                    id: Reboot
                  - condition: time
                    after: input_datetime.heizungskorpersteuerung_toggle
        sequence:
          - service: automation.toggle
            target:
              entity_id: automation.heizungskorpersteuerung_oben
          - choose:
              - conditions:
                  - condition: state
                    entity_id: automation.heizungskorpersteuerung_oben
                    state: 'on'
                sequence:
                  - service: input_datetime.set_datetime
                    target:
                      entity_id: input_datetime.heizungskorpersteuerung_toggle
                    data:
                      timestamp: '{{ as_timestamp(now())|int + 3*60*60 }}'
            default:
              - service: input_datetime.set_datetime
                target:
                  entity_id: input_datetime.heizungskorpersteuerung_toggle
                data:
                  timestamp: '{{ as_timestamp(now())|int + 1*60*60 }}'
              - service: switch.turn_off
                target:
                  entity_id: switch.heizkorpersteuerung_oben
    default: []
mode: single

For the record, this is just a simplified example meant to inspire in finding a good solution. You could use more templating to reduce the number of lines, but I wanted to keep it as simple/basic as possible, even though it’s harder to read in YAML.

Automation 2 requires a datetime helper named ‘input_datetime.heizungskorpersteuerung_toggle’, but you can name it anything you want of course.

I hope this brings you to a reliable and predictable automation.

Hello, i`m absolute beginner, so please look excuse my maybe stupid question.

Would you please post an code example of how you would turn on an device as long the state is ON.

Do i have to add an action for turning OFF when State is OFF?

many thanks in advance!