2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-03 16:56:54 +00:00

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

This commit is contained in:
tpoitzsch 2014-02-08 10:30:40 +00:00
parent 215263bca1
commit f028c1d9dd
2 changed files with 221 additions and 112 deletions

View File

@ -1,6 +1,7 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # 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. # Do not insert empty lines here, update check depends on it.
- SVN - SVN
- feature: LUXTRONIK2: attribute 'doStatistics' calculates boiler gradients
- feature: GEOFANCY: support both apps, Geofency.app and Geofancy.app - feature: GEOFANCY: support both apps, Geofency.app and Geofancy.app
- feature: LightScene: added attribute lightSceneRestoreOnlyIfChanged - feature: LightScene: added attribute lightSceneRestoreOnlyIfChanged
- bugfix: SYSMON: Fix: CPUTemp & BogoMIPS for utilite-Box. - bugfix: SYSMON: Fix: CPUTemp & BogoMIPS for utilite-Box.
@ -30,7 +31,7 @@
- feature: DASHBOARD: Dashboard get Tabs. Redesign saving of Group - feature: DASHBOARD: Dashboard get Tabs. Redesign saving of Group
positioning. positioning.
- bugfix: SYSMON: Log Warnings, unnoetige Readings erkenen und entfernen - bugfix: SYSMON: Log Warnings, unnoetige Readings erkenen und entfernen
- feature: LUXTRONIK2: Setting of controller parameter and internal clock now possible - feature: LUXTRONIK2: Setting of controller parameter and internal clock
- feature: new module 71_YAMAHA_BD.pm to control Yamaha Blu-Ray - feature: new module 71_YAMAHA_BD.pm to control Yamaha Blu-Ray
players over network. players over network.
- bugfix: DbLog: fix for plotfork - bugfix: DbLog: fix for plotfork

View File

@ -83,6 +83,7 @@ LUXTRONIK2_Define($$)
$hash->{STATE} = "Initializing"; $hash->{STATE} = "Initializing";
$hash->{HOST} = $host; $hash->{HOST} = $host;
$hash->{INTERVAL} = $interval; $hash->{INTERVAL} = $interval;
$hash->{NOTIFYDEV} = "global";
RemoveInternalTimer($hash); RemoveInternalTimer($hash);
#Get first data after 10 seconds #Get first data after 10 seconds
@ -92,7 +93,8 @@ LUXTRONIK2_Define($$)
$hash->{fhem}{durationFetchReadingsMin} = 0; $hash->{fhem}{durationFetchReadingsMin} = 0;
$hash->{fhem}{durationFetchReadingsMax} = 0; $hash->{fhem}{durationFetchReadingsMax} = 0;
$hash->{fhem}{alertFirmware} = 0; $hash->{fhem}{alertFirmware} = 0;
$hash->{fhem}{statModeHotWater} = 0; $hash->{fhem}{statBoilerHeatUpStep} = 0;
$hash->{fhem}{statBoilerCoolDownStep} = 0;
$hash->{fhem}{modulVersion} = $modulVersion; $hash->{fhem}{modulVersion} = $modulVersion;
Log3 $hash,5,"$name: LUXTRONIK2.pm version is $modulVersion."; Log3 $hash,5,"$name: LUXTRONIK2.pm version is $modulVersion.";
@ -117,8 +119,7 @@ LUXTRONIK2_Notify(@) {
my ($hash,$dev) = @_; my ($hash,$dev) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
if ($dev->{NAME} eq "global" ) { # splitted to reduce CPU load if ($dev->{NAME} eq "global" && grep (m/^INITIALIZED|REREADCFG$/,@{$dev->{CHANGED}})){
if (grep (m/^INITIALIZED|REREADCFG$/,@{$dev->{CHANGED}})){
# housekeeping # housekeeping
my %cleanUp = ( my %cleanUp = (
delayDeviceTime => "delayDeviceTimeCalc", delayDeviceTime => "delayDeviceTimeCalc",
@ -146,8 +147,8 @@ LUXTRONIK2_Notify(@) {
hotWaterStatus => "opStateHotWater", hotWaterStatus => "opStateHotWater",
hotWaterState => "opStateHotWater", hotWaterState => "opStateHotWater",
heatingSystemCirculationPump => "heatingSystemCircPump", heatingSystemCirculationPump => "heatingSystemCircPump",
hotWaterCirculationPumpExtern => "hotWaterCircPumpExtern" ); hotWaterCirculationPumpExtern => "hotWaterCircPumpExtern",
statGradientBoilerTempLoss => "statBoilerGradientHeatUp' and 'statBoilerGradientCoolDown" );
my $oldReading; my $oldReading;
my $newReading; my $newReading;
while (($oldReading, $newReading) = each(%cleanUp)) { while (($oldReading, $newReading) = each(%cleanUp)) {
@ -157,7 +158,6 @@ LUXTRONIK2_Notify(@) {
} }
} }
} }
}
return; return;
} }
@ -174,14 +174,14 @@ LUXTRONIK2_Set($$@)
$hash->{LOCAL} = 0; $hash->{LOCAL} = 0;
return undef; return undef;
} }
elsif ($cmd eq 'deleteStatistics') { elsif ($cmd eq 'resetStatistics') {
if ( ($val eq "all" || $val eq "statGradientBoilerTempLoss") if ( ($val eq "all" || $val eq "statBoilerGradientCoolDownMin")
&& exists($defs{$name}{READINGS}{statGradientBoilerTempLoss})) { && exists($defs{$name}{READINGS}{statBoilerGradientCoolDownMin})) {
delete $defs{$name}{READINGS}{statGradientBoilerTempLoss}; delete $defs{$name}{READINGS}{statBoilerGradientCoolDownMin};
$resultStr .= " statGradientBoilerTempLoss"; $resultStr .= " statBoilerGradientCoolDownMin";
} }
if ( $resultStr eq "" ) { if ( $resultStr eq "" ) {
$resultStr = "$name: No statistics to delete"; $resultStr = "$name: No statistics to reset";
} else { } else {
$resultStr = "$name: Statistic value(s) deleted:" . $resultStr; $resultStr = "$name: Statistic value(s) deleted:" . $resultStr;
} }
@ -233,7 +233,7 @@ LUXTRONIK2_Set($$@)
} }
my $list = "statusRequest:noArg". my $list = "statusRequest:noArg".
" deleteStatistics:all,statGradientBoilerTempLoss". " resetStatistics:all,statBoilerGradientCoolDownMin".
" hotWaterTemperatureTarget:slider,30.0,0.5,65.0". " hotWaterTemperatureTarget:slider,30.0,0.5,65.0".
" opModeHotWater:Auto,Party,Off". " opModeHotWater:Auto,Party,Off".
" synchronizeClockHeatPump:noArg". " synchronizeClockHeatPump:noArg".
@ -582,6 +582,8 @@ SKIP_VISIBILITY_READING:
$return_str .= "|".$heatpump_parameters[13]; $return_str .= "|".$heatpump_parameters[13];
# 48 - thresholdTemperatureSetBack # 48 - thresholdTemperatureSetBack
$return_str .= "|".$heatpump_parameters[111]; $return_str .= "|".$heatpump_parameters[111];
# 49 - hotWaterTemperatureHysterese
$return_str .= "|".$heatpump_parameters[74];
return $return_str; return $return_str;
} }
@ -611,7 +613,9 @@ LUXTRONIK2_UpdateDone($)
1 => "Waermepumpe steht", 1 => "Waermepumpe steht",
2 => "Waermepumpe kommt", 2 => "Waermepumpe kommt",
4 => "Fehler", 4 => "Fehler",
5 => "Abtauen" ); 5 => "Abtauen",
6 => "Warte auf LIN-Verbindung",
7 => "Verdichter heizt auf");
my %wpOpStat2 = ( 0 => "Heizbetrieb", my %wpOpStat2 = ( 0 => "Heizbetrieb",
1 => "Keine Anforderung", 1 => "Keine Anforderung",
2 => "Netz Einschaltverzoegerung", 2 => "Netz Einschaltverzoegerung",
@ -623,7 +627,7 @@ LUXTRONIK2_UpdateDone($)
8 => "Pumpenvorlauf", 8 => "Pumpenvorlauf",
9 => "Thermische Desinfektion", 9 => "Thermische Desinfektion",
10 => "Kuehlbetrieb", 10 => "Kuehlbetrieb",
12 => "Schwimmbad", 12 => "Schwimmbad/Photovoltaik",
13 => "Heizen_Ext_En", 13 => "Heizen_Ext_En",
14 => "Brauchw_Ext_En", 14 => "Brauchw_Ext_En",
16 => "Durchflussueberwachung", 16 => "Durchflussueberwachung",
@ -686,6 +690,8 @@ LUXTRONIK2_UpdateDone($)
my $ambientTemperature = LUXTRONIK2_CalcTemp($a[12]); my $ambientTemperature = LUXTRONIK2_CalcTemp($a[12]);
my $averageAmbientTemperature = LUXTRONIK2_CalcTemp($a[13]); my $averageAmbientTemperature = LUXTRONIK2_CalcTemp($a[13]);
my $hotWaterTemperature = LUXTRONIK2_CalcTemp($a[14]); my $hotWaterTemperature = LUXTRONIK2_CalcTemp($a[14]);
my $hotWaterTemperatureTarget = LUXTRONIK2_CalcTemp($a[25]);
my $hotWaterTemperatureThreshold = LUXTRONIK2_CalcTemp($a[25] - $a[49]);
my $thresholdHeatingLimit = LUXTRONIK2_CalcTemp($a[21]); my $thresholdHeatingLimit = LUXTRONIK2_CalcTemp($a[21]);
my $thresholdTemperatureSetBack = LUXTRONIK2_CalcTemp($a[48]); my $thresholdTemperatureSetBack = LUXTRONIK2_CalcTemp($a[48]);
my $flowTemperature = LUXTRONIK2_CalcTemp($a[15]); my $flowTemperature = LUXTRONIK2_CalcTemp($a[15]);
@ -693,10 +699,28 @@ LUXTRONIK2_UpdateDone($)
# if selected, do all the statistic calculations # if selected, do all the statistic calculations
if ( AttrVal($name,"doStatistics",0) == 1) { if ( AttrVal($name,"doStatistics",0) == 1) {
$value = LUXTRONIK2_doStatisticBoiler ($hash, $a[22], $a[37]/10, $hotWaterTemperature); #LUXTRONIK2_doStatisticBoilerHeatUp $hash, $currOpHours, $currHQ, $currTemp, $opState, $target
$value = LUXTRONIK2_doStatisticBoilerHeatUp ($hash, $a[35], $a[37]/10, $hotWaterTemperature, $a[3],$hotWaterTemperatureTarget);
if ($value ne "") { if ($value ne "") {
readingsBulkUpdate($hash,"statGradientBoilerTempLoss",$value); readingsBulkUpdate($hash,"statBoilerGradientHeatUp",$value);
Log3 $name,3,"$name: statGradientBoilerTempLoss set to $value" Log3 $name,3,"$name: statBoilerGradientHeatUp set to $value";
}
#LUXTRONIK2_doStatisticBoilerCoolDown $hash, $time, $currTemp, $opState, $target, $threshold
$value = LUXTRONIK2_doStatisticBoilerCoolDown ($hash, $a[22], $hotWaterTemperature, $a[3], $hotWaterTemperatureTarget, $hotWaterTemperatureThreshold);
if ($value ne "") {
readingsBulkUpdate($hash,"statBoilerGradientCoolDown",$value);
Log3 $name,3,"$name: statBoilerGradientCoolDown set to $value";
if ( exists( $hash->{READINGS}{statBoilerGradientCoolDownMin} ) ) {
my @new = split / /, $value;
my @old = split / /, $hash->{READINGS}{statBoilerGradientCoolDownMin};
if ($new[5]>6 && $new[0]<$old[0]) {
readingsBulkUpdate($hash,"statBoilerGradientCoolDownMin",$value);
Log3 $name,3,"$name: statBoilerGradientCoolDownMin set to $value";
}
} else {
readingsBulkUpdate($hash,"statBoilerGradientCoolDownMin",$value);
Log3 $name,3,"$name: statBoilerGradientCoolDownMin set to $value";
}
} }
} }
@ -786,7 +810,7 @@ LUXTRONIK2_UpdateDone($)
readingsBulkUpdate( $hash, "thresholdHeatingLimit", $thresholdHeatingLimit); readingsBulkUpdate( $hash, "thresholdHeatingLimit", $thresholdHeatingLimit);
readingsBulkUpdate( $hash, "thresholdTemperatureSetBack", $thresholdTemperatureSetBack); readingsBulkUpdate( $hash, "thresholdTemperatureSetBack", $thresholdTemperatureSetBack);
readingsBulkUpdate( $hash, "hotWaterTemperature", $hotWaterTemperature); readingsBulkUpdate( $hash, "hotWaterTemperature", $hotWaterTemperature);
readingsBulkUpdate( $hash, "hotWaterTemperatureTarget",LUXTRONIK2_CalcTemp($a[25])); readingsBulkUpdate( $hash, "hotWaterTemperatureTarget",$hotWaterTemperatureTarget);
readingsBulkUpdate( $hash, "flowTemperature", $flowTemperature); readingsBulkUpdate( $hash, "flowTemperature", $flowTemperature);
readingsBulkUpdate( $hash, "returnTemperature", $returnTemperature); readingsBulkUpdate( $hash, "returnTemperature", $returnTemperature);
readingsBulkUpdate( $hash, "returnTemperatureTarget",LUXTRONIK2_CalcTemp($a[17])); readingsBulkUpdate( $hash, "returnTemperatureTarget",LUXTRONIK2_CalcTemp($a[17]));
@ -830,10 +854,9 @@ LUXTRONIK2_UpdateDone($)
if ($a[36]>0) {readingsBulkUpdate($hash,"counterHeatQHeating",$a[36]/10);} if ($a[36]>0) {readingsBulkUpdate($hash,"counterHeatQHeating",$a[36]/10);}
if ($a[37]>0) {readingsBulkUpdate($hash,"counterHeatQHotWater",$a[37]/10);} if ($a[37]>0) {readingsBulkUpdate($hash,"counterHeatQHotWater",$a[37]/10);}
if ($a[36]+$a[37]>0) {readingsBulkUpdate($hash,"counterHeatQTotal",($a[36]+$a[37])/10);} if ($a[36]+$a[37]>0) {readingsBulkUpdate($hash,"counterHeatQTotal",($a[36]+$a[37])/10);}
#WM[kW] = Wäremekapazität * (TVL-TRL) * Durchfluss [ccm/s] #WM[kW] = delta_Temp [K] * Durchfluss [l/h] / ( 3.600 [kJ/kWh] / ( 4,179 [kJ/(kg*K)] (H2O Wärmekapazität bei 30 & 40°C) * 0,994 [kg/l] (H2O Dichte bei 35°C) )
$value = 4.18 * ($flowTemperature-$returnTemperature) * $a[19] / 36000; $value = ($flowTemperature-$returnTemperature) * $a[19] / 866.65;
$value = floor( 10 * $value + 0.5) / 10; readingsBulkUpdate( $hash, "currentThermalOutput", sprintf("%.1f", $value));
readingsBulkUpdate( $hash, "currentThermalOutput", $value);
# HTML for floorplan # HTML for floorplan
if(AttrVal($name, "statusHTML", "none") ne "none") { if(AttrVal($name, "statusHTML", "none") ne "none") {
@ -1074,87 +1097,168 @@ LUXTRONIK2_checkFirmware ($)
} }
} }
# Calculate hourly gradients of boiler based on hotWaterTemperature and counterHeatQHeating # Calculate heat-up gradients of boiler based on hotWaterTemperature and counterHeatQHeating
sub ######################################## sub ########################################
LUXTRONIK2_doStatisticBoiler ($$$$) LUXTRONIK2_doStatisticBoilerHeatUp ($$$$$$)
{ {
my ($hash,$time,$currHQ,$currTemp) = @_; my ($hash, $currOpHours, $currHQ, $currTemp, $opState, $target) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $statModeHW = $hash->{fhem}{statModeHotWater}; my $step = $hash->{fhem}{statBoilerHeatUpStep};
my $minTemp = $hash->{fhem}{statHotWaterTempMin}; my $minTemp = $hash->{fhem}{statBoilerHeatUpMin};
my $maxTemp = $hash->{fhem}{statHotWaterTempMax}; my $maxTemp = $hash->{fhem}{statBoilerHeatUpMax};
my $lastHQ = $hash->{fhem}{statHQHotWater}; my $lastHQ = $hash->{fhem}{statBoilerHeatUpHQ};
my $lastOpHours = $hash->{fhem}{statBoilerHeatUpOpHours};
my $value1 = 0; my $value1 = 0;
my $value2 = 0; my $value2 = 0;
my $value3 = 0; my $value3 = 0;
my $returnStr = "";
# mode 0 = init hot water gradient calculation # step 0 = Initialize - if hot water preparation is off
if ($statModeHW == 0) { # -> Mode 1 if ($step == 0) {
Log3 $name, 4, "$name: Boiler statMode 0: Initialized"; if ($opState != 5) { # wait till hot water preparation stopped
$hash->{fhem}{statModeHotWater} = 1; Log3 $name, 4, "$name: Statistic Boiler Heat-Up step 0->1: Initializing Measurment";
$hash->{fhem}{statStartTimeHotWater} = $time; $step = 1;
$hash->{fhem}{statHQHotWater} = $currHQ; $lastOpHours = $currOpHours;
$hash->{fhem}{statHotWaterTempMax} = $currTemp; $lastHQ = $currHQ;
$hash->{fhem}{statHotWaterTempMin} = $currTemp; $minTemp = $currTemp;
# mode 1 = wait till maximum of temperature is reached
} elsif ($statModeHW == 1) {
# wait until heat quantity does not change anymore
if ($lastHQ != $currHQ) {
Log3 $name, 4, "$name: Boiler statMode 1: Heat Quantity changed ($lastHQ -> $currHQ)";
$hash->{fhem}{statHQHotWater} = $currHQ;
$hash->{fhem}{statHotWaterTempMax} = $currTemp;
# and temperature is not rising anymore
} elsif ($maxTemp < $currTemp) {
Log3 $name, 4, "$name: Boiler statMode 1: Temperature increased ($maxTemp < $currTemp)";
$hash->{fhem}{statHotWaterTempMax} = $currTemp;
# and temperature is starting to decrease -> Mode 2
} elsif ($maxTemp - 0.2 > $currTemp) {
$value1 = $maxTemp - $minTemp; # delta against last hot water temperature
$value2 = ( $time - $hash->{fhem}{statStartTimeHotWater} ) / 60; # devided by delta time (minutes)
$value3 = floor(100 * $value1 / $value2 + 0.5) / 100; # rounded to 1/100th
$value2 = floor($value2 + 0.5); # rounded
Log3 $name, 4, "$name: Boiler statMode 1: Measurement finished, start new measurement (maximum = $maxTemp )";
$hash->{fhem}{statModeHotWater} = 2;
$hash->{fhem}{statStartTimeHotWater} = $time;
$hash->{fhem}{statHotWaterTempMin} = $currTemp;
return "DT/min: $value3 DT: $value1 Dmin: $value2";
} else {
Log3 $name, 4, "$name: Boiler statMode 1: Wait till temperature decreases (".($maxTemp-0.2)." <= $currTemp <= ".$maxTemp.")";
} }
# mode 2 = wait till heat quantity changes or minimum of temperature reached # step 1 = wait till hot water preparation starts -> monitor Tmin, take previous HQ and previous operating hours
} elsif ($statModeHW == 2) { } elsif ($step == 1) {
# wait until heat quantity changes or temperature is raising again if ($currTemp < $minTemp) { # monitor minimum temperature
if ($hash->{fhem}{statHQHotWater} != $currHQ Log3 $name, 4, "$name: Statistic Boiler Heat-Up step 1: Monitor minimum temperature ($minTemp -> $currTemp)";
|| $minTemp + 0.2 < $currTemp) { # wait till change of heat quantity or rising temperature -> Mode 1 $minTemp = $currTemp;
Log3 $name, 4, "$name: Boiler statMode 2: Heat quantiy changed or temperature raised ($lastHQ != $currHQ or $minTemp +0.2 < $currTemp)"; }
$value1 = $minTemp - $maxTemp; # delta against last hot water temperature if ($opState != 5) { # wait -> update operating hours and HQ to be used as start value in calculations
$value2 = ( $time - $hash->{fhem}{statStartTimeHotWater} ) / 3600; # devided by delta time (hours) $lastOpHours = $currOpHours;
$value3 = floor(100 * $value1 / $value2 + 0.5) / 100; # rounded to 1/100th $lastHQ = $currHQ;
} else { # go to step 2 - if hot water preparation running
Log3 $name, 4, "$name: Statistic Boiler Heat-Up step 1->2: Hot water preparation started ".($currOpHours-$lastOpHours)." s ago";
$step = 2;
$maxTemp = $currTemp;
}
# step 2 = wait till hot water preparation done and target reached
} elsif ($step == 2) {
if ($currTemp < $minTemp) { # monitor minimal temperature
Log3 $name, 4, "$name: Statistic Boiler Heat-Up step 2: Boiler temperature still decreasing ($minTemp -> $currTemp)";
$minTemp = $currTemp;
}
if ($currTemp > $maxTemp) { # monitor maximal temperature
Log3 $name, 4, "$name: Statistic Boiler Heat-Up step 2: Boiler temperature increasing ($maxTemp -> $currTemp)";
$maxTemp = $currTemp;
}
if ($opState != 5) { # wait till hot water preparation stopped
if ($currTemp >= $target) {
Log3 $name, 4, "$name: Statistic Boiler Heat-Up step 2->3: Hot water preparation stopped";
$step = 3;
} else {
Log3 $name, 4, "$name: Statistic Boiler Heat-Up step 2->1: Measurement cancelled (hot water preparation stopped but target not reached, $currTemp < $target)";
$step = 1;
$lastOpHours = $currOpHours;
$lastHQ = $currHQ;
$minTemp = $currTemp;
}
}
# step 3 = wait with calculation till temperature maximum reached once
} elsif ($step == 3) {
# cancel measurement - if hot water preparation has restarted
if ($opState == 5) {
Log3 $name, 4, "$name: Statistic Boiler Heat-Up step 3->0: Measurement cancelled (hot water preparation restarted before maximum reached)";
$step = 0;
# monitor maximal temperature
} elsif ($currTemp > $maxTemp) {
Log3 $name, 4, "$name: Statistic Boiler Heat-Up step 3: Temperature still increasing ($maxTemp -> $currTemp)";
$maxTemp = $currTemp;
# else calculate temperature gradient
} else {
Log3 $name, 4, "$name: Statistic Boiler Heat-Up step 3->1: Boiler heat-up measurement finished";
$value1 = ( int(10 * $maxTemp) - int(10 * $minTemp) ) / 10; # delta hot water temperature
$value2 = ( $currOpHours - $lastOpHours ) / 60; # delta time (minutes)
# $value3 = floor(100 * $value1 / $value2 + 0.5) / 100; # Temperature gradient over time rounded to 1/100th
# $value2 = floor(100 * $value2 + 0.5) / 100; # rounded to 1/100th
$returnStr = "DT/min: ".sprintf("%.2f", $value1/$value2)." DT: ".sprintf("%.2f", $value1)." Dmin: ".sprintf("%.0f", $value2);
$value2 = $currHQ - $lastHQ; # delta heat quantity
# $value2 = floor(10*($currHQ - $lastHQ)+0.5)/10; # delta heat quantity
# $value3 = floor(100 * $value2 / $value1 + 0.5) / 100; # heat gradient over temperature rounded to 1/100th
$returnStr .= " DQ/T: ".sprintf("%.2f",$value2/$value1)." DQ: ".sprintf("%.1f",$value2);
#Volumen [l] = Wärmemenge [kWh] / (delta T) [K] * ( 3.600 [kJ/kWh] / ( 4,179 [kJ/(kg*K)] (H2O Wärmekapazität bei 40°C) * 0,992 [kg/l] (H2O Dichte bei 40°C) ) [K/(kWh*l)] )
$value3 = 868.4 * $value2 / $value1 ; # heated water volume in liter
$returnStr .= " DV: ".sprintf("%.0f",$value3);
$step = 1;
$lastOpHours = $currOpHours;
$lastHQ = $currHQ;
$minTemp = $currTemp;
}
}
$hash->{fhem}{statBoilerHeatUpStep} = $step;
$hash->{fhem}{statBoilerHeatUpMin} = $minTemp;
$hash->{fhem}{statBoilerHeatUpMax} = $maxTemp;
$hash->{fhem}{statBoilerHeatUpHQ} = $lastHQ;
$hash->{fhem}{statBoilerHeatUpOpHours} = $lastOpHours;
return $returnStr;
}
# Calculate heat loss gradients of boiler based on hotWaterTemperature and counterHeatQHeating
sub ########################################
LUXTRONIK2_doStatisticBoilerCoolDown ($$$$$$)
{
my ($hash, $time, $currTemp, $opState, $target, $threshold) = @_;
my $name = $hash->{NAME};
my $step = $hash->{fhem}{statBoilerCoolDownStep};
my $maxTemp = $hash->{fhem}{statBoilerCoolDownMax};
my $startTime = $hash->{fhem}{statBoilerCoolDownStartTime};
my $value1 = 0;
my $value2 = 0;
my $value3 = 0;
my $returnStr = "";
# step 0 = Initialize - if hot water preparation is off and target reached,
if ($step == 0) {
if ($opState == 5 || $currTemp < $target) { # -> stay step 0
# Log3 $name, 4, "$name: Statistic Boiler Cool-Down step 0: Wait till hot water preparation stops and target is reached ($currTemp < $target)";
} else {
Log3 $name, 4, "$name: Statistic Boiler Cool-Down step 0->1: Initializing, target reached ($currTemp >= $target)";
$step = 1;
$startTime = $time;
$maxTemp = $currTemp;
}
# step 1 = wait till threshold is reached -> do calculation, monitor maximal temperature
} elsif ($step == 1) {
if ($currTemp > $maxTemp) { # monitor maximal temperature
Log3 $name, 4, "$name: Statistic Boiler Cool-Down step 1: Temperature still increasing ($currTemp > $maxTemp)";
$maxTemp = $currTemp;
$startTime = $time;
}
if ($opState == 5) {
Log3 $name, 4, "$name: Statistic Boiler Cool-Down step 1: Measurement cancelled (restart of hot water preparation)";
$step = 0;
} elsif ($currTemp <= $threshold) {
Log3 $name, 4, "$name: Statistic Boiler Cool-Down step 2->1: Measurement finished, threshold reached ($currTemp <= $threshold)";
$value1 = ( int(10 * $currTemp) - int(10 * $maxTemp) ) / 10; # delta hot water temperature
$value2 = ( $time - $startTime ) / 3600; # delta time (hours)
$value3 = floor(100 * $value1 / $value2 + 0.5) / 100; # Temperature gradient over time rounded to 1/100th
$value2 = floor(100 * $value2 + 0.5) / 100; # rounded to 1/100th $value2 = floor(100 * $value2 + 0.5) / 100; # rounded to 1/100th
Log3 $name, 4, "$name: Boiler statMode 2: Measurement finished, start new measurment (minimum = $minTemp)"; $returnStr = "DT/h: $value3 DT: $value1 Dh: $value2";
$hash->{fhem}{statModeHotWater} = 1; $step = 0;
$hash->{fhem}{statStartTimeHotWater} = $time;
$hash->{fhem}{statHotWaterTempMax} = $currTemp;
$hash->{fhem}{statHQHotWater} = $currHQ;
return "DT/h: $value3 DT: $value1 Dh: $value2";
} elsif ($minTemp > $currTemp) {
Log3 $name, 4, "$name: Boiler statMode 2: Temperature decreased ($minTemp > $currTemp)";
$hash->{fhem}{statHotWaterTempMin} = $currTemp;
} else {
Log3 $name, 4, "$name: Boiler statMode 2: Monitoring temperature change ($minTemp <= $currTemp <= ".($minTemp+0.2).")";
} }
} }
return ""; $hash->{fhem}{statBoilerCoolDownStep} = $step;
$hash->{fhem}{statBoilerCoolDownMax} = $maxTemp;
$hash->{fhem}{statBoilerCoolDownStartTime} = $startTime;
return $returnStr;
} }
@ -1166,7 +1270,7 @@ LUXTRONIK2_doStatisticBoiler ($$$$)
<a name="LUXTRONIK2"></a> <a name="LUXTRONIK2"></a>
<h3>LUXTRONIK2</h3> <h3>LUXTRONIK2</h3>
<ul> <ul>
Luxtronik 2.0 is a heating controller used in Alpha Innotec and Siemens Novelan (WPR NET) heat pumps. Luxtronik 2.0 is a heating controller used in Alpha Innotec and Siemens Novelan (WPR NET) heat pumps.<br>
It has a built-in ethernet port, so it can be directly integrated into a local area network (LAN). It has a built-in ethernet port, so it can be directly integrated into a local area network (LAN).
<br> <br>
<i>The modul is reported to work with firmware: V1.54C, V1.60, V1.69.</i> <i>The modul is reported to work with firmware: V1.54C, V1.60, V1.69.</i>
@ -1187,12 +1291,16 @@ LUXTRONIK2_doStatisticBoiler ($$$$)
<a name="LUXTRONIK2set"></a> <a name="LUXTRONIK2set"></a>
<b>Set</b><br> <b>Set</b><br>
<ul>A firmware check assures before each set operation that a heat pump with untested firmware is not damaged accidently. <ul>A firmware check assures before each set operation that a heat pump with untested firmware is not damaged accidently.
<li>opModeHotWater &lt;Mode&gt;- Operating Mode of domestic hot water boiler (Auto | Party | Off)</li> <li><code>opModeHotWater &lt;Mode&gt;</code><br>
<li>hotWaterTemperatureTarget &lt;temperature&gt; - Target temperature of domestic hot water boiler in &deg;C</li> Operating Mode of domestic hot water boiler (Auto | Party | Off)</li>
<li>INTERVAL &lt;polling interval&gt; - Polling interval in seconds</li> <li><code>hotWaterTemperatureTarget &lt;temperature&gt;</code><br>
<li>statusRequest - Update device information</li> Target temperature of domestic hot water boiler in &deg;C</li>
<li>synchClockHeatPump - Synchronizes controller clock with FHEM time.<br> <li><code>INTERVAL &lt;polling interval&gt;</code><br>
<b>!! This change is lost in case of controller power off!!</b></li> Polling interval in seconds</li>
<li><code>statusRequest</code><br>
Update device information</li>
<li><code>synchClockHeatPump</code><br>
Synchronizes controller clock with FHEM time. <b>!! This change is lost in case of controller power off!!</b></li>
</ul> </ul>
<br> <br>
<a name="LUXTRONIK2get"></a> <a name="LUXTRONIK2get"></a>
@ -1205,17 +1313,17 @@ LUXTRONIK2_doStatisticBoiler ($$$$)
<a name="LUXTRONIK2attr"></a> <a name="LUXTRONIK2attr"></a>
<b>Attributes</b> <b>Attributes</b>
<ul> <ul>
<li>statusHTML<br> <li><code>statusHTML</code><br>
If set, a HTML-formatted reading named "floorplanHTML" is created. It can be used with the <a href="#FLOORPLAN">FLOORPLAN</a> module.<br> If set, a HTML-formatted reading named "floorplanHTML" is created. It can be used with the <a href="#FLOORPLAN">FLOORPLAN</a> module.<br>
Currently, if the value of this attribute is not NULL, the corresponding reading consists of the current status of the heat pump and the temperature of the water.</li> Currently, if the value of this attribute is not NULL, the corresponding reading consists of the current status of the heat pump and the temperature of the water.</li>
<li>doStatistics &lt; 0 | 1 &gt;<br> <li><code>doStatistics &lt; 0 | 1 &gt;</code><br>
Still Beta - Calculates statistic values: <i>statGradientBoilerTempLoss</i> Calculates statistic values: <i>statBoilerGradientHeatUp, statBoilerGradientCoolDown, statBoilerGradientCoolDownMin (boiler heat loss)</i></li>
<li>allowSetParameter &lt; 0 | 1 &gt;<br> <li><code>allowSetParameter &lt; 0 | 1 &gt;</code><br>
The <a href="#LUXTRONIK2set">parameters</a> of the heat pump controller can only be changed if this attribut is set to 1.</li> The <a href="#LUXTRONIK2set">parameters</a> of the heat pump controller can only be changed if this attribut is set to 1.</li>
<li>autoSynchClock &lt;delay&gt;<br> <li><code>autoSynchClock &lt;delay&gt;</code><br>
Corrects the clock of the heatpump automatically if a certain <i>delay</i> (10 s - 600 s) against the FHEM time is exeeded. Does a firmware check before.<br> Corrects the clock of the heatpump automatically if a certain <i>delay</i> (10 s - 600 s) against the FHEM time is exeeded. Does a firmware check before.<br>
<i>(A 'delayDeviceTimeCalc' &lt;= 2 s can be caused by the internal calculation interval of the heat pump controller.)</i></li> <i>(A 'delayDeviceTimeCalc' &lt;= 2 s can be caused by the internal calculation interval of the heat pump controller.)</i></li>
<li>ignoreFirmwareCheck &lt; 0 | 1 &gt;<br> <li><code>ignoreFirmwareCheck &lt; 0 | 1 &gt;</code><br>
A firmware check assures before each set operation that a heatpump controller with untested firmware is not damaged accidently.<br> A firmware check assures before each set operation that a heatpump controller with untested firmware is not damaged accidently.<br>
If this attribute is set to 1, the firmware check is ignored and new firmware can be tested for compatibility.</li> If this attribute is set to 1, the firmware check is ignored and new firmware can be tested for compatibility.</li>
<li><a href="#readingFnAttributes">readingFnAttributes</a></li> <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
@ -1276,7 +1384,7 @@ LUXTRONIK2_doStatisticBoiler ($$$$)
wenn gesetzt, dann wird ein HTML-formatierter Wert "floorplanHTML" erzeugt, welcher vom Modul <a href="#FLOORPLAN">FLOORPLAN</a> genutzt werden kann.<br> wenn gesetzt, dann wird ein HTML-formatierter Wert "floorplanHTML" erzeugt, welcher vom Modul <a href="#FLOORPLAN">FLOORPLAN</a> genutzt werden kann.<br>
Momentan wird nur gepr&uuml;ft, ob der Wert dieses Attributes ungleich NULL ist, der entsprechende Ger&auml;tewerte besteht aus dem aktuellen W&auml;rmepumpenstatus und der Heizwassertemperatur.</li> Momentan wird nur gepr&uuml;ft, ob der Wert dieses Attributes ungleich NULL ist, der entsprechende Ger&auml;tewerte besteht aus dem aktuellen W&auml;rmepumpenstatus und der Heizwassertemperatur.</li>
<li>doStatistics &lt; 0 | 1 &gt;<br> <li>doStatistics &lt; 0 | 1 &gt;<br>
Noch im Versuchsstadium - Berechnet statistische Werte: <i>statGradientBoilerTempLoss</i> Berechnet statistische Werte: <i>statBoilerGradientHeatUp, statBoilerGradientCoolDown, statBoilerGradientCoolDownMin (Wärmeverlust des Boilers)</i></li>
<li>allowSetParameter &lt; 0 | 1 &gt;<br> <li>allowSetParameter &lt; 0 | 1 &gt;<br>
Die internen <a href="#LUXTRONIK2set">Parameter</a> der W&auml;rmepumpensteuerung k&ouml;nnen nur ge&auml;ndert werden, wenn dieses Attribut auf 1 gesetzt ist.</li> Die internen <a href="#LUXTRONIK2set">Parameter</a> der W&auml;rmepumpensteuerung k&ouml;nnen nur ge&auml;ndert werden, wenn dieses Attribut auf 1 gesetzt ist.</li>
<li>autoSynchClock &lt;Zeitunterschied&gt;<br> <li>autoSynchClock &lt;Zeitunterschied&gt;<br>