2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-10 09:16:53 +00:00

ZWDongle/ZWave: SUC+DOC Patch from krikan (Forum #53066)

git-svn-id: https://svn.fhem.de/fhem/trunk@11477 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2016-05-18 07:11:24 +00:00
parent e2b193bc4b
commit 0c50026378
2 changed files with 194 additions and 158 deletions

View File

@ -45,7 +45,7 @@ my %sets = (
"sendNIF" => { cmd => "12%02x05@" },# ZW_SEND_NODE_INFORMATION
"setNIF" => { cmd => "03%02x%02x%02x%02x" },
# SERIAL_API_APPL_NODE_INFORMATION
"sucNodeId" => { cmd => "54%02x%02x25%02x@"},
"sucNodeId" => { cmd => "54%02x%02x00%02x@"},
# ZW_SET_SUC_NODE_ID
"timeouts" => { cmd => "06%02x%02x" }, # SERIAL_API_SET_TIMEOUTS
);
@ -114,7 +114,7 @@ ZWDongle_Define($$)
if($dev =~ m/none:(.*)/) {
$hash->{homeId} = $1;
Log3 $name, 1,
Log3 $name, 1,
"$name device is none (homeId:$1), commands will be echoed only";
$attr{$name}{dummy} = 1;
readingsSingleUpdate($hash, "state", "dummy", 1);
@ -138,10 +138,10 @@ ZWDongle_Define($$)
#####################################
sub
ZWDongle_Undef($$)
ZWDongle_Undef($$)
{
my ($hash,$arg) = @_;
DevIo_CloseDev($hash);
DevIo_CloseDev($hash);
return undef;
}
@ -223,7 +223,7 @@ ZWDongle_Set($@)
close(IN);
return "Restored $l bytes from $fName";
}
if($type eq "factoryReset") {
return "Reset to default is not supported by this device"
if(ReadingsVal($name, "caps","") !~ m/ZW_SET_DEFAULT/);
@ -309,7 +309,7 @@ ZWDongle_Get($@)
ReadingsVal($name, "caps","") !~ m/\b$zw_func_id{$fb}\b/) {
return "$cmd is unsupported by this controller";
}
if($cmd eq "raw") {
if($a[0] =~ s/^42//) {
Log3 $hash, 4, "ZWDongle *** get $name $cmd 42".join(" ",@a)." blocked";
@ -376,7 +376,7 @@ ZWDongle_Get($@)
$msg .= " ".join(" ",@list);
} elsif($cmd eq "homeId") { ############################
$msg = sprintf("HomeId:%s CtrlNodeIdHex:%s",
$msg = sprintf("HomeId:%s CtrlNodeIdHex:%s",
substr($ret,4,8), substr($ret,12,2));
$hash->{homeId} = substr($ret,4,8);
$hash->{nodeIdHex} = substr($ret,12,2);
@ -512,9 +512,9 @@ ZWDongle_ProcessSendStack($)
#Log3 $hash, 1, "ZWDongle_ProcessSendStack: ".@{$hash->{SendStack}}.
# " items on stack, waitForAck ".$hash->{WaitForAck};
RemoveInternalTimer($hash);
RemoveInternalTimer($hash);
my $ts = gettimeofday();
my $ts = gettimeofday();
if($hash->{WaitForAck}){
if($hash->{WaitForAck} == 1 && $ts-$hash->{SendTime} >= 1) {
@ -736,7 +736,7 @@ ZWDongle_Parse($$$)
{
my ($hash, $name, $rmsg) = @_;
if(!defined($hash->{STATE}) ||
if(!defined($hash->{STATE}) ||
ReadingsVal($name, "state", "") ne "Initialized"){
Log3 $hash, 4,"ZWDongle_Parse $rmsg: dongle not yet initialized";
return;
@ -747,7 +747,7 @@ ZWDongle_Parse($$$)
$hash->{RAWMSG} = $rmsg;
$hash->{SendTime}-- # Retry sending after a "real" msg from the dongle
if($hash->{GotCAN} && $rmsg !~ m/^(0113|0013)/);
if($hash->{GotCAN} && $rmsg !~ m/^(0113|0013)/);
my %addvals = (RAWMSG => $rmsg);
@ -786,7 +786,7 @@ ZWDongle_Attr($$$$)
return;
}
return undef;
return undef;
}
@ -851,7 +851,7 @@ ZWDongle_Ready($)
<b>Set</b>
<ul>
<li>addNode &lt;on|onNw|onSec|onNwSec|off&gt;<br>
<li>addNode on|onNw|onSec|onNwSec|off<br>
Activate (or deactivate) inclusion mode. The controller (i.e. the dongle)
will accept inclusion (i.e. pairing/learning) requests only while in this
mode. After activating inclusion mode usually you have to press a switch
@ -863,7 +863,7 @@ ZWDongle_Ready($)
device supports the SECURITY class, then a secure inclusion is attempted.
</li>
<li>backupCreate &lt;64k|128k|256k&gt;<br>
<li>backupCreate 64k|128k|256k<br>
read out the NVRAM of the ZWDongle, and store it in a file called
&lt;ZWDongle_Name&gt;.bin in the modpath folder. Since the size of the
NVRAM is currently unknown to FHEM, you have to specify the size. The
@ -876,49 +876,56 @@ ZWDongle_Ready($)
Restore the file created by backupCreate. Restoring the file takes about
the same time as saving it, and FHEM is blocked during this time.
</li>
<li>controllerChange &lt;on|stop|stopFailed&gt;<br>
<li>controllerChange on|stop|stopFailed<br>
Add a controller to the current network and transfer role as primary to it.
Invoking controller is converted to secondary.
&lt;stop&gt; = stop controllerChange
&lt;stopFailed&gt; = stop controllerChange and report an error</li>
<li>createNewPrimary &lt;on|stop|stopFailed&gt;<br>
Add a controller to the current network as a replacement for an old
primary. Command can be invoked only by a secondary configured as basic SUC
&lt;stop&gt; = stop controllerChange
&lt;stopFailed&gt; = stop controllerChange and report an error</li>
Invoking controller is converted to secondary.<br>
stop: stop controllerChange<br>
stopFailed: stop controllerChange and report an error
</li>
<li>createNewPrimary on|stop|stopFailed<br>
Add a controller to the current network as a replacement for an old
primary. Command can be invoked only by a secondary configured as basic
SUC<br>
stop: stop createNewPrimary<br>
stopFailed: stop createNewPrimary and report an error
</li>
<li>createNode &lt;decimal nodeId&gt;<br>
Request the class information for the specified node, and create a FHEM
device upon reception of the answer. Used to create FHEM devices for nodes
included with another software or if the fhem.cfg got lost. For the node id
see the get nodeList command below. Note: the node must be "alive", i.e.
for battery based devices you have to press the "wakeup" button 1-2 seconds
before entering this command in FHEM.</li>
Request the class information for the specified node, and create
a FHEM device upon reception of the answer. Used to create FHEM devices for
nodes included with another software or if the fhem.cfg got lost. For the
node id see the get nodeList command below. Note: the node must be "alive",
i.e. for battery based devices you have to press the "wakeup" button 1-2
seconds before entering this command in FHEM.
</li>
<li>factoryReset &lt;yes&gt;<br>
<li>factoryReset yes<br>
Reset controller to default state.
Erase all node and routing infos, assign a new random homeId.
To control a device it must be re-included and re-configured.
!Use this with care AND only if You know what You do!
Note: the corresponding FHEM devices have to be deleted manually.</li>
<li>learnMode &lt;on|onNw|disable&gt;<br>
To control a device it must be re-included and re-configured.<br>
!Use this with care AND only if You know what You do!<br>
Note: the corresponding FHEM devices have to be deleted manually.
</li>
<li>learnMode on|onNw|disable<br>
Add or remove controller to/from an other network.
Assign a homeId, nodeId and receive/store nodeList and routing infos.
</li>
<li>removeFailedNode &lt;decimal nodeId&gt;<br>
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.
Note: the corresponding FHEM device have to be deleted manually.</li>
</li>
<li>removeNode &lt;onNw|on|off&gt;<br>
Activate (or deactivate) exclusion mode. "on" activates standard exclusion.
<li>removeFailedNode &lt;decimal nodeId&gt;<br>
Remove non-responding node -that must be on the failed node list-
from the routing table in controller. Instead, always use removeNode if
possible. Note: the corresponding FHEM device have to be deleted manually.
</li>
<li>removeNode onNw|on|off<br>
Activate (or deactivate) exclusion mode. "on" activates standard exclusion.
"onNw" activates network wide exclusion (only SDK 4.5-4.9, SDK 6.x and
above). Note: the corresponding FHEM device have to be deleted
manually.</li>
manually.
</li>
<li>reopen<br>
First close and then open the device. Used for debugging purposes.
@ -927,12 +934,14 @@ ZWDongle_Ready($)
<li>replaceFailedNode &lt;decimal nodeId&gt;<br>
Replace a non-responding node with a new one. The non-responding node
must be on the failed node list.</li>
<li>sucNodeId &lt;decimal nodeId&gt; &lt;sucState&gt; &lt;capabilities><br>
Configure a controller Node to be a SUC/SIS or not.
&lt;nodeId&gt; to be SUC/SIS
&lt;sucState&gt; 0 = deactivate; 1 = activate
&lt;capabilities&gt; 0 = basic SUC; 1 = SIS</li>
<li>sucNodeId &lt;decimal nodeId&gt; &lt;sucState&gt;
&lt;capabilities&gt;<br>
&lt;Configure a controller node to be a SUC/SIS or not.<br>
&lt;nodeId&gt;: decimal nodeId to be SUC/SIS<br>
&lt;sucState&gt;: 0 = deactivate; 1 = activate<br>
&lt;capabilities&gt;: 0 = basic SUC; 1 = SIS
</li>
</ul>
<br>
@ -941,40 +950,47 @@ ZWDongle_Ready($)
<b>Get</b>
<ul>
<li>homeId<br>
return the six hex-digit homeId of the controller.</li>
return the six hex-digit homeId of the controller.
</li>
<li>isFailedNode &lt;decimal nodeId&gt;<br>
return if a node is stored in the failed node list.</li>
return if a node is stored in the failed node list.
</li>
<li>caps, ctrlCaps, version<br>
return different controller specific information. Needed by developers
only. </li>
only.
</li>
<li>neighborList [excludeDead] [onlyRep] &lt;decimal nodeId&gt;<br>
return data for the decimal nodeId.<br>
return neighborList of the decimal nodeId.<br>
With onlyRep the result will include only nodes with repeater
functionality.
</li>
<li>nodeInfo &lt;decimal nodeId&gt;<br>
return node specific information. Needed by developers only.</li>
return node specific information.
Needed by developers only.
</li>
<li>nodeList<br>
return the list of included nodenames or UNKNOWN_id, if there is no
corresponding device in FHEM. Can be used to recreate FHEM-nodes with the
createNode command.</li>
return the list of included nodenames or UNKNOWN_id (decimal id), if there
is no corresponding device in FHEM. Can be used to recreate FHEM-nodes with
the createNode command.
</li>
<li>random &lt;N&gt;<br>
request &lt;N&gt; random bytes from the controller.
</li>
<li>raw &lt;hex&gt;<br>
Send raw data &lt;hex&gt; to the controller. Developer only.</li>
<li>sucNodeId<br>
return the currently registered decimal SUC node ID.
Send raw data &lt;hex&gt; to the controller. Developer only.
</li>
<li>sucNodeId<br>
return the currently registered decimal SUC nodeId.
</li>
</ul>
<br>
@ -997,37 +1013,48 @@ ZWDongle_Ready($)
<a name="ZWDongleevents"></a>
<b>Generated events:</b>
<ul>
<li>UNDEFINED ZWave_${type6}_$id ZWave $homeId $id $classes"
</li>
<br><b>General</b>
<li>UNDEFINED ZWave_${type6}_$id ZWave $homeId $id $classes"</li>
<br><b>addNode</b>
<li>ZW_ADD_NODE_TO_NETWORK [learnReady|nodeFound|slave|controller|
done|failed]
</li>
<li>ZW_CONTROLLER_CHANGE [learnReady|nodeFound|controller|done|failed]
</li>
<li>ZW_CREATE_NEW_PRIMARY [learnReady|nodeFound|controller|done|failed]
</li>
<li>ZW_REMOVE_FAILED_NODE_ID
done|failed]</li>
<br><b>controllerChange</b>
<li>ZW_CONTROLLER_CHANGE [learnReady|nodeFound|controller|done|failed]</li>
<br><b>createNewPrimary</b>
<li>ZW_CREATE_NEW_PRIMARY [learnReady|nodeFound|controller|done|failed]</li>
<br><b>factoryReset</b>
<li>ZW_SET_DEFAULT [done]</li>
<br><b>learnMode</b>
<li>ZW_SET_LEARN_MODE [started|done|failed|deleted]</li>
<br><b>neighborUpdate</b>
<li>ZW_REQUEST_NODE_NEIGHBOR_UPDATE [started|done|failed]</li>
<br><b>removeFailedNode</b>
<li>ZW_REMOVE_FAILED_NODE_ID
[failedNodeRemoveStarted|notPrimaryController|noCallbackFunction|
failedNodeNotFound|failedNodeRemoveProcessBusy|
failedNodeRemoveFail|nodeOk|nodeRemoved|nodeNotRemoved]
</li>
<li>ZW_REMOVE_NODE_FROM_NETWORK
[learnReady|nodeFound|slave|controller|done|failed]
</li>
<li>ZW_REPLACE_FAILED_NODE
failedNodeRemoveFail|nodeOk|nodeRemoved|nodeNotRemoved]</li>
<br><b>removeNode</b>
<li>ZW_REMOVE_NODE_FROM_NETWORK
[learnReady|nodeFound|slave|controller|done|failed]</li>
<br><b>replaceFailedNode</b>
<li>ZW_REPLACE_FAILED_NODE
[failedNodeRemoveStarted|notPrimaryController|noCallbackFunction|
failedNodeNotFound|failedNodeRemoveProcessBusy|
failedNodeRemoveFail|nodeOk|failedNodeReplace|
failedNodeReplaceDone|failedNodeRemoveFailed]
</li>
<li>ZW_REQUEST_NODE_NEIGHBOR_UPDATE [started|done|failed]
</li>
<li>ZW_SET_DEFAULT [done]
</li>
<li>ZW_SET_LEARN_MODE [started|done|failed|deleted]
</li>
<li>ZW_SET_SUC_NODE_ID [ok|failed|callbackSucceeded|callbackFailed]
</li>
failedNodeReplaceDone|failedNodeRemoveFailed]</li>
<br><b>sucNodeId</b>
<li>ZW_SET_SUC_NODE_ID [ok|failed|callbackSucceeded|callbackFailed]</li>
</ul>
</ul>

View File

@ -49,7 +49,7 @@ my %zwave_class = (
"..2003(.*)"=> '"basicReport:$1"' }},
CONTROLLER_REPLICATION => { id => '21' },
APPLICATION_STATUS => { id => '22', # V1
parse => { "..2201(..)(..)" =>
parse => { "..2201(..)(..)" =>
'ZWave_applicationStatusBusyParse($hash, $1, $2)',
"03220200" => "applicationStatus:cmdRejected" } },
ZIP_SERVICES => { id => '23' },
@ -219,9 +219,9 @@ my %zwave_class = (
scheduleEntryLockDailyRepeating => "0e%02x%02x",
scheduleEntryLockTimeOffset => '0b'
},
set => { scheduleEntryLockSet =>
set => { scheduleEntryLockSet =>
'ZWave_scheduleEntryLockSet($hash, "%s")',
scheduleEntryLockAllSet =>
scheduleEntryLockAllSet =>
'ZWave_scheduleEntryLockAllSet($hash, "%s")',
scheduleEntryLockWeekDaySet =>
'ZWave_scheduleEntryLockWeekDaySet($hash, "%s")',
@ -232,7 +232,7 @@ my %zwave_class = (
scheduleEntryLockYearDailyRepeatingSet =>
'ZWave_scheduleEntryLockDailyRepeatingSet($hash, "%s")'
},
parse => { "..4e0a(.*)" =>
parse => { "..4e0a(.*)" =>
'ZWave_scheduleEntryLockTypeSupportedParse($hash, $1)',
"..4e05(.{14})" =>
'ZWave_scheduleEntryLockWeekDayParse($hash, $1)',
@ -259,7 +259,7 @@ my %zwave_class = (
schedule => "04%02x",
scheduleState => "08"},
set => { scheduleRemove => "06%02x",
schedule => 'ZWave_scheduleSet($hash, "%s")',
schedule => 'ZWave_scheduleSet($hash, "%s")',
scheduleState => "07%02x%02x"},
parse => { "..5302(.*)" => 'ZWave_scheduleSupportedParse($hash, $1)',
"..5305(.*)" => 'ZWave_scheduleParse($hash, $1)',
@ -436,7 +436,7 @@ my %zwave_class = (
parse => { "..8a04(.*)" => 'ZWave_dateReport($hash,$1)',
"..8a02(.*)" => 'ZWave_timeReport($hash,$1)',
"..8a07(.*)" => 'ZWave_timeOffsetReport($hash,$1)'} },
TIME_PARAMETERS => { id => '8b',
TIME_PARAMETERS => { id => '8b',
set => { timeParameters => 'ZWave_timeParametersSet($hash, "%s")'},
get => { timeParameters => "02"},
parse => { "..8b02" => 'timeParametersGet',
@ -995,7 +995,7 @@ ZWave_scheduleEntryLockWeekDayParse ($$)
my $start = sprintf("%02d:%02d", hex($4), hex($5));
my $end = sprintf("%02d:%02d", hex($6), hex($7));
my $end = sprintf("%02d:%02d", hex($6), hex($7));
my $rt1 = sprintf ("weekDaySchedule_%d:", hex($1));
$rt1 .= "$userId $scheduleSlotId $dayOfWeek $start $end";
@ -1063,7 +1063,7 @@ ZWave_scheduleEntryLockDailyRepeatingParse ($$)
sub
ZWave_scheduleEntryLockDailyRepeatingSet ($$)
{
{
my ($hash, $arg) = @_;
my $name = $hash->{NAME};
@ -1109,7 +1109,7 @@ ZWave_scheduleEntryLockYearDayParse ($$)
sub
ZWave_scheduleEntryLockYearDaySet ($$)
{
{
my ($hash, $arg) = @_;
my $name = $hash->{NAME};
@ -1132,7 +1132,7 @@ ZWave_scheduleEntryLockYearDaySet ($$)
sub
ZWave_scheduleEntryLockTimeOffsetParse ($$)
{
{
my ($hash, $val) = @_;
return if($val !~ m/^(..)(..)(..)/);
@ -1148,7 +1148,7 @@ ZWave_scheduleEntryLockTimeOffsetParse ($$)
sub
ZWave_scheduleEntryLockTimeOffsetSet ($$)
{
{
my ($hash, $arg) = @_;
my $name = $hash->{NAME};
@ -1220,11 +1220,11 @@ ZWave_thermostatSetpointSet ($$)
my $sp = int($temp * (10 ** $prec));
my $max = (2 ** (8*$size-1)) - 1;
my $min = -1 * (2 ** (8*$size-1));
my $min = -1 * (2 ** (8*$size-1));
if (($sp > $max) || ($sp < $min)) {
my $rt = sprintf("temperature value out of range for given "
."size and precision [%0.*f, %0.*f]",
."size and precision [%0.*f, %0.*f]",
$prec, $min/(10**$prec), $prec, $max/(10**$prec));
return ($rt, "");
}
@ -1235,12 +1235,12 @@ ZWave_thermostatSetpointSet ($$)
my $precScaleSize = sprintf("%02x", ($size | ($scale<<3) | ($prec<<5)));
my $rt = "01$type$precScaleSize$sp";
return ("",$rt);
return ("",$rt);
}
sub
ZWave_thermostatSetpointParse ($$)
{
{
my ($hash, $val) = @_;
my $name = $hash->{NAME};
@ -1318,7 +1318,7 @@ ZWave_thermostatSetpointSupportedParse ($$)
for (my $j=$i*8; $j<$i*8+8; $j++) {
# loop over all bits
last if $j >= $numTypes;
if ($supported & (2 ** ($j-$i*8))) {
if ($supported & (2 ** ($j-$i*8))) {
$rt .= sprintf("$delimeter$supportedType[$j]");
$delimeter = " ";
}
@ -1347,9 +1347,9 @@ ZWave_scheduleSupportedParse ($$)
$val = $4;
for (my $i=0;$i<hex($3); $i++) {
$val =~ m/(..)(..)(.*)/;
my $supportedCC = sprintf ("CC_%d: %d CCname_%d: %s",
my $supportedCC = sprintf ("CC_%d: %d CCname_%d: %s",
$i+1, hex($1), $i+1, $zwave_id2class{lc($1)});
my $supportedCCmask = sprintf (" CCmask_%d: %02b",
my $supportedCCmask = sprintf (" CCmask_%d: %02b",
$i+1, (hex($2) & 0x03));
$supportedCCs .= " " if $i >0;
$supportedCCs .= $supportedCC . $supportedCCmask;
@ -1405,7 +1405,7 @@ ZWave_scheduleSet ($$)
Log3 $name, 1, "$name: param: $#param $12";
for (my $i=0; $i<=$#param; $i++) {
$cmdgroup .= sprintf("%02x%s", length($param[$i])/2, $param[$i]);
}
}
}
my $numCmd = sprintf("%02x", $#param+1);
@ -1712,7 +1712,7 @@ ZWave_applicationStatusBusyParse($$$)
my $rt .= $status==0 ? "tryAgainLater " :
$status==1 ? "tryAgainInWaitTimeSeconds " :
$status==2 ? "RequestQueued " : "unknownStatusCode ";
$rt .= sprintf("waitTime: %d", hex($wTime));
$rt .= sprintf("waitTime: %d", hex($wTime));
return ("applicationBusy:$rt");
}
@ -1725,8 +1725,8 @@ ZWave_timeParametersReport($$)
Log3 $name,1,"$name: timeParametersReport with wrong format received: $arg";
return;
}
return
sprintf("timeParameters:date: %04d-%02d-%02d time(UTC): %02d:%02d:%02d",
return
sprintf("timeParameters:date: %04d-%02d-%02d time(UTC): %02d:%02d:%02d",
hex($1), hex($2), hex($3), hex($4), (hex$5), hex($6));
}
@ -1737,7 +1737,7 @@ ZWave_timeParametersSet($$)
my $name = $hash->{NAME};
return ("wrong format, see commandref", "")
if($arg !~ m/(....)-(..)-(..) (..):(..):(..)/);
my $rt = sprintf("%04x%02x%02x%02x%02x%02x", $1, $2, $3, $4, $5, $6);
my $rt = sprintf("%04x%02x%02x%02x%02x%02x", $1, $2, $3, $4, $5, $6);
return ("", sprintf("01%s", $rt));
}
@ -1762,8 +1762,8 @@ ZWave_timeReport($$)
Log3 $name, 1, "$name: timeReport with wrong format received: $arg";
return;
}
return (sprintf("time:%02d:%02d:%02d RTC: %s",
(hex($1) & 0x1f), hex($2), hex($3),
return (sprintf("time:%02d:%02d:%02d RTC: %s",
(hex($1) & 0x1f), hex($2), hex($3),
(hex($1) & 0x80) ? "failed" : "working"));
}
@ -1797,10 +1797,10 @@ ZWave_timeOffsetReport($$)
$DSToffset .= sprintf ("%02d", $minuteOffsetDST);
my $startDST = "DST-Start: ";
$startDST .= sprintf ("%02d-%02d_%02d:00",
$startDST .= sprintf ("%02d-%02d_%02d:00",
$monthStartDST, $dayStartDST, $hourStartDST);
my $endDST = "DST-End: ";
$endDST .= sprintf ("%02d-%02d_%02d:00",
$endDST .= sprintf ("%02d-%02d_%02d:00",
$monthEndDST, $dayEndDST, $hourEndDST);
return (sprintf("timeOffset:$UTCoffset $DSToffset $startDST $endDST"));
@ -1828,11 +1828,11 @@ ZWave_timeOffsetSet($$)
my $dayEndDST = $10;
my $hourEndDST = $11;
my $rt = sprintf("%02x%02x",
my $rt = sprintf("%02x%02x",
($hourTZO | ($signTZO eq "-" ? 0x01 : 0x00)), $minuteTZO);
$rt .= sprintf("%02x",
$rt .= sprintf("%02x",
($minuteOffsetDST | ($signOffsetDST eq "-" ? 0x01 : 0x00)));
$rt .= sprintf("%02x%02x%02x",
$rt .= sprintf("%02x%02x%02x",
$monthStartDST, $dayStartDST, $hourStartDST);
$rt .= sprintf("%02x%02x%02x", $monthEndDST, $dayEndDST, $hourEndDST);
@ -1975,7 +1975,7 @@ ZWave_DoorLockConfigSet($$)
return ("doorLockConfigurationSet: 1-15238 seconds allowed","");
}
return ("", sprintf("04%02x%02x%02x%02x",
return ("", sprintf("04%02x%02x%02x%02x",
$oT,$handles, int($4 / 60) ,($4 % 60)));
}
@ -2011,7 +2011,7 @@ ZWave_swmParse($$$$)
my $fl2 = (hex($fl) & 0xc0)>>6;
$fl = ($fl1==0 ? "Increment": $fl1==1 ? "Decrement" : "")." ".
($fl2==0 ? "Up": $fl1==1 ? "Down" : "");
return sprintf("state:swm %s Start: %d Duration: %d Step: %d",
return sprintf("state:swm %s Start: %d Duration: %d Step: %d",
$fl, hex($sl), hex($dur), hex($step));
}
@ -2797,7 +2797,7 @@ ZWave_secIncludeStart($$)
'DISABLED (SECURITY not supported by device)', 0);
Log3 $name, 1, "$name: secure inclusion failed, ".
"SECURITY disabled, device does not support SECURITY command class";
}
}
return 0;
}
@ -2819,12 +2819,12 @@ ZWave_secSchemeReport($$) # only called by zwave_parseHook during Include
} else {
Log3 $name, 1, "$name: Unknown SECURITY-SchemeReport received: $arg";
}
return 1; # "veto" for parseHook
return 1; # "veto" for parseHook
}
sub
ZWave_secNetworkkeySet($$) # only called by zwave_parseHook during Include
{
{
my ($hash, $arg) = @_;
my $name = $hash->{NAME};
my $iodev = $hash->{IODev};
@ -2913,11 +2913,11 @@ ZWave_secAddToSendStack($$)
my ($hash, $cmd) = @_;
my $name = $hash->{NAME};
my $id = $hash->{nodeIdHex};
my $id = $hash->{nodeIdHex};
my $len = sprintf("%02x", (length($cmd)-2)/2+1);
my $cmdEf = (AttrVal($name, "noExplorerFrames", 0) == 0 ? "25" : "05");
my $data = "13$id$len$cmd$cmdEf" . ZWave_callbackId($hash);
ZWave_addToSendStack($hash, "set", $data);
ZWave_addToSendStack($hash, "set", $data);
}
sub
@ -3576,7 +3576,7 @@ ZWave_processSendStack($$;$)
my $now = gettimeofday();
if($ss->[0] =~ m/^sent(.*?):(.*)(..)$/) {
my ($stype,$smsg, $cbid) = ($1,$2,$3);
if($ackType eq "ack") {
if($ackType eq "ack") {
if($cbid ne $omsg) {
Log 4, "ZWave: wrong callbackid $omsg received, expecting $cbid";
return;
@ -3633,7 +3633,7 @@ ZWave_addToSendStack($$$)
push @{$ss}, "$type:$cmd";
if(ZWave_isWakeUp($hash)) {
# SECURITY XXX
# SECURITY XXX
if($cmd =~ m/^......988[01].*/) {
Log3 $hash->{NAME}, 5, "$hash->{NAME}: Sendstack bypassed for $cmd";
} else {
@ -3706,7 +3706,7 @@ ZWave_Parse($$@)
DoTrigger($ioName, "$cmd $retval");
return "";
}
if($cmd eq "ZW_SET_SUC_NODE_ID") {
my $retval;
if($arg eq "00") { $retval = 'failed';
@ -3733,7 +3733,7 @@ ZWave_Parse($$@)
return "";
}
}
if($msg !~ m/^00(..)(..)(..)(.*)/) { # 00=REQUEST
Log3 $ioName, 4, "$ioName: UNKNOWN msg $msg";
return "";
@ -3809,21 +3809,27 @@ ZWave_Parse($$@)
return $ret;
} elsif($callbackid eq "10") {
Log3 $ioName, 2, "ZW_APPLICATION_UPDATE sucId ".hex($id);
$evt = 'sucId '.hex($id);
DoTrigger($ioName, "$cmd $evt");
Log3 $ioName, 4, "$ioName $cmd $evt";
return "";
} elsif($callbackid eq "20") {
Log3 $ioName, 2, "ZW_APPLICATION_UPDATE deleteDone ".hex($id);
$evt = 'deleteDone '.hex($id);
DoTrigger($ioName, "$cmd $evt");
Log3 $ioName, 4, "$ioName $cmd $evt";
return "";
} elsif($callbackid eq "40") {
Log3 $ioName, 2, "ZW_APPLICATION_UPDATE addDone ".hex($id);
$evt = 'addDone '.hex($id);
DoTrigger($ioName, "$cmd $evt");
Log3 $ioName, 4, "$ioName $cmd $evt";
return "";
} elsif($callbackid eq "81") {
Log3 $ioName, 2, "ZW_REQUEST_NODE_INFO failed".hex($id);
Log3 $ioName, 2, "ZW_REQUEST_NODE_INFO failed ".hex($id);
return "";
} else {
Log3 $ioName, 2, "ZW_APPLICATION_UPDATE unknown $callbackid";
return "";
@ -3852,7 +3858,7 @@ ZWave_Parse($$@)
readingsSingleUpdate($hash, "transmit", $lmsg, 1);
return $hash->{NAME};
}
} elsif($cmd eq "ZW_SET_LEARN_MODE") {
if($id eq "01") { $evt = 'started';
} elsif($id eq "06") { $evt = 'done'; # $arg = new NodeId
@ -3888,7 +3894,7 @@ ZWave_Parse($$@)
} elsif($id eq "06") { $evt = 'callbackFailed';
} else { $evt = 'unknown_'.$id; # do not know
}
} elsif($cmd eq "ZW_CONTROLLER_CHANGE" ||
$cmd eq "ZW_CREATE_NEW_PRIMARY") {
my @vals = ("learnReady", "nodeFound", "slave","controller", "protocolDone",
@ -4071,7 +4077,7 @@ ZWave_computeRoute($;$)
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;
Log 1, $msg;
return $msg;
}
push(@h, $defs{$r}{nodeIdHex});
@ -4385,7 +4391,7 @@ s2Hex($)
</li>
<br><br><b>Class NETWORK_SCHEDULE (SCHEDULE), V1</b>
<li>schedule ID USER_ID YEAR-MONTH-DAY WDAY ACTIVE_ID DURATION_TYPE
<li>schedule ID USER_ID YEAR-MONTH-DAY WDAY ACTIVE_ID DURATION_TYPE
HOUR:MINUTE DURATION NUM_REPORTS CMD ... CMD<br>
Set a schedule for a user. Due to lack of documentation,
details for some parameters are not available. Command Class is
@ -4478,7 +4484,7 @@ s2Hex($)
ACTION: 0=erase schedule slot, 1=modify the schedule slot for the user<br>
USER_ID: id of user, starting from 1 up to the number of supported users,
refer also to the USER_CODE class description.<br>
SCHEDULE_ID: schedule slot id (from 1 up to number of supported
SCHEDULE_ID: schedule slot id (from 1 up to number of supported
schedule slots)<br>
WEEKDAY: day of week, choose one of:
"sun","mon","tue","wed","thu","fri","sat"<br>
@ -4488,14 +4494,14 @@ s2Hex($)
(leading 0 is mandatory)<br>
</ul>
</li>
<li>scheduleEntryLockYearDaySet ACTION USER_ID SCHEDULE_ID
<li>scheduleEntryLockYearDaySet ACTION USER_ID SCHEDULE_ID
STARTDATE STARTTIME ENDDATE ENDTIME<br>
erase or set a year day schedule for a specified user ID (V1)<br>
<ul>
ACTION: 0=erase schedule slot, 1=modify the schedule slot for the user<br>
USER_ID: id of user, starting from 1 up to the number of supported users,
refer also to the USER_CODE class description.<br>
SCHEDULE_ID: schedule slot id (from 1 up to number of supported
SCHEDULE_ID: schedule slot id (from 1 up to number of supported
schedule slots)<br>
STARTDATE: date of schedule start in the format YYYY-MM-DD<br>
STARTTIME: time of schedule start in the format HH:MM
@ -4506,7 +4512,7 @@ s2Hex($)
</ul>
</li>
<li>scheduleEntryLockTimeOffsetSet TZO DST<br>
set the TZO and DST (V2)<br>
set the TZO and DST (V2)<br>
<ul>
TZO: current local time zone offset in the format (+|-)HH:MM
(sign and leading 0 is mandatory)<br>
@ -4521,7 +4527,7 @@ s2Hex($)
ACTION: 0=erase schedule slot, 1=modify the schedule slot for the user<br>
USER_ID: id of user, starting from 1 up to the number of supported users,
refer also to the USER_CODE class description.<br>
SCHEDULE_ID: schedule slot id (from 1 up to number of supported
SCHEDULE_ID: schedule slot id (from 1 up to number of supported
schedule slots)<br>
WEEKDAYS: concatenated string of weekdays (choose from:
"sun","mon","tue","wed","thu","fri","sat");
@ -4870,14 +4876,14 @@ s2Hex($)
returns the number of available slots for week day and year day
schedules (V1), in V3 the number of available slots for the daily
repeating schedule is reported additionally
</li>
</li>
<li>scheduleEntryLockWeekDay USER_ID SCHEDULE_ID<br>
returns the specified week day schedule for the specified user
(day of week, start time, end time) (V1)<br>
<ul>
USER_ID: id of user, starting from 1 up to the number of supported users,
refer also to the USER_CODE class description.<br>
SCHEDULE_ID: schedule slot id (from 1 up to number of supported
SCHEDULE_ID: schedule slot id (from 1 up to number of supported
schedule slots)<br>
</ul>
</li>
@ -4887,7 +4893,7 @@ s2Hex($)
<ul>
USER_ID: id of user, starting from 1 up to the number of supported users,
refer also to the USER_CODE class description.<br>
SCHEDULE_ID: schedule slot id (from 1 up to number of supported
SCHEDULE_ID: schedule slot id (from 1 up to number of supported
schedule slots)<br>
</ul>
</li>
@ -4897,7 +4903,7 @@ s2Hex($)
<ul>
USER_ID: id of user, starting from 1 up to the number of supported users,
refer also to the USER_CODE class description.<br>
SCHEDULE_ID: schedule slot id (from 1 up to number of supported
SCHEDULE_ID: schedule slot id (from 1 up to number of supported
schedule slots)<br>
</ul>
</li>
@ -5096,6 +5102,9 @@ s2Hex($)
<b>Generated events:</b>
<ul>
<br><b>neighborUpdate</b>
<li>ZW_REQUEST_NODE_NEIGHBOR_UPDATE [started|done|failed]</li>
<br><b>Class ALARM</b>
<li>Devices with class version 1 support: alarm_type_X:level Y</li>
<li>For higher class versions more detailed events with 100+ different
@ -5208,7 +5217,7 @@ s2Hex($)
<li>mcCapability_X:class1 class2 ...</li>
<br><br><b>Class NETWORK_SCHEDULE (SCHEDULE), V1</b>
<li>schedule_&lt;id&gt;: ID: $schedule_id userID: $user_id sYear:
<li>schedule_&lt;id&gt;: ID: $schedule_id userID: $user_id sYear:
$starting_year sMonth: $starting_month activeID: $active_id
sDay: $starting_day sWeekDay: $starting_weekday sHour:
$starting_hour durationType: $duration_type sMinute:
@ -5219,7 +5228,7 @@ s2Hex($)
startTimeSupport: $start_time_support(6 bit field) fallbackSupport:
$fallback_support enableDisableSupport: $ena_dis_support
numCCs: $number_of_supported_command_classes
overrideTypes: $override_types(7 bit field) overrideSupport:
overrideTypes: $override_types(7 bit field) overrideSupport:
$override_support</li>
<li>scheduleSupportedCC: CC_&lt;x&gt;: $number_of_command_class
CCname_&lt;x&gt;: $name_of_command_class]CCmask_&lt;x&gt;:
@ -5248,9 +5257,9 @@ s2Hex($)
<li>group_Id:scene dimmingDuration</li>
<br><br><b>Class SCHEDULE_ENTRY_LOCK</b>
<li>scheduleEntryLockEntryTypeSupported:WeekDaySlots: $value
<li>scheduleEntryLockEntryTypeSupported:WeekDaySlots: $value
YearDaySlots: $value</li>
<li>weekDaySchedule_$userId:userID: $value slotID: $value $weekday
<li>weekDaySchedule_$userId:userID: $value slotID: $value $weekday
$starthour:$startminute $endhour:$endminute</li>
<li>yearDaySchedule_$userId:userID: $value slotID: $value
start: $year-$month-$day $hour:$minute
@ -5361,7 +5370,7 @@ s2Hex($)
<li>state:dim value</li>
<li>state:swmBeginUp</li>
<li>state:swmBeginDown</li>
<li>state:swm [Decrement|Increment] [Up|Down]
<li>state:swm [Decrement|Increment] [Up|Down]
Start: $sl Duration: $dur Step: $step</li>
<li>state:swmEnd</li>