Trigger only once in a certain timeframe

I have a configuration issue. I want to receive a message when one of my presence sensors detects presence while nobody is at home. See my config:

  • alias: Presence Detected
    initial_state: on
    trigger:
    • platform: state
      entity_id: sensor.keuken_presence
      to: ‘True’
      condition:
      condition: state
      entity_id: group.Family
      state: ‘not_home’
      action:
    • service: notify.pb
      data:
      title: Keuken
      message: Presence Detected while nobody is home

This works without any problem. The problem is that if the sensor is triggered a second/third time in a short time frame I do not want to receive a message again.

Is it possible to receive only a message once every half an hour?

It’s possible to do but it will take some logic.

I would probably go this route:

Create a counter that starts at 0.

docs:

Create a script that starts the timer-delayed-script, the outcome of this script would be to reset the counter instead of turning off the light.

alias: Light Timer
sequence:
  - delay:
      minutes: 2
  - service: switch.turn_off
    data:
      entity_id: switch.entry_s_switch_17_0

create a script that cancels the timer and restarts it.

alias: Door is Open
sequence:
  # Cancel ev. old timers
  - service: script.turn_off
    data:
      entity_id: script.light_timer
  # Set new timer
  - service: script.turn_on
    data:
      entity_id: script.light_timer

Then in your automation, add a condition to check the counter. If the counter is less than 1, fire the notification.

This isn’t the “correct” way to do it, its just one way to do it. I’m sure some other minds could come up with a different solution.

Basically what would happen here is that you would fire your notification, it would add a count to the counter. At the end of the timer, the counter would be reset to zero. Any time the event is fired within 2 minutes of a previous event, it would restart the timer and increment the counter. It wouldn’t reset until there was a full 2 minutes of no movement.

How about using the last_triggered portion of the sensor with a time-check? It’s my favourite go-to lately:

conditions:
  - condition: template
    value_template: '{{ as_timestamp(now()) - as_timestamp(states.automation.auto_turn_off_hallway.attributes.last_triggered) | int > 60 }}'
  - condition: template
    value_template: '{% if states.automation.auto_turn_off_hallway.attributes.last_triggered == none %}True{% else %}False{% endif %}'
  - condition: template
    value_template: '{{ as_timestamp(now()) - as_timestamp(states.automation.hallwaymotion.attributes.last_triggered) | int > 60 }}'
6 Likes

Yah that would work too. TIL

Just an FYI, did you know that you could simplfy this line:
{% if states.automation.auto_turn_off_hallway.attributes.last_triggered == none %}True{% else %}False{% endif %}

to
‘{{ states.automation.auto_turn_off_hallway.attributes.last_triggered == none }}’

2 Likes

Thanks. I was running from template editor as such and wanted output so I can could the result (as I was pasting all three expressions in so I could see: True, True, False sort of thing) :slight_smile: Never bothered changing it after that.

1 Like

Thanks Petro and chrisw for your quick reply! Super!

Never realized that an automation also had it’s own states and attributes. Now I changed into this and I quickly did some tests and it seems to work:

  • alias: Presence Detected
    initial_state: on
    trigger:
    • platform: state
      entity_id: sensor.keuken_presence
      to: ‘True’
      condition:
      condition: and
      conditions:
      • condition: state
        entity_id: group.Family
        state: ‘not_home’
      • condition: template
        value_template: ‘{{ as_timestamp(now()) - as_timestamp(states.automation.presence_detected.attributes.last_triggered) | int > 1800 }}’
        action:
    • service: notify.pb
      data:
      title: Keuken
      message: Presence Detected while nobody is home
1 Like

@Pdejong You should check, if your template condition is really working, especially after restarting home assistant. You may test this in the template editor.

As long as states.automation.presence_detected.attributes.last_triggered returns none after a restart, the template {{ as_timestamp(now()) - as_timestamp(states.automation.presence_detected.attributes.last_triggered) | int > 1800 }} doesn’t work as expected, as the as_timestamp() function doesn’t deal well with a none value as input paramenter. The condition will never become true and your automation will never trigger.

You have to test for states.automation.presence_detected.attributes.last_triggered == none separately to catch the none value.

Thank you for this suggestion - a small improvement (maybe). If you subtract two dates, you get a time delta object that has a seconds property which is super easy to futz with:

conditions:
  - condition: template
    value_template: {{ (now()-states.automation.auto_turn_off_hallway.attributes.last_triggered).seconds > 60 }}

That would error if last_triggered is none. All automation last_triggered attributes get set to none on restart. as_timestamp() handles none as an input, which is why it’s a safer option.