4.1 ZCL 简介

前述章节讲解了如何使用AF层通信API,但是现在用得更多的是基于ZCL的数据通信方式。ZCL的全称是ZigBee Cluster Library,中文意思是ZigBee集群库。ZCL与AF的关系如图所示:
第4章:ZCL 基本原理 - 图1
图中共有3个层次,分别是AF、ZCL和应用层,分别详细讲解一下。

一. AF层

在前述章节已经详细讲解了AF层,可以调用AF层的数据通信API实现ZigBee设备之间的数据发送与接收。然而,直接使用AF层通信API的最大问题是不同公司开发的设备难以做到互联互通。

二. 应用层

开发者此层次中专注于开发设备的各个功能。在讲解AF通信的章节中,我们就是在应用层中直接调用AF层的通信API来发送和接收数据的。

三. ZCL层简介

ZigBee联盟在AF层与应用层之间构建了ZCL层,其最大的作用就是实现了各个ZigBee设备的互联互通。ZCL定义了ZigBee设备的各种应用领域(Profile)、设备类型(Device)、集群(Cluster)、设备属性和命令,这些定义均由ZigBee联盟统一定制。各个厂商在开发ZigBee设备时都遵循这些定义,便实现了互联互通了。

四. ZCL层的架构

(1)ZCL的大部分内容在Z-Stack 3.0 中的以下目录中:

  1. ...\\Z-Stack 3.0.1\\Components\\stack\\zcl

(2)它的部分内容如图所示。
第4章:ZCL 基本原理 - 图2
(3)一个设备一般只会使用ZCL中的部分内容,例如本书一直讲解的这个SampleSwitch工程使用了这些内容,如图所示。
第4章:ZCL 基本原理 - 图3

五. 代码分析

(1)我们对ZCL中的代码简单分析一下,打开zcl.h文件,可以找到ZCL层数据发送函数zcl_SendCommand(),代码如下:

  1. /*********************************************************************
  2. * @fn zcl_SendCommand
  3. *
  4. * @brief Used to send Profile and Cluster Specific Command messages.
  5. *
  6. * NOTE: The calling application is responsible for incrementing
  7. * the Sequence Number.
  8. *
  9. * @param srcEp - source endpoint
  10. * @param destAddr - destination address
  11. * @param clusterID - cluster ID
  12. * @param cmd - command ID
  13. * @param specific - whether the command is Cluster Specific
  14. * @param direction - client/server direction of the command
  15. * @param disableDefaultRsp - disable Default Response command
  16. * @param manuCode - manufacturer code for proprietary extensions to a profile
  17. * @param seqNumber - identification number for the transaction
  18. * @param cmdFormatLen - length of the command to be sent
  19. * @param cmdFormat - command to be sent
  20. *
  21. * @return ZSuccess if OK
  22. */
  23. ZStatus_t zcl_SendCommand( uint8 srcEP, afAddrType_t *destAddr,
  24. uint16 clusterID, uint8 cmd, uint8 specific, uint8 direction,
  25. uint8 disableDefaultRsp, uint16 manuCode, uint8 seqNum,
  26. uint16 cmdFormatLen, uint8 *cmdFormat )
  27. {
  28. endPointDesc_t *epDesc;
  29. zclFrameHdr_t hdr;
  30. uint8 *msgBuf;
  31. uint16 msgLen;
  32. uint8 *pBuf;
  33. uint8 options;
  34. ZStatus_t status;
  35. epDesc = afFindEndPointDesc( srcEP );
  36. if ( epDesc == NULL )
  37. {
  38. return ( ZInvalidParameter ); // EMBEDDED RETURN
  39. }
  40. #if defined ( INTER_PAN )
  41. if ( StubAPS_InterPan( destAddr->panId, destAddr->endPoint ) )
  42. {
  43. options = AF_TX_OPTIONS_NONE;
  44. }
  45. else
  46. #endif
  47. {
  48. options = zclGetClusterOption( srcEP, clusterID );
  49. // The cluster might not have been defined to use security but if this message
  50. // is in response to another message that was using APS security this message
  51. // will be sent with APS security
  52. if ( !( options & AF_EN_SECURITY ) )
  53. {
  54. afIncomingMSGPacket_t *origPkt = zcl_getRawAFMsg();
  55. if ( ( origPkt != NULL ) && ( origPkt->SecurityUse == TRUE ) )
  56. {
  57. options |= AF_EN_SECURITY;
  58. }
  59. }
  60. }
  61. zcl_memset( &hdr, 0, sizeof( zclFrameHdr_t ) );
  62. // Not Profile wide command (like READ, WRITE)
  63. if ( specific )
  64. {
  65. hdr.fc.type = ZCL_FRAME_TYPE_SPECIFIC_CMD;
  66. }
  67. else
  68. {
  69. hdr.fc.type = ZCL_FRAME_TYPE_PROFILE_CMD;
  70. }
  71. if ( ( epDesc->simpleDesc == NULL ) ||
  72. ( zcl_DeviceOperational( srcEP, clusterID, hdr.fc.type,
  73. cmd, epDesc->simpleDesc->AppProfId ) == FALSE ) )
  74. {
  75. return ( ZFailure ); // EMBEDDED RETURN
  76. }
  77. // Fill in the Maufacturer Code
  78. if ( manuCode != 0 )
  79. {
  80. hdr.fc.manuSpecific = 1;
  81. hdr.manuCode = manuCode;
  82. }
  83. // Set the Command Direction
  84. if ( direction )
  85. {
  86. hdr.fc.direction = ZCL_FRAME_SERVER_CLIENT_DIR;
  87. }
  88. else
  89. {
  90. hdr.fc.direction = ZCL_FRAME_CLIENT_SERVER_DIR;
  91. }
  92. // Set the Disable Default Response field
  93. if ( disableDefaultRsp )
  94. {
  95. hdr.fc.disableDefaultRsp = 1;
  96. }
  97. else
  98. {
  99. hdr.fc.disableDefaultRsp = 0;
  100. }
  101. // Fill in the Transaction Sequence Number
  102. hdr.transSeqNum = seqNum;
  103. // Fill in the command
  104. hdr.commandID = cmd;
  105. // calculate the needed buffer size
  106. msgLen = zclCalcHdrSize( &hdr );
  107. msgLen += cmdFormatLen;
  108. // Allocate the buffer needed
  109. msgBuf = zcl_mem_alloc( msgLen );
  110. if ( msgBuf != NULL )
  111. {
  112. // Fill in the ZCL Header
  113. pBuf = zclBuildHdr( &hdr, msgBuf );
  114. // Fill in the command frame
  115. zcl_memcpy( pBuf, cmdFormat, cmdFormatLen );
  116. status = AF_DataRequest( destAddr, epDesc, clusterID, msgLen, msgBuf,
  117. &zcl_TransID, options, AF_DEFAULT_RADIUS );
  118. zcl_mem_free ( msgBuf );
  119. }
  120. else
  121. {
  122. status = ZMemError;
  123. }
  124. return ( status );
  125. }

可以看到zcl_SendCommand()函数中,其实是调用AF层的数据发送函数AF_DataRequest()来发送数据的。

(2)在zcl.c文件中还有一个名为zcl_event_loop()的函数。在这个函数中,我们可以看到AF层数据的接收和处理,代码如图所示。
第4章:ZCL 基本原理 - 图4
以上的分析也印正了ZCL层的底层就是AF层。

4.2 ZCL 内容详解

ZCL主要包含有应用领域(Profile)、设备类型(Device)、集群(Cluster)、属性(Attribute)和命令(Command)这几部分内容。

一. 应用领域(Profile)

(1)前面的章节已经多次提过Profile了,在这里做一个正式的介绍。在ZigBee协议中,Profile是指应用领域。ZigBee协议中定义了多个Profile,例如面向家居自动的ZHA(ZigBee Home Automation)、面向照明的ZLL(ZigBee Light Link)等。本文一直在使用智能插座就是属于ZHA这个Profile的产品。
(2)ZigBee协议给每种类型的Profile分配了一个固定的ID,打开Profile/zcl_ha.h文件,可以找到ZHA Profile的ID值,代码如下:

  1. // Zigbee Home Automation Profile Identification
  2. #define ZCL_HA_PROFILE_ID 0x0104

(3)打开协议栈中的Components\stack\zcl\zcl_ll.h文件,可以找到ZLL Profile的ID值,代码如下:

  1. // Zigbee Light Link Profile Identification
  2. #define ZLL_PROFILE_ID 0xc05e

(4)使用这个方式,还可以查看其它Profile的ID。在讲解简单描述符的章节中,曾经讲到AppProfId字段表示这个简单描述符所属的应用场景,它的取值其实就是这些Profile ID。

二. 设备类型(Device)

(1)每种Profile可以包含多种类型的设备,例如ZHA Profile中包含智能插座、温湿度传感器、窗帘控制器等类型的设备。每种类型的设备都被分配了一个ID,称为Device ID,并且在同一个Profile,每个Device ID都是不同的。
(2)在 ZigBee 3.0 中,ZHA Profile中的各个设备类型被划分为5大类,分别是Generic、Lighting、Closures、HVAC(Heating Ventilation and Air Conditioning,供暖通风与空气调节)和IAS(Intruder Alarm Systems,入侵报警系统)。
第4章:ZCL 基本原理 - 图5
第4章:ZCL 基本原理 - 图6
第4章:ZCL 基本原理 - 图7
第4章:ZCL 基本原理 - 图8
第4章:ZCL 基本原理 - 图9
(3)ZHA相关的源文件是Profile工程目录下的zcl_ha.h和zcl_ha.c。打开zcl_ha.h文件,可以找到以上所有设备类型的Device ID,代码如下:
(3A)Generic

  1. // Generic Device IDs
  2. #define ZCL_HA_DEVICEID_ON_OFF_SWITCH 0x0000
  3. #define ZCL_HA_DEVICEID_LEVEL_CONTROL_SWITCH 0x0001
  4. #define ZCL_HA_DEVICEID_ON_OFF_OUTPUT 0x0002
  5. #define ZCL_HA_DEVICEID_LEVEL_CONTROLLABLE_OUTPUT 0x0003
  6. #define ZCL_HA_DEVICEID_SCENE_SELECTOR 0x0004
  7. #define ZCL_HA_DEVICEID_CONFIGURATION_TOOL 0x0005
  8. #define ZCL_HA_DEVICEID_REMOTE_CONTROL 0x0006
  9. #define ZCL_HA_DEVICEID_COMBINED_INTERFACE 0x0007
  10. #define ZCL_HA_DEVICEID_RANGE_EXTENDER 0x0008
  11. #define ZCL_HA_DEVICEID_MAINS_POWER_OUTLET 0x0009
  12. #define ZCL_HA_DEVICEID_DOOR_LOCK 0x000A
  13. #define ZCL_HA_DEVICEID_DOOR_LOCK_CONTROLLER 0x000B
  14. #define ZCL_HA_DEVICEID_SIMPLE_SENSOR 0x000C
  15. #define ZCL_HA_DEVICEID_CONSUMPTION_AWARENESS_DEVICE 0x000D
  16. #define ZCL_HA_DEVICEID_HOME_GATEWAY 0x0050
  17. #define ZCL_HA_DEVICEID_SMART_PLUG 0x0051
  18. #define ZCL_HA_DEVICEID_WHITE_GOODS 0x0052
  19. #define ZCL_HA_DEVICEID_METER_INTERFACE 0x0053

(3B)Lighting

  1. // Lighting Device IDs
  2. #define ZCL_HA_DEVICEID_ON_OFF_LIGHT 0x0100
  3. #define ZCL_HA_DEVICEID_DIMMABLE_LIGHT 0x0101
  4. #define ZCL_HA_DEVICEID_COLORED_DIMMABLE_LIGHT 0x0102
  5. #define ZCL_HA_DEVICEID_ON_OFF_LIGHT_SWITCH 0x0103
  6. #define ZCL_HA_DEVICEID_DIMMER_SWITCH 0x0104
  7. #define ZCL_HA_DEVICEID_COLOR_DIMMER_SWITCH 0x0105
  8. #define ZCL_HA_DEVICEID_LIGHT_SENSOR 0x0106
  9. #define ZCL_HA_DEVICEID_OCCUPANCY_SENSOR 0x0107

(3C)Closures

  1. // Closures Device IDs
  2. #define ZCL_HA_DEVICEID_SHADE 0x0200
  3. #define ZCL_HA_DEVICEID_SHADE_CONTROLLER 0x0201
  4. #define ZCL_HA_DEVICEID_WINDOW_COVERING_DEVICE 0x0202
  5. #define ZCL_HA_DEVICEID_WINDOW_COVERING_CONTROLLER 0x0203

(3D)HVAC

  1. // HVAC Device IDs
  2. #define ZCL_HA_DEVICEID_HEATING_COOLING_UNIT 0x0300
  3. #define ZCL_HA_DEVICEID_THERMOSTAT 0x0301
  4. #define ZCL_HA_DEVICEID_TEMPERATURE_SENSOR 0x0302
  5. #define ZCL_HA_DEVICEID_PUMP 0x0303
  6. #define ZCL_HA_DEVICEID_PUMP_CONTROLLER 0x0304
  7. #define ZCL_HA_DEVICEID_PRESSURE_SENSOR 0x0305
  8. #define ZCL_HA_DEVICEID_FLOW_SENSOR 0x0306
  9. #define ZCL_HA_DEVICEID_MINI_SPLIT_AC 0x0307

(3E)IAS

  1. // Intruder Alarm Systems (IAS) Device IDs
  2. #define ZCL_HA_DEVICEID_IAS_CONTROL_INDICATING_EQUIPMENT 0x0400
  3. #define ZCL_HA_DEVICEID_IAS_ANCILLARY_CONTROL_EQUIPMENT 0x0401
  4. #define ZCL_HA_DEVICEID_IAS_ZONE 0x0402
  5. #define ZCL_HA_DEVICEID_IAS_WARNING_DEVICE 0x0403

(4)ZLL相关的源文件在工程目录Profile下的zcl_ll.h和zcl_ll.c,打开zcl_ll.h文件,可以找到ZLL Profile(领域)定义的Device ID,代码如下:

  1. // ZLL Basic Lighting Device IDs
  2. #define ZLL_DEVICEID_ON_OFF_LIGHT 0x0000
  3. #define ZLL_DEVICEID_ON_OFF_PLUG_IN_UNIT 0x0010
  4. #define ZLL_DEVICEID_DIMMABLE_LIGHT 0x0100
  5. #define ZLL_DEVICEID_DIMMABLE_PLUG_IN_UNIT 0x0110
  6. // ZLL Color Lighting Device IDs
  7. #define ZLL_DEVICEID_COLOR_LIGHT 0x0200
  8. #define ZLL_DEVICEID_EXTENDED_COLOR_LIGHT 0x0210
  9. #define ZLL_DEVICEID_COLOR_TEMPERATURE_LIGHT 0x0220
  10. // ZLL Lighting Remotes Device IDs
  11. #define ZLL_DEVICEID_COLOR_CONTORLLER 0x0800
  12. #define ZLL_DEVICEID_COLOR_SCENE_CONTROLLER 0x0810
  13. #define ZLL_DEVICEID_NON_COLOR_CONTORLLER 0x0820
  14. #define ZLL_DEVICEID_NON_COLOR_SCENE_CONTROLLER 0x0830
  15. #define ZLL_DEVICEID_CONTROL_BRIDGE 0x0840
  16. #define ZLL_DEVICEID_ON_OFF_SENSOR 0x0850

(5)使用这个方式,还可以查看其它Profile中可以被使用的Device ID,在讲解简单描述符的章节中,曾经讲到AppDeviceId字段表示这个设备的类型,它的取值其实就是这些Device ID值。

三. 集群(Cluster)

(1)Cluster的作用是什么呢?读者可以保持着这个疑问继续往下阅读。
(2)在讲解AF通信的章节中,笔者自定义了3个Cluster ID,每个Cluster ID都代表着一个Cluster,用于表示不同的通信类型。这3个Cluster是笔者自定义的,并不是由ZigBee联盟定义的,因此只有自己写的代码能够理解它们的意义,其它开发者并不知道,所以这3个Cluster可以理解为是私有的。
(3)然而,ZigBee联盟已经定义了许多标准的Cluster,可供所有开发者使用,这些Cluster可以理解为是公有的。每一个Cluster分配有一个唯一的ID,称为 Cluster ID。这些Cluster可以分成两类:属于特定Profile的Cluster,以及各个Profile共用的、不属于某个Profile的一般性Cluster(General Clusters)。
(4)Cluster ID的定义在文件zcl.h中,本文列举部分Cluster,代码如下:
(4A)General Clusters

  1. // General Clusters
  2. #define ZCL_CLUSTER_ID_GEN_BASIC 0x0000
  3. #define ZCL_CLUSTER_ID_GEN_POWER_CFG 0x0001
  4. #define ZCL_CLUSTER_ID_GEN_DEVICE_TEMP_CONFIG 0x0002
  5. #define ZCL_CLUSTER_ID_GEN_IDENTIFY 0x0003
  6. #define ZCL_CLUSTER_ID_GEN_GROUPS 0x0004
  7. #define ZCL_CLUSTER_ID_GEN_SCENES 0x0005
  8. #define ZCL_CLUSTER_ID_GEN_ON_OFF 0x0006
  9. #define ZCL_CLUSTER_ID_GEN_ON_OFF_SWITCH_CONFIG 0x0007
  10. #define ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL 0x0008
  11. #define ZCL_CLUSTER_ID_GEN_ALARMS 0x0009
  12. #define ZCL_CLUSTER_ID_GEN_TIME 0x000A
  13. #define ZCL_CLUSTER_ID_GEN_LOCATION 0x000B
  14. #define ZCL_CLUSTER_ID_GEN_ANALOG_INPUT_BASIC 0x000C
  15. #define ZCL_CLUSTER_ID_GEN_ANALOG_OUTPUT_BASIC 0x000D
  16. #define ZCL_CLUSTER_ID_GEN_ANALOG_VALUE_BASIC 0x000E
  17. #define ZCL_CLUSTER_ID_GEN_BINARY_INPUT_BASIC 0x000F
  18. #define ZCL_CLUSTER_ID_GEN_BINARY_OUTPUT_BASIC 0x0010
  19. #define ZCL_CLUSTER_ID_GEN_BINARY_VALUE_BASIC 0x0011
  20. #define ZCL_CLUSTER_ID_GEN_MULTISTATE_INPUT_BASIC 0x0012
  21. #define ZCL_CLUSTER_ID_GEN_MULTISTATE_OUTPUT_BASIC 0x0013
  22. #define ZCL_CLUSTER_ID_GEN_MULTISTATE_VALUE_BASIC 0x0014
  23. #define ZCL_CLUSTER_ID_GEN_COMMISSIONING 0x0015
  24. #define ZCL_CLUSTER_ID_GEN_PARTITION 0x0016
  25. #define ZCL_CLUSTER_ID_GEN_POWER_PROFILE 0x001A
  26. #define ZCL_CLUSTER_ID_GEN_APPLIANCE_CONTROL 0x001B
  27. #define ZCL_CLUSTER_ID_GEN_POLL_CONTROL 0x0020

(4B)Retail Clusters

  1. // Retail Clusters
  2. #define ZCL_CLUSTER_ID_MOBILE_DEVICE_CONFIGURATION 0x0022
  3. #define ZCL_CLUSTER_ID_NEIGHBOR_CLEANING 0x0023
  4. #define ZCL_CLUSTER_ID_NEAREST_GATEWAY 0x0024

(4C)Closures Clusters

  1. // Closures Clusters
  2. #define ZCL_CLUSTER_ID_CLOSURES_SHADE_CONFIG 0x0100
  3. #define ZCL_CLUSTER_ID_CLOSURES_DOOR_LOCK 0x0101
  4. #define ZCL_CLUSTER_ID_CLOSURES_WINDOW_COVERING 0x0102

(4D)HVAC Clusters

  1. // HVAC Clusters
  2. #define ZCL_CLUSTER_ID_HVAC_PUMP_CONFIG_CONTROL 0x0200
  3. #define ZCL_CLUSTER_ID_HVAC_THERMOSTAT 0x0201
  4. #define ZCL_CLUSTER_ID_HVAC_FAN_CONTROL 0x0202
  5. #define ZCL_CLUSTER_ID_HVAC_DIHUMIDIFICATION_CONTROL 0x0203
  6. #define ZCL_CLUSTER_ID_HVAC_USER_INTERFACE_CONFIG 0x0204

(4E)Lighting Clusters

  1. // Lighting Clusters
  2. #define ZCL_CLUSTER_ID_LIGHTING_COLOR_CONTROL 0x0300
  3. #define ZCL_CLUSTER_ID_LIGHTING_BALLAST_CONFIG 0x0301

(4F)Measurement and Sensing Clusters

  1. // Measurement and Sensing Clusters
  2. #define ZCL_CLUSTER_ID_MS_ILLUMINANCE_MEASUREMENT 0x0400
  3. #define ZCL_CLUSTER_ID_MS_ILLUMINANCE_LEVEL_SENSING_CONFIG 0x0401
  4. #define ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT 0x0402
  5. #define ZCL_CLUSTER_ID_MS_PRESSURE_MEASUREMENT 0x0403
  6. #define ZCL_CLUSTER_ID_MS_FLOW_MEASUREMENT 0x0404
  7. #define ZCL_CLUSTER_ID_MS_RELATIVE_HUMIDITY 0x0405
  8. #define ZCL_CLUSTER_ID_MS_OCCUPANCY_SENSING 0x0406

(4G)Security and Safety (SS) Clusters

  1. // Security and Safety (SS) Clusters
  2. #define ZCL_CLUSTER_ID_SS_IAS_ZONE 0x0500
  3. #define ZCL_CLUSTER_ID_SS_IAS_ACE 0x0501
  4. #define ZCL_CLUSTER_ID_SS_IAS_WD 0x0502

(4H)Protocol Interfaces

  1. // Protocol Interfaces
  2. #define ZCL_CLUSTER_ID_PI_GENERIC_TUNNEL 0x0600
  3. #define ZCL_CLUSTER_ID_PI_BACNET_PROTOCOL_TUNNEL 0x0601
  4. #define ZCL_CLUSTER_ID_PI_ANALOG_INPUT_BACNET_REG 0x0602
  5. #define ZCL_CLUSTER_ID_PI_ANALOG_INPUT_BACNET_EXT 0x0603
  6. #define ZCL_CLUSTER_ID_PI_ANALOG_OUTPUT_BACNET_REG 0x0604
  7. #define ZCL_CLUSTER_ID_PI_ANALOG_OUTPUT_BACNET_EXT 0x0605
  8. #define ZCL_CLUSTER_ID_PI_ANALOG_VALUE_BACNET_REG 0x0606
  9. #define ZCL_CLUSTER_ID_PI_ANALOG_VALUE_BACNET_EXT 0x0607
  10. #define ZCL_CLUSTER_ID_PI_BINARY_INPUT_BACNET_REG 0x0608
  11. #define ZCL_CLUSTER_ID_PI_BINARY_INPUT_BACNET_EXT 0x0609
  12. #define ZCL_CLUSTER_ID_PI_BINARY_OUTPUT_BACNET_REG 0x060A
  13. #define ZCL_CLUSTER_ID_PI_BINARY_OUTPUT_BACNET_EXT 0x060B
  14. #define ZCL_CLUSTER_ID_PI_BINARY_VALUE_BACNET_REG 0x060C
  15. #define ZCL_CLUSTER_ID_PI_BINARY_VALUE_BACNET_EXT 0x060D
  16. #define ZCL_CLUSTER_ID_PI_MULTISTATE_INPUT_BACNET_REG 0x060E
  17. #define ZCL_CLUSTER_ID_PI_MULTISTATE_INPUT_BACNET_EXT 0x060F
  18. #define ZCL_CLUSTER_ID_PI_MULTISTATE_OUTPUT_BACNET_REG 0x0610
  19. #define ZCL_CLUSTER_ID_PI_MULTISTATE_OUTPUT_BACNET_EXT 0x0611
  20. #define ZCL_CLUSTER_ID_PI_MULTISTATE_VALUE_BACNET_REG 0x0612
  21. #define ZCL_CLUSTER_ID_PI_MULTISTATE_VALUE_BACNET_EXT 0x0613
  22. #define ZCL_CLUSTER_ID_PI_11073_PROTOCOL_TUNNEL 0x0614
  23. #define ZCL_CLUSTER_ID_PI_ISO7818_PROTOCOL_TUNNEL 0x0615
  24. #define ZCL_CLUSTER_ID_PI_RETAIL_TUNNEL 0x0617

(4I)Smart Energy (SE) Clusters

  1. // Smart Energy (SE) Clusters
  2. #define ZCL_CLUSTER_ID_SE_PRICE 0x0700
  3. #define ZCL_CLUSTER_ID_SE_DRLC 0x0701
  4. #define ZCL_CLUSTER_ID_SE_METERING 0x0702
  5. #define ZCL_CLUSTER_ID_SE_MESSAGING 0x0703
  6. #define ZCL_CLUSTER_ID_SE_TUNNELING 0x0704
  7. #define ZCL_CLUSTER_ID_SE_PREPAYMENT 0x0705
  8. #define ZCL_CLUSTER_ID_SE_ENERGY_MGMT 0x0706
  9. #define ZCL_CLUSTER_ID_SE_CALENDAR 0x0707
  10. #define ZCL_CLUSTER_ID_SE_DEVICE_MGMT 0x0708
  11. #define ZCL_CLUSTER_ID_SE_EVENTS 0x0709
  12. #define ZCL_CLUSTER_ID_SE_MDU_PAIRING 0x070A
  13. #define ZCL_CLUSTER_ID_SE_KEY_ESTABLISHMENT 0x0800
  14. #define ZCL_CLUSTER_ID_TELECOMMUNICATIONS_INFORMATION 0x0900
  15. #define ZCL_CLUSTER_ID_TELECOMMUNICATIONS_CHATTING 0x0904
  16. #define ZCL_CLUSTER_ID_TELECOMMUNICATIONS_VOICE_OVER_ZIGBEE 0x0905
  17. #define ZCL_CLUSTER_ID_HA_APPLIANCE_IDENTIFICATION 0x0B00
  18. #define ZCL_CLUSTER_ID_HA_METER_IDENTIFICATION 0x0B01
  19. #define ZCL_CLUSTER_ID_HA_APPLIANCE_EVENTS_ALERTS 0x0B02
  20. #define ZCL_CLUSTER_ID_HA_APPLIANCE_STATISTICS 0x0B03
  21. #define ZCL_CLUSTER_ID_HA_ELECTRICAL_MEASUREMENT 0x0B04
  22. #define ZCL_CLUSTER_ID_HA_DIAGNOSTIC 0x0B05

(4J)Light Link cluster

  1. // Light Link cluster
  2. #define ZCL_CLUSTER_ID_TOUCHLINK 0x1000

(5)每个Cluster中可以包含多个特定的属性(Attribute)和命令(Command)。

四. 属性(Attribute)

(1)与面向对象编程思想中属性类似,这里的属性是用来描述描述某一类事物的特点的,例如老虎的属性有性别、年龄和体重等属性。ZigBee联盟除了预定义了多个Cluster,还为每个Cluster预定义了一组对应的属性供开发者使用。Cluster应该包含哪几个属性,可由开发者自行定义。
(2)打开zcl_samplesw_data.c文件,可以找到如图所示代码。
第4章:ZCL 基本原理 - 图10
上述代码中创建了一个属性数组,这是一个结构体数组。分析一下其中的第1个元素:

  1. {
  2. ZCL_CLUSTER_ID_GEN_BASIC,//Basic Cluster,由ZigBee联盟预定义
  3. { //Attribute record
  4. ATTRID_BASIC_ZCL_VERSION,//ZCL版本号属性,由ZigBee联盟自定义
  5. ZCL_DATATYPE_UINT8,//说明这个属性的数据类型是8个比特位的变量(无符号整型变量)
  6. ACCESS_CONTROL_READ,//说明这个属性只能被读取不能被修改
  7. (void*)&zclSampleSw_ZCLVersion//函数引用,暂不做讲解
  8. }
  9. }

(3)上述代码的设计有点特别,其主要工作内容是往ZCL_CLUSTER_ID_GEN_BASIC这个Cluster中添加ATTRID_BASIC_ZCL_VERSION这个属性,并且说明这个属性的数据类型和只能被读取。
(4)再观察一下下面的两个元素,会发现其实是把另外两个属性也添加进ZCL_CLUSTER_ID_GEN_BASIC这个Cluster中。如此一来,这个Cluster便包含了3个属性,以及这3个属性对应的操作命令。

五 命令(Command)

(1)开发者可以让源设备向目标设备的某个Cluster发送命令。当目标设备接收到这条命令时,需要执行与该Cluster相关的处理,例如修改该Cluster的中的属性等。
(2)每个Cluster都包含有一组特定的命令,即每个Cluster只能接收一组特定的命令。命令可以分为两种,分别是基础命令和属性关联命令。

  • (2A)基础命令
    每个Cluster均包含基础命令,即基础命令能被所有Cluster接收,例如读命令、写命令和上报命令等,这部分命令的定义在zcl.h文件中,如图所示。
    第4章:ZCL 基本原理 - 图11
  • (2B)Cluster限定命令
    Cluster限定命令只存在于某些特定的Cluster中,即Cluster限定命令只能被某些特定的Cluster接收。打开zcl_general.h,可以找到如图所示代码:
    第4章:ZCL 基本原理 - 图12

(3)其中的COMMAND_OFF和COMMAND_ON就是专门作用于ON_OFF Cluster的命令。

六. Cluster应用举例

(1)现在终于可以举个例子说明Cluster的用途了。现在需要设计一盏支持亮度调整的ZigBee灯,可以用两个Cluster来描述其服务,分别是开关Cluster和亮度Cluster。

  • 开关Cluster用于表示和控制这个灯的开关状态,因此开关Cluster应该包含一个开关属性,并且能够被开命令和关命令来控制。
  • 亮度Cluster用于表示和控制这个灯的亮度,因此亮度Cluster应该包含一个亮度属性,并且能够被调整亮度命令来控制。

(2)从这个例子可以看出Cluster的作用是非常强大的,可用于在逻辑上实现设备的各个服务,而且其用途远不止于此,后续章节将讲解Cluster的更多用途。