From 89e5ad679599e34a3711bdbb6c64f1b562feffe2 Mon Sep 17 00:00:00 2001 From: Andrew Grimberg Date: Fri, 14 Jan 2022 12:13:06 -0800 Subject: [PATCH] Fix: Correct fetch limit Durring manual testing it was found that setting the number of days into the future to fetch was having no affect on the number of events that were being attached to the calendar. * Taught the calendar how to properly limit the events stored * Taught the sensors how to deal with not having enough calendar events for the number of sensors Issue: #31 Signed-off-by: Andrew Grimberg --- custom_components/rental_control/__init__.py | 22 +++++++++++++++++--- custom_components/rental_control/sensor.py | 18 +++++++++++++++- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/custom_components/rental_control/__init__.py b/custom_components/rental_control/__init__.py index c85de46..c8cc5e6 100644 --- a/custom_components/rental_control/__init__.py +++ b/custom_components/rental_control/__init__.py @@ -195,11 +195,18 @@ def update_config(self, config): self.days = config.get(CONF_DAYS) self.verify_ssl = config.get(CONF_VERIFY_SSL) + # updated the calendar in case the fetch days has changed + self.calendar = self._refresh_event_dict() + def _ical_parser(self, calendar, from_date, to_date): """Return a sorted list of events from a icalendar object.""" events = [] + _LOGGER.debug( + "In _ical_parser:: from_date: %s; to_date: %s", from_date, to_date + ) + for event in calendar.walk("VEVENT"): # RRULEs should not exist in AirBnB bookings, so log and error and # skip @@ -213,13 +220,14 @@ def _ical_parser(self, calendar, from_date, to_date): # Just ignore events that ended a long time ago if "DTEND" in event and event[ "DTEND" - ].dt.date() < from_date.date() - timedelta(days=30): + ].dt < from_date.date() - timedelta(days=30): continue except Exception: # pylint: disable=broad-except pass + try: # Ignore dates that are too far in the future - if "DSTART" in event and event["DTSTART"].dt <= to_date.date(): + if "DTSTART" in event and event["DTSTART"].dt > to_date.date(): continue except Exception: # pylint: disable=broad-except pass @@ -238,7 +246,7 @@ def _ical_parser(self, calendar, from_date, to_date): if "DTEND" not in event: dtend = dtstart else: - _LOGGER.debug("DTEND in event") + _LOGGER.debug("DTEND in event: %s", event["DTEND"].dt) dtend = datetime.combine( event["DTEND"].dt, self.checkout, dt.DEFAULT_TIME_ZONE ) @@ -288,3 +296,11 @@ def _ical_event_dict(self, start, end, from_date, event): } _LOGGER.debug("Event to add: %s", str(event_dict)) return event_dict + + def _refresh_event_dict(self): + """Ensure that all events in the calendar are start before max days.""" + + cal = self.calendar + days = dt.start_of_local_day() + timedelta(days=self.days) + + return [x for x in cal if x["start"].date() <= days.date()] diff --git a/custom_components/rental_control/sensor.py b/custom_components/rental_control/sensor.py index 8bf77c7..108b140 100644 --- a/custom_components/rental_control/sensor.py +++ b/custom_components/rental_control/sensor.py @@ -67,7 +67,7 @@ def __init__(self, hass, rental_control_events, sensor_name, event_number): hass=self._hass, ) self._event_attributes = { - "summary": None, + "summary": "No reservation", "description": None, "location": None, "start": None, @@ -140,3 +140,19 @@ async def async_update(self): self._state = f"{name} - {start.strftime('%-d %B %Y')}" if not val.get("all_day"): self._state += f" {start.strftime('%H:%M')}" + else: + # No reservations + _LOGGER.debug( + "No events available for sensor %s, removing from calendar %s", + str(self._event_number), + self.name, + ) + self._event_attributes = { + "summary": "No reservation", + "description": None, + "location": None, + "start": None, + "end": None, + "eta": None, + } + self._state = "No reservation"