Refactor entity manager code in geo_json_events integration (#89847)

* moved entity manager

* fix circular reference

* simplify new entity signal
This commit is contained in:
Malte Franken 2023-03-17 21:59:29 +11:00 committed by GitHub
parent ab6e929443
commit ed0a059053
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 102 additions and 71 deletions

View File

@ -2,7 +2,7 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Callable from collections.abc import Callable
from datetime import datetime, timedelta from datetime import timedelta
import logging import logging
from typing import Any from typing import Any
@ -21,16 +21,13 @@ from homeassistant.const import (
UnitOfLength, UnitOfLength,
) )
from homeassistant.core import Event, HomeAssistant, callback from homeassistant.core import Event, HomeAssistant, callback
from homeassistant.helpers import aiohttp_client
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.dispatcher import ( from homeassistant.helpers.dispatcher import async_dispatcher_connect
async_dispatcher_connect,
async_dispatcher_send,
)
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from .manager import GeoJsonFeedEntityManager
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
ATTR_EXTERNAL_ID = "external_id" ATTR_EXTERNAL_ID = "external_id"
@ -67,8 +64,21 @@ async def async_setup_platform(
radius_in_km: float = config[CONF_RADIUS] radius_in_km: float = config[CONF_RADIUS]
# Initialize the entity manager. # Initialize the entity manager.
manager = GeoJsonFeedEntityManager( manager = GeoJsonFeedEntityManager(
hass, async_add_entities, scan_interval, coordinates, url, radius_in_km hass, scan_interval, coordinates, url, radius_in_km
) )
@callback
def async_add_geolocation(
feed_manager: GenericFeedManager,
external_id: str,
) -> None:
"""Add geolocation entity from feed."""
new_entity = GeoJsonLocationEvent(feed_manager, external_id)
_LOGGER.debug("Adding geolocation %s", new_entity)
async_add_entities([new_entity], True)
async_dispatcher_connect(hass, manager.signal_new_entity, async_add_geolocation)
await manager.async_init() await manager.async_init()
async def start_feed_manager(event: Event) -> None: async def start_feed_manager(event: Event) -> None:
@ -78,69 +88,6 @@ async def async_setup_platform(
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, start_feed_manager) hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, start_feed_manager)
class GeoJsonFeedEntityManager:
"""Feed Entity Manager for GeoJSON feeds."""
def __init__(
self,
hass: HomeAssistant,
async_add_entities: AddEntitiesCallback,
scan_interval: timedelta,
coordinates: tuple[float, float],
url: str,
radius_in_km: float,
) -> None:
"""Initialize the GeoJSON Feed Manager."""
self._hass = hass
websession = aiohttp_client.async_get_clientsession(hass)
self._feed_manager = GenericFeedManager(
websession,
self._generate_entity,
self._update_entity,
self._remove_entity,
coordinates,
url,
filter_radius=radius_in_km,
)
self._async_add_entities = async_add_entities
self._scan_interval = scan_interval
async def async_init(self) -> None:
"""Schedule initial and regular updates based on configured time interval."""
async def update(event_time: datetime) -> None:
"""Update."""
await self.async_update()
# Trigger updates at regular intervals.
async_track_time_interval(self._hass, update, self._scan_interval)
_LOGGER.debug("Feed entity manager initialized")
async def async_update(self) -> None:
"""Refresh data."""
await self._feed_manager.update()
_LOGGER.debug("Feed entity manager updated")
def get_entry(self, external_id: str) -> GenericFeedEntry | None:
"""Get feed entry by external id."""
return self._feed_manager.feed_entries.get(external_id)
async def _generate_entity(self, external_id: str) -> None:
"""Generate new entity."""
new_entity = GeoJsonLocationEvent(self, external_id)
# Add new entities to HA.
self._async_add_entities([new_entity], True)
async def _update_entity(self, external_id: str) -> None:
"""Update entity."""
async_dispatcher_send(self._hass, f"geo_json_events_update_{external_id}")
async def _remove_entity(self, external_id: str) -> None:
"""Remove entity."""
async_dispatcher_send(self._hass, f"geo_json_events_delete_{external_id}")
class GeoJsonLocationEvent(GeolocationEvent): class GeoJsonLocationEvent(GeolocationEvent):
"""Represents an external event with GeoJSON data.""" """Represents an external event with GeoJSON data."""

View File

@ -0,0 +1,84 @@
"""Entity manager for generic GeoJSON events."""
from __future__ import annotations
from datetime import datetime, timedelta
import logging
from aio_geojson_generic_client import GenericFeedManager
from aio_geojson_generic_client.feed_entry import GenericFeedEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers import aiohttp_client
from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.event import async_track_time_interval
DOMAIN = "geo_json_events"
_LOGGER = logging.getLogger(__name__)
class GeoJsonFeedEntityManager:
"""Feed Entity Manager for GeoJSON feeds."""
def __init__(
self,
hass: HomeAssistant,
scan_interval: timedelta,
coordinates: tuple[float, float],
url: str,
radius_in_km: float,
) -> None:
"""Initialize the GeoJSON Feed Manager."""
self._hass = hass
websession = aiohttp_client.async_get_clientsession(hass)
self._feed_manager = GenericFeedManager(
websession,
self._generate_entity,
self._update_entity,
self._remove_entity,
coordinates,
url,
filter_radius=radius_in_km,
)
self._scan_interval = scan_interval
self.signal_new_entity = (
f"{DOMAIN}_new_geolocation_{coordinates}-{url}-{radius_in_km}"
)
async def async_init(self) -> None:
"""Schedule initial and regular updates based on configured time interval."""
async def update(event_time: datetime) -> None:
"""Update."""
await self.async_update()
# Trigger updates at regular intervals.
async_track_time_interval(self._hass, update, self._scan_interval)
_LOGGER.debug("Feed entity manager initialized")
async def async_update(self) -> None:
"""Refresh data."""
await self._feed_manager.update()
_LOGGER.debug("Feed entity manager updated")
def get_entry(self, external_id: str) -> GenericFeedEntry | None:
"""Get feed entry by external id."""
return self._feed_manager.feed_entries.get(external_id)
async def _generate_entity(self, external_id: str) -> None:
"""Generate new entity."""
async_dispatcher_send(
self._hass,
self.signal_new_entity,
self,
external_id,
)
async def _update_entity(self, external_id: str) -> None:
"""Update entity."""
async_dispatcher_send(self._hass, f"geo_json_events_update_{external_id}")
async def _remove_entity(self, external_id: str) -> None:
"""Remove entity."""
async_dispatcher_send(self._hass, f"geo_json_events_delete_{external_id}")