Disconnect geo_json_events entity signals when the entity is removed (#183322)

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Franck Nijhof
2026-09-27 17:40:18 +02:00
committed by GitHub
co-authored by Claude
parent 4b52b378e4
commit 3b61862c19
2 changed files with 35 additions and 13 deletions
@@ -1,6 +1,5 @@
"""Support for generic GeoJSON events."""
from collections.abc import Callable
import logging
from typing import Any, override
@@ -61,28 +60,28 @@ class GeoJsonLocationEvent(GeolocationEvent):
self._feed_manager = feed_manager
self._external_id = external_id
self._attr_unique_id = f"{feed_manager.entry_id}_{external_id}"
self._remove_signal_delete: Callable[[], None]
self._remove_signal_update: Callable[[], None]
@override
async def async_added_to_hass(self) -> None:
"""Call when entity is added to hass."""
self._remove_signal_delete = async_dispatcher_connect(
self.hass,
SIGNAL_DELETE_ENTITY.format(self._external_id),
self._delete_callback,
self.async_on_remove(
async_dispatcher_connect(
self.hass,
SIGNAL_DELETE_ENTITY.format(self._external_id),
self._delete_callback,
)
)
self._remove_signal_update = async_dispatcher_connect(
self.hass,
SIGNAL_UPDATE_ENTITY.format(self._external_id),
self._update_callback,
self.async_on_remove(
async_dispatcher_connect(
self.hass,
SIGNAL_UPDATE_ENTITY.format(self._external_id),
self._update_callback,
)
)
@callback
def _delete_callback(self) -> None:
"""Remove this entity."""
self._remove_signal_delete()
self._remove_signal_update()
self.hass.async_create_task(self.async_remove(force_remove=True))
@callback
@@ -8,6 +8,8 @@ from freezegun import freeze_time
from homeassistant.components.geo_json_events.const import (
ATTR_EXTERNAL_ID,
DEFAULT_UPDATE_INTERVAL,
SIGNAL_DELETE_ENTITY,
SIGNAL_UPDATE_ENTITY,
)
from homeassistant.components.geo_location import (
ATTR_SOURCE,
@@ -26,6 +28,7 @@ from homeassistant.const import (
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.dispatcher import DATA_DISPATCHER
from homeassistant.util import dt as dt_util
from . import _generate_mock_feed_entry
@@ -145,3 +148,23 @@ async def test_entity_lifecycle(
await hass.async_block_till_done()
assert len(hass.states.async_entity_ids(GEO_LOCATION_DOMAIN)) == 0
async def test_signals_disconnected_on_unload(
hass: HomeAssistant, config_entry: MockConfigEntry
) -> None:
"""Test entity signal listeners are disconnected when the entry unloads."""
config_entry.add_to_hass(hass)
mock_entry = _generate_mock_feed_entry("1234", "Title 1", 15.5, (-31.0, 150.0))
with patch("aio_geojson_client.feed.GeoJsonFeed.update") as mock_feed_update:
mock_feed_update.return_value = "OK", [mock_entry]
assert await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
signals = (SIGNAL_DELETE_ENTITY.format("1234"), SIGNAL_UPDATE_ENTITY.format("1234"))
assert all(signal in hass.data[DATA_DISPATCHER] for signal in signals)
assert await hass.config_entries.async_unload(config_entry.entry_id)
await hass.async_block_till_done()
assert not any(signal in hass.data[DATA_DISPATCHER] for signal in signals)