Improve color mode handling in light groups (#109390)

* Improve color mode handling in light groups

* Update config flow test
This commit is contained in:
Erik Montnemery 2024-02-03 09:00:00 +01:00 committed by GitHub
parent 6f9876d5e0
commit fe4dd2cb93
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 44 additions and 40 deletions

View file

@ -30,6 +30,7 @@ from homeassistant.components.light import (
ColorMode,
LightEntity,
LightEntityFeature,
filter_supported_color_modes,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
@ -162,6 +163,9 @@ class LightGroup(GroupEntity, LightEntity):
if mode:
self.mode = all
self._attr_color_mode = ColorMode.UNKNOWN
self._attr_supported_color_modes = {ColorMode.ONOFF}
async def async_turn_on(self, **kwargs: Any) -> None:
"""Forward the turn_on command to all lights in the light group."""
data = {
@ -261,26 +265,36 @@ class LightGroup(GroupEntity, LightEntity):
effects_count = Counter(itertools.chain(all_effects))
self._attr_effect = effects_count.most_common(1)[0][0]
self._attr_color_mode = None
all_color_modes = list(find_state_attributes(on_states, ATTR_COLOR_MODE))
if all_color_modes:
# Report the most common color mode, select brightness and onoff last
color_mode_count = Counter(itertools.chain(all_color_modes))
if ColorMode.ONOFF in color_mode_count:
color_mode_count[ColorMode.ONOFF] = -1
if ColorMode.BRIGHTNESS in color_mode_count:
color_mode_count[ColorMode.BRIGHTNESS] = 0
self._attr_color_mode = color_mode_count.most_common(1)[0][0]
self._attr_supported_color_modes = None
supported_color_modes = {ColorMode.ONOFF}
all_supported_color_modes = list(
find_state_attributes(states, ATTR_SUPPORTED_COLOR_MODES)
)
if all_supported_color_modes:
# Merge all color modes.
self._attr_supported_color_modes = cast(
set[str], set().union(*all_supported_color_modes)
supported_color_modes = filter_supported_color_modes(
cast(set[ColorMode], set().union(*all_supported_color_modes))
)
self._attr_supported_color_modes = supported_color_modes
self._attr_color_mode = ColorMode.UNKNOWN
all_color_modes = list(find_state_attributes(on_states, ATTR_COLOR_MODE))
if all_color_modes:
# Report the most common color mode, select brightness and onoff last
color_mode_count = Counter(itertools.chain(all_color_modes))
if ColorMode.ONOFF in color_mode_count:
if ColorMode.ONOFF in supported_color_modes:
color_mode_count[ColorMode.ONOFF] = -1
else:
color_mode_count.pop(ColorMode.ONOFF)
if ColorMode.BRIGHTNESS in color_mode_count:
if ColorMode.BRIGHTNESS in supported_color_modes:
color_mode_count[ColorMode.BRIGHTNESS] = 0
else:
color_mode_count.pop(ColorMode.BRIGHTNESS)
if color_mode_count:
self._attr_color_mode = color_mode_count.most_common(1)[0][0]
else:
self._attr_color_mode = next(iter(supported_color_modes))
self._attr_supported_features = LightEntityFeature(0)
for support in find_state_attributes(states, ATTR_SUPPORTED_FEATURES):

View file

@ -479,7 +479,7 @@ LIGHT_ATTRS = [
"supported_color_modes": ["onoff"],
"supported_features": 0,
},
{"color_mode": "onoff"},
{"color_mode": "unknown"},
]
LOCK_ATTRS = [{"supported_features": 1}, {}]
MEDIA_PLAYER_ATTRS = [{"supported_features": 0}, {}]

View file

@ -28,9 +28,6 @@ from homeassistant.components.light import (
SERVICE_TOGGLE,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
SUPPORT_BRIGHTNESS,
SUPPORT_COLOR,
SUPPORT_COLOR_TEMP,
ColorMode,
)
from homeassistant.const import (
@ -278,10 +275,8 @@ async def test_brightness(
entity0.brightness = 255
entity1 = platform.ENTITIES[1]
entity1.supported_features = SUPPORT_BRIGHTNESS
# Set color modes to none to trigger backwards compatibility in LightEntity
entity1.supported_color_modes = None
entity1.color_mode = None
entity1.supported_color_modes = {ColorMode.BRIGHTNESS}
entity1.color_mode = ColorMode.BRIGHTNESS
assert await async_setup_component(
hass,
@ -352,10 +347,8 @@ async def test_color_hs(hass: HomeAssistant, enable_custom_integrations: None) -
entity0.hs_color = (0, 100)
entity1 = platform.ENTITIES[1]
entity1.supported_features = SUPPORT_COLOR
# Set color modes to none to trigger backwards compatibility in LightEntity
entity1.supported_color_modes = None
entity1.color_mode = None
entity1.supported_color_modes = {ColorMode.HS}
entity1.color_mode = ColorMode.HS
assert await async_setup_component(
hass,
@ -703,10 +696,8 @@ async def test_color_temp(
entity0.color_temp_kelvin = 2
entity1 = platform.ENTITIES[1]
entity1.supported_features = SUPPORT_COLOR_TEMP
# Set color modes to none to trigger backwards compatibility in LightEntity
entity1.supported_color_modes = None
entity1.color_mode = None
entity1.supported_color_modes = {ColorMode.COLOR_TEMP}
entity1.color_mode = ColorMode.COLOR_TEMP
assert await async_setup_component(
hass,
@ -846,10 +837,8 @@ async def test_min_max_mireds(
entity0._attr_max_color_temp_kelvin = 5
entity1 = platform.ENTITIES[1]
entity1.supported_features = SUPPORT_COLOR_TEMP
# Set color modes to none to trigger backwards compatibility in LightEntity
entity1.supported_color_modes = None
entity1.color_mode = None
entity1.supported_color_modes = {ColorMode.COLOR_TEMP}
entity1.color_mode = ColorMode.COLOR_TEMP
entity1._attr_min_color_temp_kelvin = 1
entity1._attr_max_color_temp_kelvin = 1234567890
@ -1021,15 +1010,15 @@ async def test_supported_color_modes(
entity0 = platform.ENTITIES[0]
entity0.supported_color_modes = {ColorMode.COLOR_TEMP, ColorMode.HS}
entity0.color_mode = ColorMode.UNKNOWN
entity1 = platform.ENTITIES[1]
entity1.supported_color_modes = {ColorMode.RGBW, ColorMode.RGBWW}
entity1.color_mode = ColorMode.UNKNOWN
entity2 = platform.ENTITIES[2]
entity2.supported_features = SUPPORT_BRIGHTNESS
# Set color modes to none to trigger backwards compatibility in LightEntity
entity2.supported_color_modes = None
entity2.color_mode = None
entity2.supported_color_modes = {ColorMode.BRIGHTNESS}
entity2.color_mode = ColorMode.UNKNOWN
assert await async_setup_component(
hass,
@ -1051,7 +1040,6 @@ async def test_supported_color_modes(
state = hass.states.get("light.light_group")
assert set(state.attributes[ATTR_SUPPORTED_COLOR_MODES]) == {
"brightness",
"color_temp",
"hs",
"rgbw",
@ -1198,6 +1186,7 @@ async def test_color_mode2(
await hass.async_block_till_done()
state = hass.states.get("light.light_group")
assert state.attributes[ATTR_SUPPORTED_COLOR_MODES] == [ColorMode.COLOR_TEMP]
assert state.attributes[ATTR_COLOR_MODE] == ColorMode.COLOR_TEMP
await hass.services.async_call(
@ -1208,7 +1197,8 @@ async def test_color_mode2(
)
await hass.async_block_till_done()
state = hass.states.get("light.light_group")
assert state.attributes[ATTR_COLOR_MODE] == ColorMode.BRIGHTNESS
assert state.attributes[ATTR_SUPPORTED_COLOR_MODES] == [ColorMode.COLOR_TEMP]
assert state.attributes[ATTR_COLOR_MODE] == ColorMode.COLOR_TEMP
async def test_supported_features(hass: HomeAssistant) -> None: