Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save sbyx/1f6f434f0903b872b84c4302637d0890 to your computer and use it in GitHub Desktop.
Save sbyx/1f6f434f0903b872b84c4302637d0890 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 level detection & notification for all battery sensors
description: Regularly test all sensors with 'battery' device-class for crossing
a certain battery level threshold and if so execute an action.
domain: automation
input:
threshold:
name: Battery warning level threshold
description: Battery sensors below threshold are assumed to be low-battery (as
well as binary battery sensors with value 'on').
default: 20
selector:
number:
min: 5.0
max: 100.0
unit_of_measurement: '%'
mode: slider
step: 5.0
time:
name: Time to test on
description: Test is run at configured time
default: '10:00:00'
selector:
time: {}
day:
name: Weekday to test on
description: 'Test is run at configured time either everyday (0) or on a given
weekday (1: Monday ... 7: Sunday)'
default: 0
selector:
number:
min: 0.0
max: 7.0
mode: slider
step: 1.0
exclude:
name: Excluded Sensors
description: Battery sensors (e.g. smartphone) to exclude from detection. Only entities are supported, devices must be expanded!
default: {entity_id: []}
selector:
target:
entity:
device_class: battery
actions:
name: Actions
description: Notifications or similar to be run. {{sensors}} is replaced with
the names of sensors being low on battery.
selector:
action: {}
source_url: https://gist.github.com/sbyx/1f6f434f0903b872b84c4302637d0890
variables:
day: !input 'day'
threshold: !input 'threshold'
exclude: !input 'exclude'
sensors: >-
{% set result = namespace(sensors=[]) %}
{% for state in states.sensor | selectattr('attributes.device_class', '==', 'battery') %}
{% if 0 <= state.state | int(-1) < threshold | int and not state.entity_id in exclude.entity_id %}
{% set result.sensors = result.sensors + [state.name ~ ' (' ~ state.state ~ ' %)'] %}
{% endif %}
{% endfor %}
{% for state in states.binary_sensor | selectattr('attributes.device_class', '==', 'battery') | selectattr('state', '==', 'on') %}
{% if not state.entity_id in exclude.entity_id %}
{% set result.sensors = result.sensors + [state.name] %}
{% endif %}
{% endfor %}
{{result.sensors|join(', ')}}
trigger:
- platform: time
at: !input 'time'
condition:
- '{{ sensors != '''' and (day | int == 0 or day | int == now().isoweekday()) }}'
action:
- choose: []
default: !input 'actions'
mode: single
@w1ll1am23
Copy link

I've been using this for awhile and just recently added a device thats reports battery as a voltage (two AA batteries reporting at 3.14v at the moment) I know I could just exclude this device, but wondering if there would be a way to only look at devices that have a unit of measure of %? (unit in my case is v)

@leonardus1973
Copy link

leonardus1973 commented Apr 24, 2022

{{ '\n' -}}

Is possible to use {{ '\n' -}} in telegram message? I have tried but nothing happen. thank you.

Another question:

Test is run at configured time either everyday (0) or on a given weekday (1: Monday ... 7: Sunday)

Value 0 for every day is not accepted (min is 1). why? Thank you.

@JackPo
Copy link

JackPo commented Jul 3, 2022

Is there a way to only get fire the action when {{sensors}} is not empty?

@Marck
Copy link

Marck commented Oct 19, 2022

Is there a way to only get fire the action when {{sensors}} is not empty?

This is fixed in my repo (it does send a message when testing) and doesn't errors when run with no batteries matching the percentage. This also ignores batteries on entities that have the mobile app (phones for example)

https://github.com/Marck/home-assistant-automation-blueprints

@howiehowie93
Copy link

This is a great blueprint - TYVM for posting it.

Is there a way to have it continually checking the level dropping below 20% instead of at one time daily ?

@nevesenin
Copy link

Hi!
I use this for a while and it worked great until some integrations (homematic, unifi) add sensors without device_class attribute. I get a UndefinedError: 'homeassistant.util.read_only_dict.ReadOnlyDict object' has no attribute 'device_class' error. I fixed that by adding another filter selectattr('attributes.device_class', 'defined') when iterating over sensors.

@jamesearl63
Copy link

Great Blueprint. Works great. I'm new to all of this so I hope I'm posting in the right place.

I get the following error in HA log when either making a change to the automation (i.e changing the time to trigger) or reloading the automation or restarting HA:

Logger: homeassistant.components.automation
Source: components/automation/config.py:207
Integration: Automation (documentation, issues)
First occurred: 11:55:17 AM (4 occurrences)
Last logged: 11:55:28 AM

Blueprint 'Low battery level detection & notification for all battery sensors' generated invalid automation with inputs OrderedDict([('threshold', 100), ('actions', [OrderedDict([('service', ''), ('data', OrderedDict())])])]): Service does not match format . for dictionary value @ data['action'][0]['default'][0]['service']. Got ''

I don't really understand the above. Please advise.

I generally just clear the log and the automation run without generating the above error.

@Sk1nk
Copy link

Sk1nk commented Mar 12, 2023

Hi, I am new to HA and stumbled across this (my first) template while reading through the subreddit. When I try to create an automation from the template I get:
„Message malformed: Missing input actions“
But I don‘t know how to add the sensors/buttons I want to test. Could someone help me?

@colmbuckley
Copy link

To be honest, I recommend at this point using this package for low battery alerting and sensing; it's more capable and extensible than this blueprint, and covers more of my use cases.

@EQNish
Copy link

EQNish commented Mar 13, 2023

I'm really kind of liking the idea of this, but I have not been able to get the percent to show anything other then 0%, and it doesn't see any of my door sensors ZSE41 or my Multi-sensors ZSE40

@thilander
Copy link

This is fantastic, thanks

@emanuelpsilva
Copy link

emanuelpsilva commented Aug 11, 2023

Awesome script sbyx 👍
Also, battery powered devices are prune to go from 80% into no communications (i.e. Shelly DW sensores). These scenarios will not be catch by the above script hence I wrote a very similar script that will check for the last interaction with these battery powered devices and report those above a certain threshold (i.e.: 1 day => 86400 seconds. Here is the script case someone is interested:

`

{% set result = namespace(devices=[]) %}

{% for device in states.sensor |rejectattr('attributes.device_class', 'undefined') | selectattr('attributes.device_class', '==', 'battery') %}
{% set age = (as_timestamp(now()) - as_timestamp(device.last_updated)) | int %}
{% if not (device.state == 'unavailable') and age > threshold %}
{% set result.devices = result.devices + [device.name ~ ' (' ~ (age / 3600) | int ~ 'h)'] %}
{% endif %}

{% endfor %}

{{result.devices|join(', ')}}

{% set result = namespace(devices=[]) %}
`

@kitty99hub
Copy link

Hi and many thanks for sharing this blue print.
I tested it and it works very well with the usual devices with a corresponding battery display in %
But now I'm facing a problem because I also have devices that don't use the device_class "battery" but "voltage"..... and they are devices with different voltage levels.
This means, for example, some devices work with a 1.5V battery and others with 3V or 9V and therefore all of these device/battery types reach their alarm value at a different voltage level.
For 1.5V devices this could be 1.2V, for 3V devices it could be 2.5V etc...

Now I'm asking myself whether I may have overlooked something that I could use to implement this with this blue print or whether it would be possible to integrate this function into this template?

Or are there other approaches for this?
I would be very happy about any help.
regards,

@KayGundhardt
Copy link

Hi sbyx,

Many thanks for your cool blueprint!

🫶

I must admit: before using it, I've spent a few dark hours in toilets in my life because I only realized too late that the battery of the motion detector was almost empty...

🙈

Anyway, I tried to create a blueprint for an open window notification based on your example, but I have to admit that I'm a real templating noob and have never created a blueprint before.

Of course it doesn't work and is certainly full of bugs: could you please help me out? That would be great!

blueprint:
  name: Open Window detection & notification for all contact sensors
  description: Regularly test all sensors with 'contact' device-class 
    for being open and if so execute an action.
  domain: automation
  input:
    time_period:
      name: Time period to test on
      description: Test is run at configured time period
      default: '5'
      selector:
        number:
          min: 1
          max: 30
          unit_of_measurement: 'min'
          mode: slider
          step: 1
    exclude:
      name: Excluded Sensors
      description: Contact sensors (e.g. smartphone) to exclude from detection. Only
        entities are supported, devices must be expanded!
      default:
        entity_id: []
      selector:
        target:
          entity:
            device_class: binary_sensor
    actions:
      name: Actions
      description: Notifications or similar to be run. {{sensors}} is replaced with
        the names of sensors being open.
      selector:
        action: {}
variables:
  time_period: !input time_period
  exclude: !input exclude
  sensors: "{% set result = namespace(sensors=[]) %} {% for state in states.sensor
    | selectattr('attributes.device_class', '==', 'binary_sensor') %}\n  {% if 'on' <= state.state
    | int and not state.entity_id in exclude.entity_id %}\n
    \   {% set result.sensors = result.sensors + [state.name ~ ' (' ~ state.state
    ~ ' %)'] %}\n  {% endif %}\n{% endfor %} {% for state in states.binary_sensor
    | selectattr('attributes.device_class', '==', 'binary_sensor') | selectattr('state',
    '==', 'on') %}\n  {% if not state.entity_id in exclude.entity_id %}\n    {% set
    result.sensors = result.sensors + [state.name] %}\n  {% endif %}\n{% endfor %}
    {{result.sensors|join(', ')}}"
trigger:
- platform: time_pattern
  minutes: /!input time_period
condition:
- '{{ is_state (sensors != '''', 'on') }}'
action:
- choose: []
  default: !input actions
mode: single

Thank you in advance!

Kay

@Oli-BY
Copy link

Oli-BY commented Feb 12, 2024

To be honest, I recommend at this point using this package for low battery alerting and sensing; it's more capable and extensible than this blueprint, and covers more of my use cases.

I cant import this blueprint

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment