From d215e35563d62238a10fd85dc1c08d3272360968 Mon Sep 17 00:00:00 2001
From: rudolfkoenig <>
Date: Sun, 4 Oct 2015 15:30:23 +0000
Subject: [PATCH] 10_ZWave.pm: neighborList/neighborUpdate moved to ZWave from
ZWDongle (Forum #41701)
git-svn-id: https://svn.fhem.de/fhem/trunk@9371 2b470e98-0d58-463d-a4d8-8e2adae1ed80
---
fhem/FHEM/00_ZWDongle.pm | 26 ---------------
fhem/FHEM/10_ZWave.pm | 71 ++++++++++++++++++++++++++++++++++++----
2 files changed, 64 insertions(+), 33 deletions(-)
diff --git a/fhem/FHEM/00_ZWDongle.pm b/fhem/FHEM/00_ZWDongle.pm
index 9da39a01f..5231936e6 100755
--- a/fhem/FHEM/00_ZWDongle.pm
+++ b/fhem/FHEM/00_ZWDongle.pm
@@ -32,7 +32,6 @@ my %sets = (
"createNode" => { cmd => "60%02x" }, # ZW_REQUEST_NODE_INFO'
"removeFailedNode" => { cmd => "61%02x@" }, # ZW_REMOVE_FAILED_NODE_ID
"replaceFailedNode"=> { cmd => "63%02x@" }, # ZW_REPLACE_FAILED_NODE
- "neighborUpdate" => { cmd => "48%02x" }, # ZW_REQUEST_NODE_NEIGHBOR_UPDATE
"sendNIF" => { cmd => "12%02x05@" },# ZW_SEND_NODE_INFORMATION
"setNIF" => { cmd => "03%02x%02x%02x%02x" },
# SERIAL_API_APPL_NODE_INFORMATION
@@ -46,8 +45,6 @@ my %gets = (
"getVirtualNodes" => "a5", # ZW_GET_VIRTUAL_NODES
"homeId" => "20", # MEMORY_GET_ID
"isFailedNode" => "62%02x", # ZW_IS_FAILED_NODE
- "neighborList" => "80%02x0101", # GET_ROUTING_TABLE_LINE include dead links,
- # include non-routing neigbors
"nodeInfo" => "41%02x", # ZW_GET_NODE_PROTOCOL_INFO
"nodeList" => "02", # SERIAL_API_GET_INIT_DATA
"random" => "1c%02x", # ZW_GET_RANDOM
@@ -428,17 +425,6 @@ ZWDongle_Get($@)
$msg = join(" ", @list);
}
- } elsif($type eq "neighborList") { ############################
- return "$name: Bogus data received" if(int(@r) != 31);
- my @list;
- for my $byte (0..28) {
- my $bits = $r[2+$byte];
- for my $bit (0..7) {
- push @list, $byte*8+$bit+1 if($bits & (1<<$bit));
- }
- }
- $msg = join(",", @list);
-
} elsif($type eq "random") { ############################
return "$name: Cannot generate" if($ret !~ m/^011c01(..)(.*)$/);
$msg = $2; @a = ();
@@ -874,13 +860,6 @@ ZWDongle_Ready($)
device upon reception of the answer. Used for previously included nodes,
see the nodeList get command below.
-
neighborUpdate
- Requests controller to update his routing table which is based on
- slave's neighbor list. The update may take significant time to complete.
- With the event "done" or "failed" ZWDongle will notify the end of the
- update process. To read node's neighbor list see neighborList get
- below.
-
removeFailedNode
Remove a non-responding node -that must be on the failed Node list- from
the routing table in controller. Instead,always use removeNode if possible.
@@ -917,11 +896,6 @@ ZWDongle_Ready($)
nodeInfo
return node specific information. Needed by developers only.
- neighborList id
- returns the list of neighbor nodeIds of specified node.
- Provides insights to actual network topology.
- List includes dead links and non-routing neighbors
-
random N
request N random bytes from the controller.
diff --git a/fhem/FHEM/10_ZWave.pm b/fhem/FHEM/10_ZWave.pm
index 9bf5df226..47d21c8e1 100755
--- a/fhem/FHEM/10_ZWave.pm
+++ b/fhem/FHEM/10_ZWave.pm
@@ -590,9 +590,17 @@ ZWave_Cmd($$@)
my $id = $hash->{nodeIdHex};
my $isMc = ($id =~ m/(....)/);
- if($type eq "set" && !$isMc) {
- $cmdList{neighborUpdate}{fmt} = "48$id";
- $cmdList{neighborUpdate}{id} = "";
+ if(!$isMc) {
+ if($type eq "set") {
+ $cmdList{neighborUpdate}{fmt} = "48$id";
+ $cmdList{neighborUpdate}{id} = "";
+ }
+ if($type eq "get") {
+ # GET_ROUTING_TABLE_LINE, include dead links, non-routing neigbors
+ $cmdList{neighborList}{fmt} = "80${id}0101";
+ $cmdList{neighborList}{id} = "";
+ $cmdList{neighborList}{regexp} = "^0180";
+ }
}
if($type eq "set" && $cmd eq "rgb") {
@@ -686,17 +694,18 @@ ZWave_Cmd($$@)
my $data;
- if($cmd eq "neighborUpdate") {
+ if($cmd eq "neighborUpdate" ||
+ $cmd eq "neighborList") {
$data = $cmdFmt;
} else {
my $len = sprintf("%02x", length($cmdFmt)/2+1);
my $cmdEf = (AttrVal($name, "noExplorerFrames", 0) == 0 ? "25" : "05");
$data = "13$id$len$cmdId${cmdFmt}$cmdEf"; # 13==SEND_DATA
+ $data .= $id; # callback=>id
}
- $data .= $id; # callback=>id
if ($data =~ m/(......)(....)(.*)(....)/) {
my $cc_cmd=$2;
@@ -721,10 +730,14 @@ ZWave_Cmd($$@)
no strict "refs";
my $iohash = $hash->{IODev};
my $fn = $modules{$iohash->{TYPE}}{ReadAnswerFn};
- my ($err, $data) = &{$fn}($iohash, $cmd, "^000400${id}..$cmdId") if($fn);
+ my $re = $cmdList{$cmd}{regexp};
+ my ($err, $data) = &{$fn}($iohash, $cmd, $re ? $re : "^000400${id}..$cmdId")
+ if($fn);
use strict "refs";
return $err if($err);
+ $data = "$cmd $id $data" if($re);
+
$val = ($data ? ZWave_Parse($iohash, $data, $type) : "no data returned");
} else {
@@ -2468,7 +2481,8 @@ ZWave_addToSendStack($$)
push @{$ss}, $cmd;
if(ZWave_isWakeUp($hash)) {
- if ($cmd =~ m/^......988[01].*/) {
+ # SECURITY XXX and neighborList
+ if ($cmd =~ m/^......988[01].*/ || $cmd =~ m/^80..0101$/) {
Log3 $hash->{NAME}, 5, "$hash->{NAME}: Sendstack bypassed for $cmd";
} else {
return "Scheduled for sending after WAKEUP" if(!$hash->{wakeupAlive});
@@ -2504,6 +2518,35 @@ ZWave_Parse($$@)
return "";
}
+ if($msg =~ m/^neighborList (..) 0180(.*)$/) {
+ my ($id, $data) = ($1, $2);
+ my $hash = $modules{ZWave}{defptr}{"$homeId $id"};
+ my $name = ($hash ? $hash->{NAME} : "unknown");
+
+ my @r = map { ord($_) } split("", pack('H*', $data));
+ return "Bogus answer: $msg" if(int(@r) != 29);
+
+ my @list;
+ my $ioId = ReadingsVal($ioName, "homeId", "");
+ $ioId = $1 if($ioId =~ m/CtrlNodeId:(..)/);
+ for my $byte (0..28) {
+ my $bits = $r[$byte];
+ for my $bit (0..7) {
+ if($bits & (1<<$bit)) {
+ my $dec = $byte*8+$bit+1;
+ my $hex = sprintf("%02x", $dec);
+ my $h = $modules{ZWave}{defptr}{"$homeId $hex"};
+ push @list, ($hex eq $ioId ? $ioName :
+ ($h ? $h->{NAME} : "UNKNOWN_$dec"));
+ }
+ }
+ }
+ $msg = @list ? join(",", @list) : "empty";
+ readingsSingleUpdate($hash, "neighborList", $msg, 1) if($hash);
+ return $msg if($srcCmd);
+ return "";
+ }
+
if($msg =~ m/^01(..)(..*)/) { # 01==ANSWER from the ZWDongle
my ($cmd, $arg) = ($1, $2);
$cmd = $zw_func_id{$cmd} if($zw_func_id{$cmd});
@@ -2907,6 +2950,14 @@ s2Hex($)
Note: devices with on/off functionality support the set extensions.
+
All
+ neighborUpdate
+ Requests controller to update his routing table which is based on
+ slave's neighbor list. The update may take significant time to complete.
+ With the event "done" or "failed" ZWDongle will notify the end of the
+ update process. To read node's neighbor list see neighborList get
+ below.
+
Class ASSOCIATION
associationAdd groupId nodeId ...
Add the specified list of nodeIds to the assotion group groupId.
Note:
@@ -3161,6 +3212,12 @@ s2Hex($)
Get
+
All
+ - neighborList
+ returns the list of neighbors. Provides insights to actual network
+ topology. List includes dead links and non-routing neighbors.
+ Since this information is stored in the dongle, the information will be
+ returned directly even for WAKE_UP devices.
Class ALARM
- alarm alarmId