Update TrackTemplateResultInfo to remove side effects from init (#38934)
* Verify and case * Review comments * Update homeassistant/helpers/event.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Update homeassistant/helpers/event.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
parent
66a5f24d4a
commit
472b12bef5
2 changed files with 69 additions and 5 deletions
|
@ -28,7 +28,7 @@ from homeassistant.core import (
|
|||
from homeassistant.exceptions import TemplateError
|
||||
from homeassistant.helpers.entity_registry import EVENT_ENTITY_REGISTRY_UPDATED
|
||||
from homeassistant.helpers.sun import get_astral_event_next
|
||||
from homeassistant.helpers.template import Template, result_as_boolean
|
||||
from homeassistant.helpers.template import RenderInfo, Template, result_as_boolean
|
||||
from homeassistant.helpers.typing import TemplateVarsType
|
||||
from homeassistant.loader import bind_hass
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
@ -431,7 +431,7 @@ track_template = threaded_listener_factory(async_track_template)
|
|||
_UNCHANGED = object()
|
||||
|
||||
|
||||
class TrackTemplateResultInfo:
|
||||
class _TrackTemplateResultInfo:
|
||||
"""Handle removal / refresh of tracker."""
|
||||
|
||||
def __init__(
|
||||
|
@ -451,7 +451,12 @@ class TrackTemplateResultInfo:
|
|||
self._all_listener: Optional[Callable] = None
|
||||
self._domains_listener: Optional[Callable] = None
|
||||
self._entities_listener: Optional[Callable] = None
|
||||
self._info = template.async_render_to_info(variables)
|
||||
self._info: Optional[RenderInfo] = None
|
||||
self._last_info: Optional[RenderInfo] = None
|
||||
|
||||
def async_setup(self) -> None:
|
||||
"""Activation of template tracking."""
|
||||
self._info = self._template.async_render_to_info(self._variables)
|
||||
if self._info.exception:
|
||||
self._last_exception = True
|
||||
_LOGGER.exception(self._info.exception)
|
||||
|
@ -460,6 +465,8 @@ class TrackTemplateResultInfo:
|
|||
|
||||
@property
|
||||
def _needs_all_listener(self) -> bool:
|
||||
assert self._info
|
||||
|
||||
# Tracking all states
|
||||
if self._info.all_states:
|
||||
return True
|
||||
|
@ -480,6 +487,8 @@ class TrackTemplateResultInfo:
|
|||
|
||||
@callback
|
||||
def _create_listeners(self) -> None:
|
||||
assert self._info
|
||||
|
||||
if self._info.is_static:
|
||||
return
|
||||
|
||||
|
@ -516,6 +525,9 @@ class TrackTemplateResultInfo:
|
|||
|
||||
@callback
|
||||
def _update_listeners(self) -> None:
|
||||
assert self._info
|
||||
assert self._last_info
|
||||
|
||||
if self._needs_all_listener:
|
||||
if self._all_listener:
|
||||
return
|
||||
|
@ -544,6 +556,8 @@ class TrackTemplateResultInfo:
|
|||
|
||||
@callback
|
||||
def _setup_entities_listener(self) -> None:
|
||||
assert self._info
|
||||
|
||||
entities = set(self._info.entities)
|
||||
for entity_id in self.hass.states.async_entity_ids(self._info.domains):
|
||||
entities.add(entity_id)
|
||||
|
@ -553,6 +567,8 @@ class TrackTemplateResultInfo:
|
|||
|
||||
@callback
|
||||
def _setup_domains_listener(self) -> None:
|
||||
assert self._info
|
||||
|
||||
self._domains_listener = async_track_state_added_domain(
|
||||
self.hass, self._info.domains, self._refresh
|
||||
)
|
||||
|
@ -631,7 +647,7 @@ def async_track_template_result(
|
|||
template: Template,
|
||||
action: TrackTemplateResultListener,
|
||||
variables: Optional[TemplateVarsType] = None,
|
||||
) -> TrackTemplateResultInfo:
|
||||
) -> _TrackTemplateResultInfo:
|
||||
"""Add a listener that fires when a the result of a template changes.
|
||||
|
||||
The action will fire with the initial result from the template, and
|
||||
|
@ -662,7 +678,9 @@ def async_track_template_result(
|
|||
Info object used to unregister the listener, and refresh the template.
|
||||
|
||||
"""
|
||||
return TrackTemplateResultInfo(hass, template, action, variables)
|
||||
tracker = _TrackTemplateResultInfo(hass, template, action, variables)
|
||||
tracker.async_setup()
|
||||
return tracker
|
||||
|
||||
|
||||
@callback
|
||||
|
|
|
@ -796,6 +796,52 @@ async def test_track_template_result_with_group(hass):
|
|||
assert specific_runs[-1] == str(100.1 + 200.2 + 0 + 800.8)
|
||||
|
||||
|
||||
async def test_track_template_result_and_conditional(hass):
|
||||
"""Test tracking template with an and conditional."""
|
||||
specific_runs = []
|
||||
hass.states.async_set("light.a", "off")
|
||||
hass.states.async_set("light.b", "off")
|
||||
template_str = '{% if states.light.a.state == "on" and states.light.b.state == "on" %}on{% else %}off{% endif %}'
|
||||
|
||||
template = Template(template_str, hass)
|
||||
|
||||
def specific_run_callback(event, template, old_result, new_result):
|
||||
import pprint
|
||||
|
||||
pprint.pprint([event, template, old_result, new_result])
|
||||
specific_runs.append(new_result)
|
||||
|
||||
async_track_template_result(hass, template, specific_run_callback)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
hass.states.async_set("light.b", "on")
|
||||
await hass.async_block_till_done()
|
||||
assert len(specific_runs) == 0
|
||||
|
||||
hass.states.async_set("light.a", "on")
|
||||
await hass.async_block_till_done()
|
||||
assert len(specific_runs) == 1
|
||||
assert specific_runs[0] == "on"
|
||||
|
||||
hass.states.async_set("light.b", "off")
|
||||
await hass.async_block_till_done()
|
||||
assert len(specific_runs) == 2
|
||||
assert specific_runs[1] == "off"
|
||||
|
||||
hass.states.async_set("light.a", "off")
|
||||
await hass.async_block_till_done()
|
||||
assert len(specific_runs) == 2
|
||||
|
||||
hass.states.async_set("light.b", "on")
|
||||
await hass.async_block_till_done()
|
||||
assert len(specific_runs) == 2
|
||||
|
||||
hass.states.async_set("light.a", "on")
|
||||
await hass.async_block_till_done()
|
||||
assert len(specific_runs) == 3
|
||||
assert specific_runs[2] == "on"
|
||||
|
||||
|
||||
async def test_track_template_result_iterator(hass):
|
||||
"""Test tracking template."""
|
||||
iterator_runs = []
|
||||
|
|
Loading…
Add table
Reference in a new issue