Howto create battery alert without creating a template for every device

Fair point, and thanks for the added descriptions of what might be necessary. It’s good to know when something is or isn’t the right tool to use for a job. I’ll make use of this for what it’s already doing, and look for other ways to get a similar sort of scheme for the other kinds of ‘expiring maintenance’ items like batteries.

And, yes, when a UPS has a direct USB input I’d certainly consider using it. But several of the ones I’ve got around the house have nothing with a USB port near them that would be useful for managing them. There’s a balance to be struck between actively “knowing” the condition of a battery by monitoring and simply guesstimating when it’s likely to be failing and replacing it proactively. Having active monitoring often adds YET ANOTHER piece of tech to have to babysit, follow me? Versus ignoring it completely and getting awoken at 3am to a squealing UPS that’s starting to make smoke.

I think input booleans/input date helpers/automations might be you answer. I may set that up for my furnace filter. My 2 APC SmartUPS’s have periodic batttery checks and start beeping when they need new batteries so that is sufficient for me. I have automated my coffee maker and added a coffee filter counter so I am alerted that I need to go buy more. …

FWIW, I reported a new issue for the battery_alert package, issue 37. Even with issues, this package works (well, except for devices that dies before reporting low battery) so I am still using it.

Hi Everyone, I’m looking to do this exact thing - just wondering (and sorry if this is covered above, I havent read all 1000 posts!!)
is still the best way of doing this since the last update to the code was 2 years ago?

Also I notice it uses MQTT - does this mean it will only work for my MQTT devices or is that just the way that it handles doing things?

Thanks

I’ve not found a better way. It deals with all battery entities and entities with a battery_level attribute. It only uses MQTT to create new sensors for devices that have a battery_level attribute. See automation battery_sensor_from_attributes.

2 Likes

Alright - think I’ve got this working…

Couple of questions…

  1. I’d like to disable this device
    image

I see two possible ways to do this - the first being in the config

  1. To disable alerts for a specific entity, use customize to
    set battery_alert_disabled to true

    homeassistant:
      customize:
        sensor.sensor_name_to_ignore_battery:
          battery_alert_disabled: true
    

which if I’m understanding correctly would be like this:

homeassistant:
  packages: !include_dir_named packages
  customize:
    sensor.pocox3:
      battery_sensor_creation_disabled: true

although I’m unsure if i need to call out each of those different sensors individually?

The second possible way seems to be available in Lovelace - the “Delete a Battery Sensor” option - I can’t find a description of what this does anywhere tho or how to use it (and for that matter, which to use - the text box or the toggle)

The other question I have is what’s the purpose of this other card - it doesn’t seem to have any data?
image

Oh, and one more question - is it possible to test it in any way?

If you have five entities that you need/want to exclude then yes, each has to be configured via customize.

I believe the input text field only deletes an MQTT sensor which was created from an entity attribute.
The Delete a Battery Sensor is an automation in the package and the toggle simply disables/enables the automation.
image

The Battery Status and Battery Alert are groups that the package created.

which contains all the batteries being monitored.

group.battery_alert:
image

  1. I presume you are using the HA Companion App on your phone and its battery sensor is presented to HA? Just let it run down the battery!
  2. Replace a battery in some sensor with a low battery?
  3. Increase the Max Alert Threshold to some value above the lowest battery level in your entities!

image

FYI, the Min Alert Threshold is the point below which it will stop nagging you about a low battery!

Thanks for that, super useful

I actually think this functionality should be core to HA - coming over from Homey it’s a very simple flow over there to (in theory) get a battery alert for anything (albeit it frequently didn’t work!)

Happy to help!

Late to the party here - Set this up over a year ago and just noticed today that my logs are filling up with the below. What do I need to do to resolve please?

2022-11-22 12:12:00.763 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: 'homeassistant.util.read_only_dict.ReadOnlyDict object' has no attribute 'icon' when rendering '{%- for item in states.sensor if (
  not is_state_attr(item.entity_id, 'hidden', true)
  and (
    is_state_attr(item.entity_id, 'device_class', 'battery')
    or 'battery' in item.attributes.icon | lower
    or (item.entity_id | lower).endswith('_bat')
    or (item.name | lower).endswith('_bat')
    ) or (
      (
        'battery' in item.entity_id | lower
        or 'battery' in item.name | lower
      ) and (
        item.attributes.icon is not defined
      ) and (
        not is_state_attr(item.entity_id, 'battery_alert_disabled', true)
      ) and (
        not is_state_attr(item.entity_id, 'restored', true)
      )
    )
  )
-%}

Looks like you have an entity that doesn’t have an icon defined. One solution might be to just define the icon?

Edit: Or you need to check if icon is a defined attribute first

Pop this into Dev Tools, Template:

        {%- for item in states.sensor if (
          not is_state_attr(item.entity_id, 'hidden', true)
          and not 'hidden' in item.entity_id | lower
          and not is_state_attr(item.entity_id, 'battery_alert_disabled', true)
          and (
            is_state_attr(item.entity_id, 'device_class', 'battery')
            or (item.attributes.icon is defined and 'battery' in item.attributes.icon | lower)
            or (item.entity_id | lower).endswith('_bat')
            or (item.name | lower).endswith('_bat')
            ) or (
              (
                'battery' in item.entity_id | lower
                or 'battery' in item.name | lower
              ) and (
                item.attributes.icon is not defined
              ) and (
                not is_state_attr(item.entity_id, 'battery_alert_disabled', true)
              ) and (
                not is_state_attr(item.entity_id, 'restored', true)
              ) and (
                not 'consumption' in item.entity_id | lower)
            )
          )
        -%}
          {{ item.entity_id }}{% if not loop.last %}, {% endif %}
        {%- endfor -%}

and then examine the Result type: string. You will need to check each entity listed for an undefined icon?

Thank you - is there any way to narrow this down? I have over 1500 to check.
Is an undefined icon easy to spot whilst scrolling through all entities?

I compared your template from your error log:

{%- for item in states.sensor if (
  not is_state_attr(item.entity_id, 'hidden', true)
  and (
    is_state_attr(item.entity_id, 'device_class', 'battery')
    or 'battery' in item.attributes.icon | lower
    or (item.entity_id | lower).endswith('_bat')
    or (item.name | lower).endswith('_bat')
    ) or (
      (
        'battery' in item.entity_id | lower
        or 'battery' in item.name | lower
      ) and (
        item.attributes.icon is not defined
      ) and (
        not is_state_attr(item.entity_id, 'battery_alert_disabled', true)
      ) and (
        not is_state_attr(item.entity_id, 'restored', true)
      )
    )
  )
-%}

with mine and they are different.
Mine tests if item.attributes.icon is defined before checking if item.attributes.icon is battery:
(item.attributes.icon is defined and 'battery' in item.attributes.icon | lower)

Not sure how old your code is. There were lots of changes along the evolution of the package and it’s no longer actively maintained from what I can tell. I no longer use “the package” and have separated the package sections and put them into my config the way you normally would so I have code in my customize.yaml and normal automations and scripts that I can edit from HA UI if I ever need to. I grew tired of having to dig through the package, tweak it and then have to restart HA.

In that piece of code the only thing I can remember tweaking is I added an exclusion for my battery consumption entities.

You should be able to edit your package and replace

{%- for item in states.sensor if (
  not is_state_attr(item.entity_id, 'hidden', true)
  and (
    is_state_attr(item.entity_id, 'device_class', 'battery')
    or 'battery' in item.attributes.icon | lower
    or (item.entity_id | lower).endswith('_bat')
    or (item.name | lower).endswith('_bat')
    ) or (
      (
        'battery' in item.entity_id | lower
        or 'battery' in item.name | lower
      ) and (
        item.attributes.icon is not defined
      ) and (
        not is_state_attr(item.entity_id, 'battery_alert_disabled', true)
      ) and (
        not is_state_attr(item.entity_id, 'restored', true)
      )
    )
  )
-%}

with

{%- for item in states.sensor if (
  not is_state_attr(item.entity_id, 'hidden', true)
  and not 'hidden' in item.entity_id | lower
  and not is_state_attr(item.entity_id, 'battery_alert_disabled', true)
  and (
    is_state_attr(item.entity_id, 'device_class', 'battery')
    or (item.attributes.icon is defined and 'battery' in item.attributes.icon | lower)
    or (item.entity_id | lower).endswith('_bat')
    or (item.name | lower).endswith('_bat')
    ) or (
      (
        'battery' in item.entity_id | lower
        or 'battery' in item.name | lower
      ) and (
        item.attributes.icon is not defined
      ) and (
        not is_state_attr(item.entity_id, 'battery_alert_disabled', true)
      ) and (
        not is_state_attr(item.entity_id, 'restored', true)
      ) and (
        not 'consumption' in item.entity_id | lower)
    )
  )
-%}

and be good to go.

BTW, if you paste your template into Dev Tools, Template you should trigger the same error message that’s been filling your logs.

If you want to see all entities in your system that do not have the icon attribute defined:

{%- for item in states.sensor if (item.attributes.icon is not defined) %}
{{ item.entity_id }}
{%- endfor -%}

Another variation which shows all battery entities where the icon attribute is NOT defined:

{%- for item in states.sensor if (
  not is_state_attr(item.entity_id, 'hidden', true)
  and (
    is_state_attr(item.entity_id, 'device_class', 'battery')
    and item.attributes.icon is not defined
    ) or (
      (
        'battery' in item.entity_id | lower
        or 'battery' in item.name | lower
      ) and (
        item.attributes.icon is not defined
      ) and (
        not is_state_attr(item.entity_id, 'battery_alert_disabled', true)
      ) and (
        not is_state_attr(item.entity_id, 'restored', true)
      )
    )
  )
%}
{{ item.entity_id }}
{%- endfor -%}

PS Don’t leave these templates in Dev Tools for too long as it initiates an internal continual watch on ALL sensor changes and significantly slows the system!!

Hope that helps!

Daniel reading this taught me something very important. I had no idea that leaving something in developers tools continually runs and continually used system resources. I test things on many different devices and I never clear them out.

Most templates target a single entity and that puts very little load on the system. But if you’re targeting states.sensor it can be a fair number that it’s watching…