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