Simplify template integration entities (#39083)
parent
5a9246468e
commit
796d74886e
|
@ -189,20 +189,20 @@ class AlarmControlPanelTemplate(TemplateEntity, AlarmControlPanelEntity):
|
||||||
return self._code_arm_required
|
return self._code_arm_required
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def _update_state(self, state):
|
def _update_state(self, result):
|
||||||
if isinstance(state, TemplateError):
|
if isinstance(result, TemplateError):
|
||||||
self._state = None
|
self._state = None
|
||||||
return
|
return
|
||||||
|
|
||||||
# Validate state
|
# Validate state
|
||||||
if state in _VALID_STATES:
|
if result in _VALID_STATES:
|
||||||
self._state = state
|
self._state = result
|
||||||
_LOGGER.debug("Valid state - %s", state)
|
_LOGGER.debug("Valid state - %s", result)
|
||||||
return
|
return
|
||||||
|
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
"Received invalid alarm panel state: %s. Expected: %s",
|
"Received invalid alarm panel state: %s. Expected: %s",
|
||||||
state,
|
result,
|
||||||
", ".join(_VALID_STATES),
|
", ".join(_VALID_STATES),
|
||||||
)
|
)
|
||||||
self._state = None
|
self._state = None
|
||||||
|
|
|
@ -27,7 +27,7 @@ from homeassistant.helpers.event import async_call_later
|
||||||
from homeassistant.helpers.template import result_as_boolean
|
from homeassistant.helpers.template import result_as_boolean
|
||||||
|
|
||||||
from .const import CONF_AVAILABILITY_TEMPLATE
|
from .const import CONF_AVAILABILITY_TEMPLATE
|
||||||
from .template_entity import TemplateEntityWithAttributesAvailabilityAndImages
|
from .template_entity import TemplateEntity
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -93,9 +93,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
||||||
async_add_entities(sensors)
|
async_add_entities(sensors)
|
||||||
|
|
||||||
|
|
||||||
class BinarySensorTemplate(
|
class BinarySensorTemplate(TemplateEntity, BinarySensorEntity):
|
||||||
TemplateEntityWithAttributesAvailabilityAndImages, BinarySensorEntity
|
|
||||||
):
|
|
||||||
"""A virtual binary sensor that triggers from another sensor."""
|
"""A virtual binary sensor that triggers from another sensor."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -115,10 +113,10 @@ class BinarySensorTemplate(
|
||||||
):
|
):
|
||||||
"""Initialize the Template binary sensor."""
|
"""Initialize the Template binary sensor."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
attribute_templates,
|
attribute_templates=attribute_templates,
|
||||||
availability_template,
|
availability_template=availability_template,
|
||||||
icon_template,
|
icon_template=icon_template,
|
||||||
entity_picture_template,
|
entity_picture_template=entity_picture_template,
|
||||||
)
|
)
|
||||||
self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, device, hass=hass)
|
self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, device, hass=hass)
|
||||||
self._name = friendly_name
|
self._name = friendly_name
|
||||||
|
|
|
@ -38,7 +38,7 @@ 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
|
from .const import CONF_AVAILABILITY_TEMPLATE
|
||||||
from .template_entity import TemplateEntityWithAvailabilityAndImages
|
from .template_entity import TemplateEntity
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
_VALID_STATES = [STATE_OPEN, STATE_CLOSED, "true", "false"]
|
_VALID_STATES = [STATE_OPEN, STATE_CLOSED, "true", "false"]
|
||||||
|
@ -148,7 +148,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
||||||
async_add_entities(covers)
|
async_add_entities(covers)
|
||||||
|
|
||||||
|
|
||||||
class CoverTemplate(TemplateEntityWithAvailabilityAndImages, CoverEntity):
|
class CoverTemplate(TemplateEntity, CoverEntity):
|
||||||
"""Representation of a Template cover."""
|
"""Representation of a Template cover."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -174,7 +174,9 @@ class CoverTemplate(TemplateEntityWithAvailabilityAndImages, CoverEntity):
|
||||||
):
|
):
|
||||||
"""Initialize the Template cover."""
|
"""Initialize the Template cover."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
availability_template, icon_template, entity_picture_template,
|
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, device_id, hass=hass
|
||||||
|
|
|
@ -35,7 +35,7 @@ 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
|
from .const import CONF_AVAILABILITY_TEMPLATE
|
||||||
from .template_entity import TemplateEntityWithAvailability
|
from .template_entity import TemplateEntity
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
||||||
async_add_entities(fans)
|
async_add_entities(fans)
|
||||||
|
|
||||||
|
|
||||||
class TemplateFan(TemplateEntityWithAvailability, FanEntity):
|
class TemplateFan(TemplateEntity, FanEntity):
|
||||||
"""A template fan component."""
|
"""A template fan component."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -147,7 +147,7 @@ class TemplateFan(TemplateEntityWithAvailability, FanEntity):
|
||||||
unique_id,
|
unique_id,
|
||||||
):
|
):
|
||||||
"""Initialize the fan."""
|
"""Initialize the fan."""
|
||||||
super().__init__(availability_template)
|
super().__init__(availability_template=availability_template)
|
||||||
self.hass = hass
|
self.hass = hass
|
||||||
self.entity_id = async_generate_entity_id(
|
self.entity_id = async_generate_entity_id(
|
||||||
ENTITY_ID_FORMAT, device_id, hass=hass
|
ENTITY_ID_FORMAT, device_id, hass=hass
|
||||||
|
|
|
@ -34,7 +34,7 @@ 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
|
from .const import CONF_AVAILABILITY_TEMPLATE
|
||||||
from .template_entity import TemplateEntityWithAvailabilityAndImages
|
from .template_entity import TemplateEntity
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
_VALID_STATES = [STATE_ON, STATE_OFF, "true", "false"]
|
_VALID_STATES = [STATE_ON, STATE_OFF, "true", "false"]
|
||||||
|
@ -131,7 +131,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
||||||
async_add_entities(lights)
|
async_add_entities(lights)
|
||||||
|
|
||||||
|
|
||||||
class LightTemplate(TemplateEntityWithAvailabilityAndImages, LightEntity):
|
class LightTemplate(TemplateEntity, LightEntity):
|
||||||
"""Representation of a templated Light, including dimmable."""
|
"""Representation of a templated Light, including dimmable."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -157,7 +157,9 @@ class LightTemplate(TemplateEntityWithAvailabilityAndImages, LightEntity):
|
||||||
):
|
):
|
||||||
"""Initialize the light."""
|
"""Initialize the light."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
availability_template, icon_template, entity_picture_template,
|
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, device_id, hass=hass
|
||||||
|
|
|
@ -18,7 +18,7 @@ import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.helpers.script import Script
|
from homeassistant.helpers.script import Script
|
||||||
|
|
||||||
from .const import CONF_AVAILABILITY_TEMPLATE
|
from .const import CONF_AVAILABILITY_TEMPLATE
|
||||||
from .template_entity import TemplateEntityWithAvailability
|
from .template_entity import TemplateEntity
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ async def async_setup_platform(hass, config, async_add_devices, discovery_info=N
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TemplateLock(TemplateEntityWithAvailability, LockEntity):
|
class TemplateLock(TemplateEntity, LockEntity):
|
||||||
"""Representation of a template lock."""
|
"""Representation of a template lock."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -78,7 +78,7 @@ class TemplateLock(TemplateEntityWithAvailability, LockEntity):
|
||||||
unique_id,
|
unique_id,
|
||||||
):
|
):
|
||||||
"""Initialize the lock."""
|
"""Initialize the lock."""
|
||||||
super().__init__(availability_template)
|
super().__init__(availability_template=availability_template)
|
||||||
self._state = None
|
self._state = None
|
||||||
self._name = name
|
self._name = name
|
||||||
self._state_template = value_template
|
self._state_template = value_template
|
||||||
|
|
|
@ -27,7 +27,7 @@ import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.helpers.entity import Entity, async_generate_entity_id
|
from homeassistant.helpers.entity import Entity, async_generate_entity_id
|
||||||
|
|
||||||
from .const import CONF_AVAILABILITY_TEMPLATE
|
from .const import CONF_AVAILABILITY_TEMPLATE
|
||||||
from .template_entity import TemplateEntityWithAttributesAvailabilityAndImages
|
from .template_entity import TemplateEntity
|
||||||
|
|
||||||
CONF_ATTRIBUTE_TEMPLATES = "attribute_templates"
|
CONF_ATTRIBUTE_TEMPLATES = "attribute_templates"
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class SensorTemplate(TemplateEntityWithAttributesAvailabilityAndImages, Entity):
|
class SensorTemplate(TemplateEntity, Entity):
|
||||||
"""Representation of a Template Sensor."""
|
"""Representation of a Template Sensor."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -114,10 +114,10 @@ class SensorTemplate(TemplateEntityWithAttributesAvailabilityAndImages, Entity):
|
||||||
):
|
):
|
||||||
"""Initialize the sensor."""
|
"""Initialize the sensor."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
attribute_templates,
|
attribute_templates=attribute_templates,
|
||||||
availability_template,
|
availability_template=availability_template,
|
||||||
icon_template,
|
icon_template=icon_template,
|
||||||
entity_picture_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, device_id, hass=hass
|
||||||
|
|
|
@ -27,7 +27,7 @@ from homeassistant.helpers.restore_state import RestoreEntity
|
||||||
from homeassistant.helpers.script import Script
|
from homeassistant.helpers.script import Script
|
||||||
|
|
||||||
from .const import CONF_AVAILABILITY_TEMPLATE
|
from .const import CONF_AVAILABILITY_TEMPLATE
|
||||||
from .template_entity import TemplateEntityWithAvailabilityAndImages
|
from .template_entity import TemplateEntity
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
_VALID_STATES = [STATE_ON, STATE_OFF, "true", "false"]
|
_VALID_STATES = [STATE_ON, STATE_OFF, "true", "false"]
|
||||||
|
@ -86,9 +86,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
||||||
async_add_entities(switches)
|
async_add_entities(switches)
|
||||||
|
|
||||||
|
|
||||||
class SwitchTemplate(
|
class SwitchTemplate(TemplateEntity, SwitchEntity, RestoreEntity):
|
||||||
TemplateEntityWithAvailabilityAndImages, SwitchEntity, RestoreEntity
|
|
||||||
):
|
|
||||||
"""Representation of a Template switch."""
|
"""Representation of a Template switch."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -105,7 +103,11 @@ class SwitchTemplate(
|
||||||
unique_id,
|
unique_id,
|
||||||
):
|
):
|
||||||
"""Initialize the Template switch."""
|
"""Initialize the Template switch."""
|
||||||
super().__init__(availability_template, icon_template, entity_picture_template)
|
super().__init__(
|
||||||
|
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, device_id, hass=hass
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,7 +8,6 @@ import voluptuous as vol
|
||||||
from homeassistant.core import EVENT_HOMEASSISTANT_START, callback
|
from homeassistant.core import EVENT_HOMEASSISTANT_START, 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
|
||||||
from homeassistant.helpers.config_validation import match_all
|
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
from homeassistant.helpers.event import Event, async_track_template_result
|
from homeassistant.helpers.event import Event, async_track_template_result
|
||||||
from homeassistant.helpers.template import Template, result_as_boolean
|
from homeassistant.helpers.template import Template, result_as_boolean
|
||||||
|
@ -24,7 +23,7 @@ class _TemplateAttribute:
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
attribute: str,
|
attribute: str,
|
||||||
template: Template,
|
template: Template,
|
||||||
validator: Callable[[Any], Any] = match_all,
|
validator: Callable[[Any], Any] = None,
|
||||||
on_update: Optional[Callable[[Any], None]] = None,
|
on_update: Optional[Callable[[Any], None]] = None,
|
||||||
none_on_template_error: Optional[bool] = False,
|
none_on_template_error: Optional[bool] = False,
|
||||||
):
|
):
|
||||||
|
@ -130,20 +129,82 @@ class _TemplateAttribute:
|
||||||
class TemplateEntity(Entity):
|
class TemplateEntity(Entity):
|
||||||
"""Entity that uses templates to calculate attributes."""
|
"""Entity that uses templates to calculate attributes."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
availability_template=None,
|
||||||
|
icon_template=None,
|
||||||
|
entity_picture_template=None,
|
||||||
|
attribute_templates=None,
|
||||||
|
):
|
||||||
"""Template Entity."""
|
"""Template Entity."""
|
||||||
self._template_attrs = []
|
self._template_attrs = []
|
||||||
|
self._attribute_templates = attribute_templates
|
||||||
|
self._attributes = {}
|
||||||
|
self._availability_template = availability_template
|
||||||
|
self._available = True
|
||||||
|
self._icon_template = icon_template
|
||||||
|
self._entity_picture_template = entity_picture_template
|
||||||
|
self._icon = None
|
||||||
|
self._entity_picture = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def should_poll(self):
|
def should_poll(self):
|
||||||
"""No polling needed."""
|
"""No polling needed."""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _update_available(self, result):
|
||||||
|
if isinstance(result, TemplateError):
|
||||||
|
self._available = True
|
||||||
|
return
|
||||||
|
|
||||||
|
self._available = result_as_boolean(result)
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _update_state(self, result):
|
||||||
|
if self._availability_template:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._available = not isinstance(result, TemplateError)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available(self) -> bool:
|
||||||
|
"""Return if the device is available."""
|
||||||
|
return self._available
|
||||||
|
|
||||||
|
@property
|
||||||
|
def icon(self):
|
||||||
|
"""Return the icon to use in the frontend, if any."""
|
||||||
|
return self._icon
|
||||||
|
|
||||||
|
@property
|
||||||
|
def entity_picture(self):
|
||||||
|
"""Return the entity_picture to use in the frontend, if any."""
|
||||||
|
return self._entity_picture
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_state_attributes(self):
|
||||||
|
"""Return the state attributes."""
|
||||||
|
return self._attributes
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _add_attribute_template(self, attribute_key, attribute_template):
|
||||||
|
"""Create a template tracker for the attribute."""
|
||||||
|
|
||||||
|
def _update_attribute(result):
|
||||||
|
attr_result = None if isinstance(result, TemplateError) else result
|
||||||
|
self._attributes[attribute_key] = attr_result
|
||||||
|
|
||||||
|
self.add_template_attribute(
|
||||||
|
attribute_key, attribute_template, None, _update_attribute
|
||||||
|
)
|
||||||
|
|
||||||
def add_template_attribute(
|
def add_template_attribute(
|
||||||
self,
|
self,
|
||||||
attribute: str,
|
attribute: str,
|
||||||
template: Template,
|
template: Template,
|
||||||
validator: Callable[[Any], Any] = match_all,
|
validator: Callable[[Any], Any] = None,
|
||||||
on_update: Optional[Callable[[Any], None]] = None,
|
on_update: Optional[Callable[[Any], None]] = None,
|
||||||
none_on_template_error: bool = False,
|
none_on_template_error: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -183,79 +244,13 @@ class TemplateEntity(Entity):
|
||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
"""Run when entity about to be added to hass."""
|
"""Run when entity about to be added to hass."""
|
||||||
self.hass.bus.async_listen_once(
|
|
||||||
EVENT_HOMEASSISTANT_START, self._async_template_startup
|
|
||||||
)
|
|
||||||
|
|
||||||
async def async_update(self) -> None:
|
|
||||||
"""Call for forced update."""
|
|
||||||
for attribute in self._template_attrs:
|
|
||||||
if attribute.async_update:
|
|
||||||
attribute.async_update()
|
|
||||||
|
|
||||||
|
|
||||||
class TemplateEntityWithAvailability(TemplateEntity):
|
|
||||||
"""Entity that uses templates to calculate attributes with an availability template."""
|
|
||||||
|
|
||||||
def __init__(self, availability_template):
|
|
||||||
"""Template Entity."""
|
|
||||||
self._availability_template = availability_template
|
|
||||||
self._available = True
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def _update_available(self, result):
|
|
||||||
if isinstance(result, TemplateError):
|
|
||||||
self._available = True
|
|
||||||
return
|
|
||||||
|
|
||||||
self._available = result_as_boolean(result)
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def _update_state(self, result):
|
|
||||||
if self._availability_template:
|
|
||||||
return
|
|
||||||
|
|
||||||
self._available = not isinstance(result, TemplateError)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def available(self) -> bool:
|
|
||||||
"""Return if the device is available."""
|
|
||||||
return self._available
|
|
||||||
|
|
||||||
async def async_added_to_hass(self):
|
|
||||||
"""Register callbacks."""
|
|
||||||
if self._availability_template is not None:
|
if self._availability_template is not None:
|
||||||
self.add_template_attribute(
|
self.add_template_attribute(
|
||||||
"_available", self._availability_template, None, self._update_available
|
"_available", self._availability_template, None, self._update_available
|
||||||
)
|
)
|
||||||
|
if self._attribute_templates is not None:
|
||||||
await super().async_added_to_hass()
|
for key, value in self._attribute_templates.items():
|
||||||
|
self._add_attribute_template(key, value)
|
||||||
|
|
||||||
class TemplateEntityWithAvailabilityAndImages(TemplateEntityWithAvailability):
|
|
||||||
"""Entity that uses templates to calculate attributes with an availability, icon, and images template."""
|
|
||||||
|
|
||||||
def __init__(self, availability_template, icon_template, entity_picture_template):
|
|
||||||
"""Template Entity."""
|
|
||||||
self._icon_template = icon_template
|
|
||||||
self._entity_picture_template = entity_picture_template
|
|
||||||
self._icon = None
|
|
||||||
self._entity_picture = None
|
|
||||||
super().__init__(availability_template)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def icon(self):
|
|
||||||
"""Return the icon to use in the frontend, if any."""
|
|
||||||
return self._icon
|
|
||||||
|
|
||||||
@property
|
|
||||||
def entity_picture(self):
|
|
||||||
"""Return the entity_picture to use in the frontend, if any."""
|
|
||||||
return self._entity_picture
|
|
||||||
|
|
||||||
async def async_added_to_hass(self):
|
|
||||||
"""Register callbacks."""
|
|
||||||
if self._icon_template is not None:
|
if self._icon_template is not None:
|
||||||
self.add_template_attribute(
|
self.add_template_attribute(
|
||||||
"_icon", self._icon_template, vol.Or(cv.whitespace, cv.icon)
|
"_icon", self._icon_template, vol.Or(cv.whitespace, cv.icon)
|
||||||
|
@ -265,47 +260,12 @@ class TemplateEntityWithAvailabilityAndImages(TemplateEntityWithAvailability):
|
||||||
"_entity_picture", self._entity_picture_template
|
"_entity_picture", self._entity_picture_template
|
||||||
)
|
)
|
||||||
|
|
||||||
await super().async_added_to_hass()
|
self.hass.bus.async_listen_once(
|
||||||
|
EVENT_HOMEASSISTANT_START, self._async_template_startup
|
||||||
|
|
||||||
class TemplateEntityWithAttributesAvailabilityAndImages(
|
|
||||||
TemplateEntityWithAvailabilityAndImages
|
|
||||||
):
|
|
||||||
"""Entity that uses templates to calculate attributes with an attributes, availability, icon, and images template."""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
attribute_templates,
|
|
||||||
availability_template,
|
|
||||||
icon_template,
|
|
||||||
entity_picture_template,
|
|
||||||
):
|
|
||||||
"""Template Entity."""
|
|
||||||
super().__init__(availability_template, icon_template, entity_picture_template)
|
|
||||||
self._attribute_templates = attribute_templates
|
|
||||||
self._attributes = {}
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def _add_attribute_template(self, attribute_key, attribute_template):
|
|
||||||
"""Create a template tracker for the attribute."""
|
|
||||||
|
|
||||||
def _update_attribute(result):
|
|
||||||
attr_result = None if isinstance(result, TemplateError) else result
|
|
||||||
self._attributes[attribute_key] = attr_result
|
|
||||||
|
|
||||||
self.add_template_attribute(
|
|
||||||
attribute_key, attribute_template, None, _update_attribute
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
async def async_update(self) -> None:
|
||||||
def device_state_attributes(self):
|
"""Call for forced update."""
|
||||||
"""Return the state attributes."""
|
for attribute in self._template_attrs:
|
||||||
return self._attributes
|
if attribute.async_update:
|
||||||
|
attribute.async_update()
|
||||||
async def async_added_to_hass(self):
|
|
||||||
"""Register callbacks."""
|
|
||||||
|
|
||||||
for key, value in self._attribute_templates.items():
|
|
||||||
self._add_attribute_template(key, value)
|
|
||||||
|
|
||||||
await super().async_added_to_hass()
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ 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
|
from .const import CONF_AVAILABILITY_TEMPLATE
|
||||||
from .template_entity import TemplateEntityWithAttributesAvailabilityAndImages
|
from .template_entity import TemplateEntity
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -141,9 +141,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
||||||
async_add_entities(vacuums)
|
async_add_entities(vacuums)
|
||||||
|
|
||||||
|
|
||||||
class TemplateVacuum(
|
class TemplateVacuum(TemplateEntity, StateVacuumEntity):
|
||||||
TemplateEntityWithAttributesAvailabilityAndImages, StateVacuumEntity
|
|
||||||
):
|
|
||||||
"""A template vacuum component."""
|
"""A template vacuum component."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -168,7 +166,8 @@ class TemplateVacuum(
|
||||||
):
|
):
|
||||||
"""Initialize the vacuum."""
|
"""Initialize the vacuum."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
attribute_templates, availability_template, None, None,
|
attribute_templates=attribute_templates,
|
||||||
|
availability_template=availability_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, device_id, hass=hass
|
||||||
|
|
Loading…
Reference in New Issue