Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save KenGrinder/6af79f1eb227116f370a9b6ec063cf73 to your computer and use it in GitHub Desktop.
Save KenGrinder/6af79f1eb227116f370a9b6ec063cf73 to your computer and use it in GitHub Desktop.
Home Assistant Blueprint: Low battery level detection & notification for all battery sensors
blueprint:
name: Low battery detection (using state.name)
description: >
Checks battery sensors daily at a specified time on selected days.
Numeric sensors below a threshold or binary sensors with state='on'
are considered low. Excludes specified devices/areas/entities.
Calls a user-specified notify service with a custom message, and
uses state.name if available (just like your Dev Tools test),
falling back to entity_id if needed.
domain: automation
input:
threshold:
name: Battery Warning Level Threshold
description: >
Numeric sensors below this % are considered low.
Binary sensors with device_class=battery and state='on'
are also considered low regardless of threshold.
default: 70
selector:
number:
min: 5
max: 100
unit_of_measurement: "%"
mode: slider
step: 5
time:
name: Time to Run
description: "Runs at this time on the selected days."
default: "10:00:00"
selector:
time: {}
days_of_week:
name: Days to Run
description: >
Select one or more days to run. By default, it runs Monday–Sunday.
default:
- Monday
- Tuesday
- Wednesday
- Thursday
- Friday
- Saturday
- Sunday
selector:
select:
mode: list
multiple: true
custom_value: false
options:
- Monday
- Tuesday
- Wednesday
- Thursday
- Friday
- Saturday
- Sunday
exclude:
name: Excluded Battery Sensors
description: >
Exclude devices, areas, or entities with device_class=battery
you do NOT want reported as low battery.
default: { entity_id: [] }
selector:
target:
entity:
device_class: battery
notify_service:
name: Notification Service
description: >
Enter the notify service (e.g. notify.mobile_app_iphone).
By default, "notify.all_devices" if you have a group configured.
default: "notify.all_devices"
selector:
text: {}
notification_title:
name: Notification Title
description: >
Title for the notification (some platforms ignore titles).
default: "Low Battery Warning"
selector:
text: {}
notification_message:
name: Notification Message
description: >
Body of the notification. Use `{{ sensors }}` to show the list
of low-battery sensors. For example:
"Low battery on: {{ sensors }}"
default: "Low battery on: {{ sensors }}"
selector:
text: {}
# You can link to your GitHub or docs here if you wish.
source_url: https://gist.github.com/youruser/low-battery-state-name.yaml
variables:
threshold: !input "threshold"
days_of_week: !input "days_of_week"
exclude: !input "exclude"
notify_service: !input "notify_service"
notification_title: !input "notification_title"
notification_message: !input "notification_message"
# Flatten multi-level excludes (device, area, entity, label)
exclude_entities: >
{%- set ns = namespace(ret=[]) %}
{%- for key in ['device', 'area', 'entity', 'label'] %}
{%- set items = exclude.get(key ~ '_id', []) %}
{%- if items %}
{%- set items = [items] if items is string else items %}
{%- if key == 'entity' %}
{# Already entity_ids #}
{%- set ns.ret = ns.ret + items %}
{%- else %}
{# Convert device/area/label to entity_ids #}
{%- set more = items | map(key ~ '_entities') | sum(start=[]) %}
{%- set ns.ret = ns.ret + more %}
{%- endif %}
{%- endif %}
{%- endfor %}
{{ ns.ret | sum(start=[]) }}
sensors: >-
{%- set result = namespace(sensors=[]) -%}
{# 1) Numeric battery sensors #}
{% for state in states.sensor %}
{% if state.attributes.device_class == 'battery'
and (state.entity_id not in exclude_entities) %}
{# Try numeric from state, or fallback to .battery / .battery_level #}
{% set numeric_battery = none %}
{% if (state.state|float(-1) >= 0) and (state.state|float(-1) <= 100) %}
{% set numeric_battery = state.state|float(0) %}
{% elif state.attributes.battery is defined
and (state.attributes.battery|float(-1) >= 0)
and (state.attributes.battery|float(-1) <= 100) %}
{% set numeric_battery = state.attributes.battery|float(0) %}
{% elif state.attributes.battery_level is defined
and (state.attributes.battery_level|float(-1) >= 0)
and (state.attributes.battery_level|float(-1) <= 100) %}
{% set numeric_battery = state.attributes.battery_level|float(0) %}
{% endif %}
{% if numeric_battery is not none and numeric_battery < threshold %}
{# Use state.name exactly like your Dev Tools snippet #}
{% set sensor_name = state.name | default(state.entity_id) %}
{% set result.sensors = result.sensors + [
sensor_name ~ ' (' ~ numeric_battery|string ~ '%)'
] %}
{% endif %}
{% endif %}
{% endfor %}
{# 2) Binary battery sensors #}
{% for state in states.binary_sensor %}
{% if state.attributes.device_class == 'battery'
and (state.entity_id not in exclude_entities)
and state.state == 'on' %}
{% set sensor_name = state.name | default(state.entity_id) %}
{% set result.sensors = result.sensors + [sensor_name] %}
{% endif %}
{% endfor %}
{{ result.sensors | unique | sort | join(', ') }}
trigger:
- platform: time
at: !input "time"
condition:
- condition: template
value_template: >
{{
sensors != '' and
now().strftime('%A') in days_of_week
}}
action:
- service: "{{ notify_service }}"
data:
title: "{{ notification_title }}"
message: "{{ notification_message }}"
mode: single
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment