FHEM Forum

FHEM - Hausautomations-Systeme => Unterstützende Dienste => Kalendermodule => Thema gestartet von: Markus M. am 28 Oktober 2018, 11:26:22

Titel: 57_Calendar: Logikproblem bei Attributen hideOlderThan/hideLaterThan
Beitrag von: Markus M. am 28 Oktober 2018, 11:26:22
In Calendar_GetEvents wird immer zusätzlich nach hideOlderThan/hideLaterThan gefiltert.
Und zwar auch dann, wenn ich explizit einen anderen Filter für den Zeitraum angegeben habe.

Ich würde stattdessen aber erwarten, dass ein manuell angegebener anderer Zeit-Filter die Attribute überschreibt.
Ansonsten sind Termine ausserhalb der in den Attributen angegebenen Zeiträume für das Modul nicht existent.

Ist es möglich, das Modul dahingegehend zu ändern, dass die Attribute-Filter nur bei Abfragen ohne Zeitraum und den modeXXX Readings greifen?
Titel: Antw:57_Calendar: Logikproblem bei Attributen hideOlderThan/hideLaterThan
Beitrag von: Dr. Boris Neubert am 28 Oktober 2018, 11:48:45
Hallo,

ich muss darüber nachdenken, wozu diese Attribute in der aktuellen Version des Moduls eigentlich dienen sollen.

Viele Grüße
Boris
Titel: Antw:57_Calendar: Logikproblem bei Attributen hideOlderThan/hideLaterThan
Beitrag von: Markus M. am 28 Oktober 2018, 12:40:16
Ich kann dir sagen wofür ich es verwende:

Freigegebene iCloud Kalender enthalten leider keinerlei VALARM Zeiten.
Um jetzt nicht wirre Zeiten eintragen zu müssen, verwende ich die beiden Attribute um ein relativ kleines Vorschaufenster zu haben.
Zusätzlich habe ich das Modul noch um einen Standard-Alarm erweitert, um den Kalender einigermassen sinnvoll nutzen zu können.

Meine erste Idee zum Problem hier war jetzt einfach mal, die Attribute zu ignorieren sobald beim Get ein "limit" gesetzt ist.
Siehe Patch unten.

Gibt es eigentlich einen Grund dagegen, Event Titel zusätzlich zu den IDs in Readings abzulegen?
Das macht die Daten lesbarer und lässt auch Notifys ohne IDs und zusätzliche Abfragen zu.
Ist auch mit unten drin, sollte durch Kommentare einigermassen auseinanderzuhalten sein.

Grüsse, Markus

Index: 57_Calendar.pm
===================================================================
--- 57_Calendar.pm (revision 17631)
+++ 57_Calendar.pm (working copy)
@@ -1688,6 +1688,11 @@
   "ignoreCancelled:0,1 quirks " .
   "SSLVerify:0,1 defaultFormat defaultTimeFormat " .
   $readingFnAttributes;
+
+  #defaultalarm
+  $hash->{AttrList}.=  " defaultAlarm";
+  #defaultalarm
+
}


@@ -1922,6 +1927,7 @@
     my @filters= ();
     my $next= undef;
     my $count= undef;
+    my $limited= undef;

     my ($paramerror, $arrayref)= Calendar_simpleParseWords(join(" ", @a));
     return "$name: Parameter parse error: $paramerror" if(defined($paramerror));
@@ -1991,6 +1997,7 @@
     } elsif($p =~ /^limit:(.+)$/) {
         my ($limiterror, $limitarrayref)= Calendar_simpleParseWords($1, ",");
         return "$name: Limit parse error: $limiterror" if(defined($limiterror));
+        $limited= 1;
         my @limits= @{$limitarrayref};
         for my $limit (@limits) {
           if($limit =~ /count=([1-9]+\d*)/) {
@@ -2016,7 +2023,7 @@
     }

     my @texts;
-    my @events= Calendar_GetEvents($hash, $t, @filters);
+    my @events= Calendar_GetEvents($hash, $t, $limited, @filters);
     # special treatment for next
     if(defined($next)) {
         my %uids;  # remember the UIDs
@@ -2084,7 +2091,7 @@
         $param= $a[2];
     }
     my @filters= ( { ref => $filterref, param => $param } );
-    @events= Calendar_GetEvents($hash, $t, @filters);
+    @events= Calendar_GetEvents($hash, $t, undef, @filters);

     # special treatment for next
     if($filter eq "next") {
@@ -2194,6 +2201,7 @@

   my ($hash, $t) = @_;

+  return undef if(!defined($t));
   #main::Debug "RearmTimer now " . FmtDateTime($t);
   my $nt= $hash->{".fhem"}{nxtUpdtTs};
   #main::Debug "RearmTimer next update " . FmtDateTime($nt);
@@ -2237,8 +2245,8 @@
   }

   # seconds
-  if($tspec =~ m/^[0-9]+s?$/) {
-    return ("", $tspec);
+  if($tspec =~ m/^([0-9]+)s?$/) { #fix for 10s error
+    return ("", $1);
   }

   # D:HH:MM:SS
@@ -2368,9 +2376,9 @@


###################################
-sub Calendar_GetEvents($$@) {
+sub Calendar_GetEvents($$$@) {

-    my ($hash, $t, @filters)= @_;
+    my ($hash, $t, $limited, @filters)= @_;
     my $name= $hash->{NAME};
     my @result= ();

@@ -2418,8 +2426,10 @@
               #Debug "Filter $filterref, Parameter $param, Match $match";
               next unless $match==@filters;
             }
-            if(defined($t1)) { next if(defined($event->end()) && $event->end() < $t1); }
-            if(defined($t2)) { next if(defined($event->start()) && $event->start() > $t2); }
+            if(!defined($limited)){
+              if(defined($t1)) { next if(defined($event->end()) && $event->end() < $t1); }
+              if(defined($t2)) { next if(defined($event->start()) && $event->start() > $t2); }
+            }
             push @result, $event;
         }
     }
@@ -2465,7 +2475,7 @@
     if(defined($SSLVerify)) {
       eval "use IO::Socket::SSL";
       if($@) {
-        Log3 $hash, 2, $@;
+        Log3 $hash, 2, "Calendar: ".$@;
       } else {
         my $SSLVerifyMode= eval("$SSLVerify ? SSL_VERIFY_PEER : SSL_VERIFY_NONE");
         Log3 $hash, 5, "SSL verify mode set to $SSLVerifyMode";
@@ -2839,6 +2849,7 @@
         }

      #main::Debug "Merging " . $v->asString();
+        if ($v->tm($v->value("DTEND")) < time() && $v->valueOrDefault("RRULE", "") eq "") {next;} #memory fix
         my $found= 0;
         my $added= 0; # flag to prevent multiple additions
         $n++;
@@ -2999,6 +3010,7 @@

     Log3 $hash, 4, "Calendar " . $hash->{NAME} . ": Checking times...";

+    return undef if(!defined($t));
     #
     # determine the uids of all events and their most interesting mode
     #
@@ -3012,10 +3024,58 @@
     my %mim;     # most interesting mode per id
     my %changed;  # changed per id
     my %vevents= %{$hash->{".fhem"}{vevents}};
+
+    # title readings and time filtering
+    my $name = $hash->{NAME};
+    my %titles;  # title per id
+    # time window
+    my ($error, $t1, $t2)= (undef, undef, undef);
+    my $hideOlderThan= AttrVal($name, "hideOlderThan", undef);
+    my $hideLaterThan= AttrVal($name, "hideLaterThan", undef);
+    #
+    # start of time window
+    if(defined($hideOlderThan)) {
+        ($error, $t1)= Calendar_GetSecondsFromTimeSpec($hideOlderThan);
+        if($error) {
+            Log3 $hash, 2, "$name: attribute hideOlderThan: $error";
+        } else {
+            $t1= $t- $t1;
+        }
+    }
+    # end of time window
+    if(defined($hideLaterThan)) {
+        ($error, $t2)= Calendar_GetSecondsFromTimeSpec($hideLaterThan);
+        if($error) {
+            Log3 $hash, 2, "$name: attribute hideLaterThan: $error";
+        } else {
+            $t2= $t+ $t2;
+        }
+    }
+    # title readings and time filtering
+
+
     foreach my $uid (keys %vevents) {
         my $v= $vevents{$uid};
         foreach my $e (@{$v->{events}}) {
             my $uid= $e->uid();
+
+            # title readings and time filtering
+            if(defined($t1)) { next if(defined($e->end()) && $e->end() < $t1); }
+            if(defined($t2)) { next if(defined($e->start()) && $e->start() > $t2); }
+            $titles{$uid} = $e->summary();
+            # title readings and time filtering
+            #defaultalarm
+            my $defaultAlarm= AttrVal($name, "defaultAlarm", undef);
+            if(defined($defaultAlarm) && !defined($e->{alarm})){
+                my($error, $t1)= Calendar_GetSecondsFromTimeSpec($defaultAlarm);
+                if($error) {
+                    Log3 $hash, 2, "$name attribute defaultAlarm: $error";
+                } else {
+                    $e->{alarm} = $e->{start} - $t1;
+                }
+            }
+            #defaultalarm
+
             my $mode= defined($mim{$uid}) ? $mim{$uid} : "none";
             if($e->isEnded($t)) {
                 $e->setMode("end");
@@ -3050,6 +3110,14 @@
     my @alarmed;
     my @end;
     my @ended;
+
+    #title readings
+    my @upcomingtext;
+    my @starttext;
+    my @alarmtext;
+    my @endtext;
+    #title readings
+
     foreach my $uid (keys %mim) {
         push @changed, $uid if($changed{$uid});
         push @upcoming, $uid if($mim{$uid} eq "upcoming");
@@ -3065,6 +3133,14 @@
             push @end, $uid;
             push @ended, $uid if($changed{$uid});
         }
+
+        #title readings
+        push @upcomingtext, $titles{$uid} if($mim{$uid} eq "upcoming");
+        push @alarmtext, $titles{$uid} if($mim{$uid} eq "alarm");
+        push @starttext, $titles{$uid} if($mim{$uid} eq "start");
+        push @endtext, $titles{$uid} if($mim{$uid} eq "end");
+        #title readings
+
     }


@@ -3104,6 +3180,15 @@
     rbu($hash, "modeStarted", es(@started));
     rbu($hash, "modeEnd", es(@end));
     rbu($hash, "modeEnded", es(@ended));
+
+    #title readings
+    rbu($hash, "textUpcoming", es(@upcomingtext));
+    rbu($hash, "textAlarm", es(@alarmtext));
+    rbu($hash, "textAlarmOrStart", es(@alarmtext,@starttext));
+    rbu($hash, "textStart", es(@starttext));
+    rbu($hash, "textEnd", es(@endtext));
+    #title readings
+
     readingsBulkUpdate($hash, "state", "triggered");
     # DoTrigger, because sub is called by a timer instead of dispatch
     readingsEndUpdate($hash, 1);
Titel: Antw:57_Calendar: Logikproblem bei Attributen hideOlderThan/hideLaterThan
Beitrag von: Dr. Boris Neubert am 25 November 2018, 12:02:05
Nachdenken beendet.

Was wir brauchen ist ein Attribut defaultLimit, das zur Anwendung kommt, wenn kein limit angegeben ist. Damit wird hideOlderThan und hideLaterThan verzichtbar.

Dein anderer Vorschlag ist, zusätzlich zu den modeXXX-Readings, welche UIDs beinhalten, zusätzlich äquivalente Readings zu haben, die das SUMMARY der Termine enthalten.

Ich habe mir beides mal notiert für künftige Erweiterungen.