From 57324fa406994293cde5d3afbc3ce69f03ddcd1e Mon Sep 17 00:00:00 2001 From: neubert Date: Wed, 17 Mar 2021 17:30:05 +0000 Subject: [PATCH] 57_Calendar: avoid spurious re-creation of all events git-svn-id: https://svn.fhem.de/fhem/trunk@23989 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 1 + fhem/FHEM/57_Calendar.pm | 120 +++++++++++++++++++++++++++++++++------ 2 files changed, 105 insertions(+), 16 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index 9c2b210a6..ad5717401 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,6 @@ # Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Do not insert empty lines here, update check depends on it. + - bugfix: 57_Calendar: avoid spurious re-creation of all events - bugfix: 49_IPCAM: not sending events for sequential snapshots fixed - new: SYSSTAT: umstellung auf non-blocking frei konfigurierbare zusatz readings diff --git a/fhem/FHEM/57_Calendar.pm b/fhem/FHEM/57_Calendar.pm index 40a7f8d7d..0320cb421 100644 --- a/fhem/FHEM/57_Calendar.pm +++ b/fhem/FHEM/57_Calendar.pm @@ -269,6 +269,19 @@ Note: the state... readings from the previous version of this module (2015 and earlier) are not available any more. +*** Note on cutoff of event creation + +Events that are more than 400 days in the past or in the future from their +time of creation are omitted. This time window can be further reduced by +the cutoffOlderThan and cutoffLaterThan attributes. + +This would have the following consequence: as long as the calendar is not +re-initialized (set ... reload or restart of FHEM) and the VEVENT record is +not modified, events beyond the horizon may never get created. + +Thus, a forced reload should be scheduled every now and then after initialization or +reload. + Processing of calendar events ----------------------------- @@ -1729,6 +1742,7 @@ sub Calendar_Initialize($) { "cutoffOlderThan cutoffLaterThan hideOlderThan hideLaterThan ". "onCreateEvent quirks ". "defaultFormat defaultTimeFormat ". + "hasModeReadings:0,1 " . $readingFnAttributes; } @@ -1780,6 +1794,20 @@ sub Calendar_Define($$) { return undef; } +##################################### +sub Calendar_deleteModeReadings($) { + + my ($hash) = @_; + my $deletedCount= 0; + my $name= $hash->{NAME}; + + foreach my $reading (grep { /mode.*/ } keys %{$hash->{READINGS}} ) { + readingsDelete($hash, $reading); + $deletedCount++; + } + Log3 $hash, 3, "Calendar $name: $deletedCount obsolete mode readings deleted." if($deletedCount); +} + ##################################### sub Calendar_Undef($$) { @@ -3094,20 +3122,25 @@ sub Calendar_UpdateCalendar($$) { #main::Debug "Calendar $name: creating calendar events"; my $ignoreCancelled= AttrVal($name, "ignoreCancelled", 0); + my $clearedCount= 0; + my $createdCount= 0; foreach my $id (keys %vevents) { my $v= $vevents{$id}; if($v->isObsolete() or ($ignoreCancelled and $v->isCancelled())) { + $clearedCount++; $v->clearEvents(); next; } my $onCreateEvent= AttrVal($name, "onCreateEvent", undef); if($v->hasChanged() or !$v->numEvents()) { + $createdCount++; #main::Debug "createEvents"; $v->createEvents($name, $t, $onCreateEvent, $cutoffLowerBound, $cutoffUpperBound, %vevents); } - } + Log3 $hash, 4, "Calendar $name: events for $clearedCount records cleared, events for $createdCount records created."; + #main::Debug "*** Result:"; #main::Debug $ical->asString(); @@ -3134,8 +3167,12 @@ sub Calendar_UpdateCalendar($$) { sub Calendar_CheckTimes($$) { my ($hash, $t) = @_; + my $name= $hash->{NAME}; - Log3 $hash, 4, "Calendar " . $hash->{NAME} . ": Checking times..."; + Log3 $hash, 4, "Calendar $name: Checking times..."; + + # delete obsolete readings + Calendar_deleteModeReadings($hash) unless AttrVal($name, "hasModeReadings", 0); # # determine the uids of all events and their most interesting mode @@ -3230,18 +3267,22 @@ sub Calendar_CheckTimes($$) { } } + # clears all events in CHANGED, thus must be called first readingsBeginUpdate($hash); # we update the readings - rbu($hash, "modeUpcoming", es(@upcoming)); - rbu($hash, "modeAlarm", es(@alarm)); - rbu($hash, "modeAlarmed", es(@alarmed)); - rbu($hash, "modeAlarmOrStart", es(@alarm,@start)); - rbu($hash, "modeChanged", es(@changed)); - rbu($hash, "modeStart", es(@start)); - rbu($hash, "modeStarted", es(@started)); - rbu($hash, "modeEnd", es(@end)); - rbu($hash, "modeEnded", es(@ended)); + if(AttrVal($name, "hasModeReadings", 0)) { + Log3 $hash, 5, "Calendar $name: Updating obsolete mode readings..."; + rbu($hash, "modeUpcoming", es(@upcoming)); + rbu($hash, "modeAlarm", es(@alarm)); + rbu($hash, "modeAlarmed", es(@alarmed)); + rbu($hash, "modeAlarmOrStart", es(@alarm,@start)); + rbu($hash, "modeChanged", es(@changed)); + rbu($hash, "modeStart", es(@start)); + rbu($hash, "modeStarted", es(@started)); + rbu($hash, "modeEnd", es(@end)); + rbu($hash, "modeEnded", es(@ended)); + } readingsBulkUpdate($hash, "state", "triggered"); # DoTrigger, because sub is called by a timer instead of dispatch readingsEndUpdate($hash, 1); @@ -3363,8 +3404,22 @@ sub CalendarEventsAsHtml($;$) { define MyCalendar Calendar ical url https://www.google.com­/calendar/ical/john.doe%40example.com­/private-foo4711/basic.ics define YourCalendar Calendar ical url http://www.google.com­/calendar/ical/jane.doe%40example.com­/private-bar0815/basic.ics 86400 define SomeCalendar Calendar ical file /home/johndoe/calendar.ics - + + + Note on cutoff of event creation: + +
Set

@@ -3560,7 +3615,7 @@ sub CalendarEventsAsHtml($;$) { <returnTypeSpec>description $texta multiline string in human-readable format (default) @textsan array of strings in human-readable format - @eventan array of Calendar::Event hashes + @eventsan array of Calendar::Event hashes

@@ -3743,6 +3798,10 @@ sub CalendarEventsAsHtml($;$) { although they are cancelled.

+

  • hasModeReadings
    + Set to 1 to use the obsolete mode readings. +
  • +

  • quirks <values>
    Parameters to handle special situations. <values> is a comma-separated list of the following keywords: @@ -3805,7 +3864,10 @@ sub CalendarEventsAsHtml($;$) { for the earliest future time among all alarm, start or end times of all calendar events.

    - A calendar device has several readings. Except for calname, each reading is a semicolon-separated list of UIDs of + For backward compatibility, mode readings are filled when the hasModeReadings attribute is set. The remainder of + this description applies to the obsolete mode readings.

    + + Each mode reading is a semicolon-separated list of UIDs of calendar events that satisfy certain conditions: @@ -4065,7 +4127,25 @@ sub CalendarEventsAsHtml($;$) { define DeinKalender Calendar ical url http://www.google.com­/calendar/ical/jane.doe%40example.com­/private-bar0815/basic.ics 86400 define IrgendeinKalender Calendar ical file /home/johndoe/calendar.ics +
    + + Hinweis zur Erzeugung von Terminen:
    • + + Termine, die zum Zeitpunkt ihrer Erstellung mehr als 400 Tage in der Vergangenheit oder in der Zukunft liegen, + werden ausgelassen. Dieses Zeitfenster kann durch die + Attribute cutoffOlderThan und cutoffLaterThan noch verkleinert werden. + + Dies kann zur Folge haben, dass Termine jenseits dieses Horizonts niemals erstellt werden, + solange der Kalender nicht neu initialisiert wird (set ... reload oder Neustart von FHEM) + oder der VEVENT-Datensatz nicht verändert wird. + + Daher sollte ab und zu ein erzwungenes Neuladen eingeplant werden. +
    + +
    + + Set

    @@ -4262,7 +4342,7 @@ sub CalendarEventsAsHtml($;$) { - +
    calnamename of the calendar
    <returnTypeSpec>Beschreibung
    $textein mehrzeiliger String in menschenlesbarer Darstellung (Vorgabe)
    @textsein Array von Strings in menschenlesbarer Darstellung
    @eventein Array von Calendar::Event-Hashs
    @eventsein Array von Calendar::Event-Hashs


    @@ -4385,6 +4465,11 @@ sub CalendarEventsAsHtml($;$) { Serie zurückgegeben werden, die gelöscht sind.

  • +

  • hasModeReadings
    + Auf 1 setzen, um die veralteten mode-Readings zu benutzen. +
  • + +

  • quirks <values>
    Parameter für spezielle Situationen. <values> ist eine kommaseparierte Liste der folgenden Schlüsselwörter: @@ -4431,7 +4516,10 @@ sub CalendarEventsAsHtml($;$) { Ein Kalender-Ereignis wechselt umgehend von einem Modus zum anderen, wenn die Zeit für eine Änderung erreicht wurde. Dies wird dadurch erreicht, dass auf die früheste zukünftige Zeit aller Alarme, Start- oder Endzeiten aller Kalender-Ereignisse gewartet wird.

    - Ein Kalender-Device hat verschiedene Readings. Mit Ausnahme von calname stellt jedes Reading eine semikolonseparierte Liste aus UID von Kalender-Ereignisse dar, welche bestimmte Zustände haben: + Aus Gründen der Abwärtskompatibilität werden mode-Readings gefüllt, wenn das Attribut hasModeReadings gesetzt ist. + Der Rest dieser Beschreibung bezieht sich auf diese veralteten mode-Readings.

    + + Ein Kalender-Device hat verschiedene mode-Readings. Jedes mode-Reading stellt eine semikolonseparierte Liste aus UID von Kalender-Ereignisse dar, welche bestimmte Zustände haben:
    calnameName des Kalenders
    modeAlarmEreignisse im Alarm-Modus