更新时间:2023-12-12 02:26:25下载pdf
高级能力集合包括三个高级能力:带事务标识符(TID)下发命令、Vendor 心跳和设备状态打包查询。
由于 Mesh 协议的特性,在数据包较大时需要分包传输,数据越长分包越多就会导致延时与丢包。由于涂鸦产品在下发 DP 控制后需要设备回复后 App 上才会显示正确状态,所以如果数据包较长就会导致分包下发与分包上报。带 TID 命令下发,则设备只需要回复接收处理状态即可,提高了控制的响应速度与成功率。
此命令在使能后,通过 Vendor Model 发送数据长度较长、超过单包数据长度后,使用 SEG 分包数据时才会使用到此功能。
Vendor Model 自定义 opcode
做心跳可以附带更多的设备信息,例如心跳来源为设备回复还是设备上电等。SDK 中已经集成此部分功能,自动化处理设备的心跳回复。
另外,心跳中可以附带设备的开关状态。如果将开关状态注册到心跳中,则可以通过心跳来查询设备的在线状态,同时附加获取设备的开关状态。
Mesh 设备在进入 App 面板时会从设备本地同步当前的状态,当设备有较多数据需要同步时,可能会存在丢包的情况。如果将多个数据统一为一包或者几包数据,则会提高设备状态同步的效率。
但是针对于老版本 App 与网关,则仍会通过之前的通道进行查询。如果需要兼容老版本 App 与网关,则需要保留以前的状态查询回复逻辑(sig model get 指令以及 0xCCD007 opcode 0x01 CMD 数据)。
SDK 默认未开启,需要调用如下接口来开启此高级能力集合:
VOID_T tal_mesh_advanced_ability_1(UINT8_T enable);
注意:此能力位于高级能力集合中。开启后,高级能力集合中的另外两个能力(Vendor 心跳和设备状态打包查询)也会同时使能。
#define TAL_MESH_OPCODE_WRITE_WITH_TID (0xC8D007)
通过此接口,可以在 Vendor 心跳中附带 on off 状态信息,从而优化 App 内设备的快捷状态显示。
OPERATE_RET tal_mesh_heartbeat_onoff_info_set(UINT8_T enable, UINT8_T* onoff_status, UINT8_T onoff_dp_id);
enable
:是否使能心跳数据中携带开关 DP 数据。
onoff_status
:开关状态。
onoff_dp_id
:开关 DP ID。
typedef OPERATE_RET (*tal_mesh_vendor_get_cb)(UINT8_T dp_id, UINT8_T *dp_type, UINT8_T *dp_len, UINT8_T *dp_data);
DP 打包查询回调类型,应用层需实现此实例后将函数注册到 SDK 中。
OPERATE_RET tal_mesh_vendor_get_cb_init(tal_mesh_vendor_get_cb vendor_data_get_cb);
回调注册初始化 API。
App 发送
opcode
:0xC8D007 WRITE_WITH_TID
数据内容:
字段 | 长度(字节数) | 说明 |
---|---|---|
TID | 1 | 传输 ID 0-255 循环递增 |
CMD | 1 | 0x01 :DP 数据 |
数据 | N | Data point 组合,参考 蓝牙 Mesh 设备 Vendor Model 透传规范 |
设备回复
opcode
:0xCBD007 STATUS
数据内容:
字段 | 长度(字节数) | 说明 |
---|---|---|
TID | 1 | 回复指定接收数据的 TID |
status | 1 | 0x00 :数据接收成功 其他:数据异常 |
参考 Demo 中 app_common.c
文件,在 OPERATE_RET app_mesh_data_recv(TAL_MESH_ACCESS_MSG_T *msg_raw, TAL_MESH_NET_PARAM_T *net_param)
函数中,处理 TAL_MESH_OPCODE_WRITE_WITH_TID
此 opcode
的数据,同时需要设备回复接收状态。
OPERATE_RET app_mesh_data_recv(TAL_MESH_ACCESS_MSG_T *msg_raw, TAL_MESH_NET_PARAM_T *net_param)
{
switch (msg_raw->opcode) {
case TAL_MESH_OPCODE_WRITE_WITH_TID:{
// data_proc(); 数据处理
// 数据接收回复
UINT8_T data[2] = {0};
data[0] = msg_raw->data[0]; // TID
data[1] = 0x00;
tal_mesh_data_send(net_param->dst_addr, net_param->src_addr, TAL_MESH_OPCODE_STATUS, data, 2);
}
break;
default:
break;
}
return OPRT_OK;
}
OPERATE_RET app_mesh_vendor_get_recv(UINT8_T dp_id, UINT8_T *dp_type, UINT8_T *dp_len, UINT8_T *dp_data)
{
switch (dp_id) {
case DP_ID_ONOFF:
*dp_type = DP_TYPE_BOOL;
*dp_len = 1;
dp_data[0] = onoff_data;
break;
/* other DP */
default:
return OPRT_NOT_FOUND;
}
return OPRT_OK;
}
OPERATE_RET tuya_init_third(VOID_T)
{
/* other init process */
tal_mesh_advanced_ability_1(1);
tal_mesh_vendor_get_cb_init(app_mesh_vendor_get_recv);
tal_mesh_heartbeat_onoff_info_set(1, &onoff_data, 1);
return OPRT_OK;
}
SDK 中已经包含此消息的处理以及组包回复,但是设备的状态需要从应用层注册的回调中获取。
参考 app_common.c
文件中 OPERATE_RET tuya_init_third(VOID_T)
函数的接口调用 tal_mesh_vendor_get_cb_init(app_mesh_vendor_get_recv)
,通过此接口将状态查询回调注册到 SDK 中。
同时在应用中实现 OPERATE_RET app_mesh_vendor_get_recv(UINT8_T dp_id, UINT8_T *dp_type, UINT8_T *dp_len, UINT8_T *dp_data)
,当 SDK 中收到状态查询指令时,会通过此回调来查询设备的状态,您需要在此函数中实现对应 DP 数据的填充。
关于更加详细的代码,参考 Demo 中 app_common.c
的实现。
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈