Template with array/collection

I’m trying to create an automation that changes the color of a light based on the air quality index. I’m stuck on a yaml syntax issue where I can’t include an array/collection in the block scaler style.

This is probably a pretty simple thing, but I’m not getting anywhere with my searching…

If I just break it down to the simplest bit of code, what I want to do is this:

color_rgb: >
  [0, 0, 255]

I think that doesn’t work because yaml is interpreting it as a string “[0, 0, 255]” rather than a collection. So I think I’m looking for a way to indicate that it is not a string, but is a collection. But maybe this has more to do with jinja templating? Help is greatly appreciated!

Here’s the full code for context:

- id: '1598906506205'
  alias: AQIMeter
  description: ''
  trigger:
  - minutes: /5
    platform: time_pattern
  condition: []
  action:
  - data_template:
      value: '{{states("sensor.chinese_air_quality_index")|int}}'
    entity_id: input_number.aqi
    service: input_number.set_value
  - data_template:
      color_rgb: >
        {% if states('sensor.chinese_air_quality_index') | int < 50 %}
        [168, 224, 95]
        {% elif states('sensor.chinese_air_quality_index') | int < 100 %}
        [253, 215, 75]
        {% elif states('sensor.chinese_air_quality_index') | int < 150 %}
        [254, 155, 87]
        {% elif states('sensor.chinese_air_quality_index') | int < 200 %}
        [254, 106, 105]
        {% elif states('sensor.chinese_air_quality_index') | int < 300 %}
        [169, 122, 188]
        {%else %}
        [168, 115, 131]
        {% endif %}
    service: light.turn_on
    entity_id: light.officehuebulb

It can be done, but it’s a real pita. What you need to do is template each part of the array and do it like this

color_rgb:
  - >
    {{ template for red }}
  - >
    {{ template for green }}  
  - >
    {{ template for blue }} 

Much easier to use color_name instead, something like

color_name: >
  {% if states('sensor.chinese_air_quality_index') | int < 50 %} blue
  {% elif states('sensor.chinese_air_quality_index') | int < 100 %} green
  {% elif states('sensor.chinese_air_quality_index') | int < 150 %} yellow
  {% elif states('sensor.chinese_air_quality_index') | int < 200 %} orange
  {% elif states('sensor.chinese_air_quality_index') | int < 300 %} red
  {%else %} white {% endif %}
2 Likes

Thanks! That did the trick. My older Hue bulb has pretty bad colors, so I’d like to have the ability to tweak the colors and stuck with the rgb color values.

Step 1: Don’t mess up the name of the color attribute - it’s rgb_color NOT color_rgb. That definitely didn’t help with my troubleshooting…(obviously my own fault not yours)
Step 2: Templating each part of the array wasn’t too bad. Here’s the code that works:

  action:
  - data_template:
      rgb_color:
        - >
          {% if states('sensor.chinese_air_quality_index') | int < 50 %} 168
          {% elif states('sensor.chinese_air_quality_index') | int < 100 %} 253
          {% elif states('sensor.chinese_air_quality_index') | int < 150 %} 254
          {% elif states('sensor.chinese_air_quality_index') | int < 200 %} 254
          {% elif states('sensor.chinese_air_quality_index') | int < 300 %} 169
          {%else %} 168 {% endif %}
        - >
          {% if states('sensor.chinese_air_quality_index') | int < 50 %} 224
          {% elif states('sensor.chinese_air_quality_index') | int < 100 %} 215
          {% elif states('sensor.chinese_air_quality_index') | int < 150 %} 155
          {% elif states('sensor.chinese_air_quality_index') | int < 200 %} 106
          {% elif states('sensor.chinese_air_quality_index') | int < 300 %} 122
          {%else %} 115 {% endif %}
        - >
          {% if states('sensor.chinese_air_quality_index') | int < 50 %} 95
          {% elif states('sensor.chinese_air_quality_index') | int < 100 %} 75
          {% elif states('sensor.chinese_air_quality_index') | int < 150 %} 87
          {% elif states('sensor.chinese_air_quality_index') | int < 200 %} 105
          {% elif states('sensor.chinese_air_quality_index') | int < 300 %} 188
          {%else %} 131 {% endif %}        
    service: light.turn_on
    entity_id: light.officehuebulb
1 Like

If you use a variable, it can help to improve the template’s legibility.

  action:
  - data_template:
      rgb_color:
        - >
          {% set i = states('sensor.chinese_air_quality_index') | int %}
          {% if i < 50 %} 168
          {% elif i < 100 %} 253
          {% elif i < 150 %} 254
          {% elif i < 200 %} 254
          {% elif i < 300 %} 169
          {%else %} 168 {% endif %}
        - >
          {% set i = states('sensor.chinese_air_quality_index') | int %}
          {% if i < 50 %} 224
          {% elif i < 100 %} 215
          {% elif i < 150 %} 155
          {% elif i < 200 %} 106
          {% elif i < 300 %} 122
          {%else %} 115 {% endif %}
        - >
          {% set i = states('sensor.chinese_air_quality_index') | int %}
          {% if i < 50 %} 95
          {% elif i < 100 %} 75
          {% elif i < 150 %} 87
          {% elif i < 200 %} 105
          {% elif i < 300 %} 188
          {%else %} 131 {% endif %}        
    service: light.turn_on
    entity_id: light.officehuebulb

Here’s a more compact way to do it:

  action:
  - data_template:
      rgb_color:
        - >
          {% set i = (states('sensor.chinese_air_quality_index') | int) // 50 %}
          {% set r = [168, 253, 254, 254, 169, 169] %}
          {{ r[i] if i < 6 else 168 }}
        - >
          {% set i = (states('sensor.chinese_air_quality_index') | int) // 50 %}
          {% set g = [224, 215, 155, 106, 122, 122] %}
          {{ g[i] if i < 6 else 115 }}
        - >
          {% set i = (states('sensor.chinese_air_quality_index') | int) // 50 %}
          {% set b = [95, 75, 87, 105, 188, 188] %}
          {{ b[i] if i < 6 else 131 }}        
    service: light.turn_on
    entity_id: light.officehuebulb

It leverages the fact you use every additional increment of 50 (air quality index) to be represented by another color. So we use integer division to divide the air quality index by 50. The result is used to select an item from the list.