diff --git a/fhem/FHEM/00_ZWDongle.pm b/fhem/FHEM/00_ZWDongle.pm index 6bf772fc9..088930670 100755 --- a/fhem/FHEM/00_ZWDongle.pm +++ b/fhem/FHEM/00_ZWDongle.pm @@ -405,6 +405,7 @@ ZWDongle_shiftSendStack($$$$) $hash->{WaitForAck}=0; $hash->{SendRetries}=0; $hash->{MaxSendRetries}=3; + delete($hash->{GotCAN}); } } @@ -450,6 +451,7 @@ ZWDongle_ProcessSendStack($) DevIo_SimpleWrite($hash, $msg, 1); $hash->{WaitForAck} = 1; $hash->{SendTime} = $ts; + delete($hash->{GotCAN}); InternalTimer($ts+1, "ZWDongle_ProcessSendStack", $hash, 0); } @@ -500,6 +502,7 @@ ZWDongle_Read($@) Log3 $name, 4, "ZWDongle_Read $name: CAN received"; $hash->{MaxSendRetries}++ if($hash->{MaxSendRetries}<7); $data = substr($data, 2); + $hash->{GotCAN} = 1; if(!$init_done) { # InternalTimer wont work $hash->{WaitForAck} = 0; $hash->{SendRetries}++; @@ -539,7 +542,7 @@ ZWDongle_Read($@) next; } $hash->{nrNAck} = 0; - Log3 $name, 4, "ZWDongle_Read $name: sending ACK, processing $msg"; + Log3 $name, 4, "ZWDongle_Read $name: rcvd $msg, sending ACK"; DevIo_SimpleWrite($hash, "06", 1); # Send ACK ZWDongle_shiftSendStack($hash, 1, 5, "device ack reveived") if($msg =~ m/^0013/); @@ -634,8 +637,8 @@ ZWDongle_Parse($$$) $hash->{"${name}_TIME"} = TimeNow(); $hash->{RAWMSG} = $rmsg; - $hash->{SendTime} = 0 # Retry sending after a "real" msg from the dongle - if($hash->{WaitForAck} && $rmsg !~ m/^(0113|0013)/); + $hash->{SendTime}-- # Retry sending after a "real" msg from the dongle + if($hash->{GotCAN} && $rmsg !~ m/^(0113|0013)/); my %addvals = (RAWMSG => $rmsg); diff --git a/fhem/FHEM/10_ZWave.pm b/fhem/FHEM/10_ZWave.pm index 14e029875..006e66e3d 100755 --- a/fhem/FHEM/10_ZWave.pm +++ b/fhem/FHEM/10_ZWave.pm @@ -3549,7 +3549,7 @@ ZWave_isWakeUp($) # type is: set / sentset, get / sentget / sentackget # sentset will be discarded after ack, sentget needs ack (->sentackget) then msg # next discards either state. -# acktpye: next, ack or msg +# acktpye: retry, next, ack or msg sub ZWave_processSendStack($$;$) { @@ -3557,13 +3557,20 @@ ZWave_processSendStack($$;$) my $ss = $hash->{SendStack}; return if(!$ss); + if($ackType eq "retry") { + $ss->[0] =~ m/^(.*)(set|get):(.*)$/; + $ss->[0] = "$2:$3"; + return; + } + if($ss->[0] =~ m/^sent(.*?):(.*)$/) { - if($1 eq "get" && $ackType eq "ack") { - $ss->[0] = "sentackget:$2"; + my ($stype,$smsg) = ($1,$2); + if($stype =~ m/get/ && $ackType eq "ack") { # accept double-ACK + $ss->[0] = "sentackget:$smsg"; return; - } elsif($1 eq "ackget" && $ackType eq "msg") {# compare answer class for get - my $cs = substr($2, 6, 2); + } elsif($stype eq "ackget" && $ackType eq "msg") {# compare answer class + my $cs = substr($smsg, 6, 2); my $cg = substr($omsg, 2, 2); return if($cs ne $cg); } @@ -3654,7 +3661,7 @@ ZWave_Parse($$@) readingsSingleUpdate($hash, "SEND_DATA", "failed:$arg", 1); $arg = "transmit queue overflow" if($arg == 0); Log3 $ioName, 2, "ERROR: cannot SEND_DATA to $hash->{NAME}: $arg"; - ZWave_processSendStack($hash, "next"); + ZWave_processSendStack($hash, "retry"); } else { Log3 $ioName, 2, "ERROR: cannot SEND_DATA: $arg (unknown device)"; @@ -3758,7 +3765,7 @@ ZWave_Parse($$@) } return ""; - } else { + } else { # Wait for the retry timer to remove this cmd from the stack. Log3 $ioName, 2, "$ioName transmit $lmsg for $callbackid"; return "" if(!$hash); readingsSingleUpdate($hash, "state", "TRANSMIT_$lmsg", 1);