Skip to content

Commit

Permalink
Holiday update calendar once per day (#116421)
Browse files Browse the repository at this point in the history
  • Loading branch information
gjohansson-ST committed May 7, 2024
1 parent 018e773 commit b9d26c0
Showing 1 changed file with 36 additions and 5 deletions.
41 changes: 36 additions & 5 deletions homeassistant/components/holiday/calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@

from __future__ import annotations

from datetime import datetime
from datetime import datetime, timedelta

from holidays import HolidayBase, country_holidays

from homeassistant.components.calendar import CalendarEntity, CalendarEvent
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_COUNTRY
from homeassistant.core import HomeAssistant
from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.event import async_track_point_in_utc_time
from homeassistant.util import dt as dt_util

from .const import CONF_PROVINCE, DOMAIN
Expand Down Expand Up @@ -77,6 +78,9 @@ class HolidayCalendarEntity(CalendarEntity):

_attr_has_entity_name = True
_attr_name = None
_attr_event: CalendarEvent | None = None
_attr_should_poll = False
unsub: CALLBACK_TYPE | None = None

def __init__(
self,
Expand All @@ -100,14 +104,36 @@ def __init__(
)
self._obj_holidays = obj_holidays

@property
def event(self) -> CalendarEvent | None:
def get_next_interval(self, now: datetime) -> datetime:
"""Compute next time an update should occur."""
tomorrow = dt_util.as_local(now) + timedelta(days=1)
return dt_util.start_of_local_day(tomorrow)

def _update_state_and_setup_listener(self) -> None:
"""Update state and setup listener for next interval."""
now = dt_util.utcnow()
self._attr_event = self.update_event(now)
self.unsub = async_track_point_in_utc_time(
self.hass, self.point_in_time_listener, self.get_next_interval(now)
)

@callback
def point_in_time_listener(self, time_date: datetime) -> None:
"""Get the latest data and update state."""
self._update_state_and_setup_listener()
self.async_write_ha_state()

async def async_added_to_hass(self) -> None:
"""Set up first update."""
self._update_state_and_setup_listener()

def update_event(self, now: datetime) -> CalendarEvent | None:
"""Return the next upcoming event."""
next_holiday = None
for holiday_date, holiday_name in sorted(
self._obj_holidays.items(), key=lambda x: x[0]
):
if holiday_date >= dt_util.now().date():
if holiday_date >= now.date():
next_holiday = (holiday_date, holiday_name)
break

Expand All @@ -121,6 +147,11 @@ def event(self) -> CalendarEvent | None:
location=self._location,
)

@property
def event(self) -> CalendarEvent | None:
"""Return the next upcoming event."""
return self._attr_event

async def async_get_events(
self, hass: HomeAssistant, start_date: datetime, end_date: datetime
) -> list[CalendarEvent]:
Expand Down

0 comments on commit b9d26c0

Please sign in to comment.