"""Schemas for the blueprint integration.""" from typing import Any import voluptuous as vol from homeassistant.const import ( CONF_DEFAULT, CONF_DOMAIN, CONF_NAME, CONF_PATH, CONF_SELECTOR, ) from homeassistant.core import callback from homeassistant.helpers import config_validation as cv, selector from .const import ( CONF_BLUEPRINT, CONF_DESCRIPTION, CONF_HOMEASSISTANT, CONF_INPUT, CONF_MIN_VERSION, CONF_SOURCE_URL, CONF_USE_BLUEPRINT, ) def version_validator(value): """Validate a Home Assistant version.""" if not isinstance(value, str): raise vol.Invalid("Version needs to be a string") parts = value.split(".") if len(parts) != 3: raise vol.Invalid("Version needs to be formatted as {major}.{minor}.{patch}") try: parts = [int(p) for p in parts] except ValueError: raise vol.Invalid( "Major, minor and patch version needs to be an integer" ) from None return value @callback def is_blueprint_config(config: Any) -> bool: """Return if it is a blueprint config.""" return isinstance(config, dict) and CONF_BLUEPRINT in config @callback def is_blueprint_instance_config(config: Any) -> bool: """Return if it is a blueprint instance config.""" return isinstance(config, dict) and CONF_USE_BLUEPRINT in config BLUEPRINT_INPUT_SCHEMA = vol.Schema( { vol.Optional(CONF_NAME): str, vol.Optional(CONF_DESCRIPTION): str, vol.Optional(CONF_DEFAULT): cv.match_all, vol.Optional(CONF_SELECTOR): selector.validate_selector, } ) BLUEPRINT_SCHEMA = vol.Schema( { vol.Required(CONF_BLUEPRINT): vol.Schema( { vol.Required(CONF_NAME): str, vol.Optional(CONF_DESCRIPTION): str, vol.Required(CONF_DOMAIN): str, vol.Optional(CONF_SOURCE_URL): cv.url, vol.Optional(CONF_HOMEASSISTANT): { vol.Optional(CONF_MIN_VERSION): version_validator }, vol.Optional(CONF_INPUT, default=dict): { str: vol.Any( None, BLUEPRINT_INPUT_SCHEMA, ) }, } ), }, extra=vol.ALLOW_EXTRA, ) def validate_yaml_suffix(value: str) -> str: """Validate value has a YAML suffix.""" if not value.endswith(".yaml"): raise vol.Invalid("Path needs to end in .yaml") return value BLUEPRINT_INSTANCE_FIELDS = vol.Schema( { vol.Required(CONF_USE_BLUEPRINT): vol.Schema( { vol.Required(CONF_PATH): vol.All(cv.path, validate_yaml_suffix), vol.Required(CONF_INPUT, default=dict): {str: cv.match_all}, } ) }, extra=vol.ALLOW_EXTRA, )