2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-02-01 01:09:47 +00:00

LUXTRONIK: Neue Features zur Heizkurveneinstellung

git-svn-id: https://svn.fhem.de/fhem/trunk@13029 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
tupol 2017-01-09 20:32:15 +00:00
parent 98a0e689ac
commit 4d6f492fa6

View File

@ -74,6 +74,7 @@ LUXTRONIK2_Initialize($)
$hash->{DefFn} = "LUXTRONIK2_Define";
$hash->{UndefFn} = "LUXTRONIK2_Undefine";
$hash->{GetFn} = "LUXTRONIK2_Get";
$hash->{SetFn} = "LUXTRONIK2_Set";
$hash->{AttrFn} = "LUXTRONIK2_Attr";
$hash->{AttrList} = "disable:0,1 ".
@ -268,7 +269,12 @@ LUXTRONIK2_Set($$@)
($cmd eq 'hotWaterTemperatureTarget'
|| $cmd eq 'opModeHotWater'
|| $cmd eq 'returnTemperatureHyst'
|| $cmd eq 'returnTemperatureSetBack')) {
|| $cmd eq 'returnTemperatureSetBack'
|| $cmd eq 'heatingCurveEndPoint'
|| $cmd eq 'heatingCurveOffset'
|| $cmd eq 'heatSourceDefrostAirEnd'
|| $cmd eq 'heatSourceDefrostAirThreshold')) {
Log3 $name, 3, "set $name $cmd $val";
$hash->{LOCAL} = 1;
$resultStr = LUXTRONIK2_SetParameter ($hash, $cmd, $val);
@ -290,6 +296,8 @@ LUXTRONIK2_Set($$@)
my $list = "statusRequest:noArg"
." activeTariff:0,1,2,3,4,5,6,7,8,9"
." boostHotWater"
." heatingCurveEndPoint"
." heatingCurveOffset"
." hotWaterCircPumpDeaerate:on,off"
." hotWaterTemperatureTarget "
." resetStatistics:all,statBoilerGradientCoolDownMin,statAmbientTemp...,statElectricity...,statHours...,statHeatQ..."
@ -302,6 +310,43 @@ LUXTRONIK2_Set($$@)
return "Unknown argument $cmd, choose one of $list";
}
sub ########################################
LUXTRONIK2_Get($$@)
{
my ($hash, $name, $cmd, @val ) = @_;
my $resultStr = "";
if($cmd eq 'heatingCurveParameter') {
# Log3 $name, 3, "get $name $cmd";
if (int @val !=4 ) {
my $msg = "Wrong number of parameter (".int @val.")in get $name $cmd";
Log3 $name, 3, $msg;
return $msg;
}
else {
return LUXTRONIK2_calcHeatingCurveParameter ( $hash, $val[0], $val[1], $val[2], $val[3]);
}
}
elsif($cmd eq 'heatingCurveReturnTemperature') {
# Log3 $name, 3, "get $name $cmd";
if (int @val !=1) {
my $msg = "Wrong number of parameter (".int @val.")in get $name $cmd";
Log3 $name, 3, $msg;
return $msg;
}
else {
my $heatingCurveEndPoint = $hash->{READINGS}{heatingCurveEndPoint}{VAL};
my $heatingCurveOffset = $hash->{READINGS}{heatingCurveOffset}{VAL};
return LUXTRONIK2_getHeatingCurveReturnTemperature ( $hash, $val[0], $heatingCurveEndPoint, $heatingCurveOffset);
}
}
my $list = "heatingCurveParameter "
. "heatingCurveReturnTemperature ";
return "Unknown argument $cmd, choose one of $list";
}
sub ########################################
LUXTRONIK2_GetUpdate($)
@ -658,8 +703,15 @@ LUXTRONIK2_DoUpdate($)
$return_str .= "|". ($heatpump_visibility[47]==1 ? $heatpump_values[37] : "no");
# 68 - returnTempHyst
$return_str .= "|". ($heatpump_visibility[93]==1 ? $heatpump_parameters[88] : "no");
# 69 - Heating curve end point
$return_str .= "|". ($heatpump_visibility[207]==1 ? $heatpump_parameters[11] : "no");
# 70 - Heating curve parallel offset
$return_str .= "|". ($heatpump_visibility[207]==1 ? $heatpump_parameters[12] : "no");
# 71 - heatSourcedefrostAirThreshold
$return_str .= "|". ($heatpump_visibility[97]==1 ? $heatpump_parameters[44] : "no");
# 72 - heatSourcedefrostAirEnd
$return_str .= "|". ($heatpump_visibility[105]==1 ? $heatpump_parameters[98] : "no");
return $return_str;
}
@ -886,8 +938,9 @@ LUXTRONIK2_UpdateDone($)
$opStateHeatPump3Txt = "Stufe ".$a[4]." ".LUXTRONIK2_CalcTemp($a[5])." C ";
}
elsif ($opStateHeatPump3==7) {
if ($compressor1==1) {$opStateHeatPump3Txt = "Abtauen (Kreisumkehr)";}
else {$opStateHeatPump3Txt = "Luftabtauen";}
if ( $defrostValve==1 ) {$opStateHeatPump3Txt = "Abtauen (Kreisumkehr)";}
elsif ( $compressor1==0 && $heatSourceMotor==1 ) {$opStateHeatPump3Txt = "Luftabtauen";}
else {$opStateHeatPump3Txt = "Abtauen";}
}
$opStateHeatPump3Txt = "unbekannt (".$opStateHeatPump3.")" unless $opStateHeatPump3Txt;
readingsBulkUpdate($hash,"opStateHeatPump3",$opStateHeatPump3Txt);
@ -955,6 +1008,8 @@ LUXTRONIK2_UpdateDone($)
readingsBulkUpdate( $hash, "heatingLimit",$a[11]?"on":"off");
readingsBulkUpdate( $hash, "thresholdHeatingLimit", $thresholdHeatingLimit);
readingsBulkUpdate( $hash, "thresholdTemperatureSetBack", $thresholdTemperatureSetBack);
if ($a[69] !~ /no/) {readingsBulkUpdate( $hash, "heatingCurveEndPoint",LUXTRONIK2_CalcTemp($a[69]));}
if ($a[70] !~ /no/) {readingsBulkUpdate( $hash, "heatingCurveOffset",LUXTRONIK2_CalcTemp($a[70]));}
readingsBulkUpdate( $hash, "hotWaterTemperature", $hotWaterTemperature);
readingsBulkUpdate( $hash, "hotWaterTemperatureTarget",$hotWaterTemperatureTarget);
readingsBulkUpdate( $hash, "flowTemperature", $flowTemperature);
@ -967,7 +1022,10 @@ LUXTRONIK2_UpdateDone($)
readingsBulkUpdate( $hash, "heatSourceIN",$heatSourceIN);
readingsBulkUpdate( $hash, "heatSourceOUT",LUXTRONIK2_CalcTemp($a[24]));
readingsBulkUpdate( $hash, "heatSourceMotor",$heatSourceMotor?"on":"off");
if ($a[71] !~ /no/) {readingsBulkUpdate( $hash, "heatSourceDefrostAirThreshold",LUXTRONIK2_CalcTemp($a[71]));}
if ($a[72] !~ /no/) {readingsBulkUpdate( $hash, "heatSourceDefrostAirEnd",LUXTRONIK2_CalcTemp($a[72]));}
if ($a[66] !~ /no/) {readingsBulkUpdate( $hash, "heatSourceDefrostTimer",$a[66]);}
readingsBulkUpdate( $hash, "compressor1",$compressor1?"on":"off");
readingsBulkUpdate( $hash, "hotGasTemperature",LUXTRONIK2_CalcTemp($a[26]));
if ($a[55] !~ /no/) {readingsBulkUpdate( $hash, "mixer1FlowTemperature",LUXTRONIK2_CalcTemp($a[55]));}
if ($a[56] !~ /no/) {readingsBulkUpdate( $hash, "mixer1TargetTemperature",LUXTRONIK2_CalcTemp($a[56]));}
@ -1055,22 +1113,24 @@ LUXTRONIK2_UpdateDone($)
# $defrostValve = $a[67]; #AVout
# $hotWaterBoilerValve = $a[9]; #BUP
# $heatingSystemCircPump = $a[27]; #HUP
# 0=Heizen, 1=keine Anforderung, 5=Brauchwasser, 7=Abtauen, 16=Durchflussüberwachung
# 0=Heizen, 1=keine Anforderung, 3=Schaltspielzeit, 5=Brauchwasser, 7=Abtauen, 16=Durchflussüberwachung
my $lastHeatingCycle = ReadingsVal($name, "heatingCycle", "");
if ( $opStateHeatPump3 == 0 ) {
readingsBulkUpdate($hash, "heatingCycle", "running");
}
elsif ( $opStateHeatPump3 > 1 && ReadingsVal($name, "heatingCycle", "") eq "running") {
elsif ( $opStateHeatPump3 > 1 && $lastHeatingCycle eq "running") {
readingsBulkUpdate($hash, "heatingCycle", "paused");
}
elsif ( $opStateHeatPump3 == 1 && ReadingsVal($name, "heatingCycle", "") eq "running") {
elsif ( $opStateHeatPump3 == 1 && $lastHeatingCycle eq "running") {
readingsBulkUpdate($hash, "heatingCycle", "finished");
}
elsif ( $opStateHeatPump3 == 1 && ReadingsVal($name, "heatingCycle", "") eq "paused") {
if ( $returnTemperature-$returnTemperatureTarget >= $returnTempHyst ) { readingsBulkUpdate($hash, "heatingCycle", "finished"); }
else { readingsBulkUpdate($hash, "heatingCycle", "discontinued"); }
elsif ( $opStateHeatPump3 =~ /1|3/ && $lastHeatingCycle ne "finished" && $returnTemperature-$returnTemperatureTarget >= $returnTempHyst ) {
readingsBulkUpdate($hash, "heatingCycle", "finished");
}
elsif ( $opStateHeatPump3 == 1 && $lastHeatingCycle eq "paused") {
readingsBulkUpdate($hash, "heatingCycle", "discontinued");
}
readingsEndUpdate($hash,1);
$hash->{helper}{fetched_calc_values} = $a[44];
@ -1147,8 +1207,8 @@ sub LUXTRONIK2_FormatDuration($)
return $returnstr;
}
sub ########################################
LUXTRONIK2_SetParameter($$$)
########################################
sub LUXTRONIK2_SetParameter ($$$)
{
my ($hash, $parameterName, $realValue) = @_;
my $setParameter = 0;
@ -1172,11 +1232,55 @@ LUXTRONIK2_SetParameter($$$)
#limit temperature range
$realValue = 30 if( $realValue < 30 );
$realValue = 65 if( $realValue > 65 );
#Allow only integer temperature or with decimal .5
$setValue = int($realValue * 2) * 5;
#Allow only integer temperatures with decimal .1
$setValue = int($realValue * 10);
$realValue = $setValue / 10;
}
elsif ($parameterName eq "heatingCurveEndPoint") {
#parameter number
$setParameter = 11;
#limit temperature range
$realValue = 20 if( $realValue < 20.0 );
$realValue = 70 if( $realValue > 70.0 );
#Allow only integer temperatures
$setValue = int($realValue * 10);
$realValue = $setValue / 10;
}
elsif ($parameterName eq "heatingCurveOffset") {
#parameter number
$setParameter = 12;
#limit temperature range
$realValue = 5 if( $realValue < 5.0 );
$realValue = 35 if( $realValue > 35.0 );
#Allow only integer temperatures
$setValue = int($realValue * 10);
$realValue = $setValue / 10;
}
elsif ($parameterName eq "heatSourceDefrostAirEnd") {
#parameter number
$setParameter = 98;
#limit temperature range
$realValue = 1 if( $realValue < 1.0 );
$realValue = 24 if( $realValue > 24.0 );
#Allow only integer temperatures
$setValue = int($realValue * 10);
$realValue = $setValue / 10;
}
elsif ($parameterName eq "heatSourceDefrostAirThreshold") {
#parameter number
$setParameter = 44;
#limit temperature range
$realValue = 1.5 if( $realValue < 1.5 );
$realValue = 20 if( $realValue > 20.0 );
#Allow only integer temperatures
$setValue = int($realValue * 10);
$realValue = $setValue / 10;
}
elsif ($parameterName eq "opModeHotWater") {
if (! exists($opMode{$realValue})) {
return "$name Error: Wrong parameter given for opModeHotWater, use Automatik,Party,Off"
@ -1270,8 +1374,8 @@ LUXTRONIK2_SetParameter($$$)
}
sub ########################################
LUXTRONIK2_synchronizeClock (@)
########################################
sub LUXTRONIK2_synchronizeClock (@)
{
my ($hash,$maxDelta) = @_;
my $host = $hash->{HOST};
@ -1354,6 +1458,74 @@ sub LUXTRONIK2_boostHotWater_Start ($$)
}
########################################
sub LUXTRONIK2_calcHeatingCurveParameter ($$$$$)
{ my ($hash, $aussen_1, $rtSoll_1, $aussen_2, $rtSoll_2) = @_;
if ($aussen_1 > $aussen_2) {
my $temp= $aussen_1;
$aussen_1=$aussen_2;
$aussen_2=$temp;
$temp= $rtSoll_1;
$rtSoll_1=$rtSoll_2;
$rtSoll_2=$temp;
}
my $endPoint_Ist = $hash->{READINGS}{heatingCurveEndPoint}{VAL};
my $endPoint = $endPoint_Ist;
my $offset_Ist = $hash->{READINGS}{heatingCurveOffset}{VAL};
my $offset = $offset_Ist;
my $rtIst_1 = LUXTRONIK2_getHeatingCurveReturnTemperature ( $hash, $aussen_1, $endPoint, $offset);
my $rtIst_2 = LUXTRONIK2_getHeatingCurveReturnTemperature ( $hash, $aussen_2, $endPoint, $offset);
my $delta_1; my $delta_2;
my $msg; my $i;
#get Heizung heatingCurveParameter 0 27 10 25
for ( $i=0; $i<1000; $i++ ) {
$delta_1 = LUXTRONIK2_getHeatingCurveReturnTemperature ( $hash, $aussen_1, $endPoint, $offset) - $rtSoll_1;
$delta_1 = int(10.0 * $delta_1 + 0.5) / 10.0;
$delta_2 = LUXTRONIK2_getHeatingCurveReturnTemperature ( $hash, $aussen_2, $endPoint, $offset) - $rtSoll_2;
$delta_2 = int(10.0 * $delta_2 + 0.5) / 10.0;
$msg = "Calculate loop $i: hcEndPoint=$endPoint, hcOffset=$offset, delta($aussen_1)=$delta_1, delta($aussen_2)=$delta_2)\n";
LUXTRONIK2_Log $hash, 4, $msg;
last if $delta_1 == 0 && $delta_2 == 0;
if ($delta_2 > 0) {
$offset -= 0.1;
}
elsif ($delta_2 < 0) {
$offset += 0.1;
}
elsif ($delta_1 > 0) {
$endPoint -= 0.1;
}
elsif ($delta_1 < 0) {
$endPoint += 0.1;
}
$endPoint = int(10.0 * $endPoint + 0.5) / 10.0;
$offset = int(10.0 * $offset + 0.5) / 10.0;
}
LUXTRONIK2_Log $hash, 3, "Heating-Curve-Parameter calculated in $i loops.";
$msg = "New Values: heatingCurveEndPoint=$endPoint heatingCurveOffset=$offset\n";
$msg .= "Old Values: heatingCurveEndPoint=$endPoint_Ist heatingCurveOffset=$offset_Ist\n\n";
$msg .= "New Heating-Curve: returnTemp($aussen_1)=".($delta_1+$rtSoll_1)." and returnTemp($aussen_2)=".($delta_2+$rtSoll_2)."\n";
$msg .= "Old Heating-Curve: returnTemp($aussen_1)=".($rtIst_1)." and returnTemp($aussen_2)=".($rtIst_2)."\n";
$msg .= "calculated in $i loops\n";
return $msg;
}
########################################
sub LUXTRONIK2_getHeatingCurveReturnTemperature ($$$$)
{ my ($hash, $aussen, $endPoint, $offset) = @_;
LUXTRONIK2_Log $hash, 5, "Calculate return-temperature at $aussen with heating curve ($endPoint, $offset)";
my $result = $offset + ($endPoint - 20.0) * ($offset - $aussen) / (20.0 - ($aussen - $offset) / 2);
$result = int(10.0 * $result + 0.5) / 10.0;
return $result;
}
########################################
sub LUXTRONIK2_checkFirmware ($)
{