449 lines
14 KiB
Python
449 lines
14 KiB
Python
"""This module holds the vaious schemas"""
|
|
|
|
from datetime import datetime, date
|
|
import voluptuous as vol
|
|
from homeassistant.helpers import config_validation as cv
|
|
from homeassistant.const import (
|
|
CONF_ENTITY_ID,
|
|
CONF_AFTER,
|
|
CONF_BEFORE,
|
|
CONF_NAME,
|
|
CONF_WEEKDAY,
|
|
CONF_REPEAT,
|
|
CONF_DELAY,
|
|
CONF_FOR,
|
|
CONF_UNTIL,
|
|
)
|
|
|
|
from .const import (
|
|
CONF_ALLOW_MANUAL,
|
|
CONF_CLOCK,
|
|
CONF_ENABLED,
|
|
CONF_FINISH,
|
|
CONF_FIXED,
|
|
CONF_FUTURE_SPAN,
|
|
CONF_HISTORY,
|
|
CONF_HISTORY_REFRESH,
|
|
CONF_HISTORY_SPAN,
|
|
CONF_MAX_LOG_ENTRIES,
|
|
CONF_MAXIMUM,
|
|
CONF_MINIMUM,
|
|
CONF_MODE,
|
|
CONF_MONTH,
|
|
CONF_DAY,
|
|
CONF_ODD,
|
|
CONF_EVEN,
|
|
CONF_RENAME_ENTITIES,
|
|
CONF_RESULTS,
|
|
CONF_SHOW_LOG,
|
|
CONF_AUTOPLAY,
|
|
CONF_ANCHOR,
|
|
CONF_SPAN,
|
|
CONF_SYNC_SWITCHES,
|
|
CONF_SEER,
|
|
CONF_CONTROLLERS,
|
|
CONF_SCHEDULES,
|
|
CONF_ZONES,
|
|
CONF_DURATION,
|
|
CONF_SUN,
|
|
CONF_TIME,
|
|
CONF_PREAMBLE,
|
|
CONF_POSTAMBLE,
|
|
CONF_GRANULARITY,
|
|
CONF_TESTING,
|
|
CONF_SPEED,
|
|
CONF_TIMES,
|
|
CONF_START,
|
|
CONF_END,
|
|
MONTHS,
|
|
CONF_SHOW,
|
|
CONF_CONFIG,
|
|
CONF_TIMELINE,
|
|
CONF_CONTROLLER_ID,
|
|
CONF_ZONE_ID,
|
|
CONF_SEQUENCES,
|
|
CONF_ALL_ZONES_CONFIG,
|
|
CONF_REFRESH_INTERVAL,
|
|
CONF_OUTPUT_EVENTS,
|
|
CONF_CRON,
|
|
CONF_EVERY_N_DAYS,
|
|
CONF_START_N_DAYS,
|
|
CONF_CHECK_BACK,
|
|
CONF_RETRIES,
|
|
CONF_RESYNC,
|
|
CONF_STATE_ON,
|
|
CONF_STATE_OFF,
|
|
CONF_PERCENTAGE,
|
|
CONF_ACTUAL,
|
|
CONF_INCREASE,
|
|
CONF_DECREASE,
|
|
CONF_RESET,
|
|
CONF_SEQUENCE_ID,
|
|
CONF_STATES,
|
|
CONF_SCHEDULE_ID,
|
|
CONF_FROM,
|
|
CONF_VOLUME,
|
|
CONF_VOLUME_PRECISION,
|
|
CONF_VOLUME_SCALE,
|
|
CONF_FLOW_RATE_PRECISION,
|
|
CONF_FLOW_RATE_SCALE,
|
|
CONF_QUEUE,
|
|
CONF_QUEUE_MANUAL,
|
|
CONF_USER,
|
|
CONF_TOGGLE,
|
|
CONF_EXTENDED_CONFIG,
|
|
)
|
|
|
|
IU_ID = r"^[a-z0-9]+(_[a-z0-9]+)*$"
|
|
|
|
|
|
def _list_is_not_empty(value):
|
|
if value is None or len(value) < 1:
|
|
raise vol.Invalid("Must have at least one entry")
|
|
return value
|
|
|
|
|
|
def _parse_dd_mmm(value: str) -> date | None:
|
|
"""Convert a date string in dd mmm format to a date object."""
|
|
if isinstance(value, date):
|
|
return value
|
|
return datetime.strptime(value, "%d %b").date()
|
|
|
|
|
|
USER_SCHEMA = vol.Schema(
|
|
{},
|
|
extra=vol.ALLOW_EXTRA,
|
|
)
|
|
|
|
SHOW_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Optional(CONF_CONFIG, False): cv.boolean,
|
|
vol.Optional(CONF_TIMELINE, False): cv.boolean,
|
|
}
|
|
)
|
|
|
|
SUN_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Required(CONF_SUN): cv.sun_event,
|
|
vol.Optional(CONF_BEFORE): cv.positive_time_period,
|
|
vol.Optional(CONF_AFTER): cv.positive_time_period,
|
|
}
|
|
)
|
|
|
|
CRON_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Required(CONF_CRON): cv.string,
|
|
}
|
|
)
|
|
|
|
EVERY_N_DAYS_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Required(CONF_EVERY_N_DAYS): cv.positive_int,
|
|
vol.Required(CONF_START_N_DAYS): cv.date,
|
|
}
|
|
)
|
|
|
|
time_event = vol.Any(cv.time, SUN_SCHEMA, CRON_SCHEMA)
|
|
anchor_event = vol.Any(CONF_START, CONF_FINISH)
|
|
month_event = vol.All(cv.ensure_list, [vol.In(MONTHS)])
|
|
|
|
day_number = vol.All(vol.Coerce(int), vol.Range(min=0, max=31))
|
|
day_event = vol.Any(
|
|
CONF_ODD, CONF_EVEN, cv.ensure_list(day_number), EVERY_N_DAYS_SCHEMA
|
|
)
|
|
|
|
SCHEDULE_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Required(CONF_TIME): time_event,
|
|
vol.Required(CONF_ANCHOR, default=CONF_START): anchor_event,
|
|
vol.Required(CONF_DURATION): cv.positive_time_period,
|
|
vol.Optional(CONF_NAME): cv.string,
|
|
vol.Optional(CONF_SCHEDULE_ID): cv.matches_regex(IU_ID),
|
|
vol.Optional(CONF_WEEKDAY): cv.weekdays,
|
|
vol.Optional(CONF_MONTH): month_event,
|
|
vol.Optional(CONF_DAY): day_event,
|
|
vol.Optional(CONF_ENABLED): cv.boolean,
|
|
vol.Inclusive(CONF_FROM, "span"): _parse_dd_mmm,
|
|
vol.Inclusive(CONF_UNTIL, "span"): _parse_dd_mmm,
|
|
}
|
|
)
|
|
|
|
SEQUENCE_SCHEDULE_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Required(CONF_TIME): time_event,
|
|
vol.Required(CONF_ANCHOR, default=CONF_START): anchor_event,
|
|
vol.Optional(CONF_DURATION): cv.positive_time_period,
|
|
vol.Optional(CONF_NAME): cv.string,
|
|
vol.Optional(CONF_SCHEDULE_ID): cv.matches_regex(IU_ID),
|
|
vol.Optional(CONF_WEEKDAY): cv.weekdays,
|
|
vol.Optional(CONF_MONTH): month_event,
|
|
vol.Optional(CONF_DAY): day_event,
|
|
vol.Optional(CONF_ENABLED): cv.boolean,
|
|
vol.Inclusive(CONF_FROM, "span"): _parse_dd_mmm,
|
|
vol.Inclusive(CONF_UNTIL, "span"): _parse_dd_mmm,
|
|
}
|
|
)
|
|
|
|
LOAD_SCHEDULE_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Required(CONF_SCHEDULE_ID): cv.matches_regex(IU_ID),
|
|
vol.Optional(CONF_TIME): time_event,
|
|
vol.Optional(CONF_ANCHOR): anchor_event,
|
|
vol.Optional(CONF_DURATION): cv.positive_time_period_template,
|
|
vol.Optional(CONF_NAME): cv.string,
|
|
vol.Optional(CONF_WEEKDAY): cv.weekdays,
|
|
vol.Optional(CONF_MONTH): month_event,
|
|
vol.Optional(CONF_DAY): day_event,
|
|
vol.Optional(CONF_ENABLED): cv.boolean,
|
|
vol.Inclusive(CONF_FROM, "span"): _parse_dd_mmm,
|
|
vol.Inclusive(CONF_UNTIL, "span"): _parse_dd_mmm,
|
|
}
|
|
)
|
|
|
|
CHECK_BACK_SCHEMA = vol.All(
|
|
cv.deprecated(CONF_STATE_ON),
|
|
cv.deprecated(CONF_STATE_OFF),
|
|
vol.Schema(
|
|
{
|
|
vol.Optional(CONF_STATES): vol.Any("none", "all", "on", "off"),
|
|
vol.Optional(CONF_DELAY): cv.positive_int,
|
|
vol.Optional(CONF_RETRIES): cv.positive_int,
|
|
vol.Optional(CONF_RESYNC): cv.boolean,
|
|
vol.Optional(CONF_STATE_ON): cv.string, # Deprecated
|
|
vol.Optional(CONF_STATE_OFF): cv.string, # Deprecated
|
|
vol.Optional(CONF_ENTITY_ID): cv.entity_id,
|
|
vol.Optional(CONF_TOGGLE): cv.boolean,
|
|
}
|
|
),
|
|
)
|
|
|
|
VOLUME_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Required(CONF_ENTITY_ID): cv.entity_id,
|
|
vol.Optional(CONF_VOLUME_PRECISION): cv.positive_int,
|
|
vol.Optional(CONF_VOLUME_SCALE): cv.positive_float,
|
|
vol.Optional(CONF_FLOW_RATE_PRECISION): cv.positive_int,
|
|
vol.Optional(CONF_FLOW_RATE_SCALE): cv.positive_float,
|
|
}
|
|
)
|
|
|
|
ZONE_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Optional(CONF_SCHEDULES): vol.All(cv.ensure_list, [SCHEDULE_SCHEMA]),
|
|
vol.Optional(CONF_ZONE_ID): cv.matches_regex(IU_ID),
|
|
vol.Optional(CONF_NAME): cv.string,
|
|
vol.Optional(CONF_ENTITY_ID): cv.entity_ids,
|
|
vol.Optional(CONF_ENABLED): cv.boolean,
|
|
vol.Optional(CONF_ALLOW_MANUAL): cv.boolean,
|
|
vol.Optional(CONF_MINIMUM): cv.positive_time_period,
|
|
vol.Optional(CONF_MAXIMUM): cv.positive_time_period,
|
|
vol.Optional(CONF_FUTURE_SPAN): cv.positive_int,
|
|
vol.Optional(CONF_SHOW): vol.All(SHOW_SCHEMA),
|
|
vol.Optional(CONF_CHECK_BACK): vol.All(CHECK_BACK_SCHEMA),
|
|
vol.Optional(CONF_VOLUME): vol.All(VOLUME_SCHEMA),
|
|
vol.Optional(CONF_DURATION): cv.positive_time_period_template,
|
|
vol.Optional(CONF_USER): vol.All(USER_SCHEMA),
|
|
}
|
|
)
|
|
|
|
ALL_ZONES_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Optional(CONF_SHOW): vol.All(SHOW_SCHEMA),
|
|
vol.Optional(CONF_MINIMUM): cv.positive_time_period,
|
|
vol.Optional(CONF_MAXIMUM): cv.positive_time_period,
|
|
vol.Optional(CONF_FUTURE_SPAN): cv.positive_int,
|
|
vol.Optional(CONF_ALLOW_MANUAL): cv.boolean,
|
|
vol.Optional(CONF_CHECK_BACK): vol.All(CHECK_BACK_SCHEMA),
|
|
vol.Optional(CONF_VOLUME): vol.All(VOLUME_SCHEMA),
|
|
vol.Optional(CONF_DURATION): cv.positive_time_period_template,
|
|
vol.Optional(CONF_USER): vol.All(USER_SCHEMA),
|
|
}
|
|
)
|
|
|
|
SEQUENCE_ZONE_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Required(CONF_ZONE_ID): vol.All(cv.ensure_list, [cv.string]),
|
|
vol.Optional(CONF_DELAY): cv.time_period,
|
|
vol.Optional(CONF_DURATION): cv.positive_time_period,
|
|
vol.Optional(CONF_REPEAT): cv.positive_int,
|
|
vol.Optional(CONF_ENABLED): cv.boolean,
|
|
vol.Optional(CONF_VOLUME): cv.positive_float,
|
|
}
|
|
)
|
|
|
|
SEQUENCE_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Required(CONF_ZONES, default={}): vol.All(
|
|
cv.ensure_list, [SEQUENCE_ZONE_SCHEMA], _list_is_not_empty
|
|
),
|
|
vol.Optional(CONF_SCHEDULES): vol.All(
|
|
cv.ensure_list, [SEQUENCE_SCHEDULE_SCHEMA]
|
|
),
|
|
vol.Optional(CONF_NAME): cv.string,
|
|
vol.Optional(CONF_DELAY): cv.time_period,
|
|
vol.Optional(CONF_DURATION): cv.positive_time_period,
|
|
vol.Optional(CONF_REPEAT): cv.positive_int,
|
|
vol.Optional(CONF_ENABLED): cv.boolean,
|
|
}
|
|
)
|
|
|
|
CONTROLLER_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Required(CONF_ZONES): vol.All(
|
|
cv.ensure_list, [ZONE_SCHEMA], _list_is_not_empty
|
|
),
|
|
vol.Optional(CONF_SEQUENCES): vol.All(
|
|
cv.ensure_list, [SEQUENCE_SCHEMA], _list_is_not_empty
|
|
),
|
|
vol.Optional(CONF_NAME): cv.string,
|
|
vol.Optional(CONF_CONTROLLER_ID): cv.matches_regex(IU_ID),
|
|
vol.Optional(CONF_ENTITY_ID): cv.entity_ids,
|
|
vol.Optional(CONF_PREAMBLE): cv.time_period,
|
|
vol.Optional(CONF_POSTAMBLE): cv.time_period,
|
|
vol.Optional(CONF_ENABLED): cv.boolean,
|
|
vol.Optional(CONF_ALL_ZONES_CONFIG): vol.All(ALL_ZONES_SCHEMA),
|
|
vol.Optional(CONF_QUEUE_MANUAL): cv.boolean,
|
|
vol.Optional(CONF_CHECK_BACK): vol.All(CHECK_BACK_SCHEMA),
|
|
vol.Optional(CONF_VOLUME): vol.All(VOLUME_SCHEMA),
|
|
vol.Optional(CONF_USER): vol.All(USER_SCHEMA),
|
|
}
|
|
)
|
|
|
|
HISTORY_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Optional(CONF_ENABLED): cv.boolean,
|
|
vol.Optional(CONF_REFRESH_INTERVAL): cv.positive_int,
|
|
vol.Optional(CONF_SPAN): cv.positive_int,
|
|
}
|
|
)
|
|
|
|
clock_mode = vol.Any(CONF_FIXED, CONF_SEER)
|
|
|
|
CLOCK_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Optional(CONF_MODE, default=CONF_SEER): clock_mode,
|
|
vol.Optional(CONF_SHOW_LOG, default=False): cv.boolean,
|
|
vol.Optional(CONF_MAX_LOG_ENTRIES): cv.positive_int,
|
|
}
|
|
)
|
|
|
|
TEST_RESULT_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Required("t"): cv.datetime,
|
|
vol.Required("c"): cv.positive_int,
|
|
vol.Required("z"): cv.positive_int,
|
|
vol.Required("s"): cv.boolean,
|
|
}
|
|
)
|
|
|
|
TEST_TIME_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Required(CONF_START): cv.datetime,
|
|
vol.Required(CONF_END): cv.datetime,
|
|
vol.Optional(CONF_NAME): cv.string,
|
|
vol.Optional(CONF_RESULTS): [TEST_RESULT_SCHEMA],
|
|
}
|
|
)
|
|
|
|
TEST_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Optional(CONF_ENABLED): cv.boolean,
|
|
vol.Optional(CONF_SPEED): cv.positive_float,
|
|
vol.Optional(CONF_TIMES): [TEST_TIME_SCHEMA],
|
|
vol.Optional(CONF_OUTPUT_EVENTS): cv.boolean,
|
|
vol.Optional(CONF_SHOW_LOG): cv.boolean,
|
|
vol.Optional(CONF_AUTOPLAY): cv.boolean,
|
|
}
|
|
)
|
|
|
|
IRRIGATION_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Required(CONF_CONTROLLERS, default={}): vol.All(
|
|
cv.ensure_list, [CONTROLLER_SCHEMA], _list_is_not_empty
|
|
),
|
|
vol.Optional(CONF_GRANULARITY): cv.positive_int,
|
|
vol.Optional(CONF_REFRESH_INTERVAL): cv.positive_int,
|
|
vol.Optional(CONF_HISTORY_SPAN): cv.positive_int,
|
|
vol.Optional(CONF_HISTORY_REFRESH): cv.positive_int,
|
|
vol.Optional(CONF_SYNC_SWITCHES): cv.boolean,
|
|
vol.Optional(CONF_RENAME_ENTITIES): cv.boolean,
|
|
vol.Optional(CONF_TESTING): TEST_SCHEMA,
|
|
vol.Optional(CONF_HISTORY): HISTORY_SCHEMA,
|
|
vol.Optional(CONF_CLOCK): CLOCK_SCHEMA,
|
|
vol.Optional(CONF_EXTENDED_CONFIG): cv.boolean,
|
|
}
|
|
)
|
|
|
|
|
|
positive_float_template = vol.Any(cv.positive_float, cv.template)
|
|
|
|
ENTITY_SCHEMA = {vol.Required(CONF_ENTITY_ID): cv.entity_id}
|
|
|
|
ENABLE_DISABLE_SCHEMA = {
|
|
vol.Required(CONF_ENTITY_ID): cv.entity_ids,
|
|
vol.Optional(CONF_ZONES): cv.ensure_list,
|
|
vol.Optional(CONF_SEQUENCE_ID): cv.positive_int,
|
|
}
|
|
|
|
TIME_ADJUST_SCHEMA = vol.All(
|
|
vol.Schema(
|
|
{
|
|
vol.Required(CONF_ENTITY_ID): cv.entity_ids,
|
|
vol.Exclusive(
|
|
CONF_ACTUAL, "adjust_method"
|
|
): cv.positive_time_period_template,
|
|
vol.Exclusive(CONF_PERCENTAGE, "adjust_method"): positive_float_template,
|
|
vol.Exclusive(
|
|
CONF_INCREASE, "adjust_method"
|
|
): cv.positive_time_period_template,
|
|
vol.Exclusive(
|
|
CONF_DECREASE, "adjust_method"
|
|
): cv.positive_time_period_template,
|
|
vol.Exclusive(CONF_RESET, "adjust_method"): None,
|
|
vol.Optional(CONF_MINIMUM): cv.positive_time_period_template,
|
|
vol.Optional(CONF_MAXIMUM): cv.positive_time_period_template,
|
|
vol.Optional(CONF_ZONES): cv.ensure_list,
|
|
vol.Optional(CONF_SEQUENCE_ID): cv.positive_int,
|
|
}
|
|
),
|
|
cv.has_at_least_one_key(
|
|
CONF_ACTUAL, CONF_PERCENTAGE, CONF_INCREASE, CONF_DECREASE, CONF_RESET
|
|
),
|
|
)
|
|
|
|
MANUAL_RUN_SCHEMA = {
|
|
vol.Required(CONF_ENTITY_ID): cv.entity_ids,
|
|
vol.Optional(CONF_TIME): cv.positive_time_period_template,
|
|
vol.Optional(CONF_DELAY): cv.time_period,
|
|
vol.Optional(CONF_QUEUE): cv.boolean,
|
|
vol.Optional(CONF_ZONES): cv.ensure_list,
|
|
vol.Optional(CONF_SEQUENCE_ID): cv.positive_int,
|
|
}
|
|
|
|
SUSPEND_SCHEMA = vol.All(
|
|
vol.Schema(
|
|
{
|
|
vol.Required(CONF_ENTITY_ID): cv.entity_ids,
|
|
vol.Exclusive(CONF_FOR, "time_method"): cv.positive_time_period_template,
|
|
vol.Exclusive(CONF_UNTIL, "time_method"): cv.datetime,
|
|
vol.Exclusive(CONF_RESET, "time_method"): None,
|
|
vol.Optional(CONF_ZONES): cv.ensure_list,
|
|
vol.Optional(CONF_SEQUENCE_ID): cv.positive_int,
|
|
}
|
|
),
|
|
cv.has_at_least_one_key(CONF_FOR, CONF_UNTIL, CONF_RESET),
|
|
)
|
|
|
|
CANCEL_SCHEMA = {
|
|
vol.Required(CONF_ENTITY_ID): cv.entity_ids,
|
|
vol.Optional(CONF_ZONES): cv.ensure_list,
|
|
vol.Optional(CONF_SEQUENCE_ID): cv.positive_int,
|
|
}
|
|
|
|
PAUSE_RESUME_SCHEMA = {
|
|
vol.Required(CONF_ENTITY_ID): cv.entity_ids,
|
|
vol.Optional(CONF_SEQUENCE_ID): cv.positive_int,
|
|
}
|
|
|
|
RELOAD_SERVICE_SCHEMA = vol.Schema({})
|