1
mirror of https://github.com/home-assistant/core synced 2024-08-02 23:40:32 +02:00

KNX: Support for HS-color lights (#53538)

This commit is contained in:
Matthias Alphart 2021-07-27 19:36:46 +02:00 committed by GitHub
parent ce663f629c
commit 27d42e0cd8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 10 deletions

View File

@ -10,11 +10,13 @@ from xknx.telegram.address import parse_device_group_address
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
ATTR_COLOR_TEMP,
ATTR_HS_COLOR,
ATTR_RGB_COLOR,
ATTR_RGBW_COLOR,
ATTR_XY_COLOR,
COLOR_MODE_BRIGHTNESS,
COLOR_MODE_COLOR_TEMP,
COLOR_MODE_HS,
COLOR_MODE_ONOFF,
COLOR_MODE_RGB,
COLOR_MODE_RGBW,
@ -158,6 +160,12 @@ 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_hue=config.get(LightSchema.CONF_HUE_ADDRESS),
group_address_hue_state=config.get(LightSchema.CONF_HUE_STATE_ADDRESS),
group_address_saturation=config.get(LightSchema.CONF_SATURATION_ADDRESS),
group_address_saturation_state=config.get(
LightSchema.CONF_SATURATION_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,
@ -283,6 +291,13 @@ class KNXLight(KnxEntity, LightEntity):
return (*rgb, white)
return None
@property
def hs_color(self) -> tuple[float, float] | None:
"""Return the hue and saturation color value [float, float]."""
# Hue is scaled 0..360 int encoded in 1 byte in KNX (-> only 256 possible values)
# Saturation is scaled 0..100 int
return self._device.current_hs_color
@property
def xy_color(self) -> tuple[float, float] | None:
"""Return the xy color value [float, float]."""
@ -315,6 +330,8 @@ class KNXLight(KnxEntity, LightEntity):
"""Return the color mode of the light."""
if self._device.supports_xyy_color:
return COLOR_MODE_XY
if self._device.supports_hs_color:
return COLOR_MODE_HS
if self._device.supports_rgbw:
return COLOR_MODE_RGBW
if self._device.supports_color:
@ -339,6 +356,7 @@ class KNXLight(KnxEntity, LightEntity):
mireds = kwargs.get(ATTR_COLOR_TEMP)
rgb = kwargs.get(ATTR_RGB_COLOR)
rgbw = kwargs.get(ATTR_RGBW_COLOR)
hs_color = kwargs.get(ATTR_HS_COLOR)
xy_color = kwargs.get(ATTR_XY_COLOR)
if (
@ -347,6 +365,7 @@ class KNXLight(KnxEntity, LightEntity):
and mireds is None
and rgb is None
and rgbw is None
and hs_color is None
and xy_color is None
):
await self._device.set_on()
@ -396,6 +415,12 @@ class KNXLight(KnxEntity, LightEntity):
)
return
if hs_color is not None:
# round so only one telegram will be sent if the other matches state
hue = round(hs_color[0])
sat = round(hs_color[1])
await self._device.set_hs_color((hue, sat))
if brightness is not None:
# brightness: 1..255; 0 brightness will call async_turn_off()
if self._device.brightness.writable:

View File

@ -496,8 +496,12 @@ class LightSchema(KNXPlatformSchema):
CONF_COLOR_TEMP_ADDRESS = "color_temperature_address"
CONF_COLOR_TEMP_STATE_ADDRESS = "color_temperature_state_address"
CONF_COLOR_TEMP_MODE = "color_temperature_mode"
CONF_HUE_ADDRESS = "hue_address"
CONF_HUE_STATE_ADDRESS = "hue_state_address"
CONF_RGBW_ADDRESS = "rgbw_address"
CONF_RGBW_STATE_ADDRESS = "rgbw_state_address"
CONF_SATURATION_ADDRESS = "saturation_address"
CONF_SATURATION_STATE_ADDRESS = "saturation_state_address"
CONF_XYY_ADDRESS = "xyy_address"
CONF_XYY_STATE_ADDRESS = "xyy_state_address"
CONF_MIN_KELVIN = "min_kelvin"
@ -514,7 +518,18 @@ class LightSchema(KNXPlatformSchema):
CONF_BLUE = "blue"
CONF_WHITE = "white"
COLOR_SCHEMA = vol.Schema(
_hs_color_inclusion_msg = (
"'hue_address', 'saturation_address' and 'brightness_address'"
" are required for hs_color configuration"
)
HS_COLOR_SCHEMA = {
vol.Optional(CONF_HUE_ADDRESS): ga_list_validator,
vol.Optional(CONF_HUE_STATE_ADDRESS): ga_list_validator,
vol.Optional(CONF_SATURATION_ADDRESS): ga_list_validator,
vol.Optional(CONF_SATURATION_STATE_ADDRESS): ga_list_validator,
}
INDIVIDUAL_COLOR_SCHEMA = vol.Schema(
{
vol.Optional(KNX_ADDRESS): ga_list_validator,
vol.Optional(CONF_STATE_ADDRESS): ga_list_validator,
@ -536,18 +551,18 @@ class LightSchema(KNXPlatformSchema):
CONF_RED,
"individual_colors",
msg="'red', 'green' and 'blue' are required for individual colors configuration",
): COLOR_SCHEMA,
): INDIVIDUAL_COLOR_SCHEMA,
vol.Inclusive(
CONF_GREEN,
"individual_colors",
msg="'red', 'green' and 'blue' are required for individual colors configuration",
): COLOR_SCHEMA,
): INDIVIDUAL_COLOR_SCHEMA,
vol.Inclusive(
CONF_BLUE,
"individual_colors",
msg="'red', 'green' and 'blue' are required for individual colors configuration",
): COLOR_SCHEMA,
vol.Optional(CONF_WHITE): COLOR_SCHEMA,
): INDIVIDUAL_COLOR_SCHEMA,
vol.Optional(CONF_WHITE): INDIVIDUAL_COLOR_SCHEMA,
},
vol.Exclusive(CONF_COLOR_ADDRESS, "color"): ga_list_validator,
vol.Optional(CONF_COLOR_STATE_ADDRESS): ga_list_validator,
@ -556,6 +571,7 @@ class LightSchema(KNXPlatformSchema):
vol.Optional(
CONF_COLOR_TEMP_MODE, default=DEFAULT_COLOR_TEMP_MODE
): vol.All(vol.Upper, cv.enum(ColorTempModes)),
**HS_COLOR_SCHEMA,
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,
@ -569,20 +585,39 @@ class LightSchema(KNXPlatformSchema):
}
),
vol.Any(
# either global "address" or "individual_colors" is required
vol.Schema(
{vol.Required(KNX_ADDRESS): object},
extra=vol.ALLOW_EXTRA,
),
vol.Schema( # brightness addresses are required in INDIVIDUAL_COLOR_SCHEMA
{vol.Required(CONF_INDIVIDUAL_COLORS): object},
extra=vol.ALLOW_EXTRA,
),
msg="either 'address' or 'individual_colors' is required",
),
vol.Any(
vol.Schema( # 'brightness' is non-optional for hs-color
{
# brightness addresses are required in COLOR_SCHEMA
vol.Required(CONF_INDIVIDUAL_COLORS): object,
vol.Inclusive(
CONF_BRIGHTNESS_ADDRESS, "hs_color", msg=_hs_color_inclusion_msg
): object,
vol.Inclusive(
CONF_HUE_ADDRESS, "hs_color", msg=_hs_color_inclusion_msg
): object,
vol.Inclusive(
CONF_SATURATION_ADDRESS, "hs_color", msg=_hs_color_inclusion_msg
): object,
},
extra=vol.ALLOW_EXTRA,
),
vol.Schema(
vol.Schema( # hs-colors not used
{
vol.Required(KNX_ADDRESS): object,
vol.Optional(CONF_HUE_ADDRESS): None,
vol.Optional(CONF_SATURATION_ADDRESS): None,
},
extra=vol.ALLOW_EXTRA,
),
msg=_hs_color_inclusion_msg,
),
)