Just something I’ve been thinking about for a while. I have an automation that is triggered by a line crossing alert in my driveway. Works great 95% of the time. Sometimes, there are kids playing in the driveway while I’m away (which is ok), but it ends up triggering a lot of alerts. I have other automation that I use a condition to not run if it has ran in the last minute, but in this case I’d like something more like a count, etc.
Something like if you’ve sent 5 alerts i the past 5 minutes, then turn off the automation for 5 minutes then turn it back on. Or something like that, I’ve having trouble thinking of the best way to do that.
I could see this being useful for other stuff as well. Anyone done anything similiar?
You could probably use an automation to control the automation, so have a 2nd automation that turns your driveway automation off if a certain number of alerts are sent.
This should work because, AFAIK, an automation cant re-trigger while it’s running, so the delay action will keep the automation running for 5 minutes keeping it from re-triggering during that time.
I’m just writing this freehand, so it might not work right off the bat, but it’s the general idea.
What it should do is on every detection of motion, if the disabeler boolean is off, send an alert, increment the counter, and start a timer (or reset if already running).
If the counter exceeds 5 counts, it will turn on the disabeler boolean stopping further alerts. After 5 minutes it will turn the disabeler boolean off, and reset the counter.
If 5 minutes pass since the last motion trigger, the counter will be reset.
I edited my psudo code a bit, but I think you might be able to reduce it by 1 automation and get rid of the input bool by making the counter being under 5 a condition of the alert, and just have the timer reset it after 5 minutes after the last time it was triggered.
I can’t test any of it at the moment, but I’m sure you get the idea. Good luck!
The only thing that I need to tweak, is that with the timer approach as is, it could disable if I had one motion event every 4 minutes and 59 seconds over a period of 25 minutes. (I think so anyway), I’m looking to turn off if I get a lot of alerts in a short (5 minute) time.
This is super close, I think I can get it.
As I was typing this, I remembered a great example of what I’m trying to accomplish.
I have one camera that wasp’s seem to love. Sometimes a wasp will crawl over the lens, triggering alerts, and I end up with 20 alerts in a 10 minute period, etc. In that case I’d just like to turn it off for a few minutes and then back on, hopefully the wasp has moved on to somewhere else.
Here’s a simple one liner using the last time the automation was triggered. Doesn’t have as advanced a cooling off system but for most of my cases this does the trick.
- condition: template # Throttle by not triggering push messages if triggered in the last 10 seconds
value_template: >
{{ not state_attr('automation.doorbell','last_triggered') or (as_timestamp(now()) - as_timestamp(state_attr('automation.doorbell','last_triggered'))) > 10 }}
So I use the condition further down in my automation and by that point it’s already changed the last_triggered as per the changes on this recent release.
Maybe if the condition is right below the trigger this won’t happen.
This worked for me. In the UI, after the action I actually need the automation to run, I added an “action” and chose “wait for time to pass”. This worked because the automation does not re-run while it is running, but it still runs immediately if it was not recently triggered.
I just had to do a cooldown so I’ll offer this as another option. With the introduction of timer helpers, we now have an easy way to do cooldowns that aren’t impacted by HA restarts.
I have an automation that sends me an image when there is someone detected at my front door. However if my kids are playing in the front yard, I don’t want to be barraged by notifications. So I used a cooldown timer so that I wouldn’t be notified unless 5 minutes have passed since a person was last detected.
This automation triggers when a person is detected. It only sends a notification if the timer is expired. And then it starts (or restarts) the timer.
alias: Front Door Image when Person is Detected
description: ""
trigger:
- platform: state
entity_id: sensor.front_door_detected_object
to: person
action:
- if:
- condition: state
entity_id: timer.front_door_notification_cooldown
state: idle
then:
- service: camera.snapshot
data:
filename: /config/www/obscurefilename.jpg
target:
entity_id: camera.front_door
- service: notify.mobile_app_my_phone
data:
title: Front Door Motion!
message: Long-press to view image
data:
image: /local/obscurefilename.jpg
- service: timer.start
data: {}
target:
entity_id: timer.front_door_notification_cooldown
mode: single
Hey guys, I have a question. I’m not great with yaml, but I have a slightly more elaborate cooldown in a python script I use that I hope to use the same logic in yaml.
Basically, the cooldown is incremental from the last cooldown. So if an automation triggers and the PreviousCooldown + cooldown is more than the CurrentTime + cooldown, then add cooldown to the PreviousCooldown and don’t trigger. Else PreviousCooldown = CurrentTime + cooldown
So basically the more activity you have, the increasingly fewer triggers you’ll have, until time clears.
Here is the python logic using pickle (as it has to save the previous time, not sure how to achieve this with Home Assistant)
def coolDownTimer(secondsCool, picklename):
currentTime = datetime.datetime.now()
currentTimeCoolDown = datetime.datetime.now() + datetime.timedelta(seconds=secondsCool)
try:
with open(picklename, 'rb') as f: # Using Pickle to make sure to not send duplicate notifications
previousTime = pickle.load(f)
print("Previous Time: %s" % previousTime)
print("Current Time: %s" % currentTime)
with open(picklename, 'wb') as f:
pickle.dump(currentTimeCoolDown, f, pickle.HIGHEST_PROTOCOL)
except EOFError:
with open(picklename, 'wb') as f:
pickle.dump(currentTimeCoolDown, f, pickle.HIGHEST_PROTOCOL)
except FileNotFoundError:
os.open(picklename, os.O_CREAT | os.O_EXCL)
if currentTime > previousTime:
print(currentTime > previousTime)
return True;
if currentTime < previousTime:
print("COOL DOWN STILL ACTIVE")
with open(picklename, 'wb') as f:
extraCoolDown = previousTime + datetime.timedelta(seconds=secondsCool)
pickle.dump(extraCoolDown, f, pickle.HIGHEST_PROTOCOL)
return False;