mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 23:27:37 +00:00
Consolidate template integration's config schemas (#149018)
This commit is contained in:
parent
3877a6211a
commit
33cc257e75
@ -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,27 +95,28 @@ LEGACY_FIELDS = {
|
||||
|
||||
DEFAULT_NAME = "Template Alarm Control Panel"
|
||||
|
||||
ALARM_CONTROL_PANEL_SCHEMA = vol.All(
|
||||
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_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_COMMON_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_DISARM_ACTION): cv.SCRIPT_SCHEMA,
|
||||
vol.Optional(CONF_STATE): cv.template,
|
||||
vol.Optional(CONF_TRIGGER_ACTION): cv.SCRIPT_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(
|
||||
hass,
|
||||
validated_config,
|
||||
config_entry.entry_id,
|
||||
)
|
||||
]
|
||||
await async_setup_template_entry(
|
||||
hass,
|
||||
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(
|
||||
|
@ -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):
|
||||
|
@ -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,
|
||||
)
|
||||
|
||||
|
||||
|
@ -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]
|
||||
),
|
||||
},
|
||||
),
|
||||
|
@ -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"
|
||||
|
@ -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)}
|
||||
)
|
||||
|
||||
|
||||
|
@ -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)}
|
||||
)
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
)
|
||||
|
||||
|
||||
|
@ -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)}
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,30 +52,31 @@ 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_UNIT_OF_MEASUREMENT): cv.string,
|
||||
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.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.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(),
|
||||
}
|
||||
)
|
||||
|
||||
NUMBER_YAML_SCHEMA = (
|
||||
vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
|
||||
}
|
||||
)
|
||||
.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
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_platform(
|
||||
hass: HomeAssistant,
|
||||
@ -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):
|
||||
|
@ -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,26 +47,28 @@ CONF_SELECT_OPTION = "select_option"
|
||||
DEFAULT_NAME = "Template Select"
|
||||
DEFAULT_OPTIMISTIC = False
|
||||
|
||||
SELECT_SCHEMA = vol.Schema(
|
||||
SELECT_COMMON_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_STATE): cv.template,
|
||||
vol.Required(CONF_SELECT_OPTION): cv.SCRIPT_SCHEMA,
|
||||
vol.Required(ATTR_OPTIONS): cv.template,
|
||||
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
|
||||
}
|
||||
).extend(make_template_entity_common_modern_schema(DEFAULT_NAME).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(ATTR_OPTIONS): cv.template,
|
||||
vol.Optional(CONF_SELECT_OPTION): cv.SCRIPT_SCHEMA,
|
||||
vol.Optional(CONF_DEVICE_ID): selector.DeviceSelector(),
|
||||
vol.Optional(CONF_STATE): 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(SELECT_COMMON_SCHEMA.schema)
|
||||
)
|
||||
|
||||
SELECT_CONFIG_ENTRY_SCHEMA = SELECT_COMMON_SCHEMA.extend(
|
||||
TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA.schema
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_platform(
|
||||
hass: HomeAssistant,
|
||||
@ -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):
|
||||
|
@ -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(
|
||||
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.Required(CONF_STATE): cv.template,
|
||||
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):
|
||||
|
@ -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):
|
||||
|
@ -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,
|
||||
|
@ -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)}
|
||||
)
|
||||
|
||||
|
||||
|
@ -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(
|
||||
|
Loading…
x
Reference in New Issue
Block a user