"""Define a data update coordinator for Point.""" from collections.abc import Callable from datetime import datetime import logging from typing import Any from pypoint import PointSession from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.util.dt import parse_datetime from .const import DOMAIN, SCAN_INTERVAL _LOGGER = logging.getLogger(__name__) class PointDataUpdateCoordinator(DataUpdateCoordinator[dict[str, dict[str, Any]]]): """Class to manage fetching Point data from the API.""" def __init__(self, hass: HomeAssistant, point: PointSession) -> None: """Initialize.""" super().__init__( hass, _LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL, ) self.point = point self.device_updates: dict[str, datetime] = {} self._known_devices: set[str] = set() self._known_homes: set[str] = set() self.new_home_callback: Callable[[str], None] | None = None self.new_device_callbacks: list[Callable[[str], None]] = [] self.data: dict[str, dict[str, Any]] = {} async def _async_update_data(self) -> dict[str, dict[str, Any]]: if not await self.point.update(): raise UpdateFailed("Failed to fetch data from Point") if new_homes := set(self.point.homes) - self._known_homes: _LOGGER.debug("Found new homes: %s", new_homes) for home_id in new_homes: if self.new_home_callback: self.new_home_callback(home_id) self._known_homes.update(new_homes) device_ids = {device.device_id for device in self.point.devices} if new_devices := device_ids - self._known_devices: _LOGGER.debug("Found new devices: %s", new_devices) for device_id in new_devices: for callback in self.new_device_callbacks: callback(device_id) self._known_devices.update(new_devices) for device in self.point.devices: last_updated = parse_datetime(device.last_update) if ( not last_updated or device.device_id not in self.device_updates or self.device_updates[device.device_id] < last_updated ): self.device_updates[device.device_id] = ( last_updated or datetime.fromtimestamp(0) ) self.data[device.device_id] = { k: await device.sensor(k) for k in ("temperature", "humidity", "sound_pressure") } return self.data