Home Assistant Unofficial Reference 2024.12.1
calendar.py
Go to the documentation of this file.
1 """Support for Vulcan Calendar platform."""
2 
3 from __future__ import annotations
4 
5 from datetime import date, datetime, timedelta
6 import logging
7 from typing import cast
8 from zoneinfo import ZoneInfo
9 
10 from aiohttp import ClientConnectorError
11 from vulcan import UnauthorizedCertificateException
12 
14  ENTITY_ID_FORMAT,
15  CalendarEntity,
16  CalendarEvent,
17 )
18 from homeassistant.config_entries import ConfigEntry
19 from homeassistant.core import HomeAssistant
20 from homeassistant.exceptions import ConfigEntryAuthFailed
21 from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
22 from homeassistant.helpers.entity import generate_entity_id
23 from homeassistant.helpers.entity_platform import AddEntitiesCallback
24 
25 from . import DOMAIN
26 from .fetch_data import get_lessons, get_student_info
27 
28 _LOGGER = logging.getLogger(__name__)
29 
30 
32  hass: HomeAssistant,
33  config_entry: ConfigEntry,
34  async_add_entities: AddEntitiesCallback,
35 ) -> None:
36  """Set up the calendar platform for entity."""
37  client = hass.data[DOMAIN][config_entry.entry_id]
38  data = {
39  "student_info": await get_student_info(
40  client, config_entry.data.get("student_id")
41  ),
42  }
44  [
46  client,
47  data,
49  ENTITY_ID_FORMAT,
50  f"vulcan_calendar_{data['student_info']['full_name']}",
51  hass=hass,
52  ),
53  )
54  ],
55  )
56 
57 
59  """A calendar entity."""
60 
61  _attr_has_entity_name = True
62  _attr_translation_key = "calendar"
63 
64  def __init__(self, client, data, entity_id) -> None:
65  """Create the Calendar entity."""
66  self._event_event: CalendarEvent | None = None
67  self.clientclient = client
68  self.entity_identity_identity_id = entity_id
69  student_info = data["student_info"]
70  self._attr_unique_id_attr_unique_id = f"vulcan_calendar_{student_info['id']}"
71  self._attr_device_info_attr_device_info = DeviceInfo(
72  identifiers={(DOMAIN, f"calendar_{student_info['id']}")},
73  entry_type=DeviceEntryType.SERVICE,
74  name=cast(str, student_info["full_name"]),
75  model=(
76  f"{student_info['full_name']} -"
77  f" {student_info['class']} {student_info['school']}"
78  ),
79  manufacturer="Uonet +",
80  configuration_url=(
81  f"https://uonetplus.vulcan.net.pl/{student_info['symbol']}"
82  ),
83  )
84 
85  @property
86  def event(self) -> CalendarEvent | None:
87  """Return the next upcoming event."""
88  return self._event_event
89 
90  async def async_get_events(
91  self, hass: HomeAssistant, start_date: datetime, end_date: datetime
92  ) -> list[CalendarEvent]:
93  """Get all events in a specific time frame."""
94  try:
95  events = await get_lessons(
96  self.clientclient,
97  date_from=start_date,
98  date_to=end_date,
99  )
100  except UnauthorizedCertificateException as err:
101  raise ConfigEntryAuthFailed(
102  "The certificate is not authorized, please authorize integration again"
103  ) from err
104  except ClientConnectorError as err:
105  if self.availableavailable:
106  _LOGGER.warning(
107  "Connection error - please check your internet connection: %s", err
108  )
109  events = []
110 
111  event_list = []
112  for item in events:
113  event = CalendarEvent(
114  start=datetime.combine(
115  item["date"], item["time"].from_, ZoneInfo("Europe/Warsaw")
116  ),
117  end=datetime.combine(
118  item["date"], item["time"].to, ZoneInfo("Europe/Warsaw")
119  ),
120  summary=item["lesson"],
121  location=item["room"],
122  description=item["teacher"],
123  )
124 
125  event_list.append(event)
126 
127  return event_list
128 
129  async def async_update(self) -> None:
130  """Get the latest data."""
131 
132  try:
133  events = await get_lessons(self.clientclient)
134 
135  if not self.availableavailable:
136  _LOGGER.warning("Restored connection with API")
137  self._attr_available_attr_available = True
138 
139  if events == []:
140  events = await get_lessons(
141  self.clientclient,
142  date_to=date.today() + timedelta(days=7),
143  )
144  if events == []:
145  self._event_event = None
146  return
147  except UnauthorizedCertificateException as err:
148  raise ConfigEntryAuthFailed(
149  "The certificate is not authorized, please authorize integration again"
150  ) from err
151  except ClientConnectorError as err:
152  if self.availableavailable:
153  _LOGGER.warning(
154  "Connection error - please check your internet connection: %s", err
155  )
156  self._attr_available_attr_available = False
157  return
158 
159  new_event = min(
160  events,
161  key=lambda d: (
162  datetime.combine(d["date"], d["time"].to) < datetime.now(),
163  abs(datetime.combine(d["date"], d["time"].to) - datetime.now()),
164  ),
165  )
166  self._event_event = CalendarEvent(
167  start=datetime.combine(
168  new_event["date"], new_event["time"].from_, ZoneInfo("Europe/Warsaw")
169  ),
170  end=datetime.combine(
171  new_event["date"], new_event["time"].to, ZoneInfo("Europe/Warsaw")
172  ),
173  summary=new_event["lesson"],
174  location=new_event["room"],
175  description=new_event["teacher"],
176  )
list[CalendarEvent] async_get_events(self, HomeAssistant hass, datetime start_date, datetime end_date)
Definition: calendar.py:92
None __init__(self, client, data, entity_id)
Definition: calendar.py:64
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: calendar.py:35
def get_student_info(client, student_id)
Definition: fetch_data.py:81
def get_lessons(client, date_from=None, date_to=None)
Definition: fetch_data.py:4
str generate_entity_id(str entity_id_format, str|None name, list[str]|None current_ids=None, HomeAssistant|None hass=None)
Definition: entity.py:108