Changing the icon depending on the sensor state doesn't work

I have an entry in customize.yaml to change the icon of some window sensors depending on the state. But it doesn’t work at all, all sensors are showing the default sensor (“eye”) icon:

"sensor.*_fenster_status":
  templates:
    icon: "if (state === 'closed') return 'mdi:window-closed'; else return 'mdi:window-open';"

This is similar to other configurations I saw in the forum and I have no idea, why it doesn’t work in my case. Is there any typo or indentation error I overlooked?

BTW: Setting a fixed icon is working, thus the glob is obviously matching for the affected entities.

"sensor.*_fenster_status":
  icon: 'mdi:window-closed'

not sure you can name your sensor with a *.
If you’re trying to apply this to all windows, you may need to list them all.
Have you tried with a single window as an test?
I could be wrong though :slight_smile:

Is your window only open or closed? If so why not define it as a binary sensor? HA should take care of the icon automatically… Or you you “hide” your real window sensor, create a template binary_sensor where you can define your icon…

Using the glob pattern should work, as the customize.yaml file is included via customize_glob in the HA main config:

  # Customization file
  customize_glob: !include customize.yaml

But the definition for a single window without wildcards is failing as well:

"sensor.dg_bad_fenster_status":
  templates:
    icon: "if (state === 'closed') return 'mdi:window-closed'; else return 'mdi:window-open';"

The related window still shows an eye icon instead of a closed window.

Regarding your second question: Binary sensors are not suitable in this case, as these are European style tilt & turn windows, thus having three states (closed, tilted, open). I just dropped the third state for this example, but will include it as soon as it’s working with two states.

Edit: I just saw, that the separate definition for the sensor.dg_bad_fenster_status item appears in its history window…

dg_bad_fenster_status

…but nothing appears for the other entities.

Don’t know why this would be useful and if this helps solving my problem. But at least the template definition without a wildcard seems to be recognized somehow, and I would expect it to work.

if (state ===‘closed’) -> three times is equal to?

Three equal signs in comparsions mean ‘identical’, i.e. the comparsion only matches, if the datatypes of the two operators match as well. With only two equal signs the comparsion would also match, if f.e. a (string type) “2” is compared with a (int type) 2.

When comparing two operators that are obviously strings consisting only of lower case letters, testing for an identical match is kind of superfluous, but I just derived the syntax from other examples I found on the forum.

But anyways - two equal signs don’t make a difference:

dg_bad_fenster_status2

that doesn’t look right to me. Normally a template should have {{ and }} so would look like this:
{% if state == 'closed' %}mdi:window-closed{% else %}mdi:window-open{% endif %}

Are you using custom-ui? Changing icons is not supported, or am I wrong?

Oh! I remember, that I have been using Custom UI: Tiles before Lovelace was released… There was also JS coding and I could change icons :roll_eyes::thinking:
But I think, it had to be in customizing section (not customize_blob)

1 Like

Actually I didn’t realize, that these templates are a CustomUI feature. But even after installing it, the window sensor icons still remained the default eye icons.

I don’t think my config is wrong, as there are a couple of examples in other forum threads virtually doing the same that obviously seem to be working for other people.

But for now I gave up on this. Partly because there are no suitable mdi icons for European style windows anyway. And partly because I don’t want to rely on custom components, that are not officially supported. I’ve got more than enough headaches with heavily customized software in my job every weekday. :slight_smile:

For now I’m happy with some nice&clean looking cliparts for a tilt & turn window which I included via entity_picture_template in the template sensors itself.

Not very elegant and efficient, as I have to c&p the same definition for a couple of entities instead of having a single definition for all windows in customize.yaml.

But at least it’s working, and the pictures are far more recognizable than the single-hung window mdi icons.

True. :slight_smile:
Could you provide a snippet? Do you use a clipart library or a site proving these?
Just just out of curiosity. THX

All files used in the config are placed in <config-dir>/www/* on the file system. In the config they are referenced with /local/*.

For the windows I placed three png files in <config-dir>/www/window/window-*.png and this is the sensor config:

- platform: template
  sensors:
    dg_bad_fenster_status:
      friendly_name: "DG Bad Fenster Status"
      value_template: >-
        {% if is_state('binary_sensor.dg_bad_kontakt_fenster_oben', 'off') and is_state('binary_sensor.dg_bad_kontakt_fenster_unten', 'off') %}
          closed
        {% elif is_state('binary_sensor.dg_bad_kontakt_fenster_oben', 'on') and is_state('binary_sensor.dg_bad_kontakt_fenster_unten', 'off') %}
          tilted
        {% elif is_state('binary_sensor.dg_bad_kontakt_fenster_oben', 'on') and is_state('binary_sensor.dg_bad_kontakt_fenster_unten', 'on') %}
          open
        {% else %}
          error
        {% endif %}
      entity_picture_template: >-
        {% if is_state('binary_sensor.dg_bad_kontakt_fenster_oben', 'off') and is_state('binary_sensor.dg_bad_kontakt_fenster_unten', 'off') %}
          /local/window/window-closed.png
        {% elif is_state('binary_sensor.dg_bad_kontakt_fenster_oben', 'on') and is_state('binary_sensor.dg_bad_kontakt_fenster_unten', 'off') %}
          /local/window/window-tilted.png
        {% elif is_state('binary_sensor.dg_bad_kontakt_fenster_oben', 'on') and is_state('binary_sensor.dg_bad_kontakt_fenster_unten', 'on') %}
          /local/window/window-open.png
        {% endif %}

A little explanation: The templates evaluate the states of two binary window sensors per window. One at the top and one at the bottom. If the window (reed) contact is closed, the binary sensor is off, if it is opened, the binary sensor is on. i.e. “triggered”. The combined states of the top and bottom sensor of a window results in three states for a window: closed (top=off/bottom=off), tilted (top=on/bottom=off) and opened (top=on/bottom=on).

The images I used are downloaded from a window manufacturer website and slightly modified to look better (still not perfect) as thumbnails. I didn’t find any clipart library containing tilt & turn windows either.

At my home another requirement came up and I wanted to set a state by curl… So if you create a command line or rest sensor like this:

#!/bin/bash
curl -X POST \
       -H "Content-Type: application/json" \
       -d '{"state": "on", "attributes": { "icon": "mdi:run" } }' \
       http://192.168.2.31:8123/api/states/binary_sensor.wallpanel_motion > /dev/null 2>&1

:roll_eyes:

if using custom-ui, and not a template sensor, this works:

sensor.tester_state:
#  icon: mdi:test-tube
  templates:
    icon: >
      if (state === 'on') return 'mdi:test-tube';
      return 'mdi:test-tube-off';
    icon_color: >
      if (state === 'on') return 'rgb(251, 210, 41)';
      return 'rgb(54, 95, 140)';

if a template sensor, this does it:

  part_of_day:
    friendly_name: 'Part of Day'
    value_template: >
      {% if now().hour in range(0, 6) %}
        Midnight
      {% elif now().hour in range(6, 12) %}
        Morning
      {% elif now().hour in range(12, 18) %}
        Afternoon
      {% else %}
        Evening
      {% endif %}
    icon_template: >
      {% if now().hour in range(0, 6) %}
        mdi:weather-night
      {% elif now().hour in range(6, 12) %}
        mdi:weather-sunset-up
      {% elif now().hour in range(12, 18) %}
        mdi:weather-sunny
      {% else %}
        mdi:weather-sunset-down
      {% endif %}

or

  day_night:
    friendly_name: 'Day/Night'
    value_template: >
      {% if is_state('sun.sun', 'above_horizon') %}
        Day
      {% else %}
        Night
      {% endif %}
    entity_picture_template: >
      {% if is_state('sun.sun', 'above_horizon') %}
        /local/weather/day.png
      {% else %}
        /local/weather/night.png
      {% endif %}

also, customize_glob certainly has this possibility:

sensor.*_motion_sensor_temperature:
  templates:
    icon_color: >
      if (state < -5) return 'rgb(30, 255, 255)';
      if (state < 0) return 'rgb(30, 144, 255)';
      if (state < 10) return 'rgb(255, 255, 0)';
      if (state < 15) return 'rgb(255, 211, 30)';
      if (state < 20) return 'rgb(0, 128, 0)';
      if (state < 25) return 'rgb(255, 165, 0)';
      if (state < 30) return 'rgb(255, 0, 0)';
      if (state < 35) return 'rgb(85, 0, 0)';
      return 'rgb(47, 0, 0)';

device_tracker.imac_*:
  templates:
    theme: >
      if (state === 'home') return 'green';
      return 'grey';
    _stateDisplay: >
      if (state === 'home') return 'On';
      return 'Off';

etcetc.

1 Like

So the only choice is to create two sensors, if a template sensor is necessary?
e.g.
create a template sensor for the value, but for display create a mqtt sensor, which takes the values from mqtt statestream on itself?

Yes, this should work with custom-ui. But I couldn’t get this to work. Still don’t know why, as the templates syntax is simple enough to get it right. But even after checking it the third and fourth time, HA resisted to show the correct icons. I really don’t have a clue, why it didn’t work. But as stated, I needed three window states and there weren’t fitting mdi icons anyway. So I went with entity pictures and they currently don’t seem to be supported by custom-ui.