Skip to content

Instantly share code, notes, and snippets.

@Geek-MD
Last active July 14, 2026 00:47
Show Gist options
  • Select an option

  • Save Geek-MD/e79ed1aec5f527cb2c11e223110e31d9 to your computer and use it in GitHub Desktop.

Select an option

Save Geek-MD/e79ed1aec5f527cb2c11e223110e31d9 to your computer and use it in GitHub Desktop.
Home Assistant Blueprint: Low Battery Notificator
blueprint:
name: Low Battery Notificator (Exclude List)
description: >
Notifies when any battery sensor drops below a configured threshold.
All battery sensors are monitored except those explicitly excluded.
domain: automation
author: Edison Montes @_GeekMD_
homeassistant:
min_version: 2024.6.0
input:
start_time:
name: Start Time
description: Start of the notification window.
default: "08:00:00"
selector:
time: {}
end_time:
name: End Time
description: End of the notification window.
default: "22:00:00"
selector:
time: {}
battery_level:
name: Battery Level Threshold
description: Notify when battery is below this percentage.
default: 20
selector:
number:
min: 0
max: 100
step: 1
unit_of_measurement: "%"
mode: slider
interval_minutes:
name: Execution Interval
description: Run every N minutes during the notification window.
default: 30
selector:
number:
min: 1
max: 120
step: 1
unit_of_measurement: min
mode: slider
excluded_entities:
name: Excluded Entities
description: Battery sensors to exclude from monitoring.
default: []
selector:
entity:
multiple: true
domain: sensor
device_class: battery
enable_logging:
name: Enable Persistent Logging
description: >
Create a persistent notification every time low battery devices
are detected.
default: false
selector:
boolean: {}
actions:
name: Actions
description: >
Actions to run when low battery devices are detected.
Use {{ low_battery_devices }} directly in notification messages.
selector:
action: {}
trigger:
# Check at the beginning of the notification window.
- platform: time
at: !input start_time
id: start_time
# Check at the end of the notification window.
- platform: time
at: !input end_time
id: end_time
# Check after Home Assistant starts.
- platform: homeassistant
event: start
id: homeassistant_start
# Used to implement the configurable interval.
- platform: time_pattern
minutes: "/1"
id: interval
# Execute immediately when any battery sensor changes.
- platform: event
event_type: state_changed
id: battery_state_changed
variables:
start_time: !input start_time
end_time: !input end_time
battery_level: !input battery_level
interval_minutes: !input interval_minutes
enable_logging: !input enable_logging
excluded_entities: !input excluded_entities
low_battery_devices: >
{% set threshold = battery_level | int %}
{% set result = namespace(devices=[]) %}
{% for sensor in states.sensor %}
{% if sensor.attributes.device_class == 'battery'
and sensor.entity_id not in excluded_entities %}
{% set value = sensor.state %}
{% if value not in ['unknown', 'unavailable', 'none', ''] %}
{% set level = value | int(default=101) %}
{% if 0 <= level < threshold %}
{% set original_name =
sensor.attributes.friendly_name | default(sensor.entity_id, true)
%}
{% set clean_name =
original_name
| regex_replace('(?i)\\b(?:battery|batería)\\b', '')
| regex_replace('\\s+', ' ')
| trim
%}
{% if clean_name | length == 0 %}
{% set clean_name = sensor.entity_id %}
{% endif %}
{% set result.devices = result.devices + [
clean_name ~ ' (' ~ level ~ '%)'
] %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
{{ result.devices | join('\n') }}
condition:
# Only continue when the trigger is relevant.
- condition: template
value_template: >
{% if trigger.id == 'interval' %}
{% set current_minute =
(as_timestamp(now()) / 60) | int
%}
{{ current_minute % (interval_minutes | int) == 0 }}
{% elif trigger.id == 'battery_state_changed' %}
{% set entity_id = trigger.event.data.entity_id | default('') %}
{% set old_state = trigger.event.data.old_state %}
{% set new_state = trigger.event.data.new_state %}
{{ entity_id.startswith('sensor.')
and new_state is not none
and new_state.attributes.device_class == 'battery'
and entity_id not in excluded_entities
and new_state.state not in ['unknown', 'unavailable', 'none', '']
and (new_state.state | int(default=101)) < (battery_level | int)
and (
old_state is none
or old_state.state in ['unknown', 'unavailable', 'none', '']
or (old_state.state | int(default=101)) >= (battery_level | int)
)
}}
{% else %}
true
{% endif %}
# Verify the configured notification window.
# This also supports windows that cross midnight.
- condition: template
value_template: >
{% set current_time = now().strftime('%H:%M:%S') %}
{% set start = start_time | string %}
{% set end = end_time | string %}
{% if start <= end %}
{{ start <= current_time <= end }}
{% else %}
{{ current_time >= start or current_time <= end }}
{% endif %}
# Only execute actions if at least one low battery was found.
- condition: template
value_template: >
{{ low_battery_devices | trim | length > 0 }}
action:
# Make the rendered value available to user-selected actions.
- variables:
low_battery_devices: "{{ low_battery_devices | trim }}"
- choose:
- conditions:
- condition: template
value_template: "{{ enable_logging | bool }}"
sequence:
- service: persistent_notification.create
data:
notification_id: low_battery_notificator
title: "Low Battery Devices"
message: |-
Execution time: {{ now().strftime('%Y-%m-%d %H:%M:%S') }}
Devices below {{ battery_level }}%:
{{ low_battery_devices }}
- service: logbook.log
data:
name: Low Battery Notificator
message: |-
Devices below {{ battery_level }}%:
{{ low_battery_devices }}
- choose: []
default: !input actions
mode: single
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment