Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions homeassistant/components/template/template_entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,7 @@ def _handle_results(
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):
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]",
Expand Down
45 changes: 45 additions & 0 deletions tests/components/template/test_cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -1121,3 +1121,48 @@ async def test_state_gets_lowercased(hass):
hass.states.async_set("binary_sensor.garage_door_sensor", "on")
await hass.async_block_till_done()
assert hass.states.get("cover.garage_door").state == STATE_CLOSED


async def test_self_referencing_icon_with_no_template_is_not_a_loop(hass, caplog):
"""Test a self referencing icon with no value template is not a loop."""

icon_template_str = """{% if is_state('cover.office', 'open') %}
mdi:window-shutter-open
{% else %}
mdi:window-shutter
{% endif %}"""

await setup.async_setup_component(
hass,
"cover",
{
"cover": {
"platform": "template",
"covers": {
"office": {
"icon_template": icon_template_str,
"open_cover": {
"service": "switch.turn_on",
"entity_id": "switch.office_blinds_up",
},
"close_cover": {
"service": "switch.turn_on",
"entity_id": "switch.office_blinds_down",
},
"stop_cover": {
"service": "switch.turn_on",
"entity_id": "switch.office_blinds_up",
},
},
},
}
},
)

await hass.async_block_till_done()
await hass.async_start()
await hass.async_block_till_done()

assert len(hass.states.async_all()) == 1

assert "Template loop detected" not in caplog.text
14 changes: 7 additions & 7 deletions tests/components/template/test_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -797,9 +797,9 @@ async def test_self_referencing_sensor_loop(hass, caplog):
assert "Template loop detected" in caplog.text

state = hass.states.get("sensor.test")
assert int(state.state) == 1
assert int(state.state) == 2
await hass.async_block_till_done()
assert int(state.state) == 1
assert int(state.state) == 2


async def test_self_referencing_sensor_with_icon_loop(hass, caplog):
Expand Down Expand Up @@ -833,11 +833,11 @@ async def test_self_referencing_sensor_with_icon_loop(hass, caplog):
assert "Template loop detected" in caplog.text

state = hass.states.get("sensor.test")
assert int(state.state) == 2
assert int(state.state) == 3
assert state.attributes[ATTR_ICON] == "mdi:greater"

await hass.async_block_till_done()
assert int(state.state) == 2
assert int(state.state) == 3


async def test_self_referencing_sensor_with_icon_and_picture_entity_loop(hass, caplog):
Expand Down Expand Up @@ -872,12 +872,12 @@ async def test_self_referencing_sensor_with_icon_and_picture_entity_loop(hass, c
assert "Template loop detected" in caplog.text

state = hass.states.get("sensor.test")
assert int(state.state) == 3
assert int(state.state) == 4
assert state.attributes[ATTR_ICON] == "mdi:less"
assert state.attributes[ATTR_ENTITY_PICTURE] == "bigpic"

await hass.async_block_till_done()
assert int(state.state) == 3
assert int(state.state) == 4


async def test_self_referencing_entity_picture_loop(hass, caplog):
Expand Down Expand Up @@ -917,7 +917,7 @@ async def test_self_referencing_entity_picture_loop(hass, caplog):

state = hass.states.get("sensor.test")
assert int(state.state) == 1
assert state.attributes[ATTR_ENTITY_PICTURE] == "1"
assert state.attributes[ATTR_ENTITY_PICTURE] == "2"

await hass.async_block_till_done()
assert int(state.state) == 1
Expand Down