mirror of
https://github.com/basnijholt/adaptive-lighting.git
synced 2026-09-11 22:34:04 +02:00
simplify calc_percent
This commit is contained in:
parent
c1af45d46a
commit
d9deee9e52
3 changed files with 59 additions and 68 deletions
104
custom_components/circadian_lighting/__init__.py
Normal file → Executable file
104
custom_components/circadian_lighting/__init__.py
Normal file → Executable file
|
|
@ -58,6 +58,8 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
DOMAIN = "circadian_lighting"
|
||||
CIRCADIAN_LIGHTING_UPDATE_TOPIC = f"{DOMAIN}_update"
|
||||
SUN_EVENT_NOON = "solar_noon"
|
||||
SUN_EVENT_MIDNIGHT = "solar_midnight"
|
||||
|
||||
CONF_MIN_CT = "min_colortemp"
|
||||
DEFAULT_MIN_CT = 2500
|
||||
|
|
@ -195,7 +197,7 @@ class CircadianLighting:
|
|||
microsecond=int(self._time[key].strftime("%f")),
|
||||
)
|
||||
|
||||
def get_sunrise_sunset(self, date=None):
|
||||
def get_sunrise_sunset(self, date=None, as_timestamps=False):
|
||||
if self._time["sunrise"] is not None and self._time["sunset"] is not None:
|
||||
if date is None:
|
||||
date = dt_now(self._timezone)
|
||||
|
|
@ -231,65 +233,57 @@ class CircadianLighting:
|
|||
sunrise = sunrise + self._sunrise_offset
|
||||
if self._sunset_offset is not None:
|
||||
sunset = sunset + self._sunset_offset
|
||||
return {
|
||||
datetimes = {
|
||||
SUN_EVENT_SUNRISE: sunrise.astimezone(self._timezone),
|
||||
SUN_EVENT_SUNSET: sunset.astimezone(self._timezone),
|
||||
"solar_noon": solar_noon.astimezone(self._timezone),
|
||||
"solar_midnight": solar_midnight.astimezone(self._timezone),
|
||||
SUN_EVENT_NOON: solar_noon.astimezone(self._timezone),
|
||||
SUN_EVENT_MIDNIGHT: solar_midnight.astimezone(self._timezone),
|
||||
}
|
||||
if as_timestamps:
|
||||
return {k: dt.timestamp() for k, dt in datetimes.items()}
|
||||
else:
|
||||
return datetimes
|
||||
|
||||
def calc_percent(self):
|
||||
now = dt_now(self._timezone)
|
||||
_LOGGER.debug("now: " + str(now))
|
||||
|
||||
today_sun_times = self.get_sunrise_sunset(now)
|
||||
_LOGGER.debug("today_sun_times: " + str(today_sun_times))
|
||||
today = self.get_sunrise_sunset(now, as_timestamps=True)
|
||||
_LOGGER.debug("today: " + str(today))
|
||||
|
||||
# Convert everything to epoch timestamps for easy calculation
|
||||
now_seconds = now.timestamp()
|
||||
sunrise_seconds = today_sun_times[SUN_EVENT_SUNRISE].timestamp()
|
||||
sunset_seconds = today_sun_times[SUN_EVENT_SUNSET].timestamp()
|
||||
solar_noon_seconds = today_sun_times["solar_noon"].timestamp()
|
||||
solar_midnight_seconds = today_sun_times["solar_midnight"].timestamp()
|
||||
now_ts = now.timestamp()
|
||||
|
||||
if now < today_sun_times[SUN_EVENT_SUNRISE]:
|
||||
if now_ts < today[SUN_EVENT_SUNRISE]:
|
||||
# It's before sunrise (after midnight)
|
||||
# Because it's before sunrise (and after midnight) sunset must have happend yesterday
|
||||
yesterday_sun_times = self.get_sunrise_sunset(now - timedelta(days=1))
|
||||
_LOGGER.debug("yesterday_sun_times: " + str(yesterday_sun_times))
|
||||
sunset_seconds = yesterday_sun_times[SUN_EVENT_SUNSET].timestamp()
|
||||
yesterday = self.get_sunrise_sunset(
|
||||
now - timedelta(days=1), as_timestamps=True
|
||||
)
|
||||
_LOGGER.debug("yesterday: " + str(yesterday))
|
||||
today[SUN_EVENT_SUNSET] = yesterday[SUN_EVENT_SUNSET]
|
||||
if (
|
||||
today_sun_times["solar_midnight"] > today_sun_times[SUN_EVENT_SUNSET]
|
||||
and yesterday_sun_times["solar_midnight"]
|
||||
> yesterday_sun_times[SUN_EVENT_SUNSET]
|
||||
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
|
||||
solar_midnight_seconds = yesterday_sun_times[
|
||||
"solar_midnight"
|
||||
].timestamp()
|
||||
elif now > today_sun_times[SUN_EVENT_SUNSET]:
|
||||
today[SUN_EVENT_MIDNIGHT] = yesterday[SUN_EVENT_MIDNIGHT]
|
||||
elif now_ts > today[SUN_EVENT_SUNSET]:
|
||||
# It's after sunset (before midnight)
|
||||
# Because it's after sunset (and before midnight) sunrise should happen tomorrow
|
||||
tomorrow_sun_times = self.get_sunrise_sunset(now + timedelta(days=1))
|
||||
_LOGGER.debug("tomorrow_sun_times: " + str(tomorrow_sun_times))
|
||||
sunrise_seconds = tomorrow_sun_times[SUN_EVENT_SUNRISE].timestamp()
|
||||
tomorrow = self.get_sunrise_sunset(
|
||||
now + timedelta(days=1), as_timestamps=True
|
||||
)
|
||||
_LOGGER.debug("tomorrow: " + str(tomorrow))
|
||||
today[SUN_EVENT_SUNRISE] = tomorrow[SUN_EVENT_SUNRISE]
|
||||
if (
|
||||
today_sun_times["solar_midnight"] < today_sun_times[SUN_EVENT_SUNRISE]
|
||||
and tomorrow_sun_times["solar_midnight"]
|
||||
< tomorrow_sun_times[SUN_EVENT_SUNRISE]
|
||||
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
|
||||
solar_midnight_seconds = tomorrow_sun_times[
|
||||
"solar_midnight"
|
||||
].timestamp()
|
||||
today[SUN_EVENT_MIDNIGHT] = tomorrow[SUN_EVENT_MIDNIGHT]
|
||||
|
||||
_LOGGER.debug(
|
||||
f"now_seconds: {now_seconds}, "
|
||||
f"sunrise_seconds: {sunrise_seconds}, "
|
||||
f"sunset_seconds: {sunset_seconds}, "
|
||||
f"solar_midnight_seconds: {solar_midnight_seconds}, "
|
||||
f"solar_noon_seconds: {solar_noon_seconds}"
|
||||
)
|
||||
_LOGGER.debug(f"now_ts: {now_ts}, {today}")
|
||||
|
||||
# Figure out where we are in time so we know which half of the parabola to calculate
|
||||
# We're generating a different sunset-sunrise parabola for before and after solar midnight
|
||||
|
|
@ -297,31 +291,31 @@ class CircadianLighting:
|
|||
# We're also (obviously) generating a different parabola for sunrise-sunset
|
||||
|
||||
# sunrise-sunset parabola
|
||||
if now_seconds > sunrise_seconds and now_seconds < sunset_seconds:
|
||||
h = solar_noon_seconds
|
||||
if now_ts > today[SUN_EVENT_SUNRISE] and now_ts < today[SUN_EVENT_SUNSET]:
|
||||
h = today[SUN_EVENT_NOON]
|
||||
k = 100
|
||||
# parabola before solar_noon
|
||||
if now_seconds < solar_noon_seconds:
|
||||
x = sunrise_seconds
|
||||
# parabola after solar_noon
|
||||
else:
|
||||
x = sunset_seconds
|
||||
# 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]
|
||||
)
|
||||
y = 0
|
||||
|
||||
# sunset_sunrise parabola
|
||||
elif now_seconds > sunset_seconds and now_seconds < sunrise_seconds:
|
||||
h = solar_midnight_seconds
|
||||
elif now_ts > today[SUN_EVENT_SUNSET] and now_ts < today[SUN_EVENT_SUNRISE]:
|
||||
h = today[SUN_EVENT_MIDNIGHT]
|
||||
k = -100
|
||||
# parabola before solar_midnight
|
||||
if now_seconds < solar_midnight_seconds:
|
||||
x = sunset_seconds
|
||||
# parabola after solar_midnight
|
||||
else:
|
||||
x = sunrise_seconds
|
||||
# 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]
|
||||
)
|
||||
y = 0
|
||||
|
||||
a = (y - k) / (h - x) ** 2
|
||||
percentage = a * (now_seconds - h) ** 2 + k
|
||||
percentage = a * (now_ts - h) ** 2 + k
|
||||
|
||||
_LOGGER.debug(
|
||||
f"h: {h}, k: {k}, x: {x}, y: {y}, a: {a}, percentage: {percentage}"
|
||||
|
|
|
|||
0
custom_components/circadian_lighting/sensor.py
Normal file → Executable file
0
custom_components/circadian_lighting/sensor.py
Normal file → Executable file
23
custom_components/circadian_lighting/switch.py
Normal file → Executable file
23
custom_components/circadian_lighting/switch.py
Normal file → Executable file
|
|
@ -99,7 +99,7 @@ PLATFORM_SCHEMA = vol.Schema(
|
|||
vol.Optional(
|
||||
CONF_INITIAL_TRANSITION, default=DEFAULT_INITIAL_TRANSITION
|
||||
): VALID_TRANSITION,
|
||||
vol.Optional(CONF_ONCE_ONLY): cv.boolean,
|
||||
vol.Optional(CONF_ONCE_ONLY, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -359,22 +359,19 @@ class CircadianSwitch(SwitchEntity, RestoreEntity):
|
|||
_LOGGER.debug(f"{light} {which} Adjusted - {msg}")
|
||||
|
||||
def light_state_changed(self, entity_id, from_state, to_state):
|
||||
with suppress(Exception):
|
||||
_LOGGER.debug(f"{entity_id} change from {from_state} to {to_state}")
|
||||
if to_state.state == "on" and from_state.state != "on":
|
||||
self.adjust_lights([entity_id], self._initial_transition)
|
||||
_LOGGER.debug(f"{entity_id} change from {from_state} to {to_state}")
|
||||
if to_state.state == "on" and from_state.state != "on":
|
||||
self.adjust_lights([entity_id], self._initial_transition)
|
||||
|
||||
def sleep_state_changed(self, entity_id, from_state, to_state):
|
||||
with suppress(Exception):
|
||||
_LOGGER.debug(f"{entity_id} change from {from_state} to {to_state}")
|
||||
if (
|
||||
to_state.state == self._sleep_state
|
||||
_LOGGER.debug(f"{entity_id} change from {from_state} to {to_state}")
|
||||
if (
|
||||
to_state.state == self._sleep_state
|
||||
or from_state.state == self._sleep_state
|
||||
):
|
||||
self._update_switch(self._initial_transition, force=True)
|
||||
|
||||
def disable_state_changed(self, entity_id, from_state, to_state):
|
||||
with suppress(Exception):
|
||||
_LOGGER.debug("{entity_id} change from {from_state} to {to_state}")
|
||||
if from_state.state == self._disable_state:
|
||||
self._update_switch(self._initial_transition, force=True)
|
||||
_LOGGER.debug("{entity_id} change from {from_state} to {to_state}")
|
||||
if from_state.state == self._disable_state:
|
||||
self._update_switch(self._initial_transition, force=True)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue