mirror of
https://github.com/home-assistant/core.git
synced 2025-07-28 07:37:34 +00:00
KNX: Support for HS-color lights (#53538)
This commit is contained in:
parent
ce663f629c
commit
27d42e0cd8
@ -10,11 +10,13 @@ from xknx.telegram.address import parse_device_group_address
|
|||||||
from homeassistant.components.light import (
|
from homeassistant.components.light import (
|
||||||
ATTR_BRIGHTNESS,
|
ATTR_BRIGHTNESS,
|
||||||
ATTR_COLOR_TEMP,
|
ATTR_COLOR_TEMP,
|
||||||
|
ATTR_HS_COLOR,
|
||||||
ATTR_RGB_COLOR,
|
ATTR_RGB_COLOR,
|
||||||
ATTR_RGBW_COLOR,
|
ATTR_RGBW_COLOR,
|
||||||
ATTR_XY_COLOR,
|
ATTR_XY_COLOR,
|
||||||
COLOR_MODE_BRIGHTNESS,
|
COLOR_MODE_BRIGHTNESS,
|
||||||
COLOR_MODE_COLOR_TEMP,
|
COLOR_MODE_COLOR_TEMP,
|
||||||
|
COLOR_MODE_HS,
|
||||||
COLOR_MODE_ONOFF,
|
COLOR_MODE_ONOFF,
|
||||||
COLOR_MODE_RGB,
|
COLOR_MODE_RGB,
|
||||||
COLOR_MODE_RGBW,
|
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_color_state=config.get(LightSchema.CONF_COLOR_STATE_ADDRESS),
|
||||||
group_address_rgbw=config.get(LightSchema.CONF_RGBW_ADDRESS),
|
group_address_rgbw=config.get(LightSchema.CONF_RGBW_ADDRESS),
|
||||||
group_address_rgbw_state=config.get(LightSchema.CONF_RGBW_STATE_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=config.get(LightSchema.CONF_XYY_ADDRESS),
|
||||||
group_address_xyy_color_state=config.get(LightSchema.CONF_XYY_STATE_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=group_address_tunable_white,
|
||||||
@ -283,6 +291,13 @@ class KNXLight(KnxEntity, LightEntity):
|
|||||||
return (*rgb, white)
|
return (*rgb, white)
|
||||||
return None
|
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
|
@property
|
||||||
def xy_color(self) -> tuple[float, float] | None:
|
def xy_color(self) -> tuple[float, float] | None:
|
||||||
"""Return the xy color value [float, float]."""
|
"""Return the xy color value [float, float]."""
|
||||||
@ -315,6 +330,8 @@ class KNXLight(KnxEntity, LightEntity):
|
|||||||
"""Return the color mode of the light."""
|
"""Return the color mode of the light."""
|
||||||
if self._device.supports_xyy_color:
|
if self._device.supports_xyy_color:
|
||||||
return COLOR_MODE_XY
|
return COLOR_MODE_XY
|
||||||
|
if self._device.supports_hs_color:
|
||||||
|
return COLOR_MODE_HS
|
||||||
if self._device.supports_rgbw:
|
if self._device.supports_rgbw:
|
||||||
return COLOR_MODE_RGBW
|
return COLOR_MODE_RGBW
|
||||||
if self._device.supports_color:
|
if self._device.supports_color:
|
||||||
@ -339,6 +356,7 @@ class KNXLight(KnxEntity, LightEntity):
|
|||||||
mireds = kwargs.get(ATTR_COLOR_TEMP)
|
mireds = kwargs.get(ATTR_COLOR_TEMP)
|
||||||
rgb = kwargs.get(ATTR_RGB_COLOR)
|
rgb = kwargs.get(ATTR_RGB_COLOR)
|
||||||
rgbw = kwargs.get(ATTR_RGBW_COLOR)
|
rgbw = kwargs.get(ATTR_RGBW_COLOR)
|
||||||
|
hs_color = kwargs.get(ATTR_HS_COLOR)
|
||||||
xy_color = kwargs.get(ATTR_XY_COLOR)
|
xy_color = kwargs.get(ATTR_XY_COLOR)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -347,6 +365,7 @@ class KNXLight(KnxEntity, LightEntity):
|
|||||||
and mireds is None
|
and mireds is None
|
||||||
and rgb is None
|
and rgb is None
|
||||||
and rgbw is None
|
and rgbw is None
|
||||||
|
and hs_color is None
|
||||||
and xy_color is None
|
and xy_color is None
|
||||||
):
|
):
|
||||||
await self._device.set_on()
|
await self._device.set_on()
|
||||||
@ -396,6 +415,12 @@ class KNXLight(KnxEntity, LightEntity):
|
|||||||
)
|
)
|
||||||
return
|
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:
|
if brightness is not None:
|
||||||
# brightness: 1..255; 0 brightness will call async_turn_off()
|
# brightness: 1..255; 0 brightness will call async_turn_off()
|
||||||
if self._device.brightness.writable:
|
if self._device.brightness.writable:
|
||||||
|
@ -496,8 +496,12 @@ class LightSchema(KNXPlatformSchema):
|
|||||||
CONF_COLOR_TEMP_ADDRESS = "color_temperature_address"
|
CONF_COLOR_TEMP_ADDRESS = "color_temperature_address"
|
||||||
CONF_COLOR_TEMP_STATE_ADDRESS = "color_temperature_state_address"
|
CONF_COLOR_TEMP_STATE_ADDRESS = "color_temperature_state_address"
|
||||||
CONF_COLOR_TEMP_MODE = "color_temperature_mode"
|
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_ADDRESS = "rgbw_address"
|
||||||
CONF_RGBW_STATE_ADDRESS = "rgbw_state_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_ADDRESS = "xyy_address"
|
||||||
CONF_XYY_STATE_ADDRESS = "xyy_state_address"
|
CONF_XYY_STATE_ADDRESS = "xyy_state_address"
|
||||||
CONF_MIN_KELVIN = "min_kelvin"
|
CONF_MIN_KELVIN = "min_kelvin"
|
||||||
@ -514,7 +518,18 @@ class LightSchema(KNXPlatformSchema):
|
|||||||
CONF_BLUE = "blue"
|
CONF_BLUE = "blue"
|
||||||
CONF_WHITE = "white"
|
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(KNX_ADDRESS): ga_list_validator,
|
||||||
vol.Optional(CONF_STATE_ADDRESS): ga_list_validator,
|
vol.Optional(CONF_STATE_ADDRESS): ga_list_validator,
|
||||||
@ -536,18 +551,18 @@ class LightSchema(KNXPlatformSchema):
|
|||||||
CONF_RED,
|
CONF_RED,
|
||||||
"individual_colors",
|
"individual_colors",
|
||||||
msg="'red', 'green' and 'blue' are required for individual colors configuration",
|
msg="'red', 'green' and 'blue' are required for individual colors configuration",
|
||||||
): COLOR_SCHEMA,
|
): INDIVIDUAL_COLOR_SCHEMA,
|
||||||
vol.Inclusive(
|
vol.Inclusive(
|
||||||
CONF_GREEN,
|
CONF_GREEN,
|
||||||
"individual_colors",
|
"individual_colors",
|
||||||
msg="'red', 'green' and 'blue' are required for individual colors configuration",
|
msg="'red', 'green' and 'blue' are required for individual colors configuration",
|
||||||
): COLOR_SCHEMA,
|
): INDIVIDUAL_COLOR_SCHEMA,
|
||||||
vol.Inclusive(
|
vol.Inclusive(
|
||||||
CONF_BLUE,
|
CONF_BLUE,
|
||||||
"individual_colors",
|
"individual_colors",
|
||||||
msg="'red', 'green' and 'blue' are required for individual colors configuration",
|
msg="'red', 'green' and 'blue' are required for individual colors configuration",
|
||||||
): COLOR_SCHEMA,
|
): INDIVIDUAL_COLOR_SCHEMA,
|
||||||
vol.Optional(CONF_WHITE): COLOR_SCHEMA,
|
vol.Optional(CONF_WHITE): INDIVIDUAL_COLOR_SCHEMA,
|
||||||
},
|
},
|
||||||
vol.Exclusive(CONF_COLOR_ADDRESS, "color"): ga_list_validator,
|
vol.Exclusive(CONF_COLOR_ADDRESS, "color"): ga_list_validator,
|
||||||
vol.Optional(CONF_COLOR_STATE_ADDRESS): ga_list_validator,
|
vol.Optional(CONF_COLOR_STATE_ADDRESS): ga_list_validator,
|
||||||
@ -556,6 +571,7 @@ class LightSchema(KNXPlatformSchema):
|
|||||||
vol.Optional(
|
vol.Optional(
|
||||||
CONF_COLOR_TEMP_MODE, default=DEFAULT_COLOR_TEMP_MODE
|
CONF_COLOR_TEMP_MODE, default=DEFAULT_COLOR_TEMP_MODE
|
||||||
): vol.All(vol.Upper, cv.enum(ColorTempModes)),
|
): vol.All(vol.Upper, cv.enum(ColorTempModes)),
|
||||||
|
**HS_COLOR_SCHEMA,
|
||||||
vol.Exclusive(CONF_RGBW_ADDRESS, "color"): ga_list_validator,
|
vol.Exclusive(CONF_RGBW_ADDRESS, "color"): ga_list_validator,
|
||||||
vol.Optional(CONF_RGBW_STATE_ADDRESS): ga_list_validator,
|
vol.Optional(CONF_RGBW_STATE_ADDRESS): ga_list_validator,
|
||||||
vol.Exclusive(CONF_XYY_ADDRESS, "color"): ga_list_validator,
|
vol.Exclusive(CONF_XYY_ADDRESS, "color"): ga_list_validator,
|
||||||
@ -569,20 +585,39 @@ class LightSchema(KNXPlatformSchema):
|
|||||||
}
|
}
|
||||||
),
|
),
|
||||||
vol.Any(
|
vol.Any(
|
||||||
# either global "address" or "individual_colors" is required
|
|
||||||
vol.Schema(
|
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.Inclusive(
|
||||||
vol.Required(CONF_INDIVIDUAL_COLORS): object,
|
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,
|
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,
|
extra=vol.ALLOW_EXTRA,
|
||||||
),
|
),
|
||||||
|
msg=_hs_color_inclusion_msg,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user