129 lines
4.0 KiB
Python
129 lines
4.0 KiB
Python
"""Template config validator."""
|
|
import logging
|
|
|
|
import voluptuous as vol
|
|
|
|
from homeassistant.components.sensor import (
|
|
DEVICE_CLASSES_SCHEMA as SENSOR_DEVICE_CLASSES_SCHEMA,
|
|
DOMAIN as SENSOR_DOMAIN,
|
|
)
|
|
from homeassistant.config import async_log_exception, config_without_domain
|
|
from homeassistant.const import (
|
|
CONF_DEVICE_CLASS,
|
|
CONF_ENTITY_PICTURE_TEMPLATE,
|
|
CONF_FRIENDLY_NAME,
|
|
CONF_FRIENDLY_NAME_TEMPLATE,
|
|
CONF_ICON,
|
|
CONF_ICON_TEMPLATE,
|
|
CONF_NAME,
|
|
CONF_SENSORS,
|
|
CONF_STATE,
|
|
CONF_UNIQUE_ID,
|
|
CONF_UNIT_OF_MEASUREMENT,
|
|
CONF_VALUE_TEMPLATE,
|
|
)
|
|
from homeassistant.helpers import config_validation as cv, template
|
|
from homeassistant.helpers.trigger import async_validate_trigger_config
|
|
|
|
from .const import (
|
|
CONF_ATTRIBUTE_TEMPLATES,
|
|
CONF_ATTRIBUTES,
|
|
CONF_AVAILABILITY,
|
|
CONF_AVAILABILITY_TEMPLATE,
|
|
CONF_PICTURE,
|
|
CONF_TRIGGER,
|
|
DOMAIN,
|
|
)
|
|
from .sensor import SENSOR_SCHEMA as PLATFORM_SENSOR_SCHEMA
|
|
|
|
LEGACY_SENSOR = {
|
|
CONF_ICON_TEMPLATE: CONF_ICON,
|
|
CONF_ENTITY_PICTURE_TEMPLATE: CONF_PICTURE,
|
|
CONF_AVAILABILITY_TEMPLATE: CONF_AVAILABILITY,
|
|
CONF_ATTRIBUTE_TEMPLATES: CONF_ATTRIBUTES,
|
|
CONF_FRIENDLY_NAME_TEMPLATE: CONF_NAME,
|
|
CONF_FRIENDLY_NAME: CONF_NAME,
|
|
CONF_VALUE_TEMPLATE: CONF_STATE,
|
|
}
|
|
|
|
|
|
SENSOR_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Optional(CONF_NAME): cv.template,
|
|
vol.Required(CONF_STATE): cv.template,
|
|
vol.Optional(CONF_ICON): cv.template,
|
|
vol.Optional(CONF_PICTURE): cv.template,
|
|
vol.Optional(CONF_AVAILABILITY): cv.template,
|
|
vol.Optional(CONF_ATTRIBUTES): vol.Schema({cv.string: cv.template}),
|
|
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
|
|
vol.Optional(CONF_DEVICE_CLASS): SENSOR_DEVICE_CLASSES_SCHEMA,
|
|
vol.Optional(CONF_UNIQUE_ID): cv.string,
|
|
}
|
|
)
|
|
|
|
CONFIG_SECTION_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Optional(CONF_UNIQUE_ID): cv.string,
|
|
vol.Required(CONF_TRIGGER): cv.TRIGGER_SCHEMA,
|
|
vol.Optional(SENSOR_DOMAIN): vol.All(cv.ensure_list, [SENSOR_SCHEMA]),
|
|
vol.Optional(CONF_SENSORS): cv.schema_with_slug_keys(PLATFORM_SENSOR_SCHEMA),
|
|
}
|
|
)
|
|
|
|
|
|
def _rewrite_legacy_to_modern_trigger_conf(cfg: dict):
|
|
"""Rewrite a legacy to a modern trigger-basd conf."""
|
|
logging.getLogger(__name__).warning(
|
|
"The entity definition format under template: differs from the platform configuration format. See https://www.home-assistant.io/integrations/template#configuration-for-trigger-based-template-sensors"
|
|
)
|
|
sensor = list(cfg[SENSOR_DOMAIN]) if SENSOR_DOMAIN in cfg else []
|
|
|
|
for device_id, entity_cfg in cfg[CONF_SENSORS].items():
|
|
entity_cfg = {**entity_cfg}
|
|
|
|
for from_key, to_key in LEGACY_SENSOR.items():
|
|
if from_key not in entity_cfg or to_key in entity_cfg:
|
|
continue
|
|
|
|
val = entity_cfg.pop(from_key)
|
|
if isinstance(val, str):
|
|
val = template.Template(val)
|
|
entity_cfg[to_key] = val
|
|
|
|
if CONF_NAME not in entity_cfg:
|
|
entity_cfg[CONF_NAME] = template.Template(device_id)
|
|
|
|
sensor.append(entity_cfg)
|
|
|
|
return {**cfg, "sensor": sensor}
|
|
|
|
|
|
async def async_validate_config(hass, config):
|
|
"""Validate config."""
|
|
if DOMAIN not in config:
|
|
return config
|
|
|
|
config_sections = []
|
|
|
|
for cfg in cv.ensure_list(config[DOMAIN]):
|
|
try:
|
|
cfg = CONFIG_SECTION_SCHEMA(cfg)
|
|
cfg[CONF_TRIGGER] = await async_validate_trigger_config(
|
|
hass, cfg[CONF_TRIGGER]
|
|
)
|
|
except vol.Invalid as err:
|
|
async_log_exception(err, DOMAIN, cfg, hass)
|
|
continue
|
|
|
|
if CONF_TRIGGER in cfg and CONF_SENSORS in cfg:
|
|
cfg = _rewrite_legacy_to_modern_trigger_conf(cfg)
|
|
|
|
config_sections.append(cfg)
|
|
|
|
# Create a copy of the configuration with all config for current
|
|
# component removed and add validated config back in.
|
|
config = config_without_domain(config, DOMAIN)
|
|
config[DOMAIN] = config_sections
|
|
|
|
return config
|