Improve syncing light states to deCONZ groups (#117588)

This commit is contained in:
Robert Svensson 2024-05-17 08:44:09 +02:00 committed by GitHub
parent 48ea15cc6e
commit bbfc2456ec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 9 deletions

View File

@ -2,12 +2,12 @@
from __future__ import annotations from __future__ import annotations
from typing import Any, TypedDict, TypeVar from typing import Any, TypedDict, TypeVar, cast
from pydeconz.interfaces.groups import GroupHandler from pydeconz.interfaces.groups import GroupHandler
from pydeconz.interfaces.lights import LightHandler from pydeconz.interfaces.lights import LightHandler
from pydeconz.models.event import EventType from pydeconz.models.event import EventType
from pydeconz.models.group import Group from pydeconz.models.group import Group, TypedGroupAction
from pydeconz.models.light.light import Light, LightAlert, LightColorMode, LightEffect from pydeconz.models.light.light import Light, LightAlert, LightColorMode, LightEffect
from homeassistant.components.light import ( from homeassistant.components.light import (
@ -103,6 +103,23 @@ class SetStateAttributes(TypedDict, total=False):
xy: tuple[float, float] xy: tuple[float, float]
def update_color_state(
group: Group, lights: list[Light], override: bool = False
) -> None:
"""Sync group color state with light."""
data = {
attribute: light_attribute
for light in lights
for attribute in ("bri", "ct", "hue", "sat", "xy", "colormode", "effect")
if (light_attribute := light.raw["state"].get(attribute)) is not None
}
if override:
group.raw["action"] = cast(TypedGroupAction, data)
else:
group.update(cast(dict[str, dict[str, Any]], {"action": data}))
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: ConfigEntry, config_entry: ConfigEntry,
@ -135,11 +152,12 @@ async def async_setup_entry(
if (group := hub.api.groups[group_id]) and not group.lights: if (group := hub.api.groups[group_id]) and not group.lights:
return return
first = True lights = [
for light_id in group.lights: light
if (light := hub.api.lights.lights.get(light_id)) and light.reachable: for light_id in group.lights
group.update_color_state(light, update_all_attributes=first) if (light := hub.api.lights.lights.get(light_id)) and light.reachable
first = False ]
update_color_state(group, lights, True)
async_add_entities([DeconzGroup(group, hub)]) async_add_entities([DeconzGroup(group, hub)])
@ -313,7 +331,7 @@ class DeconzLight(DeconzBaseLight[Light]):
if self._device.reachable and "attr" not in self._device.changed_keys: if self._device.reachable and "attr" not in self._device.changed_keys:
for group in self.hub.api.groups.values(): for group in self.hub.api.groups.values():
if self._device.resource_id in group.lights: if self._device.resource_id in group.lights:
group.update_color_state(self._device) update_color_state(group, [self._device])
class DeconzGroup(DeconzBaseLight[Group]): class DeconzGroup(DeconzBaseLight[Group]):

View File

@ -1522,4 +1522,4 @@ async def test_verify_group_color_mode_fallback(
) )
group_state = hass.states.get("light.opbergruimte") group_state = hass.states.get("light.opbergruimte")
assert group_state.state == STATE_ON assert group_state.state == STATE_ON
assert group_state.attributes[ATTR_COLOR_MODE] is ColorMode.UNKNOWN assert group_state.attributes[ATTR_COLOR_MODE] is ColorMode.BRIGHTNESS