mirror of
https://github.com/basnijholt/adaptive-lighting.git
synced 2026-09-11 22:34:04 +02:00
unify config options flow and YAML schema
This commit is contained in:
parent
48c16ff637
commit
954e022860
3 changed files with 168 additions and 145 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue