Logic check - second set of eyes needed

Hi Everyone,

Back again with another logic problem that I think I have licked but a second set of eyes wouldn’t hurt.

Problem: I have a mudroom with an automation that turns lights based on motion. 2 minutes after the lights have been on, turn lights off.

At it’s most basic level, this works fine. However, I have noticed (and found several threads) where “stacked timers” interfere with shutting off the light if it’s turned on and off again during automation timer. I’ve seen methods like using a script timer reset to work around this. I’ve tried trigger templates (which I’ve seen require sensor.time as apparently now() doesn’t work in trigger templates–haven’t been successful in trying this but that could be my own inexperience.)

So I decided to do this instead, I think my logic is correct here based on observation while at the same time defeating the “stacked timer” effect:

- alias: Auto Turn Off Mudroom
  trigger:
    - platform: state
      entity_id: light.mudroom
      to: 'on'
      for:
        minutes: 2
**new**
  condition:
    condition: or
    conditions:
      - condition: template
        value_template: '{{ as_timestamp(now()) - as_timestamp(states.automation.auto_turn_off_mudroom.attributes.last_triggered) | int > 120 }}'
      - condition: template
        value_template: '{% if states.automation.auto_turn_off_mudroom.attributes.last_triggered == none %}true{% endif %}'
**new**
  action:
    - service: homeassistant.turn_off
      entity_id: light.mudroom

Idea being that if:

(my new automation code is in between the new section, basically, the condition check)

  1. Mudroom lights have been on for 2 minutes, turn them off if:
    a) The last time this automation was last_triggered is greater than 2 minutes, or
    b) The last time this automation was last_triggered was never

Is this logic sound?

Thanks in advance!

Dry delay instead of for

Thanks, I tried that previously as well. Still results in a stacked timer end result.

I haven’t actually tried my new version yet (will when I get home) but I think it will get around the problem but was hoping to have more eyes weigh in :slight_smile:

I get the same result noted here:

From this thread:

Seems to work and has the added benefit of resetting the timer for shut-off as well when multiple motion events happen after it’s already turned on. Nice.

Will continue to test.

Nope - don’t quite think it works like I think it does. Will continue to plug away here.

You could introduce a Boolean sensor in this?
With that you break it up in two automations.
The first one acts on the motion sensor and does two things: turn on the light and sets the Boolean to “on”.
Then you have a second automation that monitors the Boolean sensor. Once that reaches 2 minutes of being “on” it turns off the light, and sets the Boolean back to “off”.
I must admit that I’m not 100% sure from your description what you’re trying to achieve, but I would think that the booleans give you the flexibility you need, even if it is slightly different from what I described above.

I can try that too. I think it’s actually working but it’s hard to reproduce on demand it seems (the issues I’m trying to overcome.)

Basically as @Pilot wrote above (from the other thread) is that when there are multiple instances of an automation fired where a timer is attached (in my case, and his in that thread, using “for:” – even happens with with “delay:”) that a series of timers stack up causing an automation to fire multiple times rather than being atomic (if that makes sense.)

Right now it’s definitely turning off the light – I’ve tried turning on the light manually via dashboard and waiting for it to turn off, which it does. I’m trying to reproduce a scenario I encountered where the automation to turn off the lights builds multiple “off timers” and turns it off at random times.

Basically:

  • Light turns on, light turns off by human before 2 min
  • Light turns on, stays on for 1 min, turned off by automation as timer still counting

It was easier to reproduce with bigger time frames (I used to have it turning off @ 5min instead of @ 2min) so it’s a bit slow-going to repo the issue :slight_smile: But a boolean as a switch to check whether to turn off may also work (but that’s why I used last_triggered for the automation > 120; same logic being applied–in my mind anyways.)

I have actually done this, I’ll post my code shortly.

But you need 2 services in your automation :slight_smile

action:
- service: homeassistant.turn_on
entity_id: light.mudroom
- service: homeassistant.turn_off
entity_id: light.mudroom
delay: ‘2.00’

This will turn it on, then run the automation to turn it off 2 mins later.

Like you, Ive stopped using motinOff and used a delay to keep it on.

Thanks, appreciate the input. I have two automation, ones that turns the light on and one that turns it off. I’ve tried delay and for: and both produce same results. Your example above is pretty much what I have except you’re using the delay for off whereas I tried delay: and for: (stuck with for:) – It’s a pretty specific use-case I think that I’m working on.

I think I might have it licked. So here’s the automation:

- alias: Auto Turn Off Mudroom
  trigger:
    - platform: state
      entity_id: light.mudroom
      to: 'on'
      for:
        minutes: 1
  condition:
    condition: or
    conditions:
      - condition: template
        value_template: '{{ as_timestamp(now()) - as_timestamp(states.automation.auto_turn_off_mudroom.attributes.last_triggered) | int > 60 }}'
      - condition: template
        value_template: '{% if states.automation.auto_turn_off_mudroom.attributes.last_triggered == none %}true{% endif %}'
      - condition: template
        value_template: '{{ as_timestamp(now()) - as_timestamp(states.automation.mudroom_motion.attributes.last_triggered) | int > 60 }}'
  action:
    - service: homeassistant.turn_off
      entity_id: light.mudroom

Basically I check three things:

  1. Is the time for the automation to turn off lights last_triggered > 60 seconds
  2. Or is the time for the automation to turn off lights last_triggered = never
  3. Or is the time for the automation to turn ON lights last_triggered > 60 seconds

I believe this will solve the stacked timer problem. Will continue to test but just wanted to post some results I’ve had so far. I haven’t had any wonky-random shut-off’s by having these three checks which should stop any future timers from firing out of band (I think… logic seems sound to me as I understand it.)