mirror of
https://github.com/home-assistant/core.git
synced 2025-07-29 16:17:20 +00:00
Refactor async_setup_platform for template platforms (#147379)
This commit is contained in:
parent
a81e83cb28
commit
816977dd75
@ -45,12 +45,8 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
|||||||
from .const import CONF_OBJECT_ID, DOMAIN
|
from .const import CONF_OBJECT_ID, DOMAIN
|
||||||
from .coordinator import TriggerUpdateCoordinator
|
from .coordinator import TriggerUpdateCoordinator
|
||||||
from .entity import AbstractTemplateEntity
|
from .entity import AbstractTemplateEntity
|
||||||
from .template_entity import (
|
from .helpers import async_setup_template_platform
|
||||||
LEGACY_FIELDS as TEMPLATE_ENTITY_LEGACY_FIELDS,
|
from .template_entity import TemplateEntity, make_template_entity_common_modern_schema
|
||||||
TemplateEntity,
|
|
||||||
make_template_entity_common_modern_schema,
|
|
||||||
rewrite_common_legacy_to_modern_conf,
|
|
||||||
)
|
|
||||||
from .trigger_entity import TriggerEntity
|
from .trigger_entity import TriggerEntity
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -88,7 +84,7 @@ class TemplateCodeFormat(Enum):
|
|||||||
text = CodeFormat.TEXT
|
text = CodeFormat.TEXT
|
||||||
|
|
||||||
|
|
||||||
LEGACY_FIELDS = TEMPLATE_ENTITY_LEGACY_FIELDS | {
|
LEGACY_FIELDS = {
|
||||||
CONF_VALUE_TEMPLATE: CONF_STATE,
|
CONF_VALUE_TEMPLATE: CONF_STATE,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,54 +157,6 @@ ALARM_CONTROL_PANEL_CONFIG_SCHEMA = vol.Schema(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def rewrite_legacy_to_modern_conf(
|
|
||||||
hass: HomeAssistant, config: dict[str, dict]
|
|
||||||
) -> list[dict]:
|
|
||||||
"""Rewrite legacy alarm control panel configuration definitions to modern ones."""
|
|
||||||
alarm_control_panels = []
|
|
||||||
|
|
||||||
for object_id, entity_conf in config.items():
|
|
||||||
entity_conf = {**entity_conf, CONF_OBJECT_ID: object_id}
|
|
||||||
|
|
||||||
entity_conf = rewrite_common_legacy_to_modern_conf(
|
|
||||||
hass, entity_conf, LEGACY_FIELDS
|
|
||||||
)
|
|
||||||
|
|
||||||
if CONF_NAME not in entity_conf:
|
|
||||||
entity_conf[CONF_NAME] = template.Template(object_id, hass)
|
|
||||||
|
|
||||||
alarm_control_panels.append(entity_conf)
|
|
||||||
|
|
||||||
return alarm_control_panels
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def _async_create_template_tracking_entities(
|
|
||||||
async_add_entities: AddEntitiesCallback,
|
|
||||||
hass: HomeAssistant,
|
|
||||||
definitions: list[dict],
|
|
||||||
unique_id_prefix: str | None,
|
|
||||||
) -> None:
|
|
||||||
"""Create the template alarm control panels."""
|
|
||||||
alarm_control_panels = []
|
|
||||||
|
|
||||||
for entity_conf in definitions:
|
|
||||||
unique_id = entity_conf.get(CONF_UNIQUE_ID)
|
|
||||||
|
|
||||||
if unique_id and unique_id_prefix:
|
|
||||||
unique_id = f"{unique_id_prefix}-{unique_id}"
|
|
||||||
|
|
||||||
alarm_control_panels.append(
|
|
||||||
AlarmControlPanelTemplate(
|
|
||||||
hass,
|
|
||||||
entity_conf,
|
|
||||||
unique_id,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
async_add_entities(alarm_control_panels)
|
|
||||||
|
|
||||||
|
|
||||||
def rewrite_options_to_modern_conf(option_config: dict[str, dict]) -> dict[str, dict]:
|
def rewrite_options_to_modern_conf(option_config: dict[str, dict]) -> dict[str, dict]:
|
||||||
"""Rewrite option configuration to modern configuration."""
|
"""Rewrite option configuration to modern configuration."""
|
||||||
option_config = {**option_config}
|
option_config = {**option_config}
|
||||||
@ -231,7 +179,7 @@ async def async_setup_entry(
|
|||||||
validated_config = ALARM_CONTROL_PANEL_CONFIG_SCHEMA(_options)
|
validated_config = ALARM_CONTROL_PANEL_CONFIG_SCHEMA(_options)
|
||||||
async_add_entities(
|
async_add_entities(
|
||||||
[
|
[
|
||||||
AlarmControlPanelTemplate(
|
StateAlarmControlPanelEntity(
|
||||||
hass,
|
hass,
|
||||||
validated_config,
|
validated_config,
|
||||||
config_entry.entry_id,
|
config_entry.entry_id,
|
||||||
@ -247,27 +195,16 @@ async def async_setup_platform(
|
|||||||
discovery_info: DiscoveryInfoType | None = None,
|
discovery_info: DiscoveryInfoType | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the Template cover."""
|
"""Set up the Template cover."""
|
||||||
if discovery_info is None:
|
await async_setup_template_platform(
|
||||||
_async_create_template_tracking_entities(
|
|
||||||
async_add_entities,
|
|
||||||
hass,
|
hass,
|
||||||
rewrite_legacy_to_modern_conf(hass, config[CONF_ALARM_CONTROL_PANELS]),
|
ALARM_CONTROL_PANEL_DOMAIN,
|
||||||
None,
|
config,
|
||||||
)
|
StateAlarmControlPanelEntity,
|
||||||
return
|
TriggerAlarmControlPanelEntity,
|
||||||
|
|
||||||
if "coordinator" in discovery_info:
|
|
||||||
async_add_entities(
|
|
||||||
TriggerAlarmControlPanelEntity(hass, discovery_info["coordinator"], config)
|
|
||||||
for config in discovery_info["entities"]
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
_async_create_template_tracking_entities(
|
|
||||||
async_add_entities,
|
async_add_entities,
|
||||||
hass,
|
discovery_info,
|
||||||
discovery_info["entities"],
|
LEGACY_FIELDS,
|
||||||
discovery_info["unique_id"],
|
legacy_key=CONF_ALARM_CONTROL_PANELS,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -414,7 +351,7 @@ class AbstractTemplateAlarmControlPanel(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class AlarmControlPanelTemplate(TemplateEntity, AbstractTemplateAlarmControlPanel):
|
class StateAlarmControlPanelEntity(TemplateEntity, AbstractTemplateAlarmControlPanel):
|
||||||
"""Representation of a templated Alarm Control Panel."""
|
"""Representation of a templated Alarm Control Panel."""
|
||||||
|
|
||||||
_attr_should_poll = False
|
_attr_should_poll = False
|
||||||
|
@ -24,9 +24,7 @@ from homeassistant.const import (
|
|||||||
CONF_DEVICE_CLASS,
|
CONF_DEVICE_CLASS,
|
||||||
CONF_DEVICE_ID,
|
CONF_DEVICE_ID,
|
||||||
CONF_ENTITY_PICTURE_TEMPLATE,
|
CONF_ENTITY_PICTURE_TEMPLATE,
|
||||||
CONF_FRIENDLY_NAME,
|
|
||||||
CONF_FRIENDLY_NAME_TEMPLATE,
|
CONF_FRIENDLY_NAME_TEMPLATE,
|
||||||
CONF_ICON,
|
|
||||||
CONF_ICON_TEMPLATE,
|
CONF_ICON_TEMPLATE,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
CONF_SENSORS,
|
CONF_SENSORS,
|
||||||
@ -53,18 +51,9 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
|||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
|
|
||||||
from . import TriggerUpdateCoordinator
|
from . import TriggerUpdateCoordinator
|
||||||
from .const import (
|
from .const import CONF_AVAILABILITY_TEMPLATE, CONF_OBJECT_ID
|
||||||
CONF_ATTRIBUTES,
|
from .helpers import async_setup_template_platform
|
||||||
CONF_AVAILABILITY,
|
from .template_entity import TEMPLATE_ENTITY_COMMON_SCHEMA, TemplateEntity
|
||||||
CONF_AVAILABILITY_TEMPLATE,
|
|
||||||
CONF_OBJECT_ID,
|
|
||||||
CONF_PICTURE,
|
|
||||||
)
|
|
||||||
from .template_entity import (
|
|
||||||
TEMPLATE_ENTITY_COMMON_SCHEMA,
|
|
||||||
TemplateEntity,
|
|
||||||
rewrite_common_legacy_to_modern_conf,
|
|
||||||
)
|
|
||||||
from .trigger_entity import TriggerEntity
|
from .trigger_entity import TriggerEntity
|
||||||
|
|
||||||
CONF_DELAY_ON = "delay_on"
|
CONF_DELAY_ON = "delay_on"
|
||||||
@ -73,12 +62,7 @@ CONF_AUTO_OFF = "auto_off"
|
|||||||
CONF_ATTRIBUTE_TEMPLATES = "attribute_templates"
|
CONF_ATTRIBUTE_TEMPLATES = "attribute_templates"
|
||||||
|
|
||||||
LEGACY_FIELDS = {
|
LEGACY_FIELDS = {
|
||||||
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_TEMPLATE: CONF_NAME,
|
||||||
CONF_FRIENDLY_NAME: CONF_NAME,
|
|
||||||
CONF_VALUE_TEMPLATE: CONF_STATE,
|
CONF_VALUE_TEMPLATE: CONF_STATE,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,27 +105,6 @@ LEGACY_BINARY_SENSOR_SCHEMA = vol.All(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def rewrite_legacy_to_modern_conf(
|
|
||||||
hass: HomeAssistant, cfg: dict[str, dict]
|
|
||||||
) -> list[dict]:
|
|
||||||
"""Rewrite legacy binary sensor definitions to modern ones."""
|
|
||||||
sensors = []
|
|
||||||
|
|
||||||
for object_id, entity_cfg in cfg.items():
|
|
||||||
entity_cfg = {**entity_cfg, CONF_OBJECT_ID: object_id}
|
|
||||||
|
|
||||||
entity_cfg = rewrite_common_legacy_to_modern_conf(
|
|
||||||
hass, entity_cfg, LEGACY_FIELDS
|
|
||||||
)
|
|
||||||
|
|
||||||
if CONF_NAME not in entity_cfg:
|
|
||||||
entity_cfg[CONF_NAME] = template.Template(object_id, hass)
|
|
||||||
|
|
||||||
sensors.append(entity_cfg)
|
|
||||||
|
|
||||||
return sensors
|
|
||||||
|
|
||||||
|
|
||||||
PLATFORM_SCHEMA = BINARY_SENSOR_PLATFORM_SCHEMA.extend(
|
PLATFORM_SCHEMA = BINARY_SENSOR_PLATFORM_SCHEMA.extend(
|
||||||
{
|
{
|
||||||
vol.Required(CONF_SENSORS): cv.schema_with_slug_keys(
|
vol.Required(CONF_SENSORS): cv.schema_with_slug_keys(
|
||||||
@ -151,33 +114,6 @@ PLATFORM_SCHEMA = BINARY_SENSOR_PLATFORM_SCHEMA.extend(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def _async_create_template_tracking_entities(
|
|
||||||
async_add_entities: AddEntitiesCallback | AddConfigEntryEntitiesCallback,
|
|
||||||
hass: HomeAssistant,
|
|
||||||
definitions: list[dict],
|
|
||||||
unique_id_prefix: str | None,
|
|
||||||
) -> None:
|
|
||||||
"""Create the template binary sensors."""
|
|
||||||
sensors = []
|
|
||||||
|
|
||||||
for entity_conf in definitions:
|
|
||||||
unique_id = entity_conf.get(CONF_UNIQUE_ID)
|
|
||||||
|
|
||||||
if unique_id and unique_id_prefix:
|
|
||||||
unique_id = f"{unique_id_prefix}-{unique_id}"
|
|
||||||
|
|
||||||
sensors.append(
|
|
||||||
BinarySensorTemplate(
|
|
||||||
hass,
|
|
||||||
entity_conf,
|
|
||||||
unique_id,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
async_add_entities(sensors)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(
|
async def async_setup_platform(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
@ -185,27 +121,16 @@ async def async_setup_platform(
|
|||||||
discovery_info: DiscoveryInfoType | None = None,
|
discovery_info: DiscoveryInfoType | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the template binary sensors."""
|
"""Set up the template binary sensors."""
|
||||||
if discovery_info is None:
|
await async_setup_template_platform(
|
||||||
_async_create_template_tracking_entities(
|
|
||||||
async_add_entities,
|
|
||||||
hass,
|
hass,
|
||||||
rewrite_legacy_to_modern_conf(hass, config[CONF_SENSORS]),
|
BINARY_SENSOR_DOMAIN,
|
||||||
None,
|
config,
|
||||||
)
|
StateBinarySensorEntity,
|
||||||
return
|
TriggerBinarySensorEntity,
|
||||||
|
|
||||||
if "coordinator" in discovery_info:
|
|
||||||
async_add_entities(
|
|
||||||
TriggerBinarySensorEntity(hass, discovery_info["coordinator"], config)
|
|
||||||
for config in discovery_info["entities"]
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
_async_create_template_tracking_entities(
|
|
||||||
async_add_entities,
|
async_add_entities,
|
||||||
hass,
|
discovery_info,
|
||||||
discovery_info["entities"],
|
LEGACY_FIELDS,
|
||||||
discovery_info["unique_id"],
|
legacy_key=CONF_SENSORS,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -219,20 +144,20 @@ async def async_setup_entry(
|
|||||||
_options.pop("template_type")
|
_options.pop("template_type")
|
||||||
validated_config = BINARY_SENSOR_CONFIG_SCHEMA(_options)
|
validated_config = BINARY_SENSOR_CONFIG_SCHEMA(_options)
|
||||||
async_add_entities(
|
async_add_entities(
|
||||||
[BinarySensorTemplate(hass, validated_config, config_entry.entry_id)]
|
[StateBinarySensorEntity(hass, validated_config, config_entry.entry_id)]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def async_create_preview_binary_sensor(
|
def async_create_preview_binary_sensor(
|
||||||
hass: HomeAssistant, name: str, config: dict[str, Any]
|
hass: HomeAssistant, name: str, config: dict[str, Any]
|
||||||
) -> BinarySensorTemplate:
|
) -> StateBinarySensorEntity:
|
||||||
"""Create a preview sensor."""
|
"""Create a preview sensor."""
|
||||||
validated_config = BINARY_SENSOR_CONFIG_SCHEMA(config | {CONF_NAME: name})
|
validated_config = BINARY_SENSOR_CONFIG_SCHEMA(config | {CONF_NAME: name})
|
||||||
return BinarySensorTemplate(hass, validated_config, None)
|
return StateBinarySensorEntity(hass, validated_config, None)
|
||||||
|
|
||||||
|
|
||||||
class BinarySensorTemplate(TemplateEntity, BinarySensorEntity, RestoreEntity):
|
class StateBinarySensorEntity(TemplateEntity, BinarySensorEntity, RestoreEntity):
|
||||||
"""A virtual binary sensor that triggers from another sensor."""
|
"""A virtual binary sensor that triggers from another sensor."""
|
||||||
|
|
||||||
_attr_should_poll = False
|
_attr_should_poll = False
|
||||||
|
@ -3,20 +3,17 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.button import DEVICE_CLASSES_SCHEMA, ButtonEntity
|
from homeassistant.components.button import (
|
||||||
from homeassistant.config_entries import ConfigEntry
|
DEVICE_CLASSES_SCHEMA,
|
||||||
from homeassistant.const import (
|
DOMAIN as BUTTON_DOMAIN,
|
||||||
CONF_DEVICE_CLASS,
|
ButtonEntity,
|
||||||
CONF_DEVICE_ID,
|
|
||||||
CONF_NAME,
|
|
||||||
CONF_UNIQUE_ID,
|
|
||||||
)
|
)
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import CONF_DEVICE_CLASS, CONF_DEVICE_ID, CONF_NAME
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import PlatformNotReady
|
|
||||||
from homeassistant.helpers import config_validation as cv, selector
|
from homeassistant.helpers import config_validation as cv, selector
|
||||||
from homeassistant.helpers.device import async_device_info_to_link_from_device_id
|
from homeassistant.helpers.device import async_device_info_to_link_from_device_id
|
||||||
from homeassistant.helpers.entity_platform import (
|
from homeassistant.helpers.entity_platform import (
|
||||||
@ -26,6 +23,7 @@ from homeassistant.helpers.entity_platform import (
|
|||||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
|
|
||||||
from .const import CONF_PRESS, DOMAIN
|
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 .template_entity import TemplateEntity, make_template_entity_common_modern_schema
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -50,19 +48,6 @@ CONFIG_BUTTON_SCHEMA = vol.Schema(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def _async_create_entities(
|
|
||||||
hass: HomeAssistant, definitions: list[dict[str, Any]], unique_id_prefix: str | None
|
|
||||||
) -> list[TemplateButtonEntity]:
|
|
||||||
"""Create the Template button."""
|
|
||||||
entities = []
|
|
||||||
for definition in definitions:
|
|
||||||
unique_id = definition.get(CONF_UNIQUE_ID)
|
|
||||||
if unique_id and unique_id_prefix:
|
|
||||||
unique_id = f"{unique_id_prefix}-{unique_id}"
|
|
||||||
entities.append(TemplateButtonEntity(hass, definition, unique_id))
|
|
||||||
return entities
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(
|
async def async_setup_platform(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
@ -70,15 +55,14 @@ async def async_setup_platform(
|
|||||||
discovery_info: DiscoveryInfoType | None = None,
|
discovery_info: DiscoveryInfoType | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the template button."""
|
"""Set up the template button."""
|
||||||
if not discovery_info or "coordinator" in discovery_info:
|
await async_setup_template_platform(
|
||||||
raise PlatformNotReady(
|
hass,
|
||||||
"The template button platform doesn't support trigger entities"
|
BUTTON_DOMAIN,
|
||||||
)
|
config,
|
||||||
|
StateButtonEntity,
|
||||||
async_add_entities(
|
None,
|
||||||
await _async_create_entities(
|
async_add_entities,
|
||||||
hass, discovery_info["entities"], discovery_info["unique_id"]
|
discovery_info,
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -92,11 +76,11 @@ async def async_setup_entry(
|
|||||||
_options.pop("template_type")
|
_options.pop("template_type")
|
||||||
validated_config = CONFIG_BUTTON_SCHEMA(_options)
|
validated_config = CONFIG_BUTTON_SCHEMA(_options)
|
||||||
async_add_entities(
|
async_add_entities(
|
||||||
[TemplateButtonEntity(hass, validated_config, config_entry.entry_id)]
|
[StateButtonEntity(hass, validated_config, config_entry.entry_id)]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TemplateButtonEntity(TemplateEntity, ButtonEntity):
|
class StateButtonEntity(TemplateEntity, ButtonEntity):
|
||||||
"""Representation of a template button."""
|
"""Representation of a template button."""
|
||||||
|
|
||||||
_attr_should_poll = False
|
_attr_should_poll = False
|
||||||
|
@ -65,7 +65,7 @@ from . import (
|
|||||||
weather as weather_platform,
|
weather as weather_platform,
|
||||||
)
|
)
|
||||||
from .const import DOMAIN, PLATFORMS, TemplateConfig
|
from .const import DOMAIN, PLATFORMS, TemplateConfig
|
||||||
from .helpers import async_get_blueprints
|
from .helpers import async_get_blueprints, rewrite_legacy_to_modern_configs
|
||||||
|
|
||||||
PACKAGE_MERGE_HINT = "list"
|
PACKAGE_MERGE_HINT = "list"
|
||||||
|
|
||||||
@ -249,16 +249,16 @@ async def async_validate_config(hass: HomeAssistant, config: ConfigType) -> Conf
|
|||||||
|
|
||||||
legacy_warn_printed = False
|
legacy_warn_printed = False
|
||||||
|
|
||||||
for old_key, new_key, transform in (
|
for old_key, new_key, legacy_fields in (
|
||||||
(
|
(
|
||||||
CONF_SENSORS,
|
CONF_SENSORS,
|
||||||
DOMAIN_SENSOR,
|
DOMAIN_SENSOR,
|
||||||
sensor_platform.rewrite_legacy_to_modern_conf,
|
sensor_platform.LEGACY_FIELDS,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
CONF_BINARY_SENSORS,
|
CONF_BINARY_SENSORS,
|
||||||
DOMAIN_BINARY_SENSOR,
|
DOMAIN_BINARY_SENSOR,
|
||||||
binary_sensor_platform.rewrite_legacy_to_modern_conf,
|
binary_sensor_platform.LEGACY_FIELDS,
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
if old_key not in template_config:
|
if old_key not in template_config:
|
||||||
@ -276,7 +276,11 @@ async def async_validate_config(hass: HomeAssistant, config: ConfigType) -> Conf
|
|||||||
definitions = (
|
definitions = (
|
||||||
list(template_config[new_key]) if new_key in template_config else []
|
list(template_config[new_key]) if new_key in template_config else []
|
||||||
)
|
)
|
||||||
definitions.extend(transform(hass, template_config[old_key]))
|
definitions.extend(
|
||||||
|
rewrite_legacy_to_modern_configs(
|
||||||
|
hass, template_config[old_key], legacy_fields
|
||||||
|
)
|
||||||
|
)
|
||||||
template_config = TemplateConfig({**template_config, new_key: definitions})
|
template_config = TemplateConfig({**template_config, new_key: definitions})
|
||||||
|
|
||||||
config_sections.append(template_config)
|
config_sections.append(template_config)
|
||||||
|
@ -39,12 +39,11 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
|||||||
from . import TriggerUpdateCoordinator
|
from . import TriggerUpdateCoordinator
|
||||||
from .const import CONF_OBJECT_ID, DOMAIN
|
from .const import CONF_OBJECT_ID, DOMAIN
|
||||||
from .entity import AbstractTemplateEntity
|
from .entity import AbstractTemplateEntity
|
||||||
|
from .helpers import async_setup_template_platform
|
||||||
from .template_entity import (
|
from .template_entity import (
|
||||||
LEGACY_FIELDS as TEMPLATE_ENTITY_LEGACY_FIELDS,
|
|
||||||
TEMPLATE_ENTITY_COMMON_SCHEMA_LEGACY,
|
TEMPLATE_ENTITY_COMMON_SCHEMA_LEGACY,
|
||||||
TemplateEntity,
|
TemplateEntity,
|
||||||
make_template_entity_common_modern_schema,
|
make_template_entity_common_modern_schema,
|
||||||
rewrite_common_legacy_to_modern_conf,
|
|
||||||
)
|
)
|
||||||
from .trigger_entity import TriggerEntity
|
from .trigger_entity import TriggerEntity
|
||||||
|
|
||||||
@ -85,7 +84,7 @@ TILT_FEATURES = (
|
|||||||
| CoverEntityFeature.SET_TILT_POSITION
|
| CoverEntityFeature.SET_TILT_POSITION
|
||||||
)
|
)
|
||||||
|
|
||||||
LEGACY_FIELDS = TEMPLATE_ENTITY_LEGACY_FIELDS | {
|
LEGACY_FIELDS = {
|
||||||
CONF_VALUE_TEMPLATE: CONF_STATE,
|
CONF_VALUE_TEMPLATE: CONF_STATE,
|
||||||
CONF_POSITION_TEMPLATE: CONF_POSITION,
|
CONF_POSITION_TEMPLATE: CONF_POSITION,
|
||||||
CONF_TILT_TEMPLATE: CONF_TILT,
|
CONF_TILT_TEMPLATE: CONF_TILT,
|
||||||
@ -140,54 +139,6 @@ PLATFORM_SCHEMA = COVER_PLATFORM_SCHEMA.extend(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def rewrite_legacy_to_modern_conf(
|
|
||||||
hass: HomeAssistant, config: dict[str, dict]
|
|
||||||
) -> list[dict]:
|
|
||||||
"""Rewrite legacy switch configuration definitions to modern ones."""
|
|
||||||
covers = []
|
|
||||||
|
|
||||||
for object_id, entity_conf in config.items():
|
|
||||||
entity_conf = {**entity_conf, CONF_OBJECT_ID: object_id}
|
|
||||||
|
|
||||||
entity_conf = rewrite_common_legacy_to_modern_conf(
|
|
||||||
hass, entity_conf, LEGACY_FIELDS
|
|
||||||
)
|
|
||||||
|
|
||||||
if CONF_NAME not in entity_conf:
|
|
||||||
entity_conf[CONF_NAME] = template.Template(object_id, hass)
|
|
||||||
|
|
||||||
covers.append(entity_conf)
|
|
||||||
|
|
||||||
return covers
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def _async_create_template_tracking_entities(
|
|
||||||
async_add_entities: AddEntitiesCallback,
|
|
||||||
hass: HomeAssistant,
|
|
||||||
definitions: list[dict],
|
|
||||||
unique_id_prefix: str | None,
|
|
||||||
) -> None:
|
|
||||||
"""Create the template switches."""
|
|
||||||
covers = []
|
|
||||||
|
|
||||||
for entity_conf in definitions:
|
|
||||||
unique_id = entity_conf.get(CONF_UNIQUE_ID)
|
|
||||||
|
|
||||||
if unique_id and unique_id_prefix:
|
|
||||||
unique_id = f"{unique_id_prefix}-{unique_id}"
|
|
||||||
|
|
||||||
covers.append(
|
|
||||||
CoverTemplate(
|
|
||||||
hass,
|
|
||||||
entity_conf,
|
|
||||||
unique_id,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
async_add_entities(covers)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(
|
async def async_setup_platform(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
@ -195,27 +146,16 @@ async def async_setup_platform(
|
|||||||
discovery_info: DiscoveryInfoType | None = None,
|
discovery_info: DiscoveryInfoType | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the Template cover."""
|
"""Set up the Template cover."""
|
||||||
if discovery_info is None:
|
await async_setup_template_platform(
|
||||||
_async_create_template_tracking_entities(
|
|
||||||
async_add_entities,
|
|
||||||
hass,
|
hass,
|
||||||
rewrite_legacy_to_modern_conf(hass, config[CONF_COVERS]),
|
COVER_DOMAIN,
|
||||||
None,
|
config,
|
||||||
)
|
StateCoverEntity,
|
||||||
return
|
TriggerCoverEntity,
|
||||||
|
|
||||||
if "coordinator" in discovery_info:
|
|
||||||
async_add_entities(
|
|
||||||
TriggerCoverEntity(hass, discovery_info["coordinator"], config)
|
|
||||||
for config in discovery_info["entities"]
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
_async_create_template_tracking_entities(
|
|
||||||
async_add_entities,
|
async_add_entities,
|
||||||
hass,
|
discovery_info,
|
||||||
discovery_info["entities"],
|
LEGACY_FIELDS,
|
||||||
discovery_info["unique_id"],
|
legacy_key=CONF_COVERS,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -445,7 +385,7 @@ class AbstractTemplateCover(AbstractTemplateEntity, CoverEntity):
|
|||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
|
|
||||||
class CoverTemplate(TemplateEntity, AbstractTemplateCover):
|
class StateCoverEntity(TemplateEntity, AbstractTemplateCover):
|
||||||
"""Representation of a Template cover."""
|
"""Representation of a Template cover."""
|
||||||
|
|
||||||
_attr_should_poll = False
|
_attr_should_poll = False
|
||||||
|
@ -41,12 +41,11 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
|||||||
from .const import CONF_OBJECT_ID, DOMAIN
|
from .const import CONF_OBJECT_ID, DOMAIN
|
||||||
from .coordinator import TriggerUpdateCoordinator
|
from .coordinator import TriggerUpdateCoordinator
|
||||||
from .entity import AbstractTemplateEntity
|
from .entity import AbstractTemplateEntity
|
||||||
|
from .helpers import async_setup_template_platform
|
||||||
from .template_entity import (
|
from .template_entity import (
|
||||||
LEGACY_FIELDS as TEMPLATE_ENTITY_LEGACY_FIELDS,
|
|
||||||
TEMPLATE_ENTITY_AVAILABILITY_SCHEMA_LEGACY,
|
TEMPLATE_ENTITY_AVAILABILITY_SCHEMA_LEGACY,
|
||||||
TemplateEntity,
|
TemplateEntity,
|
||||||
make_template_entity_common_modern_schema,
|
make_template_entity_common_modern_schema,
|
||||||
rewrite_common_legacy_to_modern_conf,
|
|
||||||
)
|
)
|
||||||
from .trigger_entity import TriggerEntity
|
from .trigger_entity import TriggerEntity
|
||||||
|
|
||||||
@ -73,7 +72,7 @@ CONF_OSCILLATING = "oscillating"
|
|||||||
CONF_PERCENTAGE = "percentage"
|
CONF_PERCENTAGE = "percentage"
|
||||||
CONF_PRESET_MODE = "preset_mode"
|
CONF_PRESET_MODE = "preset_mode"
|
||||||
|
|
||||||
LEGACY_FIELDS = TEMPLATE_ENTITY_LEGACY_FIELDS | {
|
LEGACY_FIELDS = {
|
||||||
CONF_DIRECTION_TEMPLATE: CONF_DIRECTION,
|
CONF_DIRECTION_TEMPLATE: CONF_DIRECTION,
|
||||||
CONF_OSCILLATING_TEMPLATE: CONF_OSCILLATING,
|
CONF_OSCILLATING_TEMPLATE: CONF_OSCILLATING,
|
||||||
CONF_PERCENTAGE_TEMPLATE: CONF_PERCENTAGE,
|
CONF_PERCENTAGE_TEMPLATE: CONF_PERCENTAGE,
|
||||||
@ -132,54 +131,6 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def rewrite_legacy_to_modern_conf(
|
|
||||||
hass: HomeAssistant, config: dict[str, dict]
|
|
||||||
) -> list[dict]:
|
|
||||||
"""Rewrite legacy fan configuration definitions to modern ones."""
|
|
||||||
fans = []
|
|
||||||
|
|
||||||
for object_id, entity_conf in config.items():
|
|
||||||
entity_conf = {**entity_conf, CONF_OBJECT_ID: object_id}
|
|
||||||
|
|
||||||
entity_conf = rewrite_common_legacy_to_modern_conf(
|
|
||||||
hass, entity_conf, LEGACY_FIELDS
|
|
||||||
)
|
|
||||||
|
|
||||||
if CONF_NAME not in entity_conf:
|
|
||||||
entity_conf[CONF_NAME] = template.Template(object_id, hass)
|
|
||||||
|
|
||||||
fans.append(entity_conf)
|
|
||||||
|
|
||||||
return fans
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def _async_create_template_tracking_entities(
|
|
||||||
async_add_entities: AddEntitiesCallback,
|
|
||||||
hass: HomeAssistant,
|
|
||||||
definitions: list[dict],
|
|
||||||
unique_id_prefix: str | None,
|
|
||||||
) -> None:
|
|
||||||
"""Create the template fans."""
|
|
||||||
fans = []
|
|
||||||
|
|
||||||
for entity_conf in definitions:
|
|
||||||
unique_id = entity_conf.get(CONF_UNIQUE_ID)
|
|
||||||
|
|
||||||
if unique_id and unique_id_prefix:
|
|
||||||
unique_id = f"{unique_id_prefix}-{unique_id}"
|
|
||||||
|
|
||||||
fans.append(
|
|
||||||
TemplateFan(
|
|
||||||
hass,
|
|
||||||
entity_conf,
|
|
||||||
unique_id,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
async_add_entities(fans)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(
|
async def async_setup_platform(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
@ -187,27 +138,16 @@ async def async_setup_platform(
|
|||||||
discovery_info: DiscoveryInfoType | None = None,
|
discovery_info: DiscoveryInfoType | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the template fans."""
|
"""Set up the template fans."""
|
||||||
if discovery_info is None:
|
await async_setup_template_platform(
|
||||||
_async_create_template_tracking_entities(
|
|
||||||
async_add_entities,
|
|
||||||
hass,
|
hass,
|
||||||
rewrite_legacy_to_modern_conf(hass, config[CONF_FANS]),
|
FAN_DOMAIN,
|
||||||
None,
|
config,
|
||||||
)
|
StateFanEntity,
|
||||||
return
|
TriggerFanEntity,
|
||||||
|
|
||||||
if "coordinator" in discovery_info:
|
|
||||||
async_add_entities(
|
|
||||||
TriggerFanEntity(hass, discovery_info["coordinator"], config)
|
|
||||||
for config in discovery_info["entities"]
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
_async_create_template_tracking_entities(
|
|
||||||
async_add_entities,
|
async_add_entities,
|
||||||
hass,
|
discovery_info,
|
||||||
discovery_info["entities"],
|
LEGACY_FIELDS,
|
||||||
discovery_info["unique_id"],
|
legacy_key=CONF_FANS,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -484,7 +424,7 @@ class AbstractTemplateFan(AbstractTemplateEntity, FanEntity):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TemplateFan(TemplateEntity, AbstractTemplateFan):
|
class StateFanEntity(TemplateEntity, AbstractTemplateFan):
|
||||||
"""A template fan component."""
|
"""A template fan component."""
|
||||||
|
|
||||||
_attr_should_poll = False
|
_attr_should_poll = False
|
||||||
|
@ -1,19 +1,60 @@
|
|||||||
"""Helpers for template integration."""
|
"""Helpers for template integration."""
|
||||||
|
|
||||||
|
from collections.abc import Callable
|
||||||
|
import itertools
|
||||||
import logging
|
import logging
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from homeassistant.components import blueprint
|
from homeassistant.components import blueprint
|
||||||
from homeassistant.const import SERVICE_RELOAD
|
from homeassistant.const import (
|
||||||
|
CONF_ENTITY_PICTURE_TEMPLATE,
|
||||||
|
CONF_FRIENDLY_NAME,
|
||||||
|
CONF_ICON,
|
||||||
|
CONF_ICON_TEMPLATE,
|
||||||
|
CONF_NAME,
|
||||||
|
CONF_UNIQUE_ID,
|
||||||
|
SERVICE_RELOAD,
|
||||||
|
)
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.entity_platform import async_get_platforms
|
from homeassistant.exceptions import PlatformNotReady
|
||||||
|
from homeassistant.helpers import template
|
||||||
|
from homeassistant.helpers.entity import Entity
|
||||||
|
from homeassistant.helpers.entity_platform import (
|
||||||
|
AddEntitiesCallback,
|
||||||
|
async_get_platforms,
|
||||||
|
)
|
||||||
from homeassistant.helpers.singleton import singleton
|
from homeassistant.helpers.singleton import singleton
|
||||||
|
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
|
|
||||||
from .const import DOMAIN
|
from .const import (
|
||||||
|
CONF_ATTRIBUTE_TEMPLATES,
|
||||||
|
CONF_ATTRIBUTES,
|
||||||
|
CONF_AVAILABILITY,
|
||||||
|
CONF_AVAILABILITY_TEMPLATE,
|
||||||
|
CONF_OBJECT_ID,
|
||||||
|
CONF_PICTURE,
|
||||||
|
DOMAIN,
|
||||||
|
)
|
||||||
from .entity import AbstractTemplateEntity
|
from .entity import AbstractTemplateEntity
|
||||||
|
from .template_entity import TemplateEntity
|
||||||
|
from .trigger_entity import TriggerEntity
|
||||||
|
|
||||||
DATA_BLUEPRINTS = "template_blueprints"
|
DATA_BLUEPRINTS = "template_blueprints"
|
||||||
|
|
||||||
LOGGER = logging.getLogger(__name__)
|
LEGACY_FIELDS = {
|
||||||
|
CONF_ICON_TEMPLATE: CONF_ICON,
|
||||||
|
CONF_ENTITY_PICTURE_TEMPLATE: CONF_PICTURE,
|
||||||
|
CONF_AVAILABILITY_TEMPLATE: CONF_AVAILABILITY,
|
||||||
|
CONF_ATTRIBUTE_TEMPLATES: CONF_ATTRIBUTES,
|
||||||
|
CONF_FRIENDLY_NAME: CONF_NAME,
|
||||||
|
}
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
type CreateTemplateEntitiesCallback = Callable[
|
||||||
|
[type[TemplateEntity], AddEntitiesCallback, HomeAssistant, list[dict], str | None],
|
||||||
|
None,
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
@ -59,8 +100,131 @@ def async_get_blueprints(hass: HomeAssistant) -> blueprint.DomainBlueprints:
|
|||||||
return blueprint.DomainBlueprints(
|
return blueprint.DomainBlueprints(
|
||||||
hass,
|
hass,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
LOGGER,
|
_LOGGER,
|
||||||
_blueprint_in_use,
|
_blueprint_in_use,
|
||||||
_reload_blueprint_templates,
|
_reload_blueprint_templates,
|
||||||
TEMPLATE_BLUEPRINT_SCHEMA,
|
TEMPLATE_BLUEPRINT_SCHEMA,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def rewrite_legacy_to_modern_config(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
entity_cfg: dict[str, Any],
|
||||||
|
extra_legacy_fields: dict[str, str],
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
"""Rewrite legacy config."""
|
||||||
|
entity_cfg = {**entity_cfg}
|
||||||
|
|
||||||
|
for from_key, to_key in itertools.chain(
|
||||||
|
LEGACY_FIELDS.items(), extra_legacy_fields.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, hass)
|
||||||
|
entity_cfg[to_key] = val
|
||||||
|
|
||||||
|
if CONF_NAME in entity_cfg and isinstance(entity_cfg[CONF_NAME], str):
|
||||||
|
entity_cfg[CONF_NAME] = template.Template(entity_cfg[CONF_NAME], hass)
|
||||||
|
|
||||||
|
return entity_cfg
|
||||||
|
|
||||||
|
|
||||||
|
def rewrite_legacy_to_modern_configs(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
entity_cfg: dict[str, dict],
|
||||||
|
extra_legacy_fields: dict[str, str],
|
||||||
|
) -> list[dict]:
|
||||||
|
"""Rewrite legacy configuration definitions to modern ones."""
|
||||||
|
entities = []
|
||||||
|
for object_id, entity_conf in entity_cfg.items():
|
||||||
|
entity_conf = {**entity_conf, CONF_OBJECT_ID: object_id}
|
||||||
|
|
||||||
|
entity_conf = rewrite_legacy_to_modern_config(
|
||||||
|
hass, entity_conf, extra_legacy_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
if CONF_NAME not in entity_conf:
|
||||||
|
entity_conf[CONF_NAME] = template.Template(object_id, hass)
|
||||||
|
|
||||||
|
entities.append(entity_conf)
|
||||||
|
|
||||||
|
return entities
|
||||||
|
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def async_create_template_tracking_entities(
|
||||||
|
entity_cls: type[Entity],
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
hass: HomeAssistant,
|
||||||
|
definitions: list[dict],
|
||||||
|
unique_id_prefix: str | None,
|
||||||
|
) -> None:
|
||||||
|
"""Create the template tracking entities."""
|
||||||
|
entities: list[Entity] = []
|
||||||
|
for definition in definitions:
|
||||||
|
unique_id = definition.get(CONF_UNIQUE_ID)
|
||||||
|
if unique_id and unique_id_prefix:
|
||||||
|
unique_id = f"{unique_id_prefix}-{unique_id}"
|
||||||
|
entities.append(entity_cls(hass, definition, unique_id)) # type: ignore[call-arg]
|
||||||
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_template_platform(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
domain: str,
|
||||||
|
config: ConfigType,
|
||||||
|
state_entity_cls: type[TemplateEntity],
|
||||||
|
trigger_entity_cls: type[TriggerEntity] | None,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
discovery_info: DiscoveryInfoType | None,
|
||||||
|
legacy_fields: dict[str, str] | None = None,
|
||||||
|
legacy_key: str | None = None,
|
||||||
|
) -> None:
|
||||||
|
"""Set up the Template platform."""
|
||||||
|
if discovery_info is None:
|
||||||
|
# Legacy Configuration
|
||||||
|
if legacy_fields is not None:
|
||||||
|
if legacy_key:
|
||||||
|
configs = rewrite_legacy_to_modern_configs(
|
||||||
|
hass, config[legacy_key], legacy_fields
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
configs = [rewrite_legacy_to_modern_config(hass, config, legacy_fields)]
|
||||||
|
async_create_template_tracking_entities(
|
||||||
|
state_entity_cls,
|
||||||
|
async_add_entities,
|
||||||
|
hass,
|
||||||
|
configs,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
_LOGGER.warning(
|
||||||
|
"Template %s entities can only be configured under template:", domain
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Trigger Configuration
|
||||||
|
if "coordinator" in discovery_info:
|
||||||
|
if trigger_entity_cls:
|
||||||
|
entities = [
|
||||||
|
trigger_entity_cls(hass, discovery_info["coordinator"], config)
|
||||||
|
for config in discovery_info["entities"]
|
||||||
|
]
|
||||||
|
async_add_entities(entities)
|
||||||
|
else:
|
||||||
|
raise PlatformNotReady(
|
||||||
|
f"The template {domain} platform doesn't support trigger entities"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Modern Configuration
|
||||||
|
async_create_template_tracking_entities(
|
||||||
|
state_entity_cls,
|
||||||
|
async_add_entities,
|
||||||
|
hass,
|
||||||
|
discovery_info["entities"],
|
||||||
|
discovery_info["unique_id"],
|
||||||
|
)
|
||||||
|
@ -9,13 +9,7 @@ import voluptuous as vol
|
|||||||
|
|
||||||
from homeassistant.components.image import DOMAIN as IMAGE_DOMAIN, ImageEntity
|
from homeassistant.components.image import DOMAIN as IMAGE_DOMAIN, ImageEntity
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import CONF_DEVICE_ID, CONF_NAME, CONF_URL, CONF_VERIFY_SSL
|
||||||
CONF_DEVICE_ID,
|
|
||||||
CONF_NAME,
|
|
||||||
CONF_UNIQUE_ID,
|
|
||||||
CONF_URL,
|
|
||||||
CONF_VERIFY_SSL,
|
|
||||||
)
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.exceptions import TemplateError
|
from homeassistant.exceptions import TemplateError
|
||||||
from homeassistant.helpers import config_validation as cv, selector
|
from homeassistant.helpers import config_validation as cv, selector
|
||||||
@ -29,6 +23,7 @@ from homeassistant.util import dt as dt_util
|
|||||||
|
|
||||||
from . import TriggerUpdateCoordinator
|
from . import TriggerUpdateCoordinator
|
||||||
from .const import CONF_PICTURE
|
from .const import CONF_PICTURE
|
||||||
|
from .helpers import async_setup_template_platform
|
||||||
from .template_entity import (
|
from .template_entity import (
|
||||||
TemplateEntity,
|
TemplateEntity,
|
||||||
make_template_entity_common_modern_attributes_schema,
|
make_template_entity_common_modern_attributes_schema,
|
||||||
@ -59,19 +54,6 @@ IMAGE_CONFIG_SCHEMA = vol.Schema(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def _async_create_entities(
|
|
||||||
hass: HomeAssistant, definitions: list[dict[str, Any]], unique_id_prefix: str | None
|
|
||||||
) -> list[StateImageEntity]:
|
|
||||||
"""Create the template image."""
|
|
||||||
entities = []
|
|
||||||
for definition in definitions:
|
|
||||||
unique_id = definition.get(CONF_UNIQUE_ID)
|
|
||||||
if unique_id and unique_id_prefix:
|
|
||||||
unique_id = f"{unique_id_prefix}-{unique_id}"
|
|
||||||
entities.append(StateImageEntity(hass, definition, unique_id))
|
|
||||||
return entities
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(
|
async def async_setup_platform(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
@ -79,23 +61,14 @@ async def async_setup_platform(
|
|||||||
discovery_info: DiscoveryInfoType | None = None,
|
discovery_info: DiscoveryInfoType | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the template image."""
|
"""Set up the template image."""
|
||||||
if discovery_info is None:
|
await async_setup_template_platform(
|
||||||
_LOGGER.warning(
|
hass,
|
||||||
"Template image entities can only be configured under template:"
|
IMAGE_DOMAIN,
|
||||||
)
|
config,
|
||||||
return
|
StateImageEntity,
|
||||||
|
TriggerImageEntity,
|
||||||
if "coordinator" in discovery_info:
|
async_add_entities,
|
||||||
async_add_entities(
|
discovery_info,
|
||||||
TriggerImageEntity(hass, discovery_info["coordinator"], config)
|
|
||||||
for config in discovery_info["entities"]
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async_add_entities(
|
|
||||||
await _async_create_entities(
|
|
||||||
hass, discovery_info["entities"], discovery_info["unique_id"]
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,12 +51,11 @@ from homeassistant.util import color as color_util
|
|||||||
from . import TriggerUpdateCoordinator
|
from . import TriggerUpdateCoordinator
|
||||||
from .const import CONF_OBJECT_ID, DOMAIN
|
from .const import CONF_OBJECT_ID, DOMAIN
|
||||||
from .entity import AbstractTemplateEntity
|
from .entity import AbstractTemplateEntity
|
||||||
|
from .helpers import async_setup_template_platform
|
||||||
from .template_entity import (
|
from .template_entity import (
|
||||||
LEGACY_FIELDS as TEMPLATE_ENTITY_LEGACY_FIELDS,
|
|
||||||
TEMPLATE_ENTITY_COMMON_SCHEMA_LEGACY,
|
TEMPLATE_ENTITY_COMMON_SCHEMA_LEGACY,
|
||||||
TemplateEntity,
|
TemplateEntity,
|
||||||
make_template_entity_common_modern_schema,
|
make_template_entity_common_modern_schema,
|
||||||
rewrite_common_legacy_to_modern_conf,
|
|
||||||
)
|
)
|
||||||
from .trigger_entity import TriggerEntity
|
from .trigger_entity import TriggerEntity
|
||||||
|
|
||||||
@ -103,7 +102,7 @@ CONF_WHITE_VALUE_TEMPLATE = "white_value_template"
|
|||||||
DEFAULT_MIN_MIREDS = 153
|
DEFAULT_MIN_MIREDS = 153
|
||||||
DEFAULT_MAX_MIREDS = 500
|
DEFAULT_MAX_MIREDS = 500
|
||||||
|
|
||||||
LEGACY_FIELDS = TEMPLATE_ENTITY_LEGACY_FIELDS | {
|
LEGACY_FIELDS = {
|
||||||
CONF_COLOR_ACTION: CONF_HS_ACTION,
|
CONF_COLOR_ACTION: CONF_HS_ACTION,
|
||||||
CONF_COLOR_TEMPLATE: CONF_HS,
|
CONF_COLOR_TEMPLATE: CONF_HS,
|
||||||
CONF_EFFECT_LIST_TEMPLATE: CONF_EFFECT_LIST,
|
CONF_EFFECT_LIST_TEMPLATE: CONF_EFFECT_LIST,
|
||||||
@ -193,47 +192,6 @@ PLATFORM_SCHEMA = vol.All(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def rewrite_legacy_to_modern_conf(
|
|
||||||
hass: HomeAssistant, config: dict[str, dict]
|
|
||||||
) -> list[dict]:
|
|
||||||
"""Rewrite legacy switch configuration definitions to modern ones."""
|
|
||||||
lights = []
|
|
||||||
for object_id, entity_conf in config.items():
|
|
||||||
entity_conf = {**entity_conf, CONF_OBJECT_ID: object_id}
|
|
||||||
|
|
||||||
entity_conf = rewrite_common_legacy_to_modern_conf(
|
|
||||||
hass, entity_conf, LEGACY_FIELDS
|
|
||||||
)
|
|
||||||
|
|
||||||
if CONF_NAME not in entity_conf:
|
|
||||||
entity_conf[CONF_NAME] = template.Template(object_id, hass)
|
|
||||||
|
|
||||||
lights.append(entity_conf)
|
|
||||||
|
|
||||||
return lights
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def _async_create_template_tracking_entities(
|
|
||||||
async_add_entities: AddEntitiesCallback,
|
|
||||||
hass: HomeAssistant,
|
|
||||||
definitions: list[dict],
|
|
||||||
unique_id_prefix: str | None,
|
|
||||||
) -> None:
|
|
||||||
"""Create the Template Lights."""
|
|
||||||
lights = []
|
|
||||||
|
|
||||||
for entity_conf in definitions:
|
|
||||||
unique_id = entity_conf.get(CONF_UNIQUE_ID)
|
|
||||||
|
|
||||||
if unique_id and unique_id_prefix:
|
|
||||||
unique_id = f"{unique_id_prefix}-{unique_id}"
|
|
||||||
|
|
||||||
lights.append(LightTemplate(hass, entity_conf, unique_id))
|
|
||||||
|
|
||||||
async_add_entities(lights)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(
|
async def async_setup_platform(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
@ -241,27 +199,16 @@ async def async_setup_platform(
|
|||||||
discovery_info: DiscoveryInfoType | None = None,
|
discovery_info: DiscoveryInfoType | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the template lights."""
|
"""Set up the template lights."""
|
||||||
if discovery_info is None:
|
await async_setup_template_platform(
|
||||||
_async_create_template_tracking_entities(
|
|
||||||
async_add_entities,
|
|
||||||
hass,
|
hass,
|
||||||
rewrite_legacy_to_modern_conf(hass, config[CONF_LIGHTS]),
|
LIGHT_DOMAIN,
|
||||||
None,
|
config,
|
||||||
)
|
StateLightEntity,
|
||||||
return
|
TriggerLightEntity,
|
||||||
|
|
||||||
if "coordinator" in discovery_info:
|
|
||||||
async_add_entities(
|
|
||||||
TriggerLightEntity(hass, discovery_info["coordinator"], config)
|
|
||||||
for config in discovery_info["entities"]
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
_async_create_template_tracking_entities(
|
|
||||||
async_add_entities,
|
async_add_entities,
|
||||||
hass,
|
discovery_info,
|
||||||
discovery_info["entities"],
|
LEGACY_FIELDS,
|
||||||
discovery_info["unique_id"],
|
legacy_key=CONF_LIGHTS,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -934,7 +881,7 @@ class AbstractTemplateLight(AbstractTemplateEntity, LightEntity):
|
|||||||
self._attr_supported_features |= LightEntityFeature.TRANSITION
|
self._attr_supported_features |= LightEntityFeature.TRANSITION
|
||||||
|
|
||||||
|
|
||||||
class LightTemplate(TemplateEntity, AbstractTemplateLight):
|
class StateLightEntity(TemplateEntity, AbstractTemplateLight):
|
||||||
"""Representation of a templated Light, including dimmable."""
|
"""Representation of a templated Light, including dimmable."""
|
||||||
|
|
||||||
_attr_should_poll = False
|
_attr_should_poll = False
|
||||||
|
@ -31,12 +31,11 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
|||||||
from .const import CONF_PICTURE, DOMAIN
|
from .const import CONF_PICTURE, DOMAIN
|
||||||
from .coordinator import TriggerUpdateCoordinator
|
from .coordinator import TriggerUpdateCoordinator
|
||||||
from .entity import AbstractTemplateEntity
|
from .entity import AbstractTemplateEntity
|
||||||
|
from .helpers import async_setup_template_platform
|
||||||
from .template_entity import (
|
from .template_entity import (
|
||||||
LEGACY_FIELDS as TEMPLATE_ENTITY_LEGACY_FIELDS,
|
|
||||||
TEMPLATE_ENTITY_AVAILABILITY_SCHEMA_LEGACY,
|
TEMPLATE_ENTITY_AVAILABILITY_SCHEMA_LEGACY,
|
||||||
TemplateEntity,
|
TemplateEntity,
|
||||||
make_template_entity_common_modern_schema,
|
make_template_entity_common_modern_schema,
|
||||||
rewrite_common_legacy_to_modern_conf,
|
|
||||||
)
|
)
|
||||||
from .trigger_entity import TriggerEntity
|
from .trigger_entity import TriggerEntity
|
||||||
|
|
||||||
@ -49,7 +48,7 @@ CONF_OPEN = "open"
|
|||||||
DEFAULT_NAME = "Template Lock"
|
DEFAULT_NAME = "Template Lock"
|
||||||
DEFAULT_OPTIMISTIC = False
|
DEFAULT_OPTIMISTIC = False
|
||||||
|
|
||||||
LEGACY_FIELDS = TEMPLATE_ENTITY_LEGACY_FIELDS | {
|
LEGACY_FIELDS = {
|
||||||
CONF_CODE_FORMAT_TEMPLATE: CONF_CODE_FORMAT,
|
CONF_CODE_FORMAT_TEMPLATE: CONF_CODE_FORMAT,
|
||||||
CONF_VALUE_TEMPLATE: CONF_STATE,
|
CONF_VALUE_TEMPLATE: CONF_STATE,
|
||||||
}
|
}
|
||||||
@ -83,33 +82,6 @@ PLATFORM_SCHEMA = LOCK_PLATFORM_SCHEMA.extend(
|
|||||||
).extend(TEMPLATE_ENTITY_AVAILABILITY_SCHEMA_LEGACY.schema)
|
).extend(TEMPLATE_ENTITY_AVAILABILITY_SCHEMA_LEGACY.schema)
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def _async_create_template_tracking_entities(
|
|
||||||
async_add_entities: AddEntitiesCallback,
|
|
||||||
hass: HomeAssistant,
|
|
||||||
definitions: list[dict],
|
|
||||||
unique_id_prefix: str | None,
|
|
||||||
) -> None:
|
|
||||||
"""Create the template fans."""
|
|
||||||
fans = []
|
|
||||||
|
|
||||||
for entity_conf in definitions:
|
|
||||||
unique_id = entity_conf.get(CONF_UNIQUE_ID)
|
|
||||||
|
|
||||||
if unique_id and unique_id_prefix:
|
|
||||||
unique_id = f"{unique_id_prefix}-{unique_id}"
|
|
||||||
|
|
||||||
fans.append(
|
|
||||||
TemplateLock(
|
|
||||||
hass,
|
|
||||||
entity_conf,
|
|
||||||
unique_id,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
async_add_entities(fans)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(
|
async def async_setup_platform(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
@ -117,27 +89,15 @@ async def async_setup_platform(
|
|||||||
discovery_info: DiscoveryInfoType | None = None,
|
discovery_info: DiscoveryInfoType | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the template fans."""
|
"""Set up the template fans."""
|
||||||
if discovery_info is None:
|
await async_setup_template_platform(
|
||||||
_async_create_template_tracking_entities(
|
|
||||||
async_add_entities,
|
|
||||||
hass,
|
hass,
|
||||||
[rewrite_common_legacy_to_modern_conf(hass, config, LEGACY_FIELDS)],
|
LOCK_DOMAIN,
|
||||||
None,
|
config,
|
||||||
)
|
StateLockEntity,
|
||||||
return
|
TriggerLockEntity,
|
||||||
|
|
||||||
if "coordinator" in discovery_info:
|
|
||||||
async_add_entities(
|
|
||||||
TriggerLockEntity(hass, discovery_info["coordinator"], config)
|
|
||||||
for config in discovery_info["entities"]
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
_async_create_template_tracking_entities(
|
|
||||||
async_add_entities,
|
async_add_entities,
|
||||||
hass,
|
discovery_info,
|
||||||
discovery_info["entities"],
|
LEGACY_FIELDS,
|
||||||
discovery_info["unique_id"],
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -311,7 +271,7 @@ class AbstractTemplateLock(AbstractTemplateEntity, LockEntity):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TemplateLock(TemplateEntity, AbstractTemplateLock):
|
class StateLockEntity(TemplateEntity, AbstractTemplateLock):
|
||||||
"""Representation of a template lock."""
|
"""Representation of a template lock."""
|
||||||
|
|
||||||
_attr_should_poll = False
|
_attr_should_poll = False
|
||||||
|
@ -21,7 +21,6 @@ from homeassistant.const import (
|
|||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
CONF_OPTIMISTIC,
|
CONF_OPTIMISTIC,
|
||||||
CONF_STATE,
|
CONF_STATE,
|
||||||
CONF_UNIQUE_ID,
|
|
||||||
CONF_UNIT_OF_MEASUREMENT,
|
CONF_UNIT_OF_MEASUREMENT,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
@ -35,6 +34,7 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
|||||||
|
|
||||||
from . import TriggerUpdateCoordinator
|
from . import TriggerUpdateCoordinator
|
||||||
from .const import CONF_MAX, CONF_MIN, CONF_STEP, DOMAIN
|
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 .template_entity import TemplateEntity, make_template_entity_common_modern_schema
|
||||||
from .trigger_entity import TriggerEntity
|
from .trigger_entity import TriggerEntity
|
||||||
|
|
||||||
@ -70,19 +70,6 @@ NUMBER_CONFIG_SCHEMA = vol.Schema(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def _async_create_entities(
|
|
||||||
hass: HomeAssistant, definitions: list[dict[str, Any]], unique_id_prefix: str | None
|
|
||||||
) -> list[TemplateNumber]:
|
|
||||||
"""Create the Template number."""
|
|
||||||
entities = []
|
|
||||||
for definition in definitions:
|
|
||||||
unique_id = definition.get(CONF_UNIQUE_ID)
|
|
||||||
if unique_id and unique_id_prefix:
|
|
||||||
unique_id = f"{unique_id_prefix}-{unique_id}"
|
|
||||||
entities.append(TemplateNumber(hass, definition, unique_id))
|
|
||||||
return entities
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(
|
async def async_setup_platform(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
@ -90,23 +77,14 @@ async def async_setup_platform(
|
|||||||
discovery_info: DiscoveryInfoType | None = None,
|
discovery_info: DiscoveryInfoType | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the template number."""
|
"""Set up the template number."""
|
||||||
if discovery_info is None:
|
await async_setup_template_platform(
|
||||||
_LOGGER.warning(
|
hass,
|
||||||
"Template number entities can only be configured under template:"
|
NUMBER_DOMAIN,
|
||||||
)
|
config,
|
||||||
return
|
StateNumberEntity,
|
||||||
|
TriggerNumberEntity,
|
||||||
if "coordinator" in discovery_info:
|
async_add_entities,
|
||||||
async_add_entities(
|
discovery_info,
|
||||||
TriggerNumberEntity(hass, discovery_info["coordinator"], config)
|
|
||||||
for config in discovery_info["entities"]
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async_add_entities(
|
|
||||||
await _async_create_entities(
|
|
||||||
hass, discovery_info["entities"], discovery_info["unique_id"]
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -119,19 +97,21 @@ async def async_setup_entry(
|
|||||||
_options = dict(config_entry.options)
|
_options = dict(config_entry.options)
|
||||||
_options.pop("template_type")
|
_options.pop("template_type")
|
||||||
validated_config = NUMBER_CONFIG_SCHEMA(_options)
|
validated_config = NUMBER_CONFIG_SCHEMA(_options)
|
||||||
async_add_entities([TemplateNumber(hass, validated_config, config_entry.entry_id)])
|
async_add_entities(
|
||||||
|
[StateNumberEntity(hass, validated_config, config_entry.entry_id)]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def async_create_preview_number(
|
def async_create_preview_number(
|
||||||
hass: HomeAssistant, name: str, config: dict[str, Any]
|
hass: HomeAssistant, name: str, config: dict[str, Any]
|
||||||
) -> TemplateNumber:
|
) -> StateNumberEntity:
|
||||||
"""Create a preview number."""
|
"""Create a preview number."""
|
||||||
validated_config = NUMBER_CONFIG_SCHEMA(config | {CONF_NAME: name})
|
validated_config = NUMBER_CONFIG_SCHEMA(config | {CONF_NAME: name})
|
||||||
return TemplateNumber(hass, validated_config, None)
|
return StateNumberEntity(hass, validated_config, None)
|
||||||
|
|
||||||
|
|
||||||
class TemplateNumber(TemplateEntity, NumberEntity):
|
class StateNumberEntity(TemplateEntity, NumberEntity):
|
||||||
"""Representation of a template number."""
|
"""Representation of a template number."""
|
||||||
|
|
||||||
_attr_should_poll = False
|
_attr_should_poll = False
|
||||||
|
@ -14,13 +14,7 @@ from homeassistant.components.select import (
|
|||||||
SelectEntity,
|
SelectEntity,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import CONF_DEVICE_ID, CONF_NAME, CONF_OPTIMISTIC, CONF_STATE
|
||||||
CONF_DEVICE_ID,
|
|
||||||
CONF_NAME,
|
|
||||||
CONF_OPTIMISTIC,
|
|
||||||
CONF_STATE,
|
|
||||||
CONF_UNIQUE_ID,
|
|
||||||
)
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers import config_validation as cv, selector
|
from homeassistant.helpers import config_validation as cv, selector
|
||||||
from homeassistant.helpers.device import async_device_info_to_link_from_device_id
|
from homeassistant.helpers.device import async_device_info_to_link_from_device_id
|
||||||
@ -33,6 +27,7 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
|||||||
from . import TriggerUpdateCoordinator
|
from . import TriggerUpdateCoordinator
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
from .entity import AbstractTemplateEntity
|
from .entity import AbstractTemplateEntity
|
||||||
|
from .helpers import async_setup_template_platform
|
||||||
from .template_entity import TemplateEntity, make_template_entity_common_modern_schema
|
from .template_entity import TemplateEntity, make_template_entity_common_modern_schema
|
||||||
from .trigger_entity import TriggerEntity
|
from .trigger_entity import TriggerEntity
|
||||||
|
|
||||||
@ -65,19 +60,6 @@ SELECT_CONFIG_SCHEMA = vol.Schema(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def _async_create_entities(
|
|
||||||
hass: HomeAssistant, definitions: list[dict[str, Any]], unique_id_prefix: str | None
|
|
||||||
) -> list[TemplateSelect]:
|
|
||||||
"""Create the Template select."""
|
|
||||||
entities = []
|
|
||||||
for definition in definitions:
|
|
||||||
unique_id = definition.get(CONF_UNIQUE_ID)
|
|
||||||
if unique_id and unique_id_prefix:
|
|
||||||
unique_id = f"{unique_id_prefix}-{unique_id}"
|
|
||||||
entities.append(TemplateSelect(hass, definition, unique_id))
|
|
||||||
return entities
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(
|
async def async_setup_platform(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
@ -85,23 +67,14 @@ async def async_setup_platform(
|
|||||||
discovery_info: DiscoveryInfoType | None = None,
|
discovery_info: DiscoveryInfoType | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the template select."""
|
"""Set up the template select."""
|
||||||
if discovery_info is None:
|
await async_setup_template_platform(
|
||||||
_LOGGER.warning(
|
hass,
|
||||||
"Template select entities can only be configured under template:"
|
SELECT_DOMAIN,
|
||||||
)
|
config,
|
||||||
return
|
TemplateSelect,
|
||||||
|
TriggerSelectEntity,
|
||||||
if "coordinator" in discovery_info:
|
async_add_entities,
|
||||||
async_add_entities(
|
discovery_info,
|
||||||
TriggerSelectEntity(hass, discovery_info["coordinator"], config)
|
|
||||||
for config in discovery_info["entities"]
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async_add_entities(
|
|
||||||
await _async_create_entities(
|
|
||||||
hass, discovery_info["entities"], discovery_info["unique_id"]
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,16 +56,12 @@ from homeassistant.util import dt as dt_util
|
|||||||
|
|
||||||
from . import TriggerUpdateCoordinator
|
from . import TriggerUpdateCoordinator
|
||||||
from .const import CONF_ATTRIBUTE_TEMPLATES, CONF_AVAILABILITY_TEMPLATE, CONF_OBJECT_ID
|
from .const import CONF_ATTRIBUTE_TEMPLATES, CONF_AVAILABILITY_TEMPLATE, CONF_OBJECT_ID
|
||||||
from .template_entity import (
|
from .helpers import async_setup_template_platform
|
||||||
TEMPLATE_ENTITY_COMMON_SCHEMA,
|
from .template_entity import TEMPLATE_ENTITY_COMMON_SCHEMA, TemplateEntity
|
||||||
TemplateEntity,
|
|
||||||
rewrite_common_legacy_to_modern_conf,
|
|
||||||
)
|
|
||||||
from .trigger_entity import TriggerEntity
|
from .trigger_entity import TriggerEntity
|
||||||
|
|
||||||
LEGACY_FIELDS = {
|
LEGACY_FIELDS = {
|
||||||
CONF_FRIENDLY_NAME_TEMPLATE: CONF_NAME,
|
CONF_FRIENDLY_NAME_TEMPLATE: CONF_NAME,
|
||||||
CONF_FRIENDLY_NAME: CONF_NAME,
|
|
||||||
CONF_VALUE_TEMPLATE: CONF_STATE,
|
CONF_VALUE_TEMPLATE: CONF_STATE,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,27 +138,6 @@ def extra_validation_checks(val):
|
|||||||
return val
|
return val
|
||||||
|
|
||||||
|
|
||||||
def rewrite_legacy_to_modern_conf(
|
|
||||||
hass: HomeAssistant, cfg: dict[str, dict]
|
|
||||||
) -> list[dict]:
|
|
||||||
"""Rewrite legacy sensor definitions to modern ones."""
|
|
||||||
sensors = []
|
|
||||||
|
|
||||||
for object_id, entity_cfg in cfg.items():
|
|
||||||
entity_cfg = {**entity_cfg, CONF_OBJECT_ID: object_id}
|
|
||||||
|
|
||||||
entity_cfg = rewrite_common_legacy_to_modern_conf(
|
|
||||||
hass, entity_cfg, LEGACY_FIELDS
|
|
||||||
)
|
|
||||||
|
|
||||||
if CONF_NAME not in entity_cfg:
|
|
||||||
entity_cfg[CONF_NAME] = template.Template(object_id, hass)
|
|
||||||
|
|
||||||
sensors.append(entity_cfg)
|
|
||||||
|
|
||||||
return sensors
|
|
||||||
|
|
||||||
|
|
||||||
PLATFORM_SCHEMA = vol.All(
|
PLATFORM_SCHEMA = vol.All(
|
||||||
SENSOR_PLATFORM_SCHEMA.extend(
|
SENSOR_PLATFORM_SCHEMA.extend(
|
||||||
{
|
{
|
||||||
@ -177,33 +152,6 @@ PLATFORM_SCHEMA = vol.All(
|
|||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def _async_create_template_tracking_entities(
|
|
||||||
async_add_entities: AddEntitiesCallback | AddConfigEntryEntitiesCallback,
|
|
||||||
hass: HomeAssistant,
|
|
||||||
definitions: list[dict],
|
|
||||||
unique_id_prefix: str | None,
|
|
||||||
) -> None:
|
|
||||||
"""Create the template sensors."""
|
|
||||||
sensors = []
|
|
||||||
|
|
||||||
for entity_conf in definitions:
|
|
||||||
unique_id = entity_conf.get(CONF_UNIQUE_ID)
|
|
||||||
|
|
||||||
if unique_id and unique_id_prefix:
|
|
||||||
unique_id = f"{unique_id_prefix}-{unique_id}"
|
|
||||||
|
|
||||||
sensors.append(
|
|
||||||
SensorTemplate(
|
|
||||||
hass,
|
|
||||||
entity_conf,
|
|
||||||
unique_id,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
async_add_entities(sensors)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(
|
async def async_setup_platform(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
@ -211,27 +159,16 @@ async def async_setup_platform(
|
|||||||
discovery_info: DiscoveryInfoType | None = None,
|
discovery_info: DiscoveryInfoType | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the template sensors."""
|
"""Set up the template sensors."""
|
||||||
if discovery_info is None:
|
await async_setup_template_platform(
|
||||||
_async_create_template_tracking_entities(
|
|
||||||
async_add_entities,
|
|
||||||
hass,
|
hass,
|
||||||
rewrite_legacy_to_modern_conf(hass, config[CONF_SENSORS]),
|
SENSOR_DOMAIN,
|
||||||
None,
|
config,
|
||||||
)
|
StateSensorEntity,
|
||||||
return
|
TriggerSensorEntity,
|
||||||
|
|
||||||
if "coordinator" in discovery_info:
|
|
||||||
async_add_entities(
|
|
||||||
TriggerSensorEntity(hass, discovery_info["coordinator"], config)
|
|
||||||
for config in discovery_info["entities"]
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
_async_create_template_tracking_entities(
|
|
||||||
async_add_entities,
|
async_add_entities,
|
||||||
hass,
|
discovery_info,
|
||||||
discovery_info["entities"],
|
LEGACY_FIELDS,
|
||||||
discovery_info["unique_id"],
|
legacy_key=CONF_SENSORS,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -244,19 +181,21 @@ async def async_setup_entry(
|
|||||||
_options = dict(config_entry.options)
|
_options = dict(config_entry.options)
|
||||||
_options.pop("template_type")
|
_options.pop("template_type")
|
||||||
validated_config = SENSOR_CONFIG_SCHEMA(_options)
|
validated_config = SENSOR_CONFIG_SCHEMA(_options)
|
||||||
async_add_entities([SensorTemplate(hass, validated_config, config_entry.entry_id)])
|
async_add_entities(
|
||||||
|
[StateSensorEntity(hass, validated_config, config_entry.entry_id)]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def async_create_preview_sensor(
|
def async_create_preview_sensor(
|
||||||
hass: HomeAssistant, name: str, config: dict[str, Any]
|
hass: HomeAssistant, name: str, config: dict[str, Any]
|
||||||
) -> SensorTemplate:
|
) -> StateSensorEntity:
|
||||||
"""Create a preview sensor."""
|
"""Create a preview sensor."""
|
||||||
validated_config = SENSOR_CONFIG_SCHEMA(config | {CONF_NAME: name})
|
validated_config = SENSOR_CONFIG_SCHEMA(config | {CONF_NAME: name})
|
||||||
return SensorTemplate(hass, validated_config, None)
|
return StateSensorEntity(hass, validated_config, None)
|
||||||
|
|
||||||
|
|
||||||
class SensorTemplate(TemplateEntity, SensorEntity):
|
class StateSensorEntity(TemplateEntity, SensorEntity):
|
||||||
"""Representation of a Template Sensor."""
|
"""Representation of a Template Sensor."""
|
||||||
|
|
||||||
_attr_should_poll = False
|
_attr_should_poll = False
|
||||||
|
@ -41,18 +41,17 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
|||||||
|
|
||||||
from . import TriggerUpdateCoordinator
|
from . import TriggerUpdateCoordinator
|
||||||
from .const import CONF_OBJECT_ID, CONF_TURN_OFF, CONF_TURN_ON, DOMAIN
|
from .const import CONF_OBJECT_ID, CONF_TURN_OFF, CONF_TURN_ON, DOMAIN
|
||||||
|
from .helpers import async_setup_template_platform
|
||||||
from .template_entity import (
|
from .template_entity import (
|
||||||
LEGACY_FIELDS as TEMPLATE_ENTITY_LEGACY_FIELDS,
|
|
||||||
TEMPLATE_ENTITY_COMMON_SCHEMA_LEGACY,
|
TEMPLATE_ENTITY_COMMON_SCHEMA_LEGACY,
|
||||||
TemplateEntity,
|
TemplateEntity,
|
||||||
make_template_entity_common_modern_schema,
|
make_template_entity_common_modern_schema,
|
||||||
rewrite_common_legacy_to_modern_conf,
|
|
||||||
)
|
)
|
||||||
from .trigger_entity import TriggerEntity
|
from .trigger_entity import TriggerEntity
|
||||||
|
|
||||||
_VALID_STATES = [STATE_ON, STATE_OFF, "true", "false"]
|
_VALID_STATES = [STATE_ON, STATE_OFF, "true", "false"]
|
||||||
|
|
||||||
LEGACY_FIELDS = TEMPLATE_ENTITY_LEGACY_FIELDS | {
|
LEGACY_FIELDS = {
|
||||||
CONF_VALUE_TEMPLATE: CONF_STATE,
|
CONF_VALUE_TEMPLATE: CONF_STATE,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,27 +95,6 @@ SWITCH_CONFIG_SCHEMA = vol.Schema(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def rewrite_legacy_to_modern_conf(
|
|
||||||
hass: HomeAssistant, config: dict[str, dict]
|
|
||||||
) -> list[dict]:
|
|
||||||
"""Rewrite legacy switch configuration definitions to modern ones."""
|
|
||||||
switches = []
|
|
||||||
|
|
||||||
for object_id, entity_conf in config.items():
|
|
||||||
entity_conf = {**entity_conf, CONF_OBJECT_ID: object_id}
|
|
||||||
|
|
||||||
entity_conf = rewrite_common_legacy_to_modern_conf(
|
|
||||||
hass, entity_conf, LEGACY_FIELDS
|
|
||||||
)
|
|
||||||
|
|
||||||
if CONF_NAME not in entity_conf:
|
|
||||||
entity_conf[CONF_NAME] = template.Template(object_id, hass)
|
|
||||||
|
|
||||||
switches.append(entity_conf)
|
|
||||||
|
|
||||||
return switches
|
|
||||||
|
|
||||||
|
|
||||||
def rewrite_options_to_modern_conf(option_config: dict[str, dict]) -> dict[str, dict]:
|
def rewrite_options_to_modern_conf(option_config: dict[str, dict]) -> dict[str, dict]:
|
||||||
"""Rewrite option configuration to modern configuration."""
|
"""Rewrite option configuration to modern configuration."""
|
||||||
option_config = {**option_config}
|
option_config = {**option_config}
|
||||||
@ -127,33 +105,6 @@ def rewrite_options_to_modern_conf(option_config: dict[str, dict]) -> dict[str,
|
|||||||
return option_config
|
return option_config
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def _async_create_template_tracking_entities(
|
|
||||||
async_add_entities: AddEntitiesCallback,
|
|
||||||
hass: HomeAssistant,
|
|
||||||
definitions: list[dict],
|
|
||||||
unique_id_prefix: str | None,
|
|
||||||
) -> None:
|
|
||||||
"""Create the template switches."""
|
|
||||||
switches = []
|
|
||||||
|
|
||||||
for entity_conf in definitions:
|
|
||||||
unique_id = entity_conf.get(CONF_UNIQUE_ID)
|
|
||||||
|
|
||||||
if unique_id and unique_id_prefix:
|
|
||||||
unique_id = f"{unique_id_prefix}-{unique_id}"
|
|
||||||
|
|
||||||
switches.append(
|
|
||||||
SwitchTemplate(
|
|
||||||
hass,
|
|
||||||
entity_conf,
|
|
||||||
unique_id,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
async_add_entities(switches)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(
|
async def async_setup_platform(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
@ -161,27 +112,16 @@ async def async_setup_platform(
|
|||||||
discovery_info: DiscoveryInfoType | None = None,
|
discovery_info: DiscoveryInfoType | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the template switches."""
|
"""Set up the template switches."""
|
||||||
if discovery_info is None:
|
await async_setup_template_platform(
|
||||||
_async_create_template_tracking_entities(
|
|
||||||
async_add_entities,
|
|
||||||
hass,
|
hass,
|
||||||
rewrite_legacy_to_modern_conf(hass, config[CONF_SWITCHES]),
|
SWITCH_DOMAIN,
|
||||||
None,
|
config,
|
||||||
)
|
StateSwitchEntity,
|
||||||
return
|
TriggerSwitchEntity,
|
||||||
|
|
||||||
if "coordinator" in discovery_info:
|
|
||||||
async_add_entities(
|
|
||||||
TriggerSwitchEntity(hass, discovery_info["coordinator"], config)
|
|
||||||
for config in discovery_info["entities"]
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
_async_create_template_tracking_entities(
|
|
||||||
async_add_entities,
|
async_add_entities,
|
||||||
hass,
|
discovery_info,
|
||||||
discovery_info["entities"],
|
LEGACY_FIELDS,
|
||||||
discovery_info["unique_id"],
|
legacy_key=CONF_SWITCHES,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -195,20 +135,22 @@ async def async_setup_entry(
|
|||||||
_options.pop("template_type")
|
_options.pop("template_type")
|
||||||
_options = rewrite_options_to_modern_conf(_options)
|
_options = rewrite_options_to_modern_conf(_options)
|
||||||
validated_config = SWITCH_CONFIG_SCHEMA(_options)
|
validated_config = SWITCH_CONFIG_SCHEMA(_options)
|
||||||
async_add_entities([SwitchTemplate(hass, validated_config, config_entry.entry_id)])
|
async_add_entities(
|
||||||
|
[StateSwitchEntity(hass, validated_config, config_entry.entry_id)]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def async_create_preview_switch(
|
def async_create_preview_switch(
|
||||||
hass: HomeAssistant, name: str, config: dict[str, Any]
|
hass: HomeAssistant, name: str, config: dict[str, Any]
|
||||||
) -> SwitchTemplate:
|
) -> StateSwitchEntity:
|
||||||
"""Create a preview switch."""
|
"""Create a preview switch."""
|
||||||
updated_config = rewrite_options_to_modern_conf(config)
|
updated_config = rewrite_options_to_modern_conf(config)
|
||||||
validated_config = SWITCH_CONFIG_SCHEMA(updated_config | {CONF_NAME: name})
|
validated_config = SWITCH_CONFIG_SCHEMA(updated_config | {CONF_NAME: name})
|
||||||
return SwitchTemplate(hass, validated_config, None)
|
return StateSwitchEntity(hass, validated_config, None)
|
||||||
|
|
||||||
|
|
||||||
class SwitchTemplate(TemplateEntity, SwitchEntity, RestoreEntity):
|
class StateSwitchEntity(TemplateEntity, SwitchEntity, RestoreEntity):
|
||||||
"""Representation of a Template switch."""
|
"""Representation of a Template switch."""
|
||||||
|
|
||||||
_attr_should_poll = False
|
_attr_should_poll = False
|
||||||
|
@ -4,7 +4,6 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from collections.abc import Callable, Mapping
|
from collections.abc import Callable, Mapping
|
||||||
import contextlib
|
import contextlib
|
||||||
import itertools
|
|
||||||
import logging
|
import logging
|
||||||
from typing import Any, cast
|
from typing import Any, cast
|
||||||
|
|
||||||
@ -14,7 +13,6 @@ import voluptuous as vol
|
|||||||
from homeassistant.components.blueprint import CONF_USE_BLUEPRINT
|
from homeassistant.components.blueprint import CONF_USE_BLUEPRINT
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_ENTITY_PICTURE_TEMPLATE,
|
CONF_ENTITY_PICTURE_TEMPLATE,
|
||||||
CONF_FRIENDLY_NAME,
|
|
||||||
CONF_ICON,
|
CONF_ICON,
|
||||||
CONF_ICON_TEMPLATE,
|
CONF_ICON_TEMPLATE,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
@ -137,42 +135,6 @@ TEMPLATE_ENTITY_COMMON_SCHEMA_LEGACY = vol.Schema(
|
|||||||
).extend(TEMPLATE_ENTITY_AVAILABILITY_SCHEMA_LEGACY.schema)
|
).extend(TEMPLATE_ENTITY_AVAILABILITY_SCHEMA_LEGACY.schema)
|
||||||
|
|
||||||
|
|
||||||
LEGACY_FIELDS = {
|
|
||||||
CONF_ICON_TEMPLATE: CONF_ICON,
|
|
||||||
CONF_ENTITY_PICTURE_TEMPLATE: CONF_PICTURE,
|
|
||||||
CONF_AVAILABILITY_TEMPLATE: CONF_AVAILABILITY,
|
|
||||||
CONF_ATTRIBUTE_TEMPLATES: CONF_ATTRIBUTES,
|
|
||||||
CONF_FRIENDLY_NAME: CONF_NAME,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def rewrite_common_legacy_to_modern_conf(
|
|
||||||
hass: HomeAssistant,
|
|
||||||
entity_cfg: dict[str, Any],
|
|
||||||
extra_legacy_fields: dict[str, str] | None = None,
|
|
||||||
) -> dict[str, Any]:
|
|
||||||
"""Rewrite legacy config."""
|
|
||||||
entity_cfg = {**entity_cfg}
|
|
||||||
if extra_legacy_fields is None:
|
|
||||||
extra_legacy_fields = {}
|
|
||||||
|
|
||||||
for from_key, to_key in itertools.chain(
|
|
||||||
LEGACY_FIELDS.items(), extra_legacy_fields.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(val, hass)
|
|
||||||
entity_cfg[to_key] = val
|
|
||||||
|
|
||||||
if CONF_NAME in entity_cfg and isinstance(entity_cfg[CONF_NAME], str):
|
|
||||||
entity_cfg[CONF_NAME] = Template(entity_cfg[CONF_NAME], hass)
|
|
||||||
|
|
||||||
return entity_cfg
|
|
||||||
|
|
||||||
|
|
||||||
class _TemplateAttribute:
|
class _TemplateAttribute:
|
||||||
"""Attribute value linked to template result."""
|
"""Attribute value linked to template result."""
|
||||||
|
|
||||||
|
@ -41,13 +41,12 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
|||||||
from .const import CONF_OBJECT_ID, DOMAIN
|
from .const import CONF_OBJECT_ID, DOMAIN
|
||||||
from .coordinator import TriggerUpdateCoordinator
|
from .coordinator import TriggerUpdateCoordinator
|
||||||
from .entity import AbstractTemplateEntity
|
from .entity import AbstractTemplateEntity
|
||||||
|
from .helpers import async_setup_template_platform
|
||||||
from .template_entity import (
|
from .template_entity import (
|
||||||
LEGACY_FIELDS as TEMPLATE_ENTITY_LEGACY_FIELDS,
|
|
||||||
TEMPLATE_ENTITY_ATTRIBUTES_SCHEMA_LEGACY,
|
TEMPLATE_ENTITY_ATTRIBUTES_SCHEMA_LEGACY,
|
||||||
TEMPLATE_ENTITY_AVAILABILITY_SCHEMA_LEGACY,
|
TEMPLATE_ENTITY_AVAILABILITY_SCHEMA_LEGACY,
|
||||||
TemplateEntity,
|
TemplateEntity,
|
||||||
make_template_entity_common_modern_attributes_schema,
|
make_template_entity_common_modern_attributes_schema,
|
||||||
rewrite_common_legacy_to_modern_conf,
|
|
||||||
)
|
)
|
||||||
from .trigger_entity import TriggerEntity
|
from .trigger_entity import TriggerEntity
|
||||||
|
|
||||||
@ -72,7 +71,7 @@ _VALID_STATES = [
|
|||||||
VacuumActivity.ERROR,
|
VacuumActivity.ERROR,
|
||||||
]
|
]
|
||||||
|
|
||||||
LEGACY_FIELDS = TEMPLATE_ENTITY_LEGACY_FIELDS | {
|
LEGACY_FIELDS = {
|
||||||
CONF_BATTERY_LEVEL_TEMPLATE: CONF_BATTERY_LEVEL,
|
CONF_BATTERY_LEVEL_TEMPLATE: CONF_BATTERY_LEVEL,
|
||||||
CONF_FAN_SPEED_TEMPLATE: CONF_FAN_SPEED,
|
CONF_FAN_SPEED_TEMPLATE: CONF_FAN_SPEED,
|
||||||
CONF_VALUE_TEMPLATE: CONF_STATE,
|
CONF_VALUE_TEMPLATE: CONF_STATE,
|
||||||
@ -125,82 +124,23 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def rewrite_legacy_to_modern_conf(
|
|
||||||
hass: HomeAssistant, config: dict[str, dict]
|
|
||||||
) -> list[dict]:
|
|
||||||
"""Rewrite legacy switch configuration definitions to modern ones."""
|
|
||||||
vacuums = []
|
|
||||||
|
|
||||||
for object_id, entity_conf in config.items():
|
|
||||||
entity_conf = {**entity_conf, CONF_OBJECT_ID: object_id}
|
|
||||||
|
|
||||||
entity_conf = rewrite_common_legacy_to_modern_conf(
|
|
||||||
hass, entity_conf, LEGACY_FIELDS
|
|
||||||
)
|
|
||||||
|
|
||||||
if CONF_NAME not in entity_conf:
|
|
||||||
entity_conf[CONF_NAME] = template.Template(object_id, hass)
|
|
||||||
|
|
||||||
vacuums.append(entity_conf)
|
|
||||||
|
|
||||||
return vacuums
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def _async_create_template_tracking_entities(
|
|
||||||
async_add_entities: AddEntitiesCallback,
|
|
||||||
hass: HomeAssistant,
|
|
||||||
definitions: list[dict],
|
|
||||||
unique_id_prefix: str | None,
|
|
||||||
) -> None:
|
|
||||||
"""Create the template switches."""
|
|
||||||
vacuums = []
|
|
||||||
|
|
||||||
for entity_conf in definitions:
|
|
||||||
unique_id = entity_conf.get(CONF_UNIQUE_ID)
|
|
||||||
|
|
||||||
if unique_id and unique_id_prefix:
|
|
||||||
unique_id = f"{unique_id_prefix}-{unique_id}"
|
|
||||||
|
|
||||||
vacuums.append(
|
|
||||||
TemplateVacuum(
|
|
||||||
hass,
|
|
||||||
entity_conf,
|
|
||||||
unique_id,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
async_add_entities(vacuums)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(
|
async def async_setup_platform(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
discovery_info: DiscoveryInfoType | None = None,
|
discovery_info: DiscoveryInfoType | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the Template cover."""
|
"""Set up the Template vacuum."""
|
||||||
if discovery_info is None:
|
await async_setup_template_platform(
|
||||||
_async_create_template_tracking_entities(
|
|
||||||
async_add_entities,
|
|
||||||
hass,
|
hass,
|
||||||
rewrite_legacy_to_modern_conf(hass, config[CONF_VACUUMS]),
|
VACUUM_DOMAIN,
|
||||||
None,
|
config,
|
||||||
)
|
TemplateStateVacuumEntity,
|
||||||
return
|
TriggerVacuumEntity,
|
||||||
|
|
||||||
if "coordinator" in discovery_info:
|
|
||||||
async_add_entities(
|
|
||||||
TriggerVacuumEntity(hass, discovery_info["coordinator"], config)
|
|
||||||
for config in discovery_info["entities"]
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
_async_create_template_tracking_entities(
|
|
||||||
async_add_entities,
|
async_add_entities,
|
||||||
hass,
|
discovery_info,
|
||||||
discovery_info["entities"],
|
LEGACY_FIELDS,
|
||||||
discovery_info["unique_id"],
|
legacy_key=CONF_VACUUMS,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -350,7 +290,7 @@ class AbstractTemplateVacuum(AbstractTemplateEntity, StateVacuumEntity):
|
|||||||
self._attr_fan_speed = None
|
self._attr_fan_speed = None
|
||||||
|
|
||||||
|
|
||||||
class TemplateVacuum(TemplateEntity, AbstractTemplateVacuum):
|
class TemplateStateVacuumEntity(TemplateEntity, AbstractTemplateVacuum):
|
||||||
"""A template vacuum component."""
|
"""A template vacuum component."""
|
||||||
|
|
||||||
_attr_should_poll = False
|
_attr_should_poll = False
|
||||||
|
@ -31,12 +31,7 @@ from homeassistant.components.weather import (
|
|||||||
WeatherEntity,
|
WeatherEntity,
|
||||||
WeatherEntityFeature,
|
WeatherEntityFeature,
|
||||||
)
|
)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import CONF_TEMPERATURE_UNIT, STATE_UNAVAILABLE, STATE_UNKNOWN
|
||||||
CONF_TEMPERATURE_UNIT,
|
|
||||||
CONF_UNIQUE_ID,
|
|
||||||
STATE_UNAVAILABLE,
|
|
||||||
STATE_UNKNOWN,
|
|
||||||
)
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.exceptions import TemplateError
|
from homeassistant.exceptions import TemplateError
|
||||||
from homeassistant.helpers import config_validation as cv, template
|
from homeassistant.helpers import config_validation as cv, template
|
||||||
@ -52,11 +47,8 @@ from homeassistant.util.unit_conversion import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from .coordinator import TriggerUpdateCoordinator
|
from .coordinator import TriggerUpdateCoordinator
|
||||||
from .template_entity import (
|
from .helpers import async_setup_template_platform
|
||||||
TemplateEntity,
|
from .template_entity import TemplateEntity, make_template_entity_common_modern_schema
|
||||||
make_template_entity_common_modern_schema,
|
|
||||||
rewrite_common_legacy_to_modern_conf,
|
|
||||||
)
|
|
||||||
from .trigger_entity import TriggerEntity
|
from .trigger_entity import TriggerEntity
|
||||||
|
|
||||||
CHECK_FORECAST_KEYS = (
|
CHECK_FORECAST_KEYS = (
|
||||||
@ -138,33 +130,6 @@ WEATHER_SCHEMA = vol.Schema(
|
|||||||
PLATFORM_SCHEMA = WEATHER_PLATFORM_SCHEMA.extend(WEATHER_SCHEMA.schema)
|
PLATFORM_SCHEMA = WEATHER_PLATFORM_SCHEMA.extend(WEATHER_SCHEMA.schema)
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def _async_create_template_tracking_entities(
|
|
||||||
async_add_entities: AddEntitiesCallback,
|
|
||||||
hass: HomeAssistant,
|
|
||||||
definitions: list[dict],
|
|
||||||
unique_id_prefix: str | None,
|
|
||||||
) -> None:
|
|
||||||
"""Create the weather entities."""
|
|
||||||
entities = []
|
|
||||||
|
|
||||||
for entity_conf in definitions:
|
|
||||||
unique_id = entity_conf.get(CONF_UNIQUE_ID)
|
|
||||||
|
|
||||||
if unique_id and unique_id_prefix:
|
|
||||||
unique_id = f"{unique_id_prefix}-{unique_id}"
|
|
||||||
|
|
||||||
entities.append(
|
|
||||||
WeatherTemplate(
|
|
||||||
hass,
|
|
||||||
entity_conf,
|
|
||||||
unique_id,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
async_add_entities(entities)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(
|
async def async_setup_platform(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
@ -172,36 +137,19 @@ async def async_setup_platform(
|
|||||||
discovery_info: DiscoveryInfoType | None = None,
|
discovery_info: DiscoveryInfoType | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the Template weather."""
|
"""Set up the Template weather."""
|
||||||
if discovery_info is None:
|
await async_setup_template_platform(
|
||||||
config = rewrite_common_legacy_to_modern_conf(hass, config)
|
|
||||||
unique_id = config.get(CONF_UNIQUE_ID)
|
|
||||||
async_add_entities(
|
|
||||||
[
|
|
||||||
WeatherTemplate(
|
|
||||||
hass,
|
hass,
|
||||||
|
WEATHER_DOMAIN,
|
||||||
config,
|
config,
|
||||||
unique_id,
|
StateWeatherEntity,
|
||||||
)
|
TriggerWeatherEntity,
|
||||||
]
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
if "coordinator" in discovery_info:
|
|
||||||
async_add_entities(
|
|
||||||
TriggerWeatherEntity(hass, discovery_info["coordinator"], config)
|
|
||||||
for config in discovery_info["entities"]
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
_async_create_template_tracking_entities(
|
|
||||||
async_add_entities,
|
async_add_entities,
|
||||||
hass,
|
discovery_info,
|
||||||
discovery_info["entities"],
|
{},
|
||||||
discovery_info["unique_id"],
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class WeatherTemplate(TemplateEntity, WeatherEntity):
|
class StateWeatherEntity(TemplateEntity, WeatherEntity):
|
||||||
"""Representation of a weather condition."""
|
"""Representation of a weather condition."""
|
||||||
|
|
||||||
_attr_should_poll = False
|
_attr_should_poll = False
|
||||||
|
@ -559,7 +559,7 @@ def setup_mock() -> Generator[Mock]:
|
|||||||
"""Do setup of sensor mock."""
|
"""Do setup of sensor mock."""
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.template.binary_sensor."
|
"homeassistant.components.template.binary_sensor."
|
||||||
"BinarySensorTemplate._update_state"
|
"StateBinarySensorEntity._update_state"
|
||||||
) as _update_state:
|
) as _update_state:
|
||||||
yield _update_state
|
yield _update_state
|
||||||
|
|
||||||
|
344
tests/components/template/test_helpers.py
Normal file
344
tests/components/template/test_helpers.py
Normal file
@ -0,0 +1,344 @@
|
|||||||
|
"""The tests for template helpers."""
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from homeassistant.components.template.alarm_control_panel import (
|
||||||
|
LEGACY_FIELDS as ALARM_CONTROL_PANEL_LEGACY_FIELDS,
|
||||||
|
)
|
||||||
|
from homeassistant.components.template.binary_sensor import (
|
||||||
|
LEGACY_FIELDS as BINARY_SENSOR_LEGACY_FIELDS,
|
||||||
|
)
|
||||||
|
from homeassistant.components.template.button import StateButtonEntity
|
||||||
|
from homeassistant.components.template.cover import LEGACY_FIELDS as COVER_LEGACY_FIELDS
|
||||||
|
from homeassistant.components.template.fan import LEGACY_FIELDS as FAN_LEGACY_FIELDS
|
||||||
|
from homeassistant.components.template.helpers import (
|
||||||
|
async_setup_template_platform,
|
||||||
|
rewrite_legacy_to_modern_config,
|
||||||
|
rewrite_legacy_to_modern_configs,
|
||||||
|
)
|
||||||
|
from homeassistant.components.template.light import LEGACY_FIELDS as LIGHT_LEGACY_FIELDS
|
||||||
|
from homeassistant.components.template.lock import LEGACY_FIELDS as LOCK_LEGACY_FIELDS
|
||||||
|
from homeassistant.components.template.sensor import (
|
||||||
|
LEGACY_FIELDS as SENSOR_LEGACY_FIELDS,
|
||||||
|
)
|
||||||
|
from homeassistant.components.template.switch import (
|
||||||
|
LEGACY_FIELDS as SWITCH_LEGACY_FIELDS,
|
||||||
|
)
|
||||||
|
from homeassistant.components.template.vacuum import (
|
||||||
|
LEGACY_FIELDS as VACUUM_LEGACY_FIELDS,
|
||||||
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.exceptions import PlatformNotReady
|
||||||
|
from homeassistant.helpers.template import Template
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("legacy_fields", "old_attr", "new_attr", "attr_template"),
|
||||||
|
[
|
||||||
|
(
|
||||||
|
LOCK_LEGACY_FIELDS,
|
||||||
|
"value_template",
|
||||||
|
"state",
|
||||||
|
"{{ 1 == 1 }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
LOCK_LEGACY_FIELDS,
|
||||||
|
"code_format_template",
|
||||||
|
"code_format",
|
||||||
|
"{{ 'some format' }}",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_legacy_to_modern_config(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
legacy_fields,
|
||||||
|
old_attr: str,
|
||||||
|
new_attr: str,
|
||||||
|
attr_template: str,
|
||||||
|
) -> None:
|
||||||
|
"""Test the conversion of single legacy template to modern template."""
|
||||||
|
config = {
|
||||||
|
"friendly_name": "foo bar",
|
||||||
|
"unique_id": "foo-bar-entity",
|
||||||
|
"icon_template": "{{ 'mdi.abc' }}",
|
||||||
|
"entity_picture_template": "{{ 'mypicture.jpg' }}",
|
||||||
|
"availability_template": "{{ 1 == 1 }}",
|
||||||
|
old_attr: attr_template,
|
||||||
|
}
|
||||||
|
altered_configs = rewrite_legacy_to_modern_config(hass, config, legacy_fields)
|
||||||
|
|
||||||
|
assert {
|
||||||
|
"availability": Template("{{ 1 == 1 }}", hass),
|
||||||
|
"icon": Template("{{ 'mdi.abc' }}", hass),
|
||||||
|
"name": Template("foo bar", hass),
|
||||||
|
"picture": Template("{{ 'mypicture.jpg' }}", hass),
|
||||||
|
"unique_id": "foo-bar-entity",
|
||||||
|
new_attr: Template(attr_template, hass),
|
||||||
|
} == altered_configs
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("legacy_fields", "old_attr", "new_attr", "attr_template"),
|
||||||
|
[
|
||||||
|
(
|
||||||
|
ALARM_CONTROL_PANEL_LEGACY_FIELDS,
|
||||||
|
"value_template",
|
||||||
|
"state",
|
||||||
|
"{{ 1 == 1 }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
BINARY_SENSOR_LEGACY_FIELDS,
|
||||||
|
"value_template",
|
||||||
|
"state",
|
||||||
|
"{{ 1 == 1 }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
COVER_LEGACY_FIELDS,
|
||||||
|
"value_template",
|
||||||
|
"state",
|
||||||
|
"{{ 1 == 1 }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
COVER_LEGACY_FIELDS,
|
||||||
|
"position_template",
|
||||||
|
"position",
|
||||||
|
"{{ 100 }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
COVER_LEGACY_FIELDS,
|
||||||
|
"tilt_template",
|
||||||
|
"tilt",
|
||||||
|
"{{ 100 }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
FAN_LEGACY_FIELDS,
|
||||||
|
"value_template",
|
||||||
|
"state",
|
||||||
|
"{{ 1 == 1 }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
FAN_LEGACY_FIELDS,
|
||||||
|
"direction_template",
|
||||||
|
"direction",
|
||||||
|
"{{ 1 == 1 }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
FAN_LEGACY_FIELDS,
|
||||||
|
"oscillating_template",
|
||||||
|
"oscillating",
|
||||||
|
"{{ True }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
FAN_LEGACY_FIELDS,
|
||||||
|
"percentage_template",
|
||||||
|
"percentage",
|
||||||
|
"{{ 100 }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
FAN_LEGACY_FIELDS,
|
||||||
|
"preset_mode_template",
|
||||||
|
"preset_mode",
|
||||||
|
"{{ 'foo' }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
LIGHT_LEGACY_FIELDS,
|
||||||
|
"value_template",
|
||||||
|
"state",
|
||||||
|
"{{ 1 == 1 }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
LIGHT_LEGACY_FIELDS,
|
||||||
|
"rgb_template",
|
||||||
|
"rgb",
|
||||||
|
"{{ (255,255,255) }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
LIGHT_LEGACY_FIELDS,
|
||||||
|
"rgbw_template",
|
||||||
|
"rgbw",
|
||||||
|
"{{ (255,255,255,255) }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
LIGHT_LEGACY_FIELDS,
|
||||||
|
"rgbww_template",
|
||||||
|
"rgbww",
|
||||||
|
"{{ (255,255,255,255,255) }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
LIGHT_LEGACY_FIELDS,
|
||||||
|
"effect_list_template",
|
||||||
|
"effect_list",
|
||||||
|
"{{ ['a', 'b'] }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
LIGHT_LEGACY_FIELDS,
|
||||||
|
"effect_template",
|
||||||
|
"effect",
|
||||||
|
"{{ 'a' }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
LIGHT_LEGACY_FIELDS,
|
||||||
|
"level_template",
|
||||||
|
"level",
|
||||||
|
"{{ 255 }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
LIGHT_LEGACY_FIELDS,
|
||||||
|
"max_mireds_template",
|
||||||
|
"max_mireds",
|
||||||
|
"{{ 255 }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
LIGHT_LEGACY_FIELDS,
|
||||||
|
"min_mireds_template",
|
||||||
|
"min_mireds",
|
||||||
|
"{{ 255 }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
LIGHT_LEGACY_FIELDS,
|
||||||
|
"supports_transition_template",
|
||||||
|
"supports_transition",
|
||||||
|
"{{ True }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
LIGHT_LEGACY_FIELDS,
|
||||||
|
"temperature_template",
|
||||||
|
"temperature",
|
||||||
|
"{{ 255 }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
LIGHT_LEGACY_FIELDS,
|
||||||
|
"white_value_template",
|
||||||
|
"white_value",
|
||||||
|
"{{ 255 }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
LIGHT_LEGACY_FIELDS,
|
||||||
|
"hs_template",
|
||||||
|
"hs",
|
||||||
|
"{{ (255, 255) }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
LIGHT_LEGACY_FIELDS,
|
||||||
|
"color_template",
|
||||||
|
"hs",
|
||||||
|
"{{ (255, 255) }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
SENSOR_LEGACY_FIELDS,
|
||||||
|
"value_template",
|
||||||
|
"state",
|
||||||
|
"{{ 1 == 1 }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
SWITCH_LEGACY_FIELDS,
|
||||||
|
"value_template",
|
||||||
|
"state",
|
||||||
|
"{{ 1 == 1 }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
VACUUM_LEGACY_FIELDS,
|
||||||
|
"value_template",
|
||||||
|
"state",
|
||||||
|
"{{ 1 == 1 }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
VACUUM_LEGACY_FIELDS,
|
||||||
|
"battery_level_template",
|
||||||
|
"battery_level",
|
||||||
|
"{{ 100 }}",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
VACUUM_LEGACY_FIELDS,
|
||||||
|
"fan_speed_template",
|
||||||
|
"fan_speed",
|
||||||
|
"{{ 7 }}",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_legacy_to_modern_configs(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
legacy_fields,
|
||||||
|
old_attr: str,
|
||||||
|
new_attr: str,
|
||||||
|
attr_template: str,
|
||||||
|
) -> None:
|
||||||
|
"""Test the conversion of legacy template to modern template."""
|
||||||
|
config = {
|
||||||
|
"foo": {
|
||||||
|
"friendly_name": "foo bar",
|
||||||
|
"unique_id": "foo-bar-entity",
|
||||||
|
"icon_template": "{{ 'mdi.abc' }}",
|
||||||
|
"entity_picture_template": "{{ 'mypicture.jpg' }}",
|
||||||
|
"availability_template": "{{ 1 == 1 }}",
|
||||||
|
old_attr: attr_template,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
altered_configs = rewrite_legacy_to_modern_configs(hass, config, legacy_fields)
|
||||||
|
|
||||||
|
assert len(altered_configs) == 1
|
||||||
|
|
||||||
|
assert [
|
||||||
|
{
|
||||||
|
"availability": Template("{{ 1 == 1 }}", hass),
|
||||||
|
"icon": Template("{{ 'mdi.abc' }}", hass),
|
||||||
|
"name": Template("foo bar", hass),
|
||||||
|
"object_id": "foo",
|
||||||
|
"picture": Template("{{ 'mypicture.jpg' }}", hass),
|
||||||
|
"unique_id": "foo-bar-entity",
|
||||||
|
new_attr: Template(attr_template, hass),
|
||||||
|
}
|
||||||
|
] == altered_configs
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"legacy_fields",
|
||||||
|
[
|
||||||
|
BINARY_SENSOR_LEGACY_FIELDS,
|
||||||
|
SENSOR_LEGACY_FIELDS,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_friendly_name_template_legacy_to_modern_configs(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
legacy_fields,
|
||||||
|
) -> None:
|
||||||
|
"""Test the conversion of friendly_name_tempalte in legacy template to modern template."""
|
||||||
|
config = {
|
||||||
|
"foo": {
|
||||||
|
"unique_id": "foo-bar-entity",
|
||||||
|
"icon_template": "{{ 'mdi.abc' }}",
|
||||||
|
"entity_picture_template": "{{ 'mypicture.jpg' }}",
|
||||||
|
"availability_template": "{{ 1 == 1 }}",
|
||||||
|
"friendly_name_template": "{{ 'foo bar' }}",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
altered_configs = rewrite_legacy_to_modern_configs(hass, config, legacy_fields)
|
||||||
|
|
||||||
|
assert len(altered_configs) == 1
|
||||||
|
|
||||||
|
assert [
|
||||||
|
{
|
||||||
|
"availability": Template("{{ 1 == 1 }}", hass),
|
||||||
|
"icon": Template("{{ 'mdi.abc' }}", hass),
|
||||||
|
"object_id": "foo",
|
||||||
|
"picture": Template("{{ 'mypicture.jpg' }}", hass),
|
||||||
|
"unique_id": "foo-bar-entity",
|
||||||
|
"name": Template("{{ 'foo bar' }}", hass),
|
||||||
|
}
|
||||||
|
] == altered_configs
|
||||||
|
|
||||||
|
|
||||||
|
async def test_platform_not_ready(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
) -> None:
|
||||||
|
"""Test async_setup_template_platform raises PlatformNotReady when trigger object is None."""
|
||||||
|
with pytest.raises(PlatformNotReady):
|
||||||
|
await async_setup_template_platform(
|
||||||
|
hass,
|
||||||
|
"button",
|
||||||
|
{},
|
||||||
|
StateButtonEntity,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
{"coordinator": None, "entities": []},
|
||||||
|
)
|
@ -17,7 +17,6 @@ from homeassistant.components.light import (
|
|||||||
ColorMode,
|
ColorMode,
|
||||||
LightEntityFeature,
|
LightEntityFeature,
|
||||||
)
|
)
|
||||||
from homeassistant.components.template.light import rewrite_legacy_to_modern_conf
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_ENTITY_ID,
|
ATTR_ENTITY_ID,
|
||||||
SERVICE_TURN_OFF,
|
SERVICE_TURN_OFF,
|
||||||
@ -29,7 +28,6 @@ from homeassistant.const import (
|
|||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant, ServiceCall
|
from homeassistant.core import HomeAssistant, ServiceCall
|
||||||
from homeassistant.helpers import entity_registry as er
|
from homeassistant.helpers import entity_registry as er
|
||||||
from homeassistant.helpers.template import Template
|
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from .conftest import ConfigurationStyle
|
from .conftest import ConfigurationStyle
|
||||||
@ -289,127 +287,6 @@ TEST_UNIQUE_ID_CONFIG = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
("old_attr", "new_attr", "attr_template"),
|
|
||||||
[
|
|
||||||
(
|
|
||||||
"value_template",
|
|
||||||
"state",
|
|
||||||
"{{ 1 == 1 }}",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"rgb_template",
|
|
||||||
"rgb",
|
|
||||||
"{{ (255,255,255) }}",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"rgbw_template",
|
|
||||||
"rgbw",
|
|
||||||
"{{ (255,255,255,255) }}",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"rgbww_template",
|
|
||||||
"rgbww",
|
|
||||||
"{{ (255,255,255,255,255) }}",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"effect_list_template",
|
|
||||||
"effect_list",
|
|
||||||
"{{ ['a', 'b'] }}",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"effect_template",
|
|
||||||
"effect",
|
|
||||||
"{{ 'a' }}",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"level_template",
|
|
||||||
"level",
|
|
||||||
"{{ 255 }}",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"max_mireds_template",
|
|
||||||
"max_mireds",
|
|
||||||
"{{ 255 }}",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"min_mireds_template",
|
|
||||||
"min_mireds",
|
|
||||||
"{{ 255 }}",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"supports_transition_template",
|
|
||||||
"supports_transition",
|
|
||||||
"{{ True }}",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"temperature_template",
|
|
||||||
"temperature",
|
|
||||||
"{{ 255 }}",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"white_value_template",
|
|
||||||
"white_value",
|
|
||||||
"{{ 255 }}",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"hs_template",
|
|
||||||
"hs",
|
|
||||||
"{{ (255, 255) }}",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"color_template",
|
|
||||||
"hs",
|
|
||||||
"{{ (255, 255) }}",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
async def test_legacy_to_modern_config(
|
|
||||||
hass: HomeAssistant, old_attr: str, new_attr: str, attr_template: str
|
|
||||||
) -> None:
|
|
||||||
"""Test the conversion of legacy template to modern template."""
|
|
||||||
config = {
|
|
||||||
"foo": {
|
|
||||||
"friendly_name": "foo bar",
|
|
||||||
"unique_id": "foo-bar-light",
|
|
||||||
"icon_template": "{{ 'mdi.abc' }}",
|
|
||||||
"entity_picture_template": "{{ 'mypicture.jpg' }}",
|
|
||||||
"availability_template": "{{ 1 == 1 }}",
|
|
||||||
old_attr: attr_template,
|
|
||||||
**OPTIMISTIC_ON_OFF_LIGHT_CONFIG,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
altered_configs = rewrite_legacy_to_modern_conf(hass, config)
|
|
||||||
|
|
||||||
assert len(altered_configs) == 1
|
|
||||||
|
|
||||||
assert [
|
|
||||||
{
|
|
||||||
"availability": Template("{{ 1 == 1 }}", hass),
|
|
||||||
"icon": Template("{{ 'mdi.abc' }}", hass),
|
|
||||||
"name": Template("foo bar", hass),
|
|
||||||
"object_id": "foo",
|
|
||||||
"picture": Template("{{ 'mypicture.jpg' }}", hass),
|
|
||||||
"turn_off": {
|
|
||||||
"data_template": {
|
|
||||||
"action": "turn_off",
|
|
||||||
"caller": "{{ this.entity_id }}",
|
|
||||||
},
|
|
||||||
"service": "test.automation",
|
|
||||||
},
|
|
||||||
"turn_on": {
|
|
||||||
"data_template": {
|
|
||||||
"action": "turn_on",
|
|
||||||
"caller": "{{ this.entity_id }}",
|
|
||||||
},
|
|
||||||
"service": "test.automation",
|
|
||||||
},
|
|
||||||
"unique_id": "foo-bar-light",
|
|
||||||
new_attr: Template(attr_template, hass),
|
|
||||||
}
|
|
||||||
] == altered_configs
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_legacy_format(
|
async def async_setup_legacy_format(
|
||||||
hass: HomeAssistant, count: int, light_config: dict[str, Any]
|
hass: HomeAssistant, count: int, light_config: dict[str, Any]
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -7,7 +7,6 @@ from syrupy.assertion import SnapshotAssertion
|
|||||||
|
|
||||||
from homeassistant.components import switch, template
|
from homeassistant.components import switch, template
|
||||||
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
||||||
from homeassistant.components.template.switch import rewrite_legacy_to_modern_conf
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_ENTITY_ID,
|
ATTR_ENTITY_ID,
|
||||||
SERVICE_TURN_OFF,
|
SERVICE_TURN_OFF,
|
||||||
@ -18,7 +17,6 @@ from homeassistant.const import (
|
|||||||
)
|
)
|
||||||
from homeassistant.core import CoreState, HomeAssistant, ServiceCall, State
|
from homeassistant.core import CoreState, HomeAssistant, ServiceCall, State
|
||||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||||
from homeassistant.helpers.template import Template
|
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from .conftest import ConfigurationStyle, async_get_flow_preview_state
|
from .conftest import ConfigurationStyle, async_get_flow_preview_state
|
||||||
@ -306,37 +304,6 @@ async def setup_single_attribute_optimistic_switch(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_legacy_to_modern_config(hass: HomeAssistant) -> None:
|
|
||||||
"""Test the conversion of legacy template to modern template."""
|
|
||||||
config = {
|
|
||||||
"foo": {
|
|
||||||
"friendly_name": "foo bar",
|
|
||||||
"value_template": "{{ 1 == 1 }}",
|
|
||||||
"unique_id": "foo-bar-switch",
|
|
||||||
"icon_template": "{{ 'mdi.abc' }}",
|
|
||||||
"entity_picture_template": "{{ 'mypicture.jpg' }}",
|
|
||||||
"availability_template": "{{ 1 == 1 }}",
|
|
||||||
**SWITCH_ACTIONS,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
altered_configs = rewrite_legacy_to_modern_conf(hass, config)
|
|
||||||
|
|
||||||
assert len(altered_configs) == 1
|
|
||||||
assert [
|
|
||||||
{
|
|
||||||
"availability": Template("{{ 1 == 1 }}", hass),
|
|
||||||
"icon": Template("{{ 'mdi.abc' }}", hass),
|
|
||||||
"name": Template("foo bar", hass),
|
|
||||||
"object_id": "foo",
|
|
||||||
"picture": Template("{{ 'mypicture.jpg' }}", hass),
|
|
||||||
"turn_off": SWITCH_TURN_OFF,
|
|
||||||
"turn_on": SWITCH_TURN_ON,
|
|
||||||
"unique_id": "foo-bar-switch",
|
|
||||||
"state": Template("{{ 1 == 1 }}", hass),
|
|
||||||
}
|
|
||||||
] == altered_configs
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(("count", "state_template"), [(1, "{{ True }}")])
|
@pytest.mark.parametrize(("count", "state_template"), [(1, "{{ True }}")])
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"style",
|
"style",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user