mirror of
https://github.com/home-assistant/core.git
synced 2025-07-15 09:17:10 +00:00
Emulate color temperature for non-ct lights in light groups (#23495)
* Emulate color temperature for non-ct lights in light groups * fix tests * Address review comments * Fix black formatting * Fix for pylint * Address comments * Fix black formatting * Address comments
This commit is contained in:
parent
fd359c6222
commit
f45f8f2f3d
@ -308,7 +308,7 @@ class ColorSettingTrait(_Trait):
|
||||
|
||||
if features & light.SUPPORT_COLOR_TEMP:
|
||||
# Max Kelvin is Min Mireds K = 1000000 / mireds
|
||||
# Min Kevin is Max Mireds K = 1000000 / mireds
|
||||
# Min Kelvin is Max Mireds K = 1000000 / mireds
|
||||
response["colorTemperatureRange"] = {
|
||||
"temperatureMaxK": color_util.color_temperature_mired_to_kelvin(
|
||||
attrs.get(light.ATTR_MIN_MIREDS)
|
||||
|
@ -1,4 +1,5 @@
|
||||
"""This platform allows several lights to be grouped into one light."""
|
||||
import asyncio
|
||||
from collections import Counter
|
||||
import itertools
|
||||
import logging
|
||||
@ -19,6 +20,7 @@ from homeassistant.core import State, callback
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.event import async_track_state_change
|
||||
from homeassistant.helpers.typing import ConfigType, HomeAssistantType
|
||||
from homeassistant.util import color as color_util
|
||||
|
||||
from homeassistant.components.light import (
|
||||
ATTR_BRIGHTNESS,
|
||||
@ -179,6 +181,7 @@ class LightGroup(light.Light):
|
||||
async def async_turn_on(self, **kwargs):
|
||||
"""Forward the turn_on command to all lights in the light group."""
|
||||
data = {ATTR_ENTITY_ID: self._entity_ids}
|
||||
emulate_color_temp_entity_ids = []
|
||||
|
||||
if ATTR_BRIGHTNESS in kwargs:
|
||||
data[ATTR_BRIGHTNESS] = kwargs[ATTR_BRIGHTNESS]
|
||||
@ -189,6 +192,23 @@ class LightGroup(light.Light):
|
||||
if ATTR_COLOR_TEMP in kwargs:
|
||||
data[ATTR_COLOR_TEMP] = kwargs[ATTR_COLOR_TEMP]
|
||||
|
||||
# Create a new entity list to mutate
|
||||
updated_entities = list(self._entity_ids)
|
||||
|
||||
# Walk through initial entity ids, split entity lists by support
|
||||
for entity_id in self._entity_ids:
|
||||
state = self.hass.states.get(entity_id)
|
||||
if not state:
|
||||
continue
|
||||
support = state.attributes.get(ATTR_SUPPORTED_FEATURES)
|
||||
# Only pass color temperature to supported entity_ids
|
||||
if bool(support & SUPPORT_COLOR) and not bool(
|
||||
support & SUPPORT_COLOR_TEMP
|
||||
):
|
||||
emulate_color_temp_entity_ids.append(entity_id)
|
||||
updated_entities.remove(entity_id)
|
||||
data[ATTR_ENTITY_ID] = updated_entities
|
||||
|
||||
if ATTR_WHITE_VALUE in kwargs:
|
||||
data[ATTR_WHITE_VALUE] = kwargs[ATTR_WHITE_VALUE]
|
||||
|
||||
@ -201,8 +221,32 @@ class LightGroup(light.Light):
|
||||
if ATTR_FLASH in kwargs:
|
||||
data[ATTR_FLASH] = kwargs[ATTR_FLASH]
|
||||
|
||||
await self.hass.services.async_call(
|
||||
light.DOMAIN, light.SERVICE_TURN_ON, data, blocking=True
|
||||
if not emulate_color_temp_entity_ids:
|
||||
await self.hass.services.async_call(
|
||||
light.DOMAIN, light.SERVICE_TURN_ON, data, blocking=True
|
||||
)
|
||||
return
|
||||
|
||||
emulate_color_temp_data = data.copy()
|
||||
temp_k = color_util.color_temperature_mired_to_kelvin(
|
||||
emulate_color_temp_data[ATTR_COLOR_TEMP]
|
||||
)
|
||||
hs_color = color_util.color_temperature_to_hs(temp_k)
|
||||
emulate_color_temp_data[ATTR_HS_COLOR] = hs_color
|
||||
del emulate_color_temp_data[ATTR_COLOR_TEMP]
|
||||
|
||||
emulate_color_temp_data[ATTR_ENTITY_ID] = emulate_color_temp_entity_ids
|
||||
|
||||
await asyncio.gather(
|
||||
self.hass.services.async_call(
|
||||
light.DOMAIN, light.SERVICE_TURN_ON, data, blocking=True
|
||||
),
|
||||
self.hass.services.async_call(
|
||||
light.DOMAIN,
|
||||
light.SERVICE_TURN_ON,
|
||||
emulate_color_temp_data,
|
||||
blocking=True,
|
||||
),
|
||||
)
|
||||
|
||||
async def async_turn_off(self, **kwargs):
|
||||
|
@ -186,6 +186,56 @@ async def test_color_temp(hass):
|
||||
assert state.attributes["color_temp"] == 1000
|
||||
|
||||
|
||||
async def test_emulated_color_temp_group(hass):
|
||||
"""Test emulated color temperature in a group."""
|
||||
await async_setup_component(
|
||||
hass,
|
||||
"light",
|
||||
{
|
||||
"light": [
|
||||
{"platform": "demo"},
|
||||
{
|
||||
"platform": "group",
|
||||
"entities": [
|
||||
"light.bed_light",
|
||||
"light.ceiling_lights",
|
||||
"light.kitchen_lights",
|
||||
],
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
hass.states.async_set("light.bed_light", "on", {"supported_features": 2})
|
||||
await hass.async_block_till_done()
|
||||
hass.states.async_set("light.ceiling_lights", "on", {"supported_features": 63})
|
||||
await hass.async_block_till_done()
|
||||
hass.states.async_set("light.kitchen_lights", "on", {"supported_features": 61})
|
||||
await hass.async_block_till_done()
|
||||
await hass.services.async_call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{"entity_id": "light.light_group", "color_temp": 200},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.bed_light")
|
||||
assert state.state == "on"
|
||||
assert state.attributes["color_temp"] == 200
|
||||
assert "hs_color" not in state.attributes.keys()
|
||||
|
||||
state = hass.states.get("light.ceiling_lights")
|
||||
assert state.state == "on"
|
||||
assert state.attributes["color_temp"] == 200
|
||||
assert "hs_color" in state.attributes.keys()
|
||||
|
||||
state = hass.states.get("light.kitchen_lights")
|
||||
assert state.state == "on"
|
||||
assert state.attributes["hs_color"] == (27.001, 19.243)
|
||||
|
||||
|
||||
async def test_min_max_mireds(hass):
|
||||
"""Test min/max mireds reporting."""
|
||||
await async_setup_component(
|
||||
|
Loading…
x
Reference in New Issue
Block a user