git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@5743 2b470e98-0d58-463d-a4d8-8e2adae1ed80

This commit is contained in:
tpoitzsch 2014-05-04 19:10:48 +00:00
parent 65dd66ef37
commit 45b5a4d1b1
3 changed files with 148 additions and 109 deletions

View File

@ -310,14 +310,11 @@ LUXTRONIK2_GetUpdate($)
if(!$hash->{LOCAL}) { if(!$hash->{LOCAL}) {
RemoveInternalTimer($hash); RemoveInternalTimer($hash);
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "LUXTRONIK2_GetUpdate", $hash, 1); InternalTimer(gettimeofday()+$hash->{INTERVAL}, "LUXTRONIK2_GetUpdate", $hash, 1);
return undef if( AttrVal($name, "disable", 0 ) == 1 );
} }
my $host = $hash->{HOST}; my $host = $hash->{HOST};
if( !$hash->{LOCAL} ) {
return undef if( AttrVal($name, "disable", 0 ) == 1 );
}
$hash->{helper}{RUNNING_PID} = BlockingCall("LUXTRONIK2_DoUpdate", $name."|".$host, "LUXTRONIK2_UpdateDone", 25, "LUXTRONIK2_UpdateAborted", $hash) unless(exists($hash->{helper}{RUNNING_PID})); $hash->{helper}{RUNNING_PID} = BlockingCall("LUXTRONIK2_DoUpdate", $name."|".$host, "LUXTRONIK2_UpdateDone", 25, "LUXTRONIK2_UpdateAborted", $hash) unless(exists($hash->{helper}{RUNNING_PID}));
} }
@ -760,7 +757,7 @@ LUXTRONIK2_UpdateDone($)
$heatPumpPower *= 1 + ($flowTemperature-35) * AttrVal($name, "heatPumpElectricalPowerFactor", 0); $heatPumpPower *= 1 + ($flowTemperature-35) * AttrVal($name, "heatPumpElectricalPowerFactor", 0);
} }
readingsBulkUpdate( $hash, "thermalPower", sprintf "%.1f", $thermalPower); readingsBulkUpdate( $hash, "thermalPower", sprintf "%.1f", $thermalPower);
if ($heatPumpPower >-1 ) { readingsBulkUpdate( $hash, "heatPumpElectricalPowerEstimated", sprintf "%.0f", $heatPumpPower); } if ($heatPumpPower >-1 ) { readingsBulkUpdate( $hash, "heatPumpElectricalPowerEstimated", sprintf "%.0f", $heatPumpPower); }
if ($heatPumpPower > 0) { if ($heatPumpPower > 0) {
$cop = $thermalPower * 1000 / $heatPumpPower; $cop = $thermalPower * 1000 / $heatPumpPower;
readingsBulkUpdate( $hash, "COP", sprintf "%.2f", $cop); readingsBulkUpdate( $hash, "COP", sprintf "%.2f", $cop);

View File

@ -326,6 +326,7 @@ JSONMETER_GetUpdate($)
if(!$hash->{LOCAL} && $hash->{INTERVAL} > 0) { if(!$hash->{LOCAL} && $hash->{INTERVAL} > 0) {
RemoveInternalTimer($hash); RemoveInternalTimer($hash);
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "JSONMETER_GetUpdate", $hash, 1); InternalTimer(gettimeofday()+$hash->{INTERVAL}, "JSONMETER_GetUpdate", $hash, 1);
return undef if( AttrVal($name, "disable", 0 ) == 1 );
} }

View File

@ -37,8 +37,10 @@ use strict;
use warnings; use warnings;
use Time::Local; use Time::Local;
sub statistics_doStatisticMinMax ($$$$); sub statistics_PeriodChange($);
sub statistics_doStatisticMinMax ($$$$$);
sub statistics_doStatisticMinMaxSingle ($$$$$$); sub statistics_doStatisticMinMaxSingle ($$$$$$);
sub statistics_DoStatistics ($$$);
# Modul Version for remote debugging # Modul Version for remote debugging
my $modulVersion = "2014-05-04"; my $modulVersion = "2014-05-04";
@ -54,8 +56,9 @@ sub statistics_doStatisticMinMaxSingle ($$$$$$);
,["KS300", "temperature", 1, 1] ,["KS300", "temperature", 1, 1]
,["KS300", "wind", 1, 0] ,["KS300", "wind", 1, 0]
,["KS300", "rain", 2, 1] ,["KS300", "rain", 2, 1]
,["FBDECT", "current", 1, 3]
,["FBDECT", "energy", 2, 0] ,["FBDECT", "energy", 2, 0]
,["FBDECT", "power", 1, 2] ,["FBDECT", "power", 1, 1]
,["FBDECT", "voltage", 1, 1] ,["FBDECT", "voltage", 1, 1]
); );
############################################################## ##############################################################
@ -66,12 +69,13 @@ statistics_Initialize($)
my ($hash) = @_; my ($hash) = @_;
$hash->{DefFn} = "statistics_Define"; $hash->{DefFn} = "statistics_Define";
$hash->{UndefFn} = "LUXTRONIK2_Undefine";
$hash->{NotifyFn} = "statistics_Notify"; $hash->{NotifyFn} = "statistics_Notify";
$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 "
."DayChangeTime " ."DayChangeTime "
."CorrectionValue " ."excludedReadings "
.$readingFnAttributes; .$readingFnAttributes;
} }
@ -96,15 +100,88 @@ statistics_Define($$)
$hash->{DEV_REGEXP} = $devname; $hash->{DEV_REGEXP} = $devname;
$hash->{STATE} = "active"; $hash->{STATE} = "active";
RemoveInternalTimer($hash);
#Run period change procedure each hour.
my $periodEndTime = 3600 * (int( gettimeofday() / 3600 ) + 1) ;
InternalTimer( $periodEndTime, "statistics_PeriodChange", $hash, 0);
return undef;
}
sub ########################################
statistics_Undefine($$)
{
my ($hash, $arg) = @_;
RemoveInternalTimer($hash);
return undef; return undef;
} }
########################## sub ########################################
sub
statistics_Notify($$) statistics_Notify($$)
{ {
my ($hash, $dev) = @_; my ($hash, $dev) = @_;
statistics_DoStatistics $hash, $dev, 0;
return;
}
sub ########################################
statistics_PeriodChange($)
{
my ($hash) = @_;
my $name = $hash->{NAME};
my $dummy;
RemoveInternalTimer($hash);
#Run period change procedure each hour.
my $periodEndTime = 3600 * (int( gettimeofday() / 3600 ) + 1 );
InternalTimer( $periodEndTime, "statistics_PeriodChange", $hash, 0);
return if( AttrVal($name, "disable", 0 ) == 1 );
# Determine if time period switched (day, month, year)
# Get deltaValue and Tariff of previous call
my $periodSwitch = 1;
my $yearLast;
my $monthLast;
my $dayLast;
my $dayNow;
my $monthNow;
my $yearNow;
($dummy, $dummy, $dummy, $dayLast, $monthLast, $yearLast) = localtime (gettimeofday()-1800);
($dummy, $dummy, $dummy, $dayNow, $monthNow, $yearNow) = localtime (gettimeofday());
if ($yearNow != $yearLast) { $periodSwitch = 4; }
elsif ($monthNow != $monthLast) { $periodSwitch = 3; }
elsif ($dayNow != $dayLast) { $periodSwitch = 2; }
foreach my $r (keys $hash->{READINGS})
{
if ($r =~ /^monitoredDevices.*/) {
Log3 $name,5,"$name: Starting period change statistics (Type: $periodSwitch) for all devices of reading $r";
my $devNameArray = split /,/, $r;
foreach my $devName ($devNameArray) {
Log3 $name,5,"$name: Doing period change statistics for device $devName";
# statistics_DoStatistics($hash, $defs{$devName}, $periodSwitch);
}
}
}
return undef;
}
##########################
sub
statistics_DoStatistics($$$)
{
my ($hash, $dev, $periodSwitch) = @_;
my $hashName = $hash->{NAME}; my $hashName = $hash->{NAME};
my $devName = $dev->{NAME}; my $devName = $dev->{NAME};
my $devType = $dev->{TYPE}; my $devType = $dev->{TYPE};
@ -125,8 +202,8 @@ statistics_Notify($$)
{ {
$readingName = $$f[1]; $readingName = $$f[1];
# notifing device type is known and the device has also the known reading # notifing device type is known and the device has also the known reading
if ($$f[0] eq $devType && exists ($dev->{READINGS}{$readingName})) { if ($$f[0] eq $devType ) {
if ($$f[2] == 1) { statistics_doStatisticMinMax ($hash, $dev, $readingName, $$f[3]);} if ($$f[2] == 1) { statistics_doStatisticMinMax ($hash, $dev, $readingName, $$f[3], $periodSwitch);}
} }
} }
@ -145,49 +222,22 @@ statistics_Notify($$)
# Calculates single MaxMin Values and informs about end of day and month # Calculates single MaxMin Values and informs about end of day and month
sub ######################################## sub ########################################
statistics_doStatisticMinMax ($$$$) statistics_doStatisticMinMax ($$$$$)
{ {
my ($hash, $dev, $readingName, $decPlaces) = @_; my ($hash, $dev, $readingName, $decPlaces, $periodSwitch) = @_;
my $dummy;
my $lastReading; return if not exists ($dev->{READINGS}{$readingName});
my $lastSums;
my @newReading;
my $yearLast;
my $monthLast;
my $dayLast;
my $dayNow;
my $monthNow;
my $yearNow;
my $prefix = $hash->{PREFIX};
my $value = $dev->{READINGS}{$readingName}{VAL}; my $value = $dev->{READINGS}{$readingName}{VAL};
$value =~ s/^([\d.]*).*/$1/eg; $value = ($value =~ s/^([\d.]*)/$1/eg);
# Determine date of last and current reading
if (exists($dev->{READINGS}{$prefix.ucfirst($readingName)."Day"}{TIME})) {
($yearLast, $monthLast, $dayLast) = $dev->{READINGS}{$prefix.ucfirst($readingName)."Day"}{TIME} =~ /^(\d\d\d\d)-(\d\d)-(\d\d)/;
} else {
($dummy, $dummy, $dummy, $dayLast, $monthLast, $yearLast) = localtime;
$yearLast += 1900;
$monthLast ++;
}
($dummy, $dummy, $dummy, $dayNow, $monthNow, $yearNow) = localtime;
$yearNow += 1900;
$monthNow ++;
# statistics_doStatisticMinMaxSingle: $hash, $readingName, $value, $saveLast, decPlaces
# Daily Statistic # Daily Statistic
#statistics_doStatisticMinMaxSingle: $hash, $readingName, $value, $saveLast, decPlaces statistics_doStatisticMinMaxSingle $hash, $dev, $readingName."Day", $value, ($periodSwitch >= 2), $decPlaces;
statistics_doStatisticMinMaxSingle $hash, $dev, $readingName."Day", $value, ($dayNow != $dayLast), $decPlaces;
# Monthly Statistic # Monthly Statistic
#statistics_doStatisticMinMaxSingle: $hash, $readingName, $value, $saveLast, decPlaces statistics_doStatisticMinMaxSingle $hash, $dev, $readingName."Month", $value, ($periodSwitch >= 3), $decPlaces;
statistics_doStatisticMinMaxSingle $hash, $dev, $readingName."Month", $value, ($monthNow != $monthLast), $decPlaces;
# Yearly Statistic # Yearly Statistic
#statistics_doStatisticMinMaxSingle: $hash, $readingName, $value, $saveLast, decPlaces statistics_doStatisticMinMaxSingle $hash, $dev, $readingName."Year", $value, ($periodSwitch == 4), $decPlaces;
statistics_doStatisticMinMaxSingle $hash, $dev, $readingName."Year", $value, ($yearNow != $yearLast), $decPlaces;
return ; return ;
@ -203,65 +253,66 @@ statistics_doStatisticMinMaxSingle ($$$$$$)
my $statReadingName = $hash->{PREFIX}; my $statReadingName = $hash->{PREFIX};
$statReadingName .= ucfirst($readingName); $statReadingName .= ucfirst($readingName);
my @hidden;
my @stat;
my $firstRun = not exists($hash->{READINGS}{$hiddenReadingName});
my $lastReading = $dev->{READINGS}{$statReadingName}{VAL} || ""; if ( $firstRun ) {
# Show since-Value
# Initializing $hidden[1] = 0; $hidden[3] = 0; $hidden[9] = 1;
if ( $lastReading eq "" ) { $stat[1] = $value; $stat[3] = $value; $stat[5] = $value;
my $since = strftime "%Y-%m-%d_%H:%M:%S", localtime(); $stat[7] = strftime ("%Y-%m-%d_%H:%M:%S",localtime());
$result = "Count: 1 Sum: $value ShowDate: 1"; } else {
readingsSingleUpdate($hash, $hiddenReadingName, $result,0); # Do calculations if hidden reading exists
@hidden = split / /, $hash->{READINGS}{$hiddenReadingName}{VAL}; # Internal values
$value = sprintf( "%.".$decPlaces."f", $value); @stat = split / /, $dev->{READINGS}{$statReadingName}{VAL};
$result = "Min: $value Avg: $value Max: $value (since: $since )"; my $timeDiff = gettimeofday()-$hidden[7];
readingsSingleUpdate($dev, $statReadingName, $result,0); $hidden[1] += $hidden[5] * $timeDiff; # sum
$hidden[3] += $timeDiff; # time
# Calculations if ($value < $stat[1]) { $stat[1]=$value; } # Min
} else { $stat[3] = $hidden[1] / $hidden[3]; # Avg
my @a = split / /, $hash->{READINGS}{$hiddenReadingName}{VAL}; # Internal values if ($value > $stat[5]) { $stat[5]=$value; } # Max
my @b = split / /, $lastReading;
# Do calculations
$a[1]++; # Count
$a[3] += $value; # Sum
if ($value < $b[1]) { $b[1]=$value; } # Min
$b[3] = $a[3] / $a[1]; # Avg
if ($value > $b[5]) { $b[5]=$value; } # Max
# in case of period change, save "last" values and reset counters
if ($saveLast) {
$result = "Min: $b[1] Avg: $b[3] Max: $b[5]";
if ($a[5] == 1) { $result .= " (since: $b[7] )"; }
readingsSingleUpdate($dev, $statReadingName . "Last", $lastReading,0);
$a[1] = 1; $a[3] = $value; $a[5] = 0;
$b[1] = $value; $b[3] = $value; $b[5] = $value;
}
# Store internal calculation values
$result = "Count: $a[1] Sum: $a[3] ShowDate: $a[5]";
readingsSingleUpdate($hash, $hiddenReadingName, $result,0);
# Store visible Reading
$result = "Min: ". sprintf( "%.".$decPlaces."f", $b[1]);
$result .= " Avg: ". sprintf( "%.".$decPlaces."f", $b[3]);
$result .= " Max: ". sprintf( "%.".$decPlaces."f", $b[5]);
if ($a[5] == 1) { $result .= " (since: $b[7] )"; }
readingsSingleUpdate($dev, $statReadingName, $result,0);
} }
# Prepare new current reading
$result = "Min: ". sprintf( "%.".$decPlaces."f", $stat[1]);
$result .= " Avg: ". sprintf( "%.".$decPlaces."f", $stat[3]);
$result .= " Max: ". sprintf( "%.".$decPlaces."f", $stat[5]);
if ($hidden[9] == 1) { $result .= " (since: $stat[7] )"; }
# Store current reading as last reading, Reset current reading
if ($saveLast) {
readingsSingleUpdate($dev, $statReadingName . "Last", $result,0);
$hidden[1] = 0; $hidden[3] = 0; $hidden[9] = 0; # No since value anymore
$result = "Min: $value Avg: $value Max: $value";
}
# Store current reading
readingsSingleUpdate($dev, $statReadingName, $result,0);
# Store hidden reading
$result = "Sum: $hidden[1] Time: $hidden[3] LastValue: ".$value." LastTime: ".gettimeofday()." ShowDate: $hidden[9]";
readingsSingleUpdate($hash, $hiddenReadingName, $result,0);
return; return;
} }
# Calculates deltas for day, month and year # Calculates deltas for day, month and year
sub ######################################## sub ########################################
statistics_doStatisticDelta ($$$$$) statistics_doStatisticDelta ($$$$)
{ {
my ($hash, $readingName, $value, $special, $activeTariff) = @_; my ($hash, $dev, $readingName, $decPlaces) = @_;
my $dummy; my $dummy;
my $result; my $result;
my $deltaValue; my $deltaValue;
my $previousTariff; my $previousTariff;
my $showDate; my $showDate;
# Determine if time period switched (day, month, year) my $value = $dev->{READINGS}{$readingName}{VAL};
# Determine if time period switched (day, month, year)
# Get deltaValue and Tariff of previous call # Get deltaValue and Tariff of previous call
my $periodSwitch = 0; my $periodSwitch = 0;
my $yearLast; my $monthLast; my $dayLast; my $hourLast; my $hourNow; my $dayNow; my $monthNow; my $yearNow; my $yearLast; my $monthLast; my $dayLast; my $hourLast; my $hourNow; my $dayNow; my $monthNow; my $yearNow;
@ -269,7 +320,7 @@ statistics_doStatisticDelta ($$$$$)
($yearLast, $monthLast, $dayLast, $hourLast) = ($hash->{READINGS}{"." . $readingName . "Before"}{TIME} =~ /^(\d\d\d\d)-(\d\d)-(\d\d) (\d\d)/); ($yearLast, $monthLast, $dayLast, $hourLast) = ($hash->{READINGS}{"." . $readingName . "Before"}{TIME} =~ /^(\d\d\d\d)-(\d\d)-(\d\d) (\d\d)/);
$yearLast -= 1900; $yearLast -= 1900;
$monthLast --; $monthLast --;
($dummy, $deltaValue, $dummy, $previousTariff, $dummy, $showDate) = split / /, $hash->{READINGS}{"." . $readingName . "Before"}{VAL} || ""; ($dummy, $deltaValue, $dummy, $showDate) = split / /, $hash->{READINGS}{"." . $readingName . "Before"}{VAL} || "";
$deltaValue = $value - $deltaValue; $deltaValue = $value - $deltaValue;
} else { } else {
($dummy, $dummy, $hourLast, $dayLast, $monthLast, $yearLast) = localtime; ($dummy, $dummy, $hourLast, $dayLast, $monthLast, $yearLast) = localtime;
@ -302,28 +353,20 @@ statistics_doStatisticDelta ($$$$$)
if ($showDate >= 8) { $showDate = 7; } # Shows the "since:" value for the first hour change if ($showDate >= 8) { $showDate = 7; } # Shows the "since:" value for the first hour change
} }
# statistics_doStatisticDeltaSingle; $hash, $readingName, $deltaValue, $special, $periodSwitch, $showDate, $firstCall # statistics_doStatisticDeltaSingle; $hash, $readingName, $deltaValue, $periodSwitch, $showDate, $firstCall
statistics_doStatisticDeltaSingle ($hash, $readingName, $deltaValue, $special, $periodSwitch, $showDate); statistics_doStatisticDeltaSingle ($hash, $readingName, $deltaValue, $periodSwitch, $showDate);
foreach (1,2,3,4,5,6,7,8,9) { # Hidden storage of current values for next call(before values)
if ( $previousTariff == $_ ) { $result = "Value: $value ShowDate: $showDate ";
statistics_doStatisticDeltaSingle ($hash, $readingName."Tariff".$_, $deltaValue, 0, $periodSwitch, $showDate);
} elsif ($activeTariff == $_ || ($periodSwitch > 0 && exists($hash->{READINGS}{$readingName . "Tariff".$_}))) {
statistics_doStatisticDeltaSingle ($hash, $readingName."Tariff".$_, 0, 0 , $periodSwitch, $showDate);
}
}
# Hidden storage of current values for next call(before values)
$result = "Value: $value Tariff: $activeTariff ShowDate: $showDate ";
readingsBulkUpdate($hash, ".".$readingName."Before", $result); readingsBulkUpdate($hash, ".".$readingName."Before", $result);
return ; return ;
} }
sub ######################################## sub ########################################
statistics_doStatisticDeltaSingle ($$$$$$) statistics_doStatisticDeltaSingle ($$$$$)
{ {
my ($hash, $readingName, $deltaValue, $special, $periodSwitch, $showDate) = @_; my ($hash, $readingName, $deltaValue, $periodSwitch, $showDate) = @_;
my $dummy; my $dummy;
my $result; my $result;
@ -393,8 +436,6 @@ statistics_doStatisticDeltaSingle ($$$$$$)
if ( $showDate >=2 ) { $result .= " (since: $curr[9] )"; } if ( $showDate >=2 ) { $result .= " (since: $curr[9] )"; }
readingsBulkUpdate($hash,$readingName,$result); readingsBulkUpdate($hash,$readingName,$result);
if ($special == 1) { readingsBulkUpdate($hash,$readingName."Today",$curr[3]) };
# 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]";