Interpolating Colors + Whites

Is there any documentation or reading available regarding how the system interpolates between whites and colors?

I’m trying to build a persistent controller using the HTTP API to cycle through a lookup table continuously but I want to be able to ‘jump in’ at any point (after an interrupt like a manual override).

That means I can’t just rely on calling long-duration state change events — I have to be able to interpolate between the (arbitrary) whites and colors in the lookup in order to create a new transition event at an arbitrary point in between.

What would really help me out is something that describes how the system handles those color transitions so I can replicate it on my end.


1 Like

I believe this is linear interpolation in HSL space.

Thanks for your reply, Cake — if this is linear HSL interpretation then how are whites represented in HSL?

Specifically, what I’m wondering is how to go from, say, 5000K at 100% brightness to, say, H: 30 S: 40% B: 50%, or, more generally, from a white to a color or vice versa.

Any help would be appreciated.

1 Like

Its a linear interpolation across the Hue, Saturation, Brightness and Kelvin values.

The Saturation, Brightness and Kelvin values will move linearly to the new value.
The Hue will take into account the wrapping from 360 -> 0 to ensure that the shortest path is taken to any particular hue.

Thanks for your reply @daniel_hall, but I’m still not clear on this so please bear with me …

How do Kelvin values affect the interpretation of the HSL color space? Is this documented somewhere?

Do Kelvin values override HS settings?

I just ran a test — putting a state with a color of:
hue: 0
sat: 1.0
bright: 0.67
kelvin: 9000
… gets you a very cold white, which, after applying and polling the lights, looks like it was interpreted to have a 0 saturation.

Putting a state with a color of:
sat: 1.0
bright: 0.67
… without specifying a Kelvin value … gets you pure red, with the lights reporting the specified 1.0 saturation, as well as the residual 9000 Kelvin value from the previous setting.

So if I’m understanding this correctly, setting a Kelvin value overrides any saturation setting in that color and sets it to 0.

Is that right?

If that is the case, Kelvin->Kelvin interpolations are, as you say, linear interpolations between Brightness and Kelvin values.

HS->HS interpolations, similarly, can be handled by putting states with only HSL components and doing linear interpolation. All fine so far.

But what about HS->Kelvin interpolations? I would think that in order to go from HSB(1) to KB(2), you’d just linearly interpolate B(1)->B(2) while ramping the saturation from S to 0, but in order for that ramp to approach the correct white point, you’ll need to set the Kelvin ‘target’ before you begin the interpolation, and, in so doing, if even for a moment, you’ll get a flash of that Kelvin color because assigning Kelvin colors overrides the Sat to 0. Would you then try to set the Kelvin target and then ‘instantly’ reset the initial color to the previous HS? This produces said (not very short, undesirable) flash of the target Kelvin setting.

I tested setting a state with a 10s transition duration, from a starting color with 1.0 saturation to an ending Kelvin value, and saw the Kelvin values interpolating as the transition played out, which meant that the transition was headed towards a (spurious, residual) initial Kelvin value that moved towards the target setting as the transition played out. This should, in my opinion, not be the expected behavior.

Is there any way to ‘silently’ set the target Kelvin value without putting it live to the lights?



1 Like

Kelvin is always applied. The implementation will tint a color the same way it will tint pure white light, though it is much less noticeable. So the HSBK values are always used to generate a color.

There is not currently any documented way to change only the Kelvin values.

OK - that’s an interesting detail…

Regardless, the system still appears to strangely implemented. If Kelvin values affect the white point for all colors, why is it that if there is a Kelvin value at all in a Color assignment, that overrides the saturation to 0?

That seems broken to me. Why can’t I set the Kelvin point as part of a color assignment without the light first jumping to the 0-saturation equivalent of that Kelvin color?

I’m going to type it out one more time in the hope that you’ll address the real root of my question —

How can I go from a fully saturated color HSBK(1) to a 0-saturation white with a different Kelvin setting H0BK(2), without:
1) having the Kelvin values interpolate across the duration of the transition
2) having to first set the Kelvin endpoint, resulting in a flash of white at the start of the transition from a fully-saturated color?


1 Like

We went with kelvin also setting saturation to 0 as we felt it covers the most common use case where people would want the light to be set to white when they set kelvin.

The color field is evaluated left to right, so you can work around this issue by putting kelvin:XXXX at the start, and any saturation after that will be applied correctly. If you’re not happy with this, we can add a kelvin_only option that only applies kelvin.

What’s the reason behind needing to build a persistent controller? The lights are able to interpolate from their current state when you request another state transition during a transition.

Thank you Chendo!! This is exactly what I needed. I don’t really need a kelvin_only option given that this behavior, while strangely implemented and undocumented, does exactly what I need.

I’m building a persistent controller to accept toggle power commands only and then translate those to continuously-transitioning circadian-synced states from a LUT. I wrote a little about it here.

I’ll be posting my code when it’s ready and I hope it’s useful to others. I’m designing it to run in the background on a network-attached system and to host a simple toggle controller over HTTP, but anybody could use it as an API to your API with a few mods.

As I mentioned in the linked post, I think this is the real use case for the high-quality color reproduction and white capabilities of lights like LIFX. Alert behaviors, IFTTT tie-ins, psychedelic colors, etc., are all pretty niche and uninteresting applications as far as I’m concerned, but reinforcing good circadian scheduling through the use of controlled light, and doing so invisibly - THAT is a big deal.

I’m not alone in thinking this, either - LDs, architects, integrators - everyone I talk to agrees that this application is compelling and they’d love to design around a system with this kind of capability.

Is there any particular reason why you need to have continuously synced circadian states? Is it due to the transitions not being able to be modelled using our existing transitions, or more that you want have it work through on and off? Color transitions are unaffected by soft power changes, so a device will continue to transition even if the power state was changed via the SetPower message.

I’ve got sunrise-sunset schedules that change the kelvin values of all the lights in my house which work well enough for my purposes without extra infrastructure. My personal goal is to have my lights do everything I want them to do without needing to run anything special on my home network.

I went to verify that this is the case and I discovered a bug in the PUT /state API that would interrupt the transition even if you only set power. This has now been fixed and is in production.

That certainly helps! I didn’t realize that was a bug - I thought it was intended behavior…

I’m gonna test that in a bit but in the meantime — how are you doing your scheduling? IFTTT?

I’m not sure what you mean by existing transitions, but so far nothing I’ve seen has the granularity / customizability of writing a localized LUT.

I’m totally with you about not wanting extra hardware / code around but I want to have real control over the ramp, across seasons, with some override capability, etc…

It was affecting my motion-activated Hallway lights as motion would trigger on/off and it would interrupt my long warm white (an hour before sunset over an hour) and low brightness (10% brightness over an hour at 10pm) but I thought there was a bug elsewhere heh.

Scheduling is done using our built-in scheduling functionality. You’ll need 3.1.0 or later to have the ability to do sunrise/sunset scheduling though.

Using the effects API, you can specify the location of the peak in our breathe effect, which is effectively a sine wave. By setting persist to true and modifying the period and cycle (which can be fractional!) parameters, you can do fairly complicated transitions with that.

How do you want the override capability to work? It’s something I’ve considered personally as well.

Hey Chendo -

I’m running 3.1.0 on iOS — am I missing a piece of the interface? I don’t see scheduling anywhere. I have no ‘smarts’ tab on my interface.

As for the breathe effect - that’s a good tip … I’m going to look into that for non-linear transitions, maybe an ease-in-ease-out.

As for the override - I’m not sure how it would work from an API perspective — from an end-user (DX) side, what I’d like is for my LUT behavior to be persistent and to have an toggle in my interface to bypass that and enable normal use. At any point I could then disable the bypass to re-engage the LUT behavior.

Is there an API interface for scheduling?

It’s on the main dashboard, second section from the bottom under “Schedules”. We’re still in the process of updating our support documentation. Then, to create a sunrise/sunset schedule, tap “New Schedule”, then tap “Start Time”, then pick “With the Sun” at the top.

I see, that’s similar to how I was thinking about doing it if we ever implemented that feature.

There isn’t a public API interface for scheduling but we are considering opening this up in the future.

I figured out why scheduling wasn’t showing up … apparently I have two LIFX logins and the bulbs were claimed on a different login.

In the ‘wrong’ login, there’s no indication on the interface that you’re controlling the bulbs locally but that cloud features (like scenes and schedules) are inaccessible to you. Those features are just not presented on the interface, nor is any way to attempt to claim the bulbs for that login. I actually didn’t know those categories existed in this version of the app.

OK so based on what I’m seeing here, the functionality I’d like, that’s missing from scheduling, is the ability to schedule a transition-only scene, one without a power on/off command associated with it. I want on/off to be manual but to have the color lookup automated and persistent. Make sense? Anytime I switch on the lights they’re at the appropriate color temp and continue to transition throughout the day.

We’re working on improving communicating that in the app as it’s a known issue.

Scheduling transition-only scenes are coming to the apps soon :slight_smile: I’ve been using transition-only scenes at home for a while now but the apps currently don’t have the ability to create those, but it’s coming.

Great! It would also be nice to be able to schedule power on/off -only scenes as well (ones that don’t override the current color transition in progress…)

Thanks for your help so far.