diff --git a/custom_components/tahoma/light.py b/custom_components/tahoma/light.py index 5ddb0ef6..b640a184 100644 --- a/custom_components/tahoma/light.py +++ b/custom_components/tahoma/light.py @@ -1,65 +1,60 @@ -"""Support for Overkiz light devices.""" +"""Support for Overkiz lights.""" +from __future__ import annotations + +from typing import Any, cast + from pyoverkiz.enums import OverkizCommand, OverkizCommandParam, OverkizState from homeassistant.components.light import ( ATTR_BRIGHTNESS, - ATTR_EFFECT, - ATTR_HS_COLOR, - SUPPORT_BRIGHTNESS, - SUPPORT_COLOR, - SUPPORT_EFFECT, + ATTR_RGB_COLOR, + COLOR_MODE_BRIGHTNESS, + COLOR_MODE_ONOFF, + COLOR_MODE_RGB, LightEntity, ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback -import homeassistant.util.color as color_util from . import HomeAssistantOverkizData from .const import DOMAIN from .coordinator import OverkizDataUpdateCoordinator from .entity import OverkizEntity -COMMAND_SET_INTENSITY = "setIntensity" -COMMAND_SET_RGB = "setRGB" -COMMAND_WINK = "wink" - -CORE_BLUE_COLOR_INTENSITY_STATE = "core:BlueColorIntensityState" -CORE_GREEN_COLOR_INTENSITY_STATE = "core:GreenColorIntensityState" -CORE_LIGHT_INTENSITY_STATE = "core:LightIntensityState" -CORE_RED_COLOR_INTENSITY_STATE = "core:RedColorIntensityState" - async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback, -): +) -> None: """Set up the Overkiz lights from a config entry.""" data: HomeAssistantOverkizData = hass.data[DOMAIN][entry.entry_id] - entities = [ + async_add_entities( OverkizLight(device.device_url, data.coordinator) for device in data.platforms[Platform.LIGHT] - ] - - async_add_entities(entities) + ) class OverkizLight(OverkizEntity, LightEntity): """Representation of an Overkiz Light.""" - def __init__(self, device_url: str, coordinator: OverkizDataUpdateCoordinator): + def __init__( + self, device_url: str, coordinator: OverkizDataUpdateCoordinator + ) -> None: """Initialize a device.""" super().__init__(device_url, coordinator) - self._effect = None - @property - def brightness(self) -> int: - """Return the brightness of this light between 0..255.""" - brightness = self.executor.select_state(OverkizState.CORE_LIGHT_INTENSITY) - return round(brightness * 255 / 100) + self._attr_supported_color_modes = set() + + if self.executor.has_command(OverkizCommand.SET_RGB): + self._attr_supported_color_modes.add(COLOR_MODE_RGB) + if self.executor.has_command(OverkizCommand.SET_INTENSITY): + self._attr_supported_color_modes.add(COLOR_MODE_BRIGHTNESS) + if not self.supported_color_modes: + self._attr_supported_color_modes = {COLOR_MODE_ONOFF} @property def is_on(self) -> bool: @@ -70,67 +65,46 @@ def is_on(self) -> bool: ) @property - def hs_color(self): - """Return the hue and saturation color value [float, float].""" - r = self.executor.select_state(OverkizState.CORE_RED_COLOR_INTENSITY) - g = self.executor.select_state(OverkizState.CORE_GREEN_COLOR_INTENSITY) - b = self.executor.select_state(OverkizState.CORE_BLUE_COLOR_INTENSITY) - return None if None in [r, g, b] else color_util.color_RGB_to_hs(r, g, b) - - @property - def supported_features(self) -> int: - """Flag supported features.""" - supported_features = 0 + def rgb_color(self) -> tuple[int, int, int] | None: + """Return the rgb color value [int, int, int] (0-255).""" + red = self.executor.select_state(OverkizState.CORE_RED_COLOR_INTENSITY) + green = self.executor.select_state(OverkizState.CORE_GREEN_COLOR_INTENSITY) + blue = self.executor.select_state(OverkizState.CORE_BLUE_COLOR_INTENSITY) - if self.executor.has_command(OverkizCommand.SET_INTENSITY): - supported_features |= SUPPORT_BRIGHTNESS + if red is None or green is None or blue is None: + return None - if self.executor.has_command(OverkizCommand.WINK): - supported_features |= SUPPORT_EFFECT + return (cast(int, red), cast(int, green), cast(int, blue)) - if self.executor.has_command(OverkizCommand.SET_RGB): - supported_features |= SUPPORT_COLOR + @property + def brightness(self) -> int | None: + """Return the brightness of this light (0-255).""" + value = self.executor.select_state(OverkizState.CORE_LIGHT_INTENSITY) + if value is not None: + return round(cast(int, value) * 255 / 100) - return supported_features + return None - async def async_turn_on(self, **kwargs) -> None: + async def async_turn_on(self, **kwargs: Any) -> None: """Turn the light on.""" - if ATTR_HS_COLOR in kwargs: + rgb_color = kwargs.get(ATTR_RGB_COLOR) + brightness = kwargs.get(ATTR_BRIGHTNESS) + + if rgb_color is not None: await self.executor.async_execute_command( OverkizCommand.SET_RGB, - *[ - round(float(c)) - for c in color_util.color_hs_to_RGB(*kwargs[ATTR_HS_COLOR]) - ], + *[round(float(c)) for c in kwargs[ATTR_RGB_COLOR]], ) + return - if ATTR_BRIGHTNESS in kwargs: - brightness = round(float(kwargs[ATTR_BRIGHTNESS]) / 255 * 100) + if brightness is not None: await self.executor.async_execute_command( - OverkizCommand.SET_INTENSITY, brightness + OverkizCommand.SET_INTENSITY, round(float(brightness) / 255 * 100) ) + return - elif ATTR_EFFECT in kwargs: - self._effect = kwargs[ATTR_EFFECT] - await self.executor.async_execute_command(self._effect, 100) - - else: - await self.executor.async_execute_command(OverkizCommand.ON) + await self.executor.async_execute_command(OverkizCommand.ON) - async def async_turn_off(self, **_) -> None: + async def async_turn_off(self, **kwargs: Any) -> None: """Turn the light off.""" await self.executor.async_execute_command(OverkizCommand.OFF) - - @property - def effect_list(self) -> list: - """Return the list of supported effects.""" - return ( - [OverkizCommand.WINK] - if self.executor.has_command(OverkizCommand.WINK) - else None - ) - - @property - def effect(self) -> str: - """Return the current effect.""" - return self._effect