From 40dbeb0b60aaafc6909c477626851094659a4f4e Mon Sep 17 00:00:00 2001 From: Ryan Kraus Date: Sun, 24 Jan 2016 17:46:05 -0500 Subject: [PATCH] Another revision on event decorators This revision of event decorators removes much of the complexity. The decorated functions are no longer wrapped with a class that tracks last_run, etc. Bootstrap now gives hass to the event_decorators module before initializing components so the decorators no longer require activation. --- homeassistant/bootstrap.py | 8 +- homeassistant/helpers/event_decorators.py | 116 ++-------------------- 2 files changed, 15 insertions(+), 109 deletions(-) diff --git a/homeassistant/bootstrap.py b/homeassistant/bootstrap.py index aa649c400a0..132178361e0 100644 --- a/homeassistant/bootstrap.py +++ b/homeassistant/bootstrap.py @@ -24,6 +24,7 @@ import homeassistant.config as config_util import homeassistant.loader as loader import homeassistant.components as core_components import homeassistant.components.group as group +from homeassistant.helpers import event_decorators from homeassistant.helpers.entity import Entity from homeassistant.const import ( __version__, EVENT_COMPONENT_LOADED, CONF_LATITUDE, CONF_LONGITUDE, @@ -199,14 +200,13 @@ def from_config_dict(config, hass=None, config_dir=None, enable_log=True, _LOGGER.info('Home Assistant core initialized') + # give event decorators access to HASS + event_decorators.HASS = hass + # Setup the components for domain in loader.load_order_components(components): _setup_component(hass, domain, config) - # activate event decorators - from homeassistant.helpers import event_decorators - event_decorators.activate(hass) - return hass diff --git a/homeassistant/helpers/event_decorators.py b/homeassistant/helpers/event_decorators.py index fbf979eaf47..e48cf4bf88d 100644 --- a/homeassistant/helpers/event_decorators.py +++ b/homeassistant/helpers/event_decorators.py @@ -1,15 +1,8 @@ """ Event Decorators for custom components """ -from datetime import datetime -import functools -import inspect -import logging - from homeassistant.helpers import event -from homeassistant.components import logbook -REGISTERED_DECORATORS = [] -_LOGGER = logging.getLogger(__name__) +HASS = None def track_state_change(entity_ids, from_state=None, to_state=None): @@ -17,9 +10,9 @@ def track_state_change(entity_ids, from_state=None, to_state=None): def track_state_change_decorator(action): """ Decorator to track state changes """ - return Automation(action, event.track_state_change, - {"entity_ids": entity_ids, "from_state": from_state, - "to_state": to_state}) + event.track_state_change(HASS, entity_ids, action, + from_state, to_state) + return action return track_state_change_decorator @@ -29,7 +22,8 @@ def track_sunrise(offset=None): def track_sunrise_decorator(action): """ Decorator to track sunrise events """ - return Automation(action, event.track_sunrise, {"offset": offset}) + event.track_sunrise(HASS, action, offset) + return action return track_sunrise_decorator @@ -39,7 +33,8 @@ def track_sunset(offset=None): def track_sunset_decorator(action): """ Decorator to track sunset events """ - return Automation(action, event.track_sunset, {"offset": offset}) + event.track_sunset(HASS, action, offset) + return action return track_sunset_decorator @@ -51,97 +46,8 @@ def track_time_change(year=None, month=None, day=None, hour=None, minute=None, def track_time_change_decorator(action): """ Decorator to track time changes """ - return Automation(action, event.track_time_change, - {"year": year, "month": month, "day": day, - "hour": hour, "minute": minute, "second": second}) + event.track_time_change(HASS, action, year, month, day, hour, + minute, second) + return action return track_time_change_decorator - - -def activate(hass): - """ Activate all event decorators """ - Automation.hass = hass - - return all([rule.activate() for rule in REGISTERED_DECORATORS]) - - -class Automation(object): - """ Base Decorator for automation functions """ - - hass = None - - def __init__(self, action, event_fun, event_args): - # store action and config - self.action = action - self._event = (event_fun, event_args) - self._activated = False - self._last_run = None - self._running = 0 - module = inspect.getmodule(action) - self._domain = module.DOMAIN - - REGISTERED_DECORATORS.append(self) - - functools.update_wrapper(self, action) - - def __call__(self, *args, **kwargs): - """ Call the action """ - # pylint: disable=broad-except - if not self.activated: - return - - self._running += 1 - - _LOGGER.info('Executing %s', self.alias) - logbook.log_entry(self.hass, self.alias, 'has been triggered', - self._domain) - - try: - self.action(*args, **kwargs) - except Exception: - _LOGGER.exception('Error running Python automation: %s', - self.alias) - else: - self._last_run = datetime.now() - - self._running -= 1 - - @property - def alias(self): - """ The name of the action """ - return self.action.__name__ - - @property - def domain(self): - """ The domain to which this automation belongs """ - return self._domain - - @property - def is_running(self): - """ Boolean if the automation is running """ - return self._running > 0 - - @property - def num_running(self): - """ Integer of how many instances of the automation are running """ - return self._running - - @property - def activated(self): - """ Boolean indicating if the automation has been activated """ - return self._activated - - @property - def last_run(self): - """ Datetime object of the last automation completion """ - return self._last_run - - def activate(self): - """ Activates the automation with HASS """ - if self.activated: - return True - - self._event[0](hass=self.hass, action=self.action, **self._event[1]) - - self._activated = True - return True