Consolidate template integration's config schemas (#149018)

This commit is contained in:
Petro31 2025-07-18 14:38:53 -04:00 committed by GitHub
parent 3877a6211a
commit 33cc257e75
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 385 additions and 253 deletions

View File

@ -21,7 +21,6 @@ from homeassistant.components.alarm_control_panel import (
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_CODE,
CONF_DEVICE_ID,
CONF_NAME,
CONF_STATE,
CONF_UNIQUE_ID,
@ -31,7 +30,7 @@ from homeassistant.const import (
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import TemplateError
from homeassistant.helpers import config_validation as cv, selector, template
from homeassistant.helpers import config_validation as cv, template
from homeassistant.helpers.entity_platform import (
AddConfigEntryEntitiesCallback,
AddEntitiesCallback,
@ -43,8 +42,16 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from .const import DOMAIN
from .coordinator import TriggerUpdateCoordinator
from .entity import AbstractTemplateEntity
from .helpers import async_setup_template_platform
from .template_entity import TemplateEntity, make_template_entity_common_modern_schema
from .helpers import (
async_setup_template_entry,
async_setup_template_platform,
async_setup_template_preview,
)
from .template_entity import (
TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA,
TemplateEntity,
make_template_entity_common_modern_schema,
)
from .trigger_entity import TriggerEntity
_LOGGER = logging.getLogger(__name__)
@ -88,8 +95,7 @@ LEGACY_FIELDS = {
DEFAULT_NAME = "Template Alarm Control Panel"
ALARM_CONTROL_PANEL_SCHEMA = vol.All(
vol.Schema(
ALARM_CONTROL_PANEL_COMMON_SCHEMA = vol.Schema(
{
vol.Optional(CONF_ARM_AWAY_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_ARM_CUSTOM_BYPASS_ACTION): cv.SCRIPT_SCHEMA,
@ -97,18 +103,20 @@ ALARM_CONTROL_PANEL_SCHEMA = vol.All(
vol.Optional(CONF_ARM_NIGHT_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_ARM_VACATION_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_CODE_ARM_REQUIRED, default=True): cv.boolean,
vol.Optional(
CONF_CODE_FORMAT, default=TemplateCodeFormat.number.name
): cv.enum(TemplateCodeFormat),
vol.Optional(CONF_CODE_FORMAT, default=TemplateCodeFormat.number.name): cv.enum(
TemplateCodeFormat
),
vol.Optional(CONF_DISARM_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_STATE): cv.template,
vol.Optional(CONF_TRIGGER_ACTION): cv.SCRIPT_SCHEMA,
}
).extend(make_template_entity_common_modern_schema(DEFAULT_NAME).schema)
)
ALARM_CONTROL_PANEL_YAML_SCHEMA = ALARM_CONTROL_PANEL_COMMON_SCHEMA.extend(
make_template_entity_common_modern_schema(DEFAULT_NAME).schema
)
LEGACY_ALARM_CONTROL_PANEL_SCHEMA = vol.Schema(
ALARM_CONTROL_PANEL_LEGACY_YAML_SCHEMA = vol.Schema(
{
vol.Optional(CONF_ARM_AWAY_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_ARM_CUSTOM_BYPASS_ACTION): cv.SCRIPT_SCHEMA,
@ -130,59 +138,29 @@ LEGACY_ALARM_CONTROL_PANEL_SCHEMA = vol.Schema(
PLATFORM_SCHEMA = ALARM_CONTROL_PANEL_PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_ALARM_CONTROL_PANELS): cv.schema_with_slug_keys(
LEGACY_ALARM_CONTROL_PANEL_SCHEMA
ALARM_CONTROL_PANEL_LEGACY_YAML_SCHEMA
),
}
)
ALARM_CONTROL_PANEL_CONFIG_SCHEMA = vol.Schema(
{
vol.Optional(CONF_ARM_AWAY_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_ARM_CUSTOM_BYPASS_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_ARM_HOME_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_ARM_NIGHT_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_ARM_VACATION_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_CODE_ARM_REQUIRED, default=True): cv.boolean,
vol.Optional(CONF_CODE_FORMAT, default=TemplateCodeFormat.number.name): cv.enum(
TemplateCodeFormat
),
vol.Optional(CONF_DEVICE_ID): selector.DeviceSelector(),
vol.Optional(CONF_DISARM_ACTION): cv.SCRIPT_SCHEMA,
vol.Required(CONF_NAME): cv.template,
vol.Optional(CONF_STATE): cv.template,
vol.Optional(CONF_TRIGGER_ACTION): cv.SCRIPT_SCHEMA,
}
ALARM_CONTROL_PANEL_CONFIG_ENTRY_SCHEMA = ALARM_CONTROL_PANEL_COMMON_SCHEMA.extend(
TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA.schema
)
def rewrite_options_to_modern_conf(option_config: dict[str, dict]) -> dict[str, dict]:
"""Rewrite option configuration to modern configuration."""
option_config = {**option_config}
if CONF_VALUE_TEMPLATE in option_config:
option_config[CONF_STATE] = option_config.pop(CONF_VALUE_TEMPLATE)
return option_config
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Initialize config entry."""
_options = dict(config_entry.options)
_options.pop("template_type")
_options = rewrite_options_to_modern_conf(_options)
validated_config = ALARM_CONTROL_PANEL_CONFIG_SCHEMA(_options)
async_add_entities(
[
StateAlarmControlPanelEntity(
await async_setup_template_entry(
hass,
validated_config,
config_entry.entry_id,
)
]
config_entry,
async_add_entities,
StateAlarmControlPanelEntity,
ALARM_CONTROL_PANEL_CONFIG_ENTRY_SCHEMA,
True,
)
@ -211,11 +189,14 @@ def async_create_preview_alarm_control_panel(
hass: HomeAssistant, name: str, config: dict[str, Any]
) -> StateAlarmControlPanelEntity:
"""Create a preview alarm control panel."""
updated_config = rewrite_options_to_modern_conf(config)
validated_config = ALARM_CONTROL_PANEL_CONFIG_SCHEMA(
updated_config | {CONF_NAME: name}
return async_setup_template_preview(
hass,
name,
config,
StateAlarmControlPanelEntity,
ALARM_CONTROL_PANEL_CONFIG_ENTRY_SCHEMA,
True,
)
return StateAlarmControlPanelEntity(hass, validated_config, None)
class AbstractTemplateAlarmControlPanel(

View File

@ -22,7 +22,6 @@ from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_FRIENDLY_NAME,
CONF_DEVICE_CLASS,
CONF_DEVICE_ID,
CONF_ENTITY_PICTURE_TEMPLATE,
CONF_FRIENDLY_NAME_TEMPLATE,
CONF_ICON_TEMPLATE,
@ -38,7 +37,7 @@ from homeassistant.const import (
)
from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
from homeassistant.exceptions import TemplateError
from homeassistant.helpers import config_validation as cv, selector, template
from homeassistant.helpers import config_validation as cv, template
from homeassistant.helpers.entity_platform import (
AddConfigEntryEntitiesCallback,
AddEntitiesCallback,
@ -50,8 +49,16 @@ from homeassistant.util import dt as dt_util
from . import TriggerUpdateCoordinator
from .const import CONF_AVAILABILITY_TEMPLATE
from .helpers import async_setup_template_platform
from .template_entity import TEMPLATE_ENTITY_COMMON_SCHEMA, TemplateEntity
from .helpers import (
async_setup_template_entry,
async_setup_template_platform,
async_setup_template_preview,
)
from .template_entity import (
TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA,
TEMPLATE_ENTITY_COMMON_SCHEMA,
TemplateEntity,
)
from .trigger_entity import TriggerEntity
CONF_DELAY_ON = "delay_on"
@ -64,7 +71,7 @@ LEGACY_FIELDS = {
CONF_VALUE_TEMPLATE: CONF_STATE,
}
BINARY_SENSOR_SCHEMA = vol.Schema(
BINARY_SENSOR_COMMON_SCHEMA = vol.Schema(
{
vol.Optional(CONF_AUTO_OFF): vol.Any(cv.positive_time_period, cv.template),
vol.Optional(CONF_DELAY_OFF): vol.Any(cv.positive_time_period, cv.template),
@ -73,15 +80,17 @@ BINARY_SENSOR_SCHEMA = vol.Schema(
vol.Required(CONF_STATE): cv.template,
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
}
).extend(TEMPLATE_ENTITY_COMMON_SCHEMA.schema)
BINARY_SENSOR_CONFIG_SCHEMA = BINARY_SENSOR_SCHEMA.extend(
{
vol.Optional(CONF_DEVICE_ID): selector.DeviceSelector(),
}
)
LEGACY_BINARY_SENSOR_SCHEMA = vol.All(
BINARY_SENSOR_YAML_SCHEMA = BINARY_SENSOR_COMMON_SCHEMA.extend(
TEMPLATE_ENTITY_COMMON_SCHEMA.schema
)
BINARY_SENSOR_CONFIG_ENTRY_SCHEMA = BINARY_SENSOR_COMMON_SCHEMA.extend(
TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA.schema
)
BINARY_SENSOR_LEGACY_YAML_SCHEMA = vol.All(
cv.deprecated(ATTR_ENTITY_ID),
vol.Schema(
{
@ -106,7 +115,7 @@ LEGACY_BINARY_SENSOR_SCHEMA = vol.All(
PLATFORM_SCHEMA = BINARY_SENSOR_PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_SENSORS): cv.schema_with_slug_keys(
LEGACY_BINARY_SENSOR_SCHEMA
BINARY_SENSOR_LEGACY_YAML_SCHEMA
),
}
)
@ -138,11 +147,12 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Initialize config entry."""
_options = dict(config_entry.options)
_options.pop("template_type")
validated_config = BINARY_SENSOR_CONFIG_SCHEMA(_options)
async_add_entities(
[StateBinarySensorEntity(hass, validated_config, config_entry.entry_id)]
await async_setup_template_entry(
hass,
config_entry,
async_add_entities,
StateBinarySensorEntity,
BINARY_SENSOR_CONFIG_ENTRY_SCHEMA,
)
@ -151,8 +161,9 @@ def async_create_preview_binary_sensor(
hass: HomeAssistant, name: str, config: dict[str, Any]
) -> StateBinarySensorEntity:
"""Create a preview sensor."""
validated_config = BINARY_SENSOR_CONFIG_SCHEMA(config | {CONF_NAME: name})
return StateBinarySensorEntity(hass, validated_config, None)
return async_setup_template_preview(
hass, name, config, StateBinarySensorEntity, BINARY_SENSOR_CONFIG_ENTRY_SCHEMA
)
class StateBinarySensorEntity(TemplateEntity, BinarySensorEntity, RestoreEntity):

View File

@ -14,9 +14,9 @@ from homeassistant.components.button import (
ButtonEntity,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_DEVICE_CLASS, CONF_DEVICE_ID, CONF_NAME
from homeassistant.const import CONF_DEVICE_CLASS
from homeassistant.core import HomeAssistant
from homeassistant.helpers import config_validation as cv, selector
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity_platform import (
AddConfigEntryEntitiesCallback,
AddEntitiesCallback,
@ -24,29 +24,31 @@ from homeassistant.helpers.entity_platform import (
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from .const import CONF_PRESS, DOMAIN
from .helpers import async_setup_template_platform
from .template_entity import TemplateEntity, make_template_entity_common_modern_schema
from .helpers import async_setup_template_entry, async_setup_template_platform
from .template_entity import (
TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA,
TemplateEntity,
make_template_entity_common_modern_schema,
)
_LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = "Template Button"
DEFAULT_OPTIMISTIC = False
BUTTON_SCHEMA = vol.Schema(
BUTTON_YAML_SCHEMA = vol.Schema(
{
vol.Required(CONF_PRESS): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
}
).extend(make_template_entity_common_modern_schema(DEFAULT_NAME).schema)
CONFIG_BUTTON_SCHEMA = vol.Schema(
BUTTON_CONFIG_ENTRY_SCHEMA = vol.Schema(
{
vol.Optional(CONF_NAME): cv.template,
vol.Optional(CONF_PRESS): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_DEVICE_ID): selector.DeviceSelector(),
}
)
).extend(TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA.schema)
async def async_setup_platform(
@ -73,11 +75,12 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Initialize config entry."""
_options = dict(config_entry.options)
_options.pop("template_type")
validated_config = CONFIG_BUTTON_SCHEMA(_options)
async_add_entities(
[StateButtonEntity(hass, validated_config, config_entry.entry_id)]
await async_setup_template_entry(
hass,
config_entry,
async_add_entities,
StateButtonEntity,
BUTTON_CONFIG_ENTRY_SCHEMA,
)

View File

@ -102,57 +102,57 @@ CONFIG_SECTION_SCHEMA = vol.All(
{
vol.Optional(CONF_ACTIONS): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_BINARY_SENSORS): cv.schema_with_slug_keys(
binary_sensor_platform.LEGACY_BINARY_SENSOR_SCHEMA
binary_sensor_platform.BINARY_SENSOR_LEGACY_YAML_SCHEMA
),
vol.Optional(CONF_CONDITIONS): cv.CONDITIONS_SCHEMA,
vol.Optional(CONF_SENSORS): cv.schema_with_slug_keys(
sensor_platform.LEGACY_SENSOR_SCHEMA
sensor_platform.SENSOR_LEGACY_YAML_SCHEMA
),
vol.Optional(CONF_TRIGGERS): cv.TRIGGER_SCHEMA,
vol.Optional(CONF_UNIQUE_ID): cv.string,
vol.Optional(CONF_VARIABLES): cv.SCRIPT_VARIABLES_SCHEMA,
vol.Optional(DOMAIN_ALARM_CONTROL_PANEL): vol.All(
cv.ensure_list,
[alarm_control_panel_platform.ALARM_CONTROL_PANEL_SCHEMA],
[alarm_control_panel_platform.ALARM_CONTROL_PANEL_YAML_SCHEMA],
),
vol.Optional(DOMAIN_BINARY_SENSOR): vol.All(
cv.ensure_list, [binary_sensor_platform.BINARY_SENSOR_SCHEMA]
cv.ensure_list, [binary_sensor_platform.BINARY_SENSOR_YAML_SCHEMA]
),
vol.Optional(DOMAIN_BUTTON): vol.All(
cv.ensure_list, [button_platform.BUTTON_SCHEMA]
cv.ensure_list, [button_platform.BUTTON_YAML_SCHEMA]
),
vol.Optional(DOMAIN_COVER): vol.All(
cv.ensure_list, [cover_platform.COVER_SCHEMA]
cv.ensure_list, [cover_platform.COVER_YAML_SCHEMA]
),
vol.Optional(DOMAIN_FAN): vol.All(
cv.ensure_list, [fan_platform.FAN_SCHEMA]
cv.ensure_list, [fan_platform.FAN_YAML_SCHEMA]
),
vol.Optional(DOMAIN_IMAGE): vol.All(
cv.ensure_list, [image_platform.IMAGE_SCHEMA]
cv.ensure_list, [image_platform.IMAGE_YAML_SCHEMA]
),
vol.Optional(DOMAIN_LIGHT): vol.All(
cv.ensure_list, [light_platform.LIGHT_SCHEMA]
cv.ensure_list, [light_platform.LIGHT_YAML_SCHEMA]
),
vol.Optional(DOMAIN_LOCK): vol.All(
cv.ensure_list, [lock_platform.LOCK_SCHEMA]
cv.ensure_list, [lock_platform.LOCK_YAML_SCHEMA]
),
vol.Optional(DOMAIN_NUMBER): vol.All(
cv.ensure_list, [number_platform.NUMBER_SCHEMA]
cv.ensure_list, [number_platform.NUMBER_YAML_SCHEMA]
),
vol.Optional(DOMAIN_SELECT): vol.All(
cv.ensure_list, [select_platform.SELECT_SCHEMA]
cv.ensure_list, [select_platform.SELECT_YAML_SCHEMA]
),
vol.Optional(DOMAIN_SENSOR): vol.All(
cv.ensure_list, [sensor_platform.SENSOR_SCHEMA]
cv.ensure_list, [sensor_platform.SENSOR_YAML_SCHEMA]
),
vol.Optional(DOMAIN_SWITCH): vol.All(
cv.ensure_list, [switch_platform.SWITCH_SCHEMA]
cv.ensure_list, [switch_platform.SWITCH_YAML_SCHEMA]
),
vol.Optional(DOMAIN_VACUUM): vol.All(
cv.ensure_list, [vacuum_platform.VACUUM_SCHEMA]
cv.ensure_list, [vacuum_platform.VACUUM_YAML_SCHEMA]
),
vol.Optional(DOMAIN_WEATHER): vol.All(
cv.ensure_list, [weather_platform.WEATHER_SCHEMA]
cv.ensure_list, [weather_platform.WEATHER_YAML_SCHEMA]
),
},
),

View File

@ -1,6 +1,9 @@
"""Constants for the Template Platform Components."""
from homeassistant.const import Platform
import voluptuous as vol
from homeassistant.const import CONF_ICON, CONF_NAME, CONF_UNIQUE_ID, Platform
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.typing import ConfigType
CONF_ATTRIBUTE_TEMPLATES = "attribute_templates"
@ -16,6 +19,15 @@ CONF_STEP = "step"
CONF_TURN_OFF = "turn_off"
CONF_TURN_ON = "turn_on"
TEMPLATE_ENTITY_BASE_SCHEMA = vol.Schema(
{
vol.Optional(CONF_ICON): cv.template,
vol.Optional(CONF_NAME): cv.template,
vol.Optional(CONF_PICTURE): cv.template,
vol.Optional(CONF_UNIQUE_ID): cv.string,
}
)
DOMAIN = "template"
PLATFORM_STORAGE_KEY = "template_platforms"

View File

@ -91,7 +91,7 @@ LEGACY_FIELDS = {
DEFAULT_NAME = "Template Cover"
COVER_SCHEMA = vol.All(
COVER_YAML_SCHEMA = vol.All(
vol.Schema(
{
vol.Inclusive(CLOSE_ACTION, CONF_OPEN_AND_CLOSE): cv.SCRIPT_SCHEMA,
@ -110,7 +110,7 @@ COVER_SCHEMA = vol.All(
cv.has_at_least_one_key(OPEN_ACTION, POSITION_ACTION),
)
LEGACY_COVER_SCHEMA = vol.All(
COVER_LEGACY_YAML_SCHEMA = vol.All(
cv.deprecated(CONF_ENTITY_ID),
vol.Schema(
{
@ -134,7 +134,7 @@ LEGACY_COVER_SCHEMA = vol.All(
)
PLATFORM_SCHEMA = COVER_PLATFORM_SCHEMA.extend(
{vol.Required(CONF_COVERS): cv.schema_with_slug_keys(LEGACY_COVER_SCHEMA)}
{vol.Required(CONF_COVERS): cv.schema_with_slug_keys(COVER_LEGACY_YAML_SCHEMA)}
)

View File

@ -81,7 +81,7 @@ LEGACY_FIELDS = {
DEFAULT_NAME = "Template Fan"
FAN_SCHEMA = vol.All(
FAN_YAML_SCHEMA = vol.All(
vol.Schema(
{
vol.Optional(CONF_DIRECTION): cv.template,
@ -101,7 +101,7 @@ FAN_SCHEMA = vol.All(
).extend(make_template_entity_common_modern_schema(DEFAULT_NAME).schema)
)
LEGACY_FAN_SCHEMA = vol.All(
FAN_LEGACY_YAML_SCHEMA = vol.All(
cv.deprecated(CONF_ENTITY_ID),
vol.Schema(
{
@ -126,7 +126,7 @@ LEGACY_FAN_SCHEMA = vol.All(
)
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend(
{vol.Required(CONF_FANS): cv.schema_with_slug_keys(LEGACY_FAN_SCHEMA)}
{vol.Required(CONF_FANS): cv.schema_with_slug_keys(FAN_LEGACY_YAML_SCHEMA)}
)

View File

@ -5,14 +5,19 @@ import itertools
import logging
from typing import Any
import voluptuous as vol
from homeassistant.components import blueprint
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
CONF_ENTITY_PICTURE_TEMPLATE,
CONF_FRIENDLY_NAME,
CONF_ICON,
CONF_ICON_TEMPLATE,
CONF_NAME,
CONF_STATE,
CONF_UNIQUE_ID,
CONF_VALUE_TEMPLATE,
SERVICE_RELOAD,
)
from homeassistant.core import HomeAssistant, callback
@ -20,6 +25,7 @@ from homeassistant.exceptions import PlatformNotReady
from homeassistant.helpers import template
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_platform import (
AddConfigEntryEntitiesCallback,
AddEntitiesCallback,
async_get_platforms,
)
@ -228,3 +234,41 @@ async def async_setup_template_platform(
discovery_info["entities"],
discovery_info["unique_id"],
)
async def async_setup_template_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
state_entity_cls: type[TemplateEntity],
config_schema: vol.Schema,
replace_value_template: bool = False,
) -> None:
"""Setup the Template from a config entry."""
options = dict(config_entry.options)
options.pop("template_type")
if replace_value_template and CONF_VALUE_TEMPLATE in options:
options[CONF_STATE] = options.pop(CONF_VALUE_TEMPLATE)
validated_config = config_schema(options)
async_add_entities(
[state_entity_cls(hass, validated_config, config_entry.entry_id)]
)
def async_setup_template_preview[T: TemplateEntity](
hass: HomeAssistant,
name: str,
config: ConfigType,
state_entity_cls: type[T],
schema: vol.Schema,
replace_value_template: bool = False,
) -> T:
"""Setup the Template preview."""
if replace_value_template and CONF_VALUE_TEMPLATE in config:
config[CONF_STATE] = config.pop(CONF_VALUE_TEMPLATE)
validated_config = schema(config | {CONF_NAME: name})
return state_entity_cls(hass, validated_config, None)

View File

@ -13,10 +13,10 @@ from homeassistant.components.image import (
ImageEntity,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_DEVICE_ID, CONF_NAME, CONF_URL, CONF_VERIFY_SSL
from homeassistant.const import CONF_URL, CONF_VERIFY_SSL
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import TemplateError
from homeassistant.helpers import config_validation as cv, selector
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity_platform import (
AddConfigEntryEntitiesCallback,
AddEntitiesCallback,
@ -26,8 +26,9 @@ from homeassistant.util import dt as dt_util
from . import TriggerUpdateCoordinator
from .const import CONF_PICTURE
from .helpers import async_setup_template_platform
from .helpers import async_setup_template_entry, async_setup_template_platform
from .template_entity import (
TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA,
TemplateEntity,
make_template_entity_common_modern_attributes_schema,
)
@ -39,7 +40,7 @@ DEFAULT_NAME = "Template Image"
GET_IMAGE_TIMEOUT = 10
IMAGE_SCHEMA = vol.Schema(
IMAGE_YAML_SCHEMA = vol.Schema(
{
vol.Required(CONF_URL): cv.template,
vol.Optional(CONF_VERIFY_SSL, default=True): bool,
@ -47,14 +48,12 @@ IMAGE_SCHEMA = vol.Schema(
).extend(make_template_entity_common_modern_attributes_schema(DEFAULT_NAME).schema)
IMAGE_CONFIG_SCHEMA = vol.Schema(
IMAGE_CONFIG_ENTRY_SCHEMA = vol.Schema(
{
vol.Optional(CONF_NAME): cv.template,
vol.Required(CONF_URL): cv.template,
vol.Optional(CONF_VERIFY_SSL, default=True): bool,
vol.Optional(CONF_DEVICE_ID): selector.DeviceSelector(),
}
)
).extend(TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA.schema)
async def async_setup_platform(
@ -81,11 +80,12 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Initialize config entry."""
_options = dict(config_entry.options)
_options.pop("template_type")
validated_config = IMAGE_CONFIG_SCHEMA(_options)
async_add_entities(
[StateImageEntity(hass, validated_config, config_entry.entry_id)]
await async_setup_template_entry(
hass,
config_entry,
async_add_entities,
StateImageEntity,
IMAGE_CONFIG_ENTRY_SCHEMA,
)

View File

@ -121,7 +121,7 @@ LEGACY_FIELDS = {
DEFAULT_NAME = "Template Light"
LIGHT_SCHEMA = vol.Schema(
LIGHT_YAML_SCHEMA = vol.Schema(
{
vol.Inclusive(CONF_EFFECT_ACTION, "effect"): cv.SCRIPT_SCHEMA,
vol.Inclusive(CONF_EFFECT_LIST, "effect"): cv.template,
@ -147,7 +147,7 @@ LIGHT_SCHEMA = vol.Schema(
}
).extend(make_template_entity_common_modern_schema(DEFAULT_NAME).schema)
LEGACY_LIGHT_SCHEMA = vol.All(
LIGHT_LEGACY_YAML_SCHEMA = vol.All(
cv.deprecated(CONF_ENTITY_ID),
vol.Schema(
{
@ -186,7 +186,7 @@ PLATFORM_SCHEMA = vol.All(
cv.removed(CONF_WHITE_VALUE_ACTION),
cv.removed(CONF_WHITE_VALUE_TEMPLATE),
LIGHT_PLATFORM_SCHEMA.extend(
{vol.Required(CONF_LIGHTS): cv.schema_with_slug_keys(LEGACY_LIGHT_SCHEMA)}
{vol.Required(CONF_LIGHTS): cv.schema_with_slug_keys(LIGHT_LEGACY_YAML_SCHEMA)}
),
)

View File

@ -54,7 +54,7 @@ LEGACY_FIELDS = {
CONF_VALUE_TEMPLATE: CONF_STATE,
}
LOCK_SCHEMA = vol.All(
LOCK_YAML_SCHEMA = vol.All(
vol.Schema(
{
vol.Optional(CONF_CODE_FORMAT): cv.template,
@ -68,7 +68,6 @@ LOCK_SCHEMA = vol.All(
).extend(make_template_entity_common_modern_schema(DEFAULT_NAME).schema)
)
PLATFORM_SCHEMA = LOCK_PLATFORM_SCHEMA.extend(
{
vol.Optional(CONF_CODE_FORMAT_TEMPLATE): cv.template,

View File

@ -18,14 +18,13 @@ from homeassistant.components.number import (
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
CONF_DEVICE_ID,
CONF_NAME,
CONF_OPTIMISTIC,
CONF_STATE,
CONF_UNIT_OF_MEASUREMENT,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import config_validation as cv, selector
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity_platform import (
AddConfigEntryEntitiesCallback,
AddEntitiesCallback,
@ -34,8 +33,16 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from . import TriggerUpdateCoordinator
from .const import CONF_MAX, CONF_MIN, CONF_STEP, DOMAIN
from .helpers import async_setup_template_platform
from .template_entity import TemplateEntity, make_template_entity_common_modern_schema
from .helpers import (
async_setup_template_entry,
async_setup_template_platform,
async_setup_template_preview,
)
from .template_entity import (
TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA,
TemplateEntity,
make_template_entity_common_modern_schema,
)
from .trigger_entity import TriggerEntity
_LOGGER = logging.getLogger(__name__)
@ -45,28 +52,29 @@ CONF_SET_VALUE = "set_value"
DEFAULT_NAME = "Template Number"
DEFAULT_OPTIMISTIC = False
NUMBER_SCHEMA = vol.Schema(
NUMBER_COMMON_SCHEMA = vol.Schema(
{
vol.Required(CONF_STATE): cv.template,
vol.Required(CONF_SET_VALUE): cv.SCRIPT_SCHEMA,
vol.Required(CONF_STEP): cv.template,
vol.Optional(CONF_MIN, default=DEFAULT_MIN_VALUE): cv.template,
vol.Optional(CONF_MAX, default=DEFAULT_MAX_VALUE): cv.template,
vol.Optional(CONF_MIN, default=DEFAULT_MIN_VALUE): cv.template,
vol.Required(CONF_SET_VALUE): cv.SCRIPT_SCHEMA,
vol.Required(CONF_STATE): cv.template,
vol.Required(CONF_STEP): cv.template,
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
}
)
NUMBER_YAML_SCHEMA = (
vol.Schema(
{
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
}
).extend(make_template_entity_common_modern_schema(DEFAULT_NAME).schema)
NUMBER_CONFIG_SCHEMA = vol.Schema(
{
vol.Required(CONF_NAME): cv.template,
vol.Required(CONF_STATE): cv.template,
vol.Required(CONF_STEP): cv.template,
vol.Required(CONF_SET_VALUE): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_MIN): cv.template,
vol.Optional(CONF_MAX): cv.template,
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
vol.Optional(CONF_DEVICE_ID): selector.DeviceSelector(),
}
)
.extend(make_template_entity_common_modern_schema(DEFAULT_NAME).schema)
.extend(NUMBER_COMMON_SCHEMA.schema)
)
NUMBER_CONFIG_ENTRY_SCHEMA = NUMBER_COMMON_SCHEMA.extend(
TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA.schema
)
@ -94,11 +102,12 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Initialize config entry."""
_options = dict(config_entry.options)
_options.pop("template_type")
validated_config = NUMBER_CONFIG_SCHEMA(_options)
async_add_entities(
[StateNumberEntity(hass, validated_config, config_entry.entry_id)]
await async_setup_template_entry(
hass,
config_entry,
async_add_entities,
StateNumberEntity,
NUMBER_CONFIG_ENTRY_SCHEMA,
)
@ -107,8 +116,9 @@ def async_create_preview_number(
hass: HomeAssistant, name: str, config: dict[str, Any]
) -> StateNumberEntity:
"""Create a preview number."""
validated_config = NUMBER_CONFIG_SCHEMA(config | {CONF_NAME: name})
return StateNumberEntity(hass, validated_config, None)
return async_setup_template_preview(
hass, name, config, StateNumberEntity, NUMBER_CONFIG_ENTRY_SCHEMA
)
class StateNumberEntity(TemplateEntity, NumberEntity):

View File

@ -15,9 +15,9 @@ from homeassistant.components.select import (
SelectEntity,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_DEVICE_ID, CONF_NAME, CONF_OPTIMISTIC, CONF_STATE
from homeassistant.const import CONF_NAME, CONF_OPTIMISTIC, CONF_STATE
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import config_validation as cv, selector
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity_platform import (
AddConfigEntryEntitiesCallback,
AddEntitiesCallback,
@ -27,8 +27,16 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from . import TriggerUpdateCoordinator
from .const import DOMAIN
from .entity import AbstractTemplateEntity
from .helpers import async_setup_template_platform
from .template_entity import TemplateEntity, make_template_entity_common_modern_schema
from .helpers import (
async_setup_template_entry,
async_setup_template_platform,
async_setup_template_preview,
)
from .template_entity import (
TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA,
TemplateEntity,
make_template_entity_common_modern_schema,
)
from .trigger_entity import TriggerEntity
_LOGGER = logging.getLogger(__name__)
@ -39,24 +47,26 @@ CONF_SELECT_OPTION = "select_option"
DEFAULT_NAME = "Template Select"
DEFAULT_OPTIMISTIC = False
SELECT_SCHEMA = vol.Schema(
SELECT_COMMON_SCHEMA = vol.Schema(
{
vol.Optional(ATTR_OPTIONS): cv.template,
vol.Optional(CONF_SELECT_OPTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_STATE): cv.template,
vol.Required(CONF_SELECT_OPTION): cv.SCRIPT_SCHEMA,
vol.Required(ATTR_OPTIONS): cv.template,
}
)
SELECT_YAML_SCHEMA = (
vol.Schema(
{
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
}
).extend(make_template_entity_common_modern_schema(DEFAULT_NAME).schema)
)
.extend(make_template_entity_common_modern_schema(DEFAULT_NAME).schema)
.extend(SELECT_COMMON_SCHEMA.schema)
)
SELECT_CONFIG_SCHEMA = vol.Schema(
{
vol.Required(CONF_NAME): cv.template,
vol.Required(CONF_STATE): cv.template,
vol.Required(CONF_OPTIONS): cv.template,
vol.Optional(CONF_SELECT_OPTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_DEVICE_ID): selector.DeviceSelector(),
}
SELECT_CONFIG_ENTRY_SCHEMA = SELECT_COMMON_SCHEMA.extend(
TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA.schema
)
@ -84,10 +94,13 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Initialize config entry."""
_options = dict(config_entry.options)
_options.pop("template_type")
validated_config = SELECT_CONFIG_SCHEMA(_options)
async_add_entities([TemplateSelect(hass, validated_config, config_entry.entry_id)])
await async_setup_template_entry(
hass,
config_entry,
async_add_entities,
TemplateSelect,
SELECT_CONFIG_ENTRY_SCHEMA,
)
@callback
@ -95,8 +108,9 @@ def async_create_preview_select(
hass: HomeAssistant, name: str, config: dict[str, Any]
) -> TemplateSelect:
"""Create a preview select."""
validated_config = SELECT_CONFIG_SCHEMA(config | {CONF_NAME: name})
return TemplateSelect(hass, validated_config, None)
return async_setup_template_preview(
hass, name, config, TemplateSelect, SELECT_CONFIG_ENTRY_SCHEMA
)
class AbstractTemplateSelect(AbstractTemplateEntity, SelectEntity):

View File

@ -15,6 +15,7 @@ from homeassistant.components.sensor import (
DOMAIN as SENSOR_DOMAIN,
ENTITY_ID_FORMAT,
PLATFORM_SCHEMA as SENSOR_PLATFORM_SCHEMA,
STATE_CLASSES_SCHEMA,
RestoreSensor,
SensorDeviceClass,
SensorEntity,
@ -25,7 +26,6 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_ENTITY_ID,
CONF_DEVICE_CLASS,
CONF_DEVICE_ID,
CONF_ENTITY_PICTURE_TEMPLATE,
CONF_FRIENDLY_NAME,
CONF_FRIENDLY_NAME_TEMPLATE,
@ -43,19 +43,26 @@ from homeassistant.const import (
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import TemplateError
from homeassistant.helpers import config_validation as cv, selector, template
from homeassistant.helpers import config_validation as cv, template
from homeassistant.helpers.entity_platform import (
AddConfigEntryEntitiesCallback,
AddEntitiesCallback,
)
from homeassistant.helpers.trigger_template_entity import TEMPLATE_SENSOR_BASE_SCHEMA
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.util import dt as dt_util
from . import TriggerUpdateCoordinator
from .const import CONF_ATTRIBUTE_TEMPLATES, CONF_AVAILABILITY_TEMPLATE
from .helpers import async_setup_template_platform
from .template_entity import TEMPLATE_ENTITY_COMMON_SCHEMA, TemplateEntity
from .helpers import (
async_setup_template_entry,
async_setup_template_platform,
async_setup_template_preview,
)
from .template_entity import (
TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA,
TEMPLATE_ENTITY_COMMON_SCHEMA,
TemplateEntity,
)
from .trigger_entity import TriggerEntity
LEGACY_FIELDS = {
@ -77,29 +84,31 @@ def validate_last_reset(val):
return val
SENSOR_SCHEMA = vol.All(
vol.Schema(
SENSOR_COMMON_SCHEMA = vol.Schema(
{
vol.Required(CONF_STATE): cv.template,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_STATE_CLASS): STATE_CLASSES_SCHEMA,
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
}
)
SENSOR_YAML_SCHEMA = vol.All(
vol.Schema(
{
vol.Optional(ATTR_LAST_RESET): cv.template,
}
)
.extend(TEMPLATE_SENSOR_BASE_SCHEMA.schema)
.extend(SENSOR_COMMON_SCHEMA.schema)
.extend(TEMPLATE_ENTITY_COMMON_SCHEMA.schema),
validate_last_reset,
)
SENSOR_CONFIG_SCHEMA = vol.All(
vol.Schema(
{
vol.Required(CONF_STATE): cv.template,
vol.Optional(CONF_DEVICE_ID): selector.DeviceSelector(),
}
).extend(TEMPLATE_SENSOR_BASE_SCHEMA.schema),
SENSOR_CONFIG_ENTRY_SCHEMA = SENSOR_COMMON_SCHEMA.extend(
TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA.schema
)
LEGACY_SENSOR_SCHEMA = vol.All(
SENSOR_LEGACY_YAML_SCHEMA = vol.All(
cv.deprecated(ATTR_ENTITY_ID),
vol.Schema(
{
@ -141,7 +150,9 @@ PLATFORM_SCHEMA = vol.All(
{
vol.Optional(CONF_TRIGGER): cv.match_all, # to raise custom warning
vol.Optional(CONF_TRIGGERS): cv.match_all, # to raise custom warning
vol.Required(CONF_SENSORS): cv.schema_with_slug_keys(LEGACY_SENSOR_SCHEMA),
vol.Required(CONF_SENSORS): cv.schema_with_slug_keys(
SENSOR_LEGACY_YAML_SCHEMA
),
}
),
extra_validation_checks,
@ -176,11 +187,12 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Initialize config entry."""
_options = dict(config_entry.options)
_options.pop("template_type")
validated_config = SENSOR_CONFIG_SCHEMA(_options)
async_add_entities(
[StateSensorEntity(hass, validated_config, config_entry.entry_id)]
await async_setup_template_entry(
hass,
config_entry,
async_add_entities,
StateSensorEntity,
SENSOR_CONFIG_ENTRY_SCHEMA,
)
@ -189,8 +201,9 @@ def async_create_preview_sensor(
hass: HomeAssistant, name: str, config: dict[str, Any]
) -> StateSensorEntity:
"""Create a preview sensor."""
validated_config = SENSOR_CONFIG_SCHEMA(config | {CONF_NAME: name})
return StateSensorEntity(hass, validated_config, None)
return async_setup_template_preview(
hass, name, config, StateSensorEntity, SENSOR_CONFIG_ENTRY_SCHEMA
)
class StateSensorEntity(TemplateEntity, SensorEntity):

View File

@ -16,7 +16,6 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_FRIENDLY_NAME,
CONF_DEVICE_ID,
CONF_NAME,
CONF_STATE,
CONF_SWITCHES,
@ -29,7 +28,7 @@ from homeassistant.const import (
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import TemplateError
from homeassistant.helpers import config_validation as cv, selector, template
from homeassistant.helpers import config_validation as cv, template
from homeassistant.helpers.entity_platform import (
AddConfigEntryEntitiesCallback,
AddEntitiesCallback,
@ -39,8 +38,13 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from . import TriggerUpdateCoordinator
from .const import CONF_TURN_OFF, CONF_TURN_ON, DOMAIN
from .helpers import async_setup_template_platform
from .helpers import (
async_setup_template_entry,
async_setup_template_platform,
async_setup_template_preview,
)
from .template_entity import (
TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA,
TEMPLATE_ENTITY_COMMON_SCHEMA_LEGACY,
TemplateEntity,
make_template_entity_common_modern_schema,
@ -55,16 +59,19 @@ LEGACY_FIELDS = {
DEFAULT_NAME = "Template Switch"
SWITCH_SCHEMA = vol.Schema(
SWITCH_COMMON_SCHEMA = vol.Schema(
{
vol.Optional(CONF_STATE): cv.template,
vol.Required(CONF_TURN_ON): cv.SCRIPT_SCHEMA,
vol.Required(CONF_TURN_OFF): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_TURN_ON): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_TURN_OFF): cv.SCRIPT_SCHEMA,
}
).extend(make_template_entity_common_modern_schema(DEFAULT_NAME).schema)
)
LEGACY_SWITCH_SCHEMA = vol.All(
SWITCH_YAML_SCHEMA = SWITCH_COMMON_SCHEMA.extend(
make_template_entity_common_modern_schema(DEFAULT_NAME).schema
)
SWITCH_LEGACY_YAML_SCHEMA = vol.All(
cv.deprecated(ATTR_ENTITY_ID),
vol.Schema(
{
@ -79,17 +86,11 @@ LEGACY_SWITCH_SCHEMA = vol.All(
)
PLATFORM_SCHEMA = SWITCH_PLATFORM_SCHEMA.extend(
{vol.Required(CONF_SWITCHES): cv.schema_with_slug_keys(LEGACY_SWITCH_SCHEMA)}
{vol.Required(CONF_SWITCHES): cv.schema_with_slug_keys(SWITCH_LEGACY_YAML_SCHEMA)}
)
SWITCH_CONFIG_SCHEMA = vol.Schema(
{
vol.Required(CONF_NAME): cv.template,
vol.Optional(CONF_STATE): cv.template,
vol.Optional(CONF_TURN_ON): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_TURN_OFF): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_DEVICE_ID): selector.DeviceSelector(),
}
SWITCH_CONFIG_ENTRY_SCHEMA = SWITCH_COMMON_SCHEMA.extend(
TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA.schema
)
@ -129,12 +130,13 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Initialize config entry."""
_options = dict(config_entry.options)
_options.pop("template_type")
_options = rewrite_options_to_modern_conf(_options)
validated_config = SWITCH_CONFIG_SCHEMA(_options)
async_add_entities(
[StateSwitchEntity(hass, validated_config, config_entry.entry_id)]
await async_setup_template_entry(
hass,
config_entry,
async_add_entities,
StateSwitchEntity,
SWITCH_CONFIG_ENTRY_SCHEMA,
True,
)
@ -143,9 +145,14 @@ def async_create_preview_switch(
hass: HomeAssistant, name: str, config: dict[str, Any]
) -> StateSwitchEntity:
"""Create a preview switch."""
updated_config = rewrite_options_to_modern_conf(config)
validated_config = SWITCH_CONFIG_SCHEMA(updated_config | {CONF_NAME: name})
return StateSwitchEntity(hass, validated_config, None)
return async_setup_template_preview(
hass,
name,
config,
StateSwitchEntity,
SWITCH_CONFIG_ENTRY_SCHEMA,
True,
)
class StateSwitchEntity(TemplateEntity, SwitchEntity, RestoreEntity):

View File

@ -12,6 +12,7 @@ import voluptuous as vol
from homeassistant.components.blueprint import CONF_USE_BLUEPRINT
from homeassistant.const import (
CONF_DEVICE_ID,
CONF_ENTITY_PICTURE_TEMPLATE,
CONF_ICON,
CONF_ICON_TEMPLATE,
@ -30,7 +31,7 @@ from homeassistant.core import (
validate_state,
)
from homeassistant.exceptions import TemplateError
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers import config_validation as cv, selector
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.event import (
TrackTemplate,
@ -46,7 +47,6 @@ from homeassistant.helpers.template import (
result_as_boolean,
)
from homeassistant.helpers.trigger_template_entity import (
TEMPLATE_ENTITY_BASE_SCHEMA,
make_template_entity_base_schema,
)
from homeassistant.helpers.typing import ConfigType
@ -57,6 +57,7 @@ from .const import (
CONF_AVAILABILITY,
CONF_AVAILABILITY_TEMPLATE,
CONF_PICTURE,
TEMPLATE_ENTITY_BASE_SCHEMA,
)
from .entity import AbstractTemplateEntity
@ -91,6 +92,13 @@ TEMPLATE_ENTITY_COMMON_SCHEMA = (
.extend(TEMPLATE_ENTITY_ATTRIBUTES_SCHEMA.schema)
)
TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA = vol.Schema(
{
vol.Required(CONF_NAME): cv.template,
vol.Optional(CONF_DEVICE_ID): selector.DeviceSelector(),
}
).extend(TEMPLATE_ENTITY_AVAILABILITY_SCHEMA.schema)
def make_template_entity_common_modern_schema(
default_name: str,

View File

@ -76,7 +76,7 @@ LEGACY_FIELDS = {
CONF_VALUE_TEMPLATE: CONF_STATE,
}
VACUUM_SCHEMA = vol.All(
VACUUM_YAML_SCHEMA = vol.All(
vol.Schema(
{
vol.Optional(CONF_BATTERY_LEVEL): cv.template,
@ -94,7 +94,7 @@ VACUUM_SCHEMA = vol.All(
).extend(make_template_entity_common_modern_attributes_schema(DEFAULT_NAME).schema)
)
LEGACY_VACUUM_SCHEMA = vol.All(
VACUUM_LEGACY_YAML_SCHEMA = vol.All(
cv.deprecated(CONF_ENTITY_ID),
vol.Schema(
{
@ -119,7 +119,7 @@ LEGACY_VACUUM_SCHEMA = vol.All(
)
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend(
{vol.Required(CONF_VACUUMS): cv.schema_with_slug_keys(LEGACY_VACUUM_SCHEMA)}
{vol.Required(CONF_VACUUMS): cv.schema_with_slug_keys(VACUUM_LEGACY_YAML_SCHEMA)}
)

View File

@ -31,7 +31,12 @@ from homeassistant.components.weather import (
WeatherEntity,
WeatherEntityFeature,
)
from homeassistant.const import CONF_TEMPERATURE_UNIT, STATE_UNAVAILABLE, STATE_UNKNOWN
from homeassistant.const import (
CONF_NAME,
CONF_TEMPERATURE_UNIT,
STATE_UNAVAILABLE,
STATE_UNKNOWN,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import TemplateError
from homeassistant.helpers import config_validation as cv, template
@ -100,7 +105,7 @@ CONF_APPARENT_TEMPERATURE_TEMPLATE = "apparent_temperature_template"
DEFAULT_NAME = "Template Weather"
WEATHER_SCHEMA = vol.Schema(
WEATHER_YAML_SCHEMA = vol.Schema(
{
vol.Optional(CONF_APPARENT_TEMPERATURE_TEMPLATE): cv.template,
vol.Optional(CONF_ATTRIBUTION_TEMPLATE): cv.template,
@ -126,7 +131,32 @@ WEATHER_SCHEMA = vol.Schema(
}
).extend(make_template_entity_common_modern_schema(DEFAULT_NAME).schema)
PLATFORM_SCHEMA = WEATHER_PLATFORM_SCHEMA.extend(WEATHER_SCHEMA.schema)
PLATFORM_SCHEMA = vol.Schema(
{
vol.Optional(CONF_APPARENT_TEMPERATURE_TEMPLATE): cv.template,
vol.Optional(CONF_ATTRIBUTION_TEMPLATE): cv.template,
vol.Optional(CONF_CLOUD_COVERAGE_TEMPLATE): cv.template,
vol.Required(CONF_CONDITION_TEMPLATE): cv.template,
vol.Optional(CONF_DEW_POINT_TEMPLATE): cv.template,
vol.Required(CONF_HUMIDITY_TEMPLATE): cv.template,
vol.Optional(CONF_FORECAST_DAILY_TEMPLATE): cv.template,
vol.Optional(CONF_FORECAST_HOURLY_TEMPLATE): cv.template,
vol.Optional(CONF_FORECAST_TWICE_DAILY_TEMPLATE): cv.template,
vol.Optional(CONF_OZONE_TEMPLATE): cv.template,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.template,
vol.Optional(CONF_PRECIPITATION_UNIT): vol.In(DistanceConverter.VALID_UNITS),
vol.Optional(CONF_PRESSURE_TEMPLATE): cv.template,
vol.Optional(CONF_PRESSURE_UNIT): vol.In(PressureConverter.VALID_UNITS),
vol.Required(CONF_TEMPERATURE_TEMPLATE): cv.template,
vol.Optional(CONF_TEMPERATURE_UNIT): vol.In(TemperatureConverter.VALID_UNITS),
vol.Optional(CONF_VISIBILITY_TEMPLATE): cv.template,
vol.Optional(CONF_VISIBILITY_UNIT): vol.In(DistanceConverter.VALID_UNITS),
vol.Optional(CONF_WIND_BEARING_TEMPLATE): cv.template,
vol.Optional(CONF_WIND_GUST_SPEED_TEMPLATE): cv.template,
vol.Optional(CONF_WIND_SPEED_TEMPLATE): cv.template,
vol.Optional(CONF_WIND_SPEED_UNIT): vol.In(SpeedConverter.VALID_UNITS),
}
).extend(WEATHER_PLATFORM_SCHEMA.schema)
async def async_setup_platform(