Skip to content

Commit

Permalink
Improve syncing light states to deCONZ groups (#117588)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kane610 authored and frenck committed May 17, 2024
1 parent 5cd101d commit f043b2d
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 9 deletions.
34 changes: 26 additions & 8 deletions homeassistant/components/deconz/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

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.lights import LightHandler
from pydeconz.models import ResourceType
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 homeassistant.components.light import (
Expand Down Expand Up @@ -105,6 +105,23 @@ class SetStateAttributes(TypedDict, total=False):
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(
hass: HomeAssistant,
config_entry: ConfigEntry,
Expand Down Expand Up @@ -148,11 +165,12 @@ def async_add_group(_: EventType, group_id: str) -> None:
if (group := hub.api.groups[group_id]) and not group.lights:
return

first = True
for light_id in group.lights:
if (light := hub.api.lights.lights.get(light_id)) and light.reachable:
group.update_color_state(light, update_all_attributes=first)
first = False
lights = [
light
for light_id in group.lights
if (light := hub.api.lights.lights.get(light_id)) and light.reachable
]
update_color_state(group, lights, True)

async_add_entities([DeconzGroup(group, hub)])

Expand Down Expand Up @@ -326,7 +344,7 @@ def async_update_callback(self) -> None:
if self._device.reachable and "attr" not in self._device.changed_keys:
for group in self.hub.api.groups.values():
if self._device.resource_id in group.lights:
group.update_color_state(self._device)
update_color_state(group, [self._device])


class DeconzGroup(DeconzBaseLight[Group]):
Expand Down
2 changes: 1 addition & 1 deletion tests/components/deconz/test_light.py
Original file line number Diff line number Diff line change
Expand Up @@ -1522,4 +1522,4 @@ async def test_verify_group_color_mode_fallback(
)
group_state = hass.states.get("light.opbergruimte")
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

0 comments on commit f043b2d

Please sign in to comment.