diff --git a/fhem/CHANGED b/fhem/CHANGED index 0d0f7a980..428f5bce5 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. + - feature: 57_Calendar: new parameter "limit" (forum #87566) - bugfix: 55_DWD_OpenData: updateAlertsCache causing "not a HASH reference" error on some platforms (forum #83097) - change: 98_dewpoint: Don't manipulate STATE of target device if has diff --git a/fhem/FHEM/57_Calendar.pm b/fhem/FHEM/57_Calendar.pm index d45f40780..1f7baa35f 100644 --- a/fhem/FHEM/57_Calendar.pm +++ b/fhem/FHEM/57_Calendar.pm @@ -1921,6 +1921,7 @@ sub Calendar_Get($@) { my $timeFormat= AttrVal($name, "defaultTimeFormat",'%d.%m.%Y %H:%M'); my @filters= (); my $next= undef; + my $count= undef; my ($paramerror, $arrayref)= Calendar_simpleParseWords(join(" ", @a)); return "$name: Parameter parse error: $paramerror" if(defined($paramerror)); @@ -1986,6 +1987,29 @@ sub Calendar_Get($@) { return "$name: Illegal series specification: $seriesspec"; } } + ### limit + } elsif($p =~ /^limit:(.+)$/) { + my ($limiterror, $limitarrayref)= Calendar_simpleParseWords($1, ","); + return "$name: Limit parse error: $limiterror" if(defined($limiterror)); + my @limits= @{$limitarrayref}; + for my $limit (@limits) { + if($limit =~ /count=([1-9]+\d*)/) { + $count= $1; + } elsif($limit =~ /from=([+-]?)(.+)/ ) { + my $sign= $1 eq "-" ? -1 : 1; + my ($error, $from)= Calendar_GetSecondsFromTimeSpec($2); + return "$name: $error" if($error); + push @filters, { ref => \&filter_endafter, param => $t+$sign*$from }; + } elsif($limit =~ /to=([+-]?)(.+)/ ) { + my $sign= $1 eq "-" ? -1 : 1; + my ($error, $to)= Calendar_GetSecondsFromTimeSpec($2); + return "$name: $error" if($error); + push @filters, { ref => \&filter_startbefore, param => $t+$sign*$to }; + } else { + return "$name: Illegal limit specification: $limit"; + } + + } } else { return "$name: Illegal parameter: $p"; } @@ -2006,9 +2030,10 @@ sub Calendar_Get($@) { } @events; } + my $n= 0; foreach my $event (@events) { push @texts, $event->formatted($format, $timeFormat); - + last if(defined($count) && (++$n>= $count)); } return "" if($#texts<0); return join("\n", @texts); @@ -2020,6 +2045,7 @@ sub Calendar_Get($@) { if($cmd ~~ @cmds2) { return "argument is missing" if($#a < 2); + Log3 $hash, 2, "get $name $cmd is deprecated and will be removed soon. Use get $name events instead."; my $filter= $a[2]; @@ -2297,11 +2323,21 @@ sub filter_start($) { return $event->getMode() eq "start" ? 1 : 0; } +sub filter_startbefore($$) { + my ($event, $param)= @_; + return $event->start() < $param ? 1 : 0; +} + sub filter_end($) { my ($event)= @_; return $event->getMode() eq "end" ? 1 : 0; } +sub filter_endafter($$) { + my ($event, $param)= @_; + return $event->end() > $param ? 1 : 0; +} + sub filter_notend($) { my ($event)= @_; #Debug "filter_notend: event " . $event->{summary} . ", mode= " . $event->getMode(); @@ -3153,12 +3189,12 @@ sub CalendarEventsAsHtml($;$) { Same as set <name> update

-
  • get <name> events [format:<formatSpec>] [timeFormat:<timeFormatSpec>] [filter:<filterSpecs>] [series:next[=<max>]]

    +
  • get <name> events [format:<formatSpec>] [timeFormat:<timeFormatSpec>] [filter:<filterSpecs>] [series:next[=<max>]] [limit:<limitSpecs>]

    The swiss army knife for displaying calendar events. Returns, line by line, information on the calendar events in the calendar <name> according to formatting and filtering rules. You can give none, one or several of the format, - timeFormat, filter and series + timeFormat, filter, series and limit parameters and it makes even sense to give the filter parameter several times.

    @@ -3275,10 +3311,36 @@ sub CalendarEventsAsHtml($;$) { recurring events. series:next limits the display to the next calendar event out of all calendar events in the series that have not yet ended. series:next=<max> shows at most the - <max> next calendar events in the series.

    + <max> next calendar events in the series. This applies + per series. To limit the total amount of events displayed see the limit + parameter below.

    + + The limit parameter limits the number of events displayed. + <limitSpecs> is a comma-separated list of <limitSpec> + specifications.

    + + + + + + +
    <limitSpec>description
    count=<n>shows at most <n> events, <n> is a positive integer
    from=[+|-]<timespec>shows only events that end after + a timespan <timespec> from now; use a minus sign for events in the + past; <timespec> is described below in the Attributes section
    to=[+|-]<timespec>shows only events that start before + a timespan <timespec> from now; use a minus sign for events in the + past; <timespec> is described below in the Attributes section

    + + Examples:
    + get MyCalendar limit:count=10
    + get MyCalendar limit:from=-2d
    + get MyCalendar limit:count=10,from=0,to=+10d
    +

  • + +
  • get <name> find <regexp>
    Returns, line by line, the UIDs of all calendar events whose summary matches the regular expression