Goal: Only wake up only when there is a real problem.
Context: I’m trying to get rid of the problem of false positives in my home security setup. A PIR can trigger because of a sudden temperature change, without a real human being around. A camera can mistake a dog’s movement for a human. But several PIRs or Camera triggering within a timeframe of say 90 secondsis extremely unlikely to be a false positive.
Setup: I’ve two types of motion detectors (all are of binary_sensor)
The first group contains the PIRs (group.PIRs). They are basic (but good) Neo Cam Zwave PIRs
The second group contains the camera (group.cameras). They are Dahua PTZs, being piloted by BlueIris, which triggers an MQTT request to turn a motion sensor on if the camera has a confirmed (meaning post-AI treatment) alert. Long story short, if a PTZ sees someone moving in-between zones or jumping over a fence, it turns a binary_sensor on for 60 seconds.
All those motion sensors are part of the same group.security
Problem: I’d like to find a way to “sum” the number of motion_sensors that turned to state “on” within the last 90 seconds and then triggers some automation (make the “dog bark” over sonos, notify myself, turn on lights, trip alarm, close blinds, etc.) if the number of sensors triggered in a minute period is >3.
The thinking behind is that if a burglar is on a recon phase, he will most likely trip several PIRS (there are 6 of them, around the house and at the gate) and / or one of the cameras (5 of them). If he/she can dodge all of this, well they deserve my laptop and wife jewellery honestly.
I suck at Jinja templates and cannot figure out how to properly do so.
I tried stuffs like those and miserably failed. Help needed.
Thanks for the pointer, I never tried history sensors, will try it now.
The idea is to re-create a new history sensor per existing motion sensor in the sensor.yaml file, then create a new group containing all the newly created history sensors, and finally integrate a third history stats counter back in the sensor.yaml, which is basically the count of all the others right?
It defeats a bit the idea of having a group and no duplicates for the same sensor, but it could work. Will it be as reactive as my other approach Jinja template? (cause as soon as something change, it’s instantly reported)
Edit: tried and it didn’t work, but I may have misunderstood some points. Anyway I don’t have a counter climbing when I tilt two sensors.
{% for sensor in expand('group.motion') %}
{{ iif(now() - sensor.last_changed < timedelta(seconds=60), 1, 0) }}
{% endfor %}
It’s super reactive and does print all lines with 0 if nothing changed over the last 60 seconds and 1 if it did. I’m guessing the only thing left is to add the results lines by lines in the for loop.
I don’t know how to do that but it should be doable I guess?
Ok, templating-wise, with a small group of sensors to test, it seems to work in the developer tab.
Now I don’t know if limited templates will allow this to work in automation. Further tests are required.
- id: 9937164948080
alias: Combined PIR/Alarm system (anti false positives)
description: Combine three different motions trigger in 90s before setting off Alarm
trigger:
- platform: template
value_template: >
{%- set counter = namespace(total=0) %}
{%- for sensor in expand('group.security') | map(attribute='last_changed') %}
{%- if now() - sensor < timedelta(seconds=90) %}
{%- set counter.total = counter.total + 1 %}
{%- endif %}
{%- endfor %}
{{ iif(counter.total > 1, true, false) }}
condition:
- condition: or
conditions:
- condition: state
entity_id: group.family_members
state: not_home
- condition: time
after: '21:00'
before: '08:00'
action:
- service: notify.home_alert
data:
message: At least 3 different triggers (Cameras/PIRs) tripped within 90s, serious alarm!
Hi @kameo4242,
Are you sure the automation is working as per the code you pasted here? I am asking that because a dash is missing in front of ‘platform’ keyboard. In my case: a state change in group.security is not triggering the automation. I have 2 binary sensors (PIRs) in the group.
Am I missing something?
Thanks,
True, typo indeed, I added back the missing “-”.
When your security group is changing you see it passing to “on” in the developer tool → state or template tab?
You also see each individual sensor state being on?
btw, I actually updated it to:
- id: "110020"
alias: Alarm - Combined (3+) tiggers
description: Combine 3 different camera and PIR motion sensors triggers within 90s before setting off Alarm
trigger:
- platform: state
entity_id:
- sensor1
- ...
- sensorX
to: "on"
condition:
and:
- condition: template
value_template: >
{{ expand('group.security') | map(attribute='last_changed') |
select('gt', now() - timedelta(seconds=90)) | list | count > 2 }}
- condition: state
entity_id: group.friends_members
state: "not_home"
- condition: state
entity_id: input_boolean.security_2h_snooze
state: "off"
- or:
- condition: state
entity_id: group.family_members
state: not_home
- condition: time
after: "23:00"
before: "08:00"
action:
- service: notify.emergency
data_template:
title: "ALARM!"
message: >
{{ "3 or more sensors triggered:" }}
{% for sensor in expand('group.security') -%}
{% if now() - sensor.last_changed < timedelta(seconds=90) -%}
{{- " * " + state_attr(sensor.entity_id, 'friendly_name').partition(' ')[0] + "\n" -}}
{% endif -%}
{%- endfor %}
data:
priority: 1
sound: bugle
Thanks for your response.
When my security group is changing, I see it passing to ‘on’ in developer tool but it is not passing to ‘true’ (or ‘false’) when I try the template lines in template section of dev tool.
As to the individual sensors, I see them changing status, yes.
I’ll check the changes in your code and give it another try later today.
(Sorry, I had to edit this post as I responded too fast and incorrectly).
I pinpointed my issue: the count is always 1, so automation never triggers…
Is this supposed to work the same if I replace ‘group.security’ by one of my sensors? Because that’s what I am doing for testing (as a window sensor, it is easier to trigger).
I believe my issue is that I am testing with only one sensor, assuming that multiple events of that same sensor would be stored in this expand(sensor) which doesn’t seem to be the case. It seems that only the last event, of one sensor is stored.
Unless the code can be changed so that multiple events, in a short timeframe, coming from the same sensor can be counted, I’ll have to revert to history sensors method.
For the records: I need this because my PIRs outside are sending false positives multiple times a day and I know that only when multiple events are received in a very short timeframe then it is a real alert. That’s what and why I want to capture multiple occurence coming from the same PIR sensor in say 60 seconds.
BTW, @kameo4242 what if only one sensor is triggered, even multiple times in 60 seconds, by an intruder, will your alert work?
@eole210 that is the problem indeed. You need several sensors to test.
The same one won’t raise the counter.
What you can do for test purposes is to create fake boolean sensors, add them to you security group and manually (dev.tools->states) trigger them to on, or do it with a simple automation that turn on/off every 5 mins or so.
@kameo4242 yes, that’s what I have been doing when testing.
I have only one sensor on this outside wall and the alert must trigger if it is triggered more than 2 times in 60 seconds. So, this won’t work for me. I’ll try the history platform even if I believe there should be some other solutions.