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.
This commit is contained in:
Ryan Kraus 2016-01-24 17:46:05 -05:00
parent ef92940ffb
commit 40dbeb0b60
2 changed files with 15 additions and 109 deletions

View File

@ -24,6 +24,7 @@ import homeassistant.config as config_util
import homeassistant.loader as loader import homeassistant.loader as loader
import homeassistant.components as core_components import homeassistant.components as core_components
import homeassistant.components.group as group import homeassistant.components.group as group
from homeassistant.helpers import event_decorators
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.const import ( from homeassistant.const import (
__version__, EVENT_COMPONENT_LOADED, CONF_LATITUDE, CONF_LONGITUDE, __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') _LOGGER.info('Home Assistant core initialized')
# give event decorators access to HASS
event_decorators.HASS = hass
# Setup the components # Setup the components
for domain in loader.load_order_components(components): for domain in loader.load_order_components(components):
_setup_component(hass, domain, config) _setup_component(hass, domain, config)
# activate event decorators
from homeassistant.helpers import event_decorators
event_decorators.activate(hass)
return hass return hass

View File

@ -1,15 +1,8 @@
""" Event Decorators for custom components """ """ Event Decorators for custom components """
from datetime import datetime
import functools
import inspect
import logging
from homeassistant.helpers import event from homeassistant.helpers import event
from homeassistant.components import logbook
REGISTERED_DECORATORS = [] HASS = None
_LOGGER = logging.getLogger(__name__)
def track_state_change(entity_ids, from_state=None, to_state=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): def track_state_change_decorator(action):
""" Decorator to track state changes """ """ Decorator to track state changes """
return Automation(action, event.track_state_change, event.track_state_change(HASS, entity_ids, action,
{"entity_ids": entity_ids, "from_state": from_state, from_state, to_state)
"to_state": to_state}) return action
return track_state_change_decorator return track_state_change_decorator
@ -29,7 +22,8 @@ def track_sunrise(offset=None):
def track_sunrise_decorator(action): def track_sunrise_decorator(action):
""" Decorator to track sunrise events """ """ 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 return track_sunrise_decorator
@ -39,7 +33,8 @@ def track_sunset(offset=None):
def track_sunset_decorator(action): def track_sunset_decorator(action):
""" Decorator to track sunset events """ """ 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 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): def track_time_change_decorator(action):
""" Decorator to track time changes """ """ Decorator to track time changes """
return Automation(action, event.track_time_change, event.track_time_change(HASS, action, year, month, day, hour,
{"year": year, "month": month, "day": day, minute, second)
"hour": hour, "minute": minute, "second": second}) return action
return track_time_change_decorator 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