Binary sensor template for directional sensor based on 2 seperate binary sensors (motion/presence/door/occupancy etc)

Hi,

inspired by this question on how to make a directional sensor, I created a reusable/configurable piece of yaml to be used in a ‘binary template sensor’ which can easily be created via the helpers section .

Basically, it uses 2 binary_sensor entitites of choice that have some sort of relation that implies ‘direction’ when they have their events fire in a certain way in a given timespan.

I’ve used it for the combination of 2 pir detectors (stairway + upstairs hallway) to know if a person is going up or down (can also be done with (stairway + downstairs)) and with a pir and a door sensor to detect if a person is entering or leaving a room.

You create a binary template sensor in the helpers section, in my case, I’ve used the type ‘motion’.
You can then use that for automations that use the new binary sensor just created.

As an example: one of my kids only has a door sensor, but I can now use another pir sensor in the area leading to his door to create a new sensor that checks if it is a ‘leave the room’ or ‘enter the room’ type of event.

Since it is about the relation of the state change to ‘on’ of the 2 binary sensors, you can also use this to couple other sensors where you are interested in the result of sequential state changes.

here is the code

{# this can be used as a binary template sensor of type motion/presence etc #}
{% set bs1 = 'binary_sensor.living_hallway_door_contact' %}
{% set bs2 = 'binary_sensor.living_sensor_occupancy' %}
{# reverses direction of sensors (in/out, up/down, first/second #}
{% set reverse_sensor_direction = false %}
{# timeframe in which measurement is valid to prevent stale/inaccurate readings #}
{% set time_window = 10 %}
{# ensure sensors exist and are not unavailable #}
{% if states[bs1] is not none and states[bs2] is not none 
      and states[bs1].state not in ['unknown', 'unavailable'] 
      and states[bs2].state not in ['unknown', 'unavailable']
-%}
  {# check if both sensors are active and changed state recently #}
  {% if is_state(bs1, 'on') and is_state(bs2, 'on')
        and (now() - states[bs1].last_changed).total_seconds() < time_window
        and (now() - states[bs2].last_changed).total_seconds() < time_window 
  -%}
    {# determine movement direction #}
    {% if as_timestamp(states[bs1].last_changed) > as_timestamp(states[bs2].last_changed) -%}
      {{ not reverse_sensor_direction }}
    {% else -%}
      {{ reverse_sensor_direction }}
    {% endif -%}
  {% else -%}
    {# fallback, no valid movement / 0 or 1 sensor only #}
    false
  {% endif %}
{% else %}
  {# return false if sensors are missing or unavailable #}
  false 
{% endif %}
1 Like

This is great stuff! Thank you for the detailed info and code

1 Like