Skip to content

Brightness changes push a stale saturated colour, overriding colour temperature #51

Description

@nashw83

Describe The Bug:

With Adaptive Lighting active, changing brightness pushes a stale saturated colour to the bulb, which overrides the colour temperature.

setKelvin() stores a colour approximation of the temperature into the internal state:

this.States.color.hue = color.h;
this.States.color.saturation = color.s;

...but sends white to the bulb via updateKelvin(): light.color(0, 0, brightness, kelvin).

setBrightness() then calls update(), which sends the stored values:

this.light.color(state.color.hue, state.color.saturation, state.color.brightness, state.color.kelvin, duration);

Because the stored saturation is non-zero, the bulb blends toward the hue and the kelvin value is effectively ignored — so a brightness change silently switches the bulb from white into a saturated colour.

The stored values, computed from convertHomeKitColorTemperatureToHomeKitColor:

6500K -> hue 308, saturation 2
4000K -> hue  29, saturation 36
3500K -> hue  29, saturation 46
2700K -> hue  30, saturation 66
2200K -> hue  30, saturation 83

At typical evening temperatures the saturation is high enough to be plainly visible as orange.

It is also self-reinforcing: once the bulb is genuinely in a colour state, the next status poll reads that hue/saturation back into States, so the following brightness change sends it again. Only a fresh setKelvin (which sends saturation 0) breaks the cycle.

Adaptive Lighting makes this frequent, since HAP recomputes and writes ColorTemperature whenever brightness changes — so a brightness drag produces Brightness and ColorTemperature writes in rapid succession, continuously.

This may share a root cause with #16 (bulbs randomly dimming to 0%), which would also be explained by update() sending stale state.

To Reproduce:

  1. Enable Adaptive Lighting on a colour bulb.
  2. Drag the brightness slider in the Home app, particularly at low brightness.
  3. A brief strongly-orange flash appears.
  4. Keep dragging — the bulb can end up sitting in a very warm saturated state that does not correct itself.

Setting a specific colour manually behaves correctly, and the problem does not occur when Adaptive Lighting has not recently written a colour temperature.

Expected behavior:

A brightness change should change only brightness, leaving the bulb in white/temperature mode at its current colour temperature.

Logs:

The plugin does not log the arguments passed to light.color(), so the behaviour above is
inferred from src/bulb.ts rather than captured in a log. Happy to run a build with the
outgoing values logged if that would help confirm it.

Plugin Config:

{
  "platform": "LifxPlugin",
  "autoDiscover": false,
  "colorDuration": 300,
  "brightnessDuration": 300
}

Screenshots:

N/A — the flash is too brief to capture reliably.

Environment:

  • Plugin Version: 0.3.7
  • Homebridge Version: 1.11.4
  • Node.js Version: v22.20.0
  • NPM Version: 10.9.3
  • Operating System: Raspbian (hb-service)

@ghoelscher-git — your fork's write-coalescing branch tracks a colour/temperature mode and comments that "Saturation must be 0 or the bulb blends toward the hue and ignores kelvin", which sounds like it's the behaviour here. Your commit message describes the problem as scenes setting multiple characteristics in rapid succession; this is the same pattern but triggered by the brightness slider, since Adaptive Lighting writes ColorTemperature on every brightness change. Is that path already in scope for your branch, or is it focused on the scene case?

I'm happy to test your branch — I have 13 devices on it and can reproduce reliably. If it's out of scope I can look at a narrower fix and raise a PR, but I'd rather not duplicate your work, so I'll hold off until you've had a chance to say.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions