Extract Tile coordinator in separate file (#134104)

This commit is contained in:
Joost Lekkerkerker 2024-12-27 19:30:13 +01:00 committed by GitHub
parent b9c2b3f7e3
commit 52318f5f37
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 53 additions and 42 deletions

View File

@ -3,11 +3,9 @@
from __future__ import annotations
from dataclasses import dataclass
from datetime import timedelta
from functools import partial
from pytile import async_login
from pytile.errors import InvalidAuthError, SessionExpiredError, TileError
from pytile.errors import InvalidAuthError, TileError
from pytile.tile import Tile
from homeassistant.config_entries import ConfigEntry
@ -15,16 +13,15 @@ from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers import aiohttp_client
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from homeassistant.util.async_ import gather_with_limited_concurrency
from .const import DOMAIN, LOGGER
from .const import DOMAIN
from .coordinator import TileCoordinator
PLATFORMS = [Platform.DEVICE_TRACKER]
DEVICE_TYPES = ["PHONE", "TILE"]
DEFAULT_INIT_TASK_LIMIT = 2
DEFAULT_UPDATE_INTERVAL = timedelta(minutes=2)
CONF_SHOW_INACTIVE = "show_inactive"
@ -33,7 +30,7 @@ CONF_SHOW_INACTIVE = "show_inactive"
class TileData:
"""Define an object to be stored in `hass.data`."""
coordinators: dict[str, DataUpdateCoordinator[None]]
coordinators: dict[str, TileCoordinator]
tiles: dict[str, Tile]
@ -56,30 +53,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
except TileError as err:
raise ConfigEntryNotReady("Error during integration setup") from err
async def async_update_tile(tile: Tile) -> None:
"""Update the Tile."""
try:
await tile.async_update()
except InvalidAuthError as err:
raise ConfigEntryAuthFailed("Invalid credentials") from err
except SessionExpiredError:
LOGGER.debug("Tile session expired; creating a new one")
await client.async_init()
except TileError as err:
raise UpdateFailed(f"Error while retrieving data: {err}") from err
coordinators: dict[str, DataUpdateCoordinator[None]] = {}
coordinators: dict[str, TileCoordinator] = {}
coordinator_init_tasks = []
for tile_uuid, tile in tiles.items():
coordinator = coordinators[tile_uuid] = DataUpdateCoordinator(
hass,
LOGGER,
config_entry=entry,
name=tile.name,
update_interval=DEFAULT_UPDATE_INTERVAL,
update_method=partial(async_update_tile, tile),
)
coordinator = coordinators[tile_uuid] = TileCoordinator(hass, client, tile)
coordinator_init_tasks.append(coordinator.async_refresh())
await gather_with_limited_concurrency(

View File

@ -0,0 +1,40 @@
"""Update coordinator for Tile."""
from datetime import timedelta
from pytile.api import API
from pytile.errors import InvalidAuthError, SessionExpiredError, TileError
from pytile.tile import Tile
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import LOGGER
class TileCoordinator(DataUpdateCoordinator[None]):
"""Define an object to coordinate Tile data retrieval."""
def __init__(self, hass: HomeAssistant, client: API, tile: Tile) -> None:
"""Initialize."""
super().__init__(
hass,
LOGGER,
name=tile.name,
update_interval=timedelta(minutes=2),
)
self.tile = tile
self.client = client
async def _async_update_data(self) -> None:
"""Update data via library."""
try:
await self.tile.async_update()
except InvalidAuthError as err:
raise ConfigEntryAuthFailed("Invalid credentials") from err
except SessionExpiredError:
LOGGER.debug("Tile session expired; creating a new one")
await self.client.async_init()
except TileError as err:
raise UpdateFailed(f"Error while retrieving data: {err}") from err

View File

@ -4,8 +4,6 @@ from __future__ import annotations
import logging
from pytile.tile import Tile
from homeassistant.components.device_tracker import AsyncSeeCallback, TrackerEntity
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
@ -13,13 +11,10 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
DataUpdateCoordinator,
)
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from homeassistant.util.dt import as_utc
from . import TileData
from . import TileCoordinator, TileData
from .const import DOMAIN
_LOGGER = logging.getLogger(__name__)
@ -43,7 +38,7 @@ async def async_setup_entry(
async_add_entities(
[
TileDeviceTracker(entry, data.coordinators[tile_uuid], tile)
TileDeviceTracker(entry, data.coordinators[tile_uuid])
for tile_uuid, tile in data.tiles.items()
]
)
@ -75,23 +70,21 @@ async def async_setup_scanner(
return True
class TileDeviceTracker(CoordinatorEntity[DataUpdateCoordinator[None]], TrackerEntity):
class TileDeviceTracker(CoordinatorEntity[TileCoordinator], TrackerEntity):
"""Representation of a network infrastructure device."""
_attr_has_entity_name = True
_attr_name = None
_attr_translation_key = "tile"
def __init__(
self, entry: ConfigEntry, coordinator: DataUpdateCoordinator[None], tile: Tile
) -> None:
def __init__(self, entry: ConfigEntry, coordinator: TileCoordinator) -> None:
"""Initialize."""
super().__init__(coordinator)
self._attr_extra_state_attributes = {}
self._attr_unique_id = f"{entry.data[CONF_USERNAME]}_{tile.uuid}"
self._tile = coordinator.tile
self._attr_unique_id = f"{entry.data[CONF_USERNAME]}_{self._tile.uuid}"
self._entry = entry
self._tile = tile
@property
def available(self) -> bool: