Template Sensor with Dynamic Battery Icon

Still having fun with this one. I have tried almost everything:

any ideas?

- platform: template
  sensors:
    back_gate_sensor_battery:
      friendly_name: 'Back Gate Battery'
      unit_of_measurement: '%'
      value_template: {{ states.binary_sensor.back_gate_opened.attributes.battery_level | round(0) }}
      icon_template:
      {%- if 'states.binary_sensor.back_gate_opened.attributes.battery_level' == '100' %}
           mdi:battery-charging
      {%- elif 'states.binary_sensor.back_gate_opened.attributes.battery_level' <= '5' %}
           mdi:battery-outline
      {%- elif 'states.binary_sensor.back_gate_opened.attributes.battery_level' >= '95' %}
           mdi:battery
      {% else %}
           mdi:battery-{{('states.binary_sensor.back_gate_opened.attributes.battery_level' | float / 10)|round*10}}
      {%- endif %}

results in:
- platform: template
sensors:
back_gate_sensor_battery:
friendly_name: ‘Back Gate Battery’
unit_of_measurement: ‘%’
value_template: 80
icon_template:
mdi:battery

I think you need >- on your icon_template: line. You also have quotes around your numbers, which I think makes them into a string comparison. What I use is below and looks fairly similar to yours except for handling the 5% and 95% use case.

- platform: template
  sensors:
    mailbox_battery:
      value_template: '{{ states.zwave.mailbox.attributes.battery_level }}'
      friendly_name: 'Mailbox Battery'
      entity_id: zwave.mailbox
      unit_of_measurement: '%'
      icon_template: >-
        {% set battery_level = states('sensor.mailbox_battery')|int('unknown') %}
        {% set battery_round = (battery_level|int / 10)|int * 10 %}
        {% if battery_level == 'unknown' %}
          mdi:battery-unknown
        {% else %}
          {% if battery_round >= 100 %}
            mdi:battery
          {% elif battery_round > 0 %}
            mdi:battery-{{ battery_round }}
          {% else %}
            mdi:battery-alert
          {% endif %}
        {% endif %}
6 Likes

I like your icon template. But is there anyway of not getting this error at startup?

Could not render icon template Dørsensor Batteri: UndefinedError: 'mappingproxy object' has no attribute 'battery_level'

I use it for my zwave devices, so it is not ready at startup.

Wow!! Thanks for this @NotoriousBDG - I now have all my zwave devices showing dynamic icons for their batteries :slight_smile:

Quick question though - I get the following error in my log at startup for all my zwave devices now though:

Could not render template Kitchen sensor, the state is unknown.

Any ideas how to avoid this error?

That’s most likely because battery devices sleep most of the time. It should show up once the device wakes up and reports in.

Thanks @NotoriousBDG, but it seems this is because the zwave devices aren’t “ready” at startup and only a few seconds later.
I found it worked by replacing the “value_template” you had above with the “value_template” as seen here.
No more error :slight_smile:

1 Like

Awesome. I’ll update my templates with that fix too.

1 Like

Tried this:

value_template: '{% if states.zwave.vannsensor_oppvaskmaskin %}
  {{ states.zwave.vannsensor_oppvaskmaskin.attributes.battery_level }}
{% else %}
  n/a
{% endif %}'
icon_template: >-
  {% set battery_level = (states.zwave.vannsensor_oppvaskmaskin.attributes.battery_level)|int('unknown') %}
  {% set battery_round = (battery_level|int / 10)|int * 10 %}
  {% if battery_level == 'unknown' %}
    mdi:battery-unknown
  {% else %}
    {% if battery_round >= 100 %}
      mdi:battery
    {% elif battery_round > 0 %}
      mdi:battery-{{ battery_round }}
    {% else %}
      mdi:battery-alert
    {% endif %}
  {% endif %}

Still got this error:
Could not render icon template Vanndetektor Oppvaskmaskin Batteri: UndefinedError: ‘mappingproxy object’ has no attribute ‘battery_level’

Do you not get this error?

Your first line below icon_template is currently this:

{% set battery_level = (states.zwave.vannsensor_oppvaskmaskin.attributes.battery_level)|int(‘unknown’) %}

It should rather be this:

{% set battery_level = states(‘name of your sensor here’)|int(‘unknown’) %}

Sorry, not sure what you are calling your sensor as you haven’t included that part of the code. In @NotoriousBDG’s example, it would be sensor.mailbox_battery

Hope that helps?

Yes! How could I miss that. Thank you, no more errors! :smile:

Awesome!! Enjoy :slight_smile:

Have a problem with my smokesensor templates. Get this error:

Could not render template Branndetektor Kjøkken, the state is unknown.

. Do you know if its possible to get this to work?

  branndetektor_kjokken_template:
    friendly_name: 'Branndetektor Kjøkken'
    value_template: >-
     {%- if is_state("sensor.brannvarsler_kjokken_smoke", "2") -%}
      Brann
     {%- elif is_state("sensor.brannvarsler_kjokken_smoke", "3") -%}
      Brann Test
     {%- elif float(states.sensor.timestamp_now.state | int - as_timestamp(states.zwave.brannvarsler_kjokken.last_updated)) | float > (5000) -%}
      Error
     {%- else -%}
      Ok
     {%- endif -%}

It is this line that is causing the problem:

 {%- elif float(states.sensor.timestamp_now.state | int - as_timestamp(states.zwave.brannvarsler_kjokken.last_updated)) | float > (5000) -%}
  Error

But really want that function, but meaby possible to fix?

Did you ever get this to work? I’m seeing similar errors, also with a Z-wave device. I’ve got the following in my sensors.yaml:

- platform: template
  sensors:
    battery_entry_sensor:
      value_template: '{% if states.zwave.vision_unknown_type0004_id0000_2 is not none %}
        {{ states.zwave.vision_unknown_type0004_id0000_2.attributes.battery_level }}
        {% else %}
          n/a
        {% endif %}'
      unit_of_measurement: '%'
      friendly_name: 'Door Lock'
      icon_template: >
        {% set battery = ['-outline','-20','-20','-30','-40','-40','-60','-70','-80','-90',''] %}
        {% set charge = (states('battery_entry_sensor') | float / 10) | round %}
        mdi:battery-{{ battery[charge] }}

for battery, why don’t you just use device_class: battery instead of the icon_template:

- platform: template
  sensors:
    corridor_motion_sensor_battery:
      friendly_name: 'Corridor battery'
      unit_of_measurement: '%'
      value_template: >
        {{ states.sensor.corridor_motion_sensor.attributes.battery }}
      device_class: battery

#      icon_template: >
#        {% set battery_level = states.sensor.corridor_motion_sensor.attributes.battery|default(0)|int %}
#        {% set battery_round = (battery_level / 10) |int * 10 %}
#        {% if battery_round >= 100 %}
#          mdi:battery
##        {% elif battery_round > 0 %}
#          mdi:battery-{{ battery_round }}
#        {% else %}
#          mdi:battery-alert
#        {% endif %}
6 Likes

That was too easy… thank you!

1 Like

Thanks for suggestion.

Hi, have tried several combinations of the suggestions here, but cant seem to get it working. The sensor always shows the battery-alert icon for all battery levels:

image

Running Home Assistant v0.92.2. Hope someone can find the error please?

configuration.yaml

image

using the device_class is the way to go, why did you take that out?

try

{{ state_attr('device_tracker.life360_callum','battery')|round }}

Blockquote

Hi Mariusthvdb, thanks for your help.

Sorry, but I am not sure where I would put the line you suggested and which line(s) it replaces. Here is my original config in text form (hopefully easier to edit):

>  - platform: template
>     sensors:
>       callum_battery:
>         value_template: >-
>           {{ states.device_tracker.life360_callum.attributes.battery }}
>         friendly_name: 'Callum Battery'
>         unit_of_measurement: '%'
>         #device_class: battery
>         icon_template: >-
>           {% set battery_level = states.sensor.callum_battery|default(0)|int %}
>           {% set battery_round = (battery_level|int / 10)|int * 10 %}
>           {% if battery_level == 'unknown' %}
>             mdi:battery-unknown
>           {% else %}
>             {% if battery_round >= 100 %}
>               mdi:battery
>             {% elif battery_round > 0 %}
>               mdi:battery-{{ battery_round }}
>             {% else %}
>               mdi:battery-alert
>             {% endif %}
>           {% endif %}

its the value_template…

try:

  - platform: template
    sensors:
      callum_battery:
        value_template: >
           {{ state_attr('device_tracker.life360_callum','battery')|round }}
        friendly_name: 'Callum Battery'
        unit_of_measurement: '%'
        device_class: battery
1 Like