I was looking at the recent blueprint for Send Notifications for Battery Level and thought I would share what I use in case it helps people.
Personally I’ve found that an automation for low battery is really only useful for your phone. Since your phone’s battery gets drained daily, if you get a notification about low battery you’re probably going to go plug it in pretty quickly. But with IOT devices most of them take months, a year or even longer to go from 100% to 0. So a low battery alert probably isn’t urgent at all. It’s something you have to take care of but definitely not an immediate problem.
For this reason, I prefer something that nags me periodically until I do get the job done. This is possible but difficult with an automation. I prefer an alert since that is exactly its purpose, a nagging periodic notification about something until you resolve it.
What I have is this:
- A template sensor which collects all sensors with a
device_class
ofbattery
and sets it state equal to the number of those sensors with a state <= 10 - A threshold sensor which is true any time that template sensor’s value is above 0
- An alert which notifies me every 12 hours with a count of the number of devices with low battery (if any have low battery)
If anyone is interested, here’s a package you can use to do the same:
sensor:
- platform: template
sensors:
devices_with_low_battery:
friendly_name: 'Devices with low battery'
unit_of_measurement: devices
value_template: >-
{{ states.sensor
| selectattr('attributes.device_class', 'eq', 'battery')
| map(attribute='state')
| reject('in', ['unknown', 'unavailable', 'Ok'])
| map('int', -1) | select('le', 10)
| list | count
}}
icon_template: >-
{% if is_state('sensor.devices_with_low_battery', '0') %}
mdi:check-circle
{% else %}
mdi:battery-alert
{% endif %}
binary_sensor:
- platform: threshold
entity_id: sensor.devices_with_low_battery
name: Devices with low battery
upper: 0.5
alert:
low_battery_devices:
name: Devices have low battery
entity_id: binary_sensor.devices_with_low_battery
title: "{{ states('sensor.devices_with_low_battery') }} devices in house with low battery"
message: "Devices all have 10% or less battery, you should change them"
state: 'on'
can_acknowledge: true
repeat: 720
notifiers:
- 'me'
Note - This uses me
as the notifier in the alert (which is really a call to notify.me
). This was intended as a generic placeholder, you should put in the name of the notifier you want to use after import. Sorry for not mentioning this initially
Also personally I prefer to exclude phones from this notification since I have other automation specifically around a phone having a low battery. I took that bit out of the package above since I figured people would prefer to just have one low battery alert for everything. If you do want to have separate automation for low phone battery as well though, you can do this by just adjusting the value_template
of the sensor.devices_with_low_battery
to this:
value_template: >-
{% set ignore_entities = ['sensor.phone_1_battery_level', 'sensor.phone_2_battery_level', '...'] %}
{{ states.sensor
| selectattr('attributes.device_class', 'eq', 'battery')
| rejectattr('entity_id', 'in', ignore_entities)
| map(attribute='state')
| reject('in', ['unknown', 'unavailable', 'Ok'])
| map('int', -1) | select('le', 10)
| list | count
}}
Obviously fill in your own values for the phone battery level sensors you have.
Update - non-numeric battery sensors
In the discussion below I was reminded of something I forgot to mention, handling non-numeric battery sensors. Specifically this line:
| reject('in', ['unknown', 'unavailable', 'Ok'])
unknown
and unavailable
are obviously common states for sensors with issues so filtering them out makes sense. But Ok
here is being filtered out due to a use case I have. Nest Protect devices have a battery level sensor but they don’t report a numeric state, instead they simply say either Ok
or Replace
. I filter out Ok
because that means the battery is fine. I let Replace
through because then the int
filter makes the non-numeric value into -1 and that alerts me since that is <= 10.
Obviously this doesn’t apply to everyone. If you have non-numeric battery sensors like mine then you should modify Ok
to fit your use cases. Or alternatively you can add an additional filter of select('ge', 0)
to the end of the filters before the list
to remove all non-numeric sensors (since non-numeric values will get converted to -1 by the int
filter whereas all numeric battery sensors would have state >= 0).