created get_next functions

This commit is contained in:
John Lancaster
2023-03-26 23:12:04 -05:00
parent 22ad5180a3
commit dce065a996

View File

@@ -1,7 +1,7 @@
import logging import logging
from contextlib import suppress from contextlib import suppress
from dataclasses import InitVar, dataclass, field from dataclasses import InitVar, dataclass, field
from datetime import datetime, timedelta from datetime import datetime, timedelta, tzinfo
from typing import Dict, Iterable from typing import Dict, Iterable
import astral import astral
@@ -14,6 +14,7 @@ from IPython.display import display
HOME_TZ = datetime.now().astimezone().tzinfo HOME_TZ = datetime.now().astimezone().tzinfo
def format_x_axis(fig): def format_x_axis(fig):
ax: plt.Axes = fig.axes[0] ax: plt.Axes = fig.axes[0]
ax.xaxis.set_major_locator(mdates.HourLocator(byhour=range(0, 24, 2))) ax.xaxis.set_major_locator(mdates.HourLocator(byhour=range(0, 24, 2)))
@@ -29,7 +30,44 @@ def normalize(s: pd.Series, min=None, max=None):
return ((s - min) / rng) * 100 return ((s - min) / rng) * 100
def get_next_time_at_elevation(*args, **kwargs):
time = time_at_elevation(*args, **kwargs)
if time < (now := datetime.now(HOME_TZ)):
time = time_at_elevation(
*args,
date=(now + timedelta(days=1)).date(),
**kwargs
)
return time
def get_next_sun_time(named_time: str, observer: Observer):
sun_times_dict = sun(observer, datetime.today().date())
try:
time = sun_times_dict[named_time].astimezone()
except KeyError:
time = datetime.combine(
datetime.today().date(),
datetime.strptime(named_time, '%I:%M:%S%p').time()
).astimezone()
if time < (now := datetime.now(HOME_TZ)):
tomorrow = (now + timedelta(days=1)).date()
sun_times_dict = sun(observer, tomorrow)
try:
time = sun_times_dict[named_time].astimezone()
except KeyError:
time = datetime.combine(
tomorrow,
datetime.strptime(named_time, '%I:%M:%S%p').time()
).astimezone()
return time
def parse_periods(observer: Observer, periods: Dict): def parse_periods(observer: Observer, periods: Dict):
now = datetime.now(HOME_TZ)
for period in periods: for period in periods:
if 'elevation' in period: if 'elevation' in period:
if period['direction'] == 'rising': if period['direction'] == 'rising':
@@ -38,24 +76,19 @@ def parse_periods(observer: Observer, periods: Dict):
dir = SunDirection.SETTING dir = SunDirection.SETTING
if isinstance(period['elevation'], int): if isinstance(period['elevation'], int):
time = time_at_elevation( time = get_next_time_at_elevation(
observer, observer,
elevation=period['elevation'], elevation=period['elevation'],
direction=dir, direction=dir,
tzinfo=HOME_TZ, tzinfo=HOME_TZ,
) )
elif period['elevation'] == 'min': elif period['elevation'] == 'min':
pass pass
elif period['elevation'] == 'max': elif period['elevation'] == 'max':
pass pass
elif 'time' in period: elif 'time' in period:
try: time = get_next_sun_time(period['time'], observer)
time = sun(observer, datetime.today().date())[period['time']].astimezone()
except:
time = datetime.combine(
datetime.today().date(),
datetime.strptime(period['time'], '%I:%M:%S%p').time()
).astimezone()
# res = {'time': time.replace(tzinfo=None)} # res = {'time': time.replace(tzinfo=None)}
# res = {'time': time.replace(tzinfo=HOME_TZ)} # res = {'time': time.replace(tzinfo=HOME_TZ)}
@@ -64,7 +97,6 @@ def parse_periods(observer: Observer, periods: Dict):
yield res yield res
@dataclass @dataclass
class DaylightAdjuster: class DaylightAdjuster:
latitude: float latitude: float
@@ -75,28 +107,30 @@ class DaylightAdjuster:
def __post_init__(self, periods: Dict, resolution: int): def __post_init__(self, periods: Dict, resolution: int):
self.logger: logging.Logger = logging.getLogger(type(self).__name__) self.logger: logging.Logger = logging.getLogger(type(self).__name__)
today = self.datetime.date() now = datetime.now().astimezone()
times = pd.date_range( times = pd.date_range(
today, today + timedelta(days=1), start=now, end=now + timedelta(days=1),
periods=resolution, periods=resolution,
tz=HOME_TZ tz=HOME_TZ
) )
self.logger.debug(times)
pytimes = (dt.to_pydatetime() for dt in times) pytimes = [dt.to_pydatetime() for dt in times]
el = pd.Series( el = pd.Series(
(elevation(self.observer, dt) for dt in pytimes), (elevation(self.observer, dt) for dt in pytimes),
index=times, name='elevation' index=times, name='elevation'
) )
self.logger.debug(el)
# el.index = el.index.tz_convert(HOME_TZ) # el.index = el.index.tz_convert(HOME_TZ)
# el.index = el.index.tz_convert(None) # el.index = el.index.tz_convert(None)
self.periods = parse_periods(self.observer, periods)
# self.df = pd.DataFrame(el) # self.df = pd.DataFrame(el)
self.df = pd.concat([ self.df = pd.concat([pd.DataFrame(self.periods).set_index('time'), el], axis=1)
pd.DataFrame(parse_periods(self.observer, periods)).set_index('time'), self.df = self.df.sort_index().interpolate().bfill().ffill()
el
], axis=1).sort_index().interpolate().bfill().ffill()
# self.df.index = self.df.index.to_series().dt.tz_localize(None) # self.df.index = self.df.index.to_series().dt.tz_localize(None)
@@ -110,12 +144,15 @@ class DaylightAdjuster:
def elevation_fig(self): def elevation_fig(self):
fig, ax = plt.subplots(figsize=(10, 7)) fig, ax = plt.subplots(figsize=(10, 7))
handles = ax.plot(self.df['elevation']) elevation = self.df['elevation']
elevation.index = elevation.index.to_series().dt.tz_localize(None)
handles = ax.plot(elevation)
ax.set_ylabel('Elevation') ax.set_ylabel('Elevation')
ax.set_ylim(-100, 100) ax.set_ylim(-100, 100)
format_x_axis(fig) format_x_axis(fig)
ax.set_xlim(self.df.index[0], self.df.index[-1]) ax.set_xlim(elevation.index[0], elevation.index[-1])
print(elevation)
# ax.xaxis_date(HOME_TZ) # ax.xaxis_date(HOME_TZ)
@@ -125,9 +162,9 @@ class DaylightAdjuster:
ax2.set_ylabel('Brightness') ax2.set_ylabel('Brightness')
ax2.set_ylim(0, 100) ax2.set_ylim(0, 100)
handles.append(ax.axvline(datetime.now(), # handles.append(ax.axvline(datetime.now().astimezone(),
linestyle='--', # linestyle='--',
color='g')) # color='g'))
# handles.append(ax2.axhline(self.get_brightness(), # handles.append(ax2.axhline(self.get_brightness(),
# linestyle='--', # linestyle='--',