2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-10 09:16:53 +00:00

THZ: z_Last_fhem_err implemented, aesthetics and DevIo (Forum #110125)

git-svn-id: https://svn.fhem.de/fhem/trunk@21871 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
immi 2020-05-05 18:29:00 +00:00
parent 18f5bc0b22
commit 3f9fb855e0

View File

@ -1,8 +1,8 @@
############################################## ##############################################
# 00_THZ # 00_THZ
# $Id$ # $Id$
# by immi 10/2019 # by immi 05/2020
my $thzversion = "0.182"; # my $thzversion = "0.184";
# this code is based on the hard work of Robert; I just tried to port it # this code is based on the hard work of Robert; I just tried to port it
# http://robert.penz.name/heat-pump-lwz/ # http://robert.penz.name/heat-pump-lwz/
######################################################################################## ########################################################################################
@ -32,6 +32,7 @@ use Time::HiRes qw(gettimeofday);
use feature ":5.10"; use feature ":5.10";
use SetExtensions; use SetExtensions;
use Blocking; use Blocking;
use DevIo;
sub THZ_Read($); sub THZ_Read($);
sub THZ_ReadAnswer($); sub THZ_ReadAnswer($);
@ -424,6 +425,7 @@ my %sets439539common = (
"p25Hyst5" => {cmd2=>"0A05C4", argMin => "0", argMax => "5", type =>"5temp", unit =>" K"}, "p25Hyst5" => {cmd2=>"0A05C4", argMin => "0", argMax => "5", type =>"5temp", unit =>" K"},
"p29HystAsymmetry" => {cmd2=>"0A05C5", argMin => "1", argMax => "5", type =>"1clean", unit =>""}, "p29HystAsymmetry" => {cmd2=>"0A05C5", argMin => "1", argMax => "5", type =>"1clean", unit =>""},
"p30integralComponent" => {cmd2=>"0A0162", argMin => "10", argMax => "999", type =>"1clean", unit =>" Kmin"}, "p30integralComponent" => {cmd2=>"0A0162", argMin => "10", argMax => "999", type =>"1clean", unit =>" Kmin"},
"p31MaxBoosterStgHtg" => {cmd2=>"0A059F", argMin => "0", argMax => "3", type =>"1clean", unit =>""},
"p32HystDHW" => {cmd2=>"0A0140", argMin => "0", argMax => "10", type =>"5temp", unit =>" K"}, "p32HystDHW" => {cmd2=>"0A0140", argMin => "0", argMax => "10", type =>"5temp", unit =>" K"},
"p33BoosterTimeoutDHW" => {cmd2=>"0A0588", argMin => "0", argMax => "200", type =>"1clean", unit =>" min"}, #during DHW heating "p33BoosterTimeoutDHW" => {cmd2=>"0A0588", argMin => "0", argMax => "200", type =>"1clean", unit =>" min"}, #during DHW heating
"p79BoosterTimeoutHC" => {cmd2=>"0A05A0", argMin => "0", argMax => "60", type =>"1clean", unit =>" min"}, #delayed enabling of booster heater "p79BoosterTimeoutHC" => {cmd2=>"0A05A0", argMin => "0", argMax => "60", type =>"1clean", unit =>" min"}, #delayed enabling of booster heater
@ -708,7 +710,7 @@ my %sets206 = (
"progHC2Saturday" => {parent=>"pHeatProg", argMin => "0", argMax => "1", type =>"pclean", unit =>""}, "progHC2Saturday" => {parent=>"pHeatProg", argMin => "0", argMax => "1", type =>"pclean", unit =>""},
"progHC2Sunday" => {parent=>"pHeatProg", argMin => "0", argMax => "1", type =>"pclean", unit =>""}, "progHC2Sunday" => {parent=>"pHeatProg", argMin => "0", argMax => "1", type =>"pclean", unit =>""},
"progFAN1StartTime" => {parent=>"pFanProg", argMin => "00:00", argMax => "23:59", type =>"ptime", unit =>""}, "progFAN1StartTime" => {parent=>"pFanProg", argMin => "00:00", argMax => "23:59", type =>"ptime", unit =>""},
"progFAN1EndTime" => {parent=>"pFanProg", argMin => "00:00", argMax => "23:59", type =>"ütime", unit =>""}, "progFAN1EndTime" => {parent=>"pFanProg", argMin => "00:00", argMax => "23:59", type =>"ptime", unit =>""},
"progFAN1Enable" => {parent=>"pFanProg", argMin => "0", argMax => "1", type =>"pclean", unit =>""}, "progFAN1Enable" => {parent=>"pFanProg", argMin => "0", argMax => "1", type =>"pclean", unit =>""},
"progFAN1Monday" => {parent=>"pFanProg", argMin => "0", argMax => "1", type =>"pclean", unit =>""}, "progFAN1Monday" => {parent=>"pFanProg", argMin => "0", argMax => "1", type =>"pclean", unit =>""},
"progFAN1Tuesday" => {parent=>"pFanProg", argMin => "0", argMax => "1", type =>"pclean", unit =>""}, "progFAN1Tuesday" => {parent=>"pFanProg", argMin => "0", argMax => "1", type =>"pclean", unit =>""},
@ -860,7 +862,6 @@ my $internalHash;
######################################################################################## ########################################################################################
sub THZ_Initialize($) { sub THZ_Initialize($) {
my ($hash) = @_; my ($hash) = @_;
require "$attr{global}{modpath}/FHEM/DevIo.pm";
# Provider # Provider
$hash->{ReadFn} = "THZ_Read"; $hash->{ReadFn} = "THZ_Read";
@ -1021,7 +1022,6 @@ sub THZ_Write($$) {
DevIo_SimpleWrite($hash, $bstring, 1); DevIo_SimpleWrite($hash, $bstring, 1);
} }
##################################### #####################################
# sub THZ_Read($) # sub THZ_Read($)
# called from the global loop, when the select for hash reports data # called from the global loop, when the select for hash reports data
@ -1057,7 +1057,6 @@ Log3 $name, 3, "$name/RAW: $msg - $err - $hash->{helper}{step}";
} }
##################################### #####################################
# #
# THZ_Resethelper() # THZ_Resethelper()
@ -1074,7 +1073,6 @@ sub THZ_Resethelper($) {
} }
sub THZ_Testloopapproach($) { sub THZ_Testloopapproach($) {
my ($hash) = @_; my ($hash) = @_;
my $cmd="sGlobal"; my $cmd="sGlobal";
@ -1090,10 +1088,8 @@ sub THZ_testtimer($) {
my ($hash) = @_; my ($hash) = @_;
my $counter=1; my $counter=1;
my $stringa = ("starttest \n"); my $stringa = ("starttest \n");
foreach my $a (keys %intAt) foreach my $a (keys %intAt) {
{ if ($intAt{$a}{FN} eq "THZ_GetRefresh") {
if ($intAt{$a}{FN} eq "THZ_GetRefresh")
{
$stringa = $stringa . ("timer ". $counter ." ARG". $intAt{$a}{ARG} ."fn " . $intAt{$a}{FN} ."\n") ; $stringa = $stringa . ("timer ". $counter ." ARG". $intAt{$a}{ARG} ."fn " . $intAt{$a}{FN} ."\n") ;
$counter+=1; $counter+=1;
} }
@ -1111,8 +1107,7 @@ sub THZ_testtimer($) {
######################################################################################## ########################################################################################
sub THZ_Ready($) { sub THZ_Ready($) {
my ($hash) = @_; my ($hash) = @_;
if($hash->{STATE} eq "disconnected") if($hash->{STATE} eq "disconnected") { #RemoveInternalTimer(0, "THZ_GetRefresh"); #non necessario in THZ_getrefresh non vengono piu' rinnoovati
{ #RemoveInternalTimer(0, "THZ_GetRefresh"); #non necessario in THZ_getrefresh non vengono piu' rinnoovati
#THZ_testtimer($hash); #THZ_testtimer($hash);
select(undef, undef, undef, 0.010); #equivalent to sleep 10ms select(undef, undef, undef, 0.010); #equivalent to sleep 10ms
#Log3 $hash->{NAME}, 3, "THZ_Ready: readyevent"; #Log3 $hash->{NAME}, 3, "THZ_Ready: readyevent";
@ -1124,13 +1119,8 @@ sub THZ_Ready($) {
my ($BlockingFlags, $InBytes, $OutBytes, $ErrorFlags) = $po->status; my ($BlockingFlags, $InBytes, $OutBytes, $ErrorFlags) = $po->status;
return ($InBytes>0); return ($InBytes>0);
} }
} }
##################################### #####################################
# #
# THZ_Set - provides a method for setting the heatpump # THZ_Set - provides a method for setting the heatpump
@ -1159,31 +1149,10 @@ sub THZ_Set($@){
#if (($value->{argMax} - $value->{argMin})<2 ) {$setList .= ":uzsuToggle," . join (",", ($value->{argMin} .. $value->{argMax})) . " ";} #if (($value->{argMax} - $value->{argMin})<2 ) {$setList .= ":uzsuToggle," . join (",", ($value->{argMin} .. $value->{argMax})) . " ";}
if (($value->{argMax} - $value->{argMin})<5 ) {$setList .= ":uzsuSelectRadio," . join (",", ($value->{argMin} .. $value->{argMax})) . " ";} if (($value->{argMax} - $value->{argMin})<5 ) {$setList .= ":uzsuSelectRadio," . join (",", ($value->{argMin} .. $value->{argMax})) . " ";}
else {$setList .= ":textField ";} else {$setList .= ":textField ";}
#else {$setList .= ":slider,$value->{argMin},1,$value->{argMax} ";}
#else {$setList .= ":knob,min:$value->{argMin},max:$value->{argMax},step:1 " ;}
} }
elsif ($value->{type} eq "2opmode"){ elsif ($value->{type} eq "2opmode"){
$setList .= ":" . join (",", (sort {lc $a cmp lc $b} values %OpMode)) . " "; $setList .= ":" . join (",", (sort {lc $a cmp lc $b} values %OpMode)) . " ";
#$setList .= ":uzsuSelectRadio," . join (",", (sort {lc $a cmp lc $b} values %OpMode)) . " ";
#attr Mythz widgetOverride pOpMode:uzsuDropDown,automatic,standby
} }
#elsif ($value->{type} eq "9holy"){
#$setList .= ":time ";
# $setList .= ":textField ";
# }
#elsif ($value->{type} eq "5temp") {
# $setList .= ":slider,$value->{argMin},0.1,$value->{argMax},1 " ;
#$setList .= ":knob,min:$value->{argMin},max:$value->{argMax},step:0.1 " ;
#$setList .= ":knob,min:$value->{argMin},max:$value->{argMax},step:0.1,angleOffset:-125,angleArc:250 "
#attr Mythz widgetOverride p01RoomTempDayHC1:knob,min:22,max:26,step:0.1,angleOffset:-125,angleArc:250
#attr Mythz widgetOverride p01RoomTempDayHC1:slider,$value->{argMin},0.1,$value->{argMax}
#attr Mythz widgetOverride p01RoomTempDayHC1:uzsuDropDown,21,29
#attr Mythz widgetOverride p01RoomTempDayHC1:uzsuSelectRadio,44,234,21
# }
#elsif ($value->{type} eq "6gradient") {
# $setList .= ":slider,$value->{argMin},0.01,$value->{argMax},1 " ;
#$setList .= ":knob,min:$value->{argMin},max:$value->{argMax},step:0.01 " ;
# }
else { else {
#$setList .= ":textField "; #$setList .= ":textField ";
$setList .= " "; $setList .= " ";
@ -1191,15 +1160,10 @@ sub THZ_Set($@){
} }
return "Unknown argument $cmd, choose one of $setList"; return "Unknown argument $cmd, choose one of $setList";
} }
return "\"set $name $cmd\" needs at least one further argument: <value-to-be-modified>" if(!defined($arg)); return "\"set $name $cmd\" needs at least one further argument: <value-to-be-modified>" if(!defined($arg));
my $cmdHex2 = $cmdhash->{cmd2}; my $cmdHex2 = $cmdhash->{cmd2};
my $argMax = $cmdhash->{argMax}; my $argMax = $cmdhash->{argMax};
my $argMin = $cmdhash->{argMin}; my $argMin = $cmdhash->{argMin};
#-- check the parameter range #-- check the parameter range
if ($cmdhash->{type} =~ /ptime/) { if ($cmdhash->{type} =~ /ptime/) {
$arg1=undef; $arg1=undef;
@ -1230,7 +1194,9 @@ sub THZ_Set($@){
$cmdHex2=THZ_encodecommand($cmdHex2, "get"); #read before write the register $cmdHex2=THZ_encodecommand($cmdHex2, "get"); #read before write the register
($err, $msg) = THZ_Get_Comunication($hash, $cmdHex2); ($err, $msg) = THZ_Get_Comunication($hash, $cmdHex2);
if (defined($err)) { if (defined($err)) {
Log3 $hash->{NAME}, 3, "THZ_Set: error reading register: '$err'"; $err="THZ_Set: error reading register: '$err'";
Log3 $hash->{NAME}, 3, $err;
eadingsSingleUpdate($hash, "z_Last_fhem_err", $err, 0);
return ($msg ."\n msg " . $err); return ($msg ."\n msg " . $err);
} }
substr($msg, 0, 2, ""); #remove the checksum from the head of the payload substr($msg, 0, 2, ""); #remove the checksum from the head of the payload
@ -1253,7 +1219,6 @@ sub THZ_Set($@){
my $parsingtype = @$parsingrule[$i]->[3]; my $parsingtype = @$parsingrule[$i]->[3];
my $dec = @$parsingrule[$i]->[4]; my $dec = @$parsingrule[$i]->[4];
Log3 $hash->{NAME}, 5, "write command (parsed element/pos/len/dec/parsingtype): $i / $pos / $len / $dec / $parsingtype"; Log3 $hash->{NAME}, 5, "write command (parsed element/pos/len/dec/parsingtype): $i / $pos / $len / $dec / $parsingtype";
$arg *= $dec if ($dec != 1); $arg *= $dec if ($dec != 1);
$arg = time2quaters($arg) if ($parsingtype eq "quater"); $arg = time2quaters($arg) if ($parsingtype eq "quater");
$arg= join('', (split(':', $arg))) if ($parsingtype eq "hex2time"); # only in firmware 2.x $arg= join('', (split(':', $arg))) if ($parsingtype eq "hex2time"); # only in firmware 2.x
@ -1261,7 +1226,6 @@ sub THZ_Set($@){
$arg=(hex(substr($msg, $pos, 1)) & (15-2**$1)) | (2**$1*$arg) if ($parsingtype =~ /bit(\d)/); $arg=(hex(substr($msg, $pos, 1)) & (15-2**$1)) | (2**$1*$arg) if ($parsingtype =~ /bit(\d)/);
$arg = substr((sprintf(("%0".$len."X"), $arg)), (-1*$len)); #04X converts to hex and fills up 0s; for negative, it must be trunckated. $arg = substr((sprintf(("%0".$len."X"), $arg)), (-1*$len)); #04X converts to hex and fills up 0s; for negative, it must be trunckated.
substr($msg, $pos, $len, $arg); substr($msg, $pos, $len, $arg);
if (defined($arg1)) { #only in case of "8party" or "7prog" if (defined($arg1)) { #only in case of "8party" or "7prog"
$arg1 = time2quaters($arg1); $arg1 = time2quaters($arg1);
$arg1 = substr((sprintf(("%02X"), $arg1)), -2); $arg1 = substr((sprintf(("%02X"), $arg1)), -2);
@ -1273,17 +1237,15 @@ sub THZ_Set($@){
($err, $msg) = THZ_Get_Comunication($hash, $cmdHex2); ($err, $msg) = THZ_Get_Comunication($hash, $cmdHex2);
#$err=undef; #$err=undef;
if (defined($err)) { if (defined($err)) {
Log3 $hash->{NAME}, 3, "THZ_Set: Error msg: $err -- $cmdHex2 -> $msg"; $err="THZ_Set: Error msg: $err -- $cmdHex2 -> $msg";
Log3 $hash->{NAME}, 3, $err;
readingsSingleUpdate($hash, "z_Last_fhem_err", $err, 0);
return($cmdHex2 . "-". $msg ."--" . $err); return($cmdHex2 . "-". $msg ."--" . $err);
} }
else { else {
select(undef, undef, undef, 0.25); select(undef, undef, undef, 0.25);
if (defined($gets{$cmd})) { if (defined($gets{$cmd})) {$msg=THZ_Get($hash, $name, $cmd);}
$msg=THZ_Get($hash, $name, $cmd); else {$msg=$cmd.": OK";}
}
else {
$msg=$cmd.": OK";
}
#because of F8 reset introduced by andre topic=33211 msg695420 #because of F8 reset introduced by andre topic=33211 msg695420
#take care of program of the week #take care of program of the week
if ($a[1] =~ /Mo-So/){ if ($a[1] =~ /Mo-So/){
@ -1315,8 +1277,6 @@ sub THZ_Set($@){
} }
} }
######################################################################################## ########################################################################################
# #
# THZ_GetNB - NonBlocking Get parameter from heatpump # THZ_GetNB - NonBlocking Get parameter from heatpump
@ -1350,7 +1310,6 @@ sub THZ_GetNB($){
} }
} }
######################################################################################## ########################################################################################
# #
# THZ_GetNBDone - Finish Function # THZ_GetNBDone - Finish Function
@ -1369,7 +1328,6 @@ sub THZ_GetNBDone($){
return; return;
} }
######################################################################################## ########################################################################################
# #
# THZ_GetNBAbort - Abort Function # THZ_GetNBAbort - Abort Function
@ -1385,7 +1343,6 @@ sub THZ_GetNBAbort($){
return; return;
} }
######################################################################################## ########################################################################################
# #
# THZ_AvoidCollisions - prevents collisions between parent and child process is used at the beginning of THZ_Get and THZ_Set # THZ_AvoidCollisions - prevents collisions between parent and child process is used at the beginning of THZ_Get and THZ_Set
@ -1413,10 +1370,6 @@ sub THZ_AvoidCollisions($) {
return; return;
} }
##################################### #####################################
# #
# THZ_Get - provides a method for polling the heatpump # THZ_Get - provides a method for polling the heatpump
@ -1428,11 +1381,9 @@ sub THZ_Get($@) {
my ($hash, @a) = @_; my ($hash, @a) = @_;
my $dev = $hash->{DeviceName}; my $dev = $hash->{DeviceName};
my $name = $hash->{NAME}; my $name = $hash->{NAME};
return "\"get $name\" needs one parameter" if(@a != 2); return "\"get $name\" needs one parameter" if(@a != 2);
my $cmd = $a[1]; my $cmd = $a[1];
my ($err, $msg2) =("", " "); my ($err, $msg2) =("", " ");
if ($cmd eq "debug_read_raw_register_slow") { if ($cmd eq "debug_read_raw_register_slow") {
THZ_debugread($hash); THZ_debugread($hash);
return ("all raw registers read and saved"); return ("all raw registers read and saved");
@ -1441,8 +1392,6 @@ sub THZ_Get($@) {
$err=THZ_backup_readings($hash); $err=THZ_backup_readings($hash);
return $err; return $err;
} }
my $cmdhash = $gets{$cmd}; my $cmdhash = $gets{$cmd};
#return "Unknown argument $cmd, choose one of " . join(" ", sort keys %gets) if(!defined($cmdhash)); #return "Unknown argument $cmd, choose one of " . join(" ", sort keys %gets) if(!defined($cmdhash));
if(!defined($cmdhash)) { if(!defined($cmdhash)) {
@ -1451,7 +1400,6 @@ sub THZ_Get($@) {
$getList .= "zBackupParameters:noArg"; $getList .= "zBackupParameters:noArg";
return "Unknown argument $cmd, choose one of $getList"; return "Unknown argument $cmd, choose one of $getList";
} }
Log3 $hash->{NAME}, 5, "THZ_Get: Try to get '$cmd'"; Log3 $hash->{NAME}, 5, "THZ_Get: Try to get '$cmd'";
THZ_AvoidCollisions($hash); THZ_AvoidCollisions($hash);
my $parent = $cmdhash->{parent}; #if I have a father read from it my $parent = $cmdhash->{parent}; #if I have a father read from it
@ -1465,29 +1413,31 @@ sub THZ_Get($@) {
my $i=0; my $i=0;
for (@$parsingrule) { for (@$parsingrule) {
last if ((@$parsingrule[$i]->[0]) =~ m/$cmd/); last if ((@$parsingrule[$i]->[0]) =~ m/$cmd/);
$i++;} $i++;
}
$msg2=(split ' ', $risultato)[$i*2+1]; $msg2=(split ' ', $risultato)[$i*2+1];
Log3 $hash->{NAME}, 5, "THZ_split: $msg2 --- $risultato"; Log3 $hash->{NAME}, 5, "THZ_split: $msg2 --- $risultato";
} }
else { else {
my $cmdHex2 = $cmdhash->{cmd2}; my $cmdHex2 = $cmdhash->{cmd2};
if(defined($cmdHex2) ) { if(defined($cmdHex2) ) {#empty
#empty
($err, $msg2) = THZ_Get_Comunication($hash, THZ_encodecommand($cmdHex2,"get") ); ($err, $msg2) = THZ_Get_Comunication($hash, THZ_encodecommand($cmdHex2,"get") );
if (defined($err)) { if (defined($err)) {
Log3 $hash->{NAME}, 3, "THZ_Get: Error msg2: $err -- $cmdHex2 -> $msg2"; $err="THZ_Get: Error msg2: $err -- $cmdHex2 -> $msg2";
Log3 $hash->{NAME}, 3, $err;
readingsSingleUpdate($hash, "z_Last_fhem_err", $err, 0);
return ($msg2 ."\n msg2 " . $err); return ($msg2 ."\n msg2 " . $err);
} }
$msg2 = THZ_Parse1($hash,$msg2); $msg2 = THZ_Parse1($hash,$msg2);
} }
my $cmdHex3 = $cmdhash->{cmd3}; my $cmdHex3 = $cmdhash->{cmd3};
if(defined($cmdHex3)) { if(defined($cmdHex3)) {
my $msg3= " "; my $msg3= " "; #empty
#empty
($err, $msg3) = THZ_Get_Comunication($hash, THZ_encodecommand($cmdHex3,"get")); ($err, $msg3) = THZ_Get_Comunication($hash, THZ_encodecommand($cmdHex3,"get"));
if (defined($err)) { if (defined($err)) {
Log3 $hash->{NAME}, 3, "THZ_Get: Error msg3: $err -- $cmdHex3 -> $msg3"; $err="THZ_Get: Error msg3: $err -- $cmdHex3 -> $msg3";
Log3 $hash->{NAME}, 3, $err;
readingsSingleUpdate($hash, "z_Last_fhem_err", $err, 0);
return ($msg3 ."\n msg3 " . $err); return ($msg3 ."\n msg3 " . $err);
} }
$msg2 = THZ_Parse1($hash,$msg3) * 1000 + $msg2 ; $msg2 = THZ_Parse1($hash,$msg3) * 1000 + $msg2 ;
@ -1495,16 +1445,11 @@ sub THZ_Get($@) {
} }
my $unit = $cmdhash->{unit}; my $unit = $cmdhash->{unit};
$msg2 = $msg2 . $unit if(defined($unit)) ; $msg2 = $msg2 . $unit if(defined($unit)) ;
my $activatetrigger =1; my $activatetrigger =1;
readingsSingleUpdate($hash, $cmd, $msg2, $activatetrigger); readingsSingleUpdate($hash, $cmd, $msg2, $activatetrigger);
return ($msg2); return ($msg2);
} }
##################################### #####################################
# #
# THZ_Get_Comunication- provides a method for comunication called from THZ_Get or THZ_Set # THZ_Get_Comunication- provides a method for comunication called from THZ_Get or THZ_Set
@ -1517,23 +1462,17 @@ sub THZ_Get_Comunication($$) {
my ($err, $msg) =("", " "); my ($err, $msg) =("", " ");
Log3 $hash->{NAME}, 5, "THZ_Get_Comunication: Check if port is open. State = '($hash->{STATE})'"; Log3 $hash->{NAME}, 5, "THZ_Get_Comunication: Check if port is open. State = '($hash->{STATE})'";
if (!(($hash->{STATE}) eq "opened")) { return("closed connection", "");} if (!(($hash->{STATE}) eq "opened")) { return("closed connection", "");}
select(undef, undef, undef, 0.001); select(undef, undef, undef, 0.001);
THZ_Write($hash, "02"); # step0 --> STX start of text THZ_Write($hash, "02"); # step0 --> STX start of text
($err, $msg) = THZ_ReadAnswer($hash); ($err, $msg) = THZ_ReadAnswer($hash);
#Expectedanswer0 is "10" DLE data link escape #Expectedanswer0 is "10" DLE data link escape
if ($msg ne "10") {$err .= " THZ_Get_Com: error found at step0 $msg"; $err .=" NAK!!" if ($msg eq "15"); select(undef, undef, undef, 0.1); return($err, $msg) ;} if ($msg ne "10") {$err .= " THZ_Get_Com: error found at step0 $msg"; $err .=" NAK!!" if ($msg eq "15"); select(undef, undef, undef, 0.1); return($err, $msg) ;}
else { else {
THZ_Write($hash, $cmdHex); # step1 --> send request SOH start of heading -- Null -- ?? -- DLE data link escape -- EOT End of Text THZ_Write($hash, $cmdHex); # step1 --> send request SOH start of heading -- Null -- ?? -- DLE data link escape -- EOT End of Text
($err, $msg) = THZ_ReadAnswer($hash); ($err, $msg) = THZ_ReadAnswer($hash);
} }
if ((defined($err))) { $err .= " THZ_Get_Com: error found at step1 "; select(undef, undef, undef, 0.1); return($err, $msg) ;} if ((defined($err))) { $err .= " THZ_Get_Com: error found at step1 "; select(undef, undef, undef, 0.1); return($err, $msg) ;}
# Expectedanswer1 is "1002", DLE data link escape -- STX start of text # Expectedanswer1 is "1002", DLE data link escape -- STX start of text
if ($msg eq "10") { ($err, $msg) = THZ_ReadAnswer($hash);} if ($msg eq "10") { ($err, $msg) = THZ_ReadAnswer($hash);}
elsif ($msg eq "15") { $err .= " THZ_Get_Com: error found at step1 NAK!! "; select(undef, undef, undef, 0.1); return($err, $msg) ;} elsif ($msg eq "15") { $err .= " THZ_Get_Com: error found at step1 NAK!! "; select(undef, undef, undef, 0.1); return($err, $msg) ;}
if ($msg eq "1002" || $msg eq "02") { if ($msg eq "1002" || $msg eq "02") {
@ -1541,21 +1480,11 @@ sub THZ_Get_Comunication($$) {
($err, $msg) = THZ_ReadAnswer($hash); # Expectedanswer2 // read from the heatpump ($err, $msg) = THZ_ReadAnswer($hash); # Expectedanswer2 // read from the heatpump
THZ_Write($hash, "10"); THZ_Write($hash, "10");
} }
if ((defined($err))) { $err .= " THZ_Get_Com: error found at step2"; select(undef, undef, undef, 0.1);} if ((defined($err))) { $err .= " THZ_Get_Com: error found at step2"; select(undef, undef, undef, 0.1);}
else {($err, $msg) = THZ_decode($msg);} #clean up and remove footer and header else {($err, $msg) = THZ_decode($msg);} #clean up and remove footer and header
return($err, $msg) ; return($err, $msg) ;
} }
##################################### #####################################
# #
# THZ_ReadAnswer- provides a method for simple read # THZ_ReadAnswer- provides a method for simple read
@ -1640,9 +1569,6 @@ sub quaters2time($) {
return $time; return $time;
} }
#################################### ####################################
# #
# time2quarters - convert from time to quarters in hex; specific to the week programm registers # time2quarters - convert from time to quarters in hex; specific to the week programm registers
@ -1662,8 +1588,6 @@ sub time2quaters($) {
return ($num); return ($num);
} }
#################################### ####################################
# #
# bitmap2string - convert from bitmap to concatenated string # bitmap2string - convert from bitmap to concatenated string
@ -1683,8 +1607,6 @@ sub bitmap2string($$) {
return $res; return $res;
} }
#################################### ####################################
# #
# THZ_replacebytes - replaces bytes in string # THZ_replacebytes - replaces bytes in string
@ -1708,15 +1630,17 @@ sub THZ_replacebytes($$$) {
return ($new_stringa); return ($new_stringa);
} }
####################################
#
## usage THZ_overwritechecksum("0100XX". $cmd."1003"); not needed anymore ## usage THZ_overwritechecksum("0100XX". $cmd."1003"); not needed anymore
#
########################################################################################
sub THZ_overwritechecksum($) { sub THZ_overwritechecksum($) {
my ($stringa) = @_; my ($stringa) = @_;
my $checksumadded=substr($stringa,0,4) . THZ_checksum($stringa) . substr($stringa,6); my $checksumadded=substr($stringa,0,4) . THZ_checksum($stringa) . substr($stringa,6);
return($checksumadded); return($checksumadded);
} }
#################################### ####################################
# #
# THZ_encodecommand - creates a telegram for the heatpump with a given command # THZ_encodecommand - creates a telegram for the heatpump with a given command
@ -1745,10 +1669,6 @@ sub THZ_encodecommand($$) {
return($header. $checksumadded .$footer); return($header. $checksumadded .$footer);
} }
#################################### ####################################
# #
# THZ_decode - decodes a telegram from the heatpump -- no parsing here # THZ_decode - decodes a telegram from the heatpump -- no parsing here
@ -1771,12 +1691,10 @@ sub THZ_decode($) {
$find = "2B18"; # - each sequece 2B 18 must be replaced with single byte 2B $find = "2B18"; # - each sequece 2B 18 must be replaced with single byte 2B
$replace = "2B"; $replace = "2B";
$message_orig=THZ_replacebytes($message_orig, $find, $replace); $message_orig=THZ_replacebytes($message_orig, $find, $replace);
#Check if answer is NAK #Check if answer is NAK
if (length($message_orig) == 2 && $message_orig eq "15") { if (length($message_orig) == 2 && $message_orig eq "15") {
return("decode: NAK received from device",$message_orig); return("decode: NAK received from device",$message_orig);
} }
#check header and if ok 0100, check checksum and return the decoded msg #check header and if ok 0100, check checksum and return the decoded msg
my $header = substr($message_orig,0,4); my $header = substr($message_orig,0,4);
if ($header eq "0100") { if ($header eq "0100") {
@ -1792,11 +1710,9 @@ sub THZ_decode($) {
if ($header eq "0102") { return("decode: CRC error in request", $message_orig);} if ($header eq "0102") { return("decode: CRC error in request", $message_orig);}
if ($header eq "0104") { return("decode: UNKNOWN Register REQUEST", $message_orig);} if ($header eq "0104") { return("decode: UNKNOWN Register REQUEST", $message_orig);}
if ($header eq "0180") { return(undef, $message_orig);} if ($header eq "0180") { return(undef, $message_orig);}
return("decode: new unknown answer " , $message_orig); return("decode: new unknown answer " , $message_orig);
} }
############################### ###############################
#added by jakob do not know if needed #added by jakob do not know if needed
# #
@ -1815,7 +1731,6 @@ local $SIG{__WARN__} = sub {
}; };
####################################### #######################################
#THZ_Parse1($) could be used in order to test an external config file; I do not know if I want it #THZ_Parse1($) could be used in order to test an external config file; I do not know if I want it
#e.g. {THZ_Parse1(undef,"F70B000500E6")} #e.g. {THZ_Parse1(undef,"F70B000500E6")}
@ -1832,19 +1747,18 @@ sub THZ_Parse1($$) {
my $parsingelement; my $parsingelement;
# search for the type in %gets # search for the type in %gets
foreach my $cmdhash (values %gets) { foreach my $cmdhash (values %gets) {
if (defined ($cmdhash->{cmd2}) and ($cmdhash->{cmd2} eq $parsingcmd)) if (defined ($cmdhash->{cmd2}) and ($cmdhash->{cmd2} eq $parsingcmd)) {
{$msgtype = $cmdhash->{type} ; $msgtype = $cmdhash->{type} ;
last last
} }
elsif (defined ($cmdhash->{cmd3})) elsif (defined ($cmdhash->{cmd3})){
{ if ($cmdhash->{cmd3} eq $parsingcmd) if ($cmdhash->{cmd3} eq $parsingcmd) {
{$msgtype = $cmdhash->{type} ; $msgtype = $cmdhash->{type} ;
last last
} }
} }
} }
$parsingrule = $parsinghash{$msgtype} if(defined($msgtype)); $parsingrule = $parsinghash{$msgtype} if(defined($msgtype));
my $ParsedMsg = $message; my $ParsedMsg = $message;
if(defined($parsingrule)) { if(defined($parsingrule)) {
$ParsedMsg = ""; $ParsedMsg = "";
@ -1900,10 +1814,6 @@ sub THZ_Parse1($$) {
return (undef, $ParsedMsg); return (undef, $ParsedMsg);
} }
######################################################################################## ########################################################################################
# only for debug # only for debug
# #
@ -1950,13 +1860,13 @@ sub THZ_debugread($){
select(undef, undef, undef, 0.001); select(undef, undef, undef, 0.001);
($err, $msg) = THZ_ReadAnswer($hash); ($err, $msg) = THZ_ReadAnswer($hash);
THZ_Write($hash, "10"); THZ_Write($hash, "10");
if (defined($err)) {return ($msg ."\n" . $err);} if (defined($err)) {return ($msg ."\n" . $err);}
else { #clean up and remove footer and header else { #clean up and remove footer and header
($err, $msg) = THZ_decode($msg); ($err, $msg) = THZ_decode($msg);
if (defined($err)) { if (defined($err)) {
$msg = THZ_Parse1($hash,$msg); $msg = THZ_Parse1($hash,$msg);
$msg=$cmdHex2 ."-". $msg ."-". $err;} $msg=$cmdHex2 ."-". $msg ."-". $err;
}
my $activatetrigger =1; my $activatetrigger =1;
# readingsSingleUpdate($hash, $cmd, $msg, $activatetrigger); # readingsSingleUpdate($hash, $cmd, $msg, $activatetrigger);
open (MYFILE, '>>data.txt'); open (MYFILE, '>>data.txt');
@ -1969,15 +1879,15 @@ sub THZ_debugread($){
} }
####################################### #######################################
#
#THZ_Attr($) #THZ_Attr($)
#in case of change of attribute starting with interval_ refresh all #in case of change of attribute starting with interval_ refresh all
#
######################################################################################## ########################################################################################
sub THZ_Attr(@) { sub THZ_Attr(@) {
my ($cmd, $name, $attrName, $attrVal) = @_; my ($cmd, $name, $attrName, $attrVal) = @_;
my $hash = $defs{$name}; my $hash = $defs{$name};
$attrVal = "4.39" if (($cmd eq "del") and ($attrName eq "firmware")); $attrVal = "4.39" if (($cmd eq "del") and ($attrName eq "firmware"));
if ( $attrName eq "firmware" ) { if ( $attrName eq "firmware" ) {
if ($attrVal eq "2.06") { if ($attrVal eq "2.06") {
%sets = %sets206; %sets = %sets206;
@ -2005,44 +1915,30 @@ sub THZ_Attr(@) {
THZ_Refresh_all_gets($hash); THZ_Refresh_all_gets($hash);
} }
} }
if( $attrName =~ /^interval_/ ) { if( $attrName =~ /^interval_/ ) {
#DevIo_CloseDev($hash);
#sleep 1;
#DevIo_OpenDev($hash, 1, "THZ_Refresh_all_gets");
THZ_Refresh_all_gets($hash); THZ_Refresh_all_gets($hash);
} }
return undef; return undef;
} }
##################################### #####################################
sub THZ_Undef($$) { sub THZ_Undef($$) {
my ($hash, $arg) = @_; my ($hash, $arg) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
RemoveInternalTimer(0, "THZ_GetRefresh"); RemoveInternalTimer(0, "THZ_GetRefresh");
#THZ_RemoveInternalTimer("THZ_GetRefresh");
foreach my $d (sort keys %defs) { foreach my $d (sort keys %defs) {
if(defined($defs{$d}) && if(defined($defs{$d}) && defined($defs{$d}{IODev}) && $defs{$d}{IODev} == $hash) {
defined($defs{$d}{IODev}) &&
$defs{$d}{IODev} == $hash)
{
my $lev = ($reread_active ? 4 : 2); my $lev = ($reread_active ? 4 : 2);
Log3 $hash->{NAME}, $lev, "deleting port for $d"; Log3 $hash->{NAME}, $lev, "deleting port for $d";
delete $defs{$d}{IODev}; delete $defs{$d}{IODev};
} }
} }
BlockingKill($hash->{helper}{RUNNING_PID}) if(defined($hash->{helper}{RUNNING_PID})); BlockingKill($hash->{helper}{RUNNING_PID}) if(defined($hash->{helper}{RUNNING_PID}));
DevIo_CloseDev($hash); DevIo_CloseDev($hash);
return undef; return undef;
} }
########################################## ##########################################
# nearest rounds to the nearrest value multiple of the first argumen # nearest rounds to the nearrest value multiple of the first argumen
# nearest_ceil(10, 45); --> 50 # nearest_ceil(10, 45); --> 50
@ -2054,24 +1950,16 @@ sub nearest_ceil($$) {
my $targ = abs(shift); my $targ = abs(shift);
my $Math1 = 0.5000000000003; my $Math1 = 0.5000000000003;
my @res = map { $targ * POSIX::floor(($_ + $Math1 * $targ) / $targ) } @_; my @res = map { $targ * POSIX::floor(($_ + $Math1 * $targ) / $targ) } @_;
return wantarray ? @res : $res[0]; return wantarray ? @res : $res[0];
} }
sub nearest_floor($$) { sub nearest_floor($$) {
my $targ = abs(shift); my $targ = abs(shift);
my $Math1 = 0.5000000000003; my $Math1 = 0.5000000000003;
my @res = map { $targ * POSIX::ceil(($_ - $Math1 * $targ) / $targ) } @_; my @res = map { $targ * POSIX::ceil(($_ - $Math1 * $targ) / $targ) } @_;
return wantarray ? @res : $res[0]; return wantarray ? @res : $res[0];
} }
########################################## ##########################################
# THZ_RemoveInternalTimer($) # THZ_RemoveInternalTimer($)
# modified takes as an argument the function to be called, not the argument # modified takes as an argument the function to be called, not the argument
@ -2082,21 +1970,17 @@ sub nearest_floor($$) {
# delete($intAt{$a}) if($intAt{$a}{FN} eq $callingfun); # delete($intAt{$a}) if($intAt{$a}{FN} eq $callingfun);
# } # }
#} #}
################################ ################################
# #
sub function_heatSetTemp($$) { sub function_heatSetTemp($$) {
my ($start, $stop) = @_; my ($start, $stop) = @_;
my ($p13GradientHC1, $p14LowEndHC1, $p15RoomInfluenceHC1); my ($p13GradientHC1, $p14LowEndHC1, $p15RoomInfluenceHC1);
my $pOpMode = " "; my $pOpMode = " ";
my $devname; #normally Mythz but could be defined differently my $devname; #normally Mythz but could be defined differently
foreach (keys %defs) { foreach (keys %defs) {
$devname=$_; $devname=$_;
last if(($defs{$_}{TYPE}) =~ "THZ"); last if(($defs{$_}{TYPE}) =~ "THZ");
} }
if (AttrVal($devname, "firmware" , "4.39") =~ /^2/ ) { if (AttrVal($devname, "firmware" , "4.39") =~ /^2/ ) {
($p13GradientHC1, $p14LowEndHC1, $p15RoomInfluenceHC1) = (split ' ',ReadingsVal($devname,"pHeat1",0))[1,3,5]; ($p13GradientHC1, $p14LowEndHC1, $p15RoomInfluenceHC1) = (split ' ',ReadingsVal($devname,"pHeat1",0))[1,3,5];
} }
@ -2113,12 +1997,10 @@ sub function_heatSetTemp($$) {
$pOpMode ="DEMO: no data"; $pOpMode ="DEMO: no data";
$outside_tempFiltered = 0; $p14LowEndHC1 =0.5; $outside_tempFiltered = 0; $p14LowEndHC1 =0.5;
} }
my $a= 0.7 + ($roomSetTemp * (1 + $p13GradientHC1 * 0.87)) + $p14LowEndHC1 + ($p15RoomInfluenceHC1 * $p13GradientHC1 * ($roomSetTemp - $insideTemp) /10); my $a= 0.7 + ($roomSetTemp * (1 + $p13GradientHC1 * 0.87)) + $p14LowEndHC1 + ($p15RoomInfluenceHC1 * $p13GradientHC1 * ($roomSetTemp - $insideTemp) /10);
my $a1= 0.7 + ($roomSetTemp * (1 + $p13GradientHC1 * 0.87)) + $p14LowEndHC1; my $a1= 0.7 + ($roomSetTemp * (1 + $p13GradientHC1 * 0.87)) + $p14LowEndHC1;
my $b= -14 * $p13GradientHC1 / $roomSetTemp; my $b= -14 * $p13GradientHC1 / $roomSetTemp;
my $c= -1 * $p13GradientHC1 /75; my $c= -1 * $p13GradientHC1 /75;
my $Simul_heatSetTemp; my $Simul_heatSetTemp_simplified; my @ret; my $Simul_heatSetTemp; my $Simul_heatSetTemp_simplified; my @ret;
foreach ($start..$stop) { foreach ($start..$stop) {
my $tmp =$_ * $_ * $c + $_ * $b; my $tmp =$_ * $_ * $c + $_ * $b;
@ -2201,44 +2083,34 @@ polyline { stroke:black; fill:none; }
<text x="751" y="155" class="ylabel" text-anchor="middle">20</text> <polyline points="751,19 751,140" class="hgrid"/> <text x="751" y="155" class="ylabel" text-anchor="middle">20</text> <polyline points="751,19 751,140" class="hgrid"/>
<g> <g>
END END
$ret .= '<polyline points="44,140 49,140"/> <text x="39" y="144" class="ylabel" text-anchor="end">' . $v0min . '</text>'
$ret .= '<polyline points="44,140 49,140"/> <text x="39" y="144" class="ylabel" text-anchor="end">' . $v0min . '</text>'; . '<polyline points="44,110 49,110"/> <text x="39" y="114" class="ylabel" text-anchor="end">' . $v1 . '</text>'
$ret .= '<polyline points="44,110 49,110"/> <text x="39" y="114" class="ylabel" text-anchor="end">' . $v1 . '</text>'; . '<polyline points="44,80 49,80"/> <text x="39" y="84" class="ylabel" text-anchor="end">' . $v2 . '</text>'
$ret .= '<polyline points="44,80 49,80"/> <text x="39" y="84" class="ylabel" text-anchor="end">' . $v2 . '</text>'; . '<polyline points="44,49 49,49"/> <text x="39" y="53" class="ylabel" text-anchor="end">' . $v3 . '</text>'
$ret .= '<polyline points="44,49 49,49"/> <text x="39" y="53" class="ylabel" text-anchor="end">' . $v3 . '</text>'; . '<polyline points="44,19 49,19"/> <text x="39" y="23" class="ylabel" text-anchor="end">' . $v4 . '</text> </g> <g>'
$ret .= '<polyline points="44,19 49,19"/> <text x="39" y="23" class="ylabel" text-anchor="end">' . $v4 . '</text>'; . '<polyline points="751,140 756,140"/> <text x="760" y="144" class="ylabel">' . $v0min . '</text>'
$ret .= '</g> <g>'; . '<polyline points="751,110 756,110"/> <text x="760" y="114" class="ylabel">' . $v1 . '</text>'
$ret .= '<polyline points="751,140 756,140"/> <text x="760" y="144" class="ylabel">'. $v0min .'</text>'; . '<polyline points="751,80 756,80"/> <text x="760" y="84" class="ylabel">' . $v2 . '</text>'
$ret .= '<polyline points="751,110 756,110"/> <text x="760" y="114" class="ylabel">'. $v1 .'</text>'; . '<polyline points="751,49 756,49"/> <text x="760" y="53" class="ylabel">' . $v3 . '</text>'
$ret .= '<polyline points="751,80 756,80"/> <text x="760" y="84" class="ylabel">' . $v2 .'</text>'; . '<polyline points="751,19 756,19"/> <text x="760" y="23" class="ylabel">' . $v4 . '</text></g>' ."\n";
$ret .= '<polyline points="751,49 756,49"/> <text x="760" y="53" class="ylabel">' . $v3 .'</text>';
$ret .= '<polyline points="751,19 756,19"/> <text x="760" y="23" class="ylabel">' . $v4 .'</text>';
$ret .= '</g>' ."\n";
#labels ###################### #labels ######################
$ret .= '<text line_id="line_1" x="70" y="100" class="l1"> --- heat curve with insideTemp correction</text>' ; $ret .= '<text line_id="line_1" x="70" y="100" class="l1"> --- heat curve with insideTemp correction</text>'
$ret .= '<text line_id="line_3" x="70" y="115" class="l3"> --- heat curve simplified</text>' ; . '<text line_id="line_3" x="70" y="115" class="l3"> --- heat curve simplified</text>'
$ret .= '<text line_id="line_0" x="70" y="130" class="l0"> --- working point: '; . '<text line_id="line_0" x="70" y="130" class="l0"> --- working point: outside_tempFiltered='
$ret .= 'outside_tempFiltered=' . $outside_tempFiltered . '°C heatSetTemp=' . $heatSetTemp . '°C </text>'; . $outside_tempFiltered . '°C heatSetTemp=' . $heatSetTemp . '°C </text>'
$ret .= '<text line_id="line_3" x="650" y="50" class="title"> -'. $pOpMode . '- </text>' ." \n" ; . '<text line_id="line_3" x="650" y="50" class="title"> -'. $pOpMode . '- </text>' ." \n";
#title ###################### #title ######################
$ret .= '<text id="svg_title" x="400" y="14.4" class="title" text-anchor="middle">'; $ret .= '<text id="svg_title" x="400" y="14.4" class="title" text-anchor="middle">'. $titlestring .' </text>' . "\n";
$ret .= $titlestring .' </text>' . "\n";
#point ###################### #point ######################
$ret .='<polyline id="line_0" style="stroke-width:2" class="l0" points="'; $ret .='<polyline id="line_0" style="stroke-width:2" class="l0" points="';
my ($px,$py) = (sprintf("%.1f", (($outside_tempFiltered+15)*(750-49)/(15+20)+49)),sprintf("%.1f", (($heatSetTemp-$v4)*(140-19)/($v0min-$v4)+19))); my ($px,$py) = (sprintf("%.1f", (($outside_tempFiltered+15)*(750-49)/(15+20)+49)),sprintf("%.1f", (($heatSetTemp-$v4)*(140-19)/($v0min-$v4)+19)));
$ret.= ($px-3) . "," . ($py) ." " . ($px) . "," . ($py-3) ." " . ($px+3) . "," . ($py) ." " . ($px) . "," . ($py+3) ." " . ($px-3) . "," . ($py) ." " . '"/>' . "\n"; $ret.= ($px-3) . "," . ($py) ." " . ($px) . "," . ($py-3) ." " . ($px+3) . "," . ($py) ." " . ($px) . "," . ($py+3) ." " . ($px-3) . "," . ($py) ." " . '"/>' . "\n";
#curve with inside temperature correction ###################### #curve with inside temperature correction ######################
$ret .='<polyline id="line_1" title="Heat Curve with insideTemp correction" style="stroke-width:1" class="l1" points="'; $ret .='<polyline id="line_1" title="Heat Curve with insideTemp correction" style="stroke-width:1" class="l1" points="';
foreach (@{$ycurvevalues}) { foreach (@{$ycurvevalues}) {
$ret.= (sprintf("%.1f", ($_->[0]+15)*(750-49)/(15+20)+49) ). "," . sprintf("%.1f", (($_->[1]-$v4)*(140-19)/($v0min-$v4)+19)) ." "; $ret.= (sprintf("%.1f", ($_->[0]+15)*(750-49)/(15+20)+49) ). "," . sprintf("%.1f", (($_->[1]-$v4)*(140-19)/($v0min-$v4)+19)) ." ";
} }
$ret .= '"/> ' . "\n"; $ret .= '"/> ' . "\n";
#curve without inside temperature correction ###################### #curve without inside temperature correction ######################
$ret .='<polyline id="line_3" title="Heat Curve simplified" style="stroke-width:1" class="l3" points="'; $ret .='<polyline id="line_3" title="Heat Curve simplified" style="stroke-width:1" class="l3" points="';
foreach (@{$ycurvevalues}) { foreach (@{$ycurvevalues}) {
@ -2246,16 +2118,10 @@ $ret.= (sprintf("%.1f", ($_->[0]+15)*(750-49)/(15+20)+49) ). "," . sprintf("%.1f
} }
$ret .= '"/> ' . "\n"; $ret .= '"/> ' . "\n";
$ret .= '</svg>'; $ret .= '</svg>';
my $FW_RETTYPE = "image/svg+xml"; my $FW_RETTYPE = "image/svg+xml";
return ($FW_RETTYPE, $ret); return ($FW_RETTYPE, $ret);
} }
sub THZ_detailFn(@){ sub THZ_detailFn(@){
my ($FW_wname, $d, $room, $pageHash) = @_; # pageHash is set for summaryFn. my ($FW_wname, $d, $room, $pageHash) = @_; # pageHash is set for summaryFn.
my $hash = $defs{$d}; #$d is the name of the defined device my $hash = $defs{$d}; #$d is the name of the defined device
@ -2294,18 +2160,12 @@ sub THZ_backup_readings($){
return "saved Readings in $backupfile"; return "saved Readings in $backupfile";
} }
1; 1;
=pod =pod
=item device =item device
=item summary Monitors and controls Tecalor/StiebelEltron heatpumps via RS232 or ser2net =item summary Monitors and controls Tecalor/StiebelEltron heatpumps via RS232 or ser2net
=item summary_DE Kommuniziert mittels RS232 oder ser2net mit einer Tecalor/SE W&auml;rmepumpe =item summary_DE Kommuniziert mittels RS232 oder ser2net mit einer Tecalor/SE Wärmepumpe
=item cloudfree =item cloudfree
=item openapi =item openapi
=begin html =begin html
@ -2388,19 +2248,15 @@ sub THZ_backup_readings($){
<a name="THZ"></a> <a name="THZ"></a>
<h3>THZ</h3> <h3>THZ</h3>
<ul> <ul>
THZ Modul: Kommuniziert mittels einem seriellen Interface RS232/USB (z.B. /dev/ttyxx), oder mittels ser2net (z.B. 10.0.x.x:5555) mit einer Tecalor / Stiebel THZ Modul: Kommuniziert mittels einem seriellen Interface RS232/USB (z.B. /dev/ttyxx), oder mittels ser2net (z.B. 10.0.x.x:5555) mit einer Tecalor / Stiebel Eltron Wärmepumpe. <br>
Eltron W&auml;rmepumpe. <br> Getestet mit einer Tecalor THZ303/Sol (Serielle Geschwindigkeit 57600/115200@USB) und einer THZ403 (Serielle Geschwindigkeit 115200) mit identischer Firmware 4.39. <br>
Getestet mit einer Tecalor THZ303/Sol (Serielle Geschwindigkeit 57600/115200@USB) und einer THZ403 (Serielle Geschwindigkeit 115200) mit identischer
Firmware 4.39. <br>
Getestet mit einer Stiebel LWZ404 (Serielle Geschwindigkeit 115200@USB) mit Firmware 5.39. <br> Getestet mit einer Stiebel LWZ404 (Serielle Geschwindigkeit 115200@USB) mit Firmware 5.39. <br>
Getestet auf FritzBox, nas-qnap, Raspberry Pi and MacOS.<br> Getestet auf FritzBox, nas-qnap, Raspberry Pi and MacOS.<br>
Dieses Modul funktioniert nicht mit &aumlterer Firmware; Gleichwohl, das "parsing" k&ouml;nnte leicht angepasst werden da die Register gut Dieses Modul funktioniert nicht mit älterer Firmware; Gleichwohl, das "parsing" könnte leicht angepasst werden da die Register gut beschrieben wurden.
beschrieben wurden.
https://answers.launchpad.net/heatpumpmonitor/+question/100347 <br> https://answers.launchpad.net/heatpumpmonitor/+question/100347 <br>
Implementiert: Lesen der Statusinformation sowie Lesen und Schreiben einzelner Einstellungen. Implementiert: Lesen der Statusinformation sowie Lesen und Schreiben einzelner Einstellungen.
Genauere Beschreinung des Modules --> 00_THZ wiki http://www.fhemwiki.de/wiki/Tecalor_THZ_W%C3%A4rmepumpe Genauere Beschreinung des Modules --> 00_THZ wiki http://www.fhemwiki.de/wiki/Tecalor_THZ_W%C3%A4rmepumpe
<br><br> <br><br>
<a name="THZdefine"></a> <a name="THZdefine"></a>
<b>Define</b> <b>Define</b>
<ul> <ul>
@ -2472,5 +2328,3 @@ sub THZ_backup_readings($){
=cut =cut