Use the sleep RGB colour as the floor whenever it is configured

A switch with `sleep_rgb_or_color_temp: rgb_color` expresses its sleep colour
as RGB. `_apply_intensity` only walked RGB towards `sleep_rgb_color` on the
`adapt_until_sleep` path; everywhere else it re-derived RGB from the
interpolated colour temperature. Intensity 0 therefore produced
`color_temperature_to_rgb(sleep_color_temp)` rather than the configured
`sleep_rgb_color`, breaking the guarantee that 0 reproduces sleep mode.

The condition is now the switch's own configuration -- the sleep floor being in
force, and the sleep colour being expressed as RGB -- which subsumes the
`adapt_until_sleep` case and makes the `keep_rgb` parameter redundant.

The `minimum` floor still derives RGB from the colour temperature, because its
anchor is `min_color_temp`, a Kelvin, and the sleep colour is not the floor
there.

The existing test asserted the RGB match only when `force_rgb_color` was set,
so it stepped over this. Replaced with a test that asserts what was actually
promised, under both values of `adapt_until_sleep`, plus one pinning the
`minimum` floor's Kelvin-derived behaviour.

Reported by greptile-apps on #1593.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Ahmad Tawakol 2026-09-07 18:47:10 -03:00
commit 51e0b11860
2 changed files with 40 additions and 36 deletions

View file

@ -433,7 +433,6 @@ class SunLightSettings:
rgb_color: tuple[int, int, int],
*,
is_sleep: bool,
keep_rgb: bool,
) -> tuple[float | None, int, tuple[int, int, int]]:
"""Scale the adaptive result towards this switch's floor settings.
@ -473,12 +472,15 @@ class SunLightSettings:
)
color_temp_kelvin = 5 * round(color_temp_kelvin / 5) # round to nearest 5
if keep_rgb:
# This switch drives colour as RGB after sunset, so walk the RGB value
# towards the configured sleep colour rather than re-deriving it from
# the (unused) colour temperature. `keep_rgb` is only ever set when
# `adapt_until_sleep` is on, which forces the sleep floor, so the
# sleep colour is always the right target here.
if (
self.intensity_floor_is_sleep
and self.sleep_rgb_or_color_temp == "rgb_color"
):
# This switch expresses its sleep colour as RGB, so walk the RGB value
# towards `sleep_rgb_color` rather than re-deriving it from the
# interpolated colour temperature. Deriving it would land 0% on
# `color_temperature_to_rgb(sleep_color_temp)`, which is not the
# colour sleep mode actually uses.
rgb_color = lerp_color_hsv(self.sleep_rgb_color, rgb_color, factor)
else:
r, g, b = color_temperature_to_rgb(color_temp_kelvin)
@ -526,7 +528,6 @@ class SunLightSettings:
color_temp_kelvin,
rgb_color,
is_sleep=is_sleep,
keep_rgb=force_rgb_color,
)
# backwards compatibility for versions < 1.3.1 - see #403