Aircoookie / WLED

Control WS2812B and many more types of digital RGB LEDs with an ESP8266 or ESP32 over WiFi!
https://kno.wled.ge
MIT License
14.2k stars 3.03k forks source link

add param for read current color temperature (Kelvin) JSON API / WebSocket #4008

Open VolchkovVlad opened 1 month ago

VolchkovVlad commented 1 month ago

Is your request to add a new feature related to any problem? Please describe her.

The MAD 0.15.0b 2 update has become possible in state.seg{col:[]} to record the color temperature in kelvins. Which made life much easier. But to find out the current color temperature, you need to read state.seg{col[]} and convert from RGB to Kelvins, which is not convenient.

Describe the solution you would like to receive.

I would like a new parameter, for example "colKel", to display the current color temperature in kelvin

Describe alternatives you've considered

A JavaScript function that converts RGB to temperature in kelvins. The function is based on the work https://tannerhelland.com/2012/09/18/convert-temperature-rgb-algorithm-code .html Due to the fact that this function is used in your firmware

function RGB_IN_CCT(rgb){
    const minTemp = 2000
    const maxTemp = 10000
    let r = rgb[0]
    let g = rgb[1]
    let b = rgb[2]

    if(r == 255){
      if(b == 0){
        temp = minTemp/100;
      }
      else{
        temp = (Math.exp(((b + 305.0447927307)/138.5177312231))) + 10
      }
    }else{
      temp = Math.pow((r/329.698727446), (1 / -0.1332047592)) + 60
    }
    let kelvinTemp = Math.round(temp * 100)
    if(kelvinTemp > maxTemp){kelvinTemp = maxTemp}
    if(kelvinTemp < minTemp){kelvinTemp = minTemp}
    return Math.round(kelvinTemp/100)
  }

Additional context

At first I planned to use the function described by you from line 308

https://github.com/Aircoookie/WLED/blob/2f6f0d2f3e3ca7c016d7f507a9a5433564484de0/wled00/colors.cpp#L308

But it returned incorrect data.

I recorded the color temperature of 2000k In response, I received an array: [255, 137, 14] And the function described on line 308 returned the color temperature of 1938K

softhack007 commented 4 weeks ago

A few technical thoughts

So getting the value right seems not simple; it will only be meaningful for a single effect; we would calculate it each time that json/si or json/info is sent out. I'd say lets not not implement this feature request. Unless the color temperature is available any way, and we could directly add an existing internal attribute to the API.

blazoncek commented 4 weeks ago

Adding to @softhack007 comment: WLED does not use K internally though it can convert color specified in K into RGB counterpart. As such converting RGB into K is not really straightforward in every situation (i.e. RGB == FF0000, etc).

VolchkovVlad commented 4 weeks ago
  • .seg{col:[0]} is the main segment color; its color temperature would only be meaningful for single-color effects. So for any effect except "Solid" the information has little meaning

I don't really understand what the problem is? .seg{col:[0]} is also relevant only for Solid. But you have it calculated, right

  • the formula you suggest involves some "expensive" math operations, ie pow() and exp()

That is, to convert from kelvins to RGB, is this normal, but from RGB to kelvins, is this a complex function? https://github.com/Aircoookie/WLED/blob/2f6f0d2f3e3ca7c016d7f507a9a5433564484de0/wled00/colors.cpp#L117C2-L117C45

  • we'd need to calculate the value in each run of `serializeState(), which is quite often

I can't comment in any way.

VolchkovVlad commented 4 weeks ago

If you are worried about performance. You can do this with a switchable parameter

blazoncek commented 4 weeks ago

WLED is an OSS. You can contribute if you wish.