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