Custom UI - icon color change

Hello,

in what file you write this information?

@Mariusthvdb
Hi Marius can you help me?
I am seeing sometimes these errors in Log (on startup usually):

2021-11-25 19:01:28 ERROR (MainThread) [frontend.js.latest.202111090] http://192.168.1.33:8123/hacsfiles/custom-ui/custom-ui.js?hacstag=2675581482021528:219:9 Uncaught TypeError: Cannot read properties of undefined (reading 'state')

many many lots of them

Is it possible to find out which particular sensor causes it?

Yes, well, itā€™s easy but not always easy to find :wink:

You need to catch the exception . It happens when an entity is customized before the entity exists. In those customizations you need to add an if clause for the existence of the entity.

Not at my desk currently, but Iā€™ll copy a few when I get back. Meanwhile, I do think I have several in my examples in the repo.

I have TWO places where I am customizing dependingly on state.
Here is one of them - coloring a battery icon:

        icon_color: >
          if (['unavailable','unknown'].includes(state)) return 'brown';
          var WARNING = entities['input_number.battery_level_critical'].state;
          var CRITICAL = entities['input_number.battery_level_warning'].state;
          if (WARNING === 'unavailable' ||
              WARNING === 'unknown' ||
              WARNING === 'none' ||
              CRITICAL === 'unavailable' ||
              CRITICAL === 'unknown' ||
              CRITICAL === 'none')
            return 'brown';
          if (state <= Number(WARNING))
            return 'red';
          if (state <= Number(CRITICAL))
            return 'rgb(250,218,67)';
          return 'green';

In short:

  • if state <= states(ā€˜input_number.battery_level_criticalā€™) ā†’ red
  • if state <= states(ā€˜input_number.battery_level_warningā€™) ā†’ orange

Btw if you have any suggestions for the code - I am ready to listen!

Initially there were == instead of ===.
Just a few minutes ago I I realized a difference between == & === and then replaced to ===.

Now I will see if anything changes.

Update - no, same errors.

so thereā€™s 2 things:
find which template causes the Error, and fix
improve the template if possible

can you confirm commenting out the above template solves the Error? if so you are I the right track?

if so, it can be either input_number hasnā€™t been initialized upon first check. you can add a guard like:

if (entity && entity.attributes && entity.attributes.templates)

ofc depending on your needs (this from a button card template), but you get the idea: first check if the entity (state) exists, then if it has attributes, and then if it has a specific attributes.

or:

          var state = states[entity_id];
          if (state && state.state === 'on')
              count++;
          });

or on an entity:

    sensor.daylight_savings_times:
      templates:
        icon: >
          if (attributes && attributes['dst active']
              && attributes['dst active'] == true )
          return 'mdi:update';
          return 'mdi:history';
        icon_color: >
          if (attributes && attributes['dst active']
              && attributes['dst active'] == true )
          return 'maroon';
          return 'green';

hope this helps you?

btw no difference between ==/=== I always use == except for the template Romrider helped me create aboveā€¦ (just pasted that for reference sake)

I excluded this part:
image
Restarted, no errors.
But before these errors took place not every restart - so I need more restarts, more statistics.

Does it guarantee that the 1st condition will be checked first?

Seems that this entity variable relates to the sensor (sensor.daylight_savings_times in your example).
And this code checks THIS sensor.
Is there any meaning to check if THIS sensor exists in the code which customizing THIS sensor?

Also, how to check OTHER sensors - like input_numbers from my case?

yes, because those can be template sensors not yet initialized, or created by other integrations during setup. If bad luck, a non guarded customization can lock your instance in repeating errorsā€¦

you can check external entities (global is what theyā€™re called ) as you know you can do like in other JS ( eg custom:button-card)

# using an attribute of another (global) entity
    sensor.power_consumption:
      templates:
        icon_color: >
          if (entities['sensor.smart_meter'].attributes.power > 3000) return 'red';
          return green;

see custom-ui/EXAMPLES.md at 053380a7f1628ea5efe8b385e7552ec92fd35b21 Ā· Mariusthvdb/custom-ui Ā· GitHub for some further explanation

Changed the code to:

        icon_color: >-
          if (entity &&
              entities['input_number.battery_level_critical'] &&
              entities['input_number.battery_level_warning'])
          {
            var WARNING = entities['input_number.battery_level_critical'].state;
            var CRITICAL = entities['input_number.battery_level_warning'].state;
            if (state <= Number(WARNING))
              return 'red';
            if (state <= Number(CRITICAL))
              return 'rgb(250,218,67)';
            return 'green';
          }
          else
            return 'brown';

Will seeā€¦
Hope it helps.
Thank you for support!

Hello Marius,

Are you from Holland? I am and need your help. I am new to this but learned al lot the past weeks.
I installed mod-card and your custom-ui. Itā€™s in resources. I would like to change the color of the icon of the Mode when its Perm.Low to orange. Do i have to create this in the configuration of the ventilation in configuration.yaml or in this card? The card has this code:

type: custom:layoutcard
layout_type: masonry
cards:
  - type: entities
    title: Ventilatie
    entities:
      - entity: sensor.duco_ventilation_mode
        name: Mode
      - entity: sensor.duco_fan_speed
        name: Rpm
      - entity: sensor.duco_current_fan_percentage
        name: Percentage
      - entity: sensor.duco_ventilation_countdown
        name: Countdown
    show_header_toggle: false
    state_color: false
  - type: grid
    columns: 1
    square: false
    cards:
      - type: custom:button-card
        entity: switch.duco_ventilation_auto
        name: Auto Mode
        styles:
          card:
            - height: 80px
      - type: grid
        columns: 3
        square: false
        cards:
          - type: custom:button-card
            entity: switch.duco_ventilation_low_perm
            name: P. Low
            styles:
              card:
               - height: 55px

Ventilation UI

HI Maarten
yes I am :wink:

you can either install custom-ui and customize those entities under:

homeassistant:
  customize:

as is described in the examples file on my repo, or you can install/use card-mod, and mod these in the lovelace card config, as is described in the card-mod repo docs ;-))

btw, please format your code correctly with the </> button in the editor, so we can check for errors. or use triple (not single) ``` backticks

please try first, and present us with the outcome of your results? scroll down to the end of this post šŸ”¹ Card-mod - Add css styles to any lovelace card - #1188 by Ildar_Gabdullin and see all options.

to get you on track:

          - entity: sensor.backup_state
            card_mod:
              style: |
                :host {
                  --card-mod-icon:
                    {% if states(config.entity) == 'backed_up' %} mdi:check-circle
                    {% else %} mdi:alert-circle
                    {% endif %};

                  --paper-item-icon-color:
                    {% if states(config.entity) == 'backed_up' %} green
                    {% else %} red
                    {% endif %};
                }

adapt to your liking ofc.

I have the low icon in red now, so itā€™s working.
What i would like to have is the icon of the sensor Mode changing to red when mode is Low.

type: custom:layout-card
layout_type: masonry
cards:
  - type: entities
    title: Ventilatie
    entities:
      - entity: sensor.duco_ventilation_mode
        name: Mode
      - entity: sensor.duco_fan_speed
        name: Rpm
      - entity: sensor.duco_current_fan_percentage
        name: Percentage
      - entity: sensor.duco_ventilation_countdown
        name: Countdown
    show_header_toggle: false
    state_color: false
  - type: grid
    columns: 1
    square: false
    cards:
      - type: custom:button-card
        entity: switch.duco_ventilation_auto
        name: Auto Mode
        styles:
          card:
            - height: 80px
      - type: grid
        columns: 3
        square: false
        cards:
          - type: custom:button-card
            entity: switch.duco_ventilation_low
            name: Low
            card_mod:
              style: |
                :host {
                  --card-mod-icon:
                    {% if states(config.entity) == 'backed_up' %} mdi:check-circle
                    {% else %} mdi:alert-circle
                    {% endif %};

                  --paper-item-icon-color:
                    {% if states(config.entity) == 'backed_up' %} green
                    {% else %} red
                    {% endif %};
                }
            styles:
              card:
                - height: 55px
          - type: custom:button-card
            entity: switch.duco_ventilation_middle
            name: Mid
            styles:
              card:
                - height: 55px
          - type: custom:button-card
            entity: switch.duco_ventilation_high
            name: High
            styles:
              card:
                - height: 55px
          - type: custom:button-card
            entity: switch.duco_ventilation_low_perm
            name: P. Low
            icon: mdi:fan-speed-1
            styles:
              card:
                - height: 55px
          - type: custom:button-card
            entity: switch.duco_ventilation_mid_perm
            name: P. Mid
            icon: mdi:fan-speed-2
            styles:
              card:
                - height: 55px
          - type: custom:button-card
            entity: switch.duco_ventilation_high_perm
            name: P. High
            icon: mdi:fan-speed-3
            styles:
              card:
                - height: 55px

This is in my configuration.yaml


- platform: mqtt
  unique_id: duco_vent_mode
  name: Duco Ventilation Mode
  state_topic: "VENTILATION_GATEWAY/VENTILATION_GATEWAY/Ventilationmode"
  icon: mdi:hvac
  value_template: >-
    {% set status = value | int %}
    {% if status == 13 %}
    {{'Perm. High'}}
    {% elif status == 12 %}
    {{'Perm. Mid'}}
    {% elif status == 11 %}
    {{'Perm. Low'}}
    {% elif status == 3 %}
    {{'High'}}
    {% elif status == 2 %}
    {{'Mid'}}
    {% elif status == 1 %}
    {{'Low'}}
    {% elif status == 0 %}
    {{'Auto'}}
    {% else %}
    {{'Undefined'}}
    {% endif %}
1 Like

rightā€¦ my code was an example, and ofc based on an entity with its specific states. I dont think your entity has state 'backed_upā€™ :wink: so adjust to your specific setting and needs

how do you find the state of your entity?

(not trying to be a pain here, but trying to help you find out yourself)

I know that and i found out :wink:
Just one thing left to do. I like to have the Mode Auto Icon to be not white but like the transparant Rpm.

        card_mod:
          style: |
            :host {
                --paper-item-icon-color:
                {% if states(config.entity) == 'Perm. High' %} red
                {% else %} primary-color
                {% endif %};
                }

that seems like var(--disabled-text-color) but you could simply test that and check your theme?
or, it could be what ever color is in your paper-item-icon-color:.

ofc you can also put var(--paper-item-icon-color) in the case

var(ā€“disabled-text-color) works and (ā€“paper-item-icon-color) to. Thank you very much.
Can i add Mode Mid and Low also to color red?

HI Marius,
I have 171 of these errors at every startup. Iā€™ve just been ignoring them as every thing works once HA is fully started.

ERROR (MainThread) [frontend.js.latest.202202030] https:/[redacted]/hacsfiles/custom-ui/custom-ui.js:219:9 Uncaught TypeError: Cannot read properties of undefined (reading 'state')

I donā€™t think I have 171 customized entities but will start trying to add the if codingā€¦

yes, thats a familiar error, when you dont ā€˜guardā€™ your templates. The state you use in the template isnt yet properly initialized at startup, and thus can not be used in the template.

it throws these until the state is ready, and you probably see no issues after that?

I would strongly suggest you find the incorrect templates, because if things go wild, you might not be able to reach the frontend at all, and all you see is frontend errors in your log :wink:

Down to 54 errors now!

sensor.brunt_win10:
  templates:
    icon: >
      if (state && state.state == 'Unavailable') return 'mdi:alert';
      if (states('sensor.brunt_win10_system_idle_time') < states('input_number.pc_active_timeout')) return 'mdi:monitor-dashboard';
      return 'mdi:monitor';
    icon_color: >
      if (state && state.state == 'Unavailable') return 'red';
      if (states('sensor.brunt_win10_system_idle_time') < states('input_number.pc_active_timeout')) return 'yellow';
      return 'grey';

will need to be this?

sensor.brunt_win10:
  templates:
    icon: >
      if (state && state.state == 'Unavailable') return 'mdi:alert';
      if (states('sensor.brunt_win10_system_idle_time') && states('input_number.pc_active_timeout') && states('sensor.brunt_win10_system_idle_time') < states('input_number.pc_active_timeout')) return 'mdi:monitor-dashboard';
      return 'mdi:monitor';
    icon_color: >
      if (state && state.state == 'Unavailable') return 'red';
      if (states('sensor.brunt_win10_system_idle_time') && states('input_number.pc_active_timeout') && states('sensor.brunt_win10_system_idle_time') < states('input_number.pc_active_timeout')) return 'yellow';
      return 'grey';