Handle color temp to RGBWW conversion (#61473)

Co-authored-by: Erik Montnemery <erik@montnemery.com>
pull/62102/head
J. Nick Koston 2021-12-16 05:39:33 -06:00 committed by GitHub
parent 12671b370e
commit 94ae6ac2b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 140 additions and 8 deletions

View File

@ -382,14 +382,22 @@ async def async_setup(hass, config): # noqa: C901
params[ATTR_WHITE_VALUE] = rgbw_color[3]
# If a color temperature is specified, emulate it if not supported by the light
if (
ATTR_COLOR_TEMP in params
and COLOR_MODE_COLOR_TEMP not in legacy_supported_color_modes
):
color_temp = params.pop(ATTR_COLOR_TEMP)
if color_supported(legacy_supported_color_modes):
temp_k = color_util.color_temperature_mired_to_kelvin(color_temp)
params[ATTR_HS_COLOR] = color_util.color_temperature_to_hs(temp_k)
if ATTR_COLOR_TEMP in params:
if (
supported_color_modes
and COLOR_MODE_COLOR_TEMP not in supported_color_modes
and COLOR_MODE_RGBWW in supported_color_modes
):
color_temp = params.pop(ATTR_COLOR_TEMP)
brightness = params.get(ATTR_BRIGHTNESS, light.brightness)
params[ATTR_RGBWW_COLOR] = color_util.color_temperature_to_rgbww(
color_temp, brightness, light.min_mireds, light.max_mireds
)
elif COLOR_MODE_COLOR_TEMP not in legacy_supported_color_modes:
color_temp = params.pop(ATTR_COLOR_TEMP)
if color_supported(legacy_supported_color_modes):
temp_k = color_util.color_temperature_mired_to_kelvin(color_temp)
params[ATTR_HS_COLOR] = color_util.color_temperature_to_hs(temp_k)
# If a color is specified, convert to the color space supported by the light
# Backwards compatibility: Fall back to hs color if light.supported_color_modes

View File

@ -528,6 +528,16 @@ def color_temperature_to_rgb(
return red, green, blue
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."""
mired_range = max_mireds - min_mireds
warm = ((max_mireds - temperature) / mired_range) * brightness
cold = brightness - warm
return (0, 0, 0, round(cold), round(warm))
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

@ -1852,6 +1852,74 @@ async def test_light_service_call_color_temp_emulation(
assert data == {"brightness": 255, "hs_color": (27.001, 19.243)}
async def test_light_service_call_color_temp_conversion(
hass, enable_custom_integrations
):
"""Test color temp conversion in service calls."""
platform = getattr(hass.components, "test.light")
platform.init(empty=True)
platform.ENTITIES.append(platform.MockLight("Test_rgbww_ct", STATE_ON))
platform.ENTITIES.append(platform.MockLight("Test_rgbww", STATE_ON))
entity0 = platform.ENTITIES[0]
entity0.supported_color_modes = {
light.COLOR_MODE_COLOR_TEMP,
light.COLOR_MODE_RGBWW,
}
entity1 = platform.ENTITIES[1]
entity1.supported_color_modes = {light.COLOR_MODE_RGBWW}
assert await async_setup_component(hass, "light", {"light": {"platform": "test"}})
await hass.async_block_till_done()
state = hass.states.get(entity0.entity_id)
assert state.attributes["supported_color_modes"] == [
light.COLOR_MODE_COLOR_TEMP,
light.COLOR_MODE_RGBWW,
]
state = hass.states.get(entity1.entity_id)
assert state.attributes["supported_color_modes"] == [light.COLOR_MODE_RGBWW]
await hass.services.async_call(
"light",
"turn_on",
{
"entity_id": [
entity0.entity_id,
entity1.entity_id,
],
"brightness_pct": 100,
"color_temp": 153,
},
blocking=True,
)
_, 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)}
await hass.services.async_call(
"light",
"turn_on",
{
"entity_id": [
entity0.entity_id,
entity1.entity_id,
],
"brightness_pct": 50,
"color_temp": 500,
},
blocking=True,
)
_, 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)}
async def test_light_service_call_white_mode(hass, enable_custom_integrations):
"""Test color_mode white in service calls."""
platform = getattr(hass.components, "test.light")

View File

@ -401,3 +401,49 @@ def test_color_rgb_to_rgbww():
assert color_util.color_rgb_to_rgbww(64, 64, 64, 154, 370) == (0, 14, 25, 64, 64)
assert color_util.color_rgb_to_rgbww(32, 64, 16, 154, 370) == (9, 64, 0, 38, 38)
assert color_util.color_rgb_to_rgbww(0, 0, 0, 154, 370) == (0, 0, 0, 0, 0)
def test_color_temperature_to_rgbww():
"""Test color temp to warm, cold conversion."""
assert color_util.color_temperature_to_rgbww(153, 255, 153, 500) == (
0,
0,
0,
0,
255,
)
assert color_util.color_temperature_to_rgbww(153, 128, 153, 500) == (
0,
0,
0,
0,
128,
)
assert color_util.color_temperature_to_rgbww(500, 255, 153, 500) == (
0,
0,
0,
255,
0,
)
assert color_util.color_temperature_to_rgbww(500, 128, 153, 500) == (
0,
0,
0,
128,
0,
)
assert color_util.color_temperature_to_rgbww(347, 255, 153, 500) == (
0,
0,
0,
143,
112,
)
assert color_util.color_temperature_to_rgbww(347, 128, 153, 500) == (
0,
0,
0,
72,
56,
)