Fix reporting correct colormode for 3rd party Hue lights (#63015)

pull/63001/head
Marcel van der Veldt 2021-12-29 18:26:52 +01:00 committed by GitHub
parent ab4effc7e2
commit 1547a046db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 14 deletions

View File

@ -7,7 +7,6 @@ from typing import Any
from aiohue.v2 import HueBridgeV2 from aiohue.v2 import HueBridgeV2
from aiohue.v2.controllers.events import EventType from aiohue.v2.controllers.events import EventType
from aiohue.v2.controllers.groups import GroupedLight, Room, Zone from aiohue.v2.controllers.groups import GroupedLight, Room, Zone
from aiohue.v2.models.feature import AlertEffectType
from homeassistant.components.light import ( from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_BRIGHTNESS,
@ -193,7 +192,6 @@ class GroupedHueLight(HueBaseEntity, LightEntity):
color_xy=xy_color if light.supports_color else None, color_xy=xy_color if light.supports_color else None,
color_temp=color_temp if light.supports_color_temperature else None, color_temp=color_temp if light.supports_color_temperature else None,
transition_time=transition, transition_time=transition,
alert=AlertEffectType.BREATHE if flash is not None else None,
allowed_errors=ALLOWED_ERRORS, allowed_errors=ALLOWED_ERRORS,
) )
for light in self.controller.get_lights(self.resource.id) for light in self.controller.get_lights(self.resource.id)

View File

@ -91,6 +91,9 @@ class HueLight(HueBaseEntity, LightEntity):
self._supported_color_modes.add(COLOR_MODE_BRIGHTNESS) self._supported_color_modes.add(COLOR_MODE_BRIGHTNESS)
# support transition if brightness control # support transition if brightness control
self._attr_supported_features |= SUPPORT_TRANSITION self._attr_supported_features |= SUPPORT_TRANSITION
self._last_xy: tuple[float, float] | None = self.xy_color
self._last_color_temp: int = self.color_temp
self._set_color_mode()
@property @property
def brightness(self) -> int | None: def brightness(self) -> int | None:
@ -100,18 +103,6 @@ class HueLight(HueBaseEntity, LightEntity):
return round((dimming.brightness / 100) * 255) return round((dimming.brightness / 100) * 255)
return None return None
@property
def color_mode(self) -> str:
"""Return the current color mode of the light."""
if color_temp := self.resource.color_temperature:
if color_temp.mirek_valid and color_temp.mirek is not None:
return COLOR_MODE_COLOR_TEMP
if self.resource.supports_color:
return COLOR_MODE_XY
if self.resource.supports_dimming:
return COLOR_MODE_BRIGHTNESS
return COLOR_MODE_ONOFF
@property @property
def is_on(self) -> bool: def is_on(self) -> bool:
"""Return true if device is on (brightness above 0).""" """Return true if device is on (brightness above 0)."""
@ -158,6 +149,11 @@ class HueLight(HueBaseEntity, LightEntity):
"dynamics": self.resource.dynamics.status.value, "dynamics": self.resource.dynamics.status.value,
} }
@callback
def on_update(self) -> None:
"""Call on update event."""
self._set_color_mode()
async def async_turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the device on.""" """Turn the device on."""
transition = normalize_hue_transition(kwargs.get(ATTR_TRANSITION)) transition = normalize_hue_transition(kwargs.get(ATTR_TRANSITION))
@ -212,3 +208,43 @@ class HueLight(HueBaseEntity, LightEntity):
id=self.resource.id, id=self.resource.id,
short=flash == FLASH_SHORT, short=flash == FLASH_SHORT,
) )
@callback
def _set_color_mode(self) -> None:
"""Set current colormode of light."""
last_xy = self._last_xy
last_color_temp = self._last_color_temp
self._last_xy = self.xy_color
self._last_color_temp = self.color_temp
# Certified Hue lights return `mired_valid` to indicate CT is active
if color_temp := self.resource.color_temperature:
if color_temp.mirek_valid and color_temp.mirek is not None:
self._attr_color_mode = COLOR_MODE_COLOR_TEMP
return
# Non-certified lights do not report their current color mode correctly
# so we keep track of the color values to determine which is active
if last_color_temp != self.color_temp:
self._attr_color_mode = COLOR_MODE_COLOR_TEMP
return
if last_xy != self.xy_color:
self._attr_color_mode = COLOR_MODE_XY
return
# if we didn't detect any changes, abort and use previous values
if self._attr_color_mode is not None:
return
# color mode not yet determined, work it out here
# Note that for lights that do not correctly report `mirek_valid`
# we might have an invalid startup state which will be auto corrected
if self.resource.supports_color:
self._attr_color_mode = COLOR_MODE_XY
elif self.resource.supports_color_temperature:
self._attr_color_mode = COLOR_MODE_COLOR_TEMP
elif self.resource.supports_dimming:
self._attr_color_mode = COLOR_MODE_BRIGHTNESS
else:
# fallback to on_off
self._attr_color_mode = COLOR_MODE_ONOFF