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:
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 never get created.
+
+ Thus, a forced reload should be scheduled every now and then.<returnTypeSpec>$text@texts@event@events+
hasModeReadings+
quirks <values><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:
+
hasModeReadings+ +
quirks <values><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:
| calname | Name des Kalenders |
| modeAlarm | Ereignisse im Alarm-Modus |