From 037621b79677b76f9d8bab7b0e1ebcca09a013f1 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Tue, 25 Jan 2022 18:19:12 +0100 Subject: [PATCH] Update _TrackStateChangeFiltered entity listener with new entities (#64909) --- homeassistant/helpers/event.py | 11 +++- tests/components/geo_location/test_trigger.py | 58 +++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/homeassistant/helpers/event.py b/homeassistant/helpers/event.py index 14b45a52ecd..cbafd2e7e95 100644 --- a/homeassistant/helpers/event.py +++ b/homeassistant/helpers/event.py @@ -536,6 +536,7 @@ class _TrackStateChangeFiltered: """Handle removal / refresh of tracker init.""" self.hass = hass self._action = action + self._action_as_hassjob = HassJob(action) self._listeners: dict[str, Callable[[], None]] = {} self._last_track_states: TrackStates = track_states @@ -631,13 +632,21 @@ class _TrackStateChangeFiltered: self.hass, entities, self._action ) + @callback + def _state_added(self, event: Event) -> None: + self._cancel_listener(_ENTITIES_LISTENER) + self._setup_entities_listener( + self._last_track_states.domains, self._last_track_states.entities + ) + self.hass.async_run_hass_job(self._action_as_hassjob, event) + @callback def _setup_domains_listener(self, domains: set[str]) -> None: if not domains: return self._listeners[_DOMAINS_LISTENER] = async_track_state_added_domain( - self.hass, domains, self._action + self.hass, domains, self._state_added ) @callback diff --git a/tests/components/geo_location/test_trigger.py b/tests/components/geo_location/test_trigger.py index bc74f01f6f1..bbf5f42ed60 100644 --- a/tests/components/geo_location/test_trigger.py +++ b/tests/components/geo_location/test_trigger.py @@ -273,6 +273,64 @@ async def test_if_fires_on_zone_appear(hass, calls): ) +async def test_if_fires_on_zone_appear_2(hass, calls): + """Test for firing if entity appears in zone.""" + assert await async_setup_component( + hass, + automation.DOMAIN, + { + automation.DOMAIN: { + "trigger": { + "platform": "geo_location", + "source": "test_source", + "zone": "zone.test", + "event": "enter", + }, + "action": { + "service": "test.automation", + "data_template": { + "some": "{{ trigger.%s }}" + % "}} - {{ trigger.".join( + ( + "platform", + "entity_id", + "from_state.state", + "to_state.state", + "zone.name", + ) + ) + }, + }, + } + }, + ) + + # Entity appears in zone without previously existing outside the zone. + context = Context() + hass.states.async_set( + "geo_location.entity", + "goodbye", + {"latitude": 32.881011, "longitude": -117.234758, "source": "test_source"}, + context=context, + ) + await hass.async_block_till_done() + + hass.states.async_set( + "geo_location.entity", + "hello", + {"latitude": 32.880586, "longitude": -117.237564, "source": "test_source"}, + context=context, + ) + await hass.async_block_till_done() + + assert len(calls) == 1 + assert calls[0].context.parent_id == context.id + assert ( + calls[0].data["some"] + == "geo_location - geo_location.entity - goodbye - hello - test" + ) + + async def test_if_fires_on_zone_disappear(hass, calls): """Test for firing if entity disappears from zone.""" hass.states.async_set(