diff --git a/custom_components/adaptive_lighting/__init__.py b/custom_components/adaptive_lighting/__init__.py index a8557561..e1ad4718 100755 --- a/custom_components/adaptive_lighting/__init__.py +++ b/custom_components/adaptive_lighting/__init__.py @@ -29,8 +29,9 @@ Technical notes: I had to make a lot of assumptions when writing this app import asyncio import logging -import homeassistant.helpers.config_validation as cv import voluptuous as vol + +import homeassistant.helpers.config_validation as cv from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry from .const import CONF_NAME, DOMAIN, UNDO_UPDATE_LISTENER, get_domain_schema @@ -48,15 +49,16 @@ def _all_unique_profiles(value): return value -# _DOMAIN_SCHEMA = get_domain_schema(with_fake_none=False) -# CONFIG_SCHEMA = vol.Schema( -# { -# DOMAIN: vol.All( -# cv.ensure_list, [vol.Schema(_DOMAIN_SCHEMA)], _all_unique_profiles -# ) -# }, -# extra=vol.ALLOW_EXTRA, -# ) +_DOMAIN_SCHEMA = get_domain_schema(yaml=True) +_LOGGER.error(_DOMAIN_SCHEMA) +CONFIG_SCHEMA = vol.Schema( + { + DOMAIN: vol.All( + cv.ensure_list, [vol.Schema(_DOMAIN_SCHEMA)], _all_unique_profiles + ) + }, + extra=vol.ALLOW_EXTRA, +) async def async_setup(hass, config): diff --git a/custom_components/adaptive_lighting/config_flow.py b/custom_components/adaptive_lighting/config_flow.py index a15fcb25..67b772d5 100644 --- a/custom_components/adaptive_lighting/config_flow.py +++ b/custom_components/adaptive_lighting/config_flow.py @@ -2,8 +2,9 @@ import logging from copy import copy -import homeassistant.helpers.config_validation as cv import voluptuous as vol + +import homeassistant.helpers.config_validation as cv from homeassistant import config_entries from homeassistant.core import callback @@ -40,7 +41,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): async def async_step_import(self, user_input=None): """Handle configuration by yaml file.""" - _DOMAIN_SCHEMA = get_domain_schema(with_fake_none=False) + _DOMAIN_SCHEMA = get_domain_schema(yaml=False) schema = {k: v for k, v in _DOMAIN_SCHEMA.items() if k in user_input} vol.Schema(schema)(user_input) _LOGGER.error(str(user_input) + str(schema)) @@ -54,7 +55,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): def validate_options(user_input, errors): - for key, validate in EXTRA_VALIDATION.items(): + for key, (validate, coerce) in EXTRA_VALIDATION.items(): # these are unserializable validators try: value = user_input.get(key) diff --git a/custom_components/adaptive_lighting/const.py b/custom_components/adaptive_lighting/const.py index 63b16939..dd3c30e3 100644 --- a/custom_components/adaptive_lighting/const.py +++ b/custom_components/adaptive_lighting/const.py @@ -1,5 +1,6 @@ -import homeassistant.helpers.config_validation as cv import voluptuous as vol + +import homeassistant.helpers.config_validation as cv from homeassistant.components.light import VALID_TRANSITION ICON = "mdi:theme-light-dark" @@ -64,22 +65,40 @@ VALIDATION_TUPLES = [ (CONF_TRANSITION, DEFAULT_TRANSITION, VALID_TRANSITION), ] -EXTRA_VALIDATION = { # these validators cannot be serialized - CONF_DISABLE_ENTITY: cv.entity_id, - CONF_DISABLE_STATE: vol.All(cv.ensure_list_csv, [cv.string]), - CONF_INTERVAL: cv.time_period, - CONF_SLEEP_ENTITY: cv.entity_id, - CONF_SLEEP_STATE: vol.All(cv.ensure_list_csv, [cv.string]), - CONF_SUNRISE_OFFSET: cv.time_period, - CONF_SUNRISE_TIME: cv.time, - CONF_SUNSET_OFFSET: cv.time_period, - CONF_SUNSET_TIME: cv.time, + +def timedelta_as_int(value): + return value.total_seconds() + + +def join_strings(lst): + return ",".join(lst) + + +# these validators cannot be serialized +EXTRA_VALIDATION = { + CONF_DISABLE_ENTITY: (cv.entity_id, str), + CONF_DISABLE_STATE: (vol.All(cv.ensure_list_csv, [cv.string]), join_strings), + CONF_INTERVAL: (cv.time_period, timedelta_as_int), + CONF_SLEEP_ENTITY: (cv.entity_id, str), + CONF_SLEEP_STATE: (vol.All(cv.ensure_list_csv, [cv.string]), join_strings), + CONF_SUNRISE_OFFSET: (cv.time_period, timedelta_as_int), + CONF_SUNRISE_TIME: (cv.time, str), + CONF_SUNSET_OFFSET: (cv.time_period, timedelta_as_int), + CONF_SUNSET_TIME: (cv.time, str), } -def get_domain_schema(with_fake_none=False): +def get_domain_schema(with_fake_none=False, yaml=False): + def get_validation(key, validation): + validation, coerce = EXTRA_VALIDATION.get(key, (validation, None)) + return ( + vol.All(validation, vol.Coerce(coerce)) + if yaml and coerce is not None + else validation + ) + validation_tuples = [ - (key, default, EXTRA_VALIDATION.get(key, validation)) + (key, default, get_validation(key, validation)) for key, default, validation in VALIDATION_TUPLES ] validation_tuples.append((CONF_NAME, DEFAULT_NAME, cv.string)) diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index bc0857a1..0f599f41 100755 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -64,20 +64,6 @@ from .const import ( CONF_SUNSET_OFFSET, CONF_SUNSET_TIME, CONF_TRANSITION, - DEFAULT_DISABLE_BRIGHTNESS_ADJUST, - DEFAULT_INITIAL_TRANSITION, - DEFAULT_INTERVAL, - DEFAULT_LIGHTS, - DEFAULT_MAX_BRIGHTNESS, - DEFAULT_MAX_COLOR_TEMP, - DEFAULT_MIN_BRIGHTNESS, - DEFAULT_MIN_COLOR_TEMP, - DEFAULT_ONLY_ONCE, - DEFAULT_SLEEP_BRIGHTNESS, - DEFAULT_SLEEP_COLOR_TEMP, - DEFAULT_SUNRISE_OFFSET, - DEFAULT_SUNSET_OFFSET, - DEFAULT_TRANSITION, DOMAIN, EXTRA_VALIDATION, FAKE_NONE, @@ -136,7 +122,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): defaults = {key: default for key, default, _ in VALIDATION_TUPLES} data = dict(defaults, **config_entry.options, **config_entry.data) data = {key: replace_none(value) for key, value in data.items()} - for key, validate in EXTRA_VALIDATION.items(): + for key, (validate, coerce) in EXTRA_VALIDATION.items(): # Fix the types of the inputs value = data.get(key) if value is not None: