hass-core/homeassistant/components/fitbit/coordinator.py
Allen Porter d78ee96e2a
Update fitbit device fetch to use a data update coordinator (#101619)
* Add a fitbit device update coordinator

* Remove unnecessary debug output

* Update comments

* Update fitbit coordinator exception handling and test coverage

* Handle reauth failures in other sensors

* Fix scope changes after rebase.
2023-10-09 08:12:59 +02:00

48 lines
1.5 KiB
Python

"""Coordinator for fetching data from fitbit API."""
import asyncio
from dataclasses import dataclass
import datetime
import logging
from typing import Final
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .api import FitbitApi
from .exceptions import FitbitApiException, FitbitAuthException
from .model import FitbitDevice
_LOGGER = logging.getLogger(__name__)
UPDATE_INTERVAL: Final = datetime.timedelta(minutes=30)
TIMEOUT = 10
class FitbitDeviceCoordinator(DataUpdateCoordinator):
"""Coordinator for fetching fitbit devices from the API."""
def __init__(self, hass: HomeAssistant, api: FitbitApi) -> None:
"""Initialize FitbitDeviceCoordinator."""
super().__init__(hass, _LOGGER, name="Fitbit", update_interval=UPDATE_INTERVAL)
self._api = api
async def _async_update_data(self) -> dict[str, FitbitDevice]:
"""Fetch data from API endpoint."""
async with asyncio.timeout(TIMEOUT):
try:
devices = await self._api.async_get_devices()
except FitbitAuthException as err:
raise ConfigEntryAuthFailed(err) from err
except FitbitApiException as err:
raise UpdateFailed(err) from err
return {device.id: device for device in devices}
@dataclass
class FitbitData:
"""Config Entry global data."""
api: FitbitApi
device_coordinator: FitbitDeviceCoordinator | None