From 710deb83161f59e425066871f99644030f0bd346 Mon Sep 17 00:00:00 2001 From: Ziv <16467659+ziv1234@users.noreply.github.com> Date: Tue, 5 May 2020 06:30:24 +0300 Subject: [PATCH] Strict creation of the config for dynalite (#34663) --- .../components/dynalite/convert_config.py | 147 ++++++++++++++---- homeassistant/components/dynalite/cover.py | 6 +- tests/components/dynalite/test_init.py | 1 + 3 files changed, 117 insertions(+), 37 deletions(-) diff --git a/homeassistant/components/dynalite/convert_config.py b/homeassistant/components/dynalite/convert_config.py index 2e21d5edd9b4ff..3cc9372eb0bfe2 100644 --- a/homeassistant/components/dynalite/convert_config.py +++ b/homeassistant/components/dynalite/convert_config.py @@ -32,47 +32,128 @@ CONF_TIME_COVER, ) -CONF_MAP = { - CONF_ACTIVE: dyn_const.CONF_ACTIVE, +ACTIVE_MAP = { ACTIVE_INIT: dyn_const.ACTIVE_INIT, + False: dyn_const.ACTIVE_OFF, ACTIVE_OFF: dyn_const.ACTIVE_OFF, ACTIVE_ON: dyn_const.ACTIVE_ON, - CONF_AREA: dyn_const.CONF_AREA, - CONF_AUTO_DISCOVER: dyn_const.CONF_AUTO_DISCOVER, - CONF_CHANNEL: dyn_const.CONF_CHANNEL, - CONF_CHANNEL_COVER: dyn_const.CONF_CHANNEL_COVER, - CONF_TYPE: dyn_const.CONF_CHANNEL_TYPE, - CONF_CLOSE_PRESET: dyn_const.CONF_CLOSE_PRESET, - CONF_DEFAULT: dyn_const.CONF_DEFAULT, - CONF_DEVICE_CLASS: dyn_const.CONF_DEVICE_CLASS, - CONF_DURATION: dyn_const.CONF_DURATION, - CONF_FADE: dyn_const.CONF_FADE, - CONF_HOST: dyn_const.CONF_HOST, - CONF_NAME: dyn_const.CONF_NAME, - CONF_NO_DEFAULT: dyn_const.CONF_NO_DEFAULT, - CONF_OPEN_PRESET: dyn_const.CONF_OPEN_PRESET, - CONF_POLL_TIMER: dyn_const.CONF_POLL_TIMER, - CONF_PORT: dyn_const.CONF_PORT, - CONF_PRESET: dyn_const.CONF_PRESET, + True: dyn_const.ACTIVE_ON, +} + +TEMPLATE_MAP = { CONF_ROOM: dyn_const.CONF_ROOM, - CONF_ROOM_OFF: dyn_const.CONF_ROOM_OFF, - CONF_ROOM_ON: dyn_const.CONF_ROOM_ON, - CONF_STOP_PRESET: dyn_const.CONF_STOP_PRESET, - CONF_TEMPLATE: dyn_const.CONF_TEMPLATE, - CONF_TILT_TIME: dyn_const.CONF_TILT_TIME, CONF_TIME_COVER: dyn_const.CONF_TIME_COVER, } +def convert_with_map(config, conf_map): + """Create the initial converted map with just the basic key:value pairs updated.""" + result = {} + for conf in conf_map: + if conf in config: + result[conf_map[conf]] = config[conf] + return result + + +def convert_channel(config: Dict[str, Any]) -> Dict[str, Any]: + """Convert the config for a channel.""" + my_map = { + CONF_NAME: dyn_const.CONF_NAME, + CONF_FADE: dyn_const.CONF_FADE, + CONF_TYPE: dyn_const.CONF_CHANNEL_TYPE, + } + return convert_with_map(config, my_map) + + +def convert_preset(config: Dict[str, Any]) -> Dict[str, Any]: + """Convert the config for a preset.""" + my_map = { + CONF_NAME: dyn_const.CONF_NAME, + CONF_FADE: dyn_const.CONF_FADE, + } + return convert_with_map(config, my_map) + + +def convert_area(config: Dict[str, Any]) -> Dict[str, Any]: + """Convert the config for an area.""" + my_map = { + CONF_NAME: dyn_const.CONF_NAME, + CONF_FADE: dyn_const.CONF_FADE, + CONF_NO_DEFAULT: dyn_const.CONF_NO_DEFAULT, + CONF_ROOM_ON: dyn_const.CONF_ROOM_ON, + CONF_ROOM_OFF: dyn_const.CONF_ROOM_OFF, + CONF_CHANNEL_COVER: dyn_const.CONF_CHANNEL_COVER, + CONF_DEVICE_CLASS: dyn_const.CONF_DEVICE_CLASS, + CONF_OPEN_PRESET: dyn_const.CONF_OPEN_PRESET, + CONF_CLOSE_PRESET: dyn_const.CONF_CLOSE_PRESET, + CONF_STOP_PRESET: dyn_const.CONF_STOP_PRESET, + CONF_DURATION: dyn_const.CONF_DURATION, + CONF_TILT_TIME: dyn_const.CONF_TILT_TIME, + } + result = convert_with_map(config, my_map) + if CONF_CHANNEL in config: + result[dyn_const.CONF_CHANNEL] = { + channel: convert_channel(channel_conf) + for (channel, channel_conf) in config[CONF_CHANNEL].items() + } + if CONF_PRESET in config: + result[dyn_const.CONF_PRESET] = { + preset: convert_preset(preset_conf) + for (preset, preset_conf) in config[CONF_PRESET].items() + } + if CONF_TEMPLATE in config: + result[dyn_const.CONF_TEMPLATE] = TEMPLATE_MAP[config[CONF_TEMPLATE]] + return result + + +def convert_default(config: Dict[str, Any]) -> Dict[str, Any]: + """Convert the config for the platform defaults.""" + return convert_with_map(config, {CONF_FADE: dyn_const.CONF_FADE}) + + +def convert_template(config: Dict[str, Any]) -> Dict[str, Any]: + """Convert the config for a template.""" + my_map = { + CONF_ROOM_ON: dyn_const.CONF_ROOM_ON, + CONF_ROOM_OFF: dyn_const.CONF_ROOM_OFF, + CONF_CHANNEL_COVER: dyn_const.CONF_CHANNEL_COVER, + CONF_DEVICE_CLASS: dyn_const.CONF_DEVICE_CLASS, + CONF_OPEN_PRESET: dyn_const.CONF_OPEN_PRESET, + CONF_CLOSE_PRESET: dyn_const.CONF_CLOSE_PRESET, + CONF_STOP_PRESET: dyn_const.CONF_STOP_PRESET, + CONF_DURATION: dyn_const.CONF_DURATION, + CONF_TILT_TIME: dyn_const.CONF_TILT_TIME, + } + return convert_with_map(config, my_map) + + def convert_config(config: Dict[str, Any]) -> Dict[str, Any]: """Convert a config dict by replacing component consts with library consts.""" - result = {} - for (key, value) in config.items(): - if isinstance(value, dict): - new_value = convert_config(value) - elif isinstance(value, str): - new_value = CONF_MAP.get(value, value) - else: - new_value = value - result[CONF_MAP.get(key, key)] = new_value + my_map = { + CONF_NAME: dyn_const.CONF_NAME, + CONF_HOST: dyn_const.CONF_HOST, + CONF_PORT: dyn_const.CONF_PORT, + CONF_AUTO_DISCOVER: dyn_const.CONF_AUTO_DISCOVER, + CONF_POLL_TIMER: dyn_const.CONF_POLL_TIMER, + } + result = convert_with_map(config, my_map) + if CONF_AREA in config: + result[dyn_const.CONF_AREA] = { + area: convert_area(area_conf) + for (area, area_conf) in config[CONF_AREA].items() + } + if CONF_DEFAULT in config: + result[dyn_const.CONF_DEFAULT] = convert_default(config[CONF_DEFAULT]) + if CONF_ACTIVE in config: + result[dyn_const.CONF_ACTIVE] = ACTIVE_MAP[config[CONF_ACTIVE]] + if CONF_PRESET in config: + result[dyn_const.CONF_PRESET] = { + preset: convert_preset(preset_conf) + for (preset, preset_conf) in config[CONF_PRESET].items() + } + if CONF_TEMPLATE in config: + result[dyn_const.CONF_TEMPLATE] = { + TEMPLATE_MAP[template]: convert_template(template_conf) + for (template, template_conf) in config[CONF_TEMPLATE].items() + } return result diff --git a/homeassistant/components/dynalite/cover.py b/homeassistant/components/dynalite/cover.py index a5c25945aa81d2..e44fd150f384f8 100644 --- a/homeassistant/components/dynalite/cover.py +++ b/homeassistant/components/dynalite/cover.py @@ -5,7 +5,6 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from .const import DEFAULT_COVER_CLASS from .dynalitebase import DynaliteBase, async_setup_entry_base @@ -32,9 +31,8 @@ class DynaliteCover(DynaliteBase, CoverEntity): def device_class(self) -> str: """Return the class of the device.""" dev_cls = self._device.device_class - if dev_cls in DEVICE_CLASSES: - return dev_cls - return DEFAULT_COVER_CLASS + assert dev_cls in DEVICE_CLASSES + return dev_cls @property def current_cover_position(self) -> int: diff --git a/tests/components/dynalite/test_init.py b/tests/components/dynalite/test_init.py index 8b1393cb32dd96..be646a1854d2d5 100644 --- a/tests/components/dynalite/test_init.py +++ b/tests/components/dynalite/test_init.py @@ -37,6 +37,7 @@ async def test_async_setup(hass): "1": { CONF_NAME: "Name1", dynalite.CONF_CHANNEL: {"4": {}}, + dynalite.CONF_PRESET: {"7": {}}, dynalite.CONF_NO_DEFAULT: True, }, "2": {CONF_NAME: "Name2"},