An essential feature of the ZAF is the communication through Command Classes. For this purpose, each of the Command Classes has a C module where incoming commands are handled, and outgoing commands are transmitted.
Command classes can have a controlling role and a supporting role. An application typically uses one of the roles. For instance, an LED bulb supports Color Switch CC, but it doesn't control Color Switch CC. The controlling role of Color Switch CC would be suited for a Z-Wave gateway as the gateway would be controlling the color of the LED bulb based on user input in a corresponding mobile app.
Based on the above, best practice would be to split the controlling implementation and the supporting implementation in two different source files like it's done for CC Basic.
Most command classes require two basic things for the supporting implementation:
Please see ZAF_types.h for descriptions REGISTER_CC_V5() and the corresponding type definition of the command handler.
https://sdomembers.z-wavealliance.org/wg/AWG/document/120 defines a list of command class / command pairs that MUST be listed for the Lifeline association group. The Z-Wave Controller will ask for the list using the Association Group Command List Get command.
ZAF will propagate this list automatically, but it requires each command class in the above registry to register the relevant commands. Use REGISTER_CC_V5() for this.
The following shows an example of how it's done for CC Door Lock. CC Door Lock must register two different commands which is why the function returns 2. Other command classes register only one command and must then return 1.
The Device Type V2 specification dictates how a certain device type (DT) must map CC Basic to other command classes.
For instance, the Lock DT must map CC Basic to CC Door Lock. This mapping is done automatically by ZAF because CC Door Lock has registered mapping functions.
Basic Set mapping is done by registering a Basic Set mapping function. Please see basic_set_mapper_t for a description of the function parameters.
Below is an example from CC Door Lock:
Basic Get mapping is done by registering a Basic Get mapping function. Please see basic_get_mapper_t for a description of the function parameters.
Below is an example from CC Multilevel Switch:
Each CC implementation defines a handler, e.g. CC_MultilevelSwitch_handler()
. This function extracts the received frame for a given Command Class. The function must be registered using a REGISTER_CC_V5 macro. Normally, the frame is carrying a “Set” or “Get” Command that results in a function call for reading or writing data. All commands are handled by the command class itself.
Example:
A controlling implementation of a CC is rather simple as the functionality is limited to transmission of one or more specific frames.
One example is CC_Basic_Set_tx() that can be found in CC_BasicController.c:
A controlling device, e.g., a wall switch, may want to send a Basic Set command. The implementation of Basic Set transmission is shown above. The value
parameter is specific for the Basic Set command. The remaining four parameters are recommended as generic parameters: p_profile
, source_endpoint
, use_supervision
and callback
. These parameters are detailed below.
Another slightly more complex example of such a function can be found in CC_MultilevelSwitch_Control.c
.
Some command classes might not offer the profile and the source endpoint, but instead rely on an index or a pointer to the configuration that contains the AGI profile and the source endpoint. One example of such an API is CC_Notification_TriggerAndTransmit()
.
p_profile (AGI profile)
The p_profile
is required together with source_endpoint
for ZAF to be able to look up the right association group. The profile must match one of those defined in the CC AGI configuration. Alternatively, if NULL is passed as the profile, the ZAF will default to the Lifeline profile.
source_endpoint
If the application is configured with endpoints, source_endpoint
must be set to the endpoint that triggers the command. An example could be a device with two temperature sensors represented by endpoint 1 and 2. This device could transmit a Basic Set if the temperature drops under a certain threshold. In that case, CC_Basic_Set_tx()
would need to be invoked with the endpoint that represents the relevant temperature sensor. If an application does not configure endpoints, source_endpoint
must be set to zero.
use_supervision
This parameter offers the application developer the option to use Supervision for a certain command. Supervision might be important in the case of a window sensor in an alarm system to make sure that a Notification Report, signaling that a window was opened, is received and decrypted by the destination node. An example where Supervision might be of less relevance could be a wall switch sending a Basic Set or a Binary Switch set. In this scenario, an end user would probably just press the button again if a frame was lost and the light didn't turn on in the first attempt.
callback
In case the application logic requires a callback whenever a transmission succeeded or failed, the callback
parameter can be used. This parameter is not required, but offering it in the API adds some flexibility to the application developer.
Each Command Class should have following folders:
inc
for public headerssrc
for private headers and source files.The command class version must be set using REGISTER_CC_V5().
Example: