fix(ha-light): apply brightness_scale once and respect boost multipliers

`_send_entity_color` was multiplying the per-mapping `brightness_scale`
into the brightness payload twice when the effective scale was below 1,
yielding a quartered output for a configured half-scale. Conversely,
when the value-stream multiplier exceeded 1.0 with a default scale,
the entire scaling step was skipped and the boost was lost.

Compute brightness as `clamp(max(r,g,b) * bs * vs, 0, 255)` once and
ship it directly, with regression tests pinning the half-scale, boost,
and 255-clamp cases.
This commit is contained in:
2026-05-11 01:42:02 +03:00
parent cdf7d94652
commit ad84b60ae4
2 changed files with 111 additions and 6 deletions
@@ -400,17 +400,16 @@ class HALightTargetProcessor(TargetProcessor):
# Cache for WS preview (always, even if HA call is skipped)
self._latest_entity_colors[entity_id] = (r, g, b)
# Calculate brightness (0-255) from max channel
brightness = max(r, g, b)
# Brightness (0-255) is derived from the max channel and scaled once by
# the per-mapping brightness_scale × value-source multiplier. eff_scale
# may exceed 1.0 (a boosting value source), so we clamp at 255.
bs = (
mapping.brightness_scale.value
if hasattr(mapping.brightness_scale, "value")
else mapping.brightness_scale
)
eff_scale = bs * vs_multiplier
if eff_scale < 1.0:
brightness = int(brightness * eff_scale)
brightness = max(0, min(255, int(max(r, g, b) * eff_scale)))
should_be_on = (
brightness >= self._min_brightness_threshold or self._min_brightness_threshold == 0
@@ -430,7 +429,7 @@ class HALightTargetProcessor(TargetProcessor):
service_data = {
"rgb_color": [r, g, b],
"brightness": min(255, int(brightness * bs)),
"brightness": brightness,
}
transition_val = self._transition.value
if transition_val > 0: