diff --git a/fhem/CHANGED b/fhem/CHANGED
index 0ff989e66..1012a42d4 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: 98_DOIFtools.pm: new report filter for event rate
- new: 96_Snapcast.pm: New module to control a snapcast server
- update: 98_DOIFtools.pm: improved Attribute handling, help corrections
new attribute DOIFtoolsHideStatReadings hides _stat Readings
diff --git a/fhem/FHEM/98_DOIFtools.pm b/fhem/FHEM/98_DOIFtools.pm
index 10620a471..45f9c6b58 100644
--- a/fhem/FHEM/98_DOIFtools.pm
+++ b/fhem/FHEM/98_DOIFtools.pm
@@ -17,6 +17,7 @@
#
###############################################
+
package main;
use strict;
use warnings;
@@ -61,7 +62,7 @@ sub DOIFtools_Initialize($)
$data{FWEXT}{"/DOIFtools_logWrapper"}{CONTENTFUNC} = "DOIFtools_logWrapper";
my $oldAttr = "target_room:noArg target_group:noArg executeDefinition:noArg executeSave:noArg eventMonitorInDOIF:noArg readingsPrefix:noArg";
- $hash->{AttrList} = "DOIFtoolsExecuteDefinition:1,0 DOIFtoolsTargetRoom DOIFtoolsTargetGroup DOIFtoolsExecuteSave:1,0 DOIFtoolsReadingsPrefix DOIFtoolsEventMonitorInDOIF:1,0 DOIFtoolsHideModulShortcuts:1,0 DOIFtoolsMyShortcuts DOIFtoolsMenuEntry:1,0 DOIFtoolsHideStatReadings:1,0 disabledForIntervals ".$oldAttr;
+ $hash->{AttrList} = "DOIFtoolsExecuteDefinition:1,0 DOIFtoolsTargetRoom DOIFtoolsTargetGroup DOIFtoolsExecuteSave:1,0 DOIFtoolsReadingsPrefix DOIFtoolsEventMonitorInDOIF:1,0 DOIFtoolsHideModulShortcuts:1,0 DOIFtoolsMyShortcuts:textField-long DOIFtoolsMenuEntry:1,0 DOIFtoolsHideStatReadings:1,0 disabledForIntervals ".$oldAttr;
}
@@ -457,9 +458,9 @@ sub DOIFtoolsCheckDOIF {
}
return("") if ($tail =~ /^ *$/);
$ret .= "
replace DOIF name with \$SELF (utilization of events)\n" if ($tail =~ m/[\[|\?]($tn)/);
- $ret .= "replace ReadingsVal(...) with [name:reading] (controlling by events)\n" if ($tail =~ m/(ReadingsVal)/);
- $ret .= "replace ReadingsNum(...) with [name:reading:d] (filtering numbers)\n" if ($tail =~ m/(ReadingsNum)/);
- $ret .= "replace InternalVal(...) with [name:&internal] (controlling by events)\n" if ($tail =~ m/(InternalVal)/);
+ $ret .= "replace ReadingsVal(...) with [name:reading,default value], if not used in an IF command, otherwise there is no possibility to use a default value (controlling by events)\n" if ($tail =~ m/(ReadingsVal)/);
+ $ret .= "replace ReadingsNum(...) with [name:reading:d,default value], if not used in an IF command, otherwise there is no possibility to use a default value (filtering numbers)\n" if ($tail =~ m/(ReadingsNum)/);
+ $ret .= "replace InternalVal(...) with [name:&internal,default value], if not used in an IF command, otherwise there is no possibility to use a default value (controlling by events)\n" if ($tail =~ m/(InternalVal)/);
$ret .= "replace $1...\")} with $2... (plain FHEM command)\n" if ($tail =~ m/(\{\s*fhem.*?\"\s*(set|get))/);
$ret .= "replace {system \"<shell command>\"} with \"\<shell command>\" (plain FHEM shell command, non blocking)\n" if ($tail =~ m/(\{\s*system.*?\})/);
$ret .= "sleep is not recommended in DOIF, use attribute wait for (delay)\n" if ($tail =~ m/(sleep\s\d+\.?\d+\s*[;|,]?)/);
@@ -684,6 +685,9 @@ sub DOIFtools_Set($@)
} elsif ($arg eq "recording_target_duration") {
$value =~ m/(\d+)/;
readingsSingleUpdate($hash,"recording_target_duration",$1 ? $1 : 0,0);
+ } elsif ($arg eq "statisticsShowRate_ge") {
+ $value =~ m/(\d+)/;
+ readingsSingleUpdate($hash,"statisticsShowRate_ge",$1 ? $1 : 0,0);
} elsif ($arg eq "specialLog") {
if ($value) {
readingsSingleUpdate($hash,"specialLog",1,0);
@@ -710,9 +714,9 @@ sub DOIFtools_Set($@)
push @rL, $key if ($key !~ "^(Device|state|error|cmd|e_|timer_|wait_|matched_|last_cmd|mode)");
}
my $rL = join(",",@rL);
- return "unknown argument $arg for $pn, choose one of statisticsTYPEs:multiple-strict,.*,$tL doStatistics:disabled,enabled,deleted sourceAttribute:readingList targetDOIF:$dL deleteReadingsInTargetDOIF:multiple-strict,$rL recording_target_duration:0,1,6,12,24,168 specialLog:0,1 statisticsDeviceFilterRegex ";
+ return "unknown argument $arg for $pn, choose one of statisticsTYPEs:multiple-strict,.*,$tL doStatistics:disabled,enabled,deleted sourceAttribute:readingList targetDOIF:$dL deleteReadingsInTargetDOIF:multiple-strict,$rL recording_target_duration:0,1,6,12,24,168 specialLog:0,1 statisticsDeviceFilterRegex statisticsShowRate_ge";
} else {
- return "unknown argument $arg for $pn, choose one of statisticsTYPEs:multiple-strict,.*,$tL doStatistics:disabled,enabled,deleted sourceAttribute:readingList targetDOIF:$dL recording_target_duration:0,1,6,12,24,168 specialLog:0,1 statisticsDeviceFilterRegex";
+ return "unknown argument $arg for $pn, choose one of statisticsTYPEs:multiple-strict,.*,$tL doStatistics:disabled,enabled,deleted sourceAttribute:readingList targetDOIF:$dL recording_target_duration:0,1,6,12,24,168 specialLog:0,1 statisticsDeviceFilterRegex statisticsShowRate_ge";
}
}
return $ret;
@@ -798,7 +802,9 @@ sub DOIFtools_Get($@)
# event statistics
my $regex = ReadingsVal($pn,"statisticsDeviceFilterRegex",".*");
my $evtsum = 0;
+ my $rate = 0;
my $typsum = 0;
+ my $typerate = 0;
my $allattr = "";
my $rx = AttrVal($pn,"DOIFtoolsHideStatReadings","") ? "\.stat_" : "stat_";
@@ -812,21 +818,25 @@ sub DOIFtools_Get($@)
$typsum = 0;
$t=0;
foreach my $key (sort keys %{$defs{$pn}->{READINGS}}) {
- if ($key =~ m/^$rx($regex)/ and $defs{$1}->{TYPE} eq $typ) {
+ $rate = ($te ? int($hash->{READINGS}{$key}{VAL}/$te + 0.5) : 0) if ($key =~ m/^$rx($regex)/ and $defs{$1}->{TYPE} eq $typ);
+ if ($key =~ m/^$rx($regex)/ and $defs{$1}->{TYPE} eq $typ and $rate >= ReadingsNum($pn,"statisticsShowRate_ge",0)) {
$evtsum += $hash->{READINGS}{$key}{VAL};
$typsum += $hash->{READINGS}{$key}{VAL};
$allattr = " ".join(" ",keys %{$attr{$1}});
- $ret .= sprintf("%-17s",$typ).sprintf("%-25s",$1).sprintf("%-12s",$hash->{READINGS}{$key}{VAL}).sprintf("%-8s",$te ? int($hash->{READINGS}{$key}{VAL}/$te + 0.5) : "").sprintf("%-12s",($allattr =~ " event-on") ? "ja" : "nein")."\n";
+ $ret .= sprintf("%-17s",$typ).sprintf("%-25s",$1).sprintf("%-12s",$hash->{READINGS}{$key}{VAL}).sprintf("%-8s",$rate).sprintf("%-12s",($allattr =~ " event-on") ? "ja" : "nein")."\n";
$i++;
$t++;
}
}
if ($t) {
- $ret .= sprintf("%52s","="x10).sprintf("%2s"," ").sprintf("="x6)."\n";
- $ret .= sprintf("%42s","Summe: ").sprintf("%-10s",$typsum).sprintf("%2s","∅:").sprintf("%-8s",$te ? int($typsum/$te + 0.5) : "")."\n";
- $ret .= sprintf("%43s","Geräte: ").sprintf("%-10s",$t)."\n";
- $ret .= sprintf("%43s","Events/Gerät: ").sprintf("%-10s",int($typsum/$t + 0.5))."\n";
- $ret .= "".sprintf("-"x71)."
";
+ $typerate = $te ? int($typsum/$te + 0.5) : 0;
+ if($typerate >= ReadingsNum($pn,"statisticsShowRate_ge",0)) {
+ $ret .= sprintf("%52s","="x10).sprintf("%2s"," ").sprintf("="x6)."\n";
+ $ret .= sprintf("%42s","Summe: ").sprintf("%-10s",$typsum).sprintf("%2s","∅:").sprintf("%-8s",$typerate)."\n";
+ $ret .= sprintf("%43s","Geräte: ").sprintf("%-10s",$t)."\n";
+ $ret .= sprintf("%43s","Events/Gerät: ").sprintf("%-10s",int($typsum/$t + 0.5))."\n";
+ $ret .= "".sprintf("-"x71)."
";
+ }
}
}
$ret .= sprintf("%52s","="x10).sprintf("%2s"," ").sprintf("="x6)."\n";
@@ -998,11 +1008,14 @@ DOIFtools stellt Funktionen zur Unterstützung von DOIF-Geräten bereit.
set <name> sourceAttribute <readingList>
sourceAttribute vor dem Erstellen einer ReadingsGroup muss das Attribut gesetzt werden aus dem die Readings gelesen werden, um die ReadingsGroup zu erstellen und zu beschriften. Default, readingsList
+ set <name> statisticsDeviceFilterRegex <regular expression as device filter>
+ statisticsDeviceFilterRegex setzt einen Filter auf Gerätenamen, nur die gefilterten Geräte werden im Bericht ausgewertet. Default, ".*".
+
set <name> statisticsTYPEs <List of TYPE used for statistics generation>
statisticsTYPEs setzt eine Liste von TYPE für die Statistikdaten erfasst werden, bestehende Statistikdaten werden gelöscht. Default, "".
- set <name> statisticsDeviceFilterRegex <regular expression as device filter>
- statisticsDeviceFilterRegex setzt einen Filter auf Gerätenamen, nur die gefilterten Geräte werden im Bericht ausgewertet. Default, ".*".
+ set <name> statisticsShowRate_ge <integer value for event rate>
+ statisticsShowRate_ge setzt eine Event-Rate, ab der ein Gerät in die Auswertung einbezogen wird. Default, 0.
set <name> specialLog <0|1>
specialLog 1 DOIF-Listing bei Status und Wait-Timer Aktualisierung im Debug-Logfile. Default, 0.
@@ -1095,9 +1108,10 @@ DOIFtools stellt Funktionen zur Unterstützung von DOIF-Geräten bereit.
recording_target_duration gibt an wie lange Daten erfasst werden sollen.
stat_<devicename> zeigt die Anzahl der gezählten Ereignisse, die das jeweilige Gerät erzeugt hat.
statisticHours zeigt die kumulierte Zeit für den Status enabled an, während der, Statistikdaten erfasst werden.
+ statisticShowRate_ge zeigt die Event-Rate, ab der Geräte in die Auswertung einbezogen werden.
+ statisticsDeviceFilterRegex zeigt den aktuellen Gerätefilterausdruck an.
statisticsTYPEs zeigt eine Liste von TYPE an, für deren Geräte die Statistik erzeugt wird.
specialLog zeigt an ob DOIF-Listing im Log eingeschaltet ist.
- statisticsDeviceFilterRegex zeigt den aktuellen Gerätefilterausdruck an.