diff --git a/custom_components/circadian_lighting/config_flow.py b/custom_components/circadian_lighting/config_flow.py new file mode 100644 index 00000000..2d292cf1 --- /dev/null +++ b/custom_components/circadian_lighting/config_flow.py @@ -0,0 +1,165 @@ +"""Config flow for Coronavirus integration.""" +import logging + +import homeassistant.helpers.config_validation as cv +import voluptuous as vol +from homeassistant import config_entries +from homeassistant.components.light import VALID_TRANSITION +from homeassistant.core import callback + +from .const import ( + CONF_DISABLE_BRIGHTNESS_ADJUST, + CONF_DISABLE_ENTITY, + CONF_DISABLE_STATE, + CONF_INITIAL_TRANSITION, + CONF_INTERVAL, + CONF_LIGHTS_BRIGHTNESS, + CONF_LIGHTS_MIRED, + CONF_LIGHTS_RGB, + CONF_LIGHTS_XY, + CONF_MAX_BRIGHTNESS, + CONF_MAX_CT, + CONF_MIN_BRIGHTNESS, + CONF_MIN_CT, + CONF_ONLY_ONCE, + CONF_SLEEP_BRIGHTNESS, + CONF_SLEEP_CT, + CONF_SLEEP_ENTITY, + CONF_SLEEP_STATE, + CONF_SUNRISE_OFFSET, + CONF_SUNRISE_TIME, + CONF_SUNSET_OFFSET, + CONF_SUNSET_TIME, + CONF_TRANSITION, + DEFAULT_INITIAL_TRANSITION, + DEFAULT_INTERVAL, + DEFAULT_MAX_BRIGHTNESS, + DEFAULT_MAX_CT, + DEFAULT_MIN_BRIGHTNESS, + DEFAULT_MIN_CT, + DEFAULT_SLEEP_BRIGHTNESS, + DEFAULT_SLEEP_CT, + DEFAULT_TRANSITION, + DOMAIN, +) + +_LOGGER = logging.getLogger(__name__) + + +class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): + """Handle a config flow for Adaptive Lighting.""" + + VERSION = 1 + + async def async_step_user(self, user_input=None): + """Handle the initial step.""" + errors = {} + + if user_input is not None: + await self.async_set_unique_id(user_input["name"]) + self._abort_if_unique_id_configured() + return self.async_create_entry(title=user_input["name"], data=user_input) + + return self.async_show_form( + step_id="user", + data_schema=vol.Schema({vol.Required("name"): str}), + errors=errors, + ) + + @staticmethod + @callback + def async_get_options_flow(config_entry): + """Get the options flow for this handler.""" + return OptionsFlowHandler(config_entry) + + +class OptionsFlowHandler(config_entries.OptionsFlow): + """Handle a option flow for Adaptive Lighting.""" + + def __init__(self, config_entry: config_entries.ConfigEntry): + """Initialize options flow.""" + self.config_entry = config_entry + + async def async_step_init(self, user_input=None): + """Handle options flow.""" + if user_input is not None: + return self.async_create_entry(title="", data=user_input) + + options = self.config_entry.options + + lights_brightness = options.get(CONF_LIGHTS_BRIGHTNESS, []) + lights_mired = options.get(CONF_LIGHTS_MIRED, []) + lights_rgb = options.get(CONF_LIGHTS_RGB, []) + lights_xy = options.get(CONF_LIGHTS_XY, []) + disable_brightness_adjust = options.get(CONF_DISABLE_BRIGHTNESS_ADJUST, False) + disable_entity = options.get(CONF_DISABLE_ENTITY) + disable_state = options.get(CONF_DISABLE_STATE) + initial_transition = options.get( + CONF_INITIAL_TRANSITION, DEFAULT_INITIAL_TRANSITION + ) + interval = options.get(CONF_INTERVAL, DEFAULT_INTERVAL) + max_brightness = options.get(CONF_MAX_BRIGHTNESS, DEFAULT_MAX_BRIGHTNESS) + max_colortemp = options.get(CONF_MAX_CT, DEFAULT_MAX_CT) + min_brightness = options.get(CONF_MIN_BRIGHTNESS, DEFAULT_MIN_BRIGHTNESS) + min_colortemp = options.get(CONF_MIN_CT, DEFAULT_MIN_CT) + only_once = options.get(CONF_ONLY_ONCE, False) + sleep_brightness = options.get(CONF_SLEEP_BRIGHTNESS, DEFAULT_SLEEP_BRIGHTNESS) + sleep_colortemp = options.get(CONF_SLEEP_CT, DEFAULT_SLEEP_CT) + sleep_entity = options.get(CONF_SLEEP_ENTITY) + sleep_state = options.get(CONF_SLEEP_STATE) + sunrise_offset = options.get(CONF_SUNRISE_OFFSET, 0) + sunrise_time = options.get(CONF_SUNRISE_TIME) + sunset_offset = options.get(CONF_SUNSET_OFFSET, 0) + sunset_time = options.get(CONF_SUNSET_TIME) + transition = options.get(CONF_TRANSITION, DEFAULT_TRANSITION) + + all_lights = self.hass.states.async_entity_ids("light") + all_lights = cv.multi_select(all_lights) + + options_schema = vol.Schema( + { + vol.Optional( + CONF_LIGHTS_BRIGHTNESS, default=lights_brightness + ): all_lights, + vol.Optional(CONF_LIGHTS_MIRED, default=lights_mired): all_lights, + vol.Optional(CONF_LIGHTS_RGB, default=lights_rgb): all_lights, + vol.Optional(CONF_LIGHTS_XY, default=lights_xy): all_lights, + vol.Optional( + CONF_DISABLE_BRIGHTNESS_ADJUST, default=disable_brightness_adjust + ): bool, + vol.Optional(CONF_DISABLE_ENTITY, default=disable_entity): str, + vol.Optional(CONF_DISABLE_STATE, default=disable_state): str, + vol.Optional( + CONF_INITIAL_TRANSITION, default=initial_transition + ): cv.positive_int, + vol.Optional(CONF_INTERVAL, default=interval): cv.positive_int, + vol.Optional(CONF_MAX_BRIGHTNESS, default=max_brightness): vol.All( + vol.Coerce(int), vol.Range(min=1, max=100) + ), + vol.Optional(CONF_MAX_CT, default=max_colortemp): vol.All( + vol.Coerce(int), vol.Range(min=1000, max=10000) + ), + vol.Optional(CONF_MIN_BRIGHTNESS, default=min_brightness): vol.All( + vol.Coerce(int), vol.Range(min=1, max=100) + ), + vol.Optional(CONF_MIN_CT, default=min_colortemp): vol.All( + vol.Coerce(int), vol.Range(min=1000, max=10000) + ), + vol.Optional(CONF_ONLY_ONCE, default=only_once): bool, + vol.Optional(CONF_SLEEP_BRIGHTNESS, default=sleep_brightness): vol.All( + vol.Coerce(int), vol.Range(min=1, max=100) + ), + vol.Optional(CONF_SLEEP_CT, default=sleep_colortemp): vol.All( + vol.Coerce(int), vol.Range(min=1000, max=10000) + ), + vol.Optional(CONF_SLEEP_ENTITY, default=sleep_entity): str, + vol.Optional(CONF_SLEEP_STATE, default=sleep_state): str, + vol.Optional(CONF_SUNRISE_OFFSET, default=sunrise_offset): int, + vol.Optional(CONF_SUNRISE_TIME, default=sunrise_time): str, + vol.Optional(CONF_SUNSET_OFFSET, default=sunset_offset): int, + vol.Optional(CONF_SUNSET_TIME, default=sunset_time): str, + vol.Optional(CONF_TRANSITION, default=transition): VALID_TRANSITION, + } + ) + + return self.async_show_form(step_id="init", data_schema=options_schema) diff --git a/custom_components/circadian_lighting/const.py b/custom_components/circadian_lighting/const.py new file mode 100644 index 00000000..1b898362 --- /dev/null +++ b/custom_components/circadian_lighting/const.py @@ -0,0 +1,30 @@ +ICON = "mdi:theme-light-dark" + +DOMAIN = "adaptive_lighting" +SUN_EVENT_NOON = "solar_noon" +SUN_EVENT_MIDNIGHT = "solar_midnight" + +CONF_LIGHTS_BRIGHTNESS = "lights_brightness" +CONF_LIGHTS_MIRED = "lights_mired" +CONF_LIGHTS_RGB = "lights_rgb" +CONF_LIGHTS_XY = "lights_xy" + +CONF_DISABLE_BRIGHTNESS_ADJUST = "disable_brightness_adjust" +CONF_DISABLE_ENTITY = "disable_entity" +CONF_DISABLE_STATE = "disable_state" +CONF_INITIAL_TRANSITION, DEFAULT_INITIAL_TRANSITION = "initial_transition", 1 +CONF_INTERVAL, DEFAULT_INTERVAL = "interval", 90 +CONF_MAX_BRIGHTNESS, DEFAULT_MAX_BRIGHTNESS = "max_brightness", 100 +CONF_MAX_CT, DEFAULT_MAX_CT = "max_colortemp", 5500 +CONF_MIN_BRIGHTNESS, DEFAULT_MIN_BRIGHTNESS = "min_brightness", 1 +CONF_MIN_CT, DEFAULT_MIN_CT = "min_colortemp", 2500 +CONF_ONLY_ONCE = "only_once" +CONF_SLEEP_BRIGHTNESS, DEFAULT_SLEEP_BRIGHTNESS = "sleep_brightness", 1 +CONF_SLEEP_CT, DEFAULT_SLEEP_CT = "sleep_colortemp", 1000 +CONF_SLEEP_ENTITY = "sleep_entity" +CONF_SLEEP_STATE = "sleep_state" +CONF_SUNRISE_OFFSET = "sunrise_offset" +CONF_SUNRISE_TIME = "sunrise_time" +CONF_SUNSET_OFFSET = "sunset_offset" +CONF_SUNSET_TIME = "sunset_time" +CONF_TRANSITION, DEFAULT_TRANSITION = "transition", 60 diff --git a/custom_components/circadian_lighting/manifest.json b/custom_components/circadian_lighting/manifest.json index 4b103323..ceae225d 100644 --- a/custom_components/circadian_lighting/manifest.json +++ b/custom_components/circadian_lighting/manifest.json @@ -2,6 +2,7 @@ "domain": "adaptive_lighting", "name": "Adaptive Lighting", "documentation": "https://github.com/basnijholt/adaptive_lighting", + "config_flow": true, "dependencies": [], "codeowners": ["@claytonjn", "@basnijholt"], "requirements": [] diff --git a/custom_components/circadian_lighting/strings.json b/custom_components/circadian_lighting/strings.json new file mode 100644 index 00000000..d9090b82 --- /dev/null +++ b/custom_components/circadian_lighting/strings.json @@ -0,0 +1,51 @@ +{ + "title": "Adaptive Lighting", + "config": { + "step": { + "user": { + "title": "Choose a name for the Adaptive Lighting", + "description": "Every instance can contain multiple lights!", + "data": { + "name": "Name" + } + } + }, + "abort": { + "already_configured": "This name is already configured." + } + }, + "options": { + "step": { + "init": { + "data": { + "lights_brightness": "lights_brightness", + "lights_mired": "lights_mired", + "lights_rgb": "lights_rgb", + "lights_xy": "lights_xy", + "disable_brightness_adjust": "disable_brightness_adjust", + "disable_entity": "disable_entity", + "disable_state": "disable_state", + "initial_transition": "initial_transition", + "interval": "interval", + "max_brightness": "max_brightness", + "max_colortemp": "max_colortemp", + "min_brightness": "min_brightness", + "min_colortemp": "min_colortemp", + "only_once": "only_once", + "sleep_brightness": "sleep_brightness", + "sleep_colortemp": "sleep_colortemp", + "sleep_entity": "sleep_entity", + "sleep_state": "sleep_state", + "sunrise_offset": "sunrise_offset", + "sunrise_time": "sunrise_time", + "sunset_offset": "sunset_offset", + "sunset_time": "sunset_time", + "transition": "transition" + } + } + }, + "error": { + "retrive_error": "Error retriving servers list" + } + } +} \ No newline at end of file diff --git a/custom_components/circadian_lighting/switch.py b/custom_components/circadian_lighting/switch.py index e9181632..a9ec2d4d 100755 --- a/custom_components/circadian_lighting/switch.py +++ b/custom_components/circadian_lighting/switch.py @@ -69,44 +69,52 @@ from homeassistant.util.color import ( color_temperature_to_rgb, color_xy_to_hs, ) +from .const import ( + ICON, + DOMAIN, + SUN_EVENT_NOON, + SUN_EVENT_MIDNIGHT, + CONF_LIGHTS_BRIGHTNESS, + CONF_LIGHTS_MIRED, + CONF_LIGHTS_RGB, + CONF_LIGHTS_XY, + CONF_DISABLE_BRIGHTNESS_ADJUST, + CONF_DISABLE_ENTITY, + CONF_DISABLE_STATE, + CONF_INITIAL_TRANSITION, + DEFAULT_INITIAL_TRANSITION, + CONF_INTERVAL, + DEFAULT_INTERVAL, + CONF_MAX_BRIGHTNESS, + DEFAULT_MAX_BRIGHTNESS, + CONF_MAX_CT, + DEFAULT_MAX_CT, + CONF_MIN_BRIGHTNESS, + DEFAULT_MIN_BRIGHTNESS, + CONF_MIN_CT, + DEFAULT_MIN_CT, + CONF_ONLY_ONCE, + CONF_SLEEP_BRIGHTNESS, + DEFAULT_SLEEP_BRIGHTNESS, + CONF_SLEEP_CT, + DEFAULT_SLEEP_CT, + CONF_SLEEP_ENTITY, + CONF_SLEEP_STATE, + CONF_SUNRISE_OFFSET, + CONF_SUNRISE_TIME, + CONF_SUNSET_OFFSET, + CONF_SUNSET_TIME, + CONF_TRANSITION, + DEFAULT_TRANSITION, +) _LOGGER = logging.getLogger(__name__) -ICON = "mdi:theme-light-dark" SCAN_INTERVAL = timedelta(seconds=10) -DOMAIN = "adaptive_lighting" -SUN_EVENT_NOON = "solar_noon" -SUN_EVENT_MIDNIGHT = "solar_midnight" - -CONF_LIGHTS_BRIGHTNESS = "lights_brightness" -CONF_LIGHTS_MIRED = "lights_mired" -CONF_LIGHTS_RGB = "lights_rgb" -CONF_LIGHTS_XY = "lights_xy" - -CONF_DISABLE_BRIGHTNESS_ADJUST = "disable_brightness_adjust" -CONF_DISABLE_ENTITY = "disable_entity" -CONF_DISABLE_STATE = "disable_state" -CONF_INITIAL_TRANSITION, DEFAULT_INITIAL_TRANSITION = "initial_transition", 1 -CONF_INTERVAL, DEFAULT_INTERVAL = "interval", 90 -CONF_MAX_BRIGHTNESS, DEFAULT_MAX_BRIGHTNESS = "max_brightness", 100 -CONF_MAX_CT, DEFAULT_MAX_CT = "max_colortemp", 5500 -CONF_MIN_BRIGHTNESS, DEFAULT_MIN_BRIGHTNESS = "min_brightness", 1 -CONF_MIN_CT, DEFAULT_MIN_CT = "min_colortemp", 2500 -CONF_ONLY_ONCE = "only_once" -CONF_SLEEP_BRIGHTNESS, DEFAULT_SLEEP_BRIGHTNESS = "sleep_brightness", 1 -CONF_SLEEP_CT, DEFAULT_SLEEP_CT = "sleep_colortemp", 1000 -CONF_SLEEP_ENTITY = "sleep_entity" -CONF_SLEEP_STATE = "sleep_state" -CONF_SUNRISE_OFFSET = "sunrise_offset" -CONF_SUNRISE_TIME = "sunrise_time" -CONF_SUNSET_OFFSET = "sunset_offset" -CONF_SUNSET_TIME = "sunset_time" -CONF_TRANSITION, DEFAULT_TRANSITION = "transition", 60 - PLATFORM_SCHEMA = vol.Schema( { - vol.Required(CONF_PLATFORM): "adaptive_lighting", + vol.Required(CONF_PLATFORM): DOMAIN, vol.Optional(CONF_NAME, default="Adaptive Lighting"): cv.string, vol.Optional(CONF_LIGHTS_BRIGHTNESS): cv.entity_ids, vol.Optional(CONF_LIGHTS_MIRED): cv.entity_ids, diff --git a/custom_components/circadian_lighting/translations/en.json b/custom_components/circadian_lighting/translations/en.json new file mode 100644 index 00000000..973a5d64 --- /dev/null +++ b/custom_components/circadian_lighting/translations/en.json @@ -0,0 +1,51 @@ +{ + "title": "Adaptive Lighting", + "config": { + "step": { + "user": { + "title": "Choose a name for the Adaptive Lighting", + "description": "Every instance can contain multiple lights!", + "data": { + "name": "Name" + } + } + }, + "abort": { + "already_configured": "This name is already configured." + } + }, + "options": { + "step": { + "init": { + "data": { + "lights_brightness": "lights_brightness", + "lights_mired": "lights_mired", + "lights_rgb": "lights_rgb", + "lights_xy": "lights_xy", + "disable_brightness_adjust": "disable_brightness_adjust", + "disable_entity": "disable_entity", + "disable_state": "disable_state", + "initial_transition": "initial_transition", + "interval": "interval", + "max_brightness": "max_brightness", + "max_colortemp": "max_colortemp", + "min_brightness": "min_brightness", + "min_colortemp": "min_colortemp", + "only_once": "only_once", + "sleep_brightness": "sleep_brightness", + "sleep_colortemp": "sleep_colortemp", + "sleep_entity": "sleep_entity", + "sleep_state": "sleep_state", + "sunrise_offset": "sunrise_offset", + "sunrise_time": "sunrise_time", + "sunset_offset": "sunset_offset", + "sunset_time": "sunset_time", + "transition": "transition" + } + } + }, + "error": { + "retrive_error": "Error retriving servers list" + } + } +}