"""Provides a light for Home Connect.""" import logging from math import ceil from homeconnect.api import HomeConnectError from homeassistant.components.light import ( ATTR_BRIGHTNESS, ATTR_HS_COLOR, SUPPORT_BRIGHTNESS, SUPPORT_COLOR, LightEntity, ) from homeassistant.const import CONF_ENTITIES import homeassistant.util.color as color_util from .const import ( ATTR_VALUE, BSH_AMBIENT_LIGHT_BRIGHTNESS, BSH_AMBIENT_LIGHT_COLOR, BSH_AMBIENT_LIGHT_COLOR_CUSTOM_COLOR, BSH_AMBIENT_LIGHT_CUSTOM_COLOR, BSH_AMBIENT_LIGHT_ENABLED, COOKING_LIGHTING, COOKING_LIGHTING_BRIGHTNESS, DOMAIN, ) from .entity import HomeConnectEntity _LOGGER = logging.getLogger(__name__) async def async_setup_entry(hass, config_entry, async_add_entities): """Set up the Home Connect light.""" def get_entities(): """Get a list of entities.""" entities = [] hc_api = hass.data[DOMAIN][config_entry.entry_id] for device_dict in hc_api.devices: entity_dicts = device_dict.get(CONF_ENTITIES, {}).get("light", []) entity_list = [HomeConnectLight(**d) for d in entity_dicts] entities += entity_list return entities async_add_entities(await hass.async_add_executor_job(get_entities), True) class HomeConnectLight(HomeConnectEntity, LightEntity): """Light for Home Connect.""" def __init__(self, device, desc, ambient): """Initialize the entity.""" super().__init__(device, desc) self._state = None self._brightness = None self._hs_color = None self._ambient = ambient if self._ambient: self._brightness_key = BSH_AMBIENT_LIGHT_BRIGHTNESS self._key = BSH_AMBIENT_LIGHT_ENABLED self._custom_color_key = BSH_AMBIENT_LIGHT_CUSTOM_COLOR self._color_key = BSH_AMBIENT_LIGHT_COLOR else: self._brightness_key = COOKING_LIGHTING_BRIGHTNESS self._key = COOKING_LIGHTING self._custom_color_key = None self._color_key = None @property def is_on(self): """Return true if the light is on.""" return bool(self._state) @property def brightness(self): """Return the brightness of the light.""" return self._brightness @property def hs_color(self): """Return the color property.""" return self._hs_color @property def supported_features(self): """Flag supported features.""" if self._ambient: return SUPPORT_BRIGHTNESS | SUPPORT_COLOR return SUPPORT_BRIGHTNESS async def async_turn_on(self, **kwargs): """Switch the light on, change brightness, change color.""" if self._ambient: _LOGGER.debug("Switching ambient light on for: %s", self.name) try: await self.hass.async_add_executor_job( self.device.appliance.set_setting, self._key, True ) except HomeConnectError as err: _LOGGER.error("Error while trying to turn on ambient light: %s", err) return if ATTR_BRIGHTNESS in kwargs or ATTR_HS_COLOR in kwargs: try: await self.hass.async_add_executor_job( self.device.appliance.set_setting, self._color_key, BSH_AMBIENT_LIGHT_COLOR_CUSTOM_COLOR, ) except HomeConnectError as err: _LOGGER.error("Error while trying selecting customcolor: %s", err) if self._brightness is not None: brightness = 10 + ceil(self._brightness / 255 * 90) if ATTR_BRIGHTNESS in kwargs: brightness = 10 + ceil(kwargs[ATTR_BRIGHTNESS] / 255 * 90) hs_color = kwargs.get(ATTR_HS_COLOR, self._hs_color) if hs_color is not None: rgb = color_util.color_hsv_to_RGB(*hs_color, brightness) hex_val = color_util.color_rgb_to_hex(rgb[0], rgb[1], rgb[2]) try: await self.hass.async_add_executor_job( self.device.appliance.set_setting, self._custom_color_key, f"#{hex_val}", ) except HomeConnectError as err: _LOGGER.error( "Error while trying setting the color: %s", err ) elif ATTR_BRIGHTNESS in kwargs: _LOGGER.debug("Changing brightness for: %s", self.name) brightness = 10 + ceil(kwargs[ATTR_BRIGHTNESS] / 255 * 90) try: await self.hass.async_add_executor_job( self.device.appliance.set_setting, self._brightness_key, brightness ) except HomeConnectError as err: _LOGGER.error("Error while trying set the brightness: %s", err) else: _LOGGER.debug("Switching light on for: %s", self.name) try: await self.hass.async_add_executor_job( self.device.appliance.set_setting, self._key, True ) except HomeConnectError as err: _LOGGER.error("Error while trying to turn on light: %s", err) self.async_entity_update() async def async_turn_off(self, **kwargs): """Switch the light off.""" _LOGGER.debug("Switching light off for: %s", self.name) try: await self.hass.async_add_executor_job( self.device.appliance.set_setting, self._key, False ) except HomeConnectError as err: _LOGGER.error("Error while trying to turn off light: %s", err) self.async_entity_update() async def async_update(self): """Update the light's status.""" if self.device.appliance.status.get(self._key, {}).get(ATTR_VALUE) is True: self._state = True elif self.device.appliance.status.get(self._key, {}).get(ATTR_VALUE) is False: self._state = False else: self._state = None _LOGGER.debug("Updated, new light state: %s", self._state) if self._ambient: color = self.device.appliance.status.get(self._custom_color_key, {}) if not color: self._hs_color = None self._brightness = None else: colorvalue = color.get(ATTR_VALUE)[1:] rgb = color_util.rgb_hex_to_rgb_list(colorvalue) hsv = color_util.color_RGB_to_hsv(rgb[0], rgb[1], rgb[2]) self._hs_color = [hsv[0], hsv[1]] self._brightness = ceil((hsv[2] - 10) * 255 / 90) _LOGGER.debug("Updated, new brightness: %s", self._brightness) else: brightness = self.device.appliance.status.get(self._brightness_key, {}) if brightness is None: self._brightness = None else: self._brightness = ceil((brightness.get(ATTR_VALUE) - 10) * 255 / 90) _LOGGER.debug("Updated, new brightness: %s", self._brightness)