From 57725136c0413f156b093ee0049752ed3f30cd25 Mon Sep 17 00:00:00 2001 From: Ryan Kraus Date: Sun, 24 Jan 2016 19:52:22 -0500 Subject: [PATCH] Many updates regarding event decorators 1. Added HASS to the arguments for callbacks that are created with event decorators. 2. Added a service decorator. 3. Updated example.py in the example config to use the event decorators. --- config/custom_components/example.py | 145 +++++++++++----------- homeassistant/helpers/event_decorators.py | 35 +++++- 2 files changed, 104 insertions(+), 76 deletions(-) diff --git a/config/custom_components/example.py b/config/custom_components/example.py index ee7f18f437a..dc29d4b1967 100644 --- a/config/custom_components/example.py +++ b/config/custom_components/example.py @@ -29,9 +29,12 @@ import time import logging from homeassistant.const import STATE_HOME, STATE_NOT_HOME, STATE_ON, STATE_OFF -import homeassistant.loader as loader from homeassistant.helpers import validate_config +from homeassistant.helpers.event_decorators import \ + track_state_change, track_time_change, service import homeassistant.components as core +from homeassistant.components import device_tracker +from homeassistant.components import light # The domain of your component. Should be equal to the name of your component DOMAIN = "example" @@ -39,11 +42,14 @@ DOMAIN = "example" # List of component names (string) your component depends upon # We depend on group because group will be loaded after all the components that # initialize devices have been setup. -DEPENDENCIES = ['group'] +DEPENDENCIES = ['group', 'device_tracker', 'light'] # Configuration key for the entity id we are targetting CONF_TARGET = 'target' +# Variable for storing configuration parameters +CONFIG = {} + # Name of the service that we expose SERVICE_FLASH = 'flash' @@ -58,79 +64,76 @@ def setup(hass, config): if not validate_config(config, {DOMAIN: [CONF_TARGET]}, _LOGGER): return False - target_id = config[DOMAIN][CONF_TARGET] + CONFIG['target_id'] = config[DOMAIN][CONF_TARGET] # Validate that the target entity id exists - if hass.states.get(target_id) is None: - _LOGGER.error("Target entity id %s does not exist", target_id) + if hass.states.get(config['target_id']) is None: + _LOGGER.error("Target entity id %s does not exist", + CONFIG['target_id']) # Tell the bootstrapper that we failed to initialize return False - # We will use the component helper methods to check the states. - device_tracker = loader.get_component('device_tracker') - light = loader.get_component('light') - - def track_devices(entity_id, old_state, new_state): - """ Called when the group.all devices change state. """ - - # If anyone comes home and the core is not on, turn it on. - if new_state.state == STATE_HOME and not core.is_on(hass, target_id): - - core.turn_on(hass, target_id) - - # If all people leave the house and the core is on, turn it off - elif new_state.state == STATE_NOT_HOME and core.is_on(hass, target_id): - - core.turn_off(hass, target_id) - - # Register our track_devices method to receive state changes of the - # all tracked devices group. - hass.states.track_change( - device_tracker.ENTITY_ID_ALL_DEVICES, track_devices) - - def wake_up(now): - """ Turn it on in the morning if there are people home and - it is not already on. """ - - if device_tracker.is_on(hass) and not core.is_on(hass, target_id): - _LOGGER.info('People home at 7AM, turning it on') - core.turn_on(hass, target_id) - - # Register our wake_up service to be called at 7AM in the morning - hass.track_time_change(wake_up, hour=7, minute=0, second=0) - - def all_lights_off(entity_id, old_state, new_state): - """ If all lights turn off, turn off. """ - - if core.is_on(hass, target_id): - _LOGGER.info('All lights have been turned off, turning it off') - core.turn_off(hass, target_id) - - # Register our all_lights_off method to be called when all lights turn off - hass.states.track_change( - light.ENTITY_ID_ALL_LIGHTS, all_lights_off, STATE_ON, STATE_OFF) - - def flash_service(call): - """ Service that will turn the target off for 10 seconds - if on and vice versa. """ - - if core.is_on(hass, target_id): - core.turn_off(hass, target_id) - - time.sleep(10) - - core.turn_on(hass, target_id) - - else: - core.turn_on(hass, target_id) - - time.sleep(10) - - core.turn_off(hass, target_id) - - # Register our service with HASS. - hass.services.register(DOMAIN, SERVICE_FLASH, flash_service) - - # Tells the bootstrapper that the component was successfully initialized + # Tell the bootstrapper that we initialized successfully return True + + +@track_state_change(device_tracker.ENTITY_ID_ALL_DEVICES) +def track_devices(hass, entity_id, old_state, new_state): + """ Called when the group.all devices change state. """ + target_id = CONFIG['target_id'] + + # If anyone comes home and the entity is not on, turn it on. + if new_state.state == STATE_HOME and not core.is_on(hass, target_id): + + core.turn_on(hass, target_id) + + # If all people leave the house and the entity is on, turn it off + elif new_state.state == STATE_NOT_HOME and core.is_on(hass, target_id): + + core.turn_off(hass, target_id) + + +@track_time_change(hour=7, minute=0, second=0) +def wake_up(hass, now): + """ + Turn it on in the morning (7 AM) if there are people home and + it is not already on. + """ + target_id = CONFIG['target_id'] + + if device_tracker.is_on(hass) and not core.is_on(hass, target_id): + _LOGGER.info('People home at 7AM, turning it on') + core.turn_on(hass, target_id) + + +@track_state_change(light.ENTITY_ID_ALL_LIGHTS, STATE_ON, STATE_OFF) +def all_lights_off(hass, entity_id, old_state, new_state): + """ If all lights turn off, turn off. """ + target_id = CONFIG['target_id'] + + if core.is_on(hass, target_id): + _LOGGER.info('All lights have been turned off, turning it off') + core.turn_off(hass, target_id) + + +@service(DOMAIN, SERVICE_FLASH) +def flash_service(hass, call): + """ + Service that will turn the target off for 10 seconds if on and vice versa. + """ + target_id = CONFIG['target_id'] + + if core.is_on(hass, target_id): + core.turn_off(hass, target_id) + + time.sleep(10) + + core.turn_on(hass, target_id) + + else: + core.turn_on(hass, target_id) + + time.sleep(10) + + core.turn_off(hass, target_id) diff --git a/homeassistant/helpers/event_decorators.py b/homeassistant/helpers/event_decorators.py index e48cf4bf88d..0fcd002c169 100644 --- a/homeassistant/helpers/event_decorators.py +++ b/homeassistant/helpers/event_decorators.py @@ -1,16 +1,36 @@ """ Event Decorators for custom components """ +import functools + from homeassistant.helpers import event HASS = None +def _callback(action, *args, **kwargs): + """ adds HASS to callback arguments """ + action(HASS, *args, **kwargs) + + +def service(domain, service): + """ Decorator factory to register a service """ + + def register_service_decorator(action): + """ Decorator to register a service """ + HASS.services.register(domain, service, + functools.partial(_callback, action)) + return action + + return register_service_decorator + + def track_state_change(entity_ids, from_state=None, to_state=None): """ Decorator factory to track state changes for entity id """ def track_state_change_decorator(action): """ Decorator to track state changes """ - event.track_state_change(HASS, entity_ids, action, + event.track_state_change(HASS, entity_ids, + functools.partial(_callback, action), from_state, to_state) return action @@ -22,7 +42,9 @@ def track_sunrise(offset=None): def track_sunrise_decorator(action): """ Decorator to track sunrise events """ - event.track_sunrise(HASS, action, offset) + event.track_sunrise(HASS, + functools.partial(_callback, action), + action, offset) return action return track_sunrise_decorator @@ -33,7 +55,9 @@ def track_sunset(offset=None): def track_sunset_decorator(action): """ Decorator to track sunset events """ - event.track_sunset(HASS, action, offset) + event.track_sunset(HASS, + functools.partial(_callback, action), + offset) return action return track_sunset_decorator @@ -46,8 +70,9 @@ 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 """ - event.track_time_change(HASS, action, year, month, day, hour, - minute, second) + event.track_time_change(HASS, + functools.partial(_callback, action), + year, month, day, hour, minute, second) return action return track_time_change_decorator