diff --git a/fhem/FHEM/98_DOIF.pm b/fhem/FHEM/98_DOIF.pm index 592f4fbab..664152b6a 100644 --- a/fhem/FHEM/98_DOIF.pm +++ b/fhem/FHEM/98_DOIF.pm @@ -725,6 +725,7 @@ sub AggrIntDoIf my $format; my $place; my $number; + my $readingRegex; if ($modeType =~ /.(sum|average|max|min)?[:]?(?:(a|d)?(\d)?)?/) { $type = (defined $1)? $1 : ""; @@ -739,73 +740,82 @@ sub AggrIntDoIf $default=EvalValueDoIf($hash,"default",$default); } } + + if (defined $reading) { + if ($reading =~ /^"(.*)"$/) { + $readingRegex = $1; + } + } + foreach my $name (($device eq "") ? keys %defs:grep {/$device/} keys %defs) { next if($attr{$name} && $attr{$name}{ignore}); - $value=""; - $number=""; - if ($reading) { - if (defined $defs{$name}{READINGS}{$reading}) { - $value=$defs{$name}{READINGS}{$reading}{VAL}; - $number = ($value =~ /(-?\d+(\.\d+)?)/ ? $1 : 0); - } else { - next; - } - } - if ($cond) { - if ($cond =~ /^"(.*)"$/) { - if (defined $defs{$name}{READINGS}{$reading}) { - $ret=($value =~ /$1/); - } - } else { - $_=$value; - $STATE=Value($name); - $TYPE=$defs{$name}{TYPE}; - $group=AttrVal($name,"group",""); - $room=AttrVal($name,"room",""); - $lastWarningMsg=""; - $ret = eval $cond; - if ($@) { - $@ =~ s/^(.*) at \(eval.*\)(.*)$/$1,$2/; - if (defined $hash) { - Log3 ($hash->{NAME},3 , "$hash->{NAME}: aggregate function: error in condition: $cond, $@"); - } - return("error in aggregate function: ".$@); + foreach my $reading ((defined $readingRegex) ? grep {/$readingRegex/} keys %{$defs{$name}{READINGS}} : $reading) { + $value=""; + $number=""; + if ($reading) { + if (defined $defs{$name}{READINGS}{$reading}) { + $value=$defs{$name}{READINGS}{$reading}{VAL}; + $number = ($value =~ /(-?\d+(\.\d+)?)/ ? $1 : 0); + } else { + next; } - if ($lastWarningMsg) { - $warning=1; - $lastWarningMsg =~ s/^(.*) at \(eval.*$/$1/; - Log3 ($hash->{NAME},3 , "$hash->{NAME}: aggregate function: warning in condition: $cond, Device: $name"); - readingsSingleUpdate ($hash, "warning_aggr", "condition: $cond , device: $name, $lastWarningMsg",0); - } - $lastWarningMsg=""; } - } else { - $ret=1; - } - if ($format eq "a") { - $devname=AttrVal($name,"alias",$name); - } else { - $devname=$name; - } - if ($ret) { - if ($type eq ""){ - $num++; - push (@devices,$devname); - } elsif (defined $value) { - if ($type eq "sum" or $type eq "average") { + if ($cond) { + if ($cond =~ /^"(.*)"$/) { + if (defined $defs{$name}{READINGS}{$reading}) { + $ret=($value =~ /$1/); + } + } else { + $_=$value; + $STATE=Value($name); + $TYPE=$defs{$name}{TYPE}; + $group=AttrVal($name,"group",""); + $room=AttrVal($name,"room",""); + $lastWarningMsg=""; + $ret = eval $cond; + if ($@) { + $@ =~ s/^(.*) at \(eval.*\)(.*)$/$1,$2/; + if (defined $hash) { + Log3 ($hash->{NAME},3 , "$hash->{NAME}: aggregate function: error in condition: $cond, $@"); + } + return("error in aggregate function: ".$@); + } + if ($lastWarningMsg) { + $warning=1; + $lastWarningMsg =~ s/^(.*) at \(eval.*$/$1/; + Log3 ($hash->{NAME},3 , "$hash->{NAME}: aggregate function: warning in condition: $cond, Device: $name"); + readingsSingleUpdate ($hash, "warning_aggr", "condition: $cond , device: $name, $lastWarningMsg",0); + } + $lastWarningMsg=""; + } + } else { + $ret=1; + } + if ($format eq "a") { + $devname=AttrVal($name,"alias",$name); + } else { + $devname=$name; + } + if ($ret) { + if ($type eq ""){ $num++; push (@devices,$devname); - $sum+=$number; - } elsif ($type eq "max") { - if (!defined $extrem or $number>$extrem) { - $extrem=$number; - @devices=($devname); - } - } elsif ($type eq "min") { - if (!defined $extrem or $number<$extrem) { - $extrem=$number; - @devices=($devname); - } + } elsif (defined $value) { + if ($type eq "sum" or $type eq "average") { + $num++; + push (@devices,$devname); + $sum+=$number; + } elsif ($type eq "max") { + if (!defined $extrem or $number>$extrem) { + $extrem=$number; + @devices=($devname); + } + } elsif ($type eq "min") { + if (!defined $extrem or $number<$extrem) { + $extrem=$number; + @devices=($devname); + } + } } } } @@ -3492,7 +3502,7 @@ Die Angabe des Readings kann weggelassen werden, dann wird lediglich nach entspr
Syntax:

-[<function>:<format>:"<regex device>:<regex event>":<reading>:<condition>,<default>]
+[<function>:<format>:"<regex device>:<regex event>":<reading>|"<regex reading>":<condition>,<default>]

<function>:

@@ -3512,6 +3522,8 @@ Die Angabe <regex Event> ist im Ausführungsteil nicht sinnvoll und sollte
<reading> Reading, welches überprüft werden soll

+"<regex reading>"; Regex für Readings, die überprüft werden sollen
+
<condition> Aggregations-Bedingung, $_ ist der Platzhalter für den aktuellen Wert des internen Schleifendurchlaufs, Angaben in Anführungszeichen der Art "<value>" entsprechen $_ =~ "<value>" , hier sind alle Perloperatoren möglich.

<default> Default-Wert, falls kein Device gefunden wird, entspricht der Syntax des Default-Wertes bei Readingangaben
@@ -3524,10 +3536,6 @@ Anzahl der Devices, die mit "window" beginnen:

[#"^window"]

-Liste der Devices, die mit "window" beginnen:
-
-[@"^window"]
-
Liste der Devices, die mit "window" beginnen, es werden Aliasnamen ausgegeben, falls definiert:

[@:a"^window"]
@@ -3544,6 +3552,14 @@ entspricht:

[@"^window":state:$_ =~ "open"] siehe Aggregationsbedingung.

+Kleinster Wert der Readings des Devices "abfall", in deren Namen "Gruenschnitt" vorkommt und die mit "_days" enden:
+
+[#min:"^abfall$":"Gruenschnitt.*_days$"]
+
+Durchschnitt von Readings aller Devices, die mit "T_" beginnen, in deren Reading-Namen "temp" vorkommt:
+
+[#average:"^T_":"temp"]
+
In der Aggregationsbedingung können alle in FHEM definierten Perlfunktionen genutzt werden. Folgende Variablen sind vorbelegt und können ebenfalls benutzt werden:

$_ Inhalt des angegebenen Readings (s.o.)