2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-10 20:19:50 +00:00

00_ZWDongle.pm: fix sending to multiple targets (Forum #43413)

git-svn-id: https://svn.fhem.de/fhem/trunk@9822 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2015-11-08 13:33:41 +00:00
parent dced82a52c
commit 1402c20276
2 changed files with 43 additions and 36 deletions

View File

@ -192,7 +192,7 @@ ZWDongle_Initialize($)
$hash->{AttrFn} = "ZWDongle_Attr";
$hash->{UndefFn} = "ZWDongle_Undef";
$hash->{AttrList}= "do_not_notify:1,0 dummy:1,0 model:ZWDongle disable:0,1 ".
"homeId networkKey delayNeeded:1,0";
"homeId networkKey";
}
#####################################
@ -237,7 +237,7 @@ ZWDongle_Define($$)
$hash->{nrNAck} = 0;
my @empty;
$hash->{SendStack} = \@empty;
ZWDongle_shiftSendStack($hash, 5, undef);
ZWDongle_shiftSendStack($hash, 0, 5, undef);
my $ret = DevIo_OpenDev($hash, 0, "ZWDongle_DoInit");
return $ret;
@ -361,7 +361,10 @@ ZWDongle_Get($@)
for my $byte (0..28) {
my $bits = $r[5+$byte];
for my $bit (0..7) {
push @list, $byte*8+$bit+1 if($bits & (1<<$bit));
next if(!($bits & (1<<$bit)));
my $idx = $byte*8+$bit+1;
my @l = devspec2array(sprintf(".*:FILTER=nodeIdHex=%02x", $idx));
push @list, ($l[0] && $defs{$l[0]} ? $l[0] : "UNKNOWN_$idx");
}
}
$msg = join(",", @list);
@ -386,6 +389,7 @@ ZWDongle_Get($@)
$msg = sprintf("HomeId:%s CtrlNodeId:%s",
substr($ret,4,8), substr($ret,12,2));
$hash->{homeId} = substr($ret,4,8);
$hash->{nodeIdHex} = substr($ret,12,2);
$attr{NAME}{homeId} = substr($ret,4,8);
} elsif($type eq "version") { ############################
@ -509,17 +513,25 @@ ZWDongle_Write($$$)
}
sub
ZWDongle_shiftSendStack($$$)
ZWDongle_shiftSendStack($$$$)
{
my ($hash, $level, $txt) = @_;
my ($hash, $reason, $loglevel, $txt) = @_;
my $ss = $hash->{SendStack};
my $cmd = shift @{$ss};
Log3 $hash, $level, "$txt, removing $cmd from dongle sendstack"
if($txt && $cmd);
my $cmd = $ss->[0];
$hash->{WaitForAck}=0;
$hash->{SendRetries}=0;
$hash->{MaxSendRetries}=3;
if($cmd && $reason==0 && $cmd =~ m/^01..0013/) { # ACK for SEND_DATA
Log3 $hash, $loglevel, "$txt, WaitForAck=>2 for $cmd"
if($txt && $cmd);
$hash->{WaitForAck}=2;
} else {
shift @{$ss};
Log3 $hash, $loglevel, "$txt, removing $cmd from dongle sendstack"
if($txt && $cmd);
$hash->{WaitForAck}=0;
$hash->{SendRetries}=0;
$hash->{MaxSendRetries}=3;
}
}
sub
@ -535,12 +547,15 @@ ZWDongle_ProcessSendStack($)
my $ts = gettimeofday();
if($hash->{WaitForAck}){
if($ts-$hash->{SendTime} >= 1){
if($hash->{WaitForAck} == 1 && $ts-$hash->{SendTime} >= 1) {
Log3 $hash, 2, "ZWDongle_ProcessSendStack: no ACK, resending message ".
$hash->{SendStack}->[0];
$hash->{SendRetries}++;
$hash->{WaitForAck} = 0;
} elsif($hash->{WaitForAck} == 2 && $ts-$hash->{SendTime} >= 2) {
ZWDongle_shiftSendStack($hash, 1, 4, "no response from device");
} else {
InternalTimer($ts+1, "ZWDongle_ProcessSendStack", $hash, 0);
return;
@ -549,7 +564,7 @@ ZWDongle_ProcessSendStack($)
}
if($hash->{SendRetries} > $hash->{MaxSendRetries}){
ZWDongle_shiftSendStack($hash, 1, "ERROR: max send retries reached");
ZWDongle_shiftSendStack($hash, 1, 1, "ERROR: max send retries reached");
}
return if(!@{$hash->{SendStack}} ||
@ -594,7 +609,7 @@ ZWDongle_Read($@)
my $fb = substr($data, 0, 2);
if($fb eq "06") { # ACK
ZWDongle_shiftSendStack($hash, 5, "ACK received");
ZWDongle_shiftSendStack($hash, 0, 5, "ACK received");
$data = substr($data, 2);
next;
}
@ -652,6 +667,8 @@ ZWDongle_Read($@)
$hash->{nrNAck} = 0;
Log3 $name, 4, "ZWDongle_Read $name: sending ACK, processing $msg";
DevIo_SimpleWrite($hash, "06", 1); # Send ACK
ZWDongle_shiftSendStack($hash, 1, 5, "device ack reveived")
if($msg =~ m/^0013/);
last if(defined($local) && (!defined($regexp) || ($msg =~ m/$regexp/)));
$hash->{PARTIAL} = $data; # Recursive call by ZWave get, Forum #37418
@ -880,8 +897,9 @@ ZWDongle_Ready($)
<b>Get</b>
<ul>
<li>nodeList<br>
return the list of included nodeIds. Can be used to recreate fhem-nodes
with the createNode command.</li>
return the list of included nodenames or UNKNOWN_id, if there is no
corresponding device in FHEM. Can be used to recreate fhem-nodes with the
createNode command.</li>
<li>homeId<br>
return the six hex-digit homeId of the controller.</li>
@ -918,10 +936,6 @@ ZWDongle_Ready($)
<li><a href="#networkKey">networkKey</a><br>
Needed for secure inclusion, hex string with length of 32
</li>
<li><a href="#delayNeeded">delayNeeded</a><br>
If set to 0, no delay is needed between sending consecutive commands to
the same receiver. Default is 1 (delay is needed).
</li>
</ul>
<br>

View File

@ -783,7 +783,7 @@ ZWave_Cmd($$@)
$data = "$cmd $id $data" if($re);
$val = ($data ? ZWave_Parse($iohash, $data, $type) : "no data returned");
ZWave_processSendStack($hash, 1) if($data && $cmd eq "neighborList");
ZWave_processSendStack($hash) if($data && $cmd eq "neighborList");
} else {
if(!$zwave_quietCmds{$cmd}) {
@ -2552,19 +2552,12 @@ ZWave_isWakeUp($)
}
sub
ZWave_processSendStack($$)
ZWave_processSendStack($)
{
my ($hash, $withDelay) = @_;
my ($hash) = @_;
my $ss = $hash->{SendStack};
return if(!$ss);
if($withDelay && AttrVal($hash->{IODev}{NAME}, "delayNeeded",1)) {
InternalTimer(gettimeofday()+0.3, sub {
ZWave_processSendStack($hash, 0);
}, {}, 0);
return;
}
if(index($ss->[0],"sent") == 0) {
shift @{$ss};
RemoveInternalTimer($hash) if(!ZWave_isWakeUp($hash));
@ -2584,7 +2577,7 @@ ZWave_processSendStack($$)
if(!ZWave_isWakeUp($hash)) {
InternalTimer($hash->{lastMsgSent}+10, sub {
Log 2, "ZWave: No ACK from $hash->{NAME} after 10s for $ss->[0]";
ZWave_processSendStack($hash, 0);
ZWave_processSendStack($hash);
}, $hash, 0);
}
}
@ -2617,7 +2610,7 @@ ZWave_addToSendStack($$)
return ZWave_addToSendStack($hash, $cmd);
}
}
ZWave_processSendStack($hash, 0) if(@{$ss} == 1);
ZWave_processSendStack($hash) if(@{$ss} == 1);
return undef;
}
@ -2676,7 +2669,7 @@ ZWave_Parse($$@)
my $hash = $zwave_lastHashSent;
readingsSingleUpdate($hash, "SEND_DATA", "failed:$arg", 1);
Log3 $ioName, 2, "ERROR: cannot SEND_DATA to $hash->{NAME}: $arg";
ZWave_processSendStack($hash, 1);
ZWave_processSendStack($hash);
} else {
Log3 $ioName, 2, "ERROR: cannot SEND_DATA: $arg (unknown device)";
@ -2782,7 +2775,7 @@ ZWave_Parse($$@)
if($hash) {
if(ZWave_isWakeUp($hash)) {
ZWave_wakeupTimer($hash, 1);
ZWave_processSendStack($hash, 0);
ZWave_processSendStack($hash);
}
if(!$ret) {
@ -2802,7 +2795,7 @@ ZWave_Parse($$@)
Log3 $ioName, 4, "$ioName transmit $lmsg for $callbackid";
if($hash) {
readingsSingleUpdate($hash, "transmit", $lmsg, 0);
ZWave_processSendStack($hash, 1);
ZWave_processSendStack($hash);
}
return "";
@ -2951,7 +2944,7 @@ ZWave_Parse($$@)
if($arg =~ m/^028407/) { # wakeup:notification
ZWave_wakeupTimer($hash, 1);
ZWave_processSendStack($hash, 0);
ZWave_processSendStack($hash);
}
return "" if(!@event);