1、 节点、设备、端点、簇、属性和命令,如下两图可以理解这几个概念的关系:
(图源于:锋硕的《ZigBee视频教程》的PDF文档)
在协议栈里每个端点应该是对应一个设备的,而上图中所表示的设备应该是指相同设备的集合。同时在HA规范文档中,已经定义了每种设备支持哪些簇(HA规范文档:《Home_Automation_Profile_for_Public_Download》)。
2、 要让zigbee节点实现某些功能(比如灯控制、可调亮度控制、可调颜色控制、窗帘控制等),那么就得在协议栈里注册符合HA规范的相应设备,这些设备可以采用多个zigbee节点分别控制,也可以在一个zigbee节点上同时注册这些设备来控制。那么,要在一个节点上实现这些设备,就得在初始化时注册好,协议栈SampleLight中的初始化程序如下:
void zclSampleLight_Init( byte task_id )
{
zclSampleLight_TaskID =task_id;
// Set destination addressto indirect
//zclSampleLight_DstAddr.addrMode = (afAddrMode_t)AddrNotPresent;
//zclSampleLight_DstAddr.endPoint = 0;
//zclSampleLight_DstAddr.addr.shortAddr = 0;
// This app is part of theHome Automation Profile
zclHA_Init( &zclSampleLight_SimpleDesc );
// Register the ZCL GeneralCluster Library callback functions
zclGeneral_RegisterCmdCallbacks(SAMPLELIGHT_ENDPOINT, &zclSampleLight_CmdCallbacks);
// Register theapplication's attribute list
zcl_registerAttrList( SAMPLELIGHT_ENDPOINT,SAMPLELIGHT_MAX_ATTRIBUTES,zclSampleLight_Attrs );
// Register the Applicationto receive the unprocessed Foundation command/response messages
zcl_registerForMsg(zclSampleLight_TaskID );
// Register for all keyevents - This app will handle all key events
RegisterForKeys(zclSampleLight_TaskID );
// Register for a testendpoint
afRegister(&sampleLight_TestEp );
}
分析:
(1) zclHA_Init( &zclSampleLight_SimpleDesc );
注册相关设备的设备描述(端点EndPoint、符合的规范(这里是HA规范ID)、设备ID、设备对应的输入簇和输出簇)
进入zclSampleLight_SimpleDesc参数,可以查看到本示例中的设备为可调灯设备:ZCL_HA_DEVICEID_DIMMABLE_LIGHT
对应规范文档中该设备的输入簇列表为:zclSampleLight_InClusterList
输出簇列表为:zclSampleLight_OutClusterList
(2) 注册好设备描述之后,当节点ZCL层接收到AF层发来的消息时,就会根据消息解析出设备描述,并匹配已经注册的设备描述,进入相应的设备端口(端点),在相应的簇里执行相关的命令。
命令的执行需要回调函数,初始化中对回调函数进行了注册:
zclGeneral_RegisterCmdCallbacks( SAMPLELIGHT_ENDPOINT, &zclSampleLight_CmdCallbacks);
进入zclSampleLight_CmdCallbacks参数中,查看它的类型为zclGeneral_AppCallbacks_t,这个类型实现了HA规范中的General功能域(即簇集,参考文档《07-5123-04-0afg-zigbee-cluster-library-specification》)的回调函数集定义,可以根据实际功能的需要来裁剪和自定义自己的回调函数集。
(功能域:规范中根据功能将簇划分为了不同的域(簇集合)(回调函数集的类型构建也根据功能域划分),这里和设备ID列表有些相似。但要区分开来,设备ID只是给设备一个规定的标号,而簇是要实现的功能。每个设备对应自己的簇,而且对应的簇可以是在不同的功能域(簇集合)里,具体对应哪些簇得看文档规范,与功能域的划分没有毛线关系。。)
(zstack中簇集列表的查看可以搜索General Clusters,设备ID列表的查看可以搜索Generic Device IDs)
General功能域的回调函数表(可以进入其类型zclGeneral_AppCallbacks_t查看):
static zclGeneral_AppCallbacks_tzclSampleLight_CmdCallbacks =
{
zclSampleLight_BasicResetCB, // Basic Cluster Reset command
zclSampleLight_IdentifyCB, // Identify command
zclSampleLight_IdentifyQueryRspCB, // Identify Query Responsecommand
zclSampleLight_OnOffCB, // On/Off cluster command
NULL, //Level Control Move to Level command
NULL, // Level Control Move command
NULL, // Level Control Step command
NULL, // GroupResponse commands
NULL, // Scene Store Request command
NULL, // Scene Recall Request command
NULL, // Scene Response command
NULL, // Alarm (Response) command
NULL, // RSSI Location commands
NULL, // RSSI Location Response commands
};
其中 zclSampleLight_OnOffCB() 函数正是执行开关命令的回调函数。如果要实现该可调灯设备的亮度调节,则在 // Level Control Move to Level command这一行添加回调函数(自定义)。
而控制端只需通过调用《Z-Stack ZCL API》中的zclGeneral_SendLevelControlMoveToLevel();API来发送控制命令。
问题:
怎么自定义回调函数?(可以根据上面已经实现的回调函数进行自定义)
怎么构建其它的回调函数集??(在《Z-Stack ZCL API》文档第4~5页中有找到以上General功能域和Protocol Interfaces功能域的回调函数集的类型定义,但没找到其它功能域的类型定义。。如果要实现Lighting Clusters功能域下的COLOR_CONTROL命令该怎么做??命令API也只定义了General 功能域和ProtocolInterfaces功能域的API,而其它功能域的命令发送函数要自己定义吗??)