Skip to content

Commit

Permalink
Merge pull request #95 from tykeal/fix_calendar
Browse files Browse the repository at this point in the history
Refactor: Update calendar data model
  • Loading branch information
tykeal authored May 10, 2022
2 parents 771e217 + 58bb451 commit f79969d
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 58 deletions.
51 changes: 26 additions & 25 deletions custom_components/rental_control/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
# Andrew Grimberg - Initial implementation
##############################################################################
"""The Rental Control integration."""
from __future__ import annotations

import asyncio
import logging
from datetime import datetime
Expand All @@ -21,6 +23,7 @@
import homeassistant.helpers.config_validation as cv
import icalendar
import voluptuous as vol
from homeassistant.components.calendar import CalendarEvent
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_NAME
from homeassistant.const import CONF_URL
Expand Down Expand Up @@ -224,22 +227,22 @@ def version(self):

async def async_get_events(
self, hass, start_date, end_date
): # pylint: disable=unused-argument
) -> list[CalendarEvent]: # pylint: disable=unused-argument
"""Get list of upcoming events."""
_LOGGER.debug("Running ICalEvents async_get_events")
events = []
if len(self.calendar) > 0:
for event in self.calendar:
_LOGGER.debug(
"Checking if event %s has start %s and end %s within in the limit: %s and %s",
event["summary"],
event["start"],
event["end"],
event.summary,
event.start,
event.end,
start_date,
end_date,
)

if event["start"] < end_date and event["end"] > start_date:
if event.start < end_date and event.end > start_date:
_LOGGER.debug("... and it has")
events.append(event)
return events
Expand Down Expand Up @@ -364,16 +367,15 @@ def _ical_parser(self, calendar, from_date, to_date):
if self.event_prefix:
event["SUMMARY"] = self.event_prefix + " " + event["SUMMARY"]

event_dict = self._ical_event_dict(start, end, from_date, event)
if event_dict:
events.append(event_dict)
cal_event = self._ical_event(start, end, from_date, event)
if cal_event:
events.append(cal_event)

sorted_events = sorted(events, key=lambda k: k["start"])
sorted_events = sorted(events, key=lambda k: k.start)
return sorted_events

def _ical_event_dict(self, start, end, from_date, event):
def _ical_event(self, start, end, from_date, event) -> CalendarEvent | None:
"""Ensure that events are within the start and end."""

# Skip this event if it's in the past
if end.date() < from_date.date():
_LOGGER.debug("This event has already ended")
Expand All @@ -394,24 +396,23 @@ def _ical_event_dict(self, start, end, from_date, event):
self.timezone,
start.astimezone(self.timezone),
)
event_dict = {
"summary": event.get("SUMMARY", "Unknown"),
"start": start.astimezone(self.timezone),
"end": end.astimezone(self.timezone),
"location": event.get("LOCATION"),
"description": event.get("DESCRIPTION"),
"all_day": self.all_day,
}
_LOGGER.debug("Event to add: %s", str(event_dict))
return event_dict
cal_event = CalendarEvent(
description=event.get("DESCRIPTION"),
end=end.astimezone(self.timezone),
location=event.get("LOCATION"),
summary=event.get("SUMMARY", "Unknown"),
start=start.astimezone(self.timezone),
)
_LOGGER.debug("Event to add: %s", str(CalendarEvent))
return cal_event

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()]
return [x for x in cal if x.start.date() <= days.date()]

async def _refresh_calendar(self):
"""Update list of upcoming events."""
Expand Down Expand Up @@ -439,11 +440,11 @@ async def _refresh_calendar(self):
if len(self.calendar) > 0:
found_next_event = False
for event in self.calendar:
if event["end"] > dt.now() and not found_next_event:
if event.end > dt.now() and not found_next_event:
_LOGGER.debug(
"Event %s is the first event with end in the future: %s",
event["summary"],
event["end"],
event.summary,
event.end,
)
self.event = event
found_next_event = True
29 changes: 11 additions & 18 deletions custom_components/rental_control/calendar.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
"""Support for iCal-URLs."""
import copy
from __future__ import annotations

import logging

from homeassistant.components.calendar import CalendarEventDevice
from homeassistant.components.calendar import CalendarEntity
from homeassistant.components.calendar import CalendarEvent
from homeassistant.const import CONF_NAME
from homeassistant.helpers.entity import EntityCategory

Expand All @@ -23,12 +25,12 @@ async def async_setup_entry(hass, config_entry, async_add_entities):

rental_control_events = hass.data[DOMAIN][config_entry.unique_id]

calendar = ICalCalendarEventDevice(hass, f"{NAME} {name}", rental_control_events)
calendar = RentalCalendar(hass, f"{NAME} {name}", rental_control_events)

async_add_entities([calendar], True)


class ICalCalendarEventDevice(CalendarEventDevice):
class RentalCalendar(CalendarEntity):
"""A device for getting the next Task from a WebDav Calendar."""

def __init__(
Expand All @@ -52,7 +54,7 @@ def entity_category(self):
return self._entity_category

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

Expand All @@ -66,24 +68,15 @@ def unique_id(self):
"""Return the unique_id."""
return self._unique_id

async def async_get_events(self, hass, start_date, end_date):
async def async_get_events(self, hass, start_date, end_date) -> list[CalendarEvent]:
"""Get all events in a specific time frame."""
_LOGGER.debug("Running ICalCalendarEventDevice async get events")
_LOGGER.debug("Running RentalCalendar async get events")
return await self.rental_control_events.async_get_events(
hass, start_date, end_date
)

async def async_update(self):
"""Update event data."""
_LOGGER.debug("Running ICalCalendarEventDevice async update for %s", self.name)
_LOGGER.debug("Running RentalCalendar async update for %s", self.name)
await self.rental_control_events.update()
event = copy.deepcopy(self.rental_control_events.event)
if event is None:
self._event = event
return
self._event = copy.deepcopy(event)
self._event["start"] = {}
self._event["end"] = {}
self._event["start"]["dateTime"] = event["start"].isoformat()
self._event["end"]["dateTime"] = event["end"].isoformat()
self._event["all_day"] = event["all_day"]
self._event = self.rental_control_events.event
26 changes: 12 additions & 14 deletions custom_components/rental_control/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,31 +225,29 @@ async def async_update(self):
self._code_generator = self.rental_control_events.code_generator
event_list = self.rental_control_events.calendar
if event_list and (self._event_number < len(event_list)):
val = event_list[self._event_number]
name = val.get("summary", "Unknown")
start = val.get("start")
event = event_list[self._event_number]
name = event.summary
start = event.start

_LOGGER.debug(
"Adding event %s - Start %s - End %s - as event %s to calendar %s",
val.get("summary", "unknown"),
val.get("start"),
val.get("end"),
event.summary,
event.start,
event.end,
str(self._event_number),
self.name,
)

self._event_attributes["summary"] = val.get("summary", "unknown")
self._event_attributes["start"] = val.get("start")
self._event_attributes["end"] = val.get("end")
self._event_attributes["location"] = val.get("location", "")
self._event_attributes["description"] = val.get("description", "")
self._event_attributes["summary"] = event.summary
self._event_attributes["start"] = event.start
self._event_attributes["end"] = event.end
self._event_attributes["location"] = event.location
self._event_attributes["description"] = event.description
self._event_attributes["eta"] = (
start - datetime.now(start.tzinfo) + timedelta(days=1)
).days
self._event_attributes["all_day"] = val.get("all_day")
self._state = f"{name} - {start.strftime('%-d %B %Y')}"
if not val.get("all_day"):
self._state += f" {start.strftime('%H:%M')}"
self._state += f" {start.strftime('%H:%M')}"
self._event_attributes["slot_name"] = self._get_slot_name()
self._event_attributes["slot_code"] = self._generate_door_code()
else:
Expand Down
2 changes: 1 addition & 1 deletion hacs.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"iot_class": "Cloud Polling",
"zip_release": true,
"filename": "rental_control.zip",
"homeassistant": "2021.7.0"
"homeassistant": "2022.5.0"
}

0 comments on commit f79969d

Please sign in to comment.