Home Assistant Unofficial Reference 2024.12.1
coordinator.py
Go to the documentation of this file.
1 """Define an object to manage fetching Mealie data."""
2 
3 from __future__ import annotations
4 
5 from abc import abstractmethod
6 from dataclasses import dataclass
7 from datetime import timedelta
8 
9 from aiomealie import (
10  MealieAuthenticationError,
11  MealieClient,
12  MealieConnectionError,
13  Mealplan,
14  MealplanEntryType,
15  ShoppingItem,
16  ShoppingList,
17  Statistics,
18 )
19 
20 from homeassistant.config_entries import ConfigEntry
21 from homeassistant.core import HomeAssistant
22 from homeassistant.exceptions import ConfigEntryAuthFailed
23 from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
24 import homeassistant.util.dt as dt_util
25 
26 from .const import LOGGER
27 
28 WEEK = timedelta(days=7)
29 
30 
31 @dataclass
32 class MealieData:
33  """Mealie data type."""
34 
35  client: MealieClient
36  mealplan_coordinator: MealieMealplanCoordinator
37  shoppinglist_coordinator: MealieShoppingListCoordinator
38  statistics_coordinator: MealieStatisticsCoordinator
39 
40 
41 type MealieConfigEntry = ConfigEntry[MealieData]
42 
43 
44 class MealieDataUpdateCoordinator[_DataT](DataUpdateCoordinator[_DataT]):
45  """Base coordinator."""
46 
47  config_entry: MealieConfigEntry
48  _name: str
49  _update_interval: timedelta
50 
51  def __init__(self, hass: HomeAssistant, client: MealieClient) -> None:
52  """Initialize the Mealie data coordinator."""
53  super().__init__(
54  hass,
55  LOGGER,
56  name=self._name,
57  update_interval=self._update_interval_update_interval,
58  )
59  self.clientclient = client
60 
61  async def _async_update_data(self) -> _DataT:
62  """Fetch data from Mealie."""
63  try:
64  return await self._async_update_internal_async_update_internal()
65  except MealieAuthenticationError as error:
66  raise ConfigEntryAuthFailed from error
67  except MealieConnectionError as error:
68  raise UpdateFailed(error) from error
69 
70  @abstractmethod
71  async def _async_update_internal(self) -> _DataT:
72  """Fetch data from Mealie."""
73 
74 
75 class MealieMealplanCoordinator(
76  MealieDataUpdateCoordinator[dict[MealplanEntryType, list[Mealplan]]]
77 ):
78  """Class to manage fetching Mealie data."""
79 
80  _name = "MealieMealplan"
81  _update_interval = timedelta(hours=1)
82 
83  async def _async_update_internal(self) -> dict[MealplanEntryType, list[Mealplan]]:
84  next_week = dt_util.now() + WEEK
85  current_date = dt_util.now().date()
86  next_week_date = next_week.date()
87  response = await self.clientclient.get_mealplans(current_date, next_week_date)
88  res: dict[MealplanEntryType, list[Mealplan]] = {
89  type_: [] for type_ in MealplanEntryType
90  }
91  for meal in response.items:
92  res[meal.entry_type].append(meal)
93  return res
94 
95 
96 @dataclass
98  """Data class for shopping list data."""
99 
100  shopping_list: ShoppingList
101  items: list[ShoppingItem]
102 
103 
105  MealieDataUpdateCoordinator[dict[str, ShoppingListData]]
106 ):
107  """Class to manage fetching Mealie Shopping list data."""
108 
109  _name = "MealieShoppingList"
110  _update_interval = timedelta(minutes=5)
111 
113  self,
114  ) -> dict[str, ShoppingListData]:
115  shopping_list_items = {}
116  shopping_lists = (await self.clientclient.get_shopping_lists()).items
117  for shopping_list in shopping_lists:
118  shopping_list_id = shopping_list.list_id
119 
120  shopping_items = (
121  await self.clientclient.get_shopping_items(shopping_list_id)
122  ).items
123 
124  shopping_list_items[shopping_list_id] = ShoppingListData(
125  shopping_list=shopping_list, items=shopping_items
126  )
127  return shopping_list_items
128 
129 
131  """Class to manage fetching Mealie Statistics data."""
132 
133  _name = "MealieStatistics"
134  _update_interval = timedelta(minutes=15)
135 
137  self,
138  ) -> Statistics:
139  return await self.clientclient.get_statistics()
None __init__(self, HomeAssistant hass, MealieClient client)
Definition: coordinator.py:51
dict[MealplanEntryType, list[Mealplan]] _async_update_internal(self)
Definition: coordinator.py:83
list[dict[str, Any]]|None get_statistics(data, IstaConsumptionType consumption_type, IstaValueType|None value_type=None)
Definition: util.py:105