Minor refactor of template cover (#59537)

This commit is contained in:
Erik Montnemery 2021-12-02 19:26:10 +01:00 committed by GitHub
parent 824e5ed6b8
commit a67a4873dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 104 additions and 104 deletions

View file

@ -46,7 +46,11 @@ from .const import (
CONF_OBJECT_ID, CONF_OBJECT_ID,
CONF_PICTURE, CONF_PICTURE,
) )
from .template_entity import TEMPLATE_ENTITY_COMMON_SCHEMA, TemplateEntity 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"
@ -106,14 +110,7 @@ def rewrite_legacy_to_modern_conf(cfg: dict[str, dict]) -> list[dict]:
for object_id, entity_cfg in cfg.items(): for object_id, entity_cfg in cfg.items():
entity_cfg = {**entity_cfg, CONF_OBJECT_ID: object_id} entity_cfg = {**entity_cfg, CONF_OBJECT_ID: object_id}
for from_key, to_key in LEGACY_FIELDS.items(): entity_cfg = rewrite_common_legacy_to_modern_conf(entity_cfg, LEGACY_FIELDS)
if from_key not in entity_cfg or to_key in entity_cfg:
continue
val = entity_cfg.pop(from_key)
if isinstance(val, str):
val = template.Template(val)
entity_cfg[to_key] = val
if CONF_NAME not in entity_cfg: if CONF_NAME not in entity_cfg:
entity_cfg[CONF_NAME] = template.Template(object_id) entity_cfg[CONF_NAME] = template.Template(object_id)

View file

@ -25,5 +25,6 @@ PLATFORMS = [
CONF_AVAILABILITY = "availability" CONF_AVAILABILITY = "availability"
CONF_ATTRIBUTES = "attributes" CONF_ATTRIBUTES = "attributes"
CONF_ATTRIBUTE_TEMPLATES = "attribute_templates"
CONF_PICTURE = "picture" CONF_PICTURE = "picture"
CONF_OBJECT_ID = "object_id" CONF_OBJECT_ID = "object_id"

View file

@ -23,9 +23,7 @@ from homeassistant.const import (
CONF_COVERS, CONF_COVERS,
CONF_DEVICE_CLASS, CONF_DEVICE_CLASS,
CONF_ENTITY_ID, CONF_ENTITY_ID,
CONF_ENTITY_PICTURE_TEMPLATE,
CONF_FRIENDLY_NAME, CONF_FRIENDLY_NAME,
CONF_ICON_TEMPLATE,
CONF_OPTIMISTIC, CONF_OPTIMISTIC,
CONF_UNIQUE_ID, CONF_UNIQUE_ID,
CONF_VALUE_TEMPLATE, CONF_VALUE_TEMPLATE,
@ -40,8 +38,12 @@ import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import async_generate_entity_id from homeassistant.helpers.entity import async_generate_entity_id
from homeassistant.helpers.script import Script from homeassistant.helpers.script import Script
from .const import CONF_AVAILABILITY_TEMPLATE, DOMAIN from .const import DOMAIN
from .template_entity import TemplateEntity from .template_entity import (
TEMPLATE_ENTITY_COMMON_SCHEMA_LEGACY,
TemplateEntity,
rewrite_common_legacy_to_modern_conf,
)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
_VALID_STATES = [ _VALID_STATES = [
@ -79,11 +81,8 @@ COVER_SCHEMA = vol.All(
vol.Inclusive(CLOSE_ACTION, CONF_OPEN_AND_CLOSE): cv.SCRIPT_SCHEMA, vol.Inclusive(CLOSE_ACTION, CONF_OPEN_AND_CLOSE): cv.SCRIPT_SCHEMA,
vol.Optional(STOP_ACTION): cv.SCRIPT_SCHEMA, vol.Optional(STOP_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_AVAILABILITY_TEMPLATE): cv.template,
vol.Optional(CONF_POSITION_TEMPLATE): cv.template, vol.Optional(CONF_POSITION_TEMPLATE): cv.template,
vol.Optional(CONF_TILT_TEMPLATE): cv.template, vol.Optional(CONF_TILT_TEMPLATE): cv.template,
vol.Optional(CONF_ICON_TEMPLATE): cv.template,
vol.Optional(CONF_ENTITY_PICTURE_TEMPLATE): cv.template,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA, vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_OPTIMISTIC): cv.boolean, vol.Optional(CONF_OPTIMISTIC): cv.boolean,
vol.Optional(CONF_TILT_OPTIMISTIC): cv.boolean, vol.Optional(CONF_TILT_OPTIMISTIC): cv.boolean,
@ -93,7 +92,7 @@ COVER_SCHEMA = vol.All(
vol.Optional(CONF_ENTITY_ID): cv.entity_ids, vol.Optional(CONF_ENTITY_ID): cv.entity_ids,
vol.Optional(CONF_UNIQUE_ID): cv.string, vol.Optional(CONF_UNIQUE_ID): cv.string,
} }
), ).extend(TEMPLATE_ENTITY_COMMON_SCHEMA_LEGACY.schema),
cv.has_at_least_one_key(OPEN_ACTION, POSITION_ACTION), cv.has_at_least_one_key(OPEN_ACTION, POSITION_ACTION),
) )
@ -106,44 +105,17 @@ async def _async_create_entities(hass, config):
"""Create the Template cover.""" """Create the Template cover."""
covers = [] covers = []
for device, device_config in config[CONF_COVERS].items(): for object_id, entity_config in config[CONF_COVERS].items():
state_template = device_config.get(CONF_VALUE_TEMPLATE)
position_template = device_config.get(CONF_POSITION_TEMPLATE)
tilt_template = device_config.get(CONF_TILT_TEMPLATE)
icon_template = device_config.get(CONF_ICON_TEMPLATE)
availability_template = device_config.get(CONF_AVAILABILITY_TEMPLATE)
entity_picture_template = device_config.get(CONF_ENTITY_PICTURE_TEMPLATE)
friendly_name = device_config.get(CONF_FRIENDLY_NAME, device) entity_config = rewrite_common_legacy_to_modern_conf(entity_config)
device_class = device_config.get(CONF_DEVICE_CLASS)
open_action = device_config.get(OPEN_ACTION) unique_id = entity_config.get(CONF_UNIQUE_ID)
close_action = device_config.get(CLOSE_ACTION)
stop_action = device_config.get(STOP_ACTION)
position_action = device_config.get(POSITION_ACTION)
tilt_action = device_config.get(TILT_ACTION)
optimistic = device_config.get(CONF_OPTIMISTIC)
tilt_optimistic = device_config.get(CONF_TILT_OPTIMISTIC)
unique_id = device_config.get(CONF_UNIQUE_ID)
covers.append( covers.append(
CoverTemplate( CoverTemplate(
hass, hass,
device, object_id,
friendly_name, entity_config,
device_class,
state_template,
position_template,
tilt_template,
icon_template,
entity_picture_template,
availability_template,
open_action,
close_action,
stop_action,
position_action,
tilt_action,
optimistic,
tilt_optimistic,
unique_id, unique_id,
) )
) )
@ -162,55 +134,41 @@ class CoverTemplate(TemplateEntity, CoverEntity):
def __init__( def __init__(
self, self,
hass, hass,
device_id, object_id,
friendly_name, config,
device_class,
state_template,
position_template,
tilt_template,
icon_template,
entity_picture_template,
availability_template,
open_action,
close_action,
stop_action,
position_action,
tilt_action,
optimistic,
tilt_optimistic,
unique_id, unique_id,
): ):
"""Initialize the Template cover.""" """Initialize the Template cover."""
super().__init__( super().__init__(config=config)
availability_template=availability_template,
icon_template=icon_template,
entity_picture_template=entity_picture_template,
)
self.entity_id = async_generate_entity_id( self.entity_id = async_generate_entity_id(
ENTITY_ID_FORMAT, device_id, hass=hass ENTITY_ID_FORMAT, object_id, hass=hass
) )
self._name = friendly_name self._name = friendly_name = config.get(CONF_FRIENDLY_NAME, object_id)
self._template = state_template self._template = config.get(CONF_VALUE_TEMPLATE)
self._position_template = position_template self._position_template = config.get(CONF_POSITION_TEMPLATE)
self._tilt_template = tilt_template self._tilt_template = config.get(CONF_TILT_TEMPLATE)
self._device_class = device_class self._device_class = config.get(CONF_DEVICE_CLASS)
self._open_script = None self._open_script = None
if open_action is not None: if (open_action := config.get(OPEN_ACTION)) is not None:
self._open_script = Script(hass, open_action, friendly_name, DOMAIN) self._open_script = Script(hass, open_action, friendly_name, DOMAIN)
self._close_script = None self._close_script = None
if close_action is not None: if (close_action := config.get(CLOSE_ACTION)) is not None:
self._close_script = Script(hass, close_action, friendly_name, DOMAIN) self._close_script = Script(hass, close_action, friendly_name, DOMAIN)
self._stop_script = None self._stop_script = None
if stop_action is not None: if (stop_action := config.get(STOP_ACTION)) is not None:
self._stop_script = Script(hass, stop_action, friendly_name, DOMAIN) self._stop_script = Script(hass, stop_action, friendly_name, DOMAIN)
self._position_script = None self._position_script = None
if position_action is not None: if (position_action := config.get(POSITION_ACTION)) is not None:
self._position_script = Script(hass, position_action, friendly_name, DOMAIN) self._position_script = Script(hass, position_action, friendly_name, DOMAIN)
self._tilt_script = None self._tilt_script = None
if tilt_action is not None: if (tilt_action := config.get(TILT_ACTION)) is not None:
self._tilt_script = Script(hass, tilt_action, friendly_name, DOMAIN) self._tilt_script = Script(hass, tilt_action, friendly_name, DOMAIN)
self._optimistic = optimistic or (not state_template and not position_template) optimistic = config.get(CONF_OPTIMISTIC)
self._tilt_optimistic = tilt_optimistic or not tilt_template self._optimistic = optimistic or (
not self._template and not self._position_template
)
tilt_optimistic = config.get(CONF_TILT_OPTIMISTIC)
self._tilt_optimistic = tilt_optimistic or not self._tilt_template
self._position = None self._position = None
self._is_opening = False self._is_opening = False
self._is_closing = False self._is_closing = False

View file

@ -20,7 +20,6 @@ from homeassistant.const import (
CONF_ENTITY_PICTURE_TEMPLATE, CONF_ENTITY_PICTURE_TEMPLATE,
CONF_FRIENDLY_NAME, 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,
@ -36,21 +35,18 @@ from homeassistant.helpers.entity import async_generate_entity_id
from .const import ( from .const import (
CONF_ATTRIBUTE_TEMPLATES, CONF_ATTRIBUTE_TEMPLATES,
CONF_ATTRIBUTES,
CONF_AVAILABILITY,
CONF_AVAILABILITY_TEMPLATE, CONF_AVAILABILITY_TEMPLATE,
CONF_OBJECT_ID, CONF_OBJECT_ID,
CONF_PICTURE,
CONF_TRIGGER, CONF_TRIGGER,
) )
from .template_entity import TEMPLATE_ENTITY_COMMON_SCHEMA, TemplateEntity 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
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_FRIENDLY_NAME: CONF_NAME,
CONF_VALUE_TEMPLATE: CONF_STATE, CONF_VALUE_TEMPLATE: CONF_STATE,
@ -106,20 +102,13 @@ def extra_validation_checks(val):
def rewrite_legacy_to_modern_conf(cfg: dict[str, dict]) -> list[dict]: def rewrite_legacy_to_modern_conf(cfg: dict[str, dict]) -> list[dict]:
"""Rewrite a legacy sensor definitions to modern ones.""" """Rewrite legacy sensor definitions to modern ones."""
sensors = [] sensors = []
for object_id, entity_cfg in cfg.items(): for object_id, entity_cfg in cfg.items():
entity_cfg = {**entity_cfg, CONF_OBJECT_ID: object_id} entity_cfg = {**entity_cfg, CONF_OBJECT_ID: object_id}
for from_key, to_key in LEGACY_FIELDS.items(): entity_cfg = rewrite_common_legacy_to_modern_conf(entity_cfg, LEGACY_FIELDS)
if from_key not in entity_cfg or to_key in entity_cfg:
continue
val = entity_cfg.pop(from_key)
if isinstance(val, str):
val = template.Template(val)
entity_cfg[to_key] = val
if CONF_NAME not in entity_cfg: if CONF_NAME not in entity_cfg:
entity_cfg[CONF_NAME] = template.Template(object_id) entity_cfg[CONF_NAME] = template.Template(object_id)

View file

@ -2,12 +2,18 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Callable from collections.abc import Callable
import itertools
import logging import logging
from typing import Any from typing import Any
import voluptuous as vol import voluptuous as vol
from homeassistant.const import ATTR_ENTITY_ID, CONF_ICON from homeassistant.const import (
ATTR_ENTITY_ID,
CONF_ENTITY_PICTURE_TEMPLATE,
CONF_ICON,
CONF_ICON_TEMPLATE,
)
from homeassistant.core import EVENT_HOMEASSISTANT_START, CoreState, callback from homeassistant.core import EVENT_HOMEASSISTANT_START, CoreState, callback
from homeassistant.exceptions import TemplateError from homeassistant.exceptions import TemplateError
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
@ -20,7 +26,13 @@ from homeassistant.helpers.event import (
) )
from homeassistant.helpers.template import Template, result_as_boolean from homeassistant.helpers.template import Template, result_as_boolean
from .const import CONF_ATTRIBUTES, CONF_AVAILABILITY, CONF_PICTURE from .const import (
CONF_ATTRIBUTE_TEMPLATES,
CONF_ATTRIBUTES,
CONF_AVAILABILITY,
CONF_AVAILABILITY_TEMPLATE,
CONF_PICTURE,
)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -34,6 +46,49 @@ TEMPLATE_ENTITY_COMMON_SCHEMA = vol.Schema(
} }
) )
TEMPLATE_ENTITY_AVAILABILITY_SCHEMA_LEGACY = vol.Schema(
{
vol.Optional(CONF_AVAILABILITY_TEMPLATE): cv.template,
}
)
TEMPLATE_ENTITY_COMMON_SCHEMA_LEGACY = vol.Schema(
{
vol.Optional(CONF_ENTITY_PICTURE_TEMPLATE): cv.template,
vol.Optional(CONF_ICON_TEMPLATE): cv.template,
}
).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,
}
def rewrite_common_legacy_to_modern_conf(
entity_cfg: dict[str, Any], extra_legacy_fields: dict[str, str] = None
) -> list[dict]:
"""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)
entity_cfg[to_key] = val
return entity_cfg
class _TemplateAttribute: class _TemplateAttribute:
"""Attribute value linked to template result.""" """Attribute value linked to template result."""