FastLED - addressable_set - trouble setting colour with a lambda statement

I have created this service definition in ESPHOME. The lambda statements that set the ranges work perfectly but not having any success from the colour settings. I am trying to setup a visual temperature scale where the colour attempts to represent the temperature, so blue being cooler and red being hotter.

When I set the temperature to 40 I would expect the lambda statement to return a value of 1 for the red colour. But nothing turns on. When I get rid of the lambda statement and hardcode the value 1, it works.

Any ideas?

    - service: disp_temperature
      variables:
        temperature: int
      then:
        - light.addressable_set:
            id: fastled_clockless_led
            range_from: 0 
            range_to: 90 
            red: 0%
            green: 0%
            blue: 0%
        - light.addressable_set:
            id: fastled_clockless_led
            range_from: !lambda 'if (temperature >= 0) {return (40 - temperature);} else {return (40);}'
            range_to: !lambda 'if (temperature >= 0) {return (40);} else {return (40 + (temperature * -1));}'   
            red: !lambda 'if (temperature >= 0) {return (temperature / 40);} else {return (0);}'
            green: !lambda 'if (temperature >= 0) {return (0);} else {return ((50 * (temperature * -1 / 30))/100);}'
            blue: !lambda 'if (temperature >= 0) {return (1 - (temperature / 40));} else {return ((50 * (temperature * -1 / 30))/100);}'
        - light.addressable_set:
            id: fastled_clockless_led
            range_to: !lambda 'if (temperature >= 0) {return (40 - temperature);} else {return (40);}'
            range_from: !lambda 'if (temperature >= 0) {return (40);} else {return (40 + (temperature * -1));}'     
            red: 0%
            green: 0%
            blue: 0%

First of all, so we can read your code, please edit it so the if statements are on multiple lines.

Hopefully this is more clear. As I mentioned the coding for the ranges work fine it’s the colour that is not.

    - service: disp_temperature
      variables:
        temperature: float
      then:
        - light.addressable_set:
            id: fastled_clockless_led
            range_from: 0 
            range_to: 90 
            red: 0%
            green: 0%
            blue: 0%
        - light.addressable_set:
            id: fastled_clockless_led
            range_from: !lambda 
              'if (temperature >= 0) {
                 return (40 - temperature); 
               } else { 
                 return (40);
                 
               }'
            range_to: !lambda 
              'if (temperature >= 0) {
                 return (40);
               } else {
                 return (40 + (temperature * -1));
                 
               }'   
            red: !lambda 
              'if (temperature >= 0) {
                 return (temperature / 40);
                
               } else {
                 return (0);
                 
               }'
            green: !lambda 
              'if (temperature >= 0) {
                 return (0);
               } else {
                 return ((50 * (temperature * -1 / 30))/100);
                 
               }'
            blue: !lambda 
              'if (temperature >= 0) {
                 return (1 - (temperature / 40));
                
               } else {
                 return ((50 * (temperature * -1 / 30))/100);
               }'
        - light.addressable_set:
            id: fastled_clockless_led
            range_to: !lambda 
              'if (temperature >= 0) {
                 return (40 - temperature);
               } else {
                 return (40);
                 
               }'
            range_from: !lambda 
              'if (temperature >= 0) {
                 return (40);
                
               } else {
                 return (40 + (temperature * -1));
                 
               }'     
            red: 0%
            green: 0%
            blue: 0%

If you use ESP_LOGD with formatting, what shows up?

Now you exceeded my knowledge. How would you suggest I use that? I did a search and could find any good examples to provide guidance.

https://esphome.io/components/sensor/custom.html#logging-in-custom-components and https://esphome.io/components/display/index.html#display-printf should help

I added in the logging statements to see if the IF statements evaluated correctly. Here’s what I got. I am not sure how to show the result of the return statement.

    - service: disp_temperature
      variables:
        temperature: float
      then:
        - light.addressable_set:
            id: fastled_clockless_led
            range_from: 0 
            range_to: 90 
            red: 0%
            green: 0%
            blue: 0%
        - light.addressable_set:
            id: fastled_clockless_led
            range_from: !lambda 
              'if (temperature >= 0) {
                 ESP_LOGD("custom", "temperature 1 %f", temperature);
                 return (40 - temperature); 
               } else { 
                 return (40);
                 
               }'
            range_to: !lambda 
              'if (temperature >= 0) {
                 return (40);
               } else {
                 return (40 + (temperature * -1));
                 
               }'   
            red: !lambda 
              'if (temperature >= 0) {
                 ESP_LOGD("custom", "temperature 2 %f", temperature);
                 return (temperature / 40);
               } else {
                 return (0);
                 
               }'
            green: !lambda 
              'if (temperature >= 0) {
                 return (0);
               } else {
                 return ((50 * (temperature * -1 / 30))/100);
                 
               }'
            blue: !lambda 
              'if (temperature >= 0) {
                 return (1 - (temperature / 40));
                
               } else {
                 return ((50 * (temperature * -1 / 30))/100);
               }'
        - light.addressable_set:
            id: fastled_clockless_led
            range_to: !lambda 
              'if (temperature >= 0) {
                 return (40 - temperature);
               } else {
                 return (40);
                 
               }'
            range_from: !lambda 
              'if (temperature >= 0) {
                 return (40);
                
               } else {
                 return (40 + (temperature * -1));
                 
               }'     
            red: 0%
            green: 0%
            blue: 0%
[10:09:20][C][logger:185]: Logger:
[10:09:20][C][logger:186]:   Level: DEBUG
[10:09:20][C][logger:187]:   Log Baud Rate: 115200
[10:09:20][C][logger:188]:   Hardware UART: UART0
[10:09:20][C][light:178]: Light 'Front Door Light Strip'
[10:09:20][C][light:180]:   Default Transition Length: 1.0s
[10:09:20][C][light:181]:   Gamma Correct: 2.80
[10:09:20][C][captive_portal:169]: Captive Portal:
[10:09:20][C][web_server:131]: Web Server:
[10:09:20][C][web_server:132]:   Address: 192.168.1.244:80
[10:09:20][C][ota:029]: Over-The-Air Updates:
[10:09:20][C][ota:030]:   Address: 192.168.1.244:8266
[10:09:20][C][ota:032]:   Using Password.
[10:09:20][C][api:095]: API Server:
[10:09:20][C][api:096]:   Address: 192.168.1.244:6053
[10:09:22][D][api.connection:604]: Client 'Home Assistant 2020.12.0 (192.168.1.105)' connected successfully!
[10:10:14][D][custom:468]: temperature 1 10.000000
[10:10:14][D][custom:476]: temperature 2 10.000000

Looks like you passed a temperature of 10, which resulted in it setting the red to 0.25. Is that what you expected?

Yes, as I understand you can pass a percentage or a value to the colour. So .25 should be equivalent to 25% (as is my reasoning).

Got that from here.

  • red ( Optional , percentage, templatable): The red channel of the light. Must be in range 0% to 100% or 0.0 to 1.0 . Defaults to not changing red.

What happens to the light strip? Nothing?

Nothing! As I mentioned if I hardcode the value to a 1 it works.

What if you hardcode it to 0.25?

Tried a couple of things;

            red: !lambda return (1); 

No result.

            red: 1

Works correctly.

            red: !lambda return 1;

No result.

It’s like the return is not working for colours but works in the range to and from.

What about red: "1"? What about red: !lambda 1?

The ESPHOME editor says that lambda is expecting a return statement so that is not a valid syntax.

What about the first one?

That fails on a compile error.

INFO Reading configuration /config/esphome/frontdoorledstrip.yaml...
ERROR Error while reading config: Invalid YAML syntax:

while parsing a block mapping
  in "/config/esphome/frontdoorledstrip.yaml", line 75, column 13:
                id: fastled_clockless_led
                ^
expected <block end>, but found '<scalar>'
  in "/config/esphome/frontdoorledstrip.yaml", line 91, column 29:
                red: !lambda "1";

Not !lamba "1", just hardcoded "1".

Sorry. Yes that works.

What if you use !lambda return "1"?