Attaching two different actions to a sensor

This is a variant of this thread which has been locked: I have some smoke sensors that have occasional false triggers, for which I’d like to do something like the following:

  1. Immediately send a notification when triggered, action: notify.notify.
  2. Wait awhile to see if it’s still triggered, delay_on: / seconds: 5.
  3. Trigger the alarm after this point, done via Alarmo.

This means each sensor will need an automation (for the notification) and a delay template sensor (to wait for the delay time after which Alarmo will trigger off it). When I get the notification I’ve got 5s to disable the alarm if it’s just a false alarm.

Question: Is this the best way to handle things or is there an easier way?

You could use template binary sensors for each smoke sensor. e.g. these will only turn on if the smoke sensor is active for a continuous 10 seconds:

configuration.yaml

template:
  - binary_sensor:
      - name: "Smoke Sensor 1 Filtered"
        unique_id: bd252e61-2a94-4a7c-ae7f-9d2ce2c4919f
        state: "{{ states('binary_sensor.smoke_detector_1')|bool }}"
        device_class: smoke
        delay_on:
          seconds: 10
      - name: "Smoke Sensor 2 Filtered"
        unique_id: 4e600b5b-9754-4637-987c-71049e8027e7
        state: "{{ states('binary_sensor.smoke_detector_2')|bool }}"
        device_class: smoke
        delay_on:
          seconds: 10
      - name: "Smoke Sensor 3 Filtered"
        unique_id: etc...

Then use those sensors in Alarmo.

Use the unfiltered sensors in your notification automation.

For 5 seconds the easiest solution is just to wait for 5 seconds in your automation then check the condition again.

if the condition check fails it will abort the automation.

Yeah, that was what #2 was, the delay template sensor. My concern was that it tripled the total number of entities (the original sensor, the delay template sensor, and the automation) for each physical sensor, which I took as a sign that I could be doing it wrong.

For anyone else needing to do this, here’s what I’ve ended up using. Assuming you start with a bunch of binary sensors that sometimes false-trigger, in my case running through a KC868 I/O board so they have names like kc868_input_9. First, the debouncing:

template:
  - binary_sensor:
      - name: kc868_input_9_debounce
        unique_id: uniqueid__kc868_input_9_debounce
        delay_on:
          seconds: 15
        state: "{{ states('binary_sensor.kc868_input_9') }}"
        device_class: smoke

This requires a 15s on time for the smoke sensor before it changes state to on. The reason for the 15s delay is that 12-15s is the smoke detect/smoke clear time for common smoke sensor controllers like the Freescale MC145010 or Allegro A5358, so enough time for a trigger from a smoke detect and then a clear on the next scan cycle. If it’s an actual fire then the smoke will collect towards the ceiling and the sensor will stay triggered over more than one scan cycle.

Then the alerting:

automation:
  - alias: "Alert on Living Room Smoke Trigger"
    triggers:
      - trigger: state
        entity_id:
          - binary_sensor.kc868_input_9
    actions:
      - action: notify.notify
        data:
          title: "Living Room Smoke Sensor Triggered"
          message: "Living room smoke sensor has been triggered, alarm will sound in 15s."

This one should be pretty self-explanatory.

The config got tested this morning in a somewhat unexpected way, at 6:56:42am all (by the looks of it) HA entities became unavailable. Since the smoke sensor entities trigger on a state change, going from all-clear to unavailable is regarded as a triggering of the sensor because its state has changed.

At 6:56:52 all the entities became available again, and the smoke sensors went back to all-clear. Because all entities were unavailable I’m not 100% certain whether the 15s time delay in the template sensor prevented the alarm siren from sounding or the fact that it was unavailable prevented it from sounding, but hopefully it was the former, so the delay seems to work.

Only thing I need to do is change the time-delay template sensor to trigger not on any smoke sensor state change but specifically on a change from $any to “on”, i.e. all-clear to unavailable shouldn’t trigger it. So something like:

state: >-
  {% if states('binary_sensor.smoke') not in ("unavailable", "unknown") %}
    {{ states('binary_sensor.smoke') }}
  {% else %}
    {{ "off" }}
  {% endif %}