Open jcallaghan opened 4 years ago
Firstly before I kick off creating any automation I decided to make a Lovelace panel to give me a view of things. What this has shown me is I have a sh*t load of batteries, yet I've never really had a problem with this.
After getting all the devices into cards, I decided to add to filter cards to show me devices with low batteries (<20%) and those with critical batteries (unavailable or less than 10%). These two panels are worth their weight in gold, especially the critical battery filter. After creating this, I discovered I had a few devices that were unavailable due to recently running out of battery.
The critical battery filter card uses two filters and looks like this:
card:
show_header_toggle: false
title: Critical Batteries
entities:
- entity: sensor.battery
state_filter:
- operator: <=
value: 10
- operator: ==
value: unavailable
type: entity-filter
The low battery filter card looks like this:
card:
show_header_toggle: false
title: Critical Batteries
entities:
- entity: sensor.battery
state_filter:
- operator: regex
value: '\b(1[1-9]|2[0])\b'
type: entity-filter
I was interested to see how long it was between batteries cycles so I've created a dashboard to report on battery levels. This example is of the devices in my back garden but I'm curious if I should do this on a room-by-room basis or by a thing-type basis such as Ring, Aqara, Hue etc.
For the keen eyes out there, yes the garden is showing a battery with 200% capacity. This is because the Ring spotlight camera has two batteries, therefore, reports 200% capacity.
I think I prefer the retro LCD for a realtime summary of each battery over the gauges. This really emphasises the critical (<10%) and low (<20%) levels that I monitor.
Leverage examples such as:
Few observations I have made during this exercise.
Rui Espinho asked on Twitter how I made the batter level gauges. These are made by leveraging the bar gauge visualisation in a Grafana dashboard along with some thresholds to align to my low (20%) and critical levels (10%).
Matthias Matousek (@m_matou) asked on Twitter how I achieve the queries for batteries.
Most of my sensors are Zigbee bases and connected to Home Assistant through a Conbee II stick and deCONZ. Each sensor typically has an entity where the battery level is available. Depending on how the battery data is reported you may need to try different queries.
This is where I was trying to get the battery from an attribute of an entity. I haven't had much luck with this method just yet.
For the visualisations I make the following changes:
Call-outs: null values connected, unit (0-100).
Calls: For the bar gauge, I show the last (not null) value. I also change the thresholds to the values I monitor against. These match my filters in Lovelace and in my automations.
https://community.home-assistant.io/t/howto-create-battery-alert-without-creating-a-template-for-every-device/30576/675 https://github.com/notoriousbdg/Home-AssistantConfig/blob/master/packages/battery_alert.yaml#L231
history:
exclude:
entities:
- automation.battery_persistent_notification
- automation.battery_persistent_notification_clear
- automation.battery_notification_default
- automation.battery_notification_slack
- automation.battery_sensor_from_attributes
- automation.update_battery_status_group_members
- automation.update_battery_low_group_members
- automation.remove_battery_low_group
- automation.delete_battery_sensor
So it was always going to end up here in my view. Automated maintenance tasks. It was more deciding to use issues in this repo or creating a task in Microsoft Todo. I may still do this for testing and fun anyway.
Leveraging Postman to test the GitHub API I was able to create a new issue. Postman is great for testing APIs! You can also use parameters in the URL to fill prepare an issue: https://github.com/jcallaghan/home-assistant-config/issues/newtitle=test&body=test&labels=battery,task:%20maintenance
.
https://github.com/settings/tokens
https://api.github.com/repos/jcallaghan/home-assistant-config/issues
{
"title": "Test",
"body": "Test",
"labels": [
"battery",
"task: maintenance"
]
}
Using the rest_command integrated I created the following service.
rest_command:
new_github_issue_replace_battery:
url: https://api.github.com/repos/jcallaghan/home-assistant-config/issues
method: POST
headers:
Authorization: !secret github_token
payload: '{"title":"{{ title }}","body":"{{ message }}","labels":["battery","task: maintenance"]}'
Don't forget to add Bearer
in front of your access token in your secrets file.
github_token: "Bearer 000000000000000"
Service name:
rest_command.new_github_issue_replace_battery
Service data:
{
"title": "Service test",
"message": "Create via service call in Home Assistant"
}
I just noticed my low battery entity-filter
card was not working as expected. Turns out I wasn't able to perform an AND filter so switched to using a regex pattern.
Using a great regex tool (https://regexr.com/)[https://regexr.com/] I was able to test an expression that would return numbers in the 11-20 range.
state_filter:
- operator: regex
value: \b(1[1-9]|2[0])\b'
I understand why folks use the big loop to check battery status dynamically as adding each battery-related entity and maintaining them manually is a real pain. But while creating a solution to notify me when I have a low battery today I came across a few things which have led me to create a hybrid approach building on @Carlos's work CCOSTAN/Home-AssistantConfig#269.
Carlos leverages an approach using a template sensor with a domain-based for loop where the word battery is either found in the entity name or a battery_level attribute is defined. The sensor value consists of the entity name and battery level which Carlos goes on to use with his TTS engine.
While experimenting with the template I found I had various text-based values being returned which I excluded and at the time due to the number of sensors being returned by the template I hit the sensor text limit causing an value of unknown
to be thrown. This was when I decided to split out the sensor into three, critical batteries (0-10%), low batteries (10-20%), and those that are unavailable. To achieve this I added two variables to define a threshold range.
Once I created the sensor and move from the template developer tool I noticed that the sensor wasn't updating. This is because the sensor wasn't associated to any entities. To update the sensor you need to call the service_ homeassistant.update_entity
service. Another alternative is binding it to sensor.date, sensor.hour or sensor.minute which will update the sensor daily, hourly, or every minute.
To make things a little nicer on the UI side I created a binary sensor for each template sensor. The state of the binary sensor is true when a battery falls within the applicable range. I still need to settle on the right device_class.
I'm also tempted to use a template icon to make it more obvious when the sensor is on or not.
I also added the template sensor text as an attribute to each of the binary sensors. This provides much more detail when clicking on the entity detail screen.
I really like the extensibility of an approach shared in the community forum that leverages MQTT to maintain configuration. I don't plan to use this for batteries but I do like the concept for some other ideas I have.
Right now I have automations for all three of my ranges (critical, low, and unavailable) which send a notification through to my phone. This is great but I'd still like to build some automated DevOps into this although with this automations that won't be possible as these are generic i.e. any battery is with one of these ranges.
If I create an additional automation that triggers when a single entity falls into my low range I should be able to create a GitHub issue for me to replace the sensor battery. This will also provide more context in the message as it will be for a specific entity rather than the collection like in the others. The full string is more useful for TTS scenarios. I'll work on this tomorrow and commit the code to share with you all.
Well with the additional automation I'm able to create a GitHub issue when a device has a low battery which is pretty cool. I might replicate this for sensors that have become unavailable for an extended time too.
It has taken a few weeks but I've achieved everything I wanted to and some (for now at least). This single issue and idea has leveraged stuff I already knew about and a ton of new stuff I've learned about but most of all it was fun and has allowed me to build on the work and ideas of others and share something back with a little edge to it.
Seems overnight a device (Hue remote) rushed my new automation. I disabled the automation as soon as I realised it was triggering over and over. On closer inspection, the battery level fluctuates enormously so I'll need to get my thinking cap on and work our how I deal with this as a simple numeric_state
trigger with below: 20
and for: 00:01:00
isn't going to cut it.
Further ideas > https://github.com/notoriousbdg/Home-AssistantConfig/blob/master/packages/battery_alert.yaml
Also factor in monitored and unmonitored devices.
GitHub
Contribute to notoriousbdg/Home-AssistantConfig development by creating an account on GitHub.
{% set domains = ['light', 'switch', 'sensor', 'lock', 'binary_sensor'] %}
{%- for domain in domains -%}
{%- for item in states[domain] if (item.attributes.battery_level is defined) or ("battery" in item.name | lower) -%}
- entity_id: {{ item.entity_id }}
{% endfor %}
{%- endfor -%}
{%- for battery in expand('group.battery_all') -%}
{%- if battery.state | int < 100 -%}
{{ battery.entity_id }}
{%- if not loop.last -%}, {%- endif -%}
{%- endif -%}
{%- endfor -%}
Objective
Receive a notification when batteries are getting critical
< 10%
or low10%-20%
or those that are unavailable.Features
Related to #51, #103