2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-19 00:26:03 +00:00

added max send queue length checking and correct handling of 0xD2 Message type

git-svn-id: https://svn.fhem.de/fhem/trunk@6464 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
ststrobel 2014-08-26 16:27:29 +00:00
parent f69bfa186a
commit fac239fb38

View File

@ -32,7 +32,10 @@
#
# 2014-04-18 initial version
# 2014-05-17 added more protocol commands, changed logging settings
# 2014-05-25 added hide- attributes
# 2014-05-25 added hide- attributes
# 2014-07-07 corrected handling of 0xD2 Message (protocol is different than documented)
# 2014-07-24 added max queue length checking and attribute
#
package main;
@ -158,9 +161,10 @@ my %parseInfo = (
{ name => "Proz_Abluft_hoch"},
{ name => "Proz_Zuluft_hoch"}]},
"00d2" => { unpack => "CCCCCxC",
"00d2" => { unpack => "CCCCCCC",
name => "Temperaturen",
request => "00d1", defaultpoll => 1,
check => '($fields[5] & 15) == 15',
readings => [ { name => "Temp_Komfort", expr => '$val / 2 - 20',
set => "00D3:%02x", setexpr => '($val + 20) *2',
setmin => 12, setmax => 28, hint => "slider,12,1,28"},
@ -169,6 +173,7 @@ my %parseInfo = (
{ name => "Temp_Zuluft" , expr => '$val / 2 - 20'},
{ name => "Temp_Abluft" , expr => '$val / 2 - 20'},
{ name => "Temp_Fortluft", expr => '$val / 2 - 20'},
{ name => "Temp_Flag"},
{ name => "Temp_EWT", expr => '$val / 2 - 20'}]},
"00de" => { unpack => "H6H6H6S>S>S>S>H6",
@ -245,13 +250,13 @@ ComfoAir_Initialize($)
if (defined ($msgHashRef->{request})) { # Nachricht kann abgefragt werden
my $requestName = "request-" . $msgName; # für eine Set-Option
my $attrName = "poll-" . $msgName; # für das Attribut zur Steuerung welche Blöcke abgefragt werden
my $attr2Name = "hide-" . $msgName; # für das Attribut zum Verstecken von Blöcken
my $attr2Name = "hide-" . $msgName; # für das Attribut zum Verstecken von Blöcken
$requestHash{$requestName} = $msgHashRef; # erzeuge requestHash für Verweis von requestName auf msgHash
$requestHash{$requestName}->{replyCode} = $replyCode; # ergänze Replycode im msgHash
$cmdHash{$msgHashRef->{request}} = $msgHashRef; # erzeuge %cmdHash für Verweis von RequestCode auf msgHash (für Debug Log)
push @setList, $requestName;
push @pollList, "$attrName:0,1";
push @pollList, "$attr2Name:0,1";
push @pollList, "$attr2Name:0,1";
}
# gehe durch alle Readings im Nachrichtentyp und erzeuge getHash, setHash und setList, rmap, setopt
foreach my $readingHashRef (@{$msgHashRef->{readings}}) {
@ -292,6 +297,7 @@ ComfoAir_Initialize($)
$hash->{AttrList}= "do_not_notify:1,0 " .
"queueDelay " .
"timeout " .
"queueMax " .
#"minSendDelay " .
join (" ", @pollList) . " " . # Def der zyklisch abzufragenden Nachrichten
$readingFnAttributes;
@ -556,33 +562,44 @@ ComfoAir_InterpretFrame($$)
# Parse Data
if ($parseInfo{$hexcmd}) {
if (!AttrVal($name, "hide-$parseInfo{$hexcmd}{name}", 0)) {
# Definition für diesen Nachrichten-Typ gefunden
my %p = %{$parseInfo{$hexcmd}};
Log3 $name, 4, "$name: read got " . $p{"name"} . " (reply code $hexcmd) with data $hexdata";
readingsBeginUpdate($hash);
# Definition der einzelnen Felder abarbeiten
my @fields = unpack($p{"unpack"}, $data);
for (my $i = 0; $i < scalar(@fields); $i++) {
# einzelne Felder verarbeiten
my $reading = $p{"readings"}[$i]{"name"};
my $val = $fields[$i];
# Exp zur Nachbearbeitung der Werte?
if ($p{"readings"}[$i]{"expr"}) {
Log3 $name, 5, "$name: read evaluate $val with expr " . $p{"readings"}[$i]{"expr"};
$val = eval($p{"readings"}[$i]{"expr"});
}
# Map zur Nachbereitung der Werte?
if ($p{"readings"}[$i]{"map"}) {
my %map = split (/[,: ]+/, $p{"readings"}[$i]{"map"});
Log3 $name, 5, "$name: read maps value $val with " . $p{"readings"}[$i]{"map"};
$val = $map{$val} if ($map{$val});
}
Log3 $name, 5, "$name: read assign $reading with $val";
readingsBulkUpdate($hash, $reading, $val);
}
readingsEndUpdate($hash, 1);
}
if (!AttrVal($name, "hide-$parseInfo{$hexcmd}{name}", 0)) {
# Definition für diesen Nachrichten-Typ gefunden
my %p = %{$parseInfo{$hexcmd}};
Log3 $name, 4, "$name: read got " . $p{"name"} . " (reply code $hexcmd) with data $hexdata";
# Definition der einzelnen Felder abarbeiten
my @fields = unpack($p{"unpack"}, $data);
my $filter = 0;
if ($p{check}) {
Log3 $name, 5, "$name: cmd $hexcmd check is " . eval($p{check}) .
', $fields[5] = ' . $fields[5] if ($fields[5] > 15);
if (!eval($p{check})) {
Log3 $name, 5, "$name: filter data for failed check: @fields";
$filter = 1;
}
}
if (!$filter) {
readingsBeginUpdate($hash);
for (my $i = 0; $i < scalar(@fields); $i++) {
# einzelne Felder verarbeiten
my $reading = $p{"readings"}[$i]{"name"};
my $val = $fields[$i];
# Exp zur Nachbearbeitung der Werte?
if ($p{"readings"}[$i]{"expr"}) {
Log3 $name, 5, "$name: read evaluate $val with expr " . $p{"readings"}[$i]{"expr"};
$val = eval($p{"readings"}[$i]{"expr"});
}
# Map zur Nachbereitung der Werte?
if ($p{"readings"}[$i]{"map"}) {
my %map = split (/[,: ]+/, $p{"readings"}[$i]{"map"});
Log3 $name, 5, "$name: read maps value $val with " . $p{"readings"}[$i]{"map"};
$val = $map{$val} if ($map{$val});
}
Log3 $name, 5, "$name: read assign $reading with $val";
readingsBulkUpdate($hash, $reading, $val);
}
readingsEndUpdate($hash, 1);
}
}
} else {
my $level = ($hash->{INTERVAL} ? 4 : 5);
Log3 $name, $level, "$name: read: unknown cmd $hexcmd, len " . unpack ('C', $len) .
@ -651,10 +668,10 @@ ComfoAir_ReadAnswer($$$)
if($^O =~ m/Win/ && $hash->{USBDev}) {
$hash->{USBDev}->read_const_time($to*1000); # set timeout (ms)
$buf = $hash->{USBDev}->read(999);
if(length($buf) == 0) {
Log3 $name, 3, "$name: Timeout in ReadAnswer for get $arg";
return ("Timeout reading answer for $arg", undef);
}
if(length($buf) == 0) {
Log3 $name, 3, "$name: Timeout in ReadAnswer for get $arg";
return ("Timeout reading answer for $arg", undef);
}
} else {
if(!$hash->{FD}) {
Log3 $name, 3, "$name: Device lost in ReadAnswer for get $arg";
@ -723,7 +740,7 @@ sub
ComfoAir_GetUpdate($$) {
my ($hash) = @_;
my $name = $hash->{NAME};
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "ComfoAir_GetUpdate", $hash, 1)
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "ComfoAir_GetUpdate", $hash, 0)
if ($hash->{INTERVAL});
foreach my $msgHashRef (values %parseInfo) {
@ -763,13 +780,19 @@ ComfoAir_Send($$$;$$){
$entry{DATA} = $frame;
$entry{EXPECT} = $expectReply;
if(!$hash->{QUEUE} || 0 == scalar(@{$hash->{QUEUE}})) {
my $qlen = ($hash->{QUEUE} ? scalar(@{$hash->{QUEUE}}) : 0);
Log3 $name, 5, "$name: send queue length : $qlen";
if(!$qlen) {
$hash->{QUEUE} = [ \%entry ];
} else {
if ($first) {
unshift (@{$hash->{QUEUE}}, \%entry);
if ($qlen > AttrVal($name, "queueMax", 20)) {
Log3 $name, 3, "$name: send queue too long, dropping request";
} else {
push(@{$hash->{QUEUE}}, \%entry);
if ($first) {
unshift (@{$hash->{QUEUE}}, \%entry);
} else {
push(@{$hash->{QUEUE}}, \%entry);
}
}
}
ComfoAir_HandleSendQueue("direct:".$name);
@ -930,7 +953,7 @@ ComfoAir_SendAck($)
Bootloader-Version
Firmware-Version
RS232-Modus
Sensordaten
Sensordaten
KonPlatine-Version
Verzoegerungen
Ventilation-Levels
@ -946,7 +969,7 @@ ComfoAir_SendAck($)
poll-Bootloader-Version
poll-Firmware-Version
poll-RS232-Modus
poll-Sensordaten
poll-Sensordaten
poll-KonPlatine-Version
poll-Verzoegerungen
poll-Ventilation-Levels
@ -974,7 +997,7 @@ ComfoAir_SendAck($)
<pre>
request-Status-Bypass
request-Bootloader-Version
request-Sensordaten
request-Sensordaten
request-Temperaturen
request-Firmware-Version
request-KonPlatine-Version
@ -1006,7 +1029,7 @@ ComfoAir_SendAck($)
<li><b>poll-Bootloader-Version</b></li>
<li><b>poll-Firmware-Version</b></li>
<li><b>poll-RS232-Modus</b></li>
<li><b>poll-Sensordaten</b></li>
<li><b>poll-Sensordaten</b></li>
<li><b>poll-KonPlatine-Version</b></li>
<li><b>poll-Verzoegerungen</b></li>
<li><b>poll-Ventilation-Levels</b></li>
@ -1018,7 +1041,7 @@ ComfoAir_SendAck($)
<li><b>hide-Bootloader-Version</b></li>
<li><b>hide-Firmware-Version</b></li>
<li><b>hide-RS232-Modus</b></li>
<li><b>hide-Sensordaten</b></li>
<li><b>hide-Sensordaten</b></li>
<li><b>hide-KonPlatine-Version</b></li>
<li><b>hide-Verzoegerungen</b></li>
<li><b>hide-Ventilation-Levels</b></li>
@ -1026,10 +1049,12 @@ ComfoAir_SendAck($)
<li><b>hide-Betriebsstunden</b></li>
<li><b>hide-Status-Bypass</b></li>
<li><b>hide-Status-Vorheizung</b></li>
prevent readings of the named group from being created even if used passively without polling and an external remote control requests this data.
please note that this attribute doesn't delete already existing readings.<br>
prevent readings of the named group from being created even if used passively without polling and an external remote control requests this data.
please note that this attribute doesn't delete already existing readings.<br>
<li><b>queueDelay</b></li>
modify the delay used when sending requests to the device from the internal queue, defaults to 1 second <br>
<li><b>queueMax</b></li>
max length of the send queue, defaults to 50<br>
<li><b>timeout</b></li>
set the timeout for reads, defaults to 2 seconds <br>
</ul>