Files
Home-Assistant/blueprints/automation/bferd/esphome_auto_bulk_update.yaml
T
2026-06-28 14:27:20 -04:00

214 lines
6.5 KiB
YAML

blueprint:
name: ESPHome Device Auto Bulk Update
description: 'Automatically updates ESPHome devices when a specified number of them
have pending updates. Optionally sends a notification before updating.
DEVICE FIRMWARE ENTITIES MUST BE ENABLED
FLOW:
1. Triggers when device update count exceeds the threshold, or daily sweep at
the start of the time window.
2. Checks the time window and device count conditions are met.
3. Sends a notification listing devices to be updated with Update Now and Cancel
buttons.
4. Waits for the delay period listening for a button response.
5. If Cancel is tapped - sends a cancellation notification and stops.
6. If Update Now is tapped or delay expires - proceeds with updates.
7. Updates all devices at once or sequentially depending on mode selected.
8. Sends a completion notification listing updated devices.
9. Waits out the cooldown period before the automation can trigger again.
'
domain: automation
source_url: https://github.com/bferd/homeassistant-blueprints/blob/main/esphome_auto_bulk_update.yaml
input:
update_threshold:
name: Device Update Threshold
description: How many devices need a pending update before updates are pushed.
default: 1
selector:
number:
min: 1.0
max: 20.0
step: 1.0
mode: slider
update_delay:
name: Delay Before Updating
description: How many minutes to wait before pushing updates.
default: 30
selector:
number:
min: 0.0
max: 60.0
step: 1.0
mode: slider
unit_of_measurement: minutes
cooldown:
name: Cooldown After Update
description: Minutes to wait after updates complete before the automation can
trigger again.
default: 30
selector:
number:
min: 0.0
max: 120.0
step: 1.0
mode: slider
unit_of_measurement: minutes
time_window_start:
name: Update Window Start
description: Earliest time of day updates can be triggered.
default: 08:00:00
selector:
time: {}
time_window_end:
name: Update Window End
description: Latest time of day updates can be triggered.
default: '21:00:00'
selector:
time: {}
notify_device:
name: Notification Device
description: Device to notify before updates are pushed.
selector:
device:
integration: mobile_app
multiple: false
update_mode:
name: Update Mode
description: Update all devices at once or one at a time sequentially.
default: all_at_once
selector:
select:
options:
- label: All at once
value: all_at_once
- label: One at a time (Sequential)
value: sequential
custom_value: false
multiple: false
sort: false
sequential_delay:
name: Delay Between Sequential Updates
description: Minutes to wait between each device when using sequential mode.
default: 0
selector:
number:
min: 0.0
max: 10.0
step: 1.0
mode: slider
unit_of_measurement: minutes
variables:
update_threshold: !input update_threshold
update_delay: !input update_delay
cooldown: !input cooldown
update_mode: !input update_mode
sequential_delay: !input sequential_delay
device_list: "{{ expand(integration_entities('esphome'))\n | selectattr(\"entity_id\",
\"contains\", \"update\")\n | selectattr(\"state\", \"eq\", \"on\")\n | map(attribute='entity_id')
| list }}\n"
device_names: "{{ expand(integration_entities('esphome'))\n | selectattr(\"entity_id\",
\"contains\", \"update\")\n | selectattr(\"state\", \"eq\", \"on\")\n | map(attribute='name')
| join(', ') }}\n"
device_count: "{{ expand(integration_entities('esphome'))\n | selectattr(\"entity_id\",
\"contains\", \"update\")\n | selectattr(\"state\", \"eq\", \"on\")\n | list
| count }}\n"
trigger:
- platform: template
value_template: "{{ expand(integration_entities('esphome'))\n | selectattr(\"entity_id\",
\"contains\", \"update\")\n | selectattr(\"state\", \"eq\", \"on\")\n | list
| count > update_threshold }}\n"
- platform: time
at: !input time_window_start
- platform: time_pattern
hours: /1
condition:
- condition: time
after: !input time_window_start
before: !input time_window_end
- condition: template
value_template: "{{ expand(integration_entities('esphome'))\n | selectattr(\"entity_id\",
\"contains\", \"update\")\n | selectattr(\"state\", \"eq\", \"on\")\n | list
| count > update_threshold }}\n"
action:
- domain: mobile_app
type: notify
device_id: !input notify_device
title: ESPHome Device Update(s)
message: '{{ device_count }} device(s) need updating: {{ device_names }}. Updates
will begin in {{ update_delay }} minute(s).
'
data:
sticky: 'true'
persistent: 'true'
actions:
- action: UPDATE_NOW_ESPHOME
title: Update Now
- action: CANCEL_ESPHOME_UPDATE
title: Cancel
- wait_for_trigger:
- platform: event
event_type: mobile_app_notification_action
event_data:
action: CANCEL_ESPHOME_UPDATE
- platform: event
event_type: mobile_app_notification_action
event_data:
action: UPDATE_NOW_ESPHOME
timeout:
minutes: '{{ update_delay }}'
continue_on_timeout: true
- if:
- condition: template
value_template: "{{ wait.trigger is not none and\n wait.trigger.event.data.action
== 'CANCEL_ESPHOME_UPDATE' }}\n"
then:
- domain: mobile_app
type: notify
device_id: !input notify_device
title: ESPHome Update Cancelled
message: ESPHome device updates have been cancelled.
else:
- if:
- condition: template
value_template: '{{ update_mode == ''sequential'' }}'
then:
- repeat:
for_each: '{{ device_list }}'
sequence:
- action: update.install
continue_on_error: true
data: {}
target:
entity_id: '{{ repeat.item }}'
- delay:
minutes: '{{ 0 if repeat.last else sequential_delay }}'
else:
- action: update.install
continue_on_error: true
data: {}
target:
entity_id: '{{ device_list }}'
- domain: mobile_app
type: notify
device_id: !input notify_device
title: ESPHome Updates Complete
message: '{{ device_count }} device(s) have been updated: {{ device_names }}.
'
- delay:
minutes: '{{ cooldown }}'
mode: single