Template Binary Sensors after HA restart

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.

just to be sure, I mentioned the thread and credited it didn’t I? Didn’t want to take the honors myself at all.

Yes you did, don’t worry, @petro’s name is there :wink:

@pnbruckner, @anon43302295,

I take it back.

I think the ONLY way to achieve what I need is to have automations set to initial: off and then implement some kind of delayed startup.

It’s not the automation having a

    trigger:
      platform: homeassistant
      event: start

that’s a problem.

It’s all the other triggers that are not being evaluated correctly.

I’m going to have to change all my automations. Thanks Marc (that is both genuine and sarcastic :sunglasses:).
And get in the habit from now on to include initial: off in any new automations.

1 Like

To avoid binary sensors firing at startup, you can make your automations follow an inverted binary sensor:

- platform: template
  sensors:
    contact_inverted:
      value_template: >-
         {{ is_state('binary_sensor.contact', 'off') }}
      device_class: door

Idea comes from ☔ DIY Zigbee rain gauge - #96 by oet