From 6f3ef12d31bb4fe94da2645e2445d365eb84186f Mon Sep 17 00:00:00 2001 From: Gustav Ahlberg Date: Wed, 28 Jan 2015 20:01:16 +0100 Subject: [PATCH] Refactered event listeners so that they can be part of a component instead of having to be stand alone components --- .../components/scheduler/__init__.py | 17 ++- homeassistant/components/scheduler/sun.py | 114 ------------------ homeassistant/components/scheduler/time.py | 2 +- homeassistant/components/sun.py | 110 +++++++++++++++++ 4 files changed, 122 insertions(+), 121 deletions(-) delete mode 100644 homeassistant/components/scheduler/sun.py diff --git a/homeassistant/components/scheduler/__init__.py b/homeassistant/components/scheduler/__init__.py index c06f6acd7f5..29a09c25fb0 100644 --- a/homeassistant/components/scheduler/__init__.py +++ b/homeassistant/components/scheduler/__init__.py @@ -25,9 +25,6 @@ from homeassistant.const import ATTR_ENTITY_ID # The domain of your component. Should be equal to the name of your component DOMAIN = 'scheduler' -# List of component names (string) your component depends upon -# If you are setting up a group but not using a group for anything, -# don't depend on group DEPENDENCIES = ['sun'] _LOGGER = logging.getLogger(__name__) @@ -39,6 +36,16 @@ _SCHEDULE_FILE = 'schedule.json' def setup(hass, config): """ Create the schedules """ + def setup_listener(schedule, event_data): + type = event_data['type'] + component = type + + if type in ('time'): + component = 'scheduler.{}'.format(type) + + return get_component(component).create_event_listener(schedule, + event_data) + def setup_schedule(schedule_data): """ setup a schedule based on the description """ @@ -49,9 +56,7 @@ def setup(hass, config): days=schedule_data['days']) for event_data in schedule_data['events']: - event_listener_type = \ - get_component('scheduler.{}'.format(event_data['type'])) - event_listener = event_listener_type.create(schedule, event_data) + event_listener = setup_listener(schedule, event_data) schedule.add_event_listener(event_listener) schedule.schedule(hass) diff --git a/homeassistant/components/scheduler/sun.py b/homeassistant/components/scheduler/sun.py deleted file mode 100644 index 5af965a1764..00000000000 --- a/homeassistant/components/scheduler/sun.py +++ /dev/null @@ -1,114 +0,0 @@ -""" -An event in the scheduler component that will call the service -when the sun rises or sets with an offset. -The sun evnt need to have the type 'sun', which service to call, -which event (sunset or sunrise) and the offset. - -{ - "type": "sun", - "service": "switch.turn_on", - "event": "sunset", - "offset": "-01:00:00" -} - -""" - -from datetime import datetime, timedelta -import logging - -from homeassistant.components.scheduler import ServiceEventListener -import homeassistant.components.sun as sun - -_LOGGER = logging.getLogger(__name__) - - -def create(schedule, event_listener_data): - """ Create a sun event listener based on the description. """ - - negative_offset = False - service = event_listener_data['service'] - offset_str = event_listener_data['offset'] - event = event_listener_data['event'] - - if offset_str.startswith('-'): - negative_offset = True - offset_str = offset_str[1:] - - (hour, minute, second) = [int(x) for x in offset_str.split(':')] - - offset = timedelta(hours=hour, minutes=minute, seconds=second) - - if event == 'sunset': - return SunsetEventListener(schedule, service, offset, negative_offset) - - return SunriseEventListener(schedule, service, offset, negative_offset) - - -# pylint: disable=too-few-public-methods -class SunEventListener(ServiceEventListener): - """ This is the base class for sun event listeners. """ - - def __init__(self, schedule, service, offset, negative_offset): - ServiceEventListener.__init__(self, schedule, service) - - self.offset = offset - self.negative_offset = negative_offset - - def __get_next_time(self, next_event): - """ - Returns when the next time the service should be called. - Taking into account the offset and which days the event should execute. - """ - - if self.negative_offset: - next_time = next_event - self.offset - else: - next_time = next_event + self.offset - - while next_time < datetime.now() or \ - next_time.weekday() not in self.my_schedule.days: - next_time = next_time + timedelta(days=1) - - return next_time - - def schedule_next_event(self, hass, next_event): - """ Schedule the event """ - next_time = self.__get_next_time(next_event) - - # pylint: disable=unused-argument - def execute(now): - """ Call the execute method """ - self.execute(hass) - - hass.track_point_in_time(execute, next_time) - - return next_time - - -# pylint: disable=too-few-public-methods -class SunsetEventListener(SunEventListener): - """ This class is used the call a service when the sun sets. """ - def schedule(self, hass): - """ Schedule the event """ - next_setting = sun.next_setting(hass) - - next_time = self.schedule_next_event(hass, next_setting) - - _LOGGER.info( - 'SunsetEventListener scheduled for %s, will call service %s.%s', - next_time, self.domain, self.service) - - -# pylint: disable=too-few-public-methods -class SunriseEventListener(SunEventListener): - """ This class is used the call a service when the sun rises. """ - - def schedule(self, hass): - """ Schedule the event """ - next_rising = sun.next_rising(hass) - - next_time = self.schedule_next_event(hass, next_rising) - - _LOGGER.info( - 'SunriseEventListener scheduled for %s, will call service %s.%s', - next_time, self.domain, self.service) diff --git a/homeassistant/components/scheduler/time.py b/homeassistant/components/scheduler/time.py index c1d8ebb7845..90fa495cee2 100644 --- a/homeassistant/components/scheduler/time.py +++ b/homeassistant/components/scheduler/time.py @@ -20,7 +20,7 @@ from homeassistant.components.scheduler import ServiceEventListener _LOGGER = logging.getLogger(__name__) -def create(schedule, event_listener_data): +def create_event_listener(schedule, event_listener_data): """ Create a TimeEvent based on the description """ service = event_listener_data['service'] diff --git a/homeassistant/components/sun.py b/homeassistant/components/sun.py index c6bacb45f87..87832b7cb23 100644 --- a/homeassistant/components/sun.py +++ b/homeassistant/components/sun.py @@ -12,6 +12,8 @@ from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE from homeassistant.helpers import validate_config from homeassistant.util import str_to_datetime, datetime_to_str +from homeassistant.components.scheduler import ServiceEventListener + DEPENDENCIES = [] DOMAIN = "sun" ENTITY_ID = "sun.sun" @@ -22,6 +24,7 @@ STATE_BELOW_HORIZON = "below_horizon" STATE_ATTR_NEXT_RISING = "next_rising" STATE_ATTR_NEXT_SETTING = "next_setting" +_LOGGER = logging.getLogger(__name__) def is_on(hass, entity_id=None): """ Returns if the sun is currently up based on the statemachine. """ @@ -137,3 +140,110 @@ def setup(hass, config): update_sun_state(datetime.now()) return True + +""" +An event in the scheduler component that will call the service +when the sun rises or sets with an offset. +The sun evnt need to have the type 'sun', which service to call, +which event (sunset or sunrise) and the offset. + +{ + "type": "sun", + "service": "switch.turn_on", + "event": "sunset", + "offset": "-01:00:00" +} + +""" + +def create_event_listener(schedule, event_listener_data): + """ Create a sun event listener based on the description. """ + + negative_offset = False + service = event_listener_data['service'] + offset_str = event_listener_data['offset'] + event = event_listener_data['event'] + + if offset_str.startswith('-'): + negative_offset = True + offset_str = offset_str[1:] + + (hour, minute, second) = [int(x) for x in offset_str.split(':')] + + offset = timedelta(hours=hour, minutes=minute, seconds=second) + + if event == 'sunset': + return SunsetEventListener(schedule, service, offset, negative_offset) + + return SunriseEventListener(schedule, service, offset, negative_offset) + +# pylint: disable=too-few-public-methods +class SunEventListener(ServiceEventListener): + """ This is the base class for sun event listeners. """ + + def __init__(self, schedule, service, offset, negative_offset): + ServiceEventListener.__init__(self, schedule, service) + + self.offset = offset + self.negative_offset = negative_offset + + def __get_next_time(self, next_event): + """ + Returns when the next time the service should be called. + Taking into account the offset and which days the event should execute. + """ + + if self.negative_offset: + next_time = next_event - self.offset + else: + next_time = next_event + self.offset + + while next_time < datetime.now() or \ + next_time.weekday() not in self.my_schedule.days: + next_time = next_time + timedelta(days=1) + + return next_time + + def schedule_next_event(self, hass, next_event): + """ Schedule the event """ + next_time = self.__get_next_time(next_event) + + # pylint: disable=unused-argument + def execute(now): + """ Call the execute method """ + self.execute(hass) + + hass.track_point_in_time(execute, next_time) + + return next_time + + +# pylint: disable=too-few-public-methods +class SunsetEventListener(SunEventListener): + """ This class is used the call a service when the sun sets. """ + def schedule(self, hass): + """ Schedule the event """ + next_setting_dt = next_setting(hass) + + print("------------", hass, "-------------") + + next_time_dt = self.schedule_next_event(hass, next_setting_dt) + + _LOGGER.info( + 'SunsetEventListener scheduled for %s, will call service %s.%s', + next_time_dt, self.domain, self.service) + + +# pylint: disable=too-few-public-methods +class SunriseEventListener(SunEventListener): + """ This class is used the call a service when the sun rises. """ + + def schedule(self, hass): + """ Schedule the event """ + next_rising_dt = next_rising(hass) + + next_time_dt = self.schedule_next_event(hass, next_rising_dt) + + _LOGGER.info( + 'SunriseEventListener scheduled for %s, will call service %s.%s', + next_time_dt, self.domain, self.service)