Binary sensor question regarding surviving restarts

I have a binary sensor.

I want to know when it has been off for 23 hours.

Is there a way to do this without using any other intermediate sensors/helpers given that the binary sensor will change state to unknown during a restart?

I seem to remember some discussion around this when the binary sensor was changed to be unknown at start up in that there was a way to persist the previous state. But I can’t find it now so I could be wrong.

And no need to rehash the debate about whether a binary sensor is indeed a binary sensor if it can have three possible states :wink:

However, all bets are off if there’s a restart involved because, as you said, that’s a momentary but legitimate state-change to unknown. It affects the calculation of the state value’s duration.

I know you don’t want to use templates, but they are very powerful and to do anything sophisticated you need them. I probably have 10x more template sensors than device sensors. Anyways using templates:

It’s easy to do using a trigger template. Just trigger on the state changing from Off to On and in the template expression use now() to record the current time. This value will persist restarts and will only update when state goes from Off to On and will not update when it goes from Unavailable to On.

Then create another template sensor that calculates the difference between now() and the value of the trigger template - call this latency.

Then create a binary sensor that is true if the latency >= to 23 hours and the target sensor is On

This is the way.

I believe it’s possible for the Trigger-based Template Sensor to compute that without requiring a second Template Sensor.

Either way, klogg will first need to remove the ban on “intermediate sensors/helpers”.

Yes it should be. A trade off between one more complicated sensor and simpler set of sensors. For things like this, I like to have the latency sensor so I can see how far away it is from 23 hours. Also I’d likely create an input number to hold the limit to 23 so that I can change it when needed without going back to YAML.

The great thing with HA is there are many ways to do just about anything.

Might be more challenging to sell klogg on the idea of using multiple “intermediate sensors/helpers” than just a single one. Nevertheless, I agree, Home Assistant’s flexibility often allows for more than one way to do something.

Thanks both of you.

I currently do it with an intermediate sensor but for various reasons I wanted it to be just one. It isn’t a hard limit though, just something I wondered if it could be done.

Also I’m not averse to templates. On the contrary, over the years I’ve ‘acquired’ hundreds of them :slight_smile:

I think something like this would work:

  - trigger:
      - platform: state
        entity_id:
          - binary_sensor.my_source_sensor
        to:
          - 'on'
          - 'off'
      - platform: time_pattern
        minutes: "/1"
    binary_sensor:
      - name: Source Sensor off for 23 hours
        unique_id: a6edb6dd-b0ff-4ef9-a0ad-b020dd35d540
        state: >
          {{ trigger.platform == 'time_pattern'
            and this.attributes.last_confirmed_state == 'off'
            and now() - this.attributes.last_confirmed_state_changed | as_datetime >= timedelta(hours=23) }}
        attributes:
          last_confirmed_state: >
            {{ trigger.to_state.state
              if trigger.platform=='state'
              else this.attributes.last_confirmed_state }}
          last_confirmed_state_changed: >
            {{ now() if trigger.platform=='state'
              and this.attributes.last_confirmed_state != trigger.to_state.state
              else this.attributes.last_confirmed_state_changed }}
1 Like

Thanks!
I don’t have time right now to look into his but last_confirmed_state looks really interesting.

I was trying to guess attribute names along these lines but you can work out how successful that would be :upside_down_face:.

Is there any place we can get a list (or find out in any other way) what attributes exist for entities like trigger and this?

Those attributes are ones I created in the template sensor. this is the state object for whatever it is self-referencing. This page has all the information on what is in a state object. Trigger data can be found here, the data is different depending on which trigger platform is used.

So, for example, since the code I posted made up an attribute called last_confirmed_state I can reference it from within that sensor by using this.attributes.last_confirmed_state. But I could have called it anything I wanted. So no, the attribute last_confirmed_state doesn’t exist elsewhere in other home assistant entities.

oops… Sorry, yes.
In my defence, I did say I didn’t have time to look right now :blush:

Using trigger.platform to determine if the state has changed due to the trigger rather than an HA restart is very clever.

Out of interest, what would trigger.platform be during a restart?

The trigger variable is only populated when the trigger is fired. And I don’t have triggers that fire upon a restart directly. However the state of the source sensor changing after a restart (from unavailable to off for example) will fire the state trigger. But then the template will check to see if the state is different from what the previous state (last_confirmed_state) was, and if it isn’t different, the timestamp doesn’t get updated.