core/homeassistant/components/lamarzocco/calendar.py

114 lines
3.7 KiB
Python
Raw Normal View History

"""Calendar platform for La Marzocco espresso machines."""
from collections.abc import Iterator
from datetime import datetime, timedelta
from homeassistant.components.calendar import CalendarEntity, CalendarEvent
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util import dt as dt_util
from .const import DOMAIN
from .entity import LaMarzoccoBaseEntity
CALENDAR_KEY = "auto_on_off_schedule"
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up switch entities and services."""
coordinator = hass.data[DOMAIN][config_entry.entry_id]
async_add_entities([LaMarzoccoCalendarEntity(coordinator, CALENDAR_KEY)])
class LaMarzoccoCalendarEntity(LaMarzoccoBaseEntity, CalendarEntity):
"""Class representing a La Marzocco calendar."""
_attr_translation_key = CALENDAR_KEY
@property
def event(self) -> CalendarEvent | None:
"""Return the next upcoming event."""
now = dt_util.now()
events = self._get_events(
start_date=now,
end_date=now + timedelta(days=7), # only need to check a week ahead
)
return next(iter(events), None)
async def async_get_events(
self,
hass: HomeAssistant,
start_date: datetime,
end_date: datetime,
) -> list[CalendarEvent]:
"""Return calendar events within a datetime range."""
return self._get_events(
start_date=start_date,
end_date=end_date,
)
def _get_events(
self,
start_date: datetime,
end_date: datetime,
) -> list[CalendarEvent]:
"""Get calendar events within a datetime range."""
events: list[CalendarEvent] = []
for date in self._get_date_range(start_date, end_date):
if scheduled := self._async_get_calendar_event(date):
if scheduled.end < start_date:
continue
if scheduled.start > end_date:
continue
events.append(scheduled)
return events
def _get_date_range(
self, start_date: datetime, end_date: datetime
) -> Iterator[datetime]:
current_date = start_date
while current_date.date() < end_date.date():
yield current_date
current_date += timedelta(days=1)
yield end_date
def _async_get_calendar_event(self, date: datetime) -> CalendarEvent | None:
"""Return calendar event for a given weekday."""
# check first if auto/on off is turned on in general
# because could still be on for that day but disabled
if self.coordinator.lm.current_status["global_auto"] != "Enabled":
return None
# parse the schedule for the day
schedule_day = self.coordinator.lm.schedule[date.weekday()]
if schedule_day["enable"] == "Disabled":
return None
hour_on, minute_on = schedule_day["on"].split(":")
hour_off, minute_off = schedule_day["off"].split(":")
return CalendarEvent(
start=date.replace(
hour=int(hour_on),
minute=int(minute_on),
second=0,
microsecond=0,
),
end=date.replace(
hour=int(hour_off),
minute=int(minute_off),
second=0,
microsecond=0,
),
summary=f"Machine {self.coordinator.config_entry.title} on",
description="Machine is scheduled to turn on at the start time and off at the end time",
)