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:
parent
18f5bc0b22
commit
3f9fb855e0
@ -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ä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ä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 äterer Firmware; Gleichwohl, das "parsing" kö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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user