Skip to content

Commit

Permalink
Extract Tile coordinator in separate file (home-assistant#134104)
Browse files Browse the repository at this point in the history
  • Loading branch information
joostlek authored Dec 27, 2024
1 parent b9c2b3f commit 52318f5
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 42 deletions.
34 changes: 6 additions & 28 deletions homeassistant/components/tile/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,25 @@
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
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"

Expand All @@ -33,7 +30,7 @@
class TileData:
"""Define an object to be stored in `hass.data`."""

coordinators: dict[str, DataUpdateCoordinator[None]]
coordinators: dict[str, TileCoordinator]
tiles: dict[str, Tile]


Expand All @@ -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(
Expand Down
40 changes: 40 additions & 0 deletions homeassistant/components/tile/coordinator.py
Original file line number Diff line number Diff line change
@@ -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
21 changes: 7 additions & 14 deletions homeassistant/components/tile/device_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,17 @@

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
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__)
Expand All @@ -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()
]
)
Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit 52318f5

Please sign in to comment.