Template Binary Sensors after HA restart

I have been falling foul of automations being triggered by a template binary_sensor changing to ‘off’ because it did not initialise quickly enough after a restart. This happens because the template is itself waiting for other things to be initialised before it could be evaluated. For example an input_select.

e.g.

{% if is_state('input_select.something', 'Some Text') %}

Will always momentarily be false after a restart.

The way I got around this was by changing the binary_sensor to a sensor and in the template, checking for all the necessary elements not having a state of ‘unavailable’, ‘unknown’, or ‘none’. If any are then the template sets the sensor state to something like ‘Undefined’.

Otherwise the template can be evaluated as normal setting the state to the usual True/False (or On/Off).

It’s not rocket science but it took me a while to think of this.

However, is there a better way to achieve this because something about this method doesn’t feel optimal to me? :roll_eyes:

Personally I’d set the initial state of the automation to off. Then use an automation to turn it on after HA starts with whatever delay is necessary for the entities used in the triggers/conditions to be fully initialized.

I’ve literally just made some changes to my system to eliminate startup problems due to unavailable entities and the like. I’m not home right now so I can’t post the automation, but basically what I’ve done is…

Created a sensor that counts unavailable entities

Set all but one of my automations to initial_state false.

The one that isn’t is set to initial_state true and triggers on homeassistant’s built-in ‘start’ event.

I replaced the start event trigger in any other automations with a custom event that I fire.

So, system restarts, all automations are off except the one that fires, that automation then waits for a maximum 20 seconds for the unavailable entities sensor to register zero. Then it switches on all the other automations, then it fires the custom event, which in turn fires the other automations that should run ‘at startup’

In the event that the 20 seconds passes and I still have unavailable entities the sequence continues but warns me that there are unavailable entities so I can double check everything worked properly.

Two separate restarts shown in this output, one with no issues, one that had an unavailable entity…

Can send code later if needed.

1 Like

Yes I briefly thought of that but (and this is a purely personal and you may say irrational, feeling) I have never had any automations ‘off’ at startup. It somehow seems wrong and illogical to me (I said it was a personal thing).

However, maybe it is time to revise my ‘prejudices’?

It seems wrong for something that uses inputs to wait until those inputs are working? That that seems wrong seems illogical to me. :wink:

1 Like

I definitely have a delayed start event that I use to trigger automations that need to evaluate things at startup (but after everything is fully initialized.) I’ve not had to resort to turning automations off.

I’m well and truly having my ‘prejudices’ tested here!!

Actually that is an interesting approach. I’d be interested to see your code when you get a chance. One reservation is that every automation I have will need to be edited!

image

Probably overkill, but the walnut is well and truly cracked :slightly_smiling_face:

Also, its not always the start event. Like sometimes the ‘light level’ hasn’t caught up so it changes after the system is up and triggers something that it shouldn’t, or the temperature average drops so the heating switches off when it jumps back up, but it hadn’t completed the cycle or whatever.

Maybe I’ll try the peanut approach…

A delayed start event is sounding like a good idea. I knew there was a better way!

One of the first things I did when I started using HA:

- alias: Delayed Startup
  trigger:
    - platform: homeassistant
      event: start
  action:
    - delay: 15
    - event: DELAYED_HOMEASSISTANT_START
1 Like

please do, this homeassistant bot looks very nice. And a true upgrade to the somewhat verbose messages my system sends to pushbullet.

What is that bot? or is it simply a name for one of the notification services…
Looks nifty!

as for the issue of @klogg, indeed had a few startup issues, and using the delayed startup do this:

  - alias: 'Delayed Startup'
    id: 'Delayed startup'
    trigger:
      platform: homeassistant
      event: start
    condition: []
    action:
      - service: script.notify_startup
      - delay: 
          seconds: >
            {{ states('input_number.ha_delayed_startup')|int }}
      - event: delayed_homeassistant_start

  - alias: 'Delayed Startup notification'
    id: 'Delayed startup notification'
    trigger:
      platform: event
      event_type: delayed_homeassistant_start
    condition: []
    action:
      - service: script.notify_delayed_startup
      - service: input_boolean.turn_off
        entity_id: input_boolean.just_started
      - service: script.run_after_delayed_startup

the input_boolean is used in several automations I do not want to run when restarting the system. it is ‘on’ initially:

input_boolean:
  just_started:
    name: Just started
    initial: 'on'

every time I need something retriggered because the system was not ready yet at startup, I add it to the script.run_after_delayed_startup

which is quite short to be honest:

script:
  run_after_delayed_startup:
    alias: Run after delayed startup
    sequence:
# first give it some extra time
      - delay:
          seconds: 30
      - service: homeassistant.update_entity
        entity_id: sensor.count_lights
      - service: python_script.average_indoor_temp
      - service: python_script.overview_entities
      - service: python_script.overview_domains
      - service: python_script.overview_components
      - service: python_script.ha_domains

Telegram :+1:

Yes Telegram is really good. I wrote almost an entire control system for my HA using Telegram. It doesn’t get a huge amount of use but when it does it works really well.

And thanks for all the suggestions. I must confess to having never raised an Event in HA. I never saw a use for doing so. That has now changed…

What you implemented seems so logical that it’s a wonder it isn’t the standard operating procedure for Home Assistant: wait for dependencies to become available before attempting to use them.

I’ve always found it odd that the cart can come before the horse: automations are allowed to come alive before their referenced entities. This creates the status quo where (to be safe) each automation must confirm its entities are truly alive before proceeding to use them.

1 Like

This is the automation that runs on startup, checking the system for unavailable entities before starting…

automation:
  - alias: System - Starting
    initial_state: true
    trigger:
      platform: homeassistant
      event: start
    action:
      - service: notify.mf
        data:
          message: "The system is back online.  Holding for any unavailable entities (max 20 seconds)..."
      - &wait
        wait_template: "{{ states('sensor.unavailable_entities')|int == 0 }}"
        timeout: '00:00:05'
      - &retry
        service: homeassistant.update_entity
        entity_id: sensor.unavailable_entities
      - *wait
      - *retry
      - *wait
      - *retry
      - *wait
      - service: automation.turn_on
        entity_id: all
      - service: notify.mf
        data_template:
          message: "...there are {{ 'no' if states('sensor.unavailable_entities')|int == 0 else states('sensor.unavailable_entities') }} unavailable entities{% if states('sensor.unavailable_entities')|int != 0 %} but 20 seconds has expired so we're proceeding anyway{% endif %}.  Activating automations..."
      - delay: '00:00:02'
      - service: notify.mf
        data:
          message: "...triggering automations that re-evaluate on startup..."
      - event: system_startup
      - delay: '00:00:02'
      - service: notify.mf
        data:
          message: "...system is ready."

The anchored wait_templates and update_entity services make it so that if there are unavailable entities when it first looks, it waits 5 seconds, updates the sensor and tries again for a max of 20 seconds. Obviously at the point that the entities are all available it just flies through all the gates to the next service.

Hope this helps.

4 Likes

thanks! very educational.
Just so happens a sensor for the ['unavailable', 'unknown', 'None'] has entered the premises since yesterday. No such thing as coincidence.

value_template: >
        {{ states | selectattr('state', 'in', ['unavailable', 'unknown', 'none']) | list | length }}
      attribute_templates:
        entities: >
          {{ states | selectattr('state', 'in', ['unavailable', 'unknown', 'none'])| map(attribute='entity_id')  | list | join(',\n ') }}

by @petro
see: How to list all sensors with state = 'unavailable', 'none' or 'unknown'

This gives me a reason to use it :wink:

cool.

1 Like

My first thought was to use a timer but after seeing your example (and its slick use of YAML anchors and aliases) this is a textbook application for wait_template.

1 Like

See here for the almost-most-up-to-date version of my sensor if it’s any use. It has a slight problem at the minute that when a whitelisted entry comes online and then goes offline later it gets included twice, so I need to check for duplicates, and also in that example I’m mapping the name attribute, but I’ve changed that my end to entity_id (in preparation for sorting out the duplicates).

Yes, it is always a pleasure when I ask a question here and it turns out that the answers are not only more useful than I expected, but useful to others as well. I feel I have contributed something by proxy!

And

Yes indeed! That post was the one that led me to my (ahem) solution.

I looked into anchors a long time ago but stopped using them because they seemed a bit obtuse to me. but I agree with @taras this is very slick.