Template Binary Sensor Different Entrance / Exit Criteria

Hi everyone-

I have a binary template sensor that I use in my set up to determine if the house should be “asleep” or not. This will turn the lights off at a certain time if no one is at home and when we go to bed if we are at home.

The sensor works perfectly, but I have a feature I’d like to add and have been struggling to come up with an elegant solution.

If both my wife and I are at home, binary_sensor.house_asleep will not turn on until both of our phones report that we’re asleep (done through Tasker integration). At night, this is exactly the behavior that I want.

What I’d like to solve is: if one of us gets up prior to the other in the morning, binary_sensor.house_asleep will turn off when a phone is unplugged and reports that that person is awake. Then when that person leaves, binary_sensor.house_asleep will turn back on and my nighttime shutdown routine will run again.

I’d like to have binary_sensor.house_asleep remain on until our phones both report that we’re awake.

Is it possible to have a template binary turn on only when both of our statuses change to ‘sleeping’ and have the sensor only turn off when neither status is ‘sleeping’?

I have a few workarounds that I’m trying to work through in my mind (another sensor or two with a few other automations), but they feel clunky to me every time I start to write out psuedo-code.

Any suggestions?

The sensor definition is below, and this thread has some additional information on the sensor as well.

Thanks!

  - platform: template
    sensors:
      house_asleep:
        value_template: >-
          {% set hour = states('sensor.time').split(':')[0]|int %}
          {{ (is_state('binary_sensor.anybody_home', 'off') and (hour > 22 or hour < 6))
              or (is_state('binary_sensor.tyler_home', 'on') and is_state('binary_sensor.amy_home', 'off') and is_state('input_select.tyler_status', 'sleeping'))
              or (is_state('binary_sensor.amy_home', 'on') and is_state('binary_sensor.tyler_home', 'off') and is_state('input_select.amy_status', 'sleeping'))
              or (is_state('binary_sensor.tyler_home', 'on') and is_state('binary_sensor.amy_home', 'on') and is_state('input_select.tyler_status', 'sleeping') and is_state('input_select.amy_status', 'sleeping')) }}

How about something like:

  - platform: template
    sensors:
      house_asleep:
        value_template: >-
          {% set hour = states('sensor.time').split(':')[0]|int %}
          {% set was_on = is_state('sensor.house_asleep','on') %}
          {% set tyler_asleep = is_state('binary_sensor.tyler_home', 'on') and
                                is_state('input_select.tyler_status', 'sleeping') %}
          {% set amy_asleep = is_state('binary_sensor.amy_home', 'on') and
                                is_state('input_select.amy_status', 'sleeping') %}
          {{ is_state('binary_sensor.anybody_home', 'off') and (hour > 22 or hour < 6) or
             tyler_asleep and amy_asleep or
             was_asleep and not (not tyler_asleep and not amy_asleep) }}
1 Like

At first look, once I wrapped my head around the double not clause at the bottom, I think this is brilliant! Much more elegant than anything I’d so far come up with in my head.

Let me implement it into my config file tonight and I’ll let you know how it goes.

Thanks for the help with this sensor again!

I would look to solving this with a bayesian sensor, similar to this

The issue I’m hoping to solve here isn’t so much more accurate detection of when we’re asleep or not – what I’m using does an okay job of that already – but rather turning on when we’re both asleep and then turning off when neither of us are asleep (i.e. x && y to turn on and !x && !y to turn off).

I think the recursive nature of what @pnbruckner came up with is going to work to solve that piece.

I probably should look into a bayesian sensor to knock off the 5-10% false positives I get with the actual “sleeping” sensor though; that’s a good idea.

Thanks!

Based on the bit of testing I’ve been able to do this evening, it looks like your solution is working perfectly for me! I made a couple of small changes, so I’ve posted the template for the final sensor below so it might help someone else down the road.

Thanks again for all the help; I owe you a beer or three! :beers:

  - platform: template
    sensors:
      house_asleep:
        value_template: >-
          {% set hour = states('sensor.time').split(':')[0]|int %}
          {% set was_asleep = is_state('binary_sensor.house_asleep','on') %}
          {% set tyler_asleep = is_state('binary_sensor.tyler_home', 'on') and
                                is_state('input_select.tyler_status', 'sleeping') %}
          {% set amy_asleep = is_state('binary_sensor.amy_home', 'on') and
                              is_state('input_select.amy_status', 'sleeping') %}
          {{ (is_state('binary_sensor.anybody_home', 'off') and (hour > 22 or hour < 6)) or
             (tyler_asleep and amy_asleep) or
             (was_asleep and (tyler_asleep or amy_asleep)) or
             (is_state('binary_sensor.tyler_home', 'off') and amy_asleep) or
             (is_state('binary_sensor.amy_home', 'off') and tyler_asleep) }}
1 Like