mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-28 17:12:32 +00:00
statistics: bugfix
git-svn-id: https://svn.fhem.de/fhem/trunk@5771 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
a74a9c8809
commit
c54bda5869
@ -5,7 +5,6 @@
|
|||||||
# Copyright notice
|
# Copyright notice
|
||||||
#
|
#
|
||||||
# (c) 2014 Torsten Poitzsch < torsten . poitzsch at gmx . de >
|
# (c) 2014 Torsten Poitzsch < torsten . poitzsch at gmx . de >
|
||||||
# inspired by 98_rain.pm of Andreas Vogt
|
|
||||||
#
|
#
|
||||||
# This module computes statistic data of and for readings of other modules
|
# This module computes statistic data of and for readings of other modules
|
||||||
#
|
#
|
||||||
@ -48,7 +47,7 @@ sub statistics_doStatisticDelta ($$$$$);
|
|||||||
|
|
||||||
##############################################################
|
##############################################################
|
||||||
# Syntax: deviceType, readingName, statisticType, decimalPlaces
|
# Syntax: deviceType, readingName, statisticType, decimalPlaces
|
||||||
# statisticType: 0=noStatistic | 1=maxMinAvgStatistic | 2=integralTimeStatistic | 3=onOffTimeCount
|
# statisticType: 0=noStatistic | 1=minMaxAvg | 2=deltaTime | 3=stateTimeCount
|
||||||
##############################################################
|
##############################################################
|
||||||
my @knownDeviceReadings = (
|
my @knownDeviceReadings = (
|
||||||
["CUL_WS", "humidity", 1, 0]
|
["CUL_WS", "humidity", 1, 0]
|
||||||
@ -70,8 +69,9 @@ statistics_Initialize($)
|
|||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
|
|
||||||
$hash->{DefFn} = "statistics_Define";
|
$hash->{DefFn} = "statistics_Define";
|
||||||
$hash->{UndefFn} = "LUXTRONIK2_Undefine";
|
$hash->{UndefFn} = "statistics_Undefine";
|
||||||
$hash->{NotifyFn} = "statistics_Notify";
|
$hash->{NotifyFn} = "statistics_Notify";
|
||||||
|
$hash->{NOTIFYDEV} = "global";
|
||||||
|
|
||||||
$hash->{NotifyOrderPrefix} = "10-"; # Want to be called before the rest
|
$hash->{NotifyOrderPrefix} = "10-"; # Want to be called before the rest
|
||||||
$hash->{AttrList} = "disable:0,1 "
|
$hash->{AttrList} = "disable:0,1 "
|
||||||
@ -91,20 +91,20 @@ statistics_Define($$)
|
|||||||
if(3>@a || @a>4);
|
if(3>@a || @a>4);
|
||||||
|
|
||||||
my $name = $a[0];
|
my $name = $a[0];
|
||||||
my $devname = $a[2];
|
my $devName = $a[2];
|
||||||
|
|
||||||
if (@a == 4) {$hash->{PREFIX} = $a[3];}
|
if (@a == 4) {$hash->{PREFIX} = $a[3];}
|
||||||
else {$hash->{PREFIX} = "stat";}
|
else {$hash->{PREFIX} = "stat";}
|
||||||
|
|
||||||
eval { "Hallo" =~ m/^$devname$/ };
|
eval { "Hallo" =~ m/^$devName$/ };
|
||||||
return "Bad regexp: $@" if($@);
|
return "Bad regexp: $@" if($@);
|
||||||
$hash->{DEV_REGEXP} = $devname;
|
$hash->{DEV_REGEXP} = $devName;
|
||||||
|
|
||||||
$hash->{STATE} = "active";
|
$hash->{STATE} = "active";
|
||||||
|
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
|
|
||||||
#Run period change procedure each hour.
|
# Run period change procedure each full hour.
|
||||||
my $periodEndTime = 3600 * (int( gettimeofday() / 3600 ) + 1) ;
|
my $periodEndTime = 3600 * (int( gettimeofday() / 3600 ) + 1) ;
|
||||||
InternalTimer( $periodEndTime, "statistics_PeriodChange", $hash, 0);
|
InternalTimer( $periodEndTime, "statistics_PeriodChange", $hash, 0);
|
||||||
|
|
||||||
@ -126,7 +126,45 @@ sub ########################################
|
|||||||
statistics_Notify($$)
|
statistics_Notify($$)
|
||||||
{
|
{
|
||||||
my ($hash, $dev) = @_;
|
my ($hash, $dev) = @_;
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
my $devName = $dev->{NAME};
|
||||||
|
|
||||||
|
# Delete old Readings of monitored devices at startup
|
||||||
|
if ($devName eq "global" && grep (m/^INITIALIZED|REREADCFG$/,@{$dev->{CHANGED}})){
|
||||||
|
foreach my $r (keys $hash->{READINGS})
|
||||||
|
{
|
||||||
|
if ($r =~ /^monitoredDevices.*/) {
|
||||||
|
Log3 $name,5,"$name: Initialization - Delete old reading $r.";
|
||||||
|
delete($hash->{READINGS}{$r});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Return if the notifying device is not monitored
|
||||||
|
return "" if(!defined($hash->{DEV_REGEXP}));
|
||||||
|
my $regexp = $hash->{DEV_REGEXP};
|
||||||
|
if($devName !~ m/^($regexp)$/) {
|
||||||
|
Log3 $name,5,"$name: Notification of '".$dev->{NAME}."' received. Device not monitored.";
|
||||||
|
return "" ;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if it notifies only for the statistic values
|
||||||
|
my $prefix = $hash->{PREFIX};
|
||||||
|
my $normalReadingFound = 0;
|
||||||
|
my $max = int(@{$dev->{CHANGED}});
|
||||||
|
for (my $i = 0; $i < $max; $i++) {
|
||||||
|
my $s = $dev->{CHANGED}[$i];
|
||||||
|
next if(!defined($s));
|
||||||
|
if ($s !~ /^$prefix[A-Z]/) { $normalReadingFound = 1;}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($normalReadingFound==1) {
|
||||||
statistics_DoStatistics $hash, $dev, 0;
|
statistics_DoStatistics $hash, $dev, 0;
|
||||||
|
Log3 $name,5,"$name: Notification of '".$dev->{NAME}."' received. Update statistics.";
|
||||||
|
} else {
|
||||||
|
Log3 $name,5,"$name: Notification of '".$dev->{NAME}."' received but for my own readings only.";
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -143,12 +181,14 @@ statistics_PeriodChange($)
|
|||||||
#Run period change procedure each hour.
|
#Run period change procedure each hour.
|
||||||
my $periodEndTime = 3600 * (int( gettimeofday() / 3600 ) + 1 );
|
my $periodEndTime = 3600 * (int( gettimeofday() / 3600 ) + 1 );
|
||||||
InternalTimer( $periodEndTime, "statistics_PeriodChange", $hash, 0);
|
InternalTimer( $periodEndTime, "statistics_PeriodChange", $hash, 0);
|
||||||
|
Log3 $name,5,"$name: Next period change will be calculated at ".strftime ("%H:%M:%S", localtime($periodEndTime));
|
||||||
|
|
||||||
return if( AttrVal($name, "disable", 0 ) == 1 );
|
return if( AttrVal($name, "disable", 0 ) == 1 );
|
||||||
|
|
||||||
# Determine if time period switched (day, month, year)
|
# Determine if time period switched (day, month, year)
|
||||||
# Get deltaValue and Tariff of previous call
|
# Get deltaValue and Tariff of previous call
|
||||||
|
|
||||||
my $periodSwitch = 1;
|
my $periodSwitch = 0;
|
||||||
my $yearLast;
|
my $yearLast;
|
||||||
my $monthLast;
|
my $monthLast;
|
||||||
my $dayLast;
|
my $dayLast;
|
||||||
@ -167,10 +207,10 @@ statistics_PeriodChange($)
|
|||||||
{
|
{
|
||||||
if ($r =~ /^monitoredDevices.*/) {
|
if ($r =~ /^monitoredDevices.*/) {
|
||||||
Log3 $name,5,"$name: Starting period change statistics (Type: $periodSwitch) for all devices of reading $r";
|
Log3 $name,5,"$name: Starting period change statistics (Type: $periodSwitch) for all devices of reading $r";
|
||||||
my $devNameArray = split /,/, $hash->{READINGS}{$r};
|
my @devNameArray = split /,/, $hash->{READINGS}{$r};
|
||||||
foreach my $devName ($devNameArray) {
|
foreach my $devName (@devNameArray) {
|
||||||
Log3 $name,5,"$name: Doing period change statistics for device $devName";
|
Log3 $name,5,"$name: Doing period change statistics for device $devName";
|
||||||
# statistics_DoStatistics($hash, $defs{$devName}, $periodSwitch);
|
statistics_DoStatistics($hash, $defs{$devName}, $periodSwitch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -189,17 +229,15 @@ statistics_DoStatistics($$$)
|
|||||||
|
|
||||||
return "" if(AttrVal($hashName, "disable", undef));
|
return "" if(AttrVal($hashName, "disable", undef));
|
||||||
|
|
||||||
# Return if the notifying device is not monitored
|
|
||||||
return "" if(!defined($hash->{DEV_REGEXP}));
|
|
||||||
my $regexp = $hash->{DEV_REGEXP};
|
|
||||||
return "" if($devName !~ m/^($regexp)$/);
|
|
||||||
|
|
||||||
my $output = $devName." (".$devType.")" ;
|
my $output = $devName." (".$devType.")" ;
|
||||||
my $max = int(@{$dev->{CHANGED}});
|
my $max = int(@{$dev->{CHANGED}});
|
||||||
my $readingName;
|
my $readingName;
|
||||||
my $value;
|
my $value;
|
||||||
my $exclReadings = AttrVal($hashName, "excludedReadings", "");
|
my $exclReadings = AttrVal($hashName, "excludedReadings", "");
|
||||||
|
|
||||||
|
readingsBeginUpdate($hash);
|
||||||
|
readingsBeginUpdate($dev);
|
||||||
|
|
||||||
# Loop through all known device types and readings
|
# Loop through all known device types and readings
|
||||||
foreach my $f (@knownDeviceReadings)
|
foreach my $f (@knownDeviceReadings)
|
||||||
{
|
{
|
||||||
@ -213,6 +251,8 @@ statistics_DoStatistics($$$)
|
|||||||
if ($$f[2] == 2) { statistics_doStatisticDelta ($hash, $dev, $readingName, $$f[3], $periodSwitch);}
|
if ($$f[2] == 2) { statistics_doStatisticDelta ($hash, $dev, $readingName, $$f[3], $periodSwitch);}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ($periodSwitch >0) {readingsEndUpdate($dev,1);}
|
||||||
|
else {readingsEndUpdate($dev,0);}
|
||||||
|
|
||||||
# Record device as monitored
|
# Record device as monitored
|
||||||
my $monReadingName = "monitoredDevices".$devType;
|
my $monReadingName = "monitoredDevices".$devType;
|
||||||
@ -221,8 +261,10 @@ statistics_DoStatistics($$$)
|
|||||||
if ($monReadingValue !~ /$temp/) {
|
if ($monReadingValue !~ /$temp/) {
|
||||||
if($monReadingValue eq "") { $monReadingValue = $devName;}
|
if($monReadingValue eq "") { $monReadingValue = $devName;}
|
||||||
else {$monReadingValue .= ",".$devName;}
|
else {$monReadingValue .= ",".$devName;}
|
||||||
readingsSingleUpdate($hash,$monReadingName,$monReadingValue,0);
|
readingsBulkUpdate($hash,$monReadingName,$monReadingValue);
|
||||||
}
|
}
|
||||||
|
readingsEndUpdate($hash,1);
|
||||||
|
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
@ -290,17 +332,17 @@ statistics_doStatisticMinMaxSingle ($$$$$$)
|
|||||||
|
|
||||||
# Store current reading as last reading, Reset current reading
|
# Store current reading as last reading, Reset current reading
|
||||||
if ($saveLast) {
|
if ($saveLast) {
|
||||||
readingsSingleUpdate($dev, $statReadingName . "Last", $result,0);
|
readingsBulkUpdate($dev, $statReadingName . "Last", $result);
|
||||||
$hidden[1] = 0; $hidden[3] = 0; $hidden[9] = 0; # No since value anymore
|
$hidden[1] = 0; $hidden[3] = 0; $hidden[9] = 0; # No since value anymore
|
||||||
$result = "Min: $value Avg: $value Max: $value";
|
$result = "Min: $value Avg: $value Max: $value";
|
||||||
}
|
}
|
||||||
|
|
||||||
# Store current reading
|
# Store current reading
|
||||||
readingsSingleUpdate($dev, $statReadingName, $result,0);
|
readingsBulkUpdate($dev, $statReadingName, $result);
|
||||||
|
|
||||||
# Store hidden reading
|
# Store hidden reading
|
||||||
$result = "Sum: $hidden[1] Time: $hidden[3] LastValue: ".$value." LastTime: ".int(gettimeofday())." ShowDate: $hidden[9]";
|
$result = "Sum: $hidden[1] Time: $hidden[3] LastValue: ".$value." LastTime: ".int(gettimeofday())." ShowDate: $hidden[9]";
|
||||||
readingsSingleUpdate($hash, $hiddenReadingName, $result,0);
|
readingsBulkUpdate($hash, $hiddenReadingName, $result);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -396,18 +438,18 @@ statistics_doStatisticDelta ($$$$$)
|
|||||||
# Store visible statistic readings (delta values)
|
# Store visible statistic readings (delta values)
|
||||||
$result = "Hour: $stat[1] Day: $stat[3] Month: $stat[5] Year: $stat[7]";
|
$result = "Hour: $stat[1] Day: $stat[3] Month: $stat[5] Year: $stat[7]";
|
||||||
if ( $showDate >=2 ) { $result .= " (since: $stat[9] )"; }
|
if ( $showDate >=2 ) { $result .= " (since: $stat[9] )"; }
|
||||||
readingsSingleUpdate($dev,$statReadingName,$result,0);
|
readingsBulkUpdate($dev,$statReadingName,$result);
|
||||||
|
|
||||||
# if changed, store previous visible statistic (delta) values
|
# if changed, store previous visible statistic (delta) values
|
||||||
if ($periodSwitch >= 1) {
|
if ($periodSwitch >= 1) {
|
||||||
$result = "Hour: $last[1] Day: $last[3] Month: $last[5] Year: $last[7]";
|
$result = "Hour: $last[1] Day: $last[3] Month: $last[5] Year: $last[7]";
|
||||||
if ( $showDate =~ /1|3|5|7/ ) { $result .= " (since: $last[9] )";}
|
if ( $showDate =~ /1|3|5|7/ ) { $result .= " (since: $last[9] )";}
|
||||||
readingsSingleUpdate($dev,$statReadingName."Last",$result,0);
|
readingsBulkUpdate($dev,$statReadingName."Last",$result);
|
||||||
}
|
}
|
||||||
|
|
||||||
# Store hidden reading
|
# Store hidden reading
|
||||||
$result = "LastValue: $value ShowDate: $showDate ";
|
$result = "LastValue: $value ShowDate: $showDate ";
|
||||||
readingsSingleUpdate($hash, $hiddenReadingName, $result,0);
|
readingsBulkUpdate($hash, $hiddenReadingName, $result);
|
||||||
|
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
@ -519,7 +561,7 @@ statistics_doStatisticDelta ($$$$$)
|
|||||||
<li><code>excludedReadings <GeräteName:WertRegExp></code>
|
<li><code>excludedReadings <GeräteName:WertRegExp></code>
|
||||||
<br>
|
<br>
|
||||||
Regulärer Ausdruck der Gerätewerte, für die keine Statistiken gebildet werden sollen.<br>
|
Regulärer Ausdruck der Gerätewerte, für die keine Statistiken gebildet werden sollen.<br>
|
||||||
Die Gerätewerte werden in der Form <i>Geätename:Geätewert</i> angegeben. Z.B. "FritzDect:current|Sensor_.*:humidity"
|
Die Gerätewerte werden in der Form <i>Gerätename:Gerätewert</i> angegeben. Z.B. "FritzDect:current|Sensor_.*:humidity"
|
||||||
<br>
|
<br>
|
||||||
</li><br>
|
</li><br>
|
||||||
</ul>
|
</ul>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user