Template Platform Binary Sensor not Updating

I’m having an issue with one of my binary sensors and wanted to see if I could get the community’s help to figure out what’s going on.

The template sensor that I have is to determine whether the house is “asleep” or not. This is used to trigger automatons to shut off the lights in the house at the appropriate time.

If my wife and I are both at home (determined by a separate binary sensor using logic from this excellent script), and both of our statuses (input select components changed from our phones via HTTP POST commands within Tasker) are set to “Sleeping”, then the sensor should show that the house is asleep. When the status is changed back to standby, the sensor should turn back off. This works 100% of the time; no problem at all.

If one of us is at home and the other is not at home, then the sensor will only look at the status of the person who is home to determine if the house is asleep. I haven’t had a ton of opportunity to thoroughly test this, but it seems to work fine.

Here’s where I’m seeing the issue. In the event that neither of us are home, between 23:00 and 05:59, the sensor should show that the house is asleep irrespective of either of our statuses (i.e. sleeping or not). The vast majority of the time the sensor will not turn “on” as expected, but on a rare occasion (maybe 5% of the time), it will.

If I manually flip one of our status from “asleep” to “standby” and back (or the opposite) during the 23:00 to 06:00 time period when we’re not home, sometimes I can get this sensor to also change, but I haven’t been able to nail down why it’s behaving this way. The way it’s written, if we’re not at home then the status should have impact on the sensor’s output.

The other interesting bit is that if I take the code for the sensor and put it into the “Templates editor” within Home Assistant, the code will always return the correct “answer” even while the sensor that runs on the exact same code says something different.

The code driving the sensor is below. I’m considering breaking this apart into a few separate binary sensors if I can’t get this working properly, but that doesn’t feel like the most elegant solution, and I wanted to see if anyone here had any ideas first.

Thanks!

- platform: template
    sensors:
      house_asleep:
        value_template: >-
          {{ (is_state('binary_sensor.anybody_home', 'off') and (now().hour|float > 22 or now().hour|float < 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')) }}

Template sensors update when one of the referenced entities changes. But the function now() is not an entity; i.e., it does not cause state_change events. You need to use an entity that causes state changes, such as sensor.time instead.

Assuming you enable sensor.time, then you can change:

        value_template: >-
          {{ (is_state('binary_sensor.anybody_home', 'off') and (now().hour|float > 22 or now().hour|float < 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')) }}

to:

        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')) }}
3 Likes

That seems like a perfect explanation for the behavior I’m seeing and have been banging my head over for the past several weeks.

I’ll give it a shot when I get home this evening and report back.

Thanks a bunch!

Had some time to test this out tonight and it works perfectly now. Really appreciate the help!

1 Like