What is the right way of constructing icon_template?

Hi All,

I have a template sensor and wanted to change its icon based on the sensor’s state.
So far I saw only examples where value_template and icon_template definitions were identical (but obviously the latter had to return icon name instead of state).
It’s very inconvenient, especially if involves several sensors and/or complex logic.

Am I missing something or that’s the way it is and there is no way to avoid duplication of code and possible glitches if changes made only in one of the two locations (in value_template but not in icon_template or vice versa)?

Here’s the sensor’s definition that DOES NOT work right:

- platform: template
  sensors:
    contact_1st_floor_safe:
      friendly_name: safe
      entity_id:
        - input_boolean.contact_8895854
        - input_boolean.contact_8895854_tampered
      value_template: >
        {% if is_state('input_boolean.contact_8895854_tampered', 'on') %}
          {{ states('sensor.contact_always_tampered') }}
        {% elif is_state('input_boolean.contact_8895854', 'on') %}
          {{ states('sensor.contact_always_open') }}
        {% else %}
          {{ states('sensor.contact_always_closed') }}
        {% endif %}
      icon_template: >-
        {%- set state = states('sensor.contact_1st_floor_safe') -%}
        {%- if state == states('sensor.contact_always_open') -%}
          mdi:door-open
        {%- elif state == states('sensor.contact_always_closed') -%}
          mdi:door-closed
        {%- elif state == states('sensor.contact_always_tampered') -%}
          mdi:image-broken
        {%- else -%}
          mdi:cloud-question
        {%- endif -%}

1 Like

Ok, 5 minutes after asking the question I realised the answer was VERY close.
Basically, leave that sensor alone (without icon_template) and use it as a source of states for another one that only change its icon. “Onion” approach :wink:

- platform: template
  sensors:
    # this one gives us states
    contact_1st_floor_safe:
      friendly_name: safe
      entity_id:
        - input_boolean.contact_8895854
        - input_boolean.contact_8895854_tampered
      value_template: >
        {% if is_state('input_boolean.contact_8895854_tampered', 'on') %}
          {{ states('sensor.contact_always_tampered') }}
        {% elif is_state('input_boolean.contact_8895854', 'on') %}
          {{ states('sensor.contact_always_open') }}
        {% else %}
          {{ states('sensor.contact_always_closed') }}
        {% endif %}
    # and this one adds dynamic icons to states
    contact_1st_floor_safe_gui:
      entity_id: sensor.contact_1st_floor_safe
      friendly_name_template: "{{ state_attr('sensor.contact_1st_floor_safe', 'friendly_name') }}"
      value_template: "{{ states('sensor.contact_1st_floor_safe') }}"
      icon_template: >-
        {%- set state = states('sensor.contact_1st_floor_safe') -%}
        {%- if state == states('sensor.contact_always_open') -%}
          mdi:door-open
        {%- elif state == states('sensor.contact_always_closed') -%}
          mdi:door-closed
        {%- elif state == states('sensor.contact_always_tampered') -%}
          mdi:image-broken
        {%- else -%}
          mdi:cloud-question
        {%- endif -%}

Another option is to create a sensor (template binary or template) that returns state and use it in value_template and icon_template:

- platform: template
  sensors:
    # trhis one gives us states
    contact_1st_floor_safe:
      entity_id:
        - input_boolean.contact_8895854
        - input_boolean.contact_8895854_tampered
      value_template: >
        {% if is_state('input_boolean.contact_8895854_tampered', 'on') %}
          {{ states('sensor.contact_always_tampered') }}
        {% elif is_state('input_boolean.contact_8895854', 'on') %}
          {{ states('sensor.contact_always_open') }}
        {% else %}
          {{ states('sensor.contact_always_closed') }}
        {% endif %}
    # and this one adds friendly_name and dynamic icons to states
    contact_1st_floor_safe_gui:
      entity_id: sensor.contact_1st_floor_safe
      friendly_name: safe
      value_template: "{{ states('sensor.contact_1st_floor_safe_state') }}"
      icon_template: >-
        {%- set state = states('sensor.contact_1st_floor_safe_state') -%}
        {%- if state == states('sensor.contact_always_open') -%}
          mdi:door-open
        {%- elif state == states('sensor.contact_always_closed') -%}
          mdi:door-closed
        {%- elif state == states('sensor.contact_always_tampered') -%}
          mdi:image-broken
        {%- else -%}
          mdi:cloud-question
        {%- endif -%}
1 Like