Clusters, defined by a 16-bit identifier, are application objects. Whereas the NwkAddr and endpoint are addressing concepts, the cluster defines application meaning. The cluster that has been used for many examples in this book is the OnOff Cluster (ID 0x0006). This cluster knows how to turn something on or off. It doesn't matter whether the something is a light, a pump, a doorbell, or is a mechanism to open and close a door. All of these things have a binary state: on or off, open or closed.
Clusters encapsulate both commands and data. A ZigBee application can determine whether the light is on or off by querying the OnOffAttribute within the OnOff Cluster, or it can set the state of that light by commanding the cluster to turn the light on, off, or to toggle it. A small subset of the clusters defined by the ZigBee Cluster Library includes the information shown in Table 4.8.
Table 4.8: Some ZigBee Clusters
|Power Configuration Cluster
|Temperature Configuration Cluster
|OnOff Configuration Cluster
|Level Control Cluster
Clusters only have meaning within a particular profile. For example, a private profile may define cluster 0x0000 as the "shut down the network" cluster, whereas cluster 0x0000 is the Basic Cluster in the Home Automation profile. To keep things simple, all profiles which support the ZigBee Cluster Library use the same cluster IDs. That is, any ZigBee public profile which turns something on or off will use cluster ID 0x0006 for that purpose.
Clusters, in addition to the identifier, have direction. In the SimpleDescriptor which describes an endpoint, a cluster is listed as either input or output. This is used only for the purposes of service discovery: a switch, which has cluster 0x0006 as an output, can find a light, which has cluster 0x0006 as an input. But a switch doesn't find another switch, as they are both outputs on cluster 0x0006 and don't match.
Clusters contain both code (commands) and data (attributes). Commands cause action. Attributes keep track of the current state of that cluster.
A good example of this is the HA DimmingLight. It supports both the OnOff Cluster (0x0006) and the LevelControl Cluster (0x0008). There are commands to turn the light on, off, or toggle it on the OnOff Cluster; but to control the dimming function, commands on the LevelControl Cluster are used. The data on the OnOff Cluster is simply a field: Is the light on, or off. The data on the Level Control Cluster indicates what dimming level the light is (or will be) at when it is in the "on" state.
Clusters in a private profile may communicate any kind of data. ZigBee places no restrictions. Attributes and commands, which are part of the ZigBee Cluster Library specification, may not even be used at all. For example, San Juan Software uses a private profile, 0xc035, for all of our training and demo programs. You've seen one of these demo programs already in "Example 3-2: Morse Code," from Chapter 3, "The ZigBee Development Environment." The Morse Code program uses two clusters, shown in Table 4.9.
Table 4.9: Morse Code Clusters
||short (0) or long (1)
The Morse Code program does not use the ZigBee Cluster Library, so the meanings of the clusters are completely open. San Juan Software maintains a database of clusters for the training applications on the SJS private profile 0xC035, so the applications can be used together on the same network without conflict.
The following source code shows how the data indication is handled with these clusters from the SJS private profile. Notice that the code needs only to check the cluster ID. Endpoint and profile ID are already handled by the ZigBee stack:
/* Get a message from a queue */
pMsg = MSG_DeQueue(&gAppDataIndicationQueue);
/* ask ZCL to handle the frame */
pIndication = & (pMsg- > msgData.dataIndication);
/* user wants to blink (short or long) */
if(pIndication- > aClusterId == gClusterMorseBlink)
MorseBlink(pIndication- > pAsdu);
/* user passed a string to */
else if(pIndication- > aClusterId == gClusterMorseString)
MorseString(pIndication- > asduLength, pIndication- > pAsdu);
/* Free memory allocated by data indication */
Think of clusters as an object, including both code (commands) and data (attributes).
Clusters may have any meaning in a private profile.