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>]
format
,
- timeFormat
, filter
and series
+ timeFormat
, filter
, series
and limit
parameters and it makes even sense to give the filter
parameter several times.
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.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 |
get MyCalendar limit:count=10
get MyCalendar limit:from=-2d
get MyCalendar limit:count=10,from=0,to=+10d
get <name> find <regexp>