mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-18 12:06:04 +00:00
CUL_MAX: Enqueue messages for ShutterContact until its button is pressed
git-svn-id: https://svn.fhem.de/fhem/trunk@4111 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
60511648a0
commit
4bca443027
@ -15,7 +15,7 @@ sub CUL_MAX_Set($@);
|
||||
sub CUL_MAX_SendTimeInformation(@);
|
||||
sub CUL_MAX_GetTimeInformationPayload();
|
||||
sub CUL_MAX_Send(@);
|
||||
sub CUL_MAX_SendQueueHandler($);
|
||||
sub CUL_MAX_SendQueueHandler($$);
|
||||
|
||||
my $pairmodeDuration = 60; #seconds
|
||||
|
||||
@ -276,13 +276,18 @@ CUL_MAX_Parse($$)
|
||||
|
||||
return $shash->{NAME} if(!@{$shash->{sendQueue}}); #we are not waiting for any Ack
|
||||
|
||||
my $packet = $shash->{sendQueue}[0];
|
||||
if($packet->{src} eq $dst and $packet->{dst} eq $src and $packet->{cnt} == hex($msgcnt)) {
|
||||
Log $ll5, "Got matching ack";
|
||||
my $isnak = unpack("C",pack("H*",$payload)) & 0x80;
|
||||
$packet->{sent} = $isnak ? 3 : 2;
|
||||
return $shash->{NAME};
|
||||
for my $i (0 .. $#{$shash->{sendQueue}}) {
|
||||
my $packet = $shash->{sendQueue}[$i];
|
||||
if($packet->{src} eq $dst and $packet->{dst} eq $src and $packet->{cnt} == hex($msgcnt)) {
|
||||
Log $ll5, "Got matching ack";
|
||||
my $isnak = unpack("C",pack("H*",$payload)) & 0x80;
|
||||
$packet->{sent} = $isnak ? 3 : 2;
|
||||
}
|
||||
}
|
||||
#Handle outgoing messages to that ShutterContact. It is only awake shortly
|
||||
#after sending an Ack to a PairPong
|
||||
CUL_MAX_SendQueueHandler($shash, $src) if($modules{MAX}{defptr}{$src}{type} eq "ShutterContact");
|
||||
return $shash->{NAME};
|
||||
|
||||
} elsif($msgType eq "TimeInformation") {
|
||||
if($isToMe) {
|
||||
@ -386,7 +391,7 @@ CUL_MAX_Send(@)
|
||||
|
||||
#Call CUL_MAX_SendQueueHandler if we just enqueued the only packet
|
||||
#otherwise it is already in the InternalTimer list
|
||||
CUL_MAX_SendQueueHandler($hash) if(@{$hash->{sendQueue}} == 1);
|
||||
CUL_MAX_SendQueueHandler($hash,undef) if(@{$hash->{sendQueue}} == 1);
|
||||
return undef;
|
||||
}
|
||||
|
||||
@ -399,12 +404,17 @@ CUL_MAX_DeviceHash($)
|
||||
|
||||
#This can be called for two reasons:
|
||||
#1. @sendQueue was empty, CUL_MAX_Send added a packet and then called us
|
||||
#2. We sent a packet from @sendQueue and know the ackTimeout is over.
|
||||
#2. We sent a packet from @sendQueue and now the ackTimeout is over.
|
||||
# The packet my still be in @sendQueue (timed out) or removed when the Ack was received.
|
||||
# Arguments are hash and responseToShutterContact.
|
||||
# If SendQueueHandler was called after receiving a message from a shutter contact, responseToShutterContact
|
||||
# holds the address of the respective shutter contact. Otherwise, it is empty.
|
||||
sub
|
||||
CUL_MAX_SendQueueHandler($)
|
||||
CUL_MAX_SendQueueHandler($$)
|
||||
{
|
||||
my $hash = shift;
|
||||
my $responseToShutterContact = shift;
|
||||
|
||||
Log GetLogLevel($hash->{NAME}, 5), "CUL_MAX_SendQueueHandler: " . @{$hash->{sendQueue}} . " items in queue";
|
||||
return if(!@{$hash->{sendQueue}}); #nothing to do
|
||||
|
||||
@ -423,13 +433,34 @@ CUL_MAX_SendQueueHandler($)
|
||||
return undef;
|
||||
}
|
||||
|
||||
my $packet = $hash->{sendQueue}[0];
|
||||
my ($packet, $pktIdx, $packetForShutterContactInQueue);
|
||||
for($pktIdx = 0; $pktIdx < @{$hash->{sendQueue}}; $pktIdx += 1) {
|
||||
$packet = $hash->{sendQueue}[$pktIdx];
|
||||
|
||||
if(defined($responseToShutterContact)) {
|
||||
#Find a packet to the ShutterContact in $responseToShutterContact
|
||||
last if($packet->{dst} eq $responseToShutterContact);
|
||||
} else {
|
||||
#We cannot sent packets to a ShutterContact directly, everything else is possible
|
||||
last if($packet->{cmd} eq "PairPong"
|
||||
|| $packet->{sent} != 0
|
||||
|| $modules{MAX}{defptr}{$packet->{dst}}{type} ne "ShutterContact");
|
||||
$packetForShutterContactInQueue = $modules{MAX}{defptr}{$packet->{dst}}{NAME};
|
||||
}
|
||||
}
|
||||
if($pktIdx == @{$hash->{sendQueue}} && !defined($responseToShutterContact)) {
|
||||
Log 2, "There is a packet for ShutterContact $packetForShutterContactInQueue in queue. Please push the button on the respective ShutterContact so the packet can be send.";
|
||||
$timeout += 3;
|
||||
InternalTimer($timeout, "CUL_MAX_SendQueueHandler", $hash, 0);
|
||||
return undef;
|
||||
}
|
||||
|
||||
if( $packet->{sent} == 0 ) { #Need to send it first
|
||||
#We can use fast sending without preamble on culfw 1.53 and higher when the devices has been woken up
|
||||
my $needPreamble = ((CUL_MAX_Check($hash) < 153)
|
||||
|| !defined($modules{MAX}{defptr}{$packet->{dst}}{wakeUpUntil})
|
||||
|| $modules{MAX}{defptr}{$packet->{dst}}{wakeUpUntil} < gettimeofday()) ? 1 : 0;
|
||||
|| (!defined($responseToShutterContact) &&
|
||||
(!defined($modules{MAX}{defptr}{$packet->{dst}}{wakeUpUntil})
|
||||
|| $modules{MAX}{defptr}{$packet->{dst}}{wakeUpUntil} < gettimeofday()))) ? 1 : 0;
|
||||
|
||||
#Send to CUL
|
||||
my ($credit10ms) = (CommandGet("","$hash->{IODev}{NAME} credit10ms") =~ /[^ ]* [^ ]* => (.*)/);
|
||||
@ -465,7 +496,7 @@ CUL_MAX_SendQueueHandler($)
|
||||
if( $packet->{sentTime} + $ackTimeout < gettimeofday() ) {
|
||||
# ackTimeout exceeded
|
||||
Log 2, "CUL_MAX_SendQueueHandler: Missing ack from $packet->{dst} for $packet->{packet}";
|
||||
splice @{$hash->{sendQueue}}, 0, 1; #Remove from array
|
||||
splice @{$hash->{sendQueue}}, $pktIdx, 1; #Remove from array
|
||||
readingsSingleUpdate($hash, "packetsLost", ReadingsVal($hash->{NAME}, "packetsLost", 0) + 1, 1);
|
||||
} else {
|
||||
# Recheck for Ack
|
||||
@ -476,13 +507,14 @@ CUL_MAX_SendQueueHandler($)
|
||||
if(defined($packet->{callbackParam})) {
|
||||
Dispatch($hash, "MAX,1,Ack$packet->{cmd},$packet->{dst},$packet->{callbackParam}", {RAWMSG => ""});
|
||||
}
|
||||
splice @{$hash->{sendQueue}}, 0, 1; #Remove from array
|
||||
splice @{$hash->{sendQueue}}, $pktIdx, 1; #Remove from array
|
||||
|
||||
} elsif( $packet->{sent} == 3 ) { #Got nack
|
||||
splice @{$hash->{sendQueue}}, 0, 1; #Remove from array
|
||||
splice @{$hash->{sendQueue}}, $pktIdx, 1; #Remove from array
|
||||
}
|
||||
|
||||
return if(!@{$hash->{sendQueue}}); #everything done
|
||||
return if(defined($responseToShutterContact)); #this was not called from InternalTimer
|
||||
InternalTimer($timeout, "CUL_MAX_SendQueueHandler", $hash, 0);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user