Skip to content

Commit

Permalink
Preload supported color properties in fritzbox lights (home-assistant…
Browse files Browse the repository at this point in the history
  • Loading branch information
mib1185 authored Dec 23, 2024
1 parent 6cbc803 commit bbb5f9e
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 30 deletions.
17 changes: 15 additions & 2 deletions homeassistant/components/fritzbox/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class FritzboxCoordinatorData:

devices: dict[str, FritzhomeDevice]
templates: dict[str, FritzhomeTemplate]
supported_color_properties: dict[str, tuple[dict, list]]


class FritzboxDataUpdateCoordinator(DataUpdateCoordinator[FritzboxCoordinatorData]):
Expand All @@ -49,7 +50,7 @@ def __init__(self, hass: HomeAssistant, name: str) -> None:
self.new_devices: set[str] = set()
self.new_templates: set[str] = set()

self.data = FritzboxCoordinatorData({}, {})
self.data = FritzboxCoordinatorData({}, {}, {})

async def async_setup(self) -> None:
"""Set up the coordinator."""
Expand Down Expand Up @@ -120,6 +121,7 @@ def _update_fritz_devices(self) -> FritzboxCoordinatorData:

devices = self.fritz.get_devices()
device_data = {}
supported_color_properties = self.data.supported_color_properties
for device in devices:
# assume device as unavailable, see #55799
if (
Expand All @@ -136,6 +138,13 @@ def _update_fritz_devices(self) -> FritzboxCoordinatorData:

device_data[device.ain] = device

# pre-load supported colors and color temps for new devices
if device.has_color and device.ain not in supported_color_properties:
supported_color_properties[device.ain] = (
device.get_colors(),
device.get_color_temps(),
)

template_data = {}
if self.has_templates:
templates = self.fritz.get_templates()
Expand All @@ -145,7 +154,11 @@ def _update_fritz_devices(self) -> FritzboxCoordinatorData:
self.new_devices = device_data.keys() - self.data.devices.keys()
self.new_templates = template_data.keys() - self.data.templates.keys()

return FritzboxCoordinatorData(devices=device_data, templates=template_data)
return FritzboxCoordinatorData(
devices=device_data,
templates=template_data,
supported_color_properties=supported_color_properties,
)

async def _async_update_data(self) -> FritzboxCoordinatorData:
"""Fetch all device data."""
Expand Down
48 changes: 20 additions & 28 deletions homeassistant/components/fritzbox/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,33 @@ def __init__(
) -> None:
"""Initialize the FritzboxLight entity."""
super().__init__(coordinator, ain, None)
self._supported_hs: dict[int, list[int]] = {}

self._attr_supported_color_modes = {ColorMode.ONOFF}
if self.data.has_color:
self._attr_supported_color_modes = {ColorMode.COLOR_TEMP, ColorMode.HS}
elif self.data.has_level:
self._attr_supported_color_modes = {ColorMode.BRIGHTNESS}

(supported_colors, supported_color_temps) = (
coordinator.data.supported_color_properties.get(self.data.ain, ({}, []))
)

# Fritz!DECT 500 only supports 12 values for hue, with 3 saturations each.
# Map supported colors to dict {hue: [sat1, sat2, sat3]} for easier lookup
self._supported_hs: dict[int, list[int]] = {}
for values in supported_colors.values():
hue = int(values[0][0])
self._supported_hs[hue] = [
int(values[0][1]),
int(values[1][1]),
int(values[2][1]),
]

if supported_color_temps:
# only available for color bulbs
self._attr_max_color_temp_kelvin = int(max(supported_color_temps))
self._attr_min_color_temp_kelvin = int(min(supported_color_temps))

@property
def is_on(self) -> bool:
"""If the light is currently on or off."""
Expand Down Expand Up @@ -148,30 +167,3 @@ async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the light off."""
await self.hass.async_add_executor_job(self.data.set_state_off)
await self.coordinator.async_refresh()

async def async_added_to_hass(self) -> None:
"""Get light attributes from device after entity is added to hass."""
await super().async_added_to_hass()

def _get_color_data() -> tuple[dict, list]:
return (self.data.get_colors(), self.data.get_color_temps())

(
supported_colors,
supported_color_temps,
) = await self.hass.async_add_executor_job(_get_color_data)

if supported_color_temps:
# only available for color bulbs
self._attr_max_color_temp_kelvin = int(max(supported_color_temps))
self._attr_min_color_temp_kelvin = int(min(supported_color_temps))

# Fritz!DECT 500 only supports 12 values for hue, with 3 saturations each.
# Map supported colors to dict {hue: [sat1, sat2, sat3]} for easier lookup
for values in supported_colors.values():
hue = int(values[0][0])
self._supported_hs[hue] = [
int(values[0][1]),
int(values[1][1]),
int(values[2][1]),
]

0 comments on commit bbb5f9e

Please sign in to comment.