Auto-update ESPHome Devices via Automation

Is the firmware entity of the device enabled and set to visible?

1 Like

yeah, by default, the update entity is disabled for some (or maybe all) devices. Enable that, and it should work normally.

im stupid!
this is the solution!
thanks a lot!!!

2 Likes

A small limitation in the automation.

If some devices are offline/unavailable at the time the automation was triggered, those devices wont get updated.

This happenrd to me. Two of my devices were offline when the automation was triggered, they came online after a minute. But i had to manually update them.

How to fix the automation for such a case ?

I’ve had a few instances where the ESPhome upgrade has broken the existing configuration and required it to be refactored.

I’d personally say that unless there is a specific reason to upgrade your ESPhome devices to the latest version, I would simply leave them on whatever their current version is.

1 Like

Just turn off the firmware entity in the device. You won’t be prompted to update it again.

This was broke. I fixed it.

2 Likes

Hi all,

I created an automation that automatically updates ESPHome devices after an ESPHome addon/app update. It can optionally send progress notifications so you can monitor the update process, and it will provide a list of devices that failed to update at the end.

You only need to replace <YOUR PHONE> with the mobile device that should receive the notifications.

alias: ESPHome Update Checker
description: >-
  Automatically update ESPHome Devices after ESPHome upgrade, and notify when
  they are updated.
triggers:
  - trigger: template
    id: update_check
    value_template: |
      {{ integration_entities('esphome')
        | select('match', '^update.')
        | select('is_state', 'on')
        | list | count > 0 }}
conditions:
  - alias: Confirm something needs to be updated still
    condition: template
    value_template: |
      {{ states.update
        | selectattr('entity_id','in', integration_entities('esphome'))
        | selectattr('state','eq','on')
        | list | count > 0 }}
actions:
  - variables:
      failed: []
      esphome_updates: |
        {{ states.update
          | selectattr('entity_id','in', integration_entities('esphome'))
          | selectattr('state','eq','on')
          | map(attribute='entity_id')
          | list }}
      total_updates: "{{ esphome_updates | count }}"
      updated: 0
  - data:
      action: notify.mobile_app_<YOUR PHONE>
      title: ESPHome Devices update
      message: >-
        {% set entity = esphome_updates[0] %}
        Updating {{ total_updates }} ESPHome device(s).
        First device will now be updated from {{
        state_attr(entity,'installed_version') }} to {{
        state_attr(entity,'latest_version') }}.
  - alias: Update all ESPHome devices in sequence
    repeat:
      for_each: "{{ esphome_updates }}"
      sequence:
        - action: notify.mobile_app_<YOUR PHONE>
          data:
            title: ESPHome Devices update
            message: |-
              Updating {{ state_attr(repeat.item,'friendly_name') }}
                    ({{ repeat.index }} / {{ total_updates }})
              {{ total_updates - repeat.index }} devices remaining
            data:
              tag: esphome_update
        - action: update.install
          target:
            entity_id: "{{ repeat.item }}"
          data: {}
          enabled: true
          continue_on_error: true
        - wait_template: "{{ state_attr(repeat.item, 'in_progress') == false }}"
          continue_on_timeout: true
          timeout: "00:1:00"
        - wait_template: |-
            {{ state_attr(repeat.item,'installed_version') is not none
               and state_attr(repeat.item,'latest_version') is not none
               and state_attr(repeat.item,'installed_version')
               == state_attr(repeat.item,'latest_version') }}
          continue_on_timeout: true
          timeout: "00:00:30"
        - if:
            - condition: template
              value_template: >-
                {{ state_attr(repeat.item,'installed_version') !=
                state_attr(repeat.item,'latest_version') }}
          then:
            - variables:
                failed: "{{ failed + [repeat.item] }}"
            - action: notify.mobile_app_hessel_s_flurkje
              data:
                title: ESPHome Devices
                message: >
                  Update failed for {{ state_attr(repeat.item, 'friendly_name')
                  }}. Please check the ESPHome addon.
          else:
            - variables:
                updated: "{{ updated + 1 }}"
  - action: notify.mobile_app_<YOUR PHONE>
    data:
      title: ESPHome Devices update
      message: |-
        {% set entity = esphome_updates[0] %}
        {% if failed | count == 0 %}
          All ESPHome devices are successfully updated to {{ state_attr(entity,'latest_version') }}.({{ updated }} / {{ total_updates }}) 
        {% else %} 
          Updates finished, updated ({{ updated }} / {{ total_updates }}) to {{ state_attr(entity,'latest_version') }}
          Failed: {{ failed | map('state_attr', 'friendly_name') | list | join(', ') }}
        {% endif %}
      data:
        tag: esphome_update
mode: single

Hi, for some reason this part will not save:

  • data:
    • action: notify.mobile_app_iphone
      title: ESPHome Devices update
      message: >-
      {% set entity = esphome_updates[0] %}
      Updating {{ total_updates }} ESPHome device(s).
      First device will now be updated from {{
      state_attr(entity,‘installed_version’) }} to {{
      state_attr(entity,‘latest_version’) }}.

Could you please share your full yaml? I wanna understand the context where this data: is, as I wasn’t expecting the action inside there.

So I've set up the automation via blue print

Getting some errors:

Logger: homeassistant.components.template.trigger
Source: components/template/trigger.py:63
Integration: Template (documentation, issues)
First occurred: 2:17:42 PM (1 occurrence)
Last logged: 2:17:42 PM

1st error:
Error initializing 'template' trigger for 'ESPHome Device Auto Bulk Update': UndefinedError: 'update_threshold' is undefined

2nd error:
Logger: homeassistant.helpers.event
Source: helpers/template/init.py:360
First occurred: 2:17:42 PM (1 occurrence)
Last logged: 2:17:42 PM

Error while processing template: Template<template=({{ expand(integration_entities('esphome')) | selectattr("entity_id", "contains", "update") | selectattr("state", "eq", "on") | list | count > update_threshold }}) renders=5348>
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/template/init.py", line 358, in async_render
render_result = render_with_context(self.template, compiled, **kwargs)
File "/usr/src/homeassistant/homeassistant/helpers/template/context.py", line 45, in render_with_context
return template.render(**kwargs)
~~~~~~~~~~~~~~~^^^^^^^^^^
File "/usr/local/lib/python3.14/site-packages/jinja2/environment.py", line 1295, in render
self.environment.handle_exception()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
File "/usr/local/lib/python3.14/site-packages/jinja2/environment.py", line 942, in handle_exception
raise rewrite_traceback_stack(source=source)
File "", line 4, in top-level template code
jinja2.exceptions.UndefinedError: 'update_threshold' is undefined

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/template/init.py", line 476, in async_render_to_info
render_info._result = self.async_render( # noqa: SLF001
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
variables, strict=strict, log_fn=log_fn, **kwargs
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/usr/src/homeassistant/homeassistant/helpers/template/init.py", line 360, in async_render
raise TemplateError(err) from err
homeassistant.exceptions.TemplateError: UndefinedError: 'update_threshold' is undefined

3rd error:
Logger: homeassistant.components.template.trigger
Source: components/template/trigger.py:79
Integration: Template (documentation, issues)
First occurred: 2:17:43 PM (1 occurrence)
Last logged: 2:17:43 PM

Error evaluating 'template' trigger for 'ESPHome Device Auto Bulk Update': UndefinedError: 'update_threshold' is undefined

This is most likely due to changes over time with Home Assistant.
Could you please review your blueprint with the latest HAOS, Core, Frontend
Thank you

Do you mean my blueprint? I don't think I use update_threshold on any recent version.
If so, could you please try to update the blueprint and try it again?

Sorry, I've tagged the wrong ESPHome update script/blueprint. Yours works fine at the moment. Still in the process of finding one with more options that checking, updating, notification (messaging cell phones) which seems to be limited due to only 3 messaging platforms to be supported currently, none of which I use or trust. Wish Google Messaging was supported/listed.

Message to HA companion app should be available now with Home Assistant latest version (from today).

Thank you just added that to your script along with a delay (time) to allow completion of the script to update all the devices.