diff --git a/custom_components/yasno_outages/coordinator.py b/custom_components/yasno_outages/coordinator.py index ef56798..bfec6e1 100644 --- a/custom_components/yasno_outages/coordinator.py +++ b/custom_components/yasno_outages/coordinator.py @@ -24,6 +24,8 @@ LOGGER = logging.getLogger(__name__) +TIMEFRAME_TO_CHECK = datetime.timedelta(hours=24) + class YasnoOutagesCoordinator(DataUpdateCoordinator): """Class to manage fetching Yasno outages data.""" @@ -91,23 +93,37 @@ async def async_fetch_translations(self) -> None: ) LOGGER.debug("Translations loaded: %s", self.translations) + def _get_next_event_of_type(self, state_type: str) -> CalendarEvent | None: + """Get the next event of a specific type.""" + now = dt_utils.now() + # Sort events to handle multi-day spanning events correctly + next_events = sorted( + self.get_events_between( + now, + now + TIMEFRAME_TO_CHECK, + translate=False, + ), + key=lambda event: event.start, + ) + LOGGER.debug("Next events: %s", next_events) + for event in next_events: + if self._event_to_state(event) == state_type and event.start > now: + return event + return None + @property def next_outage(self) -> datetime.datetime | None: """Get the next outage time.""" - next_events = self.get_next_events() - for event in next_events: - if self._event_to_state(event) == STATE_OFF: - return event.start - return None + event = self._get_next_event_of_type(STATE_OFF) + LOGGER.debug("Next outage: %s", event) + return event.start if event else None @property def next_possible_outage(self) -> datetime.datetime | None: - """Get the next outage time.""" - next_events = self.get_next_events() - for event in next_events: - if self._event_to_state(event) == STATE_MAYBE: - return event.start - return None + """Get the next possible outage time.""" + event = self._get_next_event_of_type(STATE_MAYBE) + LOGGER.debug("Next possible outage: %s", event) + return event.start if event else None @property def next_connectivity(self) -> datetime.datetime | None: @@ -119,11 +135,9 @@ def next_connectivity(self) -> datetime.datetime | None: return current_event.end # Otherwise, return the next maybe event's end - next_events = self.get_next_events() - for event in next_events: - if self._event_to_state(event) == STATE_MAYBE: - return event.end - return None + event = self._get_next_event_of_type(STATE_MAYBE) + LOGGER.debug("Next connectivity: %s", event) + return event.end if event else None @property def current_state(self) -> str: @@ -150,14 +164,6 @@ def get_events_between( self._get_calendar_event(event, translate=translate) for event in events ] - def get_next_events(self) -> CalendarEvent: - """Get the next event of a specific type.""" - now = dt_utils.now() - current_event = self.get_event_at(now) - start = current_event.end if current_event else now - end = start + datetime.timedelta(days=1) - return self.get_events_between(start, end, translate=False) - def _get_calendar_event( self, event: dict | None,