137 lines
4.9 KiB
Python
137 lines
4.9 KiB
Python
"""Anniversaries calendar."""
|
|
import logging
|
|
from datetime import datetime, timedelta
|
|
|
|
from homeassistant.components.calendar import CalendarEntity, CalendarEvent
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.util import Throttle
|
|
|
|
from .const import CALENDAR_NAME, CALENDAR_PLATFORM, DOMAIN, SENSOR_PLATFORM
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=1)
|
|
|
|
|
|
async def async_setup_platform(
|
|
hass, config, async_add_entities, discovery_info=None
|
|
) -> None:
|
|
"""Add calendar entities to HA, of there are calendar instances."""
|
|
# pylint: disable=unused-argument
|
|
# Only single instance allowed
|
|
if not AnniversariesCalendar.instances:
|
|
async_add_entities([AnniversariesCalendar()], True)
|
|
|
|
|
|
class AnniversariesCalendar(CalendarEntity):
|
|
"""The Anniversaries collection calendar class."""
|
|
|
|
instances = False
|
|
|
|
def __init__(self) -> None:
|
|
"""Create empty calendar."""
|
|
self._cal_data: dict = {}
|
|
self._attr_name = CALENDAR_NAME
|
|
AnniversariesCalendar.instances = True
|
|
|
|
@property
|
|
def event(self) -> CalendarEvent | None:
|
|
"""Return the next upcoming event."""
|
|
return self.hass.data[DOMAIN][CALENDAR_PLATFORM].event
|
|
|
|
@property
|
|
def name(self) -> str | None:
|
|
"""Return the name of the entity."""
|
|
return self._attr_name
|
|
|
|
async def async_update(self) -> None:
|
|
"""Update all calendars."""
|
|
await self.hass.data[DOMAIN][CALENDAR_PLATFORM].async_update()
|
|
|
|
async def async_get_events(
|
|
self, hass: HomeAssistant, start_date: datetime, end_date: datetime
|
|
) -> list[CalendarEvent]:
|
|
"""Get all events in a specific time frame."""
|
|
return await self.hass.data[DOMAIN][CALENDAR_PLATFORM].async_get_events(
|
|
hass, start_date, end_date
|
|
)
|
|
|
|
@property
|
|
def extra_state_attributes(self) -> dict | None:
|
|
"""Return the device state attributes."""
|
|
if self.hass.data[DOMAIN][CALENDAR_PLATFORM].event is None:
|
|
# No tasks, we don't need to show anything.
|
|
return None
|
|
return {}
|
|
|
|
|
|
class EntitiesCalendarData:
|
|
"""Class used by the Entities Calendar class to hold all entity events."""
|
|
|
|
__slots__ = "_hass", "event", "entities", "_throttle"
|
|
|
|
def __init__(self, hass: HomeAssistant) -> None:
|
|
"""Initialize an Entities Calendar Data."""
|
|
self._hass = hass
|
|
self.event: CalendarEvent | None = None
|
|
self.entities: list[str] = []
|
|
|
|
def add_entity(self, entity_id: str) -> None:
|
|
"""Append entity ID to the calendar."""
|
|
if entity_id not in self.entities:
|
|
self.entities.append(entity_id)
|
|
|
|
def remove_entity(self, entity_id: str) -> None:
|
|
"""Remove entity ID from the calendar."""
|
|
if entity_id in self.entities:
|
|
self.entities.remove(entity_id)
|
|
|
|
async def async_get_events(
|
|
self, hass: HomeAssistant, start_datetime: datetime, end_datetime: datetime
|
|
) -> list[CalendarEvent]:
|
|
"""Get all events in a specific time frame."""
|
|
events: list[CalendarEvent] = []
|
|
_LOGGER.debug("Anniversaries Calendar - Get Events")
|
|
if SENSOR_PLATFORM not in hass.data[DOMAIN]:
|
|
return events
|
|
start_date = start_datetime.date()
|
|
end_date = end_datetime.date()
|
|
for ent in self.entities:
|
|
_LOGGER.debug("Get Events: Entity Name: " + str(ent))
|
|
if (ent not in hass.data[DOMAIN][SENSOR_PLATFORM]):
|
|
continue
|
|
entity = self._hass.data[DOMAIN][SENSOR_PLATFORM][ent]
|
|
if (
|
|
entity
|
|
and entity.name
|
|
and entity._next_date.date()
|
|
and start_date <= entity._next_date.date() <= end_date
|
|
):
|
|
event = CalendarEvent(
|
|
summary=entity.name,
|
|
start=entity._next_date.date(),
|
|
end=entity._next_date.date() + timedelta(days=1),
|
|
description=entity.extra_state_attributes["description"]
|
|
if "description" in entity.extra_state_attributes
|
|
else None,
|
|
)
|
|
events.append(event)
|
|
return events
|
|
|
|
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
|
async def async_update(self) -> None:
|
|
"""Get the latest data."""
|
|
_LOGGER.debug("Update anniversary calendar")
|
|
for ent in self.entities:
|
|
_LOGGER.debug("Update Entity Name: " + str(ent))
|
|
entity = self._hass.data[DOMAIN][SENSOR_PLATFORM][ent]
|
|
if entity and entity.name and entity._date:
|
|
self.event = CalendarEvent(
|
|
summary=entity.name,
|
|
start=entity._next_date.date(),
|
|
end=entity._next_date.date() + timedelta(days=1),
|
|
description=entity.extra_state_attributes["description"]
|
|
if "description" in entity.extra_state_attributes
|
|
else None,
|
|
)
|