mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-15 04:20:56 +00:00
00_ZWCUL: add zwaveRouting (experimental)
git-svn-id: https://svn.fhem.de/fhem/trunk@10824 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
3dc1f2c5ae
commit
bd8b3f215b
@ -25,6 +25,7 @@ sub ZWCUL_Write($$$);
|
||||
sub ZWCUL_ProcessSendStack($);
|
||||
|
||||
use vars qw(%zwave_id2class);
|
||||
my %sentIdx;
|
||||
|
||||
my %sets = (
|
||||
"reopen" => { cmd=>"" },
|
||||
@ -217,6 +218,7 @@ ZWCUL_cmd($$@)
|
||||
ZWCUL_tmp9600($hash, $a[0] ? "zm9" : 0); # expect random homeId
|
||||
return;
|
||||
}
|
||||
|
||||
if($cmdName eq "removeNode") {
|
||||
delete $hash->{addNode};
|
||||
delete $hash->{removeNode};
|
||||
@ -224,6 +226,7 @@ ZWCUL_cmd($$@)
|
||||
ZWCUL_tmp9600($hash, $a[0] ? "zr9" : 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if($cmdName eq "nodeInfo") {
|
||||
my $node = ZWCUL_getNode($hash, sprintf("%02x", $a[0]));
|
||||
return "Node with decimal id $a[0] not found" if(!$node);
|
||||
@ -275,24 +278,23 @@ ZWCUL_Write($$$)
|
||||
|
||||
Log3 $hash, 5, "ZWCUL_Write $fn $msg";
|
||||
if($msg =~ m/0013(..)(..)(.*)(....)/) {
|
||||
my ($t,$l,$p) = ($1,$2,$3);
|
||||
my $th = $modules{ZWave}{defptr}{"$fn $t"};
|
||||
if(!$th) {
|
||||
Log3 $hash, 1, "ZWCUL: no device found for $fn $t";
|
||||
return;
|
||||
}
|
||||
my ($targetId,$l,$p) = ($1,$2,$3);
|
||||
my ($homeId,$route) = split(",",$fn);
|
||||
|
||||
# Do not send wakeupNoMoreInformation in monitor mode
|
||||
return if($p eq "8408" && $hash->{monitor});
|
||||
|
||||
$th->{sentIdx} = 0 if(!$th->{sentIdx} || $th->{sentIdx} == 15);
|
||||
$th->{sentIdx}++;
|
||||
$sentIdx{$targetId} = 0 if(!$sentIdx{$targetId} || $sentIdx{$targetId}==15);
|
||||
$sentIdx{$targetId}++;
|
||||
|
||||
my $s100 = ($hash->{baudRate} eq "100k");
|
||||
|
||||
$msg = sprintf("%s%s41%02x%02x%s%s",
|
||||
$fn, $hash->{nodeIdHex}, $th->{sentIdx},
|
||||
length($p)/2+($s100 ? 11 : 10), $th->{nodeIdHex}, $p);
|
||||
my $rf = 0x41;
|
||||
if($route) {
|
||||
$rf = 0x81;
|
||||
$p = sprintf("00%d0%s%s",length($route)/2, $route, $p);
|
||||
}
|
||||
|
||||
$msg = sprintf("%s%s%02x%02x%02x%s%s",
|
||||
$homeId, $hash->{nodeIdHex}, $rf, $sentIdx{$targetId},
|
||||
length($p)/2+($s100 ? 11 : 10), $targetId, $p);
|
||||
$msg .= ($s100 ? zwlib_checkSum_16($msg) : zwlib_checkSum_8($msg));
|
||||
|
||||
ZWCUL_SimpleWrite($hash, "zs".$msg);
|
||||
@ -462,21 +464,13 @@ ZWCUL_Parse($$$$$)
|
||||
return;
|
||||
}
|
||||
|
||||
if($hash->{addNode} && $T eq "ff" && $S eq "00" &&
|
||||
$P =~ m/^0101(......)(..)..(.*)/) {
|
||||
if($hash->{addNode} && $T eq "ff" && $S eq "00" && $P =~ m/^0101/) {
|
||||
ZWCUL_assignId($hash, "00", $hash->{homeIdSet}, $hash->{addNode});
|
||||
$hash->{addNodeParam} = $P;
|
||||
return;
|
||||
}
|
||||
|
||||
$rmsg = sprintf("0004%s%s%02x%s", $S, $S, length($P)/2, $P);
|
||||
my $th = $modules{ZWave}{defptr}{"$H $S"};
|
||||
|
||||
if(!($S eq $hash->{nodeIdHex} && $H eq $hash->{homeIdSet}) && !$th) {
|
||||
DoTrigger("global", "UNDEFINED ZWNode_${H}_$S ZWave $H ".hex($S));
|
||||
$th = $modules{ZWave}{defptr}{"$H $S"};
|
||||
}
|
||||
|
||||
|
||||
} else { # ACK
|
||||
if($hash->{removeNode} && $hash->{removeNode} eq $S) { #############
|
||||
@ -507,8 +501,8 @@ ZWCUL_Parse($$$$$)
|
||||
}
|
||||
|
||||
if($hash->{addNode} && $hash->{addNode} eq $S) { # Another hack
|
||||
Log3 $hash, 3, "ZWCUL node ".hex($S)." excluded from network";
|
||||
delete $hash->{removeNode};
|
||||
Log3 $hash, 3,"ZWCUL node ".hex($S)." (hex $S) included into the network";
|
||||
delete $hash->{addNode};
|
||||
ZWCUL_tmp9600($hash, 0);
|
||||
return;
|
||||
}
|
||||
@ -701,13 +695,12 @@ ZWCUL_Ready($)
|
||||
Activate (or deactivate) inclusion mode. The CUL will switch to dataRate
|
||||
9600 until terminating this mode with off, or a node is included. If onSec
|
||||
is specified, the ZWCUL networkKey ist set, and the device supports the
|
||||
SECURITY class, then a secure inclusion is attempted.
|
||||
</li>
|
||||
SECURITY class, then a secure inclusion is attempted. </li>
|
||||
|
||||
<li>addNodeId <decimalNodeId><br>
|
||||
Activate inclusion mode, and assign decimalNodeId to the next node.
|
||||
To deactivate this mode, use addNode off.
|
||||
</li>
|
||||
To deactivate this mode, use addNode off. Note: addNode won't work for a
|
||||
FHEM2FHEM:RAW attached ZWCUL, use addNodeId instead</li>
|
||||
|
||||
<li>removeNode [onNw|on|off]<br>
|
||||
Activate (or deactivate) exclusion mode. Like with addNode, the CUL will
|
||||
|
@ -36,7 +36,8 @@ my %zwave_class = (
|
||||
"..0105" => '"zwaveGetNodesInRange:noarg"',
|
||||
"..0106(.*)"=> '"zwaveNodeRangeInfo:$1"',
|
||||
"..0107(.*)"=> '"zwaveCommandComplete:$1"',
|
||||
"..010801" => '"zwaveTransferPresentation"'
|
||||
"..010801" => '"zwaveTransferPresentation"',
|
||||
"..010c(.*)"=> '"zwaveAssignRoute:$1"'
|
||||
}},
|
||||
BASIC => { id => '20',
|
||||
set => { basicValue => "01%02x",
|
||||
@ -535,10 +536,25 @@ ZWave_Initialize($)
|
||||
$hash->{GetFn} = "ZWave_Get";
|
||||
$hash->{DefFn} = "ZWave_Define";
|
||||
$hash->{UndefFn} = "ZWave_Undef";
|
||||
$hash->{AttrFn} = "ZWave_Attr";
|
||||
$hash->{ParseFn} = "ZWave_Parse";
|
||||
$hash->{AttrList} = "IODev do_not_notify:1,0 noExplorerFrames:1,0 ".
|
||||
"ignore:1,0 dummy:1,0 showtime:1,0 classes vclasses ".
|
||||
"secure_classes WNMI_delay $readingFnAttributes";
|
||||
no warnings 'qw';
|
||||
my @attrList = qw(
|
||||
IODev
|
||||
WNMI_delay
|
||||
classes
|
||||
do_not_notify:1,0
|
||||
dummy:1,0
|
||||
ignore:1,0
|
||||
noExplorerFrames:1,0
|
||||
secure_classes
|
||||
showtime:1,0
|
||||
vclasses
|
||||
zwaveRoute
|
||||
);
|
||||
use warnings 'qw';
|
||||
$hash->{AttrList} = join(" ", @attrList)." ".$readingFnAttributes;
|
||||
|
||||
map { $zwave_id2class{lc($zwave_class{$_}{id})} = $_ } keys %zwave_class;
|
||||
|
||||
$hash->{FW_detailFn} = "ZWave_fhemwebFn";
|
||||
@ -3467,7 +3483,9 @@ ZWave_wakeupTimer($$)
|
||||
my $nodeId = $hash->{nodeIdHex};
|
||||
my $cmdEf = (AttrVal($hash->{NAME},"noExplorerFrames",0)==0 ? "25":"05");
|
||||
# wakeupNoMoreInformation
|
||||
IOWrite($hash, $hash->{homeId}, "0013${nodeId}028408${cmdEf}$nodeId");
|
||||
IOWrite($hash,
|
||||
$hash->{homeId}.($hash->{route} ? ",".$hash->{route} : ""),
|
||||
"0013${nodeId}028408${cmdEf}$nodeId");
|
||||
}
|
||||
delete $hash->{wakeupAlive};
|
||||
|
||||
@ -3515,15 +3533,17 @@ ZWave_processSendStack($$)
|
||||
|
||||
$ss->[0] =~ m/^([^:]*?):(.*)$/;
|
||||
my ($type, $msg) = ($1, $2);
|
||||
IOWrite($hash, $hash->{homeId}, "00$msg");
|
||||
IOWrite($hash,
|
||||
$hash->{homeId}.($hash->{route}?",".$hash->{route}:""),
|
||||
"00$msg");
|
||||
$ss->[0] = "sent$type:$msg";
|
||||
|
||||
$hash->{lastMsgSent} = gettimeofday();
|
||||
$zwave_lastHashSent = $hash;
|
||||
|
||||
if(!ZWave_isWakeUp($hash)) {
|
||||
InternalTimer($hash->{lastMsgSent}+3, sub {
|
||||
Log 2, "ZWave: No ACK from $hash->{NAME} after 3s for $ss->[0]";
|
||||
InternalTimer($hash->{lastMsgSent}+5, sub { # zme generates NO_ACK after 4s
|
||||
Log 2, "ZWave: No ACK from $hash->{NAME} after 5s for $ss->[0]";
|
||||
ZWave_processSendStack($hash, "next");
|
||||
}, $hash, 0);
|
||||
}
|
||||
@ -3550,9 +3570,9 @@ ZWave_addToSendStack($$$)
|
||||
|
||||
} else { # clear commands without 0113 and 0013
|
||||
my $now = gettimeofday();
|
||||
if(@{$ss} > 1 && $now-$hash->{lastMsgSent} > 3) {
|
||||
if(@{$ss} > 1 && $now-$hash->{lastMsgSent} > 5) {
|
||||
Log3 $hash, 2,
|
||||
"ERROR: $hash->{NAME}: cleaning commands without ack after 3s";
|
||||
"ERROR: $hash->{NAME}: cleaning commands without ack after 5s";
|
||||
delete $hash->{SendStack};
|
||||
return ZWave_addToSendStack($hash, $type, $cmd);
|
||||
}
|
||||
@ -3884,6 +3904,46 @@ ZWave_Undef($$)
|
||||
return undef;
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
ZWave_computeRoute($;$)
|
||||
{
|
||||
my ($spec,$attrVal) = @_;
|
||||
for my $dev (devspec2array($spec)) {
|
||||
my $av = AttrVal($dev, "zwaveRoute", $attrVal);
|
||||
next if(!$av);
|
||||
|
||||
my @h;
|
||||
for my $r (split(" ", $av)) {
|
||||
if(!$defs{$r} || $defs{$r}{TYPE} ne "ZWave") {
|
||||
my $msg = "zwaveRoute: $r is not a ZWave device";
|
||||
Log 1, $msg;
|
||||
return $msg;
|
||||
}
|
||||
push(@h, $defs{$r}{nodeIdHex});
|
||||
}
|
||||
$defs{$dev}{route} = join("",@h);
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub
|
||||
ZWave_Attr(@)
|
||||
{
|
||||
my ($type, $devName, $attrName, @param) = @_;
|
||||
|
||||
if($attrName eq "zwaveRoute") {
|
||||
if($type eq "del") {
|
||||
delete $defs{$devName}{route};
|
||||
return undef;
|
||||
}
|
||||
return ZWave_computeRoute($devName,join(" ",@param)) if($init_done);
|
||||
InternalTimer(1, "ZWave_computeRoute", "TYPE=ZWave", 0);
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
#####################################
|
||||
# Show the help from the device.xml, if the correct entry is selected
|
||||
sub
|
||||
@ -4822,28 +4882,36 @@ s2Hex($)
|
||||
is in seconds, subseconds my be specified. Values outside of 0.2-5.0 are
|
||||
probably harmful.
|
||||
</li>
|
||||
<li><a href="#do_not_notify">do_not_notify</a></li>
|
||||
<li><a href="#ignore">ignore</a></li>
|
||||
<li><a href="#dummy">dummy</a></li>
|
||||
<li><a href="#showtime">showtime</a></li>
|
||||
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
|
||||
<li><a href="#classes">classes</a>
|
||||
<li><a name="classes">classes</a>
|
||||
This attribute is needed by the ZWave module, as the list of the possible
|
||||
set/get commands depends on it. It contains a space separated list of
|
||||
class names (capital letters).
|
||||
</li>
|
||||
<li><a href="#secure_classes">secure_classes</a>
|
||||
<li><a href="#do_not_notify">do_not_notify</a></li>
|
||||
<li><a href="#dummy">dummy</a></li>
|
||||
<li><a href="#ignore">ignore</a></li>
|
||||
<li><a href="#noExplorerFrames">noExplorerFrames</a>
|
||||
turn off the use of Explorer Frames
|
||||
</li>
|
||||
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
|
||||
<li><a name="secure_classes">secure_classes</a>
|
||||
This attribute is the result of the "set DEVICE secSupportedReport"
|
||||
command. It contains a space seperated list of the the command classes
|
||||
that are supported with SECURITY.
|
||||
</li>
|
||||
<li><a href="#vclasses">vclasses</a>
|
||||
<li><a href="#showtime">showtime</a></li>
|
||||
<li><a name="vclasses">vclasses</a>
|
||||
This is the result of the "get DEVICE versionClassAll" command, and
|
||||
contains the version information for each of the supported classes.
|
||||
</li>
|
||||
<li><a href="#noExplorerFrames">noExplorerFrames</a>
|
||||
turn off the use of Explorer Frames
|
||||
</li>
|
||||
|
||||
<li><a name="zwaveRoute">zwaveRoute</a>
|
||||
space separated list of (ZWave) device names. They will be used in the
|
||||
given order to route messages from the controller to this device. Specify
|
||||
them in the order from the controller to the device. Do not specify the
|
||||
controller and the device itself, only the routers inbetween. Used only
|
||||
if the IODev is a ZWCUL device. </li>
|
||||
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user