Icon template not showing correct icon

I’m monitoring the battery level of a zwave sensor which is given in integer % and trying to animate the icon on a glance card in response.

I can retrieve the value no problem, but the following template is showing the battery-90 icon when the current level is 100, so should be showing the standard battery icon as it is full.

I have also tried == 100 in the first evaluation instead of >= 99 to no avail.

What am I doing wrong?

        icon_template: >-
          {% if state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int >= 99 %}
            mdi:battery
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 100 %}
            mdi:battery-90
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 90 %}
            mdi:battery-80
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 80 %}
            mdi:battery-70
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 70 %}
            mdi:battery-60
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 60 %}
            mdi:battery-50
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 50 %}
            mdi:battery-40
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 40 %}
            mdi:battery-30
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 30 %}
            mdi:battery-20
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 20 %}
            mdi:battery-10
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 10 %}
            mdi:battery-outline
          {% else %}
            mdi:battery-outline
          {% endif %}

Your tests are upside down.

Assume the battery is 50%. The first test that evaluates to true will be <100.

Order them the other way round, from <10 first to <100 last…

        icon_template: >-
          {% if state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 10 %}
            mdi:battery-outline
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 20 %}
            mdi:battery-10
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 30 %}
            mdi:battery-20
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 40 %}
            mdi:battery-30
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 50 %}
            mdi:battery-40
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 60 %}
            mdi:battery-50
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 70 %}
            mdi:battery-60
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 80 %}
            mdi:battery-70
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 90 %}
            mdi:battery-80
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 100 %}
            mdi:battery-90
          {% else %}
            mdi:battery
          {% endif %}

Thanks but that doesn’t work either, I get the battery outline icon so the first test is still evaluating to true (battery level still at 100% in reality)

        icon_template: >-
          {% if state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int <10 %}
            mdi:battery-outline
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 20 %}
            mdi:battery-10
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 30 %}
            mdi:battery-20
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 40 %}
            mdi:battery-30
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 50 %}
            mdi:battery-40
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 60 %}
            mdi:battery-50
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 70 %}
            mdi:battery-60
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 80 %}
            mdi:battery-70
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 90 %}
            mdi:battery-80
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 100 %}
            mdi:battery-90
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int == 100 %}
            mdi:battery
          {% else %}
            mdi:battery-unknown
          {% endif %}

how about playing with this in Template editor?

1 Like

Where are you putting this template?

Can you show the rest of the sensor config?

What does this evaluate to in the dev tools template editor:

{{ state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int }}

Edit: oh I see your problem. That template isn’t right at all

Try this in the template editor:

{{ state_attr('sensor.zwave.kaipule_technology_co_ltd_im20_door_window' 'battery_level') | int }}

If that is ‘unknown’ post your actual sensor entity_id and the attribute name (look them up in the dev tools states menu).

Format should be: {% if state_attr('sensor.entity_id', 'attribute') | int < n %}

it evaluates as true for all values <= 99.

==100 evaluates as false even though that should be true

Edit, the template editor evaluates the following as 100:

{{ states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level | int }}

This is in my sensor definition so that syntax won’t work, this is what I have at the moment.

Should I have the icon_template as part of the glance card definition instead?

sensor:
  - platform: systemmonitor
    resources:
      - type: memory_use_percent
      - type: processor_use
      - type: throughput_network_in
        arg: enp1s0f0
      - type: throughput_network_out
        arg: enp1s0f0
  - platform: template
    sensors:
      battery_playroomdoor:
        friendly_name: 'Playroom Door Battery'
        value_template: '{{ states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level | int }}'
        unit_of_measurement: '%'
        icon_template: >-
          {% if state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int <10 %}
            mdi:battery-outline
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 20 %}
            mdi:battery-10
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 30 %}
            mdi:battery-20
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 40 %}
            mdi:battery-30
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 50 %}
            mdi:battery-40
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 60 %}
            mdi:battery-50
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 70 %}
            mdi:battery-60
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 80 %}
            mdi:battery-70
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 90 %}
            mdi:battery-80
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 100 %}
            mdi:battery-90
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int == 100 %}
            mdi:battery
          {% else %}
            mdi:battery-unknown
          {% endif %}

      battery_backdoor:
        friendly_name: 'Backdoor Battery'
        value_template: '{{ states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor_2.attributes.battery_level | int }}'
        unit_of_measurement: '%'
        icon_template: >-
          {% if state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int <10 %}
            mdi:battery-outline
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 20 %}
            mdi:battery-10
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 30 %}
            mdi:battery-20
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 40 %}
            mdi:battery-30
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 50 %}
            mdi:battery-40
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 60 %}
            mdi:battery-50
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 70 %}
            mdi:battery-60
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 80 %}
            mdi:battery-70
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 90 %}
            mdi:battery-80
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int < 100 %}
            mdi:battery-90
          {% elif state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int == 100 %}
            mdi:battery
          {% else %}
            mdi:battery-unknown
          {% endif %}

      door_backdoor:
        friendly_name: 'Backdoor'
        value_template: '{% if states.binary_sensor.kaipule_technology_co_ltd_im20_door_window_sensor_sensor_2 %}
          {% if states.binary_sensor.kaipule_technology_co_ltd_im20_door_window_sensor_sensor_2.state == "on" %}
            Open
          {% else %}
            Closed
          {% endif %}
          {% else %}
          n/a
          {% endif %}'
        icon_template: >-
          {% if states.binary_sensor.kaipule_technology_co_ltd_im20_door_window_sensor_sensor_2.state == "on" %}
            mdi:door-open
          {% else %}
            mdi:door-closed
          {% endif %}

      door_playroomdoor:
        friendly_name: 'Playroom door'
        value_template: '{% if states.binary_sensor.kaipule_technology_co_ltd_im20_door_window_sensor_sensor %}
          {% if states.binary_sensor.kaipule_technology_co_ltd_im20_door_window_sensor_sensor.state == "on" %}
            Open
          {% else %}
            Closed
          {% endif %}
          {% else %}
          n/a
          {% endif %}'
        icon_template: >-
          {% if states.binary_sensor.kaipule_technology_co_ltd_im20_door_window_sensor_sensor.state == "on" %}
            mdi:door-open
          {% else %}
            mdi:door-closed
          {% endif %}

to answer my own question, no this doesn’t work as part of the glance card either

Then your template tests should be like this:

 {% if states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level ) | int <10 %}

Not like this:

{% if state_attr('states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level', '%')|int <10 %}

Fixed, it correct syntax is:

        icon_template: >-
          {% if  states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level | int  <10 %}
            mdi:battery-outline
          {% elif states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level | int  <20 %}
            mdi:battery-10
          {% elif states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level | int  <30 %}
            mdi:battery-20
          {% elif states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level | int  <40 %}
            mdi:battery-30
          {% elif states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level | int  <50 %}
            mdi:battery-40
          {% elif states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level | int  <60 %}
            mdi:battery-50
          {% elif states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level | int  <70 %}
            mdi:battery-60
          {% elif states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level | int  <80 %}
            mdi:battery-70
          {% elif states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level | int  <90 %}
            mdi:battery-80
          {% elif states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level | int  <100 %}
            mdi:battery-90
          {% elif states.zwave.kaipule_technology_co_ltd_im20_door_window_sensor.attributes.battery_level | int  ==100 %}
            mdi:battery
          {% else %}
            mdi:battery-unknown
          {% endif %}

Thanks for your help everyone!

Just out of interest does this evaluate correctly in the template editor:

{{ state_attr('zwave.kaipule_technology_co_ltd_im20_door_window_sensor', 'battery_level' }}

If it does, you would be better off using that format as it wont generate errors if unknown (i.e. when zwave network is initialising).

1 Like

Use a variable to avoid repeating the same long-winded expression over and over.

        icon_template: >-
          {% set bl = state_attr('zwave.kaipule_technology_co_ltd_im20_door_window_sensor', 'battery_level')|int %}
          {% if bl < 10 %} mdi:battery-outline
          {% elif bl < 20 %} mdi:battery-10
          {% elif bl < 30 %} mdi:battery-20
          {% elif bl < 40 %} mdi:battery-30
          {% elif bl < 50 %} mdi:battery-40
          {% elif bl < 60 %} mdi:battery-50
          {% elif bl < 70 %} mdi:battery-60
          {% elif bl < 80 %} mdi:battery-70
          {% elif bl < 90 %} mdi:battery-80
          {% elif bl < 100 %} mdi:battery-90
          {% elif bl == 100 %} mdi:battery
          {% else %} mdi:battery-unknown
          {% endif %}

FWIW, it’s possible to reduce this template even more.

2 Likes

yes it does if the missing “)” is added, thanks for that

1 Like

Good idea @123 thanks for that

In your template, you are using the int filter to convert battery_level to an integer value. If battery_level is unknown, the int filter will report a default value of 0. Given the way the template is currently designed, it will report mdi:battery-outline as opposed to mdi:battery-unknown.

The following template changes the int filter’s default value to -1. Now if the battery_level is unknown it will represented as -1.

        icon_template: >-
          {% set bl = state_attr('zwave.kaipule_technology_co_ltd_im20_door_window_sensor', 'battery_level') | int(default=-1) %}
          {% if bl > 0 %}
            {% if bl < 10 %} mdi:battery-outline
            {% elif bl == 100 %} mdi:battery
            {% else %} mdi:battery-{{ (bl // 10) * 10 }}
            {% endif %}
          {% else %} mdi:battery-unknown
          {% endif %}

I’m confused as to why you guys aren’t using device_class: battery for the senor. It does this icon template for you without you needing to code it…

2 Likes

Doh!

… but we’re having so much fun with templates.

@sarkyscouser

Yah, no point in templates though!

  device_class: battery

Much shorter config :wink:

1 Like

Haha! Oh dear. Well that’s something I won’t forget.

To be fair there’s no indication on that page about the battery icon changing, so unless you’ve used it, it’s an easy thing to miss.

@petro

You reminded me of something from long ago. As young engineers we made the following observation:

Being so ‘heads down’ solving a problem that you don’t have time to look up and see the solution.

It can be a hard habit to break …