Dynamic badge label (text) colours

Here’s a little something I’ve wanted to do for a long time: I wanted to create temperature badges that apply colour according to the temperature value.

temp1 temp2

And here’s the code, using card-mod:

badges:
  - entity: sensor.living_room_ht_temperature
    name: Living Room
    card_mod:
      style: |
        :host {
          --label-badge-text-color:
              {%- macro interpolate(temp, start, stop) -%}
                {%- set (start_temp, start_color) = start -%}
                {%- set (stop_temp, stop_color) = stop -%}
                {%- set (start_r, start_g, start_b) = (int(start_color[0:2], base=16), int(start_color[2:4], base=16), int(start_color[4:6], base=16)) -%}
                {%- set (stop_r, stop_g, stop_b) = (int(stop_color[0:2], base=16), int(stop_color[2:4], base=16), int(stop_color[4:6], base=16)) -%}
                {%- set s = ((temp - start_temp)/(stop_temp - start_temp)) -%}
                {# some channels might be negative; most browsers are probably tolerant, but in case not #}
                {%- set r = max(int(start_r + s*(stop_r - start_r)), 0) -%}
                {%- set g = max(int(start_g + s*(stop_g - start_g)), 0) -%}
                {%- set b = max(int(start_b + s*(stop_b - start_b)), 0) -%}
                rgb({{ r }}, {{ g }}, {{ b }});
              {%- endmacro -%}
              {%- set temp = states(config.entity) | float(0) -%}
              {%- set temp_map = {
                                   5: "3498db",
                                   15: "70a03c",
                                   22: "ff9800",
                                   30: "e74c3c"
                                 }  -%}
              {%- set keys = temp_map | sort -%}
              {%- set index = keys | select("lt", temp) | list | length -%}
              {%- if index == 0 -%}
                #{{ temp_map[keys | first] }}
              {%- elif index == keys | length -%}
                #{{ temp_map[keys | last] }}
              {%- else -%}
                {%- set start = (keys[index - 1], temp_map[keys[index - 1]]) -%}
                {%- set stop = (keys[index], temp_map[keys[index]]) -%}
                {{ interpolate(temp, start, stop) }}
              {%- endif -%}
        }

Here is the colour scale I’ve chosen:

It uses linear interpolation in the RGB colour space. I considered HSV, but didn’t find a compelling reason to do so given the result.

Simply change the map to your needs: Each key is a temperature with a colour (in hex) which that particular temperature must be. I tried to avoid going through yellow, since given my light and dark themes, yellow typically doesn’t read easily against a white background, but it’s up to you to decide what you find pleasing (or e.g. to compensate for a colour perception deficiency). You can have more colour stops if you want and they don’t need to be equidistant.

I even researched some temperature scales used in GIS that are used on sea maps, but since the range of temperatures are so different, I ditched that idea. I went with what felt right for the location I live in.

This can, of course, be applied to any continuous numeric state. It would work for discrete numeric values too, but then you can simplify this to:

    card_mod:
      style:
        .: |
          :host {
            --label-badge-text-color:
                {%- set mapping = {
                                     0: "",
                                     1: "#40b100",
                                     2: "#ffe500",
                                     3: "#ffa800",
                                     4: "#ff5800",
                                     5: "#aa0000" } -%}
                {%- set key = states(config.entity) | int(0) -%}
                {{ mapping[key] if key in mapping else "" }} !important;
          }

Credit to Ildar that’s very active with card-mod to have provided the starting point in terms of which variable to change.

2022-11-03: Fixed a bug with the indexing.

10 Likes

Good application.
In my setup, I have chosen discrete scales like “cold - cool - warm - hot” (4 colors) with tunable intervals (“input_number” settings) for temperatures (similarly - for co2, pm25, tvoc, humidity, battery level, speedtest results, …).
But gradient colors look much nicer.

Unfortunately, we cannot use this “gradient function” as a macro available for all views/cards…

@parautenbach - added a link to your post to the consolidation post! Here all credits to you )))

1 Like

Thanks for the mention, @Ildar_Gabdullin!

1 Like

Nice work! I just dropped this onto my floor plan.

But is there a way to hide to text if I use this on a picture-elements card ? tried following Hide text for badges in picture-elements card - #10 by Mincka but I’m unsure where to place color: transparent - Thanks :slight_smile:

Thanks!

What are you displaying if you’re not displaying the text? In other words, what’s being coloured?

Might make sense with a screenshot :
ksnip_20221103-161657

So, for example, I want to remove ‘Conservatory Door Temperature’ (top left)

I see – that helps.

It would be best to head over to the card-mod topic for the more general questions about badges and styling (just to keep this topic more focused on the original project). I think your answer is here, right at the start: 🔹 Card-mod - Add css styles to any lovelace card - #1310 by Ildar_Gabdullin.

Maybe insert it like this, inside the host section (I haven’t tested this):

    card_mod:
      style: |
        :host {
          color: transparent;
          --label-badge-text-color:
          ...

That worked - thanks.

1 Like

Any help on how to embed this in my picture elements card node:

elements:
  - entity: sensor.nas_pd02z_battery_powered_pir_sensor_v2_air_temperature_4
    style:
      color: black
      left: 80%
      top: 50%
    type: state-label
    tap_action:
      action: none
image: /local/floor.png
type: picture-elements

And in a simple card:

type: entities
entities:
  - entity: sensor.fgsd002_smoke_sensor_air_temperature_2
  - entity: sensor.fgsd002_smoke_sensor_air_temperature_3
  - entity: sensor.fgsd002_smoke_sensor_air_temperature_4
  - type: divider
    style:
      height: 1px
      width: 90%
      margin-left: auto
      margin-right: auto
  - entity: sensor.fgsd002_smoke_sensor_air_temperature_5
  - entity: sensor.nas_pd02z_battery_powered_pir_sensor_v2_air_temperature_3
  - type: divider
    style:
      height: 1px
      width: 90%
      margin-left: auto
      margin-right: auto
  - entity: sensor.nas_pd02z_battery_powered_pir_sensor_v2_air_temperature_5
  - entity: sensor.motion_sensor_parkeerplaats_air_temperature
  - entity: sensor.fgms001_motion_sensor_air_temperature
  - entity: sensor.zwa005_trisensor_air_temperature
  - entity: sensor.zw100_multisensor_6_air_temperature
title: Temperature

Maybe @brewston can post part of their implementation. I don’t use picture elements with anything, so I can’t test this quickly. I think one would need unique IDs (CSS) on elements to apply this repeatedly for each individual element (lots of duplication then), or if all of yours are of the same class, apply it to the CSS class.

As for the entities card, you can have a card_mod section for each entity. Again, there would be duplication, but perhaps you could simplify things with YAML anchors.

Any working examples warm welcome

You need to be prepared to experiment a bit to determine the right path, but try this (maybe):

type: entities
entities:
  - entity: sensor.fgsd002_smoke_sensor_air_temperature_2
    card_mod:
      style:
        hui-generic-entity-row:
          $:
            .: |
              .info {
                color: 
                  {%- macro interpolate(temp, start, stop) -%}
                    {%- set (start_temp, start_color) = start -%}
                    {%- set (stop_temp, stop_color) = stop -%}
                    {%- set (start_r, start_g, start_b) = (int(start_color[0:2], base=16), int(start_color[2:4], base=16), int(start_color[4:6], base=16)) -%}
                    {%- set (stop_r, stop_g, stop_b) = (int(stop_color[0:2], base=16), int(stop_color[2:4], base=16), int(stop_color[4:6], base=16)) -%}
                    {%- set s = ((temp - start_temp)/(stop_temp - start_temp)) -%}
                    {# some channels might be negative; most browsers are probably tolerant, but in case not #}
                    {%- set r = max(int(start_r + s*(stop_r - start_r)), 0) -%}
                    {%- set g = max(int(start_g + s*(stop_g - start_g)), 0) -%}
                    {%- set b = max(int(start_b + s*(stop_b - start_b)), 0) -%}
                    rgb({{ r }}, {{ g }}, {{ b }});
                  {%- endmacro -%}
                  {%- set temp = states(config.entity) | float(0) -%}
                  {%- set temp_map = {
                                       5: "3498db",
                                       15: "70a03c",
                                       22: "ff9800",
                                       30: "e74c3c"
                                     }  -%}
                  {%- set keys = temp_map | sort -%}
                  {%- set index = keys | select("lt", temp) | list | length -%}
                  {%- if index == 0 -%}
                    #{{ temp_map[keys | first] }}
                  {%- elif index == keys | length -%}
                    #{{ temp_map[keys | last] }}
                  {%- else -%}
                    {%- set start = (keys[index - 1], temp_map[keys[index - 1]]) -%}
                    {%- set stop = (keys[index], temp_map[keys[index]]) -%}
                    {{ interpolate(temp, start, stop) }}
                  {%- endif -%}
              }

nope:

Remove the indented block after the color: bit and just say e.g. red. Does that work? If you can figure out that part then the macro and template should work. Head over to the main card-mod thread to get more help. There are many examples by Ildar.

sorry, I do not get what you mean… And your startpost is exactly what I need :slight_smile: … just don’t know ho to get that into action.

Ildar_Gabdullin his huge post with all examples is unsearchable due to the word “color” pops up in somewhat all posts :-).

EDIT Sorry, did not meant to mention iildar directly (sorry) - removed @

Unless you go to the 1st post in card-mod thread and see a link to it at the bottom)

yes sure. I have read them piece by piece but none fit my question / use case as far as I can tell. Then I started to search…

Here’s my code (as you can see, there is lot of repetition) Hope it helps

type: picture-elements
elements:
  - type: state-badge
    entity: sensor.0x286d97000100f3af_temperature
    style:
      top: 38%
      left: 9%
    card_mod:
      style: |
        :host 

         {
          color: transparent;
          --label-badge-text-color:
              {%- macro interpolate(temp, start, stop) -%}
                {%- set (start_temp, start_color) = start -%}
                {%- set (stop_temp, stop_color) = stop -%}
                {%- set (start_r, start_g, start_b) = (int(start_color[0:2], base=16), int(start_color[2:4], base=16), int(start_color[4:6], base=16)) -%}
                {%- set (stop_r, stop_g, stop_b) = (int(stop_color[0:2], base=16), int(stop_color[2:4], base=16), int(stop_color[4:6], base=16)) -%}
                {%- set s = ((temp - start_temp)/(stop_temp - start_temp)) -%}
                {# some channels might be negative; most browsers are probably tolerant, but in case not #}
                {%- set r = max(int(start_r + s*(stop_r - start_r)), 0) -%}
                {%- set g = max(int(start_g + s*(stop_g - start_g)), 0) -%}
                {%- set b = max(int(start_b + s*(stop_b - start_b)), 0) -%}
                rgb({{ r }}, {{ g }}, {{ b }});
              {%- endmacro -%}
              {%- set temp = states(config.entity) | float(0) -%}
              {%- set temp_map = {
                                   5: "3498db",
                                   16: "70a03c",
                                   19: "ff9800",
                                   24: "e74c3c"
                                 }  -%}
              {%- set keys = temp_map | sort -%}
              {%- set index = keys | select("lt", temp) | list | length -%}
              {%- if index == 0 -%}
                #{{ temp_map[keys | first] }}
              {%- elif index == keys | length -%}
                #{{ temp_map[keys | last] }}
              {%- else -%}
                {%- set start = (keys[index - 2], temp_map[keys[index - 2]]) -%}
                {%- set stop = (keys[index - 1], temp_map[keys[index - 1]]) -%}
                {{ interpolate(temp, start, stop) }}
              {%- endif -%}
        }
            .: |
             color: transparent 
  - type: state-badge
    entity: sensor.kitchen_radiator_temperature
    style:
      top: 50%
      left: 9%
    card_mod:
      style: |
        :host {
          color: transparent;
          --label-badge-text-color:
              {%- macro interpolate(temp, start, stop) -%}
                {%- set (start_temp, start_color) = start -%}
                {%- set (stop_temp, stop_color) = stop -%}
                {%- set (start_r, start_g, start_b) = (int(start_color[0:2], base=16), int(start_color[2:4], base=16), int(start_color[4:6], base=16)) -%}
                {%- set (stop_r, stop_g, stop_b) = (int(stop_color[0:2], base=16), int(stop_color[2:4], base=16), int(stop_color[4:6], base=16)) -%}
                {%- set s = ((temp - start_temp)/(stop_temp - start_temp)) -%}
                {# some channels might be negative; most browsers are probably tolerant, but in case not #}
                {%- set r = max(int(start_r + s*(stop_r - start_r)), 0) -%}
                {%- set g = max(int(start_g + s*(stop_g - start_g)), 0) -%}
                {%- set b = max(int(start_b + s*(stop_b - start_b)), 0) -%}
                rgb({{ r }}, {{ g }}, {{ b }});
              {%- endmacro -%}
              {%- set temp = states(config.entity) | float(0) -%}
              {%- set temp_map = {
                                   5: "3498db",
                                   16: "70a03c",
                                   19: "ff9800",
                                   24: "e74c3c"
                                 }  -%}
              {%- set keys = temp_map | sort -%}
              {%- set index = keys | select("lt", temp) | list | length -%}
              {%- if index == 0 -%}
                #{{ temp_map[keys | first] }}
              {%- elif index == keys | length -%}
                #{{ temp_map[keys | last] }}
              {%- else -%}
                {%- set start = (keys[index - 2], temp_map[keys[index - 2]]) -%}
                {%- set stop = (keys[index - 1], temp_map[keys[index - 1]]) -%}
                {{ interpolate(temp, start, stop) }}
              {%- endif -%}
        }
  - type: state-badge
    entity: sensor.utility_room_temperature_temperature
    style:
      top: 55%
      left: 20%
    card_mod:
      style: |
        :host {
          color: transparent;
          --label-badge-text-color:
              {%- macro interpolate(temp, start, stop) -%}
                {%- set (start_temp, start_color) = start -%}
                {%- set (stop_temp, stop_color) = stop -%}
                {%- set (start_r, start_g, start_b) = (int(start_color[0:2], base=16), int(start_color[2:4], base=16), int(start_color[4:6], base=16)) -%}
                {%- set (stop_r, stop_g, stop_b) = (int(stop_color[0:2], base=16), int(stop_color[2:4], base=16), int(stop_color[4:6], base=16)) -%}
                {%- set s = ((temp - start_temp)/(stop_temp - start_temp)) -%}
                {# some channels might be negative; most browsers are probably tolerant, but in case not #}
                {%- set r = max(int(start_r + s*(stop_r - start_r)), 0) -%}
                {%- set g = max(int(start_g + s*(stop_g - start_g)), 0) -%}
                {%- set b = max(int(start_b + s*(stop_b - start_b)), 0) -%}
                rgb({{ r }}, {{ g }}, {{ b }});
              {%- endmacro -%}
              {%- set temp = states(config.entity) | float(0) -%}
              {%- set temp_map = {
                                   5: "3498db",
                                   16: "70a03c",
                                   19: "ff9800",
                                   24: "e74c3c"
                                 }  -%}
              {%- set keys = temp_map | sort -%}
              {%- set index = keys | select("lt", temp) | list | length -%}
              {%- if index == 0 -%}
                #{{ temp_map[keys | first] }}
              {%- elif index == keys | length -%}
                #{{ temp_map[keys | last] }}
              {%- else -%}
                {%- set start = (keys[index - 2], temp_map[keys[index - 2]]) -%}
                {%- set stop = (keys[index - 1], temp_map[keys[index - 1]]) -%}
                {{ interpolate(temp, start, stop) }}
              {%- endif -%}
        }
  - type: state-badge
    entity: sensor.hallway_current_temperature
    style:
      top: 70%
      left: 9%
    card_mod:
      style: |
        :host {
          color: transparent;
          --label-badge-text-color:
              {%- macro interpolate(temp, start, stop) -%}
                {%- set (start_temp, start_color) = start -%}
                {%- set (stop_temp, stop_color) = stop -%}
                {%- set (start_r, start_g, start_b) = (int(start_color[0:2], base=16), int(start_color[2:4], base=16), int(start_color[4:6], base=16)) -%}
                {%- set (stop_r, stop_g, stop_b) = (int(stop_color[0:2], base=16), int(stop_color[2:4], base=16), int(stop_color[4:6], base=16)) -%}
                {%- set s = ((temp - start_temp)/(stop_temp - start_temp)) -%}
                {# some channels might be negative; most browsers are probably tolerant, but in case not #}
                {%- set r = max(int(start_r + s*(stop_r - start_r)), 0) -%}
                {%- set g = max(int(start_g + s*(stop_g - start_g)), 0) -%}
                {%- set b = max(int(start_b + s*(stop_b - start_b)), 0) -%}
                rgb({{ r }}, {{ g }}, {{ b }});
              {%- endmacro -%}
              {%- set temp = states(config.entity) | float(0) -%}
              {%- set temp_map = {
                                   5: "3498db",
                                   16: "70a03c",
                                   19: "ff9800",
                                   24: "e74c3c"
                                 }  -%}
              {%- set keys = temp_map | sort -%}
              {%- set index = keys | select("lt", temp) | list | length -%}
              {%- if index == 0 -%}
                #{{ temp_map[keys | first] }}
              {%- elif index == keys | length -%}
                #{{ temp_map[keys | last] }}
              {%- else -%}
                {%- set start = (keys[index - 2], temp_map[keys[index - 2]]) -%}
                {%- set stop = (keys[index - 1], temp_map[keys[index - 1]]) -%}
                {{ interpolate(temp, start, stop) }}
              {%- endif -%}
        }
  - type: state-badge
    entity: sensor.conservatory_door_temperature
    style:
      top: 20%
      left: 20%
    card_mod:
      style: |
        :host {
          color: transparent;
          --label-badge-text-color:
              {%- macro interpolate(temp, start, stop) -%}
                {%- set (start_temp, start_color) = start -%}
                {%- set (stop_temp, stop_color) = stop -%}
                {%- set (start_r, start_g, start_b) = (int(start_color[0:2], base=16), int(start_color[2:4], base=16), int(start_color[4:6], base=16)) -%}
                {%- set (stop_r, stop_g, stop_b) = (int(stop_color[0:2], base=16), int(stop_color[2:4], base=16), int(stop_color[4:6], base=16)) -%}
                {%- set s = ((temp - start_temp)/(stop_temp - start_temp)) -%}
                {# some channels might be negative; most browsers are probably tolerant, but in case not #}
                {%- set r = max(int(start_r + s*(stop_r - start_r)), 0) -%}
                {%- set g = max(int(start_g + s*(stop_g - start_g)), 0) -%}
                {%- set b = max(int(start_b + s*(stop_b - start_b)), 0) -%}
                rgb({{ r }}, {{ g }}, {{ b }});
              {%- endmacro -%}
              {%- set temp = states(config.entity) | float(0) -%}
              {%- set temp_map = {
                                   5: "3498db",
                                   16: "70a03c",
                                   19: "ff9800",
                                   24: "e74c3c"
                                 }  -%}
              {%- set keys = temp_map | sort -%}
              {%- set index = keys | select("lt", temp) | list | length -%}
              {%- if index == 0 -%}
                #{{ temp_map[keys | first] }}
              {%- elif index == keys | length -%}
                #{{ temp_map[keys | last] }}
              {%- else -%}
                {%- set start = (keys[index - 2], temp_map[keys[index - 2]]) -%}
                {%- set stop = (keys[index - 1], temp_map[keys[index - 1]]) -%}
                {{ interpolate(temp, start, stop) }}
              {%- endif -%}
        }
  - type: state-badge
    entity: sensor.front_room_temperature
    style:
      top: 70%
      left: 20%
    card_mod:
      style: |
        :host {
          color: transparent;
          --label-badge-text-color:
              {%- macro interpolate(temp, start, stop) -%}
                {%- set (start_temp, start_color) = start -%}
                {%- set (stop_temp, stop_color) = stop -%}
                {%- set (start_r, start_g, start_b) = (int(start_color[0:2], base=16), int(start_color[2:4], base=16), int(start_color[4:6], base=16)) -%}
                {%- set (stop_r, stop_g, stop_b) = (int(stop_color[0:2], base=16), int(stop_color[2:4], base=16), int(stop_color[4:6], base=16)) -%}
                {%- set s = ((temp - start_temp)/(stop_temp - start_temp)) -%}
                {# some channels might be negative; most browsers are probably tolerant, but in case not #}
                {%- set r = max(int(start_r + s*(stop_r - start_r)), 0) -%}
                {%- set g = max(int(start_g + s*(stop_g - start_g)), 0) -%}
                {%- set b = max(int(start_b + s*(stop_b - start_b)), 0) -%}
                rgb({{ r }}, {{ g }}, {{ b }});
              {%- endmacro -%}
              {%- set temp = states(config.entity) | float(0) -%}
              {%- set temp_map = {
                                   5: "3498db",
                                   16: "70a03c",
                                   19: "ff9800",
                                   24: "e74c3c"
                                 }  -%}
              {%- set keys = temp_map | sort -%}
              {%- set index = keys | select("lt", temp) | list | length -%}
              {%- if index == 0 -%}
                #{{ temp_map[keys | first] }}
              {%- elif index == keys | length -%}
                #{{ temp_map[keys | last] }}
              {%- else -%}
                {%- set start = (keys[index - 2], temp_map[keys[index - 2]]) -%}
                {%- set stop = (keys[index - 1], temp_map[keys[index - 1]]) -%}
                {{ interpolate(temp, start, stop) }}
              {%- endif -%}
        }
  - type: state-badge
    entity: sensor.ellie_bedroom_temperature_temperature
    style:
      top: 20%
      left: 70%
    card_mod:
      style: |
        :host {
          color: transparent;
          --label-badge-text-color:
              {%- macro interpolate(temp, start, stop) -%}
                {%- set (start_temp, start_color) = start -%}
                {%- set (stop_temp, stop_color) = stop -%}
                {%- set (start_r, start_g, start_b) = (int(start_color[0:2], base=16), int(start_color[2:4], base=16), int(start_color[4:6], base=16)) -%}
                {%- set (stop_r, stop_g, stop_b) = (int(stop_color[0:2], base=16), int(stop_color[2:4], base=16), int(stop_color[4:6], base=16)) -%}
                {%- set s = ((temp - start_temp)/(stop_temp - start_temp)) -%}
                {# some channels might be negative; most browsers are probably tolerant, but in case not #}
                {%- set r = max(int(start_r + s*(stop_r - start_r)), 0) -%}
                {%- set g = max(int(start_g + s*(stop_g - start_g)), 0) -%}
                {%- set b = max(int(start_b + s*(stop_b - start_b)), 0) -%}
                rgb({{ r }}, {{ g }}, {{ b }});
              {%- endmacro -%}
              {%- set temp = states(config.entity) | float(0) -%}
              {%- set temp_map = {
                                   5: "3498db",
                                   16: "70a03c",
                                   19: "ff9800",
                                   24: "e74c3c"
                                 }  -%}
              {%- set keys = temp_map | sort -%}
              {%- set index = keys | select("lt", temp) | list | length -%}
              {%- if index == 0 -%}
                #{{ temp_map[keys | first] }}
              {%- elif index == keys | length -%}
                #{{ temp_map[keys | last] }}
              {%- else -%}
                {%- set start = (keys[index - 2], temp_map[keys[index - 2]]) -%}
                {%- set stop = (keys[index - 1], temp_map[keys[index - 1]]) -%}
                {{ interpolate(temp, start, stop) }}
              {%- endif -%}
        }
  - type: state-badge
    entity: sensor.office_radiator_temperature
    style:
      top: 21%
      left: 58%
    card_mod:
      style: |
        :host {
          color: transparent;
          --label-badge-text-color:
              {%- macro interpolate(temp, start, stop) -%}
                {%- set (start_temp, start_color) = start -%}
                {%- set (stop_temp, stop_color) = stop -%}
                {%- set (start_r, start_g, start_b) = (int(start_color[0:2], base=16), int(start_color[2:4], base=16), int(start_color[4:6], base=16)) -%}
                {%- set (stop_r, stop_g, stop_b) = (int(stop_color[0:2], base=16), int(stop_color[2:4], base=16), int(stop_color[4:6], base=16)) -%}
                {%- set s = ((temp - start_temp)/(stop_temp - start_temp)) -%}
                {# some channels might be negative; most browsers are probably tolerant, but in case not #}
                {%- set r = max(int(start_r + s*(stop_r - start_r)), 0) -%}
                {%- set g = max(int(start_g + s*(stop_g - start_g)), 0) -%}
                {%- set b = max(int(start_b + s*(stop_b - start_b)), 0) -%}
                rgb({{ r }}, {{ g }}, {{ b }});
              {%- endmacro -%}
              {%- set temp = states(config.entity) | float(0) -%}
              {%- set temp_map = {
                                   5: "3498db",
                                   16: "70a03c",
                                   19: "ff9800",
                                   24: "e74c3c"
                                 }  -%}
              {%- set keys = temp_map | sort -%}
              {%- set index = keys | select("lt", temp) | list | length -%}
              {%- if index == 0 -%}
                #{{ temp_map[keys | first] }}
              {%- elif index == keys | length -%}
                #{{ temp_map[keys | last] }}
              {%- else -%}
                {%- set start = (keys[index - 2], temp_map[keys[index - 2]]) -%}
                {%- set stop = (keys[index - 1], temp_map[keys[index - 1]]) -%}
                {{ interpolate(temp, start, stop) }}
              {%- endif -%}
        }
  - type: state-badge
    entity: sensor.isobel_bedroom_temperature_temperature
    style:
      top: 60%
      left: 67%
    card_mod:
      style: |
        :host {
          color: transparent;
          --label-badge-text-color:
              {%- macro interpolate(temp, start, stop) -%}
                {%- set (start_temp, start_color) = start -%}
                {%- set (stop_temp, stop_color) = stop -%}
                {%- set (start_r, start_g, start_b) = (int(start_color[0:2], base=16), int(start_color[2:4], base=16), int(start_color[4:6], base=16)) -%}
                {%- set (stop_r, stop_g, stop_b) = (int(stop_color[0:2], base=16), int(stop_color[2:4], base=16), int(stop_color[4:6], base=16)) -%}
                {%- set s = ((temp - start_temp)/(stop_temp - start_temp)) -%}
                {# some channels might be negative; most browsers are probably tolerant, but in case not #}
                {%- set r = max(int(start_r + s*(stop_r - start_r)), 0) -%}
                {%- set g = max(int(start_g + s*(stop_g - start_g)), 0) -%}
                {%- set b = max(int(start_b + s*(stop_b - start_b)), 0) -%}
                rgb({{ r }}, {{ g }}, {{ b }});
              {%- endmacro -%}
              {%- set temp = states(config.entity) | float(0) -%}
              {%- set temp_map = {
                                   5: "3498db",
                                   16: "70a03c",
                                   19: "ff9800",
                                   24: "e74c3c"
                                 }  -%}
              {%- set keys = temp_map | sort -%}
              {%- set index = keys | select("lt", temp) | list | length -%}
              {%- if index == 0 -%}
                #{{ temp_map[keys | first] }}
              {%- elif index == keys | length -%}
                #{{ temp_map[keys | last] }}
              {%- else -%}
                {%- set start = (keys[index - 2], temp_map[keys[index - 2]]) -%}
                {%- set stop = (keys[index - 1], temp_map[keys[index - 1]]) -%}
                {{ interpolate(temp, start, stop) }}
              {%- endif -%}
        }
  - type: state-badge
    entity: sensor.bedroom_motion_temperature
    style:
      top: 25%
      left: 88%
    card_mod:
      style: |
        :host {
          color: transparent;
          --label-badge-text-color:
              {%- macro interpolate(temp, start, stop) -%}
                {%- set (start_temp, start_color) = start -%}
                {%- set (stop_temp, stop_color) = stop -%}
                {%- set (start_r, start_g, start_b) = (int(start_color[0:2], base=16), int(start_color[2:4], base=16), int(start_color[4:6], base=16)) -%}
                {%- set (stop_r, stop_g, stop_b) = (int(stop_color[0:2], base=16), int(stop_color[2:4], base=16), int(stop_color[4:6], base=16)) -%}
                {%- set s = ((temp - start_temp)/(stop_temp - start_temp)) -%}
                {# some channels might be negative; most browsers are probably tolerant, but in case not #}
                {%- set r = max(int(start_r + s*(stop_r - start_r)), 0) -%}
                {%- set g = max(int(start_g + s*(stop_g - start_g)), 0) -%}
                {%- set b = max(int(start_b + s*(stop_b - start_b)), 0) -%}
                rgb({{ r }}, {{ g }}, {{ b }});
              {%- endmacro -%}
              {%- set temp = states(config.entity) | float(0) -%}
              {%- set temp_map = {
                                   5: "3498db",
                                   16: "70a03c",
                                   19: "ff9800",
                                   24: "e74c3c"
                                 }  -%}
              {%- set keys = temp_map | sort -%}
              {%- set index = keys | select("lt", temp) | list | length -%}
              {%- if index == 0 -%}
                #{{ temp_map[keys | first] }}
              {%- elif index == keys | length -%}
                #{{ temp_map[keys | last] }}
              {%- else -%}
                {%- set start = (keys[index - 2], temp_map[keys[index - 2]]) -%}
                {%- set stop = (keys[index - 1], temp_map[keys[index - 1]]) -%}
                {{ interpolate(temp, start, stop) }}
              {%- endif -%}
        }
  - type: state-badge
    entity: sensor.ensuite_temperature_temperature
    style:
      top: 40%
      left: 85%
    card_mod:
      style: |
        :host {
          color: transparent;
          --label-badge-text-color:
              {%- macro interpolate(temp, start, stop) -%}
                {%- set (start_temp, start_color) = start -%}
                {%- set (stop_temp, stop_color) = stop -%}
                {%- set (start_r, start_g, start_b) = (int(start_color[0:2], base=16), int(start_color[2:4], base=16), int(start_color[4:6], base=16)) -%}
                {%- set (stop_r, stop_g, stop_b) = (int(stop_color[0:2], base=16), int(stop_color[2:4], base=16), int(stop_color[4:6], base=16)) -%}
                {%- set s = ((temp - start_temp)/(stop_temp - start_temp)) -%}
                {# some channels might be negative; most browsers are probably tolerant, but in case not #}
                {%- set r = max(int(start_r + s*(stop_r - start_r)), 0) -%}
                {%- set g = max(int(start_g + s*(stop_g - start_g)), 0) -%}
                {%- set b = max(int(start_b + s*(stop_b - start_b)), 0) -%}
                rgb({{ r }}, {{ g }}, {{ b }});
              {%- endmacro -%}
              {%- set temp = states(config.entity) | float(0) -%}
              {%- set temp_map = {
                                   5: "3498db",
                                   16: "70a03c",
                                   19: "ff9800",
                                   24: "e74c3c"
                                 }  -%}
              {%- set keys = temp_map | sort -%}
              {%- set index = keys | select("lt", temp) | list | length -%}
              {%- if index == 0 -%}
                #{{ temp_map[keys | first] }}
              {%- elif index == keys | length -%}
                #{{ temp_map[keys | last] }}
              {%- else -%}
                {%- set start = (keys[index - 2], temp_map[keys[index - 2]]) -%}
                {%- set stop = (keys[index - 1], temp_map[keys[index - 1]]) -%}
                {{ interpolate(temp, start, stop) }}
              {%- endif -%}
        }
  - type: state-badge
    entity: sensor.lounge_motion_temperature
    style:
      top: 47%
      left: 36%
    card_mod:
      style: |
        :host {
          color: transparent;
          --label-badge-text-color:
              {%- macro interpolate(temp, start, stop) -%}
                {%- set (start_temp, start_color) = start -%}
                {%- set (stop_temp, stop_color) = stop -%}
                {%- set (start_r, start_g, start_b) = (int(start_color[0:2], base=16), int(start_color[2:4], base=16), int(start_color[4:6], base=16)) -%}
                {%- set (stop_r, stop_g, stop_b) = (int(stop_color[0:2], base=16), int(stop_color[2:4], base=16), int(stop_color[4:6], base=16)) -%}
                {%- set s = ((temp - start_temp)/(stop_temp - start_temp)) -%}
                {# some channels might be negative; most browsers are probably tolerant, but in case not #}
                {%- set r = max(int(start_r + s*(stop_r - start_r)), 0) -%}
                {%- set g = max(int(start_g + s*(stop_g - start_g)), 0) -%}
                {%- set b = max(int(start_b + s*(stop_b - start_b)), 0) -%}
                rgb({{ r }}, {{ g }}, {{ b }});
              {%- endmacro -%}
              {%- set temp = states(config.entity) | float(0) -%}
              {%- set temp_map = {
                                   5: "3498db",
                                   16: "70a03c",
                                   19: "ff9800",
                                   24: "e74c3c"
                                 }  -%}
              {%- set keys = temp_map | sort -%}
              {%- set index = keys | select("lt", temp) | list | length -%}
              {%- if index == 0 -%}
                #{{ temp_map[keys | first] }}
              {%- elif index == keys | length -%}
                #{{ temp_map[keys | last] }}
              {%- else -%}
                {%- set start = (keys[index - 2], temp_map[keys[index - 2]]) -%}
                {%- set stop = (keys[index - 1], temp_map[keys[index - 1]]) -%}
                {{ interpolate(temp, start, stop) }}
              {%- endif -%}
        }
image: /local/floorplan.png
1 Like

I meant, just try a basic version first, e.g.:

type: entities
entities:
  - entity: sensor.fgsd002_smoke_sensor_air_temperature_2
    card_mod:
      style:
        hui-generic-entity-row:
          $:
            .: |
              .info {
                color: red;
              }

If that works, then replace red with the template code. Take small steps. There are many examples doing these basic things on the card-mod thread (I mean, there will be something for an entities card to change a name’s colour, and another to colour a state, or a button, etc.). Identify exactly what you want to change, and change it in a basic way, then add the advanced changes.

My snippet here works for me, but there could be shorter and more compact ways of doing things. It (the UI) often changes and unless one has done it recently, it’s hard to know the answer without going and coding it up yourself.

Brewston posted their picture elements code. It should work for you.

I am not sure what I am doing wrong then…