It seems wrong for something that uses inputs to wait until those inputs are working? That that seems wrong seems illogical to me.
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.
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
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
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.
Hope this helps.
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
cool.
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.
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.
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 ).
And get in the habit from now on to include initial: off
in any new automations.
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