2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-08 07:24:21 +00:00

MYSENSORS: refactor handling of requestAck

git-svn-id: https://svn.fhem.de/fhem/trunk@6887 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
ntruchsess 2014-11-05 00:39:30 +00:00
parent de1e100665
commit c76081108d
2 changed files with 86 additions and 16 deletions

View File

@ -201,24 +201,38 @@ sub Init($) {
my $name = $hash->{NAME};
$hash->{'inclusion-mode'} = AttrVal($name,"autocreate",0);
$hash->{ack} = AttrVal($name,"requestAck",0);
$hash->{messages} = {};
$hash->{outstandingAck} = 0;
if ($hash->{ack}) {
GP_ForallClients($hash,sub {
my $client = shift;
$hash->{messagesForRadioId}->{$client->{radioId}} = {
lastseen => -1,
nexttry => -1,
numtries => 1,
messages => [],
};
});
}
readingsSingleUpdate($hash,"connection","connected",1);
Timer($hash);
return undef;
}
sub Timer($) {
my $hash = shift;
RemoveInternalTimer($hash);
my $now = time;
foreach my $msg (keys %{$hash->{messages}}) {
if ($now > $hash->{messages}->{$msg}) {
Log3 ($hash->{NAME},5,"MYSENSORS outstanding ack, re-send: ".$msg);
DevIo_SimpleWrite($hash,"$msg\n", undef);
foreach my $radioid (keys %{$hash->{messagesForRadioId}}) {
my $msgsForId = $hash->{messagesForRadioId}->{$radioid};
if ($now > $msgsForId->{nexttry}) {
foreach my $msg (@{$msgsForId->{messages}}) {
my $txt = createMsg(%$msg);
Log3 ($hash->{NAME},5,"MYSENSORS outstanding ack, re-send: ".dumpMsg($msg));
DevIo_SimpleWrite($hash,"$txt\n",undef);
}
$msgsForId->{numtries}++;
$msgsForId->{nexttry} = gettimeofday()+$msgsForId->{numtries};
}
}
InternalTimer(gettimeofday()+1, "MYSENSORS::Timer", $hash, 0);
_scheduleTimer($hash);
}
sub Read {
@ -240,8 +254,7 @@ sub Read {
Log3 ($name,5,"MYSENSORS Read: ".dumpMsg($msg));
if ($msg->{ack}) {
delete $hash->{messages}->{$txt};
$hash->{outstandingAck} = keys %{$hash->{messages}};
onAcknowledge($hash,$msg);
}
my $type = $msg->{cmd};
@ -371,6 +384,25 @@ sub onStreamMsg($$) {
my ($hash,$msg) = @_;
};
sub onAcknowledge($$) {
my ($hash,$msg) = @_;
my $ack;
if (defined (my $outstanding = $hash->{messagesForRadioId}->{$msg->{radioId}}->{messages})) {
my @remainMsg = grep {
$_->{childId} != $msg->{childId}
or $_->{cmd} != $msg->{cmd}
or $_->{subType} != $msg->{subType}
or $_->{payload} ne $msg->{payload}
} @$outstanding;
if ($ack = @remainMsg < @$outstanding) {
$hash->{outstandingAck} -= 1;
@$outstanding = @remainMsg;
}
$hash->{messagesForRadioId}->{$msg->{radioId}}->{numtries} = 1;
}
Log3 ($hash->{NAME},4,"MYSENSORS Read: unexpected ack ".dumpMsg($msg)) unless $ack;
}
sub sendMessage($%) {
my ($hash,%msg) = @_;
$msg{ack} = $hash->{ack} unless $msg{ack};
@ -378,11 +410,41 @@ sub sendMessage($%) {
Log3 ($hash->{NAME},5,"MYSENSORS send: ".dumpMsg(\%msg));
DevIo_SimpleWrite($hash,"$txt\n",undef);
if ($msg{ack}) {
$hash->{messages}->{$txt} = gettimeofday() + 1,
$hash->{outstandingAck} = keys %{$hash->{messages}};
my $messagesForRadioId = $hash->{messagesForRadioId}->{$msg{radioId}};
unless (defined $messagesForRadioId) {
$messagesForRadioId = {
lastseen => -1,
numtries => 1,
messages => [],
};
$hash->{messagesForRadioId}->{$msg{radioId}} = $messagesForRadioId;
}
my $messages = $messagesForRadioId->{messages};
@$messages = grep {
$_->{childId} != $msg{childId}
or $_->{cmd} != $msg{cmd}
or $_->{subType} != $msg{subType}
} @$messages;
push @$messages,\%msg;
$messagesForRadioId->{nexttry} = gettimeofday()+$messagesForRadioId->{numtries};
_scheduleTimer($hash);
}
};
sub _scheduleTimer($) {
my ($hash) = @_;
$hash->{outstandingAck} = 0;
RemoveInternalTimer($hash);
my $next;
foreach my $radioid (keys %{$hash->{messagesForRadioId}}) {
my $msgsForId = $hash->{messagesForRadioId}->{$radioid};
$hash->{outstandingAck} += @{$msgsForId->{messages}};
$next = $msgsForId->{nexttry} unless (defined $next and $next < $msgsForId->{nexttry});
};
InternalTimer($next, "MYSENSORS::Timer", $hash, 0) if (defined $next);
}
sub matchClient($$) {
my ($hash,$msg) = @_;
my $radioId = $msg->{radioId};

View File

@ -437,8 +437,12 @@ sub onInternalMessage($$) {
last;
};
$type == I_TIME and do {
sendClientMessage($hash,cmd => C_INTERNAL, childId => 255, subType => I_TIME, payload => time);
Log3 ($name,4,"MYSENSORS_DEVICE $name: update of time requested");
if ($msg->{ack}) {
Log3 ($name,4,"MYSENSORS_DEVICE $name: respons to time-request acknowledged");
} else {
sendClientMessage($hash,cmd => C_INTERNAL, childId => 255, subType => I_TIME, payload => time);
Log3 ($name,4,"MYSENSORS_DEVICE $name: update of time requested");
}
last;
};
$type == I_VERSION and do {
@ -458,8 +462,12 @@ sub onInternalMessage($$) {
last;
};
$type == I_CONFIG and do {
sendClientMessage($hash,cmd => C_INTERNAL, childId => 255, subType => I_CONFIG, payload => AttrVal($name,"config","M"));
Log3 ($name,4,"MYSENSORS_DEVICE $name: respond to config-request");
if ($msg->{ack}) {
Log3 ($name,4,"MYSENSORS_DEVICE $name: respons to config-request acknowledged");
} else {
sendClientMessage($hash,cmd => C_INTERNAL, childId => 255, subType => I_CONFIG, payload => AttrVal($name,"config","M"));
Log3 ($name,4,"MYSENSORS_DEVICE $name: respond to config-request");
}
last;
};
$type == I_PING and do {