Fix warm/cold reversal in rgbww_to_color_temperature (#65677)

pull/65713/head
J. Nick Koston 2022-02-04 13:36:30 -06:00 committed by Paulus Schoutsen
parent 35f2536d46
commit 84b2ec2244
3 changed files with 180 additions and 12 deletions

View File

@ -531,13 +531,33 @@ def color_temperature_to_rgb(
def color_temperature_to_rgbww(
temperature: int, brightness: int, min_mireds: int, max_mireds: int
) -> tuple[int, int, int, int, int]:
"""Convert color temperature to rgbcw."""
"""Convert color temperature in mireds to rgbcw."""
mired_range = max_mireds - min_mireds
warm = ((max_mireds - temperature) / mired_range) * brightness
cold = brightness - warm
cold = ((max_mireds - temperature) / mired_range) * brightness
warm = brightness - cold
return (0, 0, 0, round(cold), round(warm))
def rgbww_to_color_temperature(
rgbww: tuple[int, int, int, int, int], min_mireds: int, max_mireds: int
) -> tuple[int, int]:
"""Convert rgbcw to color temperature in mireds."""
_, _, _, cold, warm = rgbww
return while_levels_to_color_temperature(cold, warm, min_mireds, max_mireds)
def while_levels_to_color_temperature(
cold: int, warm: int, min_mireds: int, max_mireds: int
) -> tuple[int, int]:
"""Convert whites to color temperature in mireds."""
brightness = warm / 255 + cold / 255
if brightness == 0:
return (max_mireds, 0)
return round(
((cold / 255 / brightness) * (min_mireds - max_mireds)) + max_mireds
), min(255, round(brightness * 255))
def _clamp(color_component: float, minimum: float = 0, maximum: float = 255) -> float:
"""
Clamp the given color component value between the given min and max values.

View File

@ -1899,7 +1899,8 @@ async def test_light_service_call_color_temp_conversion(
_, data = entity0.last_call("turn_on")
assert data == {"brightness": 255, "color_temp": 153}
_, data = entity1.last_call("turn_on")
assert data == {"brightness": 255, "rgbww_color": (0, 0, 0, 0, 255)}
# Home Assistant uses RGBCW so a mireds of 153 should be maximum cold at 100% brightness so 255
assert data == {"brightness": 255, "rgbww_color": (0, 0, 0, 255, 0)}
await hass.services.async_call(
"light",
@ -1917,7 +1918,63 @@ async def test_light_service_call_color_temp_conversion(
_, data = entity0.last_call("turn_on")
assert data == {"brightness": 128, "color_temp": 500}
_, data = entity1.last_call("turn_on")
assert data == {"brightness": 128, "rgbww_color": (0, 0, 0, 128, 0)}
# Home Assistant uses RGBCW so a mireds of 500 should be maximum warm at 50% brightness so 128
assert data == {"brightness": 128, "rgbww_color": (0, 0, 0, 0, 128)}
await hass.services.async_call(
"light",
"turn_on",
{
"entity_id": [
entity0.entity_id,
entity1.entity_id,
],
"brightness_pct": 100,
"color_temp": 327,
},
blocking=True,
)
_, data = entity0.last_call("turn_on")
assert data == {"brightness": 255, "color_temp": 327}
_, data = entity1.last_call("turn_on")
# Home Assistant uses RGBCW so a mireds of 328 should be the midway point at 100% brightness so 127 (rounding), 128
assert data == {"brightness": 255, "rgbww_color": (0, 0, 0, 127, 128)}
await hass.services.async_call(
"light",
"turn_on",
{
"entity_id": [
entity0.entity_id,
entity1.entity_id,
],
"brightness_pct": 100,
"color_temp": 240,
},
blocking=True,
)
_, data = entity0.last_call("turn_on")
assert data == {"brightness": 255, "color_temp": 240}
_, data = entity1.last_call("turn_on")
assert data == {"brightness": 255, "rgbww_color": (0, 0, 0, 191, 64)}
await hass.services.async_call(
"light",
"turn_on",
{
"entity_id": [
entity0.entity_id,
entity1.entity_id,
],
"brightness_pct": 100,
"color_temp": 410,
},
blocking=True,
)
_, data = entity0.last_call("turn_on")
assert data == {"brightness": 255, "color_temp": 410}
_, data = entity1.last_call("turn_on")
assert data == {"brightness": 255, "rgbww_color": (0, 0, 0, 66, 189)}
async def test_light_service_call_white_mode(hass, enable_custom_integrations):

View File

@ -406,46 +406,137 @@ def test_color_rgb_to_rgbww():
def test_color_temperature_to_rgbww():
"""Test color temp to warm, cold conversion."""
"""Test color temp to warm, cold conversion.
Temperature values must be in mireds
Home Assistant uses rgbcw for rgbww
"""
assert color_util.color_temperature_to_rgbww(153, 255, 153, 500) == (
0,
0,
0,
0,
255,
0,
)
assert color_util.color_temperature_to_rgbww(153, 128, 153, 500) == (
0,
0,
0,
0,
128,
0,
)
assert color_util.color_temperature_to_rgbww(500, 255, 153, 500) == (
0,
0,
0,
255,
0,
255,
)
assert color_util.color_temperature_to_rgbww(500, 128, 153, 500) == (
0,
0,
0,
128,
0,
128,
)
assert color_util.color_temperature_to_rgbww(347, 255, 153, 500) == (
0,
0,
0,
143,
112,
143,
)
assert color_util.color_temperature_to_rgbww(347, 128, 153, 500) == (
0,
0,
0,
72,
56,
72,
)
def test_rgbww_to_color_temperature():
"""Test rgbww conversion to color temp.
Temperature values must be in mireds
Home Assistant uses rgbcw for rgbww
"""
assert (
color_util.rgbww_to_color_temperature(
(
0,
0,
0,
255,
0,
),
153,
500,
)
== (153, 255)
)
assert color_util.rgbww_to_color_temperature((0, 0, 0, 128, 0), 153, 500) == (
153,
128,
)
assert color_util.rgbww_to_color_temperature((0, 0, 0, 0, 255), 153, 500) == (
500,
255,
)
assert color_util.rgbww_to_color_temperature((0, 0, 0, 0, 128), 153, 500) == (
500,
128,
)
assert color_util.rgbww_to_color_temperature((0, 0, 0, 112, 143), 153, 500) == (
348,
255,
)
assert color_util.rgbww_to_color_temperature((0, 0, 0, 56, 72), 153, 500) == (
348,
128,
)
assert color_util.rgbww_to_color_temperature((0, 0, 0, 0, 0), 153, 500) == (
500,
0,
)
def test_white_levels_to_color_temperature():
"""Test warm, cold conversion to color temp.
Temperature values must be in mireds
Home Assistant uses rgbcw for rgbww
"""
assert (
color_util.while_levels_to_color_temperature(
255,
0,
153,
500,
)
== (153, 255)
)
assert color_util.while_levels_to_color_temperature(128, 0, 153, 500) == (
153,
128,
)
assert color_util.while_levels_to_color_temperature(0, 255, 153, 500) == (
500,
255,
)
assert color_util.while_levels_to_color_temperature(0, 128, 153, 500) == (
500,
128,
)
assert color_util.while_levels_to_color_temperature(112, 143, 153, 500) == (
348,
255,
)
assert color_util.while_levels_to_color_temperature(56, 72, 153, 500) == (
348,
128,
)
assert color_util.while_levels_to_color_temperature(0, 0, 153, 500) == (
500,
0,
)