mirror of
https://github.com/home-assistant/core.git
synced 2026-04-17 23:53:49 +01:00
662 lines
22 KiB
Python
662 lines
22 KiB
Python
"""Support for HomematicIP Cloud lights."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from typing import Any
|
|
|
|
from homematicip.base.enums import (
|
|
DeviceType,
|
|
FunctionalChannelType,
|
|
OpticalSignalBehaviour,
|
|
RGBColorState,
|
|
)
|
|
from homematicip.base.functionalChannels import (
|
|
NotificationLightChannel,
|
|
NotificationMp3SoundChannel,
|
|
)
|
|
from homematicip.device import (
|
|
BrandDimmer,
|
|
BrandSwitchNotificationLight,
|
|
CombinationSignallingDevice,
|
|
Device,
|
|
Dimmer,
|
|
DinRailDimmer3,
|
|
FullFlushDimmer,
|
|
PluggableDimmer,
|
|
SwitchMeasuring,
|
|
WiredDimmer3,
|
|
WiredPushButton,
|
|
)
|
|
from packaging.version import Version
|
|
|
|
from homeassistant.components.light import (
|
|
ATTR_BRIGHTNESS,
|
|
ATTR_COLOR_NAME,
|
|
ATTR_EFFECT,
|
|
ATTR_HS_COLOR,
|
|
ATTR_TRANSITION,
|
|
ColorMode,
|
|
LightEntity,
|
|
LightEntityFeature,
|
|
)
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|
|
|
from .entity import HomematicipGenericEntity
|
|
from .hap import HomematicIPConfigEntry, HomematicipHAP
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
config_entry: HomematicIPConfigEntry,
|
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
|
) -> None:
|
|
"""Set up the HomematicIP Cloud lights from a config entry."""
|
|
hap = config_entry.runtime_data
|
|
entities: list[HomematicipGenericEntity] = []
|
|
|
|
entities.extend(
|
|
HomematicipColorLight(hap, d, ch.index)
|
|
for d in hap.home.devices
|
|
for ch in d.functionalChannels
|
|
if ch.functionalChannelType == FunctionalChannelType.UNIVERSAL_LIGHT_CHANNEL
|
|
)
|
|
|
|
for device in hap.home.devices:
|
|
if (
|
|
isinstance(device, SwitchMeasuring)
|
|
and getattr(device, "deviceType", None) == DeviceType.BRAND_SWITCH_MEASURING
|
|
):
|
|
entities.append(HomematicipLightMeasuring(hap, device))
|
|
if isinstance(device, BrandSwitchNotificationLight):
|
|
device_version = Version(device.firmwareVersion)
|
|
entities.append(HomematicipLight(hap, device))
|
|
|
|
entity_class = (
|
|
HomematicipNotificationLightV2
|
|
if device_version > Version("2.0.0")
|
|
else HomematicipNotificationLight
|
|
)
|
|
|
|
entities.append(
|
|
entity_class(hap, device, device.topLightChannelIndex, "Top")
|
|
)
|
|
entities.append(
|
|
entity_class(hap, device, device.bottomLightChannelIndex, "Bottom")
|
|
)
|
|
|
|
elif isinstance(device, (WiredDimmer3, DinRailDimmer3)):
|
|
entities.extend(
|
|
HomematicipMultiDimmer(hap, device, channel=channel)
|
|
for channel in range(1, 4)
|
|
)
|
|
elif isinstance(
|
|
device,
|
|
(Dimmer, PluggableDimmer, BrandDimmer, FullFlushDimmer),
|
|
):
|
|
entities.append(HomematicipDimmer(hap, device))
|
|
elif isinstance(device, WiredPushButton):
|
|
optical_channels = sorted(
|
|
(
|
|
ch
|
|
for ch in device.functionalChannels
|
|
if ch.functionalChannelType
|
|
== FunctionalChannelType.OPTICAL_SIGNAL_CHANNEL
|
|
),
|
|
key=lambda ch: ch.index,
|
|
)
|
|
for led_number, ch in enumerate(optical_channels, start=1):
|
|
entities.append(
|
|
HomematicipOpticalSignalLight(hap, device, ch.index, led_number)
|
|
)
|
|
elif isinstance(device, CombinationSignallingDevice):
|
|
entities.append(HomematicipCombinationSignallingLight(hap, device))
|
|
|
|
async_add_entities(entities)
|
|
|
|
|
|
class HomematicipLight(HomematicipGenericEntity, LightEntity):
|
|
"""Representation of the HomematicIP light."""
|
|
|
|
_attr_color_mode = ColorMode.ONOFF
|
|
_attr_supported_color_modes = {ColorMode.ONOFF}
|
|
|
|
def __init__(self, hap: HomematicipHAP, device) -> None:
|
|
"""Initialize the light entity."""
|
|
super().__init__(hap, device)
|
|
|
|
@property
|
|
def is_on(self) -> bool:
|
|
"""Return true if light is on."""
|
|
return self._device.on
|
|
|
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
|
"""Turn the light on."""
|
|
await self._device.turn_on_async()
|
|
|
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
|
"""Turn the light off."""
|
|
await self._device.turn_off_async()
|
|
|
|
|
|
class HomematicipColorLight(HomematicipGenericEntity, LightEntity):
|
|
"""Representation of the HomematicIP color light."""
|
|
|
|
def __init__(self, hap: HomematicipHAP, device: Device, channel_index: int) -> None:
|
|
"""Initialize the light entity."""
|
|
super().__init__(hap, device, channel=channel_index, is_multi_channel=True)
|
|
|
|
def _supports_color(self) -> bool:
|
|
"""Return true if device supports hue/saturation color control."""
|
|
channel = self.get_channel_or_raise()
|
|
return channel.hue is not None and channel.saturationLevel is not None
|
|
|
|
@property
|
|
def color_mode(self) -> ColorMode:
|
|
"""Return the color mode of the light."""
|
|
if self._supports_color():
|
|
return ColorMode.HS
|
|
return ColorMode.BRIGHTNESS
|
|
|
|
@property
|
|
def supported_color_modes(self) -> set[ColorMode]:
|
|
"""Return the supported color modes."""
|
|
if self._supports_color():
|
|
return {ColorMode.HS}
|
|
return {ColorMode.BRIGHTNESS}
|
|
|
|
@property
|
|
def is_on(self) -> bool:
|
|
"""Return true if light is on."""
|
|
channel = self.get_channel_or_raise()
|
|
return channel.on
|
|
|
|
@property
|
|
def brightness(self) -> int | None:
|
|
"""Return the current brightness."""
|
|
channel = self.get_channel_or_raise()
|
|
return int(channel.dimLevel * 255.0)
|
|
|
|
@property
|
|
def hs_color(self) -> tuple[float, float] | None:
|
|
"""Return the hue and saturation color value [float, float]."""
|
|
channel = self.get_channel_or_raise()
|
|
if channel.hue is None or channel.saturationLevel is None:
|
|
return None
|
|
return (
|
|
channel.hue,
|
|
channel.saturationLevel * 100.0,
|
|
)
|
|
|
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
|
"""Turn the light on."""
|
|
channel = self.get_channel_or_raise()
|
|
dim_level = round(kwargs.get(ATTR_BRIGHTNESS, 255) / 255.0, 2)
|
|
|
|
if ATTR_BRIGHTNESS not in kwargs:
|
|
# If no brightness is set, use the current brightness
|
|
dim_level = channel.dimLevel or 1.0
|
|
|
|
# Use dim-only method for monochrome mode (hue/saturation not supported)
|
|
if not self._supports_color():
|
|
await channel.set_dim_level_async(dim_level=dim_level)
|
|
return
|
|
|
|
# Full color mode with hue/saturation
|
|
if ATTR_HS_COLOR in kwargs:
|
|
hs_color = kwargs[ATTR_HS_COLOR]
|
|
hue = hs_color[0] % 360.0
|
|
saturation = hs_color[1] / 100.0
|
|
else:
|
|
hue = channel.hue
|
|
saturation = channel.saturationLevel
|
|
|
|
await channel.set_hue_saturation_dim_level_async(
|
|
hue=hue, saturation_level=saturation, dim_level=dim_level
|
|
)
|
|
|
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
|
"""Turn the light off."""
|
|
channel = self.get_channel_or_raise()
|
|
await channel.set_switch_state_async(on=False)
|
|
|
|
|
|
class HomematicipLightMeasuring(HomematicipLight):
|
|
"""Representation of the HomematicIP measuring light."""
|
|
|
|
|
|
class HomematicipMultiDimmer(HomematicipGenericEntity, LightEntity):
|
|
"""Representation of HomematicIP Cloud dimmer."""
|
|
|
|
_attr_color_mode = ColorMode.BRIGHTNESS
|
|
_attr_supported_color_modes = {ColorMode.BRIGHTNESS}
|
|
|
|
def __init__(
|
|
self,
|
|
hap: HomematicipHAP,
|
|
device,
|
|
channel=1,
|
|
is_multi_channel=True,
|
|
) -> None:
|
|
"""Initialize the dimmer light entity."""
|
|
super().__init__(
|
|
hap, device, channel=channel, is_multi_channel=is_multi_channel
|
|
)
|
|
|
|
@property
|
|
def is_on(self) -> bool:
|
|
"""Return true if dimmer is on."""
|
|
func_channel = self._device.functionalChannels[self._channel]
|
|
return func_channel.dimLevel is not None and func_channel.dimLevel > 0.0
|
|
|
|
@property
|
|
def brightness(self) -> int:
|
|
"""Return the brightness of this light between 0..255."""
|
|
return int(
|
|
(self._device.functionalChannels[self._channel].dimLevel or 0.0) * 255
|
|
)
|
|
|
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
|
"""Turn the dimmer on."""
|
|
if ATTR_BRIGHTNESS in kwargs:
|
|
await self._device.set_dim_level_async(
|
|
kwargs[ATTR_BRIGHTNESS] / 255.0, self._channel
|
|
)
|
|
else:
|
|
await self._device.set_dim_level_async(1, self._channel)
|
|
|
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
|
"""Turn the dimmer off."""
|
|
await self._device.set_dim_level_async(0, self._channel)
|
|
|
|
|
|
class HomematicipDimmer(HomematicipMultiDimmer, LightEntity):
|
|
"""Representation of HomematicIP Cloud dimmer."""
|
|
|
|
def __init__(self, hap: HomematicipHAP, device) -> None:
|
|
"""Initialize the dimmer light entity."""
|
|
super().__init__(hap, device, is_multi_channel=False)
|
|
|
|
|
|
class HomematicipNotificationLight(HomematicipGenericEntity, LightEntity):
|
|
"""Representation of HomematicIP Cloud notification light."""
|
|
|
|
_attr_color_mode = ColorMode.HS
|
|
_attr_supported_color_modes = {ColorMode.HS}
|
|
_attr_supported_features = LightEntityFeature.TRANSITION
|
|
|
|
def __init__(self, hap: HomematicipHAP, device, channel: int, post: str) -> None:
|
|
"""Initialize the notification light entity."""
|
|
super().__init__(hap, device, post=post, channel=channel, is_multi_channel=True)
|
|
|
|
self._color_switcher: dict[str, tuple[float, float]] = {
|
|
RGBColorState.WHITE: (0.0, 0.0),
|
|
RGBColorState.RED: (0.0, 100.0),
|
|
RGBColorState.YELLOW: (60.0, 100.0),
|
|
RGBColorState.GREEN: (120.0, 100.0),
|
|
RGBColorState.TURQUOISE: (180.0, 100.0),
|
|
RGBColorState.BLUE: (240.0, 100.0),
|
|
RGBColorState.PURPLE: (300.0, 100.0),
|
|
}
|
|
|
|
@property
|
|
def _func_channel(self) -> NotificationLightChannel:
|
|
return self._device.functionalChannels[self._channel]
|
|
|
|
@property
|
|
def is_on(self) -> bool:
|
|
"""Return true if light is on."""
|
|
return (
|
|
self._func_channel.dimLevel is not None
|
|
and self._func_channel.dimLevel > 0.0
|
|
)
|
|
|
|
@property
|
|
def brightness(self) -> int:
|
|
"""Return the brightness of this light between 0..255."""
|
|
return int((self._func_channel.dimLevel or 0.0) * 255)
|
|
|
|
@property
|
|
def hs_color(self) -> tuple[float, float]:
|
|
"""Return the hue and saturation color value [float, float]."""
|
|
simple_rgb_color = self._func_channel.simpleRGBColorState
|
|
return self._color_switcher.get(simple_rgb_color, (0.0, 0.0))
|
|
|
|
@property
|
|
def extra_state_attributes(self) -> dict[str, Any]:
|
|
"""Return the state attributes of the notification light sensor."""
|
|
state_attr = super().extra_state_attributes
|
|
|
|
if self.is_on:
|
|
state_attr[ATTR_COLOR_NAME] = self._func_channel.simpleRGBColorState
|
|
|
|
return state_attr
|
|
|
|
@property
|
|
def unique_id(self) -> str:
|
|
"""Return a unique ID."""
|
|
return f"{self.__class__.__name__}_{self._post}_{self._device.id}"
|
|
|
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
|
"""Turn the light on."""
|
|
# Use hs_color from kwargs,
|
|
# if not applicable use current hs_color.
|
|
hs_color = kwargs.get(ATTR_HS_COLOR, self.hs_color)
|
|
simple_rgb_color = _convert_color(hs_color)
|
|
|
|
# Use brightness from kwargs,
|
|
# if not applicable use current brightness.
|
|
brightness = kwargs.get(ATTR_BRIGHTNESS, self.brightness)
|
|
|
|
# If no kwargs, use default value.
|
|
if not kwargs:
|
|
brightness = 255
|
|
|
|
# Minimum brightness is 10, otherwise the led is disabled
|
|
brightness = max(10, brightness)
|
|
dim_level = brightness / 255.0
|
|
transition = kwargs.get(ATTR_TRANSITION, 0.5)
|
|
|
|
await self._device.set_rgb_dim_level_with_time_async(
|
|
channelIndex=self._channel,
|
|
rgb=simple_rgb_color,
|
|
dimLevel=dim_level,
|
|
onTime=0,
|
|
rampTime=transition,
|
|
)
|
|
|
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
|
"""Turn the light off."""
|
|
simple_rgb_color = self._func_channel.simpleRGBColorState
|
|
transition = kwargs.get(ATTR_TRANSITION, 0.5)
|
|
|
|
await self._device.set_rgb_dim_level_with_time_async(
|
|
channelIndex=self._channel,
|
|
rgb=simple_rgb_color,
|
|
dimLevel=0.0,
|
|
onTime=0,
|
|
rampTime=transition,
|
|
)
|
|
|
|
|
|
class HomematicipNotificationLightV2(HomematicipNotificationLight, LightEntity):
|
|
"""Representation of HomematicIP Cloud notification light."""
|
|
|
|
_effect_list = [
|
|
OpticalSignalBehaviour.BILLOW_MIDDLE,
|
|
OpticalSignalBehaviour.BLINKING_MIDDLE,
|
|
OpticalSignalBehaviour.FLASH_MIDDLE,
|
|
OpticalSignalBehaviour.OFF,
|
|
OpticalSignalBehaviour.ON,
|
|
]
|
|
|
|
def __init__(self, hap: HomematicipHAP, device, channel: int, post: str) -> None:
|
|
"""Initialize the notification light entity."""
|
|
super().__init__(hap, device, post=post, channel=channel)
|
|
self._attr_supported_features |= LightEntityFeature.EFFECT
|
|
|
|
@property
|
|
def effect_list(self) -> list[str] | None:
|
|
"""Return the list of supported effects."""
|
|
return self._effect_list
|
|
|
|
@property
|
|
def effect(self) -> str | None:
|
|
"""Return the current effect."""
|
|
return self._func_channel.opticalSignalBehaviour
|
|
|
|
@property
|
|
def is_on(self) -> bool:
|
|
"""Return true if light is on."""
|
|
return self._func_channel.on
|
|
|
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
|
"""Turn the light on."""
|
|
# Use hs_color from kwargs,
|
|
# if not applicable use current hs_color.
|
|
hs_color = kwargs.get(ATTR_HS_COLOR, self.hs_color)
|
|
simple_rgb_color = _convert_color(hs_color)
|
|
|
|
# If no kwargs, use default value.
|
|
brightness = 255
|
|
if ATTR_BRIGHTNESS in kwargs:
|
|
brightness = kwargs[ATTR_BRIGHTNESS]
|
|
|
|
# Minimum brightness is 10, otherwise the led is disabled
|
|
brightness = max(10, brightness)
|
|
dim_level = round(brightness / 255.0, 2)
|
|
|
|
effect = self.effect
|
|
if ATTR_EFFECT in kwargs:
|
|
effect = kwargs[ATTR_EFFECT]
|
|
|
|
await self._func_channel.async_set_optical_signal(
|
|
opticalSignalBehaviour=effect, rgb=simple_rgb_color, dimLevel=dim_level
|
|
)
|
|
|
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
|
"""Turn the light off."""
|
|
await self._func_channel.async_turn_off()
|
|
|
|
|
|
def _convert_color(color: tuple) -> RGBColorState:
|
|
"""Convert the given color to the reduced RGBColorState color.
|
|
|
|
RGBColorStat contains only 8 colors including white and black,
|
|
so a conversion is required.
|
|
"""
|
|
if color is None:
|
|
return RGBColorState.WHITE
|
|
|
|
hue = int(color[0])
|
|
saturation = int(color[1])
|
|
if saturation < 5:
|
|
return RGBColorState.WHITE
|
|
if 30 < hue <= 90:
|
|
return RGBColorState.YELLOW
|
|
if 90 < hue <= 160:
|
|
return RGBColorState.GREEN
|
|
if 150 < hue <= 210:
|
|
return RGBColorState.TURQUOISE
|
|
if 210 < hue <= 270:
|
|
return RGBColorState.BLUE
|
|
if 270 < hue <= 330:
|
|
return RGBColorState.PURPLE
|
|
return RGBColorState.RED
|
|
|
|
|
|
class HomematicipOpticalSignalLight(HomematicipGenericEntity, LightEntity):
|
|
"""Representation of HomematicIP WiredPushButton LED light."""
|
|
|
|
_attr_color_mode = ColorMode.HS
|
|
_attr_supported_color_modes = {ColorMode.HS}
|
|
_attr_supported_features = LightEntityFeature.EFFECT
|
|
_attr_translation_key = "optical_signal_light"
|
|
|
|
_effect_to_behaviour: dict[str, OpticalSignalBehaviour] = {
|
|
"on": OpticalSignalBehaviour.ON,
|
|
"blinking": OpticalSignalBehaviour.BLINKING_MIDDLE,
|
|
"flash": OpticalSignalBehaviour.FLASH_MIDDLE,
|
|
"billow": OpticalSignalBehaviour.BILLOW_MIDDLE,
|
|
}
|
|
_behaviour_to_effect: dict[OpticalSignalBehaviour, str] = {
|
|
v: k for k, v in _effect_to_behaviour.items()
|
|
}
|
|
|
|
_attr_effect_list = list(_effect_to_behaviour)
|
|
|
|
_color_switcher: dict[str, tuple[float, float]] = {
|
|
RGBColorState.WHITE: (0.0, 0.0),
|
|
RGBColorState.RED: (0.0, 100.0),
|
|
RGBColorState.YELLOW: (60.0, 100.0),
|
|
RGBColorState.GREEN: (120.0, 100.0),
|
|
RGBColorState.TURQUOISE: (180.0, 100.0),
|
|
RGBColorState.BLUE: (240.0, 100.0),
|
|
RGBColorState.PURPLE: (300.0, 100.0),
|
|
}
|
|
|
|
def __init__(
|
|
self,
|
|
hap: HomematicipHAP,
|
|
device: WiredPushButton,
|
|
channel_index: int,
|
|
led_number: int,
|
|
) -> None:
|
|
"""Initialize the optical signal light entity."""
|
|
super().__init__(
|
|
hap,
|
|
device,
|
|
post=f"LED {led_number}",
|
|
channel=channel_index,
|
|
is_multi_channel=True,
|
|
channel_real_index=channel_index,
|
|
)
|
|
|
|
@property
|
|
def is_on(self) -> bool:
|
|
"""Return true if light is on."""
|
|
channel = self.get_channel_or_raise()
|
|
return channel.on is True
|
|
|
|
@property
|
|
def brightness(self) -> int:
|
|
"""Return the brightness of this light between 0..255."""
|
|
channel = self.get_channel_or_raise()
|
|
return int((channel.dimLevel or 0.0) * 255)
|
|
|
|
@property
|
|
def hs_color(self) -> tuple[float, float]:
|
|
"""Return the hue and saturation color value [float, float]."""
|
|
channel = self.get_channel_or_raise()
|
|
simple_rgb_color = channel.simpleRGBColorState
|
|
return self._color_switcher.get(simple_rgb_color, (0.0, 0.0))
|
|
|
|
@property
|
|
def effect(self) -> str | None:
|
|
"""Return the current effect."""
|
|
channel = self.get_channel_or_raise()
|
|
return self._behaviour_to_effect.get(channel.opticalSignalBehaviour)
|
|
|
|
@property
|
|
def extra_state_attributes(self) -> dict[str, Any]:
|
|
"""Return the state attributes of the optical signal light."""
|
|
state_attr = super().extra_state_attributes
|
|
channel = self.get_channel_or_raise()
|
|
|
|
if self.is_on:
|
|
state_attr[ATTR_COLOR_NAME] = channel.simpleRGBColorState
|
|
|
|
return state_attr
|
|
|
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
|
"""Turn the light on."""
|
|
# Use hs_color from kwargs, if not applicable use current hs_color.
|
|
hs_color = kwargs.get(ATTR_HS_COLOR, self.hs_color)
|
|
simple_rgb_color = _convert_color(hs_color)
|
|
|
|
# If no kwargs, use default value.
|
|
brightness = 255
|
|
if ATTR_BRIGHTNESS in kwargs:
|
|
brightness = kwargs[ATTR_BRIGHTNESS]
|
|
|
|
# Minimum brightness is 10, otherwise the LED is disabled
|
|
brightness = max(10, brightness)
|
|
dim_level = round(brightness / 255.0, 2)
|
|
|
|
effect = self.effect
|
|
if ATTR_EFFECT in kwargs:
|
|
effect = kwargs[ATTR_EFFECT]
|
|
elif effect is None:
|
|
effect = "on"
|
|
|
|
behaviour = self._effect_to_behaviour.get(effect, OpticalSignalBehaviour.ON)
|
|
|
|
await self._device.set_optical_signal_async(
|
|
channelIndex=self._channel,
|
|
opticalSignalBehaviour=behaviour,
|
|
rgb=simple_rgb_color,
|
|
dimLevel=dim_level,
|
|
)
|
|
|
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
|
"""Turn the light off."""
|
|
channel = self.get_channel_or_raise()
|
|
simple_rgb_color = channel.simpleRGBColorState
|
|
|
|
await self._device.set_optical_signal_async(
|
|
channelIndex=self._channel,
|
|
opticalSignalBehaviour=OpticalSignalBehaviour.OFF,
|
|
rgb=simple_rgb_color,
|
|
dimLevel=0.0,
|
|
)
|
|
|
|
|
|
class HomematicipCombinationSignallingLight(HomematicipGenericEntity, LightEntity):
|
|
"""Representation of the HomematicIP combination signalling device light (HmIP-MP3P)."""
|
|
|
|
_attr_color_mode = ColorMode.HS
|
|
_attr_supported_color_modes = {ColorMode.HS}
|
|
|
|
_color_switcher: dict[str, tuple[float, float]] = {
|
|
RGBColorState.WHITE: (0.0, 0.0),
|
|
RGBColorState.RED: (0.0, 100.0),
|
|
RGBColorState.YELLOW: (60.0, 100.0),
|
|
RGBColorState.GREEN: (120.0, 100.0),
|
|
RGBColorState.TURQUOISE: (180.0, 100.0),
|
|
RGBColorState.BLUE: (240.0, 100.0),
|
|
RGBColorState.PURPLE: (300.0, 100.0),
|
|
}
|
|
|
|
def __init__(
|
|
self, hap: HomematicipHAP, device: CombinationSignallingDevice
|
|
) -> None:
|
|
"""Initialize the combination signalling light entity."""
|
|
super().__init__(hap, device, channel=1, is_multi_channel=False)
|
|
|
|
@property
|
|
def _func_channel(self) -> NotificationMp3SoundChannel:
|
|
return self._device.functionalChannels[self._channel]
|
|
|
|
@property
|
|
def is_on(self) -> bool:
|
|
"""Return true if light is on."""
|
|
return self._func_channel.on
|
|
|
|
@property
|
|
def brightness(self) -> int:
|
|
"""Return the brightness of this light between 0..255."""
|
|
return int((self._func_channel.dimLevel or 0.0) * 255)
|
|
|
|
@property
|
|
def hs_color(self) -> tuple[float, float]:
|
|
"""Return the hue and saturation color value [float, float]."""
|
|
simple_rgb_color = self._func_channel.simpleRGBColorState
|
|
return self._color_switcher.get(simple_rgb_color, (0.0, 0.0))
|
|
|
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
|
"""Turn the light on."""
|
|
hs_color = kwargs.get(ATTR_HS_COLOR, self.hs_color)
|
|
simple_rgb_color = _convert_color(hs_color)
|
|
|
|
brightness = kwargs.get(ATTR_BRIGHTNESS, self.brightness)
|
|
|
|
# Default to full brightness when no kwargs given
|
|
if not kwargs:
|
|
brightness = 255
|
|
|
|
# Minimum brightness is 10, otherwise the LED is disabled
|
|
brightness = max(10, brightness)
|
|
dim_level = brightness / 255.0
|
|
|
|
await self._func_channel.set_rgb_dim_level_async(
|
|
rgb_color_state=simple_rgb_color.name,
|
|
dim_level=dim_level,
|
|
)
|
|
|
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
|
"""Turn the light off."""
|
|
await self._func_channel.turn_off_async()
|