Difference between revisions of "ZWave API"
(→Start) |
|||
Line 12: | Line 12: | ||
== Frame specification == | == Frame specification == | ||
Karl Denning implemented basic ZWave support in his software "HomeDaemon". He advised that basic frame specification can be derived from his source code (http://www.intouchcontrolsforum.com/forums/showpost.php?s=e11a812b08256225ebb66a73d8f6d193&p=173&postcount=13). | Karl Denning implemented basic ZWave support in his software "HomeDaemon". He advised that basic frame specification can be derived from his source code (http://www.intouchcontrolsforum.com/forums/showpost.php?s=e11a812b08256225ebb66a73d8f6d193&p=173&postcount=13). | ||
+ | |||
== Basic Classes == | == Basic Classes == | ||
From the Leviton Z-Wave RS232 ASCII Interface Programming Guide (RZC0P-1LW, 10/9/2007): | From the Leviton Z-Wave RS232 ASCII Interface Programming Guide (RZC0P-1LW, 10/9/2007): | ||
Line 171: | Line 172: | ||
36 04/11/08 18:25:29.763 ZWJobSetLearnMode: start learning <0xb68d9b90> | 36 04/11/08 18:25:29.763 ZWJobSetLearnMode: start learning <0xb68d9b90> | ||
</pre> | </pre> | ||
+ | |||
+ | = Pluto Source Code = | ||
+ | The pluto project at one point in time included zwave control classes. The source code for these classes was published for some time at svn.plutohome.com. These classes are no longer published. However, substantial details of framing formats were derivable from that source code. | ||
+ | |||
+ | Some snippets that explain how to construct some interesting PDUs are the following (all snippets from code that was labelled GPLed at the top. Full interpretation of this code requires access to the z-wave SDK headers, which are labelled proprietary and thus are not included here): | ||
+ | |||
+ | * JobSwitchChangeLevel | ||
+ | setState(ZWaveJob::RUNNING); | ||
+ | size_t len = 9; | ||
+ | char data[9]; | ||
+ | data[0] = REQUEST; | ||
+ | data[1] = FUNC_ID_ZW_SEND_DATA; | ||
+ | data[2] = (char)d->nodeID; | ||
+ | data[3] = DATA_LEN; // 3 | ||
+ | data[4] = COMMAND_CLASS_SWITCH_MULTILEVEL; | ||
+ | data[5] = SWITCH_MULTILEVEL_SET; | ||
+ | data[6] = d->level; | ||
+ | data[7] = TRANSMIT_OPTION_ACK | TRANSMIT_OPTION_AUTO_ROUTE; | ||
+ | data[8] = 1; | ||
+ | |||
+ | * JobSwitchBinaryGet | ||
+ | setState(ZWaveJob::RUNNING); | ||
+ | size_t len = 8; | ||
+ | char data[8]; | ||
+ | data[0] = REQUEST; | ||
+ | data[1] = FUNC_ID_ZW_SEND_DATA; | ||
+ | data[2] = (char)d->nodeID; | ||
+ | data[3] = DATA_LEN; | ||
+ | data[4] = COMMAND_CLASS_SWITCH_MULTILEVEL; | ||
+ | data[5] = SWITCH_BINARY_GET; | ||
+ | data[6] = TRANSMIT_OPTION_ACK | TRANSMIT_OPTION_AUTO_ROUTE; | ||
+ | data[7] = 2; | ||
+ | return handler()->sendData(data, len); | ||
+ | |||
+ | * JobSetLearnNodeState | ||
+ | char buffer[10]; | ||
+ | |||
+ | buffer[0] = REQUEST; | ||
+ | buffer[1] = FUNC_ID_ZW_SET_LEARN_NODE_STATE; | ||
+ | buffer[2] = mode(); | ||
+ | buffer[3] = 1; // Callback FunctionID | ||
+ | buffer[4] = 0; | ||
+ | |||
+ | setState(ZWaveJob::RUNNING); | ||
+ | |||
+ | d->failed = false; | ||
+ | |||
+ | return handler()->sendData(buffer, 3); | ||
+ | |||
+ | Z-Wave protocol Reset: | ||
+ | |||
+ | First command: /** */ | ||
+ | |||
+ | 01 08 00 03 01 02 01 01 21 D6 | ||
+ | |||
+ | 00 = request | ||
+ | 03 = FUNC_ID_SERIAL_API_APPL_NODE_INFORMATION | ||
+ | 01 = listening /** not moving */ | ||
+ | 02 = node generic type, GENERIC_TYPE_STATIC_CONTROLLER | ||
+ | 01 = node specific type, SPECIFIC_TYPE_PORTABLE_REMOTE_CONTROLLER | ||
+ | 01 = param length | ||
+ | 21 = COMMAND_CLASS_CONTROLLER_REPLICATION | ||
+ | |||
+ | // wait for ACK | ||
+ | ________________________________________________________________ | ||
+ | |||
+ | Second command: /** Reset to factory default. */ | ||
+ | |||
+ | 01 04 00 42 01 B8 | ||
+ | |||
+ | 00 = request | ||
+ | 42 = FUNC_ID_ZW_SET_DEFAULT | ||
+ | 01 = Callback FunctionID | ||
+ | |||
+ | Answer: | ||
+ | |||
+ | 06 | ||
+ | 01 04 00 42 01 B8 | ||
+ | |||
+ | 06 = ACK | ||
+ | |||
+ | 01 = SOF | ||
+ | 04 = Length | ||
+ | 00 = Request | ||
+ | 42 = FUNC_ID_ZW_SET_DEFAULT | ||
+ | 01 = Callback FunctionID | ||
+ | B8 = checksum | ||
+ | |||
+ | =Framing= | ||
+ | Serial PDUs are framed with a simple framing protocol. Byte value 0x01 is start of frame, or SOF. The second octet is the length in bytes of the frame, excluding the SOF or the length octet. Assume that value was n for this frame. The next n - 1 octets are the framed payload. The last octet is a checksum computed by xoring a 0xff seed with all octets of the payload. The checksum includes the length field, but not the SOF byte or the checksum byte itself. This information is derived from the pluto source code, along with observation of the serial protocol from existing commercial software. | ||
+ | |||
+ | =Capturing your own sample transactions= | ||
+ | These notes are for Microsoft Windows. Linux should be easier. | ||
+ | |||
+ | Get a copy of Device Monitoring Studio. These instructions were written with version 5.11. Use an HA22 device or other serial or usb-to-serial Z-wave dongle. Monitor the serial port for an event. Add the "Request" view in DMS. Do your operations in the software that will interact with the HA22. No click on the "complete" tab in the request view. Right click and choose "export". Save the .htm file that results. | ||
+ | |||
+ | The resulting HTML is pretty verbose. Some simple regexps can pull out interesting details. That results in transcriptions like the ones you see below. | ||
+ | |||
+ | Here's a session with an established Homeseer installation starting up: | ||
+ | |||
+ | <pre> | ||
+ | W: 01 03 00 02 fe | ||
+ | R: 06 | ||
+ | R: 01 25 01 02 04 04 1d ff 00 | ||
+ | R: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 02 38 | ||
+ | W: 06 | ||
+ | W: 01 04 00 41 01 bb | ||
+ | R: 06 01 09 01 41 12 06 00 01 01 01 a3 | ||
+ | W: 06 | ||
+ | W: 01 04 00 41 02 b8 | ||
+ | R: 06 01 09 01 41 c9 0c 00 04 11 04 62 | ||
+ | W: 06 | ||
+ | W: 01 04 00 41 03 b9 | ||
+ | R: 06 01 09 01 41 c9 0c 00 04 11 04 62 | ||
+ | W: 06 | ||
+ | W: 01 04 00 41 04 be | ||
+ | R: 06 01 09 01 41 c9 0c 00 04 11 04 62 | ||
+ | W: 06 | ||
+ | W: 01 04 00 41 05 bf | ||
+ | R: 06 01 09 01 41 c9 0c 00 04 11 04 62 | ||
+ | W: 06 | ||
+ | W: 01 04 00 41 06 bc | ||
+ | R: 06 01 09 01 41 c9 0c 00 04 10 03 64 | ||
+ | W: 06 | ||
+ | W: 01 04 00 41 07 bd | ||
+ | R: 06 01 09 01 41 c9 0c 00 04 10 03 64 | ||
+ | W: 06 | ||
+ | W: 01 04 00 41 08 b2 | ||
+ | R: 06 01 09 01 41 ca 06 00 02 02 00 7a | ||
+ | W: 06 | ||
+ | W: 01 07 00 03 01 02 00 00 f8 | ||
+ | R: 06 | ||
+ | W: 01 03 00 20 dc | ||
+ | R: 06 01 08 01 20 00 98 a2 94 08 70 | ||
+ | W: 06 | ||
+ | W: 01 03 00 07 fb | ||
+ | R: 06 01 20 01 07 02 2d 00 00 00 01 00 01 7f 80 fe 00 8f 00 00 00 7b 9f ff 00 87 00 00 00 00 00 80 00 00 64 | ||
+ | W: 06 | ||
+ | </pre> | ||
+ | |||
+ | Here's the first bits of what HomeZiX did when started: | ||
+ | |||
+ | <pre> | ||
+ | W: 01 03 00 15 e9 | ||
+ | R: 06 01 10 01 15 5a 2d 57 61 76 65 20 32 2e 30 39 00 01 9d | ||
+ | W: 06 | ||
+ | W: 01 05 00 06 0f 0a f9 | ||
+ | R: 06 01 05 01 06 96 0f 64 | ||
+ | W: 06 | ||
+ | W: 01 04 00 17 00 ec | ||
+ | R: 06 01 04 01 17 00 ed | ||
+ | W: 06 | ||
+ | W: 01 03 00 07 fb | ||
+ | R: 06 01 20 01 07 02 2d 00 00 00 01 00 01 7f 80 fe 00 8f 00 00 00 7b 9f ff 00 87 00 00 00 00 00 80 00 00 | ||
+ | R: 64 | ||
+ | W: 06 | ||
+ | W: 01 03 00 20 dc | ||
+ | R: 06 01 08 01 20 00 7a 7a af 02 7b | ||
+ | W: 06 | ||
+ | W: 01 03 00 02 fe | ||
+ | R: 06 | ||
+ | R: 01 25 01 02 04 04 1d 87 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ||
+ | R: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 02 40 | ||
+ | W: 06 | ||
+ | W: 01 03 00 56 aa | ||
+ | R: 06 01 04 01 56 00 ac | ||
+ | W: 06 | ||
+ | W: 01 04 00 41 01 bb | ||
+ | R: 06 01 09 01 41 c9 04 00 03 10 00 68 | ||
+ | W: 06 | ||
+ | W: 01 04 00 41 02 b8 | ||
+ | R: 06 01 09 01 41 ca 06 00 02 02 01 7b | ||
+ | W: 06 | ||
+ | W: 01 04 00 41 03 b9 | ||
+ | R: 06 01 09 01 41 c9 04 00 03 10 00 68 | ||
+ | W: 06 | ||
+ | W: 01 04 00 41 08 b2 | ||
+ | R: 06 01 09 01 41 c9 04 00 03 10 00 68 | ||
+ | W: 06 | ||
+ | W: 01 05 00 21 00 00 db | ||
+ | R: 06 01 04 01 21 42 99 | ||
+ | W: 06 | ||
+ | W: 01 05 00 21 00 01 da | ||
+ | R: 06 01 04 01 21 06 dd | ||
+ | W: 06 | ||
+ | W: 01 06 00 23 00 02 06 de | ||
+ | R: 06 01 09 01 23 21 72 86 82 2b 87 2f | ||
+ | W: 06 | ||
+ | W: 01 08 00 13 ff 01 00 00 01 1b | ||
+ | R: 06 01 04 01 13 01 e8 | ||
+ | W: 06 | ||
+ | R: 01 05 00 13 01 00 e8 | ||
+ | W: 06 | ||
+ | W: 01 05 00 50 ff 01 54 | ||
+ | R: 06 | ||
+ | R: 01 07 00 50 01 01 ef 00 47 | ||
+ | W: 06 | ||
+ | </pre> | ||
+ | |||
= References = | = References = | ||
http://www.basshome.com/leviton_z-wave_documentation_1970_ctg.htm | http://www.basshome.com/leviton_z-wave_documentation_1970_ctg.htm | ||
Line 193: | Line 393: | ||
http://www.ddj.com/embedded/193104353 | http://www.ddj.com/embedded/193104353 | ||
+ | |||
+ | http://www.elec-solutions.com/docs/motor_controls/abmhz/ABMHZ_v1+1_Advanced_User_Manual.pdf | ||
+ | (since pulled, but still visible as of April 26, 2008 in the Google cache) | ||
= Tools used = | = Tools used = |
Revision as of 04:09, 27 April 2008
Contents
Introduction
The ZWave API is not available for free. You have to get the Zensys SDK for command specifications and device class definitions. This page tries to collect all the freely available information about ZWave. The final goal is to provide a header file with all necessary definitions for basic operation with open source software.
IMPORTANT: all information added to this page _must_ have a reference to the source where it came from.
API
Frame specification
Karl Denning implemented basic ZWave support in his software "HomeDaemon". He advised that basic frame specification can be derived from his source code (http://www.intouchcontrolsforum.com/forums/showpost.php?s=e11a812b08256225ebb66a73d8f6d193&p=173&postcount=13).
Basic Classes
From the Leviton Z-Wave RS232 ASCII Interface Programming Guide (RZC0P-1LW, 10/9/2007):
Controller 1 Static controller 2 Slave 3 Routing Slave 4
that leads us to some definitions:
#define OZA_BASIC_CLASS_CONTROLLER 0x01 #define OZA_BASIC_CLASS_STATIC_CONTROLLER 0x02 #define OZA_BASIC_CLASS_SLAVE 0x03 #define OZA_BASIC_CLASS_ROUTING_SLAVE 0x04
Device Types
From the Z-Wave Configuration Information-1.pdf:
CONTROLLER 0x01 (like the ZTH200, Classes: ) SWITCH/APPLIANCE 0x10 (ZRP200, Classes: 25, 27, 75) DIMMER 0x11 (ZDP200, ZDW230, .., Classes: 26, 27, 75, ...) TRANSMITTER 0x12 THERMOSTAT 0x08 SHUTTER 0x09
Command and Device classes
From the Electronic Solutions, Inc. DBMZ Advanced User manual:
Command/Device Classes
Basic Slave Device
All
Multilevel Switch
- COMMAND_CLASS_SWITCH_MULTILEVEL
MULTILEVEL_SWITCH_GET MULTILEVEL_SWITCH_SET MULTILEVEL_SWITCH_START_LEVEL_CHANGE MULTILEVEL_SWITCH_STOP_LEVEL_CHANGE
additional information from http://zwaveworld.com/forum/index.php?showtopic=237:
>?FI003,017,000 //basic class 3 (slave), generic class 0x11 (multlevel switch), specific class 0
Basic
- COMMAND_CLASS_BASIC
BASIC_GET BASIC_SET
Mandatory
Multilevel Sensor
(from the Vizia RF Application Note)
- COMMAND_CLASS_SENSOR_MULTILEVEL
example get:
>N4SE49,4 (RZC0P Syntax)
sensor report:
<N004:049,005,001,009,075 049: device class 005: command report 001: value send is a temperature value 009: value represented with 1 byte in degrees fahrenheit 075: 75° F
Manufacturer Specific
- COMMAND_CLASS_MANUFACTURER_SPECIFIC
Show the ESI product data:
MANUFACTURER_SPECIFIC_GET
Example return message:
0x00 0x33 0x52 0x50 0x30 0x32 0x00: maunfacturer id high byte 0x33: manufacturer id low byte, ID: 0x0033 Product type ID "RP" Product ID "02"
Version
- COMMAND_CLASS_VERSION
VERSION_GET
Example return message:
0x04 0x02 0x06 0x01 0x01 0x5a 0x04: Library type 4 for basic slave device 0x02: Protocol version 2 0x06: Protocol sub version 6 0x01: Application version 1 0x01: Application sub version 1 0x5a: ?
All Switch
- COMMAND_CLASS_SWITCH_ALL
SWITCH_ALL_GET SWITCH_ALL_ON SWITCH_ALL_OFF
Configuration
- COMMAND_CLASS_CONFIGURATION
Each parameter is a single byte ("0" or "1")
CONFIGURATION_GET CONFIGURATION_SET
Power Level
- COMMAND_CLASS_POWERLEVEL
POWERLEVEL_TEST_NODE_SET POWERLEVEL_TEST_NODE_GET POWERLEVEL_TEST_NODE_REPORT
Example: POWERLEVEL_SET, 5, 60 set the ZWave node's power level to 5 for the length of 60 seconds
Device configuration data
Traces
Starting the ZWave device:
40 03/28/08 15:53:34.590 0x1 0x3 0x0 0x15 0xe9 (#####) <0xb698bb90> 41 03/28/08 15:53:34.741 0x6 0x1 0x10 0x1 0x15 0x5a 0x2d 0x57 0x61 0x76 0x65 0x20 0x32 0x2e 0x33 0x31 0x0 0x1 0x96 (#####Z-Wave 2.31###) <0xb718cb90> 40 03/28/08 15:53:34.792 0x1 0x3 0x0 0x20 0xdc (### #) <0xb698bb90> 41 03/28/08 15:53:35.042 0x6 0x1 0x8 0x1 0x20 0x0 0x0 0x55 0x28 0x2 0xa9 (#### ##U(##) <0xb718cb90> 40 03/28/08 15:53:35.092 0x1 0x3 0x0 0x2 0xfe (#####) <0xb698bb90> 41 03/28/08 15:53:35.342 0x6 0x1 0x25 0x1 0x2 0x4 0x4 0x1d 0x3 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x2 0x1 0xc4 (##%#) <0xb718cb90> 40 03/28/08 15:53:35.393 0x1 0x4 0x0 0x52 0x1 0xa8 (###R##) <0xb698bb90> 41 03/28/08 15:53:35.643 0x6 0x1 0x4 0x1 0x52 0x1 0xa9 (####R##) <0xb718cb90> 40 03/28/08 15:53:35.694 0x1 0x3 0x0 0x56 0xaa (###V#) <0xb698bb90> 41 03/28/08 15:53:35.944 0x6 0x1 0x4 0x1 0x56 0x0 0xac (####V##) <0xb718cb90> 40 03/28/08 15:53:35.995 0x1 0x4 0x0 0x41 0x1 0xbb (###A##) <0xb698bb90> 41 03/28/08 15:53:36.245 0x6 0x1 0x9 0x1 0x41 0xc9 0x0 0x0 0x3 0x11 0x0 0x6d (####A######m) <0xb718cb90> 40 03/28/08 15:53:36.296 0x1 0x4 0x0 0x41 0x2 0xb8 (###A##) <0xb698bb90> 41 03/28/08 15:53:36.545 0x6 0x1 0x9 0x1 0x41 0xd2 0x6 0x0 0x2 0x2 0x0 0x62 (####A######b) <0xb718cb90>
Interesting string:
0x1 0x2 0x4 0x4 0x1d 0x3 0x0 0x0 0x0 ... 0x1 means it is a response 0x2 means it is initialization data 0x4 is the version 0x4 is the capabilities
LMCE will look for the next 4 bytes to get the list of devices. It seems to be a bit map. In this case, the first byte is 0x3 or in binary 00000011 so devices ID 1 and 2 are present. It is unclear to me why we only look at 4 bytes (32 zwave devices) while the protocol supports 252
Switching on a ZDP200 lamp plug from the Orbiter:
40 03/28/08 15:49:20.707 0x1 0xa 0x0 0x13 0x1 0x3 0x26 0x1 0x63 0x5 0x6 0xa3 (#\n####&#c###) <0xb68f3b90> 41 03/28/08 15:49:21.007 0x6 0x1 0x4 0x1 0x13 0x1 0xe8 (#######) <0xb70f4b90> 41 03/28/08 15:49:21.307 0x1 0x5 0x0 0x13 0x6 0x0 0xef (#######) <0xb70f4b90>
Pressing "all units on" on the ZTH200:
41 03/28/08 15:50:58.553 0x1 0x8 0x0 0x4 0x4 0xef 0x2 0x27 0x4 0x39 (#######'#9) <0xb70f4b90> 41 03/28/08 15:50:58.854 0x1 0x8 0x0 0x4 0x0 0xef 0x2 0x27 0x4 0x3d (#######'#=) <0xb70f4b90>
Pressing "all units off" on the ZTH200:
41 03/28/08 15:51:43.713 0x1 0x8 0x0 0x4 0x4 0xef 0x2 0x27 0x5 0x38 (#######'#8) <0xb70f4b90> 41 03/28/08 15:51:44.014 0x1 0x8 0x0 0x4 0x0 0xef 0x2 0x27 0x5 0x3c (#######'#<) <0xb70f4b90>
Pressing the local switch on the ZDP200 (toggling from off to on):
41 03/28/08 15:52:37.284 0x1 0xc 0x0 0x49 0x84 0x1 0x6 0x3 0x11 0x0 0x26 0x27 0x75 0x5f (###I######&'u_) <0xb70f4b90>
Learn Mode
Start
We send:
40 04/11/08 18:25:26.852 0x1 0x4 0x0 0x50 0x1 0xaa (###P##) <0xb68d9b90>
response:
41 04/11/08 18:25:27.052 0x6 (#) <0xb70dab90> 41 04/11/08 18:25:29.763 0x1 0x7 0x0 0x50 0x2 0x1 0xef 0x0 0x44 (###P####D) <0xb70dab90> 35 04/11/08 18:25:29.763 ZWJobSetLearnMode: len = 6 buf = 0x00 0x50 0x02 0x01 0xef 0x00 <0xb68d9b90> 36 04/11/08 18:25:29.763 ZWJobSetLearnMode: start learning <0xb68d9b90>
Pluto Source Code
The pluto project at one point in time included zwave control classes. The source code for these classes was published for some time at svn.plutohome.com. These classes are no longer published. However, substantial details of framing formats were derivable from that source code.
Some snippets that explain how to construct some interesting PDUs are the following (all snippets from code that was labelled GPLed at the top. Full interpretation of this code requires access to the z-wave SDK headers, which are labelled proprietary and thus are not included here):
- JobSwitchChangeLevel
setState(ZWaveJob::RUNNING); size_t len = 9; char data[9]; data[0] = REQUEST; data[1] = FUNC_ID_ZW_SEND_DATA; data[2] = (char)d->nodeID; data[3] = DATA_LEN; // 3 data[4] = COMMAND_CLASS_SWITCH_MULTILEVEL; data[5] = SWITCH_MULTILEVEL_SET; data[6] = d->level; data[7] = TRANSMIT_OPTION_ACK | TRANSMIT_OPTION_AUTO_ROUTE; data[8] = 1;
- JobSwitchBinaryGet
setState(ZWaveJob::RUNNING); size_t len = 8; char data[8]; data[0] = REQUEST; data[1] = FUNC_ID_ZW_SEND_DATA; data[2] = (char)d->nodeID; data[3] = DATA_LEN; data[4] = COMMAND_CLASS_SWITCH_MULTILEVEL; data[5] = SWITCH_BINARY_GET; data[6] = TRANSMIT_OPTION_ACK | TRANSMIT_OPTION_AUTO_ROUTE; data[7] = 2; return handler()->sendData(data, len);
- JobSetLearnNodeState
char buffer[10];
buffer[0] = REQUEST; buffer[1] = FUNC_ID_ZW_SET_LEARN_NODE_STATE; buffer[2] = mode(); buffer[3] = 1; // Callback FunctionID buffer[4] = 0;
setState(ZWaveJob::RUNNING);
d->failed = false;
return handler()->sendData(buffer, 3);
Z-Wave protocol Reset:
First command: /** */
01 08 00 03 01 02 01 01 21 D6
00 = request 03 = FUNC_ID_SERIAL_API_APPL_NODE_INFORMATION 01 = listening /** not moving */ 02 = node generic type, GENERIC_TYPE_STATIC_CONTROLLER 01 = node specific type, SPECIFIC_TYPE_PORTABLE_REMOTE_CONTROLLER 01 = param length 21 = COMMAND_CLASS_CONTROLLER_REPLICATION
// wait for ACK
________________________________________________________________
Second command: /** Reset to factory default. */
01 04 00 42 01 B8
00 = request 42 = FUNC_ID_ZW_SET_DEFAULT 01 = Callback FunctionID
Answer:
06 01 04 00 42 01 B8
06 = ACK
01 = SOF 04 = Length 00 = Request 42 = FUNC_ID_ZW_SET_DEFAULT 01 = Callback FunctionID B8 = checksum
Framing
Serial PDUs are framed with a simple framing protocol. Byte value 0x01 is start of frame, or SOF. The second octet is the length in bytes of the frame, excluding the SOF or the length octet. Assume that value was n for this frame. The next n - 1 octets are the framed payload. The last octet is a checksum computed by xoring a 0xff seed with all octets of the payload. The checksum includes the length field, but not the SOF byte or the checksum byte itself. This information is derived from the pluto source code, along with observation of the serial protocol from existing commercial software.
Capturing your own sample transactions
These notes are for Microsoft Windows. Linux should be easier.
Get a copy of Device Monitoring Studio. These instructions were written with version 5.11. Use an HA22 device or other serial or usb-to-serial Z-wave dongle. Monitor the serial port for an event. Add the "Request" view in DMS. Do your operations in the software that will interact with the HA22. No click on the "complete" tab in the request view. Right click and choose "export". Save the .htm file that results.
The resulting HTML is pretty verbose. Some simple regexps can pull out interesting details. That results in transcriptions like the ones you see below.
Here's a session with an established Homeseer installation starting up:
W: 01 03 00 02 fe R: 06 R: 01 25 01 02 04 04 1d ff 00 R: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 02 38 W: 06 W: 01 04 00 41 01 bb R: 06 01 09 01 41 12 06 00 01 01 01 a3 W: 06 W: 01 04 00 41 02 b8 R: 06 01 09 01 41 c9 0c 00 04 11 04 62 W: 06 W: 01 04 00 41 03 b9 R: 06 01 09 01 41 c9 0c 00 04 11 04 62 W: 06 W: 01 04 00 41 04 be R: 06 01 09 01 41 c9 0c 00 04 11 04 62 W: 06 W: 01 04 00 41 05 bf R: 06 01 09 01 41 c9 0c 00 04 11 04 62 W: 06 W: 01 04 00 41 06 bc R: 06 01 09 01 41 c9 0c 00 04 10 03 64 W: 06 W: 01 04 00 41 07 bd R: 06 01 09 01 41 c9 0c 00 04 10 03 64 W: 06 W: 01 04 00 41 08 b2 R: 06 01 09 01 41 ca 06 00 02 02 00 7a W: 06 W: 01 07 00 03 01 02 00 00 f8 R: 06 W: 01 03 00 20 dc R: 06 01 08 01 20 00 98 a2 94 08 70 W: 06 W: 01 03 00 07 fb R: 06 01 20 01 07 02 2d 00 00 00 01 00 01 7f 80 fe 00 8f 00 00 00 7b 9f ff 00 87 00 00 00 00 00 80 00 00 64 W: 06
Here's the first bits of what HomeZiX did when started:
W: 01 03 00 15 e9 R: 06 01 10 01 15 5a 2d 57 61 76 65 20 32 2e 30 39 00 01 9d W: 06 W: 01 05 00 06 0f 0a f9 R: 06 01 05 01 06 96 0f 64 W: 06 W: 01 04 00 17 00 ec R: 06 01 04 01 17 00 ed W: 06 W: 01 03 00 07 fb R: 06 01 20 01 07 02 2d 00 00 00 01 00 01 7f 80 fe 00 8f 00 00 00 7b 9f ff 00 87 00 00 00 00 00 80 00 00 R: 64 W: 06 W: 01 03 00 20 dc R: 06 01 08 01 20 00 7a 7a af 02 7b W: 06 W: 01 03 00 02 fe R: 06 R: 01 25 01 02 04 04 1d 87 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 02 40 W: 06 W: 01 03 00 56 aa R: 06 01 04 01 56 00 ac W: 06 W: 01 04 00 41 01 bb R: 06 01 09 01 41 c9 04 00 03 10 00 68 W: 06 W: 01 04 00 41 02 b8 R: 06 01 09 01 41 ca 06 00 02 02 01 7b W: 06 W: 01 04 00 41 03 b9 R: 06 01 09 01 41 c9 04 00 03 10 00 68 W: 06 W: 01 04 00 41 08 b2 R: 06 01 09 01 41 c9 04 00 03 10 00 68 W: 06 W: 01 05 00 21 00 00 db R: 06 01 04 01 21 42 99 W: 06 W: 01 05 00 21 00 01 da R: 06 01 04 01 21 06 dd W: 06 W: 01 06 00 23 00 02 06 de R: 06 01 09 01 23 21 72 86 82 2b 87 2f W: 06 W: 01 08 00 13 ff 01 00 00 01 1b R: 06 01 04 01 13 01 e8 W: 06 R: 01 05 00 13 01 00 e8 W: 06 W: 01 05 00 50 ff 01 54 R: 06 R: 01 07 00 50 01 01 ef 00 47 W: 06
References
http://www.basshome.com/leviton_z-wave_documentation_1970_ctg.htm
http://zwaveworld.com/forum/index.php?showtopic=237
http://www.eilhk.com/en/product/Datasheet/Zensys/SDS10243-2%20-%20Z-Wave%20Protocol%20Overview.pdf
or
http://www.smarthus.info/support/download/zwave/Z-Wave%20Protocol%20Overview.pdf
or
http://www.smarthus.info/support/download/zwave/Z-Wave%20Node%20Type%20Overview%20and%20Network.pdf
http://www.smarthus.info/support/download/zwave/Z-Wave%20Configuration%20Information.pdf
http://www.ddj.com/embedded/193104353
http://www.elec-solutions.com/docs/motor_controls/abmhz/ABMHZ_v1+1_Advanced_User_Manual.pdf (since pulled, but still visible as of April 26, 2008 in the Google cache)
Tools used
http://sourceforge.net/projects/slsnif/
Links
http://www.intouchcontrolsforum.com/forums/showthread.php?t=41&page=2
http://www.elec-solutions.com/docs/motor_controls/dbmz/DBMZ_v1+1_Advanced_User_Manual.pdf
http://zwaveworld.com/forum/index.php?showtopic=227&st=20