From 954e022860fc484643e2b8ffc06b91d87c5d0ca2 Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Wed, 16 Sep 2020 00:00:54 +0200 Subject: [PATCH] unify config options flow and YAML schema --- .../adaptive_lighting/config_flow.py | 97 ++--------- custom_components/adaptive_lighting/const.py | 66 ++++++++ custom_components/adaptive_lighting/switch.py | 150 +++++++++++------- 3 files changed, 168 insertions(+), 145 deletions(-) diff --git a/custom_components/adaptive_lighting/config_flow.py b/custom_components/adaptive_lighting/config_flow.py index 089d625a..05b81498 100644 --- a/custom_components/adaptive_lighting/config_flow.py +++ b/custom_components/adaptive_lighting/config_flow.py @@ -1,49 +1,13 @@ """Config flow for Coronavirus integration.""" import logging -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.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, - CONF_MAX_BRIGHTNESS, - CONF_MAX_COLOR_TEMP, - CONF_MIN_BRIGHTNESS, - CONF_MIN_COLOR_TEMP, - CONF_ONLY_ONCE, - CONF_SLEEP_BRIGHTNESS, - CONF_SLEEP_COLOR_TEMP, - CONF_SLEEP_ENTITY, - CONF_SLEEP_STATE, - CONF_SUNRISE_OFFSET, - CONF_SUNRISE_TIME, - 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, -) +from .const import DOMAIN, _convert_to_options_schema _LOGGER = logging.getLogger(__name__) @@ -62,7 +26,11 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): 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,) + return self.async_show_form( + step_id="user", + data_schema=vol.Schema({vol.Required("name"): str}), + errors=errors, + ) @staticmethod @callback @@ -83,55 +51,8 @@ class OptionsFlowHandler(config_entries.OptionsFlow): if user_input is not None: return self.async_create_entry(title="", data=user_input) - options = self.config_entry.options - - lights = options.get(CONF_LIGHTS, DEFAULT_LIGHTS) - disable_brightness_adjust = options.get(CONF_DISABLE_BRIGHTNESS_ADJUST, DEFAULT_DISABLE_BRIGHTNESS_ADJUST) - 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_color_temp = options.get(CONF_MAX_COLOR_TEMP, DEFAULT_MAX_COLOR_TEMP) - min_brightness = options.get(CONF_MIN_BRIGHTNESS, DEFAULT_MIN_BRIGHTNESS) - min_color_temp = options.get(CONF_MIN_COLOR_TEMP, DEFAULT_MIN_COLOR_TEMP) - only_once = options.get(CONF_ONLY_ONCE, DEFAULT_ONLY_ONCE) - sleep_brightness = options.get(CONF_SLEEP_BRIGHTNESS, DEFAULT_SLEEP_BRIGHTNESS) - sleep_color_temp = options.get(CONF_SLEEP_COLOR_TEMP, DEFAULT_SLEEP_COLOR_TEMP) - sleep_entity = options.get(CONF_SLEEP_ENTITY) - sleep_state = options.get(CONF_SLEEP_STATE) - sunrise_offset = options.get(CONF_SUNRISE_OFFSET, DEFAULT_SUNRISE_OFFSET) - sunrise_time = options.get(CONF_SUNRISE_TIME) - sunset_offset = options.get(CONF_SUNSET_OFFSET, DEFAULT_SUNSET_OFFSET) - 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, default=lights): 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_COLOR_TEMP, default=max_color_temp): 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_COLOR_TEMP, default=min_color_temp): 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_COLOR_TEMP, default=sleep_color_temp): 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, - } + _convert_to_options_schema(self.hass, self.config_entry.options) ) return self.async_show_form(step_id="init", data_schema=options_schema) diff --git a/custom_components/adaptive_lighting/const.py b/custom_components/adaptive_lighting/const.py index 9075ed06..51a97a0d 100644 --- a/custom_components/adaptive_lighting/const.py +++ b/custom_components/adaptive_lighting/const.py @@ -1,3 +1,8 @@ +import voluptuous as vol + +import homeassistant.helpers.config_validation as cv +from homeassistant.components.light import VALID_TRANSITION + ICON = "mdi:theme-light-dark" DOMAIN = "adaptive_lighting" @@ -27,3 +32,64 @@ CONF_SUNRISE_TIME = "sunrise_time" CONF_SUNSET_OFFSET, DEFAULT_SUNSET_OFFSET = "sunset_offset", 0 CONF_SUNSET_TIME = "sunset_time" CONF_TRANSITION, DEFAULT_TRANSITION = "transition", 60 + + +_COMMON_SCHEMA = { + vol.Optional(CONF_LIGHTS, default=DEFAULT_LIGHTS): cv.entity_ids, + vol.Optional( + CONF_DISABLE_BRIGHTNESS_ADJUST, default=DEFAULT_DISABLE_BRIGHTNESS_ADJUST + ): cv.boolean, + vol.Optional(CONF_DISABLE_ENTITY): cv.entity_id, + vol.Optional(CONF_DISABLE_STATE): vol.All(cv.ensure_list, [cv.string]), + vol.Optional( + CONF_INITIAL_TRANSITION, default=DEFAULT_INITIAL_TRANSITION + ): VALID_TRANSITION, + vol.Optional(CONF_INTERVAL, default=DEFAULT_INTERVAL): cv.time_period, + vol.Optional(CONF_MAX_BRIGHTNESS, default=DEFAULT_MAX_BRIGHTNESS): vol.All( + vol.Coerce(int), vol.Range(min=1, max=100) + ), + vol.Optional(CONF_MAX_COLOR_TEMP, default=DEFAULT_MAX_COLOR_TEMP): vol.All( + vol.Coerce(int), vol.Range(min=1000, max=10000) + ), + vol.Optional(CONF_MIN_BRIGHTNESS, default=DEFAULT_MIN_BRIGHTNESS): vol.All( + vol.Coerce(int), vol.Range(min=1, max=100) + ), + vol.Optional(CONF_MIN_COLOR_TEMP, default=DEFAULT_MIN_COLOR_TEMP): vol.All( + vol.Coerce(int), vol.Range(min=1000, max=10000) + ), + vol.Optional(CONF_ONLY_ONCE, default=DEFAULT_ONLY_ONCE): cv.boolean, + vol.Optional(CONF_SLEEP_BRIGHTNESS, default=DEFAULT_SLEEP_BRIGHTNESS): vol.All( + vol.Coerce(int), vol.Range(min=1, max=100) + ), + vol.Optional(CONF_SLEEP_COLOR_TEMP, default=DEFAULT_SLEEP_COLOR_TEMP): vol.All( + vol.Coerce(int), vol.Range(min=1000, max=10000) + ), + vol.Optional(CONF_SLEEP_ENTITY): cv.entity_id, + vol.Optional(CONF_SLEEP_STATE): vol.All(cv.ensure_list, [cv.string]), + vol.Optional(CONF_SUNRISE_OFFSET, default=DEFAULT_SUNRISE_OFFSET): cv.time_period, + vol.Optional(CONF_SUNRISE_TIME): cv.time, + vol.Optional(CONF_SUNSET_OFFSET, default=DEFAULT_SUNSET_OFFSET): cv.time_period, + vol.Optional(CONF_SUNSET_TIME): cv.time, + vol.Optional(CONF_TRANSITION, default=DEFAULT_TRANSITION): VALID_TRANSITION, +} + + +def _convert_to_options_schema(hass, options): + schema = {} + for key, value in _COMMON_SCHEMA.items(): + if key.schema == CONF_LIGHTS: + all_lights = hass.states.async_entity_ids("light") + value = cv.multi_select(all_lights) + elif value == cv.boolean: + value = bool + elif ( + isinstance(value, vol.All) and value.validators[0].type == int + ) or value == VALID_TRANSITION: + pass + elif value == cv.time_period: + value = cv.time_period_dict + else: + value = str + default = options.get(key.schema, value.default()) + schema[vol.Optional(key.schema, default=default)] = value + return vol.Schema(schema) diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index e461c7c6..d394199c 100755 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -47,7 +47,6 @@ from homeassistant.components.light import ( SUPPORT_COLOR, SUPPORT_COLOR_TEMP, SUPPORT_TRANSITION, - VALID_TRANSITION, is_on, ) from homeassistant.components.switch import SwitchEntity @@ -75,6 +74,7 @@ from homeassistant.util.color import ( ) from .const import ( + _COMMON_SCHEMA, CONF_DISABLE_BRIGHTNESS_ADJUST, CONF_DISABLE_ENTITY, CONF_DISABLE_STATE, @@ -95,20 +95,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, ICON, SUN_EVENT_MIDNIGHT, @@ -131,26 +117,7 @@ PLATFORM_SCHEMA = vol.Schema( { vol.Required(CONF_PLATFORM): DOMAIN, vol.Optional(CONF_NAME, default="Adaptive Lighting"): cv.string, - vol.Optional(CONF_LIGHTS, default=DEFAULT_LIGHTS): cv.entity_ids, - vol.Optional(CONF_DISABLE_BRIGHTNESS_ADJUST, default=DEFAULT_DISABLE_BRIGHTNESS_ADJUST): cv.boolean, - vol.Optional(CONF_DISABLE_ENTITY): cv.entity_id, - vol.Optional(CONF_DISABLE_STATE): vol.All(cv.ensure_list, [cv.string]), - vol.Optional(CONF_INITIAL_TRANSITION, default=DEFAULT_INITIAL_TRANSITION): VALID_TRANSITION, - vol.Optional(CONF_INTERVAL, default=DEFAULT_INTERVAL): cv.time_period, - vol.Optional(CONF_MAX_BRIGHTNESS, default=DEFAULT_MAX_BRIGHTNESS): vol.All(vol.Coerce(int), vol.Range(min=1, max=100)), - vol.Optional(CONF_MAX_COLOR_TEMP, default=DEFAULT_MAX_COLOR_TEMP): vol.All(vol.Coerce(int), vol.Range(min=1000, max=10000)), - vol.Optional(CONF_MIN_BRIGHTNESS, default=DEFAULT_MIN_BRIGHTNESS): vol.All(vol.Coerce(int), vol.Range(min=1, max=100)), - vol.Optional(CONF_MIN_COLOR_TEMP, default=DEFAULT_MIN_COLOR_TEMP): vol.All(vol.Coerce(int), vol.Range(min=1000, max=10000)), - vol.Optional(CONF_ONLY_ONCE, default=DEFAULT_ONLY_ONCE): cv.boolean, - vol.Optional(CONF_SLEEP_BRIGHTNESS, default=DEFAULT_SLEEP_BRIGHTNESS): vol.All(vol.Coerce(int), vol.Range(min=1, max=100)), - vol.Optional(CONF_SLEEP_COLOR_TEMP, default=DEFAULT_SLEEP_COLOR_TEMP): vol.All(vol.Coerce(int), vol.Range(min=1000, max=10000)), - vol.Optional(CONF_SLEEP_ENTITY): cv.entity_id, - vol.Optional(CONF_SLEEP_STATE): vol.All(cv.ensure_list, [cv.string]), - vol.Optional(CONF_SUNRISE_OFFSET, default=DEFAULT_SUNRISE_OFFSET): cv.time_period, - vol.Optional(CONF_SUNRISE_TIME): cv.time, - vol.Optional(CONF_SUNSET_OFFSET, default=DEFAULT_SUNSET_OFFSET): cv.time_period, - vol.Optional(CONF_SUNSET_TIME): cv.time, - vol.Optional(CONF_TRANSITION, default=DEFAULT_TRANSITION): VALID_TRANSITION, + **_COMMON_SCHEMA, } ) @@ -193,13 +160,28 @@ def _difference_between_states(from_state, to_state): if to_state is None: return start + f"from_state: {from_state}, to_state: None" - changed_attrs = ", ".join([f"{key}: {val}" for key, val in to_state.attributes.items() if from_state.attributes.get(key) != val]) + changed_attrs = ", ".join( + [ + f"{key}: {val}" + for key, val in to_state.attributes.items() + if from_state.attributes.get(key) != val + ] + ) if from_state.state == to_state.state: - return start + (f"{from_state.entity_id} is still {to_state.state} but" f" these attributes changes: {changed_attrs}.") + return start + ( + f"{from_state.entity_id} is still {to_state.state} but" + f" these attributes changes: {changed_attrs}." + ) elif changed_attrs != "": - return start + (f"{from_state.entity_id} changed from {from_state.state} to" f" {to_state.state} and these attributes changes: {changed_attrs}.") + return start + ( + f"{from_state.entity_id} changed from {from_state.state} to" + f" {to_state.state} and these attributes changes: {changed_attrs}." + ) else: - return start + (f"{from_state.entity_id} changed from {from_state.state} to" f" {to_state.state} and no attributes changed.") + return start + ( + f"{from_state.entity_id} changed from {from_state.state} to" + f" {to_state.state} and no attributes changed." + ) class AdaptiveSwitch(SwitchEntity, RestoreEntity): @@ -288,7 +270,9 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): def _supported_features(self, light): state = self.hass.states.get(light) supported_features = state.attributes["supported_features"] - return {key for key, value in _SUPPORT_OPTS.items() if supported_features & value} + return { + key for key, value in _SUPPORT_OPTS.items() if supported_features & value + } def _unpack_light_groups(self, lights): all_lights = [] @@ -310,7 +294,11 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): """Call when entity about to be added to hass.""" if self._lights: async_track_state_change( - self.hass, self._unpack_light_groups(self._lights), self._light_state_changed, to_state="on", from_state="off", + self.hass, + self._unpack_light_groups(self._lights), + self._light_state_changed, + to_state="on", + from_state="off", ) track_kwargs = dict(hass=self.hass, action=self._state_changed) if self._sleep_entity is not None: @@ -320,7 +308,9 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): if self._disable_entity is not None: disable_kwargs = dict(track_kwargs, entity_ids=self._disable_entity) - async_track_state_change(**disable_kwargs, from_state=self._disable_state) + async_track_state_change( + **disable_kwargs, from_state=self._disable_state + ) async_track_state_change(**disable_kwargs, to_state=self._disable_state) last_state = await self.async_get_last_state() @@ -351,7 +341,9 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): async def async_turn_on(self, **kwargs): """Turn on adaptive lighting.""" await self._update_lights(transition=self._initial_transition, force=True) - self.unsub_tracker = async_track_time_interval(self.hass, self._async_update_at_interval, self._interval) + self.unsub_tracker = async_track_time_interval( + self.hass, self._async_update_at_interval, self._interval + ) async def async_turn_off(self, **kwargs): """Turn off adaptive lighting.""" @@ -365,7 +357,9 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): self._percent = self._calc_percent() self._brightness = self._calc_brightness() self._color_temp_kelvin = self._calc_color_temp_kelvin() - self._color_temp_mired = color_temperature_kelvin_to_mired(self._color_temp_kelvin) + self._color_temp_mired = color_temperature_kelvin_to_mired( + self._color_temp_kelvin + ) self._rgb_color = color_temperature_to_rgb(self._color_temp_kelvin) self._xy_color = color_RGB_to_xy(*self._rgb_color) self._hs_color = color_xy_to_hs(*self._xy_color) @@ -384,11 +378,24 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): def _get_sun_events(self, date): def _replace_time(date, key): other_date = getattr(self, f"_{key}_time") - return date.replace(hour=other_date.hour, minute=other_date.minute, second=other_date.second, microsecond=other_date.microsecond,) + return date.replace( + hour=other_date.hour, + minute=other_date.minute, + second=other_date.second, + microsecond=other_date.microsecond, + ) location = get_astral_location(self.hass) - sunrise = (location.sunrise(date, local=False) if self._sunrise_time is None else _replace_time(date, "sunrise")) + self._sunrise_offset - sunset = (location.sunset(date, local=False) if self._sunset_time is None else _replace_time(date, "sunset")) + self._sunset_offset + sunrise = ( + location.sunrise(date, local=False) + if self._sunrise_time is None + else _replace_time(date, "sunrise") + ) + self._sunrise_offset + sunset = ( + location.sunset(date, local=False) + if self._sunset_time is None + else _replace_time(date, "sunset") + ) + self._sunset_offset if self._sunrise_time is None and self._sunset_time is None: solar_noon = location.solar_noon(date, local=False) @@ -413,7 +420,10 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): # It's before sunrise (after midnight), because it's before # sunrise (and after midnight) sunset must have happend yesterday. yesterday = self._get_sun_events(now - timedelta(days=1)) - if today[SUN_EVENT_MIDNIGHT] > today[SUN_EVENT_SUNSET] and yesterday[SUN_EVENT_MIDNIGHT] > yesterday[SUN_EVENT_SUNSET]: + if ( + today[SUN_EVENT_MIDNIGHT] > today[SUN_EVENT_SUNSET] + and yesterday[SUN_EVENT_MIDNIGHT] > yesterday[SUN_EVENT_SUNSET] + ): # Solar midnight is after sunset so use yesterdays's time today[SUN_EVENT_MIDNIGHT] = yesterday[SUN_EVENT_MIDNIGHT] today[SUN_EVENT_SUNSET] = yesterday[SUN_EVENT_SUNSET] @@ -421,7 +431,10 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): # It's after sunset (before midnight), because it's after sunset # (and before midnight) sunrise should happen tomorrow. tomorrow = self._get_sun_events(now + timedelta(days=1)) - if today[SUN_EVENT_MIDNIGHT] < today[SUN_EVENT_SUNRISE] and tomorrow[SUN_EVENT_MIDNIGHT] < tomorrow[SUN_EVENT_SUNRISE]: + if ( + today[SUN_EVENT_MIDNIGHT] < today[SUN_EVENT_SUNRISE] + and tomorrow[SUN_EVENT_MIDNIGHT] < tomorrow[SUN_EVENT_SUNRISE] + ): # Solar midnight is before sunrise so use tomorrow's time today[SUN_EVENT_MIDNIGHT] = tomorrow[SUN_EVENT_MIDNIGHT] today[SUN_EVENT_SUNRISE] = tomorrow[SUN_EVENT_SUNRISE] @@ -437,14 +450,22 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): h = today[SUN_EVENT_NOON] k = 1 # parabola before solar_noon else after solar_noon - x = today[SUN_EVENT_SUNRISE] if now_ts < today[SUN_EVENT_NOON] else today[SUN_EVENT_SUNSET] + x = ( + today[SUN_EVENT_SUNRISE] + if now_ts < today[SUN_EVENT_NOON] + else today[SUN_EVENT_SUNSET] + ) # sunset -> sunrise parabola elif today[SUN_EVENT_SUNSET] < now_ts < today[SUN_EVENT_SUNRISE]: h = today[SUN_EVENT_MIDNIGHT] k = -1 # parabola before solar_midnight else after solar_midnight - x = today[SUN_EVENT_SUNSET] if now_ts < today[SUN_EVENT_MIDNIGHT] else today[SUN_EVENT_SUNRISE] + x = ( + today[SUN_EVENT_SUNSET] + if now_ts < today[SUN_EVENT_MIDNIGHT] + else today[SUN_EVENT_SUNRISE] + ) y = 0 a = (y - k) / (h - x) ** 2 @@ -452,7 +473,10 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): return percentage def _is_sleep(self): - return self._sleep_entity is not None and self.hass.states.get(self._sleep_entity).state in self._sleep_state + return ( + self._sleep_entity is not None + and self.hass.states.get(self._sleep_entity).state in self._sleep_state + ) def _calc_color_temp_kelvin(self): if self._is_sleep(): @@ -474,7 +498,10 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): return (delta_brightness * percent) + self._min_brightness def _is_disabled(self): - return self._disable_entity is not None and self.hass.states.get(self._disable_entity).state in self._disable_state + return ( + self._disable_entity is not None + and self.hass.states.get(self._disable_entity).state in self._disable_state + ) async def _adjust_light(self, light, transition): service_data = {ATTR_ENTITY_ID: light} @@ -494,9 +521,12 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): service_data[ATTR_COLOR_TEMP] = self._color_temp_mired _LOGGER.debug( - "Scheduling 'light.turn_on' with the following 'service_data': %s", service_data, + "Scheduling 'light.turn_on' with the following 'service_data': %s", + service_data, + ) + return self.hass.services.async_call( + LIGHT_DOMAIN, SERVICE_TURN_ON, service_data ) - return self.hass.services.async_call(LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) def _should_adjust(self): if not self._lights or not self.is_on or self._is_disabled(): @@ -506,14 +536,20 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): async def _adjust_lights(self, lights, transition): if not self._should_adjust(): return - tasks = [await self._adjust_light(light, transition) for light in lights if is_on(self.hass, light)] + tasks = [ + await self._adjust_light(light, transition) + for light in lights + if is_on(self.hass, light) + ] if tasks: await asyncio.wait(tasks) async def _light_state_changed(self, entity_id, from_state, to_state): assert to_state.state == "on" and from_state.state == "off" _LOGGER.debug(_difference_between_states(from_state, to_state)) - await self._update_lights(lights=[entity_id], transition=self._initial_transition, force=True) + await self._update_lights( + lights=[entity_id], transition=self._initial_transition, force=True + ) async def _state_changed(self, entity_id, from_state, to_state): _LOGGER.debug(_difference_between_states(from_state, to_state))