MYSENSORS: Add logic to identify channel76 GW

MYSENSORS_DEVICE: bugfix for sleeping nodes (Forum #96518)


git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@18426 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
Beta-User 2019-01-26 16:49:32 +00:00
parent 9a2b13cf9a
commit 1db23df68e
2 changed files with 45 additions and 19 deletions

View File

@ -3,6 +3,7 @@
# fhem driver for MySensors serial or network gateway (see http://mysensors.org) # fhem driver for MySensors serial or network gateway (see http://mysensors.org)
# #
# Copyright (C) 2014 Norbert Truchsess # Copyright (C) 2014 Norbert Truchsess
# Copyright (C) 2019 Hauswart@forum.fhem.de
# #
# This file is part of fhem. # This file is part of fhem.
# #
@ -236,17 +237,17 @@ sub Init($) {
# GetConnectStatus # GetConnectStatus
sub GetConnectStatus($){ sub GetConnectStatus($){
my ($hash) = @_; my ($hash) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
Log3 $name, 4, "MySensors: GetConnectStatus called ..."; Log3 $name, 4, "MySensors: GetConnectStatus called ...";
#query heartbeat from gateway #query heartbeat from gateway
sendMessage($hash, radioId => 0, childId => 0, cmd => C_INTERNAL, ack => 0, subType => I_HEARTBEAT_REQUEST, payload => ''); sendMessage($hash, radioId => 0, childId => 0, cmd => C_INTERNAL, ack => 0, subType => I_HEARTBEAT_REQUEST, payload => '');
# neuen Timer starten in einem konfigurierten Interval. # neuen Timer starten in einem konfigurierten Interval.
InternalTimer(gettimeofday()+300, "MYSENSORS::GetConnectStatus", $hash);# Restart check in 5 mins again InternalTimer(gettimeofday()+300, "MYSENSORS::GetConnectStatus", $hash);# Restart check in 5 mins again
InternalTimer(gettimeofday()+5, "MYSENSORS::Start", $hash); #Start timer for reset if after 5 seconds RESPONSE is not received InternalTimer(gettimeofday()+5, "MYSENSORS::Start", $hash); #Start timer for reset if after 5 seconds RESPONSE is not received
} }
sub Timer($) { sub Timer($) {
@ -288,8 +289,8 @@ sub Read {
onAcknowledge($hash,$msg); onAcknowledge($hash,$msg);
} }
RemoveInternalTimer($hash,"MYSENSORS::GetConnectStatus"); RemoveInternalTimer($hash,"MYSENSORS::GetConnectStatus");
InternalTimer(gettimeofday()+300, "MYSENSORS::GetConnectStatus", $hash);# Restart check in 5 mins again InternalTimer(gettimeofday()+300, "MYSENSORS::GetConnectStatus", $hash);# Restart check in 5 mins again
my $type = $msg->{cmd}; my $type = $msg->{cmd};
MESSAGE_TYPE: { MESSAGE_TYPE: {
$type == C_PRESENTATION and do { $type == C_PRESENTATION and do {
@ -384,8 +385,8 @@ sub onInternalMsg($$) {
last; last;
}; };
$type == I_HEARTBEAT_RESPONSE and do { $type == I_HEARTBEAT_RESPONSE and do {
RemoveInternalTimer($hash,"MYSENSORS::Start"); ## Reset reconnect because timeout was not reached RemoveInternalTimer($hash,"MYSENSORS::Start"); ## Reset reconnect because timeout was not reached
readingsSingleUpdate($hash, "heartbeat", "last", 0); readingsSingleUpdate($hash, "heartbeat", "last", 0);
}; };
$type == I_VERSION and do { $type == I_VERSION and do {
$hash->{version} = $msg->{payload}; $hash->{version} = $msg->{payload};
@ -417,6 +418,9 @@ sub onInternalMsg($$) {
} }
} elsif (my $client = matchClient($hash,$msg)) { } elsif (my $client = matchClient($hash,$msg)) {
MYSENSORS::DEVICE::onInternalMessage($client,$msg); MYSENSORS::DEVICE::onInternalMessage($client,$msg);
} elsif ($client = matchChan76GWClient($hash,$msg)) {
Log3($hash->{NAME}, 4, "$hash->{NAME}: received stream message for $client - Chan76-IODev");
MYSENSORS::DEVICE::onInternalMessage($client,$msg);
} else { } else {
Log3($hash->{NAME},3,"MYSENSORS: ignoring internal-msg from unknown radioId $msg->{radioId}, childId $msg->{childId} for ".internalMessageTypeToStr($msg->{subType})); Log3($hash->{NAME},3,"MYSENSORS: ignoring internal-msg from unknown radioId $msg->{radioId}, childId $msg->{childId} for ".internalMessageTypeToStr($msg->{subType}));
} }
@ -424,12 +428,17 @@ sub onInternalMsg($$) {
sub onStreamMsg($$) { sub onStreamMsg($$) {
my ($hash,$msg) = @_; my ($hash,$msg) = @_;
if (my $client = matchClient($hash, $msg)) { my $client;
if ($client = matchClient($hash, $msg)) {
Log3($hash->{NAME}, 4, "$hash->{NAME}: received stream message for $client - regular IODev");
MYSENSORS::DEVICE::onStreamMessage($client, $msg); MYSENSORS::DEVICE::onStreamMessage($client, $msg);
} elsif ($client = matchChan76GWClient($hash,$msg)) {
Log3($hash->{NAME}, 4, "$hash->{NAME}: received stream message for $client - Chan76-IODev");
MYSENSORS::DEVICE::onStreamMessage($client,$msg);
} else { } else {
Log3($hash->{NAME},3,"MYSENSORS: ignoring stream-msg from unknown radioId $msg->{radioId}, childId $msg->{childId} for ".datastreamTypeToStr($msg->{subType})); Log3($hash->{NAME},3,"MYSENSORS: ignoring stream-msg from unknown radioId $msg->{radioId}, childId $msg->{childId} for ".datastreamTypeToStr($msg->{subType}));
} }
}; }
sub onAcknowledge($$) { sub onAcknowledge($$) {
my ($hash,$msg) = @_; my ($hash,$msg) = @_;
@ -562,6 +571,24 @@ sub matchClient($$) {
return $found; return $found;
} }
sub matchChan76GWClient($$) {
my ($hash,$msg) = @_;
my $radioId = $msg->{radioId};
my $found;
foreach my $d ( sort keys %main::defs ) {
if ( defined( $main::defs{$d} )
&& defined( $main::defs{$d}{radioId} )
&& $main::defs{$d}{radioId} == $radioId ) {
my $clientname = $main::defs{$d}->{NAME};
my $name = $hash->{NAME};
$found = $main::defs{$d} if AttrVal($clientname,"OTA_Chan76_IODev","") eq $name;
}
}
Log3($hash->{NAME}, 4, "$hash->{NAME}: matched firmware config request to hash $found, name: $found->{NAME}") if $found;
return $found if $found;
return undef;
}
1; 1;
=pod =pod

View File

@ -765,11 +765,10 @@ sub onInternalMessage($$) {
last; last;
}; };
$type == I_SKETCH_NAME and do { $type == I_SKETCH_NAME and do {
#$hash->{$typeStr} = $msg->{payload};
readingsSingleUpdate($hash, "state", "received presentation", 1) unless ($hash->{STATE} eq "received presentation"); readingsSingleUpdate($hash, "state", "received presentation", 1) unless ($hash->{STATE} eq "received presentation");
readingsSingleUpdate($hash, "SKETCH_NAME", $msg->{payload}, 1); readingsSingleUpdate($hash, "SKETCH_NAME", $msg->{payload}, 1);
#undef $hash->{FW_DATA}; # enable this to free memory?
delete $hash->{FW_DATA} if (defined $hash->{FW_DATA}); delete $hash->{FW_DATA} if (defined $hash->{FW_DATA});
$hash->{nowSleeping} = 0 if $hash->{nowSleeping};
if (defined $hash->{getCommentReadings}){ if (defined $hash->{getCommentReadings}){
if ($hash->{getCommentReadings} eq "1") { if ($hash->{getCommentReadings} eq "1") {
$hash->{getCommentReadings} = 2 ; $hash->{getCommentReadings} = 2 ;
@ -777,6 +776,7 @@ sub onInternalMessage($$) {
delete $hash->{getCommentReadings}; delete $hash->{getCommentReadings};
} }
} }
Log3 $name, 3, "leaving Sketch Name update";
last; last;
}; };
$type == I_SKETCH_VERSION and do { $type == I_SKETCH_VERSION and do {
@ -896,7 +896,6 @@ sub onInternalMessage($$) {
#$hash->{$typeStr} = $msg->{payload}; #$hash->{$typeStr} = $msg->{payload};
refreshInternalMySTimer($hash,"Asleep"); refreshInternalMySTimer($hash,"Asleep");
refreshInternalMySTimer($hash,"Alive") if $hash->{timeoutAlive}; refreshInternalMySTimer($hash,"Alive") if $hash->{timeoutAlive};
#here we send out retained and outstanding messages
MYSENSORS::Timer($hash); MYSENSORS::Timer($hash);
my $retainedMsg; my $retainedMsg;
while (ref ($retainedMsg = shift @{$hash->{retainedMessagesForRadioId}->{messages}}) eq 'HASH') { while (ref ($retainedMsg = shift @{$hash->{retainedMessagesForRadioId}->{messages}}) eq 'HASH') {
@ -1070,7 +1069,7 @@ sub flashFirmware($$) {
} else { } else {
return "Nothing todo - latest firmware already installed"; return "Nothing todo - latest firmware already installed";
} }
} }
} }
sub refreshInternalMySTimer($$) { sub refreshInternalMySTimer($$) {
@ -1089,7 +1088,7 @@ sub refreshInternalMySTimer($$) {
RemoveInternalTimer("timeoutAck:$name"); RemoveInternalTimer("timeoutAck:$name");
my $nextTrigger = main::gettimeofday() + $hash->{timeoutAck}; my $nextTrigger = main::gettimeofday() + $hash->{timeoutAck};
InternalTimer($nextTrigger, "MYSENSORS::DEVICE::timeoutMySTimer", "timeoutAck:$name", 0); InternalTimer($nextTrigger, "MYSENSORS::DEVICE::timeoutMySTimer", "timeoutAck:$name", 0);
Log3 $name, 4, "$name: Ack timeout timer set at $nextTrigger"; Log3 $name, 5, "$name: Ack timeout timer set at $nextTrigger";
} elsif ($calltype eq "Asleep") { } elsif ($calltype eq "Asleep") {
RemoveInternalTimer("timeoutAwake:$name"); RemoveInternalTimer("timeoutAwake:$name");
#0.5 is default; could be dynamized by attribute if needed #0.5 is default; could be dynamized by attribute if needed