Led gradient over four colors by CO2 sensor

How do you came for -0.02 constant please?

I used:

hs_color: ['{{(states("sensor.co2") | float - 400) * 0.15 }}','100']

and it works. There are problem with the return of more than one values.

I generated a linear equation (y = mx + b ) to convert 12000-0 to 236-0.

-0.02 is the slope of the line not the constant.

https://www.mathplanet.com/education/algebra-1/formulating-linear-equations/writing-linear-equations-using-the-slope-intercept-form

A template can only return a string, not a YAML array. (I wonder how many times I’ve written that in replies in this forum… :thinking:) So you have to make sure you’re not trying to render both hs_color values in a single template. If you change the hs_color part to the following it should work. (BTW, no comment on what the equation should be. You and @tom_l have that covered.)

      hs_color:
      - >
        {% set co2 = states('sensor.co2') %}
        {% if co2 == 'unavailable' %}
          360
        {% elif co2 | float < 2000 %}
          {{ ((co2 | float - 400) * 0.15) | round(0) | int }}
        {% else %}
          1
        {% endif %}
      - 100

Thanks! I found that a couple minutes ago. Will try.

Is there anyone with a ESPhome solution?
I like to make my ESPhome nodes as much independant as possible…
I want to indicate CO2 values of a sensor (PPM) as a gradient from green to red with one RGB led.

1 Like

Solved this by defining a custom c++ function in a .h file (e.g. gradient.h):

#include "esphome.h"

Color Gradient(Color from, Color to, float f) {
   Color result;

   result.r = from.r*(1-f) + to.r*(f);
   result.g = from.g*(1-f) + to.g*(f);
   result.b = from.b*(1-f) + to.b*(f);

   return result;
}

and then include the .h file:

esphome:
  name: s3test
  friendly_name: ESP32-S3 T-Display
  platformio_options:
    build_unflags: -Werror=all
    board_build.flash_mode: dio
  includes:
    - gradient.h

and then in the lambda:

        if ((id(electricity_price).state >= 0.15) && (id(electricity_price).state < 0.30)) {
          it.printf(268, 100, id(font1), Gradient(id(my_green), id(my_red), (id(electricity_price).state - 0.15) / (0.3 - 0.15) ), TextAlign::CENTER, "%.5f", id(electricity_price).state);
        }

It works like a charm!