Create KNX light entities directly from config (#50700)

* create light entities directly from config

* review changes
This commit is contained in:
Matthias Alphart 2021-05-16 22:45:28 +02:00 committed by GitHub
parent 89dd3292ba
commit 05c6f3ca1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 116 additions and 122 deletions

View File

@ -8,7 +8,6 @@ from xknx.devices import (
ClimateMode as XknxClimateMode, ClimateMode as XknxClimateMode,
Cover as XknxCover, Cover as XknxCover,
Device as XknxDevice, Device as XknxDevice,
Light as XknxLight,
Sensor as XknxSensor, Sensor as XknxSensor,
Weather as XknxWeather, Weather as XknxWeather,
) )
@ -16,12 +15,11 @@ from xknx.devices import (
from homeassistant.const import CONF_DEVICE_CLASS, CONF_NAME, CONF_TYPE from homeassistant.const import CONF_DEVICE_CLASS, CONF_NAME, CONF_TYPE
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
from .const import KNX_ADDRESS, ColorTempModes, SupportedPlatforms from .const import SupportedPlatforms
from .schema import ( from .schema import (
BinarySensorSchema, BinarySensorSchema,
ClimateSchema, ClimateSchema,
CoverSchema, CoverSchema,
LightSchema,
SensorSchema, SensorSchema,
WeatherSchema, WeatherSchema,
) )
@ -33,9 +31,6 @@ def create_knx_device(
config: ConfigType, config: ConfigType,
) -> XknxDevice | None: ) -> XknxDevice | None:
"""Return the requested XKNX device.""" """Return the requested XKNX device."""
if platform is SupportedPlatforms.LIGHT:
return _create_light(knx_module, config)
if platform is SupportedPlatforms.COVER: if platform is SupportedPlatforms.COVER:
return _create_cover(knx_module, config) return _create_cover(knx_module, config)
@ -76,108 +71,6 @@ def _create_cover(knx_module: XKNX, config: ConfigType) -> XknxCover:
) )
def _create_light_color(
color: str, config: ConfigType
) -> tuple[str | None, str | None, str | None, str | None]:
"""Load color configuration from configuration structure."""
if "individual_colors" in config and color in config["individual_colors"]:
sub_config = config["individual_colors"][color]
group_address_switch = sub_config.get(KNX_ADDRESS)
group_address_switch_state = sub_config.get(LightSchema.CONF_STATE_ADDRESS)
group_address_brightness = sub_config.get(LightSchema.CONF_BRIGHTNESS_ADDRESS)
group_address_brightness_state = sub_config.get(
LightSchema.CONF_BRIGHTNESS_STATE_ADDRESS
)
return (
group_address_switch,
group_address_switch_state,
group_address_brightness,
group_address_brightness_state,
)
return None, None, None, None
def _create_light(knx_module: XKNX, config: ConfigType) -> XknxLight:
"""Return a KNX Light device to be used within XKNX."""
group_address_tunable_white = None
group_address_tunable_white_state = None
group_address_color_temp = None
group_address_color_temp_state = None
if config[LightSchema.CONF_COLOR_TEMP_MODE] == ColorTempModes.ABSOLUTE:
group_address_color_temp = config.get(LightSchema.CONF_COLOR_TEMP_ADDRESS)
group_address_color_temp_state = config.get(
LightSchema.CONF_COLOR_TEMP_STATE_ADDRESS
)
elif config[LightSchema.CONF_COLOR_TEMP_MODE] == ColorTempModes.RELATIVE:
group_address_tunable_white = config.get(LightSchema.CONF_COLOR_TEMP_ADDRESS)
group_address_tunable_white_state = config.get(
LightSchema.CONF_COLOR_TEMP_STATE_ADDRESS
)
(
red_switch,
red_switch_state,
red_brightness,
red_brightness_state,
) = _create_light_color(LightSchema.CONF_RED, config)
(
green_switch,
green_switch_state,
green_brightness,
green_brightness_state,
) = _create_light_color(LightSchema.CONF_GREEN, config)
(
blue_switch,
blue_switch_state,
blue_brightness,
blue_brightness_state,
) = _create_light_color(LightSchema.CONF_BLUE, config)
(
white_switch,
white_switch_state,
white_brightness,
white_brightness_state,
) = _create_light_color(LightSchema.CONF_WHITE, config)
return XknxLight(
knx_module,
name=config[CONF_NAME],
group_address_switch=config.get(KNX_ADDRESS),
group_address_switch_state=config.get(LightSchema.CONF_STATE_ADDRESS),
group_address_brightness=config.get(LightSchema.CONF_BRIGHTNESS_ADDRESS),
group_address_brightness_state=config.get(
LightSchema.CONF_BRIGHTNESS_STATE_ADDRESS
),
group_address_color=config.get(LightSchema.CONF_COLOR_ADDRESS),
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_tunable_white=group_address_tunable_white,
group_address_tunable_white_state=group_address_tunable_white_state,
group_address_color_temperature=group_address_color_temp,
group_address_color_temperature_state=group_address_color_temp_state,
group_address_switch_red=red_switch,
group_address_switch_red_state=red_switch_state,
group_address_brightness_red=red_brightness,
group_address_brightness_red_state=red_brightness_state,
group_address_switch_green=green_switch,
group_address_switch_green_state=green_switch_state,
group_address_brightness_green=green_brightness,
group_address_brightness_green_state=green_brightness_state,
group_address_switch_blue=blue_switch,
group_address_switch_blue_state=blue_switch_state,
group_address_brightness_blue=blue_brightness,
group_address_brightness_blue_state=blue_brightness_state,
group_address_switch_white=white_switch,
group_address_switch_white_state=white_switch_state,
group_address_brightness_white=white_brightness,
group_address_brightness_white_state=white_brightness_state,
min_kelvin=config[LightSchema.CONF_MIN_KELVIN],
max_kelvin=config[LightSchema.CONF_MAX_KELVIN],
)
def _create_climate(knx_module: XKNX, config: ConfigType) -> XknxClimate: def _create_climate(knx_module: XKNX, config: ConfigType) -> XknxClimate:
"""Return a KNX Climate device to be used within XKNX.""" """Return a KNX Climate device to be used within XKNX."""
climate_mode = XknxClimateMode( climate_mode = XknxClimateMode(

View File

@ -3,6 +3,7 @@ from __future__ import annotations
from typing import Any, cast from typing import Any, cast
from xknx import XKNX
from xknx.devices import Light as XknxLight from xknx.devices import Light as XknxLight
from xknx.telegram.address import parse_device_group_address from xknx.telegram.address import parse_device_group_address
@ -18,13 +19,14 @@ from homeassistant.components.light import (
COLOR_MODE_RGBW, COLOR_MODE_RGBW,
LightEntity, LightEntity,
) )
from homeassistant.const import CONF_NAME
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import entity_registry as er from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
import homeassistant.util.color as color_util import homeassistant.util.color as color_util
from .const import DOMAIN, KNX_ADDRESS from .const import DOMAIN, KNX_ADDRESS, ColorTempModes
from .knx_entity import KnxEntity from .knx_entity import KnxEntity
from .schema import LightSchema from .schema import LightSchema
@ -36,24 +38,26 @@ async def async_setup_platform(
discovery_info: DiscoveryInfoType | None = None, discovery_info: DiscoveryInfoType | None = None,
) -> None: ) -> None:
"""Set up lights for KNX platform.""" """Set up lights for KNX platform."""
_async_migrate_unique_id(hass, discovery_info) if not discovery_info or not discovery_info["platform_config"]:
return
platform_config = discovery_info["platform_config"]
_async_migrate_unique_id(hass, platform_config)
xknx: XKNX = hass.data[DOMAIN].xknx
entities = [] entities = []
for device in hass.data[DOMAIN].xknx.devices: for entity_config in platform_config:
if isinstance(device, XknxLight): entities.append(KNXLight(xknx, entity_config))
entities.append(KNXLight(device))
async_add_entities(entities) async_add_entities(entities)
@callback @callback
def _async_migrate_unique_id( def _async_migrate_unique_id(
hass: HomeAssistant, discovery_info: DiscoveryInfoType | None hass: HomeAssistant, platform_config: list[ConfigType]
) -> None: ) -> None:
"""Change unique_ids used in 2021.4 to exchange individual color switch address for brightness address.""" """Change unique_ids used in 2021.4 to exchange individual color switch address for brightness address."""
entity_registry = er.async_get(hass) entity_registry = er.async_get(hass)
if not discovery_info or not discovery_info["platform_config"]:
return
platform_config = discovery_info["platform_config"]
for entity_config in platform_config: for entity_config in platform_config:
individual_colors_config = entity_config.get(LightSchema.CONF_INDIVIDUAL_COLORS) individual_colors_config = entity_config.get(LightSchema.CONF_INDIVIDUAL_COLORS)
if individual_colors_config is None: if individual_colors_config is None:
@ -115,16 +119,113 @@ def _async_migrate_unique_id(
entity_registry.async_update_entity(entity_id, new_unique_id=new_uid) entity_registry.async_update_entity(entity_id, new_unique_id=new_uid)
def _create_light(xknx: XKNX, config: ConfigType) -> XknxLight:
"""Return a KNX Light device to be used within XKNX."""
def individual_color_addresses(color: str, feature: str) -> Any | None:
"""Load individual color address list from configuration structure."""
if (
LightSchema.CONF_INDIVIDUAL_COLORS not in config
or color not in config[LightSchema.CONF_INDIVIDUAL_COLORS]
):
return None
return config[LightSchema.CONF_INDIVIDUAL_COLORS][color].get(feature)
group_address_tunable_white = None
group_address_tunable_white_state = None
group_address_color_temp = None
group_address_color_temp_state = None
if config[LightSchema.CONF_COLOR_TEMP_MODE] == ColorTempModes.ABSOLUTE:
group_address_color_temp = config.get(LightSchema.CONF_COLOR_TEMP_ADDRESS)
group_address_color_temp_state = config.get(
LightSchema.CONF_COLOR_TEMP_STATE_ADDRESS
)
elif config[LightSchema.CONF_COLOR_TEMP_MODE] == ColorTempModes.RELATIVE:
group_address_tunable_white = config.get(LightSchema.CONF_COLOR_TEMP_ADDRESS)
group_address_tunable_white_state = config.get(
LightSchema.CONF_COLOR_TEMP_STATE_ADDRESS
)
return XknxLight(
xknx,
name=config[CONF_NAME],
group_address_switch=config.get(KNX_ADDRESS),
group_address_switch_state=config.get(LightSchema.CONF_STATE_ADDRESS),
group_address_brightness=config.get(LightSchema.CONF_BRIGHTNESS_ADDRESS),
group_address_brightness_state=config.get(
LightSchema.CONF_BRIGHTNESS_STATE_ADDRESS
),
group_address_color=config.get(LightSchema.CONF_COLOR_ADDRESS),
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_tunable_white=group_address_tunable_white,
group_address_tunable_white_state=group_address_tunable_white_state,
group_address_color_temperature=group_address_color_temp,
group_address_color_temperature_state=group_address_color_temp_state,
group_address_switch_red=individual_color_addresses(
LightSchema.CONF_RED, KNX_ADDRESS
),
group_address_switch_red_state=individual_color_addresses(
LightSchema.CONF_RED, LightSchema.CONF_STATE_ADDRESS
),
group_address_brightness_red=individual_color_addresses(
LightSchema.CONF_RED, LightSchema.CONF_BRIGHTNESS_ADDRESS
),
group_address_brightness_red_state=individual_color_addresses(
LightSchema.CONF_RED, LightSchema.CONF_BRIGHTNESS_STATE_ADDRESS
),
group_address_switch_green=individual_color_addresses(
LightSchema.CONF_RED, KNX_ADDRESS
),
group_address_switch_green_state=individual_color_addresses(
LightSchema.CONF_RED, LightSchema.CONF_STATE_ADDRESS
),
group_address_brightness_green=individual_color_addresses(
LightSchema.CONF_RED, LightSchema.CONF_BRIGHTNESS_ADDRESS
),
group_address_brightness_green_state=individual_color_addresses(
LightSchema.CONF_RED, LightSchema.CONF_BRIGHTNESS_STATE_ADDRESS
),
group_address_switch_blue=individual_color_addresses(
LightSchema.CONF_RED, KNX_ADDRESS
),
group_address_switch_blue_state=individual_color_addresses(
LightSchema.CONF_RED, LightSchema.CONF_STATE_ADDRESS
),
group_address_brightness_blue=individual_color_addresses(
LightSchema.CONF_RED, LightSchema.CONF_BRIGHTNESS_ADDRESS
),
group_address_brightness_blue_state=individual_color_addresses(
LightSchema.CONF_RED, LightSchema.CONF_BRIGHTNESS_STATE_ADDRESS
),
group_address_switch_white=individual_color_addresses(
LightSchema.CONF_RED, KNX_ADDRESS
),
group_address_switch_white_state=individual_color_addresses(
LightSchema.CONF_RED, LightSchema.CONF_STATE_ADDRESS
),
group_address_brightness_white=individual_color_addresses(
LightSchema.CONF_RED, LightSchema.CONF_BRIGHTNESS_ADDRESS
),
group_address_brightness_white_state=individual_color_addresses(
LightSchema.CONF_RED, LightSchema.CONF_BRIGHTNESS_STATE_ADDRESS
),
min_kelvin=config[LightSchema.CONF_MIN_KELVIN],
max_kelvin=config[LightSchema.CONF_MAX_KELVIN],
)
class KNXLight(KnxEntity, LightEntity): class KNXLight(KnxEntity, LightEntity):
"""Representation of a KNX light.""" """Representation of a KNX light."""
def __init__(self, device: XknxLight) -> None: def __init__(self, xknx: XKNX, config: ConfigType) -> None:
"""Initialize of KNX light.""" """Initialize of KNX light."""
self._device: XknxLight self._device: XknxLight
super().__init__(device) super().__init__(_create_light(xknx, config))
self._unique_id = self._device_unique_id() self._unique_id = self._device_unique_id()
self._min_kelvin = device.min_kelvin or LightSchema.DEFAULT_MIN_KELVIN self._min_kelvin: int = config[LightSchema.CONF_MIN_KELVIN]
self._max_kelvin = device.max_kelvin or LightSchema.DEFAULT_MAX_KELVIN self._max_kelvin: int = config[LightSchema.CONF_MAX_KELVIN]
self._min_mireds = color_util.color_temperature_kelvin_to_mired( self._min_mireds = color_util.color_temperature_kelvin_to_mired(
self._max_kelvin self._max_kelvin
) )