Migrate Tile to use entry.runtime_data (#134107)
parent
bb8d4ca255
commit
417e736746
|
@ -2,21 +2,16 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from pytile import async_login
|
||||
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.util.async_ import gather_with_limited_concurrency
|
||||
|
||||
from .const import DOMAIN
|
||||
from .coordinator import TileCoordinator
|
||||
from .coordinator import TileConfigEntry, TileCoordinator
|
||||
|
||||
PLATFORMS = [Platform.DEVICE_TRACKER]
|
||||
DEVICE_TYPES = ["PHONE", "TILE"]
|
||||
|
@ -26,15 +21,7 @@ DEFAULT_INIT_TASK_LIMIT = 2
|
|||
CONF_SHOW_INACTIVE = "show_inactive"
|
||||
|
||||
|
||||
@dataclass
|
||||
class TileData:
|
||||
"""Define an object to be stored in `hass.data`."""
|
||||
|
||||
coordinators: dict[str, TileCoordinator]
|
||||
tiles: dict[str, Tile]
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: TileConfigEntry) -> bool:
|
||||
"""Set up Tile as config entry."""
|
||||
|
||||
# Tile's API uses cookies to identify a consumer; in order to allow for multiple
|
||||
|
@ -57,24 +44,21 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
coordinator_init_tasks = []
|
||||
|
||||
for tile_uuid, tile in tiles.items():
|
||||
coordinator = coordinators[tile_uuid] = TileCoordinator(hass, client, tile)
|
||||
coordinator = coordinators[tile_uuid] = TileCoordinator(
|
||||
hass, entry, client, tile
|
||||
)
|
||||
coordinator_init_tasks.append(coordinator.async_refresh())
|
||||
|
||||
await gather_with_limited_concurrency(
|
||||
DEFAULT_INIT_TASK_LIMIT, *coordinator_init_tasks
|
||||
)
|
||||
hass.data.setdefault(DOMAIN, {})
|
||||
hass.data[DOMAIN][entry.entry_id] = TileData(coordinators=coordinators, tiles=tiles)
|
||||
entry.runtime_data = coordinators
|
||||
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: TileConfigEntry) -> bool:
|
||||
"""Unload a Tile config entry."""
|
||||
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||
if unload_ok:
|
||||
hass.data[DOMAIN].pop(entry.entry_id)
|
||||
|
||||
return unload_ok
|
||||
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||
|
|
|
@ -6,26 +6,36 @@ from pytile.api import API
|
|||
from pytile.errors import InvalidAuthError, SessionExpiredError, TileError
|
||||
from pytile.tile import Tile
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_USERNAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryAuthFailed
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
|
||||
from .const import LOGGER
|
||||
|
||||
type TileConfigEntry = ConfigEntry[dict[str, TileCoordinator]]
|
||||
|
||||
|
||||
class TileCoordinator(DataUpdateCoordinator[None]):
|
||||
"""Define an object to coordinate Tile data retrieval."""
|
||||
|
||||
def __init__(self, hass: HomeAssistant, client: API, tile: Tile) -> None:
|
||||
config_entry: TileConfigEntry
|
||||
|
||||
def __init__(
|
||||
self, hass: HomeAssistant, entry: TileConfigEntry, client: API, tile: Tile
|
||||
) -> None:
|
||||
"""Initialize."""
|
||||
super().__init__(
|
||||
hass,
|
||||
LOGGER,
|
||||
name=tile.name,
|
||||
config_entry=entry,
|
||||
update_interval=timedelta(minutes=2),
|
||||
)
|
||||
self.tile = tile
|
||||
self.client = client
|
||||
self.username = entry.data[CONF_USERNAME]
|
||||
|
||||
async def _async_update_data(self) -> None:
|
||||
"""Update data via library."""
|
||||
|
|
|
@ -5,14 +5,11 @@ from __future__ import annotations
|
|||
import logging
|
||||
|
||||
from homeassistant.components.device_tracker import TrackerEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_USERNAME
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.util.dt import as_utc
|
||||
|
||||
from . import TileCoordinator, TileData
|
||||
from .const import DOMAIN
|
||||
from .coordinator import TileConfigEntry, TileCoordinator
|
||||
from .entity import TileEntity
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -29,16 +26,12 @@ ATTR_VOIP_STATE = "voip_state"
|
|||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
hass: HomeAssistant, entry: TileConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
) -> None:
|
||||
"""Set up Tile device trackers."""
|
||||
data: TileData = hass.data[DOMAIN][entry.entry_id]
|
||||
|
||||
async_add_entities(
|
||||
[
|
||||
TileDeviceTracker(entry, data.coordinators[tile_uuid])
|
||||
for tile_uuid, tile in data.tiles.items()
|
||||
]
|
||||
TileDeviceTracker(coordinator) for coordinator in entry.runtime_data.values()
|
||||
)
|
||||
|
||||
|
||||
|
@ -48,12 +41,12 @@ class TileDeviceTracker(TileEntity, TrackerEntity):
|
|||
_attr_name = None
|
||||
_attr_translation_key = "tile"
|
||||
|
||||
def __init__(self, entry: ConfigEntry, coordinator: TileCoordinator) -> None:
|
||||
def __init__(self, coordinator: TileCoordinator) -> None:
|
||||
"""Initialize."""
|
||||
super().__init__(coordinator)
|
||||
|
||||
self._attr_extra_state_attributes = {}
|
||||
self._attr_unique_id = f"{entry.data[CONF_USERNAME]}_{self._tile.uuid}"
|
||||
self._attr_unique_id = f"{coordinator.username}_{self._tile.uuid}"
|
||||
|
||||
@callback
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
|
|
|
@ -5,12 +5,10 @@ from __future__ import annotations
|
|||
from typing import Any
|
||||
|
||||
from homeassistant.components.diagnostics import async_redact_data
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_UUID
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from . import TileData
|
||||
from .const import DOMAIN
|
||||
from .coordinator import TileConfigEntry
|
||||
|
||||
CONF_ALTITUDE = "altitude"
|
||||
|
||||
|
@ -23,11 +21,12 @@ TO_REDACT = {
|
|||
|
||||
|
||||
async def async_get_config_entry_diagnostics(
|
||||
hass: HomeAssistant, entry: ConfigEntry
|
||||
hass: HomeAssistant, entry: TileConfigEntry
|
||||
) -> dict[str, Any]:
|
||||
"""Return diagnostics for a config entry."""
|
||||
data: TileData = hass.data[DOMAIN][entry.entry_id]
|
||||
coordinators = entry.runtime_data.values()
|
||||
|
||||
return async_redact_data(
|
||||
{"tiles": [tile.as_dict() for tile in data.tiles.values()]}, TO_REDACT
|
||||
{"tiles": [coordinator.tile.as_dict() for coordinator in coordinators]},
|
||||
TO_REDACT,
|
||||
)
|
||||
|
|
|
@ -5,7 +5,7 @@ from unittest.mock import AsyncMock, patch
|
|||
import pytest
|
||||
from pytile.errors import InvalidAuthError, TileError
|
||||
|
||||
from homeassistant.components.tile import DOMAIN
|
||||
from homeassistant.components.tile.const import DOMAIN
|
||||
from homeassistant.config_entries import SOURCE_USER
|
||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
|
Loading…
Reference in New Issue