diff --git a/homeassistant/components/knx/__init__.py b/homeassistant/components/knx/__init__.py index 989efc9b376..cfa01d93d97 100644 --- a/homeassistant/components/knx/__init__.py +++ b/homeassistant/components/knx/__init__.py @@ -24,7 +24,7 @@ from homeassistant.helpers import discovery import homeassistant.helpers.config_validation as cv from homeassistant.helpers.event import async_track_state_change_event -from .const import DATA_KNX, DOMAIN, DeviceTypes +from .const import DATA_KNX, DOMAIN, SupportedPlatforms from .factory import create_knx_device from .schema import ( BinarySensorSchema, @@ -51,22 +51,11 @@ CONF_KNX_STATE_UPDATER = "state_updater" CONF_KNX_RATE_LIMIT = "rate_limit" CONF_KNX_EXPOSE = "expose" -CONF_KNX_LIGHT = "light" -CONF_KNX_COVER = "cover" -CONF_KNX_BINARY_SENSOR = "binary_sensor" -CONF_KNX_SCENE = "scene" -CONF_KNX_SENSOR = "sensor" -CONF_KNX_SWITCH = "switch" -CONF_KNX_NOTIFY = "notify" -CONF_KNX_CLIMATE = "climate" - SERVICE_KNX_SEND = "send" SERVICE_KNX_ATTR_ADDRESS = "address" SERVICE_KNX_ATTR_PAYLOAD = "payload" SERVICE_KNX_ATTR_TYPE = "type" -ATTR_DISCOVER_DEVICES = "devices" - CONFIG_SCHEMA = vol.Schema( { DOMAIN: vol.Schema( @@ -89,28 +78,28 @@ CONFIG_SCHEMA = vol.Schema( vol.Optional(CONF_KNX_EXPOSE): vol.All( cv.ensure_list, [ExposeSchema.SCHEMA] ), - vol.Optional(CONF_KNX_COVER): vol.All( + vol.Optional(SupportedPlatforms.cover.value): vol.All( cv.ensure_list, [CoverSchema.SCHEMA] ), - vol.Optional(CONF_KNX_BINARY_SENSOR): vol.All( + vol.Optional(SupportedPlatforms.binary_sensor.value): vol.All( cv.ensure_list, [BinarySensorSchema.SCHEMA] ), - vol.Optional(CONF_KNX_LIGHT): vol.All( + vol.Optional(SupportedPlatforms.light.value): vol.All( cv.ensure_list, [LightSchema.SCHEMA] ), - vol.Optional(CONF_KNX_CLIMATE): vol.All( + vol.Optional(SupportedPlatforms.climate.value): vol.All( cv.ensure_list, [ClimateSchema.SCHEMA] ), - vol.Optional(CONF_KNX_NOTIFY): vol.All( + vol.Optional(SupportedPlatforms.notify.value): vol.All( cv.ensure_list, [NotifySchema.SCHEMA] ), - vol.Optional(CONF_KNX_SWITCH): vol.All( + vol.Optional(SupportedPlatforms.switch.value): vol.All( cv.ensure_list, [SwitchSchema.SCHEMA] ), - vol.Optional(CONF_KNX_SENSOR): vol.All( + vol.Optional(SupportedPlatforms.sensor.value): vol.All( cv.ensure_list, [SensorSchema.SCHEMA] ), - vol.Optional(CONF_KNX_SCENE): vol.All( + vol.Optional(SupportedPlatforms.scene.value): vol.All( cv.ensure_list, [SceneSchema.SCHEMA] ), } @@ -129,17 +118,6 @@ SERVICE_KNX_SEND_SCHEMA = vol.Schema( } ) -KNX_CONFIG_PLATFORM_MAPPING = { - CONF_KNX_COVER: DeviceTypes.cover, - CONF_KNX_SWITCH: DeviceTypes.switch, - CONF_KNX_LIGHT: DeviceTypes.light, - CONF_KNX_SENSOR: DeviceTypes.sensor, - CONF_KNX_NOTIFY: DeviceTypes.notify, - CONF_KNX_SCENE: DeviceTypes.scene, - CONF_KNX_BINARY_SENSOR: DeviceTypes.binary_sensor, - CONF_KNX_CLIMATE: DeviceTypes.climate, -} - async def async_setup(hass, config): """Set up the KNX component.""" @@ -153,30 +131,17 @@ async def async_setup(hass, config): f"Can't connect to KNX interface:
{ex}", title="KNX" ) - for platform_config, device_type in KNX_CONFIG_PLATFORM_MAPPING.items(): - if platform_config in config[DOMAIN]: - for device_config in config[DOMAIN][platform_config]: - hass.data[DATA_KNX].xknx.devices.add( - create_knx_device( - hass, device_type, hass.data[DATA_KNX].xknx, device_config - ) + for platform in SupportedPlatforms: + if platform.value in config[DOMAIN]: + for device_config in config[DOMAIN][platform.value]: + create_knx_device( + hass, platform, hass.data[DATA_KNX].xknx, device_config ) - for component, discovery_type in ( - ("switch", "Switch"), - ("climate", "Climate"), - ("cover", "Cover"), - ("light", "Light"), - ("sensor", "Sensor"), - ("binary_sensor", "BinarySensor"), - ("scene", "Scene"), - ("notify", "Notification"), - ): - found_devices = _get_devices(hass, discovery_type) + # We need to wait until all entities are loaded into the device list since they could also be created from other platforms + for platform in SupportedPlatforms: hass.async_create_task( - discovery.async_load_platform( - hass, component, DOMAIN, {ATTR_DISCOVER_DEVICES: found_devices}, config - ) + discovery.async_load_platform(hass, platform.value, DOMAIN, {}, config) ) hass.services.async_register( @@ -189,19 +154,6 @@ async def async_setup(hass, config): return True -def _get_devices(hass, discovery_type): - """Get the KNX devices.""" - return list( - map( - lambda device: device.name, - filter( - lambda device: type(device).__name__ == discovery_type, - hass.data[DATA_KNX].xknx.devices, - ), - ) - ) - - class KNXModule: """Representation of KNX Object.""" @@ -375,7 +327,6 @@ class KNXExposeTime: self.device = DateTime( self.xknx, "Time", broadcast_type=broadcast_type, group_address=self.address ) - self.xknx.devices.add(self.device) class KNXExposeSensor: @@ -405,7 +356,6 @@ class KNXExposeSensor: group_address=self.address, value_type=self.type, ) - self.xknx.devices.add(self.device) async_track_state_change_event( self.hass, [self.entity_id], self._async_entity_changed ) diff --git a/homeassistant/components/knx/binary_sensor.py b/homeassistant/components/knx/binary_sensor.py index a18889e122a..f3b7e881134 100644 --- a/homeassistant/components/knx/binary_sensor.py +++ b/homeassistant/components/knx/binary_sensor.py @@ -4,22 +4,15 @@ from xknx.devices import BinarySensor as XknxBinarySensor from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.core import callback -from . import ATTR_DISCOVER_DEVICES, DATA_KNX +from . import DATA_KNX async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): """Set up binary sensor(s) for KNX platform.""" - if discovery_info is not None: - async_add_entities_discovery(hass, discovery_info, async_add_entities) - - -@callback -def async_add_entities_discovery(hass, discovery_info, async_add_entities): - """Set up binary sensors for KNX platform configured via xknx.yaml.""" entities = [] - for device_name in discovery_info[ATTR_DISCOVER_DEVICES]: - device = hass.data[DATA_KNX].xknx.devices[device_name] - entities.append(KNXBinarySensor(device)) + for device in hass.data[DATA_KNX].xknx.devices: + if isinstance(device, XknxBinarySensor): + entities.append(KNXBinarySensor(device)) async_add_entities(entities) diff --git a/homeassistant/components/knx/climate.py b/homeassistant/components/knx/climate.py index db0559e5158..b5aaeb67907 100644 --- a/homeassistant/components/knx/climate.py +++ b/homeassistant/components/knx/climate.py @@ -13,9 +13,8 @@ from homeassistant.components.climate.const import ( SUPPORT_TARGET_TEMPERATURE, ) from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS -from homeassistant.core import callback -from . import ATTR_DISCOVER_DEVICES, DATA_KNX +from . import DATA_KNX from .const import OPERATION_MODES, PRESET_MODES OPERATION_MODES_INV = dict(reversed(item) for item in OPERATION_MODES.items()) @@ -24,17 +23,10 @@ PRESET_MODES_INV = dict(reversed(item) for item in PRESET_MODES.items()) async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): """Set up climate(s) for KNX platform.""" - if discovery_info is not None: - async_add_entities_discovery(hass, discovery_info, async_add_entities) - - -@callback -def async_add_entities_discovery(hass, discovery_info, async_add_entities): - """Set up climates for KNX platform configured within platform.""" entities = [] - for device_name in discovery_info[ATTR_DISCOVER_DEVICES]: - device = hass.data[DATA_KNX].xknx.devices[device_name] - entities.append(KNXClimate(device)) + for device in hass.data[DATA_KNX].xknx.devices: + if isinstance(device, XknxClimate): + entities.append(KNXClimate(device)) async_add_entities(entities) diff --git a/homeassistant/components/knx/const.py b/homeassistant/components/knx/const.py index fefb0cd73c0..f259638457a 100644 --- a/homeassistant/components/knx/const.py +++ b/homeassistant/components/knx/const.py @@ -28,8 +28,8 @@ class ColorTempModes(Enum): relative = "DPT-5.001" -class DeviceTypes(Enum): - """KNX device types.""" +class SupportedPlatforms(Enum): + """Supported platforms.""" cover = "cover" light = "light" diff --git a/homeassistant/components/knx/cover.py b/homeassistant/components/knx/cover.py index 583f41c48ca..8c50bb2afe9 100644 --- a/homeassistant/components/knx/cover.py +++ b/homeassistant/components/knx/cover.py @@ -15,22 +15,15 @@ from homeassistant.components.cover import ( from homeassistant.core import callback from homeassistant.helpers.event import async_track_utc_time_change -from . import ATTR_DISCOVER_DEVICES, DATA_KNX +from . import DATA_KNX async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): """Set up cover(s) for KNX platform.""" - if discovery_info is not None: - async_add_entities_discovery(hass, discovery_info, async_add_entities) - - -@callback -def async_add_entities_discovery(hass, discovery_info, async_add_entities): - """Set up covers for KNX platform configured via xknx.yaml.""" entities = [] - for device_name in discovery_info[ATTR_DISCOVER_DEVICES]: - device = hass.data[DATA_KNX].xknx.devices[device_name] - entities.append(KNXCover(device)) + for device in hass.data[DATA_KNX].xknx.devices: + if isinstance(device, XknxCover): + entities.append(KNXCover(device)) async_add_entities(entities) diff --git a/homeassistant/components/knx/factory.py b/homeassistant/components/knx/factory.py index 64245d61a08..a596875c27b 100644 --- a/homeassistant/components/knx/factory.py +++ b/homeassistant/components/knx/factory.py @@ -19,7 +19,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.script import Script from homeassistant.helpers.typing import ConfigType -from .const import DATA_KNX, DOMAIN, ColorTempModes, DeviceTypes +from .const import DOMAIN, ColorTempModes, SupportedPlatforms from .schema import ( BinarySensorSchema, ClimateSchema, @@ -32,31 +32,34 @@ from .schema import ( def create_knx_device( - hass: HomeAssistant, device_type: DeviceTypes, knx_module: XKNX, config: ConfigType + hass: HomeAssistant, + platform: SupportedPlatforms, + knx_module: XKNX, + config: ConfigType, ) -> XknxDevice: """Return the requested XKNX device.""" - if device_type is DeviceTypes.light: + if platform is SupportedPlatforms.light: return _create_light(knx_module, config) - if device_type is DeviceTypes.cover: + if platform is SupportedPlatforms.cover: return _create_cover(knx_module, config) - if device_type is DeviceTypes.climate: - return _create_climate(hass, knx_module, config) + if platform is SupportedPlatforms.climate: + return _create_climate(knx_module, config) - if device_type is DeviceTypes.switch: + if platform is SupportedPlatforms.switch: return _create_switch(knx_module, config) - if device_type is DeviceTypes.sensor: + if platform is SupportedPlatforms.sensor: return _create_sensor(knx_module, config) - if device_type is DeviceTypes.notify: + if platform is SupportedPlatforms.notify: return _create_notify(knx_module, config) - if device_type is DeviceTypes.scene: + if platform is SupportedPlatforms.scene: return _create_scene(knx_module, config) - if device_type is DeviceTypes.binary_sensor: + if platform is SupportedPlatforms.binary_sensor: return _create_binary_sensor(hass, knx_module, config) @@ -120,9 +123,7 @@ def _create_light(knx_module: XKNX, config: ConfigType) -> XknxLight: ) -def _create_climate( - hass: HomeAssistant, 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.""" climate_mode = XknxClimateMode( knx_module, @@ -163,7 +164,6 @@ def _create_climate( ), operation_modes=config.get(ClimateSchema.CONF_OPERATION_MODES), ) - hass.data[DATA_KNX].xknx.devices.add(climate_mode) return XknxClimate( knx_module, diff --git a/homeassistant/components/knx/light.py b/homeassistant/components/knx/light.py index 2fc53fa3b7c..6d8438df0f9 100644 --- a/homeassistant/components/knx/light.py +++ b/homeassistant/components/knx/light.py @@ -15,7 +15,7 @@ from homeassistant.components.light import ( from homeassistant.core import callback import homeassistant.util.color as color_util -from . import ATTR_DISCOVER_DEVICES, DATA_KNX +from . import DATA_KNX DEFAULT_COLOR = (0.0, 0.0) DEFAULT_BRIGHTNESS = 255 @@ -24,17 +24,10 @@ DEFAULT_WHITE_VALUE = 255 async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): """Set up lights for KNX platform.""" - if discovery_info is not None: - async_add_entities_discovery(hass, discovery_info, async_add_entities) - - -@callback -def async_add_entities_discovery(hass, discovery_info, async_add_entities): - """Set up lights for KNX platform configured via xknx.yaml.""" entities = [] - for device_name in discovery_info[ATTR_DISCOVER_DEVICES]: - device = hass.data[DATA_KNX].xknx.devices[device_name] - entities.append(KNXLight(device)) + for device in hass.data[DATA_KNX].xknx.devices: + if isinstance(device, XknxLight): + entities.append(KNXLight(device)) async_add_entities(entities) diff --git a/homeassistant/components/knx/manifest.json b/homeassistant/components/knx/manifest.json index 108f3a2062a..8986d85b8b6 100644 --- a/homeassistant/components/knx/manifest.json +++ b/homeassistant/components/knx/manifest.json @@ -2,6 +2,6 @@ "domain": "knx", "name": "KNX", "documentation": "https://www.home-assistant.io/integrations/knx", - "requirements": ["xknx==0.12.0"], + "requirements": ["xknx==0.13.0"], "codeowners": ["@Julius2342", "@farmio", "@marvin-w"] } diff --git a/homeassistant/components/knx/notify.py b/homeassistant/components/knx/notify.py index fcb5bd352d5..e47cfca2794 100644 --- a/homeassistant/components/knx/notify.py +++ b/homeassistant/components/knx/notify.py @@ -1,25 +1,19 @@ """Support for KNX/IP notification services.""" +from typing import List + from xknx.devices import Notification as XknxNotification from homeassistant.components.notify import BaseNotificationService -from homeassistant.core import callback -from . import ATTR_DISCOVER_DEVICES, DATA_KNX +from . import DATA_KNX async def async_get_service(hass, config, discovery_info=None): """Get the KNX notification service.""" - if discovery_info is not None: - async_get_service_discovery(hass, discovery_info) - - -@callback -def async_get_service_discovery(hass, discovery_info): - """Set up notifications for KNX platform configured via xknx.yaml.""" notification_devices = [] - for device_name in discovery_info[ATTR_DISCOVER_DEVICES]: - device = hass.data[DATA_KNX].xknx.devices[device_name] - notification_devices.append(device) + for device in hass.data[DATA_KNX].xknx.devices: + if isinstance(device, XknxNotification): + notification_devices.append(device) return ( KNXNotificationService(notification_devices) if notification_devices else None ) @@ -28,7 +22,7 @@ def async_get_service_discovery(hass, discovery_info): class KNXNotificationService(BaseNotificationService): """Implement demo notification service.""" - def __init__(self, devices: XknxNotification): + def __init__(self, devices: List[XknxNotification]): """Initialize the service.""" self.devices = devices diff --git a/homeassistant/components/knx/scene.py b/homeassistant/components/knx/scene.py index dfa667dcd4f..b4df94a0fd4 100644 --- a/homeassistant/components/knx/scene.py +++ b/homeassistant/components/knx/scene.py @@ -4,24 +4,16 @@ from typing import Any from xknx.devices import Scene as XknxScene from homeassistant.components.scene import Scene -from homeassistant.core import callback -from . import ATTR_DISCOVER_DEVICES, DATA_KNX +from . import DATA_KNX async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): """Set up the scenes for KNX platform.""" - if discovery_info is not None: - async_add_entities_discovery(hass, discovery_info, async_add_entities) - - -@callback -def async_add_entities_discovery(hass, discovery_info, async_add_entities): - """Set up scenes for KNX platform configured via xknx.yaml.""" entities = [] - for device_name in discovery_info[ATTR_DISCOVER_DEVICES]: - device = hass.data[DATA_KNX].xknx.devices[device_name] - entities.append(KNXScene(device)) + for device in hass.data[DATA_KNX].xknx.devices: + if isinstance(device, XknxScene): + entities.append(KNXScene(device)) async_add_entities(entities) diff --git a/homeassistant/components/knx/sensor.py b/homeassistant/components/knx/sensor.py index 1fd8950a3fb..d87119239cf 100644 --- a/homeassistant/components/knx/sensor.py +++ b/homeassistant/components/knx/sensor.py @@ -4,22 +4,15 @@ from xknx.devices import Sensor as XknxSensor from homeassistant.core import callback from homeassistant.helpers.entity import Entity -from . import ATTR_DISCOVER_DEVICES, DATA_KNX +from . import DATA_KNX async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): """Set up sensor(s) for KNX platform.""" - if discovery_info is not None: - async_add_entities_discovery(hass, discovery_info, async_add_entities) - - -@callback -def async_add_entities_discovery(hass, discovery_info, async_add_entities): - """Set up sensors for KNX platform configured via xknx.yaml.""" entities = [] - for device_name in discovery_info[ATTR_DISCOVER_DEVICES]: - device = hass.data[DATA_KNX].xknx.devices[device_name] - entities.append(KNXSensor(device)) + for device in hass.data[DATA_KNX].xknx.devices: + if isinstance(device, XknxSensor): + entities.append(KNXSensor(device)) async_add_entities(entities) diff --git a/homeassistant/components/knx/switch.py b/homeassistant/components/knx/switch.py index a6e7e583b88..c378d1b0ca4 100644 --- a/homeassistant/components/knx/switch.py +++ b/homeassistant/components/knx/switch.py @@ -4,22 +4,15 @@ from xknx.devices import Switch as XknxSwitch from homeassistant.components.switch import SwitchEntity from homeassistant.core import callback -from . import ATTR_DISCOVER_DEVICES, DATA_KNX +from . import DATA_KNX async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): """Set up switch(es) for KNX platform.""" - if discovery_info is not None: - async_add_entities_discovery(hass, discovery_info, async_add_entities) - - -@callback -def async_add_entities_discovery(hass, discovery_info, async_add_entities): - """Set up switches for KNX platform configured via xknx.yaml.""" entities = [] - for device_name in discovery_info[ATTR_DISCOVER_DEVICES]: - device = hass.data[DATA_KNX].xknx.devices[device_name] - entities.append(KNXSwitch(device)) + for device in hass.data[DATA_KNX].xknx.devices: + if isinstance(device, XknxSwitch): + entities.append(KNXSwitch(device)) async_add_entities(entities) diff --git a/requirements_all.txt b/requirements_all.txt index 40670f1324c..d4a91fc0bfb 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2254,7 +2254,7 @@ xboxapi==2.0.1 xfinity-gateway==0.0.4 # homeassistant.components.knx -xknx==0.12.0 +xknx==0.13.0 # homeassistant.components.bluesound # homeassistant.components.rest