My way to track my battery states

My solution for checking battery status is this:

template sensor for every battery like this one
battery_living_heating: value_template: '{{ states.climate.living_heating_heating_1_8_1.attributes.battery_level }}' friendly_name: 'Wohnzimmer Heizung' unit_of_measurement: '%'

I put all of them into a group
batterie: view: false name: Batterie Status entities: - sensor.battery_floor_multi_sensor - sensor.battery_floor_door - sensor.battery_bathroom_multi_sensor - sensor.battery_bathroom_window - sensor.battery_bathroom_heating - sensor.battery_bedroom_multi_sensor - sensor.battery_bedroom_window - sensor.battery_bedroom_heating - sensor.battery_kitchen_multi_sensor - sensor.battery_kitchen_window - sensor.battery_kitchen_heating - sensor.battery_living_multi_sensor - sensor.battery_living_window - sensor.battery_living_heating - sensor.battery_living_canvas

And last a little automation running every evening at 7pm
`alias: Batterie Status Check - Alle Items in group.batterie
hide_entity: true
trigger:

  • platform: time
    after: ‘19:00:00’
    action:
  • service: script.turn_on
    entity_id: script.battery_check
    data_template:
    variables:
    message: ‘{% set output = “” %}{% for entity_id in states.group.batterie.attributes.entity_id %}{% set itemData = entity_id.split(".") %}{% set friendly_name = states[itemData[0]][itemData[1]].attributes.friendly_name %}{%- if states(entity_id)|int < 40 -%}{%- set output = output +friendly_name+" auf “+states(entity_id) +”% gefallen" -%}{%- endif -%}{% if loop.last %}{{ output }}{% elif states(entity_id)|int < 40 %}{% set output = output + “\n” %}{% endif %}{% endfor %}’`

And the script
battery_check: alias: "check battery of all devices in group.batterie" sequence: - service: notify.Wohnung data_template: message: "{{message}}"

Unfortunately i could not get the template working until it was in one line, should look like this
{% set output = '' %} {% for entity_id in states.group.batterie.attributes.entity_id %} {% set itemData = entity_id.split('.') %} {% set friendly_name = states[itemData[0]][itemData[1]].attributes.friendly_name %} {%- if states(entity_id)|int < 40 -%} {%- set output = output +friendly_name+' auf '+states(entity_id) +'% gefallen' -%} {%- endif -%} {% if loop.last %} {{ output }} {% elif states(entity_id)|int < 40 %} {% set output = output + '\n' %} {% endif %} {% endfor %}

And if i get new devices i want to check, i just add a sensor template and add it to the group, thats all.

I hope that helps someone of you and maybe someone can help me fix 2 little problems.

  1. In automation write the template structured instead of in one line
  2. In script i want to check if message is not empty before sending the message.
2 Likes

Thanks for the inspiration.

Wanted to share my take on this, which solves both of the problems you called out. For my use case, I didn’t really care about building a detailed message that lists each device with a low battery. I only really wanted to be notified that one or more devices had a low battery, as I could always log in to see which one was the problem.

To do this, I used a condition value template that evaluates to true if any battery level is less than a given threshold (currently 40%, same as you were using).

  - alias: 'Low battery alert'
    trigger:
      - platform: time
        after: '19:00:00'
    condition:
      - condition: template
        value_template: >-
          {% for entity_id in states.group.battery_levels.attributes.entity_id if states(entity_id) | int < 40 %}
          {%- if loop.first -%}
          {{ true }}
          {%- endif -%}
          {% endfor %}
    action:
      service: notify.<service>
      data:
        message: 'Low battery detected for at least one sensor'

By simplifying the requirements and using filtering as part of the loop, things are much simpler now.

3 Likes

@gardencity Thanks! Could you explain states.group.battery_levels.attributes.entity_id? I tried to recreate it but it triggers every time. I have a sensor (and therefore a state) for each battery state and grouped them in, so I thought iterating through group.batteries should be enough:

{% for entity_id in states.group.batteries if states(entity_id) | int < 33 %}

But even though currently the lowest batteries state is 54, I get the notification… :confused:

@domlen You’ll need to dig into the attributes of the group in order to get the underlying entity ids - states.group.batteries.attributes.entity_id. You unfortunately cannot just iterate over group.batteries itself in a template.

Also, it can be very helpful to use the template debug page (http://<ip_address:port>/dev-template) to find issues with your template. Just paste in your template there, and you can see if the output is what you expect.

Some suggestions to put into the template debug page to better explain what’s going on:
{{ states.group.batteries }} -> you’ll see that you get the full state object for the group itself
{{ states.group.batteries.attributes.entity_id }} -> this is a list that you can iterate over

1 Like

@gardencity Thank you! I totally forgot about the template debug page, since I use templates quiet rarely and only simple ones at the moment. I’ll dive into it and will adopt my automation. Thanks again!