mirror of
https://github.com/home-assistant/core.git
synced 2025-05-13 10:29:14 +00:00
71 lines
2.7 KiB
Python
71 lines
2.7 KiB
Python
"""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 tempora.utc import fromtimestamp
|
|
|
|
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 fromtimestamp(0)
|
|
self.data[device.device_id] = {
|
|
k: await device.sensor(k)
|
|
for k in ("temperature", "humidity", "sound_pressure")
|
|
}
|
|
return self.data
|