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:
Bryan York 2019-09-15 11:53:05 -07:00 committed by Martin Hjelmare
parent fd359c6222
commit f45f8f2f3d
3 changed files with 97 additions and 3 deletions

View File

@ -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)

View File

@ -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):

View File

@ -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(