Home Assistant Unofficial Reference 2024.12.1
calendar.py
Go to the documentation of this file.
1 """Calendar platform for La Marzocco espresso machines."""
2 
3 from collections.abc import Iterator
4 from datetime import datetime, timedelta
5 
6 from pylamarzocco.models import LaMarzoccoWakeUpSleepEntry
7 
8 from homeassistant.components.calendar import CalendarEntity, CalendarEvent
9 from homeassistant.core import HomeAssistant
10 from homeassistant.helpers.entity_platform import AddEntitiesCallback
11 from homeassistant.util import dt as dt_util
12 
13 from .coordinator import LaMarzoccoConfigEntry, LaMarzoccoUpdateCoordinator
14 from .entity import LaMarzoccoBaseEntity
15 
16 CALENDAR_KEY = "auto_on_off_schedule"
17 
18 DAY_OF_WEEK = [
19  "monday",
20  "tuesday",
21  "wednesday",
22  "thursday",
23  "friday",
24  "saturday",
25  "sunday",
26 ]
27 
28 
30  hass: HomeAssistant,
31  entry: LaMarzoccoConfigEntry,
32  async_add_entities: AddEntitiesCallback,
33 ) -> None:
34  """Set up switch entities and services."""
35 
36  coordinator = entry.runtime_data
38  LaMarzoccoCalendarEntity(coordinator, CALENDAR_KEY, wake_up_sleep_entry)
39  for wake_up_sleep_entry in coordinator.device.config.wake_up_sleep_entries.values()
40  )
41 
42 
44  """Class representing a La Marzocco calendar."""
45 
46  _attr_translation_key = CALENDAR_KEY
47 
48  def __init__(
49  self,
50  coordinator: LaMarzoccoUpdateCoordinator,
51  key: str,
52  wake_up_sleep_entry: LaMarzoccoWakeUpSleepEntry,
53  ) -> None:
54  """Set up calendar."""
55  super().__init__(coordinator, f"{key}_{wake_up_sleep_entry.entry_id}")
56  self.wake_up_sleep_entrywake_up_sleep_entry = wake_up_sleep_entry
57  self._attr_translation_placeholders_attr_translation_placeholders = {"id": wake_up_sleep_entry.entry_id}
58 
59  @property
60  def event(self) -> CalendarEvent | None:
61  """Return the next upcoming event."""
62  now = dt_util.now()
63 
64  events = self._get_events_get_events(
65  start_date=now,
66  end_date=now + timedelta(days=7), # only need to check a week ahead
67  )
68  return next(iter(events), None)
69 
70  async def async_get_events(
71  self,
72  hass: HomeAssistant,
73  start_date: datetime,
74  end_date: datetime,
75  ) -> list[CalendarEvent]:
76  """Return calendar events within a datetime range."""
77 
78  return self._get_events_get_events(
79  start_date=start_date,
80  end_date=end_date,
81  )
82 
84  self,
85  start_date: datetime,
86  end_date: datetime,
87  ) -> list[CalendarEvent]:
88  """Get calendar events within a datetime range."""
89 
90  events: list[CalendarEvent] = []
91  for date in self._get_date_range_get_date_range(start_date, end_date):
92  if scheduled := self._async_get_calendar_event_async_get_calendar_event(date):
93  if scheduled.end < start_date:
94  continue
95  if scheduled.start > end_date:
96  continue
97  events.append(scheduled)
98  return events
99 
101  self, start_date: datetime, end_date: datetime
102  ) -> Iterator[datetime]:
103  current_date = start_date
104  while current_date.date() < end_date.date():
105  yield current_date
106  current_date += timedelta(days=1)
107  yield end_date
108 
109  def _async_get_calendar_event(self, date: datetime) -> CalendarEvent | None:
110  """Return calendar event for a given weekday."""
111 
112  # check first if auto/on off is turned on in general
113  if not self.wake_up_sleep_entrywake_up_sleep_entry.enabled:
114  return None
115 
116  # parse the schedule for the day
117 
118  if DAY_OF_WEEK[date.weekday()] not in self.wake_up_sleep_entrywake_up_sleep_entry.days:
119  return None
120 
121  hour_on, minute_on = self.wake_up_sleep_entrywake_up_sleep_entry.time_on.split(":")
122  hour_off, minute_off = self.wake_up_sleep_entrywake_up_sleep_entry.time_off.split(":")
123 
124  # if off time is 24:00, then it means the off time is the next day
125  # only for legacy schedules
126  day_offset = 0
127  if hour_off == "24":
128  day_offset = 1
129  hour_off = "0"
130 
131  end_date = date.replace(
132  hour=int(hour_off),
133  minute=int(minute_off),
134  )
135  end_date += timedelta(days=day_offset)
136 
137  return CalendarEvent(
138  start=date.replace(
139  hour=int(hour_on),
140  minute=int(minute_on),
141  ),
142  end=end_date,
143  summary=f"Machine {self.coordinator.config_entry.title} on",
144  description="Machine is scheduled to turn on at the start time and off at the end time",
145  )
CalendarEvent|None _async_get_calendar_event(self, datetime date)
Definition: calendar.py:109
None __init__(self, LaMarzoccoUpdateCoordinator coordinator, str key, LaMarzoccoWakeUpSleepEntry wake_up_sleep_entry)
Definition: calendar.py:53
Iterator[datetime] _get_date_range(self, datetime start_date, datetime end_date)
Definition: calendar.py:102
list[CalendarEvent] async_get_events(self, HomeAssistant hass, datetime start_date, datetime end_date)
Definition: calendar.py:75
list[CalendarEvent] _get_events(self, datetime start_date, datetime end_date)
Definition: calendar.py:87
None async_setup_entry(HomeAssistant hass, LaMarzoccoConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: calendar.py:33