Change template loop detection strategy to allow self-referencing updates when there are multiple templates (#39943)

This commit is contained in:
J. Nick Koston 2020-09-12 07:20:21 -05:00 committed by GitHub
parent e746965b1c
commit aaa8083d49
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 220 additions and 39 deletions

View file

@ -5,6 +5,7 @@ from typing import Any, Callable, List, Optional, Union
import voluptuous as vol
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import EVENT_HOMEASSISTANT_START, CoreState, callback
from homeassistant.exceptions import TemplateError
import homeassistant.helpers.config_validation as cv
@ -121,7 +122,6 @@ class TemplateEntity(Entity):
"""Template Entity."""
self._template_attrs = {}
self._async_update = None
self._async_update_entity_ids_filter = None
self._attribute_templates = attribute_templates
self._attributes = {}
self._availability_template = availability_template
@ -130,6 +130,7 @@ class TemplateEntity(Entity):
self._entity_picture_template = entity_picture_template
self._icon = None
self._entity_picture = None
self._self_ref_update_count = 0
@property
def should_poll(self):
@ -223,18 +224,34 @@ class TemplateEntity(Entity):
updates: List[TrackTemplateResult],
) -> None:
"""Call back the results to the attributes."""
if event:
self.async_set_context(event.context)
entity_id = event and event.data.get(ATTR_ENTITY_ID)
if entity_id and entity_id == self.entity_id:
self._self_ref_update_count += 1
else:
self._self_ref_update_count = 0
# If we need to make this less sensitive in the future,
# change the '>=' to a '>' here.
if self._self_ref_update_count >= len(self._template_attrs):
for update in updates:
_LOGGER.warning(
"Template loop detected while processing event: %s, skipping template render for Template[%s]",
event,
update.template.template,
)
return
for update in updates:
for attr in self._template_attrs[update.template]:
attr.handle_result(
event, update.template, update.last_result, update.result
)
if self._async_update_entity_ids_filter:
self._async_update_entity_ids_filter({self.entity_id})
if self._async_update:
self.async_write_ha_state()
@ -249,12 +266,8 @@ class TemplateEntity(Entity):
)
self.async_on_remove(result_info.async_remove)
result_info.async_refresh()
result_info.async_update_entity_ids_filter({self.entity_id})
self.async_write_ha_state()
self._async_update = result_info.async_refresh
self._async_update_entity_ids_filter = (
result_info.async_update_entity_ids_filter
)
async def async_added_to_hass(self) -> None:
"""Run when entity about to be added to hass."""