51 lines
1.7 KiB
Python
51 lines
1.7 KiB
Python
import logging
|
|
from datetime import datetime, timedelta
|
|
|
|
import ephem
|
|
|
|
from app.observer.Timer import track_time_change
|
|
|
|
STATE_CATEGORY_TEMPLATE_SOLAR = "solar.{}"
|
|
|
|
STATE_CATEGORY_SUN = STATE_CATEGORY_TEMPLATE_SOLAR.format("sun")
|
|
|
|
SOLAR_STATE_ABOVE_HORIZON = "above_horizon"
|
|
SOLAR_STATE_BELOW_HORIZON = "below_horizon"
|
|
|
|
class WeatherWatcher:
|
|
def __init__(self, config, eventbus, statemachine):
|
|
self.logger = logging.getLogger("WeatherWatcher")
|
|
self.config = config
|
|
self.eventbus = eventbus
|
|
self.statemachine = statemachine
|
|
|
|
statemachine.add_category(STATE_CATEGORY_SUN, SOLAR_STATE_BELOW_HORIZON)
|
|
|
|
self.update_sun_state()
|
|
|
|
def update_sun_state(self, now=datetime.now()):
|
|
self.update_solar_state(ephem.Sun(), STATE_CATEGORY_SUN, self.update_sun_state)
|
|
|
|
def update_solar_state(self, solar_object, state_category, update_callback):
|
|
# We don't cache these objects because we use them so rarely
|
|
observer = ephem.Observer()
|
|
observer.lat = self.config.get('common','latitude')
|
|
observer.long = self.config.get('common','longitude')
|
|
|
|
next_rising = ephem.localtime(observer.next_rising(solar_object))
|
|
next_setting = ephem.localtime(observer.next_setting(solar_object))
|
|
|
|
if next_rising > next_setting:
|
|
new_state = SOLAR_STATE_ABOVE_HORIZON
|
|
next_change = next_setting
|
|
|
|
else:
|
|
new_state = SOLAR_STATE_BELOW_HORIZON
|
|
next_change = next_rising
|
|
|
|
self.logger.info("Updating solar state for {} to {}. Next change: {}".format(state_category, new_state, next_change))
|
|
|
|
self.statemachine.set_state(state_category, new_state)
|
|
|
|
# +10 seconds to be sure that the change has occured
|
|
track_time_change(self.eventbus, update_callback, datetime=next_change + timedelta(seconds=10))
|