Need a little push with Icon templates

Attempting to build a battery level sensor that has dynamic Icon based on charging status provided by Life360.

The sensor displays the battery % but always shows the ELSE icon no matter what state the device is returning.

Any suggestions to get the icon to update?

*** configuration.yaml*****

  • platform: template
    sensors:
    chris_batt_lvl:
    value_template: “{{ states.device_tracker.life360_chris.attributes.battery }}”
    unit_of_measurement: ‘%’
    icon_template: >-
    {%- if is_state(‘states.device_tracker.life360_chris.attributes.battery_charging’, ‘false’) -%}
    mdi:battery-40
    {%- else -%}
    mdi:battery-charging-70
    {%- endif -%}

I’m sure your yaml is correct because you say its working but it’s kinda hard to look at it because it isn’t formatted for the forum…I’m not familiar with the device you’re using but I guess we can assume it has a battery_charging state that you can pull up on the states page and that it is working correctly and returning the state as it should. I would start there first. Try running your logic in the template designer to make sure it actually works (assuming you haven’t) to try and figure out the problem.

anywho here’s a working icon template i use in my setup.with my phones. just so you can compare

phone:
  friendly_name: "Phone Battery"
  unit_of_measurement: "%"
  value_template: "{{states.device_tracker.phone.attributes.battery}}"
  icon_template: >
    {% if states.device_tracker.phone.attributes.battery %}
      {% if states.device_tracker.phone.attributes.battery >= 98 %}
        mdi:battery
      {% elif states.device_tracker.phone.attributes.battery >= 85 %}
        mdi:battery-90
      {% elif states.device_tracker.phone.attributes.battery >= 75 %}
        mdi:battery-80
      {% elif states.device_tracker.phone.attributes.battery >= 65 %}
        mdi:battery-70
      {% elif states.device_tracker.phone.attributes.battery >= 50 %}
        mdi:battery-50
      {% elif states.device_tracker.phone.attributes.battery >= 35 %}
        mdi:battery-30
      {% elif states.device_tracker.phone.attributes.battery >= 25 %}
        mdi:battery-20
      {% elif states.device_tracker.phone.attributes.battery <= 15 %}
        mdi:battery-10
      {% else %}
        mdi:battery-outline
      {% endif %}
    {% endif %}

hope this helps.

Thanks for the reply!
I’m just a few days into setting up my first Home Assistant build. I will take a look this evening since my companys firewall doesn’t like DuckDNS domains. My copy/paste didn’t retain the indents but they seem to be acceptable to HAss. - no errors when i check config or in my logs.

I like this template!
I have the battery values displayed as values - and I’m trying to pull a separate attribute from the device tracker to indicate if the device is on a charger. My template should be simple - since the value is just a true / false. Maybe I need a separate value_template for the charging status that drives the icon_template?

I admire your effort but there is a much easier way to implement this, device_class. In configuration.yaml in the customize section, use:

homeassistant:
  customize:
    sensor.my_battery_sensor:
      device_class: battery

And it will properly adjust your battery icon based on the %.

Still struggling on this one:

In the dev tool,

This:
{{ states.device_tracker.life360_chris.attributes.battery_charging }}
Returns a true or false value

But this “IF/THEN” doesn’t see the state:
{% if is_state(‘device_tracker.life360_chris.attributes.battery_charging’, ‘False’) %}
mdi:battery-charging-60
{% else %}
mdi:battery-70
{% endif %}

I can see its not working by changing true /false value in the first line. I’m thinking my inexperience in coding, is certainly at fault here

I also did some testing using a binary.sensor and confirmed the logic is right and the icon updates if i manually change the value, But i just cant seem to pull the attribute correctly.

  - platform: template
    sensors: 
      chris_batt_lvl:
        value_template: "{{ states.device_tracker.life360_chris.attributes.battery }}"
        unit_of_measurement: '%'
        icon_template: >
          {% if is_state('binary_sensor.c_cell_charge', 'on') %}
            mdi:battery-charging-60
          {% else %}
            mdi:battery-70
          {% endif %}

remove the quotes around True/False. That doesn’t return a string, it returns a boolean of True/False. The quotes you are adding around True or False turn them into a string. True != 'True' and False != 'False'.

Also, you weren’t using the correct method to grab the attribute out of the object. You have 2 methods to get states and attributes.

FYI, an entity_id is made of of the domain and object_id. This is used in the following examples.

entity_id = domain.object_id

States:

states('domain.object_id') # gets the state
states.domain.object_id.state # access the object without a method.
is_state('domain.object_id', 'on') #compares the state to a value

Attributes

state_attr('domain.object_id','my_attr') # gets the 'my_attr'
states.domain.object_id.attributes.my_attr # gets the 'my_attr' from the state object without a method
is_state_attr('domain.object_id','my_attr','on') # compares the attribute to a value

So, this is what your equation should look like with a method.

{% if is_state_attr('device_tracker.life360_chris','battery_charging', False) %}

or without a method

{% if states.device_tracker.life360_chris.attributes.battery_charging == False %}

Also you don’t have to see if something is equal to False, you can just use it directly (since it’s already a boolean.) Try this:

  - platform: template
    sensors: 
      chris_batt_lvl:
        value_template: "{{ states.device_tracker.life360_chris.attributes.battery }}"
        unit_of_measurement: '%'
        icon_template: >
          {% if states.device_tracker.life360_chris.attributes.battery_charging %}
            mdi:battery-70
          {% else %}
            mdi:battery-charging-60
          {% endif %}

This will work as long as device_tracker.life360_chris exists in the state machine with its full attributes. But at startup, that’s not always the case. So, this might be better:

  - platform: template
    sensors: 
      chris_batt_lvl:
        value_template: "{{ state_attr('device_tracker.life360_chris', 'battery') }}"
        unit_of_measurement: '%'
        icon_template: >
          {% set charging = state_attr('device_tracker.life360_chris', 'battery_charging') %}
          {% if charging is none %}
            mdi:help
          {% elif charging %}
            mdi:battery-70
          {% else %}
            mdi:battery-charging-60
          {% endif %}

Thanks Petro and Phil!
working great now!

Also, the additional explanation was really helpful