Delaying a light switch if on for x minutes

Hi all,

Here is wha I am trying to achive…

  1. when the batroom light is switched on - switch it on
  2. When the light is switched off, check for how long it was on for and if on for less than 5minutes, turn it off
  3. If it was on for more than 5 minutes, delay the switching off by another 5minutes.

Seemingly easy but am just not getting it right.
I created a helper, set the duration to 5 minutes and when the light is turned on, start the timer.
Then I’m checking to see if it is still active (ie light was on for less than 5 minutes) or, if it is idle… the light was on more than 5 minutes.

For the life of me I can not make it work, the timer does but the light goes on and off as per the switch (using a sonoff mini2)

alias: Bath2
description: ""
triggers:
  - trigger: state
    entity_id:
      - light.bath2
conditions: []
actions:
  - choose:
      - conditions:
          - condition: state
            entity_id: light.bath2
            to: 'on'
        sequence:
          - action: timer.start
            metadata: {}
            data: {}
            target:
              entity_id: timer.bath2light
      - conditions:
          - condition: state
            entity_id: light.bath2
            to: 'off’
          - condition: state
            entity_id: timer.bath2light
            state:
              - active
        sequence:
          - action: timer.cancel
            metadata: {}
            data: {}
            target:
              entity_id: timer.bath2light
      - conditions:
          - condition: state
            entity_id: light.bath2
            to: 'off’
          - condition: state
            entity_id: timer.bath2light
            state:
              - idle
        sequence:
          - delay:
              hours: 0
              minutes: 5
              seconds: 0
              milliseconds: 0
          - action: light.turn_off
            metadata: {}
            data: {}
            target:
              entity_id: light.bath2
          - action: timer.cancel
            metadata: {}
            data: {}
            target:
              entity_id: timer.bath2light
mode: single

Any suggestions?

You will need to edit your configuration.yaml to define a template binary sensor:

template:
  - binary_sensor:
      - name: "Bath2 Switch Delayed"
        unique_id: bath2_switch_delayed
        device_class: power
        delay_on:
          minutes: 5
        delay_off:
          minutes: 5
        state: >
          {{ is_state('switch.bath2', 'on') }}

Hence this “sensor” will not switch on unless the switch has been on for 5 minutes and if it is switched on, it won’t switch off for 5 minutes after the primary switch goes off.

Then all you need is an automation that or’s both the switch and the delayed version together, i.e.:

mode: single
triggers:
  - trigger: state
    entity_id:
      - switch.bath2
      - binary_sensor.bath2_switch_delayed
conditions: []
actions:
  - action: light.turn_{{ iif(is_state('switch.bath2', 'on') or is_state('binary_sensor.bath2_switch_delayed', 'on'), 'on', 'off') }}
    target:
      entity_id: light.bath2

So in the case the that primary switch is on for less than 5 minutes the delay never happens and as soon as you switch it off the light is turned off.

However if the switch is on for more than 5 minutes the delay “sensor” is triggered and won’t allow the light to turn off for an addition 5 minutes.

this had me smile.

done, forgot to reboot, rebooted and tested…
light on works.
light off below 5 min works too
light off after 5 minutes, switches the light off and on again and repeats it in a loop.

here comes the smile… how do I stop this… heeeelp. Figured out how and now is off again.

I like the idea, I get the thought behind it but don’t quite understand how it all works yet. Will tinker a bit and see what I can come up with.

There is a detail missing somewhere here.

Can you show me the actual YAML you are using for both the template sensor and the automation?

sure

# Loads default set of integrations. Do not remove.
default_config:

# Load frontend themes from the themes folder
frontend:
  themes: !include_dir_merge_named themes

automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml

template:
  - binary_sensor:
      - name: "Bath2 Switch Delayed"
        unique_id: bath2_switch_delayed
        device_class: power
        delay_on:
          minutes: 5
        delay_off:
          minutes: 4
        state: >
          {{ is_state('switch.bath2', 'on') }}

and the automation

alias: Bath2Delay
description: ""
triggers:
  - trigger: state
    entity_id:
      - switch.bath2
      - binary_sensor.bath2_switch_delayed
conditions: []
actions:
  - action: >-
      light.turn_{{ iif(is_state('switch.bath2', 'on') or
      is_state('binary_sensor.bath2_switch_delayed', 'on'), 'on', 'off') }}
    target:
      entity_id: light.bath2
mode: single

I was just about to test a “workaround” hence the 4 minutes

not sure if this matters.

The original is a “switch” that with the help of a helper is now a light.
switch.bath2 → light.bath2

Just saw your update so the light and the bulb are actually just the same switch ?

nope. That is the only automation for that switch. Previous one is deleted.

Let me disable all other automations, not that I have something stupid somewhere. Gimme a few minutes.

The issue here is that the switch and the light are coupled. The automation I gave you assumes that they are independent (switching the bulb doesn’t affect the switch).

If the bulb is really just a helper pointing to the same place, it will cause issues.

I only see two ways to solve this:

  • If the switch has a “decoupled” mode so the switch locally, does nothing without Home Assistant online (then the script above will work as is).
  • Otherwise we are going to need to rework it (but there will be some limitations).

back to no switching off :joy:

gimme a sec to fix that.

removed the light. now is only a switch

Now I just saw your question.

Yes the switch is the only unit turning on/off the light. To make it appear as a light on the dashboard I created the helper.

There is only one device. this one

The image is too small what is exact type of switch ?

SONOFF ZBMINIL2

https://sonoff.tech/products/sonoff-zbmini-extreme-zigbee-smart-switch-zbminil2

Alright here is what I have come up with:

First I created an additional dropdown helper with three states: Off, Arm, Hold

Then I modified the automation to:

mode: single
triggers:
  - trigger: state
    entity_id:
      - binary_sensor.bath2_switch_delayed
    id: Arm
    from: "off"
    to: "on"
  - trigger: state
    entity_id:
      - switch.bath2
    from: "on"
    to: "off"
    id: Light Off
conditions: []
actions:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - Arm
        sequence:
          - action: input_select.select_option
            metadata: {}
            data:
              option: Arm
            target:
              entity_id: input_select.bath2_track_switch
      - conditions:
          - condition: trigger
            id:
              - Light Off
          - condition: state
            entity_id: input_select.bath2_track_switch
            state: Arm
        sequence:
          - action: input_select.select_option
            metadata: {}
            data:
              option: Hold
            target:
              entity_id: input_select.bath2_track_switch
          - action: switch.turn_on
            metadata: {}
            data: {}
            target:
              entity_id: switch.bath2
          - delay:
              hours: 0
              minutes: 5
              seconds: 0
              milliseconds: 0
          - action: switch.turn_off
            metadata: {}
            data: {}
            target:
              entity_id: switch.bath2
          - action: input_select.select_option
            metadata: {}
            data:
              option: "Off"
            target:
              entity_id: input_select.bath2_track_switch

The first trigger condition “Arms” the hold if the binary sensor triggers (just changes the select to “Arm”).

The second condition is triggered if the light is turned Off AND the hold is Arm(ed), in which case it will run the final sequence to turn the light back on wait 5 minutes then turn it off again.

holy molly :scream:

this is very interesting indeed. let me try

thank you for your efforts :pray:
steep learning curve

So I was able to simplify what I had, however I am not as confident that I haven’t missed something, anyway here is a simpler version:

mode: single
triggers:
  - trigger: state
    entity_id:
      - binary_sensor.bath2_switch_delayed
    from: "off"
    to: "on"
conditions: []
actions:
  - wait_for_trigger:
      - trigger: state
        entity_id:
          - switch.bath2
        from: "on"
        to: "off"
    continue_on_timeout: false
  - action: switch.turn_on
    metadata: {}
    data: {}
    target:
      entity_id: switch.bath2
  - delay:
      hours: 0
      minutes: 5
      seconds: 0
      milliseconds: 0
  - action: switch.turn_off
    metadata: {}
    data: {}
    target:
      entity_id: switch.bath2

It does the same thing as my verbose version but leverages that fact that a script can be paused waiting for a condition to become true.

interesting.

to your first post

I set the timer to 2 minutes

switch on, wait shorter that 2 minutes, switch off - works
switch on, wait longer that 2 minutes - as expected, it turns off for a second and right back on. BUT… it does not turn off after set 2 minutes.

Still digesting and dissecting your code.

the simpler version is just switching on and off.

Time seems to have no effect

There is however a delay in switching on and off in succession.

wish I could send a video.

I"ll tinker a bit more, see what I can break.

There are now two places to set the time:

  • In the Automation
  • In the binary sensor.

And every time you change the time in the binary sensor you need to restart HA (just reloading the config doesn’t work).

For sanities sake I would just set all three:

  • Sensor: delay_on
  • Sensor: delay_off
  • Automation: delay

To 30 seconds.

Restart HA.
Then try again.

You got me thinking …
seeing the switch has to turn off because it ,think you called it detached, does not have that feature, why not test for how long it was on for…

few searches later

this is what I found and adapted. works perfectly

alias: Bath2 Test500
description: ""
triggers:
  - entity_id:
      - switch.bath2
    to:
      - "off"
    trigger: state
conditions:
  - condition: template
    value_template: >
      {{ (now() | as_timestamp) - (trigger.from_state.last_changed |
      as_timestamp) > 300 }}
actions:
  - action: switch.turn_on
    metadata: {}
    data: {}
    target:
      entity_id: switch.bath2
  - delay:
      hours: 0
      minutes: 3
      seconds: 20
      milliseconds: 0
  - action: switch.turn_off
    metadata: {}
    data: {}
    target:
      entity_id: switch.bath2
mode: single

I really appreciate your efforts, now I have a lot more code to understand and hopefully will become more proficient soon.

Glad you got it working.

And thank you for posting your solution.

One caveat, I foresee:

  • Your trigger time is 5 minutes (300 seconds).
  • Your hold (on) time is 3 minutes 20 (200 seconds).

I think your hold time MUST always be less than your trigger time or it will cause the same issue that we started with (the hold will keep triggering a new hold each time it ends).

However with the setting you have here, I believe it should work fine.

1 Like