]> git.basschouten.com Git - openhab-addons.git/commitdiff
[icalendar] Short events parallel to longer current events are now also shown as...
authorMichael Wodniok <michi@noorganization.org>
Sun, 6 Jun 2021 08:10:13 +0000 (10:10 +0200)
committerGitHub <noreply@github.com>
Sun, 6 Jun 2021 08:10:13 +0000 (10:10 +0200)
Signed-off-by: Michael Wodniok <michi@noorganization.org>
bundles/org.openhab.binding.icalendar/src/main/java/org/openhab/binding/icalendar/internal/handler/ICalendarHandler.java
bundles/org.openhab.binding.icalendar/src/main/java/org/openhab/binding/icalendar/internal/logic/BiweeklyPresentableCalendar.java
bundles/org.openhab.binding.icalendar/src/test/java/org/openhab/binding/icalendar/internal/logic/BiweeklyPresentableCalendarTest.java
bundles/org.openhab.binding.icalendar/src/test/resources/test-issue10808.ics [new file with mode: 0644]

index 632a818f3a5e5c3786780e1f095af4e174652e04..8dbf05d4c4a582f5d405c4e1d621e1d31c0017d0 100644 (file)
@@ -65,6 +65,7 @@ import org.slf4j.LoggerFactory;
  * @author Michael Wodniok - Initial contribution
  * @author Andrew Fiddian-Green - Support for Command Tags embedded in the Event description
  * @author Michael Wodniok - Added last_update-channel and additional needed handling of it
+ * @author Michael Wodniok - Changed calculation of Future for refresh of channels
  */
 @NonNullByDefault
 public class ICalendarHandler extends BaseBridgeHandler implements CalendarUpdateListener {
@@ -337,6 +338,7 @@ public class ICalendarHandler extends BaseBridgeHandler implements CalendarUpdat
             return;
         }
         final Instant now = Instant.now();
+        Instant nextRegularUpdate = null;
         if (currentCalendar.isEventPresent(now)) {
             final Event currentEvent = currentCalendar.getCurrentEvent(now);
             if (currentEvent == null) {
@@ -344,32 +346,33 @@ public class ICalendarHandler extends BaseBridgeHandler implements CalendarUpdat
                         "Could not schedule next update of states, due to unexpected behaviour of calendar implementation.");
                 return;
             }
+            nextRegularUpdate = currentEvent.end;
+        }
+
+        final Event nextEvent = currentCalendar.getNextEvent(now);
+        final ICalendarConfiguration currentConfig = this.configuration;
+        if (currentConfig == null) {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
+                    "Something is broken, the configuration is not available.");
+            return;
+        }
+        if (nextEvent != null) {
+            if (nextRegularUpdate == null || nextEvent.start.isBefore(nextRegularUpdate)) {
+                nextRegularUpdate = nextEvent.start;
+            }
+        }
+
+        if (nextRegularUpdate != null) {
             updateJobFuture = scheduler.schedule(() -> {
                 ICalendarHandler.this.updateStates();
                 ICalendarHandler.this.rescheduleCalendarStateUpdate();
-            }, currentEvent.end.getEpochSecond() - now.getEpochSecond(), TimeUnit.SECONDS);
-            logger.debug("Scheduled update in {} seconds", currentEvent.end.getEpochSecond() - now.getEpochSecond());
+            }, nextRegularUpdate.getEpochSecond() - now.getEpochSecond(), TimeUnit.SECONDS);
+            logger.debug("Scheduled update in {} seconds", nextRegularUpdate.getEpochSecond() - now.getEpochSecond());
         } else {
-            final Event nextEvent = currentCalendar.getNextEvent(now);
-            final ICalendarConfiguration currentConfig = this.configuration;
-            if (currentConfig == null) {
-                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
-                        "Something is broken, the configuration is not available.");
-                return;
-            }
-            if (nextEvent == null) {
-                updateJobFuture = scheduler.schedule(() -> {
-                    ICalendarHandler.this.rescheduleCalendarStateUpdate();
-                }, 1L, TimeUnit.DAYS);
-                logger.debug("Scheduled reschedule in 1 day");
-            } else {
-                updateJobFuture = scheduler.schedule(() -> {
-                    ICalendarHandler.this.updateStates();
-                    ICalendarHandler.this.rescheduleCalendarStateUpdate();
-                }, nextEvent.start.getEpochSecond() - now.getEpochSecond(), TimeUnit.SECONDS);
-                logger.debug("Scheduled update in {} seconds", nextEvent.start.getEpochSecond() - now.getEpochSecond());
-
-            }
+            updateJobFuture = scheduler.schedule(() -> {
+                ICalendarHandler.this.rescheduleCalendarStateUpdate();
+            }, 1L, TimeUnit.DAYS);
+            logger.debug("Scheduled reschedule in 1 day");
         }
     }
 
index 4f6d23edba647ffbf5530fbdcae9c944508ffade..61d2f9a25184da5334a3a1bdef1286dc83e3dba1 100644 (file)
@@ -59,6 +59,8 @@ import biweekly.util.com.google.ical.compat.javautil.DateIterator;
  * @author Andrew Fiddian-Green - Methods getJustBegunEvents() & getJustEndedEvents()
  * @author Michael Wodniok - Extension for filtered events
  * @author Michael Wodniok - Added logic for events moved with "RECURRENCE-ID" (issue 9647)
+ * @author Michael Wodniok - Extended logic for defined behavior with parallel current events
+ *         (issue 10808)
  */
 @NonNullByDefault
 class BiweeklyPresentableCalendar extends AbstractPresentableCalendar {
@@ -320,6 +322,8 @@ class BiweeklyPresentableCalendar extends AbstractPresentableCalendar {
         final List<VEvent> positiveEvents = new ArrayList<VEvent>();
         classifyEvents(positiveEvents, negativeEvents);
 
+        VEventWPeriod earliestEndingEvent = null;
+
         for (final VEvent currentEvent : positiveEvents) {
             final DateIterator startDates = this.getRecurredEventDateIterator(currentEvent);
             final Duration duration = getEventLength(currentEvent);
@@ -333,7 +337,9 @@ class BiweeklyPresentableCalendar extends AbstractPresentableCalendar {
                 if (startInstant.isBefore(instant) && endInstant.isAfter(instant)) {
                     final Uid eventUid = currentEvent.getUid();
                     if (eventUid == null || !isCounteredBy(startInstant, eventUid, negativeEvents)) {
-                        return new VEventWPeriod(currentEvent, startInstant, endInstant);
+                        if (earliestEndingEvent == null || endInstant.isBefore(earliestEndingEvent.end)) {
+                            earliestEndingEvent = new VEventWPeriod(currentEvent, startInstant, endInstant);
+                        }
                     }
                 }
                 if (startInstant.isAfter(instant.plus(duration))) {
@@ -342,7 +348,7 @@ class BiweeklyPresentableCalendar extends AbstractPresentableCalendar {
             }
         }
 
-        return null;
+        return earliestEndingEvent;
     }
 
     /**
index 7bdb0e39778ec99bda40f75736ed1ba9ba30f899..7c60c4fb68f3444a19cfbb32861b893bcab399bf 100644 (file)
@@ -41,13 +41,14 @@ import org.openhab.core.types.Command;
  * @author Michael Wodniok - Initial contribution.
  * @author Andrew Fiddian-Green - Tests for Command Tag code
  * @author Michael Wodniok - Extended Tests for filtered Events
- *
+ * @author Michael Wodniok - Extended Test for parallel current events
  */
 public class BiweeklyPresentableCalendarTest {
     private AbstractPresentableCalendar calendar;
     private AbstractPresentableCalendar calendar2;
     private AbstractPresentableCalendar calendar3;
     private AbstractPresentableCalendar calendar_issue9647;
+    private AbstractPresentableCalendar calendar_issue10808;
 
     @BeforeEach
     public void setUp() throws IOException, CalendarException {
@@ -56,6 +57,8 @@ public class BiweeklyPresentableCalendarTest {
         calendar3 = new BiweeklyPresentableCalendar(new FileInputStream("src/test/resources/test3.ics"));
         calendar_issue9647 = new BiweeklyPresentableCalendar(
                 new FileInputStream("src/test/resources/test-issue9647.ics"));
+        calendar_issue10808 = new BiweeklyPresentableCalendar(
+                new FileInputStream("src/test/resources/test-issue10808.ics"));
     }
 
     /**
@@ -117,6 +120,18 @@ public class BiweeklyPresentableCalendarTest {
 
         Event nonExistingEvent = calendar.getCurrentEvent(Instant.parse("2019-09-09T09:07:00Z"));
         assertNull(nonExistingEvent);
+
+        Event currentEvent2 = calendar_issue10808.getCurrentEvent(Instant.parse("2021-06-05T17:10:05Z"));
+        assertNotNull(currentEvent2);
+        assertTrue("Test event 1".contentEquals(currentEvent2.title));
+
+        Event currentEvent3 = calendar_issue10808.getCurrentEvent(Instant.parse("2021-06-05T17:13:05Z"));
+        assertNotNull(currentEvent3);
+        assertTrue("Test event 2".contentEquals(currentEvent3.title));
+
+        Event currentEvent4 = calendar_issue10808.getCurrentEvent(Instant.parse("2021-06-05T17:18:05Z"));
+        assertNotNull(currentEvent4);
+        assertTrue("Test event 1".contentEquals(currentEvent4.title));
     }
 
     /**
diff --git a/bundles/org.openhab.binding.icalendar/src/test/resources/test-issue10808.ics b/bundles/org.openhab.binding.icalendar/src/test/resources/test-issue10808.ics
new file mode 100644 (file)
index 0000000..baadc32
--- /dev/null
@@ -0,0 +1,47 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//SabreDAV//SabreDAV//EN
+X-WR-CALNAME:Test
+X-APPLE-CALENDAR-COLOR:#499AA2
+REFRESH-INTERVAL;VALUE=DURATION:PT4H
+X-PUBLISHED-TTL:PT4H
+BEGIN:VTIMEZONE
+TZID:Europe/Paris
+BEGIN:DAYLIGHT
+TZOFFSETFROM:+0100
+TZOFFSETTO:+0200
+TZNAME:CEST
+DTSTART:19700329T020000
+RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
+END:DAYLIGHT
+BEGIN:STANDARD
+TZOFFSETFROM:+0200
+TZOFFSETTO:+0100
+TZNAME:CET
+DTSTART:19701025T030000
+RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+CREATED:20210107T155730Z
+DTSTAMP:20210107T160226Z
+LAST-MODIFIED:20210605T163408Z
+SEQUENCE:4
+UID:bd676ec9-0cdb-4c8d-a6dd-9e3fcf77a45f
+DTSTART;TZID=Europe/Paris:20210605T191000
+DTEND;TZID=Europe/Paris:20210605T192000
+SUMMARY:Test event 1
+DESCRIPTION:BEGIN:DemoString:EHLO1
+END:VEVENT
+BEGIN:VEVENT
+CREATED:20210107T160405Z
+DTSTAMP:20210107T160405Z
+LAST-MODIFIED:20210605T163512Z
+UID:7d1ecca5-1ddd-4932-b096-d034c8d7f5aa
+DTSTART;TZID=Europe/Paris:20210605T191200
+DTEND;TZID=Europe/Paris:20210605T191600
+SUMMARY:Test event 2
+DESCRIPTION:BEGIN:DemoString:EHLO2
+END:VEVENT
+END:VCALENDAR