Factoring Kelvin into HSBK to RGB conversion

I’m writing a Python application right now, and I want to display the current light color to the user. I’ve written a HSBKtoRGB function:

def HSBKtoRGB(hsvk: Tuple[int, int, int, int]) -> Tuple[int, int, int]:
    """ Converted from PHP https://gist.github.com/joshrp/5200913 """
    iH, iS, iV, iK = hsvk
    dS = (100 * iS / 65535) / 100.0  # Saturation: 0.0-1.0
    dV = (100 * iV / 65535) / 100.0  # Lightness: 0.0-1.0
    dC = dV * dS  # Chroma: 0.0-1.0
    dH = (360 * iH / 65535) / 60.0  # H-prime: 0.0-6.0
    dT = dH  # Temp variable

    while dT >= 2.0:  # php modulus does not work with float
        dT -= 2.0
    dX = dC * (1 - abs(dT - 1))

    dHf = floor(dH)
    if dHf == 0:
        dR = dC
        dG = dX
        dB = 0.0
    elif dHf == 1:
        dR = dX
        dG = dC
        dB = 0.0
    elif dHf == 2:
        dR = 0.0
        dG = dC
        dB = dX
    elif dHf == 3:
        dR = 0.0
        dG = dX
        dB = dC
    elif dHf == 4:
        dR = dX
        dG = 0.0
        dB = dC
    elif dHf == 5:
        dR = dC
        dG = 0.0
        dB = dX
    else:
        dR = 0.0
        dG = 0.0
        dB = 0.0

    dM = dV - dC
    dR += dM
    dG += dM
    dB += dM

    return int(dR * 255), int(dG * 255), int(dB * 255)

Its adapted from some PHP code, so sorry if it’s ugly. But, the code doesn’t factor in the Kelvin from the HSBK, and I was wondering how I could do that.

I can’t find any way to do it online, but obviously the light is doing it somehow. I’ve tried to mix the RGB value of the kelvin temperature. I weight the temperature inversely with the Chroma (iC).

rgb_prime = int(dR * 255), int(dG * 255), int(dB * 255)
rgb_k = KelvinToRGB(iK)
return_rgb = tuple(int(min(255, ((dC)*a)+((1-dC)*b))) for (a, b) in zip(rgb_prime, rgb_k))  # Light model
return return_rgb

The values returned are ok, but not great. It’s honestly more accurate if I just don’t mix the Kelvin value to begin with. I was wondering what the most accurate way to blend these colors.

I don’t think the kelvin value affects the color… if you set the bulb to lets say fully red (255, 0,0) and change the kelvin values via code, the emitted color of the bulb doesn’t change (as far as I can judge). The kelvin value only gets factored in when you are in the „shades of white“ mode, otherwise it gets ignored (at least in my experimenting/experience). Using Hue, saturation and brightness in combination with kelvin might only be to have a unified command and avoid code duplication in the LIFX code base, but that’s simply an assumption on my side…
If you want to present RGB to your users while the lamp is in „shades of white“ mode, you might check for the saturation value and if that is 0 (I can’t check this right now, but I’m pretty sure the saturation value of 0 is and indicator of being in the „shades of white“ mode), you simply translate the current kelvin value according to for example this resource: http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/

I hope I understood your question correctly and could shed some light (pun intended) on this.

You are correct that when perfect RGB values are sent, the Kelvin doesn’t matter at all. These perfect RGB values have a Chromaticity of 1, so the 1 - dC in my code goes to 0 and Kelvin isn’t factored in. However, try picking non-perfect RGB values, turning the saturation to 50%, and then mess with the Kevlin. It’s clear that the Kelvin is having an effect on the lightbulb. I just can’t seem to reverse engineer the equation correctly.

I see. I must have never tried that combination when messing around with the bulbs… Sorry I couldn’t help.

I got adopted formulas from roohyWoK’s link and combined it with the white mixing similar to your solution some time before. This works fine for me though.
How do you measure the color difference with lifx HSBK color model?

1 Like

The code you linked worked wonderfully. Does exactly what I want. Thanks.