Files
2026-07-08 10:43:39 -04:00

221 lines
6.3 KiB
Python

"""Store constants."""
import voluptuous as vol
import re
import homeassistant.util.dt as dt_util
from homeassistant.helpers import config_validation as cv
from homeassistant.const import (
WEEKDAYS,
ATTR_ENTITY_ID,
SUN_EVENT_SUNRISE,
SUN_EVENT_SUNSET,
ATTR_SERVICE,
ATTR_SERVICE_DATA,
CONF_CONDITIONS,
CONF_ATTRIBUTE,
ATTR_NAME,
)
VERSION = "3.3.8"
DOMAIN = "scheduler"
SUN_ENTITY = "sun.sun"
DAY_TYPE_DAILY = "daily"
DAY_TYPE_WORKDAY = "workday"
DAY_TYPE_WEEKEND = "weekend"
WORKDAY_ENTITY = "binary_sensor.workday_sensor"
ATTR_SKIP_CONDITIONS = "skip_conditions"
ATTR_CONDITION_TYPE = "condition_type"
CONDITION_TYPE_AND = "and"
CONDITION_TYPE_OR = "or"
ATTR_MATCH_TYPE = "match_type"
MATCH_TYPE_EQUAL = "is"
MATCH_TYPE_UNEQUAL = "not"
MATCH_TYPE_BELOW = "below"
MATCH_TYPE_ABOVE = "above"
ATTR_TRACK_CONDITIONS = "track_conditions"
ATTR_REPEAT_TYPE = "repeat_type"
REPEAT_TYPE_REPEAT = "repeat"
REPEAT_TYPE_SINGLE = "single"
REPEAT_TYPE_PAUSE = "pause"
EVENT = "scheduler_updated"
SERVICE_REMOVE = "remove"
SERVICE_EDIT = "edit"
SERVICE_ADD = "add"
SERVICE_COPY = "copy"
SERVICE_DISABLE_ALL = "disable_all"
SERVICE_ENABLE_ALL = "enable_all"
OffsetTimePattern = re.compile(r"^([a-z]+)([-|\+]{1})([0-9:]+)$")
DatePattern = re.compile(r"^[0-9]+\-[0-9]+\-[0-9]+$")
ATTR_START = "start"
ATTR_STOP = "stop"
ATTR_TIMESLOTS = "timeslots"
ATTR_WEEKDAYS = "weekdays"
ATTR_ENABLED = "enabled"
ATTR_SCHEDULE_ID = "schedule_id"
ATTR_ACTIONS = "actions"
ATTR_VALUE = "value"
ATTR_TAGS = "tags"
ATTR_SCHEDULES = "schedules"
ATTR_START_DATE = "start_date"
ATTR_END_DATE = "end_date"
EVENT_TIMER_FINISHED = "scheduler_timer_finished"
EVENT_TIMER_UPDATED = "scheduler_timer_updated"
EVENT_ITEM_UPDATED = "scheduler_item_updated"
EVENT_ITEM_CREATED = "scheduler_item_created"
EVENT_ITEM_REMOVED = "scheduler_item_removed"
EVENT_STARTED = "scheduler_started"
EVENT_WORKDAY_SENSOR_UPDATED = "workday_sensor_updated"
STATE_INIT = "init"
STATE_READY = "ready"
STATE_COMPLETED = "completed"
def validate_time(time):
res = OffsetTimePattern.match(time)
if not res:
if dt_util.parse_time(time):
return time
else:
raise vol.Invalid("Invalid time entered: {}".format(time))
else:
if res.group(1) not in [SUN_EVENT_SUNRISE, SUN_EVENT_SUNSET]:
raise vol.Invalid("Invalid time entered: {}".format(time))
elif res.group(2) not in ["+", "-"]:
raise vol.Invalid("Invalid time entered: {}".format(time))
elif not dt_util.parse_time(res.group(3)):
raise vol.Invalid("Invalid time entered: {}".format(time))
else:
return time
def validate_date(value: str) -> str:
"""Input must be either none or a valid date."""
if value is None:
return None
date = dt_util.parse_date(value)
if date is None:
raise vol.Invalid("Invalid date entered: {}".format(value))
else:
return date.strftime("%Y-%m-%d")
CONDITION_SCHEMA = vol.Schema(
{
vol.Required(ATTR_ENTITY_ID): cv.entity_id,
vol.Required(ATTR_VALUE): vol.Any(int, float, str),
vol.Optional(CONF_ATTRIBUTE): cv.string,
vol.Required(ATTR_MATCH_TYPE): vol.In(
[MATCH_TYPE_EQUAL, MATCH_TYPE_UNEQUAL, MATCH_TYPE_BELOW, MATCH_TYPE_ABOVE]
),
}
)
ACTION_SCHEMA = vol.Schema(
{
vol.Optional(ATTR_ENTITY_ID): cv.entity_id,
vol.Required(ATTR_SERVICE): cv.entity_id,
vol.Optional(ATTR_SERVICE_DATA): dict,
}
)
TIMESLOT_SCHEMA = vol.Schema(
{
vol.Required(ATTR_START): validate_time,
vol.Optional(ATTR_STOP): validate_time,
vol.Optional(CONF_CONDITIONS): vol.All(
cv.ensure_list, vol.Length(min=1), [CONDITION_SCHEMA]
),
vol.Optional(ATTR_CONDITION_TYPE): vol.In(
[
CONDITION_TYPE_AND,
CONDITION_TYPE_OR,
]
),
vol.Optional(ATTR_TRACK_CONDITIONS): cv.boolean,
vol.Required(ATTR_ACTIONS): vol.All(
cv.ensure_list, vol.Length(min=1), [ACTION_SCHEMA]
),
}
)
ADD_SCHEDULE_SCHEMA = vol.Schema(
{
vol.Optional(ATTR_WEEKDAYS, default=[DAY_TYPE_DAILY]): vol.All(
cv.ensure_list,
vol.Unique(),
vol.Length(min=1),
[
vol.In(
WEEKDAYS
+ [
DAY_TYPE_WORKDAY,
DAY_TYPE_WEEKEND,
DAY_TYPE_DAILY,
]
)
],
),
vol.Optional(ATTR_START_DATE, default=None): validate_date,
vol.Optional(ATTR_END_DATE, default=None): validate_date,
vol.Required(ATTR_TIMESLOTS): vol.All(
cv.ensure_list, vol.Length(min=1), [TIMESLOT_SCHEMA]
),
vol.Required(ATTR_REPEAT_TYPE): vol.In(
[
REPEAT_TYPE_REPEAT,
REPEAT_TYPE_SINGLE,
REPEAT_TYPE_PAUSE,
]
),
vol.Optional(ATTR_NAME): vol.Any(cv.string, None),
vol.Optional(ATTR_TAGS): vol.All(cv.ensure_list, vol.Unique(), [cv.string]),
}
)
EDIT_SCHEDULE_SCHEMA = vol.Schema(
{
vol.Optional(ATTR_WEEKDAYS): vol.All(
cv.ensure_list,
vol.Unique(),
vol.Length(min=1),
[
vol.In(
WEEKDAYS
+ [
DAY_TYPE_WORKDAY,
DAY_TYPE_WEEKEND,
DAY_TYPE_DAILY,
]
)
],
),
vol.Optional(ATTR_START_DATE, default=None): validate_date,
vol.Optional(ATTR_END_DATE, default=None): validate_date,
vol.Optional(ATTR_TIMESLOTS): vol.All(
cv.ensure_list, vol.Length(min=1), [TIMESLOT_SCHEMA]
),
vol.Optional(ATTR_REPEAT_TYPE): vol.In(
[
REPEAT_TYPE_REPEAT,
REPEAT_TYPE_SINGLE,
REPEAT_TYPE_PAUSE,
]
),
vol.Optional(ATTR_NAME): vol.Any(cv.string, None),
vol.Optional(ATTR_TAGS): vol.All(cv.ensure_list, vol.Unique(), [cv.string]),
}
)