Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Tahutipai/971bf0e07e50ce6190e0dacd73262e2e to your computer and use it in GitHub Desktop.
Save Tahutipai/971bf0e07e50ce6190e0dacd73262e2e to your computer and use it in GitHub Desktop.
Home Assistant Blueprint: Low battery level detection & notification for all battery sensors
blueprint:
name: Report offline zigbee/zwave/battery/smart plug devices
description: Works with Smart Plugs, ZWave, Zigbee etc (Works with ZHA & Z2M)
#By Tahutipai 2024-02-21
#Originally Based on the work of Sybx @ https://community.home-assistant.io/t/low-battery-level-detection-notification-for-all-battery-sensors/258664
#Note: This has been upgraded to report only the Device that is offline, not multiple individual sensors within one Device
domain: automation
input:
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
- switch
actions:
name: Actions
description: Call your notification here. {{offline_devices}} will replaced with the name of any offline devices
selector:
action: {}
source_url: https://gist.github.com/Tahutipai/971bf0e07e50ce6190e0dacd73262e2e
variables:
day: !input 'day'
exclude: !input 'exclude'
offline_devices: >-
{% set result = namespace(offline_devices=[]) %}
{% for sensor in states.sensor | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', '==', 'battery') %}
{% if "unavailable" in sensor | string and not sensor.entity_id in exclude.entity_id %}
{% set result.offline_devices = result.offline_devices + [device_attr(device_id(sensor.entity_id), "name")] %}
{% endif %}
{% endfor %}
{% for binary_sensor in states.binary_sensor | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', '==', 'battery') %}
{% if "unavailable" in binary_sensor | string and not binary_sensor.entity_id in exclude.entity_id %}
{% set result.offline_devices = result.offline_devices + [device_attr(device_id(binary_sensor.entity_id), "name")] %}
{% endif %}
{% endfor %}
{% for switch in states.switch | selectattr('state','eq','unavailable') %}
{% if switch.entity_id not in exclude.entity_id %}
{% set result.offline_devices = result.offline_devices + [device_attr(device_id(switch.entity_id), "name")] %}
{% endif %}
{% endfor %}
{{result.offline_devices|sort|unique|join('\n')}}
trigger:
- platform: time
at: !input 'time'
condition:
- '{{ offline_devices != '''' and (day | int == 0 or day | int == now().isoweekday()) }}'
action:
- choose: []
default: !input 'actions'
mode: single
@bigthrilla
Copy link

bigthrilla commented Apr 1, 2023

This has been working really well for me, thank you. Only think I customized was to put a line break between the sensors so it's easier for me to visually look through them (line 54, replace the comma space with < br >). Totally a preference thing. Thanks again for making this.

@xcdk43
Copy link

xcdk43 commented Feb 2, 2024

This is what I'm looking for, works great on a daily basis. I would like to increase the sampling from daily to some-thing more frequent hourly or every 5min

@Tahutipai
Copy link
Author

This has been working really well for me, thank you. Only think I customized was to put a line break between the sensors so it's easier for me to visually look through them (line 54, replace the comma space with < br >). Totally a preference thing. Thanks again for making this.

Great idea, thanks!

@psitem
Copy link

psitem commented Feb 21, 2024

I propose a tweak: {{result.offline_devices|join('\n')}} -> {{result.offline_devices|sort|unique|join('\\n')}}

@Tahutipai
Copy link
Author

I propose a tweak: {{result.offline_devices|join('\n')}} -> {{result.offline_devices|sort|unique|join('\\n')}}

Thanks for the suggestions. I've just added the sort (and the ability to exclude switches). Question: What does the "\n" do? (I note that when I import the blueprint, HA automatically changes \n to \\n but I don't know why....

Can you please share a use case where the unique would be useful? Is there a situation where a person may have multiple devices with the same name? (if that is possible) Or are you referring to an edge case I haven't seen myself, e.g is there a Device that might have sensors from different categories, thus erroneously appear multiple times?

@psitem
Copy link

psitem commented Feb 22, 2024

No idea why the \n -> \\n thing happens. Looking at the file in VS Code in HA, it completely messes up the formatting of that block.

Or are you referring to an edge case I haven't seen myself, e.g is there a Device that might have sensors from different categories, thus erroneously appear multiple times?

Exactly that. Most of my offline devices were repeated 4-6X due to having multiple switches and sensors.

@Tahutipai
Copy link
Author

Great thanks @psitem, have implemented your suggestions.

Ya if I look at the yaml in vscode/fileeditor/vim/cat, that block is all screwed up (appearence wise), and quite a few additional charatachers (escape'd double quotes etc). Looks like HA is running it through some type of parser.

I cleaned up the original file just now, there was some blank space at the end of a few lines, and a found a couple of tabs instead of spaces in places, then re-imported it: no change, same messy result.

If you even come across the answer to that one, do let me know. cheers!

@abrsti
Copy link

abrsti commented Jun 11, 2024

I get this error when I try to import the blueprint:

Invalid blueprint: expected str for dictionary value @ data['blueprint']['input']['exclude']['selector']['entity']['device_class']. Got None

@ppastur
Copy link

ppastur commented Oct 3, 2024

Hi, thanks for your work. I wanted to ask if anyone is using labelled to exclude from the report? I have tried but it doesn't seem to be working

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