Home Assistant Unofficial Reference 2024.12.1
coordinator.py
Go to the documentation of this file.
1 """DataUpdateCoordinator for the Habitica integration."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Callable
6 from dataclasses import dataclass
7 from datetime import timedelta
8 from http import HTTPStatus
9 import logging
10 from typing import Any
11 
12 from aiohttp import ClientResponseError
13 from habitipy.aio import HabitipyAsync
14 
15 from homeassistant.config_entries import ConfigEntry
16 from homeassistant.core import HomeAssistant
17 from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
18 from homeassistant.helpers.debounce import Debouncer
19 from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
20 
21 from .const import DOMAIN
22 
23 _LOGGER = logging.getLogger(__name__)
24 
25 
26 @dataclass
28  """Coordinator data class."""
29 
30  user: dict[str, Any]
31  tasks: list[dict]
32 
33 
35  """Habitica Data Update Coordinator."""
36 
37  config_entry: ConfigEntry
38 
39  def __init__(self, hass: HomeAssistant, habitipy: HabitipyAsync) -> None:
40  """Initialize the Habitica data coordinator."""
41  super().__init__(
42  hass,
43  _LOGGER,
44  name=DOMAIN,
45  update_interval=timedelta(seconds=60),
46  request_refresh_debouncer=Debouncer(
47  hass,
48  _LOGGER,
49  cooldown=5,
50  immediate=False,
51  ),
52  )
53  self.apiapi = habitipy
54  self.contentcontent: dict[str, Any] = {}
55 
56  async def _async_update_data(self) -> HabiticaData:
57  try:
58  user_response = await self.apiapi.user.get()
59  tasks_response = await self.apiapi.tasks.user.get()
60  tasks_response.extend(await self.apiapi.tasks.user.get(type="completedTodos"))
61  if not self.contentcontent:
62  self.contentcontent = await self.apiapi.content.get(
63  language=user_response["preferences"]["language"]
64  )
65  except ClientResponseError as error:
66  if error.status == HTTPStatus.TOO_MANY_REQUESTS:
67  _LOGGER.debug("Rate limit exceeded, will try again later")
68  return self.datadata
69  raise UpdateFailed(f"Unable to connect to Habitica: {error}") from error
70 
71  return HabiticaData(user=user_response, tasks=tasks_response)
72 
73  async def execute(
74  self, func: Callable[[HabiticaDataUpdateCoordinator], Any]
75  ) -> None:
76  """Execute an API call."""
77 
78  try:
79  await func(self)
80  except ClientResponseError as e:
81  if e.status == HTTPStatus.TOO_MANY_REQUESTS:
83  translation_domain=DOMAIN,
84  translation_key="setup_rate_limit_exception",
85  ) from e
86  raise HomeAssistantError(
87  translation_domain=DOMAIN,
88  translation_key="service_call_exception",
89  ) from e
90  else:
91  await self.async_request_refreshasync_request_refresh()
None __init__(self, HomeAssistant hass, HabitipyAsync habitipy)
Definition: coordinator.py:39
None execute(self, Callable[[HabiticaDataUpdateCoordinator], Any] func)
Definition: coordinator.py:75