Initial script condition support (#1910)
This commit is contained in:
parent
953223b81b
commit
6354399d55
19 changed files with 656 additions and 427 deletions
|
@ -7,13 +7,16 @@ import voluptuous as vol
|
|||
from homeassistant.loader import get_platform
|
||||
from homeassistant.const import (
|
||||
CONF_PLATFORM, CONF_SCAN_INTERVAL, TEMP_CELSIUS, TEMP_FAHRENHEIT,
|
||||
CONF_ALIAS)
|
||||
CONF_ALIAS, CONF_ENTITY_ID, CONF_VALUE_TEMPLATE, WEEKDAYS,
|
||||
CONF_CONDITION, CONF_BELOW, CONF_ABOVE)
|
||||
from homeassistant.helpers.entity import valid_entity_id
|
||||
import homeassistant.util.dt as dt_util
|
||||
from homeassistant.util import slugify
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
|
||||
TIME_PERIOD_ERROR = "offset {} should be format 'HH:MM' or 'HH:MM:SS'"
|
||||
|
||||
# Home Assistant types
|
||||
byte = vol.All(vol.Coerce(int), vol.Range(min=0, max=255))
|
||||
small_float = vol.All(vol.Coerce(float), vol.Range(min=0, max=1))
|
||||
|
@ -105,9 +108,10 @@ time_period_dict = vol.All(
|
|||
|
||||
def time_period_str(value):
|
||||
"""Validate and transform time offset."""
|
||||
if not isinstance(value, str):
|
||||
raise vol.Invalid(
|
||||
'offset {} should be format HH:MM or HH:MM:SS'.format(value))
|
||||
if isinstance(value, int):
|
||||
raise vol.Invalid('Make sure you wrap time values in quotes')
|
||||
elif not isinstance(value, str):
|
||||
raise vol.Invalid(TIME_PERIOD_ERROR.format(value))
|
||||
|
||||
negative_offset = False
|
||||
if value.startswith('-'):
|
||||
|
@ -119,8 +123,7 @@ def time_period_str(value):
|
|||
try:
|
||||
parsed = [int(x) for x in value.split(':')]
|
||||
except ValueError:
|
||||
raise vol.Invalid(
|
||||
'offset {} should be format HH:MM or HH:MM:SS'.format(value))
|
||||
raise vol.Invalid(TIME_PERIOD_ERROR.format(value))
|
||||
|
||||
if len(parsed) == 2:
|
||||
hour, minute = parsed
|
||||
|
@ -128,8 +131,7 @@ def time_period_str(value):
|
|||
elif len(parsed) == 3:
|
||||
hour, minute, second = parsed
|
||||
else:
|
||||
raise vol.Invalid(
|
||||
'offset {} should be format HH:MM or HH:MM:SS'.format(value))
|
||||
raise vol.Invalid(TIME_PERIOD_ERROR.format(value))
|
||||
|
||||
offset = timedelta(hours=hour, minutes=minute, seconds=second)
|
||||
|
||||
|
@ -217,6 +219,16 @@ def template(value):
|
|||
raise vol.Invalid('invalid template ({})'.format(ex))
|
||||
|
||||
|
||||
def time(value):
|
||||
"""Validate time."""
|
||||
time_val = dt_util.parse_time(value)
|
||||
|
||||
if time_val is None:
|
||||
raise vol.Invalid('Invalid time specified: {}'.format(value))
|
||||
|
||||
return time_val
|
||||
|
||||
|
||||
def time_zone(value):
|
||||
"""Validate timezone."""
|
||||
if dt_util.get_time_zone(value) is not None:
|
||||
|
@ -225,6 +237,8 @@ def time_zone(value):
|
|||
'Invalid time zone passed in. Valid options can be found here: '
|
||||
'http://en.wikipedia.org/wiki/List_of_tz_database_time_zones')
|
||||
|
||||
weekdays = vol.All(ensure_list, [vol.In(WEEKDAYS)])
|
||||
|
||||
|
||||
# Validator helpers
|
||||
|
||||
|
@ -261,9 +275,83 @@ SERVICE_SCHEMA = vol.All(vol.Schema({
|
|||
vol.Exclusive('service_template', 'service name'): template,
|
||||
vol.Optional('data'): dict,
|
||||
vol.Optional('data_template'): {match_all: template},
|
||||
vol.Optional('entity_id'): entity_ids,
|
||||
vol.Optional(CONF_ENTITY_ID): entity_ids,
|
||||
}), has_at_least_one_key('service', 'service_template'))
|
||||
|
||||
NUMERIC_STATE_CONDITION_SCHEMA = vol.All(vol.Schema({
|
||||
vol.Required(CONF_CONDITION): 'numeric_state',
|
||||
vol.Required(CONF_ENTITY_ID): entity_id,
|
||||
CONF_BELOW: vol.Coerce(float),
|
||||
CONF_ABOVE: vol.Coerce(float),
|
||||
vol.Optional(CONF_VALUE_TEMPLATE): template,
|
||||
}), has_at_least_one_key(CONF_BELOW, CONF_ABOVE))
|
||||
|
||||
STATE_CONDITION_SCHEMA = vol.All(vol.Schema({
|
||||
vol.Required(CONF_CONDITION): 'state',
|
||||
vol.Required(CONF_ENTITY_ID): entity_id,
|
||||
vol.Required('state'): str,
|
||||
vol.Optional('for'): vol.All(time_period, positive_timedelta),
|
||||
# To support use_trigger_value in automation
|
||||
# Deprecated 2016/04/25
|
||||
vol.Optional('from'): str,
|
||||
}), key_dependency('for', 'state'))
|
||||
|
||||
SUN_CONDITION_SCHEMA = vol.All(vol.Schema({
|
||||
vol.Required(CONF_CONDITION): 'sun',
|
||||
vol.Optional('before'): vol.Any('sunset', 'sunrise'),
|
||||
vol.Optional('before_offset'): time_period,
|
||||
vol.Optional('after'): vol.All(vol.Lower, vol.Any('sunset', 'sunrise')),
|
||||
vol.Optional('after_offset'): time_period,
|
||||
}), has_at_least_one_key('before', 'after'))
|
||||
|
||||
TEMPLATE_CONDITION_SCHEMA = vol.Schema({
|
||||
vol.Required(CONF_CONDITION): 'template',
|
||||
vol.Required(CONF_VALUE_TEMPLATE): template,
|
||||
})
|
||||
|
||||
TIME_CONDITION_SCHEMA = vol.All(vol.Schema({
|
||||
vol.Required(CONF_CONDITION): 'time',
|
||||
'before': time,
|
||||
'after': time,
|
||||
'weekday': weekdays,
|
||||
}), has_at_least_one_key('before', 'after', 'weekday'))
|
||||
|
||||
ZONE_CONDITION_SCHEMA = vol.Schema({
|
||||
vol.Required(CONF_CONDITION): 'zone',
|
||||
vol.Required(CONF_ENTITY_ID): entity_id,
|
||||
'zone': entity_id,
|
||||
# To support use_trigger_value in automation
|
||||
# Deprecated 2016/04/25
|
||||
vol.Optional('event'): vol.Any('enter', 'leave'),
|
||||
})
|
||||
|
||||
AND_CONDITION_SCHEMA = vol.Schema({
|
||||
vol.Required(CONF_CONDITION): 'and',
|
||||
vol.Required('conditions'): vol.All(
|
||||
ensure_list,
|
||||
# pylint: disable=unnecessary-lambda
|
||||
[lambda value: CONDITION_SCHEMA(value)],
|
||||
)
|
||||
})
|
||||
|
||||
OR_CONDITION_SCHEMA = vol.Schema({
|
||||
vol.Required(CONF_CONDITION): 'or',
|
||||
vol.Required('conditions'): vol.All(
|
||||
ensure_list,
|
||||
# pylint: disable=unnecessary-lambda
|
||||
[lambda value: CONDITION_SCHEMA(value)],
|
||||
)
|
||||
})
|
||||
|
||||
CONDITION_SCHEMA = vol.Any(
|
||||
NUMERIC_STATE_CONDITION_SCHEMA,
|
||||
STATE_CONDITION_SCHEMA,
|
||||
SUN_CONDITION_SCHEMA,
|
||||
TEMPLATE_CONDITION_SCHEMA,
|
||||
TIME_CONDITION_SCHEMA,
|
||||
ZONE_CONDITION_SCHEMA,
|
||||
)
|
||||
|
||||
_SCRIPT_DELAY_SCHEMA = vol.Schema({
|
||||
vol.Optional(CONF_ALIAS): string,
|
||||
vol.Required("delay"): vol.All(time_period, positive_timedelta)
|
||||
|
@ -271,5 +359,6 @@ _SCRIPT_DELAY_SCHEMA = vol.Schema({
|
|||
|
||||
SCRIPT_SCHEMA = vol.All(
|
||||
ensure_list,
|
||||
[vol.Any(SERVICE_SCHEMA, _SCRIPT_DELAY_SCHEMA, EVENT_SCHEMA)],
|
||||
[vol.Any(SERVICE_SCHEMA, _SCRIPT_DELAY_SCHEMA, EVENT_SCHEMA,
|
||||
CONDITION_SCHEMA)],
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue