From 79653a672d6b3fffda1f85ef8e84d808e7f5d328 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 2 May 2016 22:05:09 -0700 Subject: [PATCH] Script cleanup (#1963) --- .../components/automation/__init__.py | 16 ++++- homeassistant/components/automation/state.py | 4 +- homeassistant/components/automation/sun.py | 18 ++---- homeassistant/components/automation/time.py | 3 +- homeassistant/components/automation/zone.py | 9 ++- homeassistant/const.py | 63 +++++++++++-------- homeassistant/helpers/condition.py | 56 ++++++++++------- homeassistant/helpers/config_validation.py | 6 +- 8 files changed, 98 insertions(+), 77 deletions(-) diff --git a/homeassistant/components/automation/__init__.py b/homeassistant/components/automation/__init__.py index 37806a6fdac..ef3a9b4a41d 100644 --- a/homeassistant/components/automation/__init__.py +++ b/homeassistant/components/automation/__init__.py @@ -9,7 +9,7 @@ import logging import voluptuous as vol from homeassistant.bootstrap import prepare_setup_platform -from homeassistant.const import CONF_PLATFORM +from homeassistant.const import ATTR_ENTITY_ID, CONF_PLATFORM from homeassistant.components import logbook from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import extract_domain_configs, script, condition @@ -140,6 +140,12 @@ def _process_if(hass, config, p_config, action): """Process if checks.""" cond_type = p_config.get(CONF_CONDITION_TYPE, DEFAULT_CONDITION_TYPE).lower() + + # Deprecated since 0.19 - 5/5/2016 + if cond_type != DEFAULT_CONDITION_TYPE: + _LOGGER.warning('Using condition_type: %s is deprecated. Please use ' + '"condition: or" instead.') + if_configs = p_config.get(CONF_CONDITION) use_trigger = if_configs == CONDITION_USE_TRIGGER_VALUES @@ -148,6 +154,8 @@ def _process_if(hass, config, p_config, action): checks = [] for if_config in if_configs: + # Deprecated except for used by use_trigger_values + # since 0.19 - 5/5/2016 if CONF_PLATFORM in if_config: if not use_trigger: _LOGGER.warning("Please switch your condition configuration " @@ -155,6 +163,12 @@ def _process_if(hass, config, p_config, action): if_config = dict(if_config) if_config[CONF_CONDITION] = if_config.pop(CONF_PLATFORM) + # To support use_trigger_values with state trigger accepting + # multiple entity_ids to monitor. + if_entity_id = if_config.get(ATTR_ENTITY_ID) + if isinstance(if_entity_id, list) and len(if_entity_id) == 1: + if_config[ATTR_ENTITY_ID] = if_entity_id[0] + try: checks.append(condition.from_config(if_config)) except HomeAssistantError as ex: diff --git a/homeassistant/components/automation/state.py b/homeassistant/components/automation/state.py index 82fcfdab341..03902c1d6e2 100644 --- a/homeassistant/components/automation/state.py +++ b/homeassistant/components/automation/state.py @@ -21,7 +21,7 @@ CONF_FOR = "for" TRIGGER_SCHEMA = vol.All( vol.Schema({ vol.Required(CONF_PLATFORM): 'state', - vol.Required(CONF_ENTITY_ID): cv.entity_id, + vol.Required(CONF_ENTITY_ID): cv.entity_ids, # These are str on purpose. Want to catch YAML conversions CONF_FROM: str, CONF_TO: str, @@ -77,7 +77,7 @@ def trigger(hass, config, action): hass, state_for_listener, dt_util.utcnow() + time_delta) attached_state_for_cancel = track_state_change( - hass, entity_id, state_for_cancel_listener) + hass, entity, state_for_cancel_listener) track_state_change( hass, entity_id, state_automation_listener, from_state, to_state) diff --git a/homeassistant/components/automation/sun.py b/homeassistant/components/automation/sun.py index 5a69970ff23..7666847575e 100644 --- a/homeassistant/components/automation/sun.py +++ b/homeassistant/components/automation/sun.py @@ -9,28 +9,18 @@ import logging import voluptuous as vol -from homeassistant.const import CONF_PLATFORM +from homeassistant.const import ( + CONF_EVENT, CONF_OFFSET, CONF_PLATFORM, SUN_EVENT_SUNRISE) from homeassistant.helpers.event import track_sunrise, track_sunset import homeassistant.helpers.config_validation as cv DEPENDENCIES = ['sun'] -CONF_OFFSET = 'offset' -CONF_EVENT = 'event' -CONF_BEFORE = "before" -CONF_BEFORE_OFFSET = "before_offset" -CONF_AFTER = "after" -CONF_AFTER_OFFSET = "after_offset" - -EVENT_SUNSET = 'sunset' -EVENT_SUNRISE = 'sunrise' - _LOGGER = logging.getLogger(__name__) TRIGGER_SCHEMA = vol.Schema({ vol.Required(CONF_PLATFORM): 'sun', - vol.Required(CONF_EVENT): - vol.All(vol.Lower, vol.Any(EVENT_SUNRISE, EVENT_SUNSET)), + vol.Required(CONF_EVENT): cv.sun_event, vol.Required(CONF_OFFSET, default=timedelta(0)): cv.time_period, }) @@ -51,7 +41,7 @@ def trigger(hass, config, action): }) # Do something to call action - if event == EVENT_SUNRISE: + if event == SUN_EVENT_SUNRISE: track_sunrise(hass, call_action, offset) else: track_sunset(hass, call_action, offset) diff --git a/homeassistant/components/automation/time.py b/homeassistant/components/automation/time.py index 8ddeb2958d4..ca80536ea96 100644 --- a/homeassistant/components/automation/time.py +++ b/homeassistant/components/automation/time.py @@ -8,14 +8,13 @@ import logging import voluptuous as vol -from homeassistant.const import CONF_PLATFORM +from homeassistant.const import CONF_AFTER, CONF_PLATFORM from homeassistant.helpers import config_validation as cv from homeassistant.helpers.event import track_time_change CONF_HOURS = "hours" CONF_MINUTES = "minutes" CONF_SECONDS = "seconds" -CONF_AFTER = "after" _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/automation/zone.py b/homeassistant/components/automation/zone.py index bf325c677cd..5578bf052c4 100644 --- a/homeassistant/components/automation/zone.py +++ b/homeassistant/components/automation/zone.py @@ -6,21 +6,19 @@ at https://home-assistant.io/components/automation/#zone-trigger """ import voluptuous as vol -from homeassistant.const import MATCH_ALL, CONF_PLATFORM +from homeassistant.const import ( + CONF_EVENT, CONF_ENTITY_ID, CONF_ZONE, MATCH_ALL, CONF_PLATFORM) from homeassistant.helpers.event import track_state_change from homeassistant.helpers import ( condition, config_validation as cv, location) -CONF_ENTITY_ID = "entity_id" -CONF_ZONE = "zone" -CONF_EVENT = "event" EVENT_ENTER = "enter" EVENT_LEAVE = "leave" DEFAULT_EVENT = EVENT_ENTER TRIGGER_SCHEMA = vol.Schema({ vol.Required(CONF_PLATFORM): 'zone', - vol.Required(CONF_ENTITY_ID): cv.entity_id, + vol.Required(CONF_ENTITY_ID): cv.entity_ids, vol.Required(CONF_ZONE): cv.entity_id, vol.Required(CONF_EVENT, default=DEFAULT_EVENT): vol.Any(EVENT_ENTER, EVENT_LEAVE), @@ -56,6 +54,7 @@ def trigger(hass, config, action): 'from_state': from_s, 'to_state': to_s, 'zone': zone_state, + 'event': event, }, }) diff --git a/homeassistant/const.py b/homeassistant/const.py index 70aa0397ab3..525f0e5b304 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -14,35 +14,44 @@ DEVICE_DEFAULT_NAME = "Unnamed Device" WEEKDAYS = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'] -# #### CONFIG #### -CONF_ALIAS = "alias" -CONF_ICON = "icon" -CONF_LATITUDE = "latitude" -CONF_LONGITUDE = "longitude" -CONF_ELEVATION = "elevation" -CONF_TEMPERATURE_UNIT = "temperature_unit" -CONF_NAME = "name" -CONF_TIME_ZONE = "time_zone" -CONF_CUSTOMIZE = "customize" +SUN_EVENT_SUNSET = 'sunset' +SUN_EVENT_SUNRISE = 'sunrise' -CONF_PLATFORM = "platform" -CONF_HOST = "host" -CONF_PORT = "port" -CONF_HOSTS = "hosts" -CONF_USERNAME = "username" -CONF_PASSWORD = "password" -CONF_API_KEY = "api_key" -CONF_ACCESS_TOKEN = "access_token" -CONF_FILENAME = "filename" -CONF_MONITORED_CONDITIONS = 'monitored_conditions' -CONF_OPTIMISTIC = 'optimistic' -CONF_ENTITY_ID = "entity_id" -CONF_ENTITY_NAMESPACE = "entity_namespace" -CONF_SCAN_INTERVAL = "scan_interval" -CONF_VALUE_TEMPLATE = "value_template" -CONF_CONDITION = 'condition' -CONF_BELOW = 'below' +# #### CONFIG #### CONF_ABOVE = 'above' +CONF_ACCESS_TOKEN = 'access_token' +CONF_AFTER = 'after' +CONF_ALIAS = 'alias' +CONF_API_KEY = 'api_key' +CONF_BEFORE = 'before' +CONF_BELOW = 'below' +CONF_CONDITION = 'condition' +CONF_CUSTOMIZE = 'customize' +CONF_ELEVATION = 'elevation' +CONF_ENTITY_ID = 'entity_id' +CONF_ENTITY_NAMESPACE = 'entity_namespace' +CONF_EVENT = 'event' +CONF_FILENAME = 'filename' +CONF_HOST = 'host' +CONF_HOSTS = 'hosts' +CONF_ICON = 'icon' +CONF_LATITUDE = 'latitude' +CONF_LONGITUDE = 'longitude' +CONF_MONITORED_CONDITIONS = 'monitored_conditions' +CONF_NAME = 'name' +CONF_OFFSET = 'offset' +CONF_OPTIMISTIC = 'optimistic' +CONF_PASSWORD = 'password' +CONF_PLATFORM = 'platform' +CONF_PORT = 'port' +CONF_SCAN_INTERVAL = 'scan_interval' +CONF_STATE = 'state' +CONF_TEMPERATURE_UNIT = 'temperature_unit' +CONF_TIME_ZONE = 'time_zone' +CONF_USERNAME = 'username' +CONF_VALUE_TEMPLATE = 'value_template' +CONF_WEEKDAY = 'weekday' +CONF_ZONE = 'zone' # #### EVENTS #### EVENT_HOMEASSISTANT_START = "homeassistant_start" diff --git a/homeassistant/helpers/condition.py b/homeassistant/helpers/condition.py index 571012bdbc8..4785612f114 100644 --- a/homeassistant/helpers/condition.py +++ b/homeassistant/helpers/condition.py @@ -8,20 +8,15 @@ from homeassistant.components import ( from homeassistant.const import ( ATTR_GPS_ACCURACY, ATTR_LATITUDE, ATTR_LONGITUDE, CONF_ENTITY_ID, CONF_VALUE_TEMPLATE, CONF_CONDITION, - WEEKDAYS) + WEEKDAYS, CONF_STATE, CONF_ZONE, CONF_BEFORE, + CONF_AFTER, CONF_WEEKDAY, SUN_EVENT_SUNRISE, SUN_EVENT_SUNSET, + CONF_BELOW, CONF_ABOVE) from homeassistant.exceptions import TemplateError, HomeAssistantError import homeassistant.helpers.config_validation as cv from homeassistant.helpers.template import render import homeassistant.util.dt as dt_util FROM_CONFIG_FORMAT = '{}_from_config' -CONF_BELOW = 'below' -CONF_ABOVE = 'above' -CONF_STATE = 'state' -CONF_ZONE = 'zone' - -EVENT_SUNRISE = 'sunrise' -EVENT_SUNSET = 'sunset' _LOGGER = logging.getLogger(__name__) @@ -47,7 +42,15 @@ def and_from_config(config, config_validation=True): def if_and_condition(hass, variables=None): """Test and condition.""" - return all(check(hass, variables) for check in checks) + for check in checks: + try: + if not check(hass, variables): + return False + except Exception as ex: # pylint: disable=broad-except + _LOGGER.warning('Error during and-condition: %s', ex) + return False + + return True return if_and_condition @@ -60,7 +63,14 @@ def or_from_config(config, config_validation=True): def if_or_condition(hass, variables=None): """Test and condition.""" - return any(check(hass, variables) for check in checks) + for check in checks: + try: + if check(hass, variables): + return True + except Exception as ex: # pylint: disable=broad-except + _LOGGER.warning('Error during or-condition: %s', ex) + + return False return if_or_condition @@ -92,8 +102,6 @@ def numeric_state(hass, entity, below=None, above=None, value_template=None, _LOGGER.warning("Value cannot be processed as a number: %s", value) return False - print(below, value, above) - if below is not None and value > below: return False @@ -157,20 +165,20 @@ def sun(hass, before=None, after=None, before_offset=None, after_offset=None): before_offset = before_offset or timedelta(0) after_offset = after_offset or timedelta(0) - if before == EVENT_SUNRISE and now > (sun_cmp.next_rising(hass) + - before_offset).time(): + if before == SUN_EVENT_SUNRISE and now > (sun_cmp.next_rising(hass) + + before_offset).time(): return False - elif before == EVENT_SUNSET and now > (sun_cmp.next_setting(hass) + - before_offset).time(): + elif before == SUN_EVENT_SUNSET and now > (sun_cmp.next_setting(hass) + + before_offset).time(): return False - if after == EVENT_SUNRISE and now < (sun_cmp.next_rising(hass) + - after_offset).time(): + if after == SUN_EVENT_SUNRISE and now < (sun_cmp.next_rising(hass) + + after_offset).time(): return False - elif after == EVENT_SUNSET and now < (sun_cmp.next_setting(hass) + - after_offset).time(): + elif after == SUN_EVENT_SUNSET and now < (sun_cmp.next_setting(hass) + + after_offset).time(): return False return True @@ -241,9 +249,9 @@ def time_from_config(config, config_validation=True): """Wrap action method with time based condition.""" if config_validation: config = cv.TIME_CONDITION_SCHEMA(config) - before = config.get('before') - after = config.get('after') - weekday = config.get('weekday') + before = config.get(CONF_BEFORE) + after = config.get(CONF_AFTER) + weekday = config.get(CONF_WEEKDAY) def time_if(hass, variables=None): """Validate time based if-condition.""" @@ -281,7 +289,7 @@ def zone_from_config(config, config_validation=True): if config_validation: config = cv.ZONE_CONDITION_SCHEMA(config) entity_id = config.get(CONF_ENTITY_ID) - zone_entity_id = config.get('zone') + zone_entity_id = config.get(CONF_ZONE) def if_in_zone(hass, variables=None): """Test if condition.""" diff --git a/homeassistant/helpers/config_validation.py b/homeassistant/helpers/config_validation.py index ca07c08db48..0c79949cdbd 100644 --- a/homeassistant/helpers/config_validation.py +++ b/homeassistant/helpers/config_validation.py @@ -8,7 +8,8 @@ from homeassistant.loader import get_platform from homeassistant.const import ( CONF_PLATFORM, CONF_SCAN_INTERVAL, TEMP_CELSIUS, TEMP_FAHRENHEIT, CONF_ALIAS, CONF_ENTITY_ID, CONF_VALUE_TEMPLATE, WEEKDAYS, - CONF_CONDITION, CONF_BELOW, CONF_ABOVE) + CONF_CONDITION, CONF_BELOW, CONF_ABOVE, SUN_EVENT_SUNSET, + SUN_EVENT_SUNRISE) from homeassistant.helpers.entity import valid_entity_id import homeassistant.util.dt as dt_util from homeassistant.util import slugify @@ -25,6 +26,7 @@ latitude = vol.All(vol.Coerce(float), vol.Range(min=-90, max=90), msg='invalid latitude') longitude = vol.All(vol.Coerce(float), vol.Range(min=-180, max=180), msg='invalid longitude') +sun_event = vol.All(vol.Lower, vol.Any(SUN_EVENT_SUNSET, SUN_EVENT_SUNRISE)) # Adapted from: @@ -298,7 +300,7 @@ STATE_CONDITION_SCHEMA = vol.All(vol.Schema({ SUN_CONDITION_SCHEMA = vol.All(vol.Schema({ vol.Required(CONF_CONDITION): 'sun', - vol.Optional('before'): vol.Any('sunset', 'sunrise'), + vol.Optional('before'): sun_event, vol.Optional('before_offset'): time_period, vol.Optional('after'): vol.All(vol.Lower, vol.Any('sunset', 'sunrise')), vol.Optional('after_offset'): time_period,