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?
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…
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’?
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!
Probably overkill, but the walnut is well and truly cracked
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.
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
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.
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.
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 ') }}
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.
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.