KNX: Support for XY-color lights (#51306)

* support for xy-color

* replace invalid name
pull/51324/head
Matthias Alphart 2021-06-01 08:59:51 +02:00 committed by GitHub
parent 164e45f0a7
commit 549b0b0727
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 18 deletions

View File

@ -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):

View File

@ -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)
),