4.2 ZCL 内容详解
一句话理解
ZCL 由五层"零件"组成:Profile(应用领域)→ Device(设备类型)→ Cluster(簇)→ Attribute(属性)+ Command(命令)。这一节把它们逐个讲透。
一. 应用领域(Profile)
Profile 就是应用领域。ZigBee 协议定义了多个 Profile,例如:
- ZHA(ZigBee Home Automation):面向家居自动化——我们用的智能插座就属于 ZHA;
- ZLL(ZigBee Light Link):面向照明。
每种 Profile 都有一个固定 ID。打开 Profile/zcl_ha.h:
// Zigbee Home Automation Profile Identification
#define ZCL_HA_PROFILE_ID 0x0104打开 Components\stack\zcl\zcl_ll.h:
// Zigbee Light Link Profile Identification
#define ZLL_PROFILE_ID 0xc05e回顾
简单描述符里的 AppProfId 字段,填的就是这些 Profile ID。
二. 设备类型(Device)
每种 Profile 可以包含多种设备,如智能插座、温湿度传感器、窗帘控制器。每种设备分配一个 Device ID,同一 Profile 内各不相同。
ZHA 设备的 5 大类
ZHA Device ID 代码(zcl_ha.h)
Generic(通用):
// Generic Device IDs
#define ZCL_HA_DEVICEID_ON_OFF_SWITCH 0x0000
#define ZCL_HA_DEVICEID_LEVEL_CONTROL_SWITCH 0x0001
#define ZCL_HA_DEVICEID_ON_OFF_OUTPUT 0x0002
#define ZCL_HA_DEVICEID_LEVEL_CONTROLLABLE_OUTPUT 0x0003
#define ZCL_HA_DEVICEID_SCENE_SELECTOR 0x0004
#define ZCL_HA_DEVICEID_CONFIGURATION_TOOL 0x0005
#define ZCL_HA_DEVICEID_REMOTE_CONTROL 0x0006
#define ZCL_HA_DEVICEID_COMBINED_INTERFACE 0x0007
#define ZCL_HA_DEVICEID_RANGE_EXTENDER 0x0008
#define ZCL_HA_DEVICEID_MAINS_POWER_OUTLET 0x0009
#define ZCL_HA_DEVICEID_DOOR_LOCK 0x000A
#define ZCL_HA_DEVICEID_DOOR_LOCK_CONTROLLER 0x000B
#define ZCL_HA_DEVICEID_SIMPLE_SENSOR 0x000C
#define ZCL_HA_DEVICEID_CONSUMPTION_AWARENESS_DEVICE 0x000D
#define ZCL_HA_DEVICEID_HOME_GATEWAY 0x0050
#define ZCL_HA_DEVICEID_SMART_PLUG 0x0051
#define ZCL_HA_DEVICEID_WHITE_GOODS 0x0052
#define ZCL_HA_DEVICEID_METER_INTERFACE 0x0053Lighting(照明):
// Lighting Device IDs
#define ZCL_HA_DEVICEID_ON_OFF_LIGHT 0x0100
#define ZCL_HA_DEVICEID_DIMMABLE_LIGHT 0x0101
#define ZCL_HA_DEVICEID_COLORED_DIMMABLE_LIGHT 0x0102
#define ZCL_HA_DEVICEID_ON_OFF_LIGHT_SWITCH 0x0103
#define ZCL_HA_DEVICEID_DIMMER_SWITCH 0x0104
#define ZCL_HA_DEVICEID_COLOR_DIMMER_SWITCH 0x0105
#define ZCL_HA_DEVICEID_LIGHT_SENSOR 0x0106
#define ZCL_HA_DEVICEID_OCCUPANCY_SENSOR 0x0107Closures(闭合件)/ HVAC / IAS(节选):
// Closures Device IDs
#define ZCL_HA_DEVICEID_SHADE 0x0200
#define ZCL_HA_DEVICEID_SHADE_CONTROLLER 0x0201
#define ZCL_HA_DEVICEID_WINDOW_COVERING_DEVICE 0x0202
#define ZCL_HA_DEVICEID_WINDOW_COVERING_CONTROLLER 0x0203
// HVAC Device IDs
#define ZCL_HA_DEVICEID_HEATING_COOLING_UNIT 0x0300
#define ZCL_HA_DEVICEID_THERMOSTAT 0x0301
#define ZCL_HA_DEVICEID_TEMPERATURE_SENSOR 0x0302
#define ZCL_HA_DEVICEID_PUMP 0x0303
#define ZCL_HA_DEVICEID_PUMP_CONTROLLER 0x0304
#define ZCL_HA_DEVICEID_PRESSURE_SENSOR 0x0305
#define ZCL_HA_DEVICEID_FLOW_SENSOR 0x0306
#define ZCL_HA_DEVICEID_MINI_SPLIT_AC 0x0307
// Intruder Alarm Systems (IAS) Device IDs
#define ZCL_HA_DEVICEID_IAS_CONTROL_INDICATING_EQUIPMENT 0x0400
#define ZCL_HA_DEVICEID_IAS_ANCILLARY_CONTROL_EQUIPMENT 0x0401
#define ZCL_HA_DEVICEID_IAS_ZONE 0x0402
#define ZCL_HA_DEVICEID_IAS_WARNING_DEVICE 0x0403ZLL Device ID 代码(zcl_ll.h)
// ZLL Basic Lighting Device IDs
#define ZLL_DEVICEID_ON_OFF_LIGHT 0x0000
#define ZLL_DEVICEID_ON_OFF_PLUG_IN_UNIT 0x0010
#define ZLL_DEVICEID_DIMMABLE_LIGHT 0x0100
#define ZLL_DEVICEID_DIMMABLE_PLUG_IN_UNIT 0x0110
// ZLL Color Lighting Device IDs
#define ZLL_DEVICEID_COLOR_LIGHT 0x0200
#define ZLL_DEVICEID_EXTENDED_COLOR_LIGHT 0x0210
#define ZLL_DEVICEID_COLOR_TEMPERATURE_LIGHT 0x0220回顾
简单描述符里的 AppDeviceId 字段,填的就是这些 Device ID。
三. 集群(Cluster)
Cluster 是"公有"还是"私有"?
在第3章 AF 通信实验里,我们自定义了 3 个 Cluster ID(0、1、2)——那是私有 Cluster,只有自己写的代码认识。而 ZigBee 联盟预定义了大量标准 Cluster,所有开发者共用,这就是"公有 Cluster"。
每个 Cluster 有一个唯一 ID,分为两类:
- General Clusters(通用簇):所有 Profile 共用;
- 特定 Profile 的 Cluster:只属于某个领域。
常用 Cluster ID(zcl.h)
General Clusters(通用簇):
// General Clusters
#define ZCL_CLUSTER_ID_GEN_BASIC 0x0000
#define ZCL_CLUSTER_ID_GEN_POWER_CFG 0x0001
#define ZCL_CLUSTER_ID_GEN_DEVICE_TEMP_CONFIG 0x0002
#define ZCL_CLUSTER_ID_GEN_IDENTIFY 0x0003
#define ZCL_CLUSTER_ID_GEN_GROUPS 0x0004
#define ZCL_CLUSTER_ID_GEN_SCENES 0x0005
#define ZCL_CLUSTER_ID_GEN_ON_OFF 0x0006
#define ZCL_CLUSTER_ID_GEN_ON_OFF_SWITCH_CONFIG 0x0007
#define ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL 0x0008
#define ZCL_CLUSTER_ID_GEN_ALARMS 0x0009
#define ZCL_CLUSTER_ID_GEN_TIME 0x000A
#define ZCL_CLUSTER_ID_GEN_LOCATION 0x000BLighting / Measurement / SS(节选):
// Lighting Clusters
#define ZCL_CLUSTER_ID_LIGHTING_COLOR_CONTROL 0x0300
#define ZCL_CLUSTER_ID_LIGHTING_BALLAST_CONFIG 0x0301
// Measurement and Sensing Clusters
#define ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT 0x0402
#define ZCL_CLUSTER_ID_MS_PRESSURE_MEASUREMENT 0x0403
#define ZCL_CLUSTER_ID_MS_RELATIVE_HUMIDITY 0x0405
// Security and Safety (SS) Clusters
#define ZCL_CLUSTER_ID_SS_IAS_ZONE 0x0500
#define ZCL_CLUSTER_ID_SS_IAS_ACE 0x0501
#define ZCL_CLUSTER_ID_SS_IAS_WD 0x0502记忆法
0x0000开头 = 通用簇(谁都能用)0x0300= 照明0x0400= 测量与传感(温度 0x0402、湿度 0x0405)0x0500= 安防
四. 属性(Attribute)
属性描述事物的特点——就像面向对象编程里的成员变量:老虎有性别、年龄、体重。每个 Cluster 预定义了一组属性,开发者也可以自行定义。
打开 zcl_samplesw_data.c,可以看到属性数组 zclSampleSw_Attrs:
CONST zclAttrRec_t zclSampleSw_Attrs[] =
{
// *** General Basic Cluster Attributes ***
{
ZCL_CLUSTER_ID_GEN_BASIC, // Cluster: Basic(通用基础簇)
{ // Attribute record
ATTRID_BASIC_ZCL_VERSION, // ZCL 版本号属性
ZCL_DATATYPE_UINT8, // 数据类型:8 位无符号整型
ACCESS_CONTROL_READ, // 访问权限:只读
(void *)&zclSampleSw_ZCLVersion // 属性值的内存地址
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC, // Cluster: Basic
{
ATTRID_BASIC_HW_VERSION, // 硬件版本号属性
ZCL_DATATYPE_UINT8, // 数据类型:8 位无符号整型
ACCESS_CONTROL_READ, // 访问权限:只读
(void *)&zclSampleSw_HWRevision
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC, // Cluster: Basic
{
ATTRID_BASIC_MANUFACTURER_NAME, // 制造商名称属性
ZCL_DATATYPE_CHAR_STR, // 数据类型:字符串
ACCESS_CONTROL_READ, // 访问权限:只读
(void *)zclSampleSw_ManufacturerName
}
}
};每个元素做三件事:指定 Cluster → 指定属性 ID → 说明数据类型和访问权限(可读/可写)。
五. 命令(Command)
命令分两种:
1. 基础命令(Foundation Command)—— 所有 Cluster 通用
如读命令、写命令、上报命令。定义在 zcl.h:
// Foundation Command IDs
#define ZCL_CMD_READ 0x00 // 读
#define ZCL_CMD_READ_RSP 0x01 // 读响应
#define ZCL_CMD_WRITE 0x02 // 写
#define ZCL_CMD_WRITE_UNDIVIDED 0x03
#define ZCL_CMD_WRITE_RSP 0x04 // 写响应
#define ZCL_CMD_WRITE_NO_RSP 0x05
#define ZCL_CMD_CONFIG_REPORT 0x06 // 配置上报
#define ZCL_CMD_CONFIG_REPORT_RSP 0x07
#define ZCL_CMD_READ_REPORT_CFG 0x08
#define ZCL_CMD_READ_REPORT_CFG_RSP 0x09
#define ZCL_CMD_REPORT 0x0A // 上报
#define ZCL_CMD_DEFAULT_RSP 0x0B // 默认响应
#define ZCL_CMD_DISCOVER_ATTRS 0x0C2. Cluster 限定命令 —— 只在特定 Cluster 中存在
例如 On/Off Cluster(开关簇) 的命令,定义在 zcl_general.h:
// On/Off Cluster Commands
#define COMMAND_OFF 0x00 // 关闭
#define COMMAND_ON 0x01 // 打开
#define COMMAND_TOGGLE 0x02 // 反转
#define COMMAND_OFF_WITH_EFFECT 0x40
#define COMMAND_ON_WITH_RECALL_GLOBAL_SCENE 0x41
#define COMMAND_ON_WITH_TIMED_OFF 0x42这些命令只能被 On/Off Cluster 接收。
六. Cluster 应用举例:一盏可调光的 ZigBee 灯
现在把知识串起来。设计一盏支持亮度调整的 ZigBee 灯,用两个 Cluster 描述它的服务:
+ 开/关/反转命令
+ 调亮度命令
- 开关 Cluster:表示并控制灯的开关状态(开/关命令);
- 亮度 Cluster:表示并控制灯的亮度(调亮度命令)。
网关发"开灯"命令 → 目标灯设备在它的 On/Off Cluster 上收到命令 → 设备执行开灯动作。这就是 ZCL 让设备"说同一种语言"的魅力。
小结
- Profile = 领域(家居/照明);Device = 设备类型(插座/灯);
- Cluster = 服务(开关/亮度);Attribute = 服务里的数据;Command = 对服务下的指令。
- 下一章开始实战:用 ZCL 命令收发实现"网关控制插座开关"。
内容来源:紫甲 IoT《ZigBee 3.0 开发指南》第四部分·4.2 ZCL 内容详解,原站链接
本章自测
一、单项选择题(每题 4 分,共 40 分)
ZCL 五层"零件"从大到小的正确顺序是(A. Profile → Device → Cluster → Attribute + Command B. Device → Profile → Attribute → Cluster C. Cluster → Profile → Device → Command D. Attribute → Cluster → Profile → Device) 答案:A
ZHA(ZigBee Home Automation)的 Profile ID
ZCL_HA_PROFILE_ID是(A. 0xc05e B. 0x0104 C. 0x0006 D. 0x0300) 答案:BZLL(ZigBee Light Link)面向照明,其 Profile ID
ZLL_PROFILE_ID是(A. 0x0104 B. 0xc05e C. 0x0402 D. 0x0008) 答案:B在 ZHA 设备 5 大类中,"开关、遥控器、智能插座"等通用设备属于哪一类,其 Device ID 范围是(A. Lighting,0x0100~0x01FF B. Generic,0x0000~0x00FF C. HVAC,0x0300~0x03FF D. IAS,0x0400~0xFFFF) 答案:B
第 3 章实验里自定义的 3 个 Cluster ID(0、1、2)属于(A. 标准公有 Cluster B. 私有 Cluster,只有自己写的代码认识 C. 通用簇 D. 照明簇) 答案:B
On/Off(开关)簇
ZCL_CLUSTER_ID_GEN_ON_OFF的 Cluster ID 是(A. 0x0000 B. 0x0006 C. 0x0008 D. 0x0300) 答案:B按照书中的记忆法,测量与传感(Temperature 0x0402、Humidity 0x0405)类 Cluster 号段通常以哪个开头(A. 0x0000 B. 0x0300 C. 0x0400 D. 0x0500) 答案:C
在属性记录
zclAttrRec_t中,下列哪一项不是每个属性元素需要说明的内容(A. 属性 ID B. 数据类型(如 UINT8、CHAR_STR) C. 访问权限(可读 / 可写) D. 设备的 64 位扩展地址) 答案:D下列命令中,属于"所有 Cluster 通用"的基础命令(Foundation Command)的是(A. COMMAND_ON B. COMMAND_TOGGLE C. ZCL_CMD_READ(读属性) D. COMMAND_OFF) 答案:C
书中"一盏可调光的 ZigBee 灯"例子使用了哪两个 Cluster 来描述其服务(A. 开关簇 0x0006 + 亮度(Level Control)簇 0x0008 B. 基础簇 0x0000 + 时间簇 0x000A C. 温湿度簇 0x0402 + 0x0405 D. 安防簇 0x0500) 答案:A
二、问答题(每题 20 分,共 60 分)
- 题干:用一句话解释 Profile、Device、Cluster、Attribute、Command 这五层"零件"各自的含义(可借助书中的类比)。 参考答案要点:
- Profile = 应用领域(如家居自动化 ZHA、照明 ZLL),每种 Profile 有固定 ID。
- Device = 该领域下的设备类型(如插座、灯、传感器),用 Device ID 标识。
- Cluster = 对外提供的一项服务(如开关、亮度调节),每个簇有唯一 Cluster ID。
- Attribute = 服务里的数据(类似成员变量,如开关状态、亮度值),有属性 ID、数据类型和访问权限。
- Command = 对服务下的指令(如开、关、反转、读 / 写属性)。
- 题干:ZCL 的命令分为哪两类?请各举一例说明。 参考答案要点:
- 基础命令(Foundation Command):所有 Cluster 通用,如读属性 ZCL_CMD_READ(0x00)、写属性 ZCL_CMD_WRITE(0x02)、上报 ZCL_CMD_REPORT(0x0A)、默认响应 ZCL_CMD_DEFAULT_RSP(0x0B)。
- Cluster 限定命令:只在特定 Cluster 中存在,如 On/Off 簇的 COMMAND_OFF(0x00)、COMMAND_ON(0x01)、COMMAND_TOGGLE(0x02),只能被 On/Off Cluster 接收。
- 题干:为什么说 ZCL 让不同厂商的设备能"说同一种语言"?请结合可调光 ZigBee 灯的例子说明。 参考答案要点:
- 开关簇(0x0006)和亮度簇(0x0008)的 ID、属性、命令都由 ZigBee 联盟统一规定,所有厂商共用。
- 灯用开关簇表示并控制开关状态(开 / 关 / 反转命令),用亮度簇表示并控制亮度(0~254)。
- 网关发"开灯"命令 → 目标灯在自己的 On/Off 簇上收到命令并执行,无论灯和网关是哪家厂商生产的都能互相理解,从而实现互联互通。