KNX: Support for XY-color lights (#51306)
* support for xy-color * replace invalid namepull/51324/head
parent
164e45f0a7
commit
549b0b0727
|
@ -4,7 +4,7 @@ from __future__ import annotations
|
|||
from typing import Any, Tuple, cast
|
||||
|
||||
from xknx import XKNX
|
||||
from xknx.devices import Light as XknxLight
|
||||
from xknx.devices.light import Light as XknxLight, XYYColor
|
||||
from xknx.telegram.address import parse_device_group_address
|
||||
|
||||
from homeassistant.components.light import (
|
||||
|
@ -12,11 +12,13 @@ from homeassistant.components.light import (
|
|||
ATTR_COLOR_TEMP,
|
||||
ATTR_RGB_COLOR,
|
||||
ATTR_RGBW_COLOR,
|
||||
ATTR_XY_COLOR,
|
||||
COLOR_MODE_BRIGHTNESS,
|
||||
COLOR_MODE_COLOR_TEMP,
|
||||
COLOR_MODE_ONOFF,
|
||||
COLOR_MODE_RGB,
|
||||
COLOR_MODE_RGBW,
|
||||
COLOR_MODE_XY,
|
||||
LightEntity,
|
||||
)
|
||||
from homeassistant.const import CONF_NAME
|
||||
|
@ -159,6 +161,8 @@ def _create_light(xknx: XKNX, config: ConfigType) -> XknxLight:
|
|||
group_address_color_state=config.get(LightSchema.CONF_COLOR_STATE_ADDRESS),
|
||||
group_address_rgbw=config.get(LightSchema.CONF_RGBW_ADDRESS),
|
||||
group_address_rgbw_state=config.get(LightSchema.CONF_RGBW_STATE_ADDRESS),
|
||||
group_address_xyy_color=config.get(LightSchema.CONF_XYY_ADDRESS),
|
||||
group_address_xyy_color_state=config.get(LightSchema.CONF_XYY_STATE_ADDRESS),
|
||||
group_address_tunable_white=group_address_tunable_white,
|
||||
group_address_tunable_white_state=group_address_tunable_white_state,
|
||||
group_address_color_temperature=group_address_color_temp,
|
||||
|
@ -253,6 +257,9 @@ class KNXLight(KnxEntity, LightEntity):
|
|||
"""Return the brightness of this light between 0..255."""
|
||||
if self._device.supports_brightness:
|
||||
return self._device.current_brightness
|
||||
if self._device.current_xyy_color is not None:
|
||||
_, brightness = self._device.current_xyy_color
|
||||
return brightness
|
||||
if (rgb := self.rgb_color) is not None:
|
||||
return max(rgb)
|
||||
return None
|
||||
|
@ -277,6 +284,14 @@ class KNXLight(KnxEntity, LightEntity):
|
|||
return (*rgb, white)
|
||||
return None
|
||||
|
||||
@property
|
||||
def xy_color(self) -> tuple[float, float] | None:
|
||||
"""Return the xy color value [float, float]."""
|
||||
if self._device.current_xyy_color is not None:
|
||||
xy_color, _ = self._device.current_xyy_color
|
||||
return xy_color
|
||||
return None
|
||||
|
||||
@property
|
||||
def color_temp(self) -> int | None:
|
||||
"""Return the color temperature in mireds."""
|
||||
|
@ -309,6 +324,8 @@ class KNXLight(KnxEntity, LightEntity):
|
|||
@property
|
||||
def color_mode(self) -> str | None:
|
||||
"""Return the color mode of the light."""
|
||||
if self._device.supports_xyy_color:
|
||||
return COLOR_MODE_XY
|
||||
if self._device.supports_rgbw:
|
||||
return COLOR_MODE_RGBW
|
||||
if self._device.supports_color:
|
||||
|
@ -329,22 +346,11 @@ class KNXLight(KnxEntity, LightEntity):
|
|||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the light on."""
|
||||
# ignore arguments if not supported to fall back to set_on()
|
||||
brightness = (
|
||||
kwargs.get(ATTR_BRIGHTNESS)
|
||||
if self._device.supports_brightness
|
||||
or self.color_mode in (COLOR_MODE_RGB, COLOR_MODE_RGBW)
|
||||
else None
|
||||
)
|
||||
mireds = (
|
||||
kwargs.get(ATTR_COLOR_TEMP)
|
||||
if self.color_mode == COLOR_MODE_COLOR_TEMP
|
||||
else None
|
||||
)
|
||||
rgb = kwargs.get(ATTR_RGB_COLOR) if self.color_mode == COLOR_MODE_RGB else None
|
||||
rgbw = (
|
||||
kwargs.get(ATTR_RGBW_COLOR) if self.color_mode == COLOR_MODE_RGBW else None
|
||||
)
|
||||
brightness = kwargs.get(ATTR_BRIGHTNESS)
|
||||
mireds = kwargs.get(ATTR_COLOR_TEMP)
|
||||
rgb = kwargs.get(ATTR_RGB_COLOR)
|
||||
rgbw = kwargs.get(ATTR_RGBW_COLOR)
|
||||
xy_color = kwargs.get(ATTR_XY_COLOR)
|
||||
|
||||
if (
|
||||
not self.is_on
|
||||
|
@ -352,6 +358,7 @@ class KNXLight(KnxEntity, LightEntity):
|
|||
and mireds is None
|
||||
and rgb is None
|
||||
and rgbw is None
|
||||
and xy_color is None
|
||||
):
|
||||
await self._device.set_on()
|
||||
return
|
||||
|
@ -394,12 +401,22 @@ class KNXLight(KnxEntity, LightEntity):
|
|||
)
|
||||
await self._device.set_tunable_white(relative_ct)
|
||||
|
||||
if xy_color is not None:
|
||||
await self._device.set_xyy_color(
|
||||
XYYColor(color=xy_color, brightness=brightness)
|
||||
)
|
||||
return
|
||||
|
||||
if brightness is not None:
|
||||
# brightness: 1..255; 0 brightness will call async_turn_off()
|
||||
if self._device.brightness.writable:
|
||||
await self._device.set_brightness(brightness)
|
||||
return
|
||||
# brightness without color in kwargs; set via color - default to white
|
||||
# brightness without color in kwargs; set via color
|
||||
if self.color_mode == COLOR_MODE_XY:
|
||||
await self._device.set_xyy_color(XYYColor(brightness=brightness))
|
||||
return
|
||||
# default to white if color not known for RGB(W)
|
||||
if self.color_mode == COLOR_MODE_RGBW:
|
||||
rgbw = self.rgbw_color
|
||||
if not rgbw or not any(rgbw):
|
||||
|
|
|
@ -421,6 +421,8 @@ class LightSchema(KNXPlatformSchema):
|
|||
CONF_COLOR_TEMP_MODE = "color_temperature_mode"
|
||||
CONF_RGBW_ADDRESS = "rgbw_address"
|
||||
CONF_RGBW_STATE_ADDRESS = "rgbw_state_address"
|
||||
CONF_XYY_ADDRESS = "xyy_address"
|
||||
CONF_XYY_STATE_ADDRESS = "xyy_state_address"
|
||||
CONF_MIN_KELVIN = "min_kelvin"
|
||||
CONF_MAX_KELVIN = "max_kelvin"
|
||||
|
||||
|
@ -479,6 +481,8 @@ class LightSchema(KNXPlatformSchema):
|
|||
): vol.All(vol.Upper, cv.enum(ColorTempModes)),
|
||||
vol.Exclusive(CONF_RGBW_ADDRESS, "color"): ga_list_validator,
|
||||
vol.Optional(CONF_RGBW_STATE_ADDRESS): ga_list_validator,
|
||||
vol.Exclusive(CONF_XYY_ADDRESS, "color"): ga_list_validator,
|
||||
vol.Optional(CONF_XYY_STATE_ADDRESS): ga_list_validator,
|
||||
vol.Optional(CONF_MIN_KELVIN, default=DEFAULT_MIN_KELVIN): vol.All(
|
||||
vol.Coerce(int), vol.Range(min=1)
|
||||
),
|
||||
|
|
Loading…
Reference in New Issue