From b107e87d3842c49241b691d2894ecea278a35f42 Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Fri, 11 Sep 2020 14:02:17 +0200 Subject: [PATCH] Don't trigger on attribute when the attribute doesn't change (#39910) Co-authored-by: Paulus Schoutsen --- .../homeassistant/triggers/state.py | 7 ++++ .../homeassistant/triggers/test_state.py | 36 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/homeassistant/components/homeassistant/triggers/state.py b/homeassistant/components/homeassistant/triggers/state.py index 0fa7a98b562..f57db0ed56a 100644 --- a/homeassistant/components/homeassistant/triggers/state.py +++ b/homeassistant/components/homeassistant/triggers/state.py @@ -80,6 +80,13 @@ async def async_attach_trigger( else: new_value = to_s.attributes.get(attribute) + # When we listen for state changes with `match_all`, we + # will trigger even if just an attribute changes. When + # we listen to just an attribute, we should ignore all + # other attribute changes. + if attribute is not None and old_value == new_value: + return + if ( not match_from_state(old_value) or not match_to_state(new_value) diff --git a/tests/components/homeassistant/triggers/test_state.py b/tests/components/homeassistant/triggers/test_state.py index 68ce907bdae..ce9ecaba1b0 100644 --- a/tests/components/homeassistant/triggers/test_state.py +++ b/tests/components/homeassistant/triggers/test_state.py @@ -1112,6 +1112,42 @@ async def test_attribute_if_fires_on_entity_change_with_both_filters(hass, calls assert len(calls) == 1 +async def test_attribute_if_fires_on_entity_where_attr_stays_constant(hass, calls): + """Test for firing if attribute stays the same.""" + hass.states.async_set("test.entity", "bla", {"name": "hello", "other": "old_value"}) + + assert await async_setup_component( + hass, + automation.DOMAIN, + { + automation.DOMAIN: { + "trigger": { + "platform": "state", + "entity_id": "test.entity", + "attribute": "name", + }, + "action": {"service": "test.automation"}, + } + }, + ) + await hass.async_block_till_done() + + # Leave all attributes the same + hass.states.async_set("test.entity", "bla", {"name": "hello", "other": "old_value"}) + await hass.async_block_till_done() + assert len(calls) == 0 + + # Change the untracked attribute + hass.states.async_set("test.entity", "bla", {"name": "hello", "other": "new_value"}) + await hass.async_block_till_done() + assert len(calls) == 0 + + # Change the tracked attribute + hass.states.async_set("test.entity", "bla", {"name": "world", "other": "old_value"}) + await hass.async_block_till_done() + assert len(calls) == 1 + + async def test_attribute_if_not_fires_on_entities_change_with_for_after_stop( hass, calls ):