Next sun rising and sun setting are now in statemachine.
parent
cb4fce7691
commit
97e82b3808
|
@ -9,13 +9,14 @@ This module provides actors that will react to events happening within homeassis
|
|||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import dateutil.parser
|
||||
from phue import Bridge
|
||||
|
||||
from . import track_state_change
|
||||
|
||||
from .observers import (STATE_CATEGORY_SUN, SUN_STATE_BELOW_HORIZON, SUN_STATE_ABOVE_HORIZON,
|
||||
STATE_CATEGORY_ALL_DEVICES, DEVICE_STATE_HOME, DEVICE_STATE_NOT_HOME,
|
||||
track_time_change)
|
||||
STATE_CATEGORY_NEXT_SUN_SETTING, track_time_change)
|
||||
|
||||
LIGHT_TRANSITION_TIME = timedelta(minutes=15)
|
||||
|
||||
|
@ -30,10 +31,9 @@ def _hue_process_transition_time(transition_seconds):
|
|||
class LightTrigger(object):
|
||||
""" Class to turn on lights based on available devices and state of the sun. """
|
||||
|
||||
def __init__(self, eventbus, statemachine, weather, device_tracker, light_control):
|
||||
def __init__(self, eventbus, statemachine, device_tracker, light_control):
|
||||
self.eventbus = eventbus
|
||||
self.statemachine = statemachine
|
||||
self.weather = weather
|
||||
self.light_control = light_control
|
||||
|
||||
self.logger = logging.getLogger(__name__)
|
||||
|
@ -58,7 +58,7 @@ class LightTrigger(object):
|
|||
We will schedule to have each light start after one another
|
||||
and slowly transition in."""
|
||||
|
||||
start_point = self._get_start_point_turn_light_before_sun_set()
|
||||
start_point = self._start_point_turn_light_before_sun_set()
|
||||
|
||||
def turn_on(light_id):
|
||||
""" Lambda can keep track of function parameters, not from local parameters
|
||||
|
@ -87,7 +87,7 @@ class LightTrigger(object):
|
|||
if category != STATE_CATEGORY_ALL_DEVICES and new_state.state == DEVICE_STATE_HOME:
|
||||
# These variables are needed for the elif check
|
||||
now = datetime.now()
|
||||
start_point = self._get_start_point_turn_light_before_sun_set()
|
||||
start_point = self._start_point_turn_light_before_sun_set()
|
||||
|
||||
# Do we need lights?
|
||||
if light_needed:
|
||||
|
@ -96,7 +96,7 @@ class LightTrigger(object):
|
|||
|
||||
# Are we in the time span were we would turn on the lights if someone would be home?
|
||||
# Check this by seeing if current time is later then the start point
|
||||
elif now > start_point and now < self.weather.next_sun_setting():
|
||||
elif now > start_point and now < self._next_sun_setting():
|
||||
|
||||
# If this is the case check for every light if it would be on
|
||||
# if someone was home when the fading in started and turn it on
|
||||
|
@ -116,11 +116,14 @@ class LightTrigger(object):
|
|||
self.logger.info("Everyone has left but lights are on. Turning lights off")
|
||||
self.light_control.turn_light_off()
|
||||
|
||||
def _next_sun_setting(self):
|
||||
""" Returns the datetime object representing the next sun setting. """
|
||||
return dateutil.parser.parse(self.statemachine.get_state(STATE_CATEGORY_NEXT_SUN_SETTING).state)
|
||||
|
||||
def _get_start_point_turn_light_before_sun_set(self):
|
||||
def _start_point_turn_light_before_sun_set(self):
|
||||
""" Helper method to calculate the point in time we have to start fading in lights
|
||||
so that all the lights are on the moment the sun sets. """
|
||||
return self.weather.next_sun_setting() - LIGHT_TRANSITION_TIME * len(self.light_control.light_ids)
|
||||
return self._next_sun_setting() - LIGHT_TRANSITION_TIME * len(self.light_control.light_ids)
|
||||
|
||||
|
||||
class HueLightControl(object):
|
||||
|
|
|
@ -21,6 +21,8 @@ import ephem
|
|||
from . import track_time_change
|
||||
|
||||
STATE_CATEGORY_SUN = "weather.sun"
|
||||
STATE_CATEGORY_NEXT_SUN_RISING = "weather.next_sun_rising"
|
||||
STATE_CATEGORY_NEXT_SUN_SETTING = "weather.next_setting"
|
||||
STATE_CATEGORY_ALL_DEVICES = 'all_devices'
|
||||
STATE_CATEGORY_DEVICE_FORMAT = '{}'
|
||||
|
||||
|
@ -37,46 +39,19 @@ TOMATO_MIN_TIME_BETWEEN_SCANS = timedelta(seconds=5)
|
|||
TOMATO_KNOWN_DEVICES_FILE = "tomato_known_devices.csv"
|
||||
|
||||
|
||||
class WeatherWatcher(object):
|
||||
""" Class that keeps track of the state of the sun. """
|
||||
def track_sun(eventbus, statemachine, latitude, longitude):
|
||||
""" Tracks the state of the sun. """
|
||||
|
||||
def __init__(self, eventbus, statemachine, latitude, longitude):
|
||||
self.logger = logging.getLogger(__name__)
|
||||
self.eventbus = eventbus
|
||||
self.statemachine = statemachine
|
||||
self.latitude = latitude
|
||||
self.longitude = longitude
|
||||
sun = ephem.Sun()
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
self.sun = ephem.Sun()
|
||||
def update_sun_state(now):
|
||||
observer = ephem.Observer()
|
||||
observer.lat = latitude
|
||||
observer.long = longitude
|
||||
|
||||
self._update_sun_state()
|
||||
|
||||
|
||||
def next_sun_rising(self, observer=None):
|
||||
""" Returns a datetime object that points at the next sun rising. """
|
||||
|
||||
if observer is None:
|
||||
observer = self._get_observer()
|
||||
|
||||
return ephem.localtime(observer.next_rising(self.sun))
|
||||
|
||||
|
||||
def next_sun_setting(self, observer=None):
|
||||
""" Returns a datetime object that points at the next sun setting. """
|
||||
|
||||
if observer is None:
|
||||
observer = self._get_observer()
|
||||
|
||||
return ephem.localtime(observer.next_setting(self.sun))
|
||||
|
||||
|
||||
def _update_sun_state(self, now=None):
|
||||
""" Updates the state of the sun and schedules when to check next. """
|
||||
|
||||
observer = self._get_observer()
|
||||
|
||||
next_rising = self.next_sun_rising(observer)
|
||||
next_setting = self.next_sun_setting(observer)
|
||||
next_rising = ephem.localtime(observer.next_rising(sun))
|
||||
next_setting = ephem.localtime(observer.next_setting(sun))
|
||||
|
||||
if next_rising > next_setting:
|
||||
new_state = SUN_STATE_ABOVE_HORIZON
|
||||
|
@ -86,21 +61,17 @@ class WeatherWatcher(object):
|
|||
new_state = SUN_STATE_BELOW_HORIZON
|
||||
next_change = next_rising
|
||||
|
||||
self.logger.info("Sun:{}. Next change: {}".format(new_state, next_change.strftime("%H:%M")))
|
||||
logger.info("Sun:{}. Next change: {}".format(new_state, next_change.strftime("%H:%M")))
|
||||
|
||||
self.statemachine.set_state(STATE_CATEGORY_SUN, new_state)
|
||||
statemachine.set_state(STATE_CATEGORY_SUN, new_state)
|
||||
statemachine.set_state(STATE_CATEGORY_NEXT_SUN_RISING, next_rising.isoformat())
|
||||
statemachine.set_state(STATE_CATEGORY_NEXT_SUN_SETTING, next_setting.isoformat())
|
||||
|
||||
# +10 seconds to be sure that the change has occured
|
||||
track_time_change(self.eventbus, self._update_sun_state, point_in_time=next_change + timedelta(seconds=10))
|
||||
track_time_change(eventbus, update_sun_state, point_in_time=next_change + timedelta(seconds=10))
|
||||
|
||||
update_sun_state(None)
|
||||
|
||||
def _get_observer(self):
|
||||
""" Creates an observer representing the location and the current time. """
|
||||
observer = ephem.Observer()
|
||||
observer.lat = self.latitude
|
||||
observer.long = self.longitude
|
||||
|
||||
return observer
|
||||
|
||||
class DeviceTracker(object):
|
||||
""" Class that tracks which devices are home and which are not. """
|
||||
|
|
8
start.py
8
start.py
|
@ -2,7 +2,7 @@ from ConfigParser import SafeConfigParser
|
|||
|
||||
from homeassistant import StateMachine, EventBus, start_home_assistant
|
||||
|
||||
from homeassistant.observers import TomatoDeviceScanner, DeviceTracker, WeatherWatcher
|
||||
from homeassistant.observers import TomatoDeviceScanner, DeviceTracker, track_sun
|
||||
from homeassistant.actors import HueLightControl, LightTrigger
|
||||
from homeassistant.httpinterface import HTTPInterface
|
||||
|
||||
|
@ -20,12 +20,10 @@ tomato = TomatoDeviceScanner(config.get('tomato','host'), config.get('tomato','u
|
|||
|
||||
devicetracker = DeviceTracker(eventbus, statemachine, tomato)
|
||||
|
||||
weatherwatcher = WeatherWatcher(eventbus, statemachine,
|
||||
config.get("common","latitude"),
|
||||
config.get("common","longitude"))
|
||||
track_sun(eventbus, statemachine, config.get("common","latitude"), config.get("common","longitude"))
|
||||
|
||||
# Init actors
|
||||
LightTrigger(eventbus, statemachine, weatherwatcher, devicetracker, HueLightControl())
|
||||
LightTrigger(eventbus, statemachine, devicetracker, HueLightControl())
|
||||
|
||||
# Init HTTP interface
|
||||
HTTPInterface(eventbus, statemachine, config.get("common","api_password"))
|
||||
|
|
Loading…
Reference in New Issue