更新时间:2024-11-20 08:51:21下载pdf
Bulk 大数据通道,即将按照特定格式存储在设备本地的数据,快速传输到 App 端的数据通道协议。
使用大数据通道可使设备快速上报 DP 数据。常应用于设备本地需要缓存大量离线数据的品类,且在蓝牙连接后快速上报本地离线数据。
例如蓝牙 智能手表/手环 等品类,在断开蓝牙连接后,设备依然会持续产生 分钟步数、分钟里程、分钟心率 等数据,但由于这些数据在离线情况下无法上传到手机,因此设备先将此类离线数据暂时缓存在本地 Flash 中。当用户打开 App 蓝牙连接设备后,App 将通过 大数据通道 指令通知设备上传本地缓存数据。
App -> 设备
字段 | 字节数 | 说明 |
---|---|---|
version | 1 | Bulk 大数据版本,当前固定为0x00。 |
bulk_type | 1 | Bulk 大数据类型,由具体产品定义,从 1 开始,0 表示通用类型数据。 |
设备 -> App
字段 | 字节数 | 说明 |
---|---|---|
version | 1 | Bulk 大数据版本,当前固定为0x00。 |
bulk_type | 1 | Bulk 大数据类型,由具体产品定义,从 1 开始,0 表示通用类型数据。 |
status | 1 | 状态
|
flag | 1 | 是否要App解析大数据 |
total_length | 4 | 数据总长度,大端格式。 |
total_crc32 | 4 | 数据总 CRC32,大端格式。 |
block_length | 2 | 块长度。大数据读取以块为单位,App 每次发送要读取的块编号,块数据会以回复的单包长度为单位分包发送。 |
App每发送一次读取 Bulk 块数据指令,设备会以响应帧中的单包长度,通过上报 Bulk 数据指令,分包上报块数据。
App -> 设备
字段 | 字节数 | 说明 |
---|---|---|
version | 1 | Bulk 大数据版本,当前固定为0x00。 |
bulk_type | 1 | Bulk 大数据类型,由具体产品定义,从 1 开始,0 表示通用类型数据。 |
block_number | 2 | 块编号:当前要读取的块编号(从0开始)。 |
设备 -> App
字段 | 字节数 | 说明 |
---|---|---|
version | 1 | Bulk 大数据版本,当前固定为0x00。 |
bulk_type | 1 | Bulk 大数据类型,由具体产品定义,从 1 开始,0 表示通用类型数据。 |
status | 1 | 状态
|
block_number | 2 | 块编号:当前要读取的块编号。 |
block_length | 2 | 块长度:当前要读取的块数据长度。 |
packet_length | 2 | 单包长度:本次读取的块数据上报的分包最大长度。 |
block_crc16 | 2 | 块CRC16:本地读取的块数据的 CRC16 |
App 每发送一次读取 Bulk 块数据指令,设备会通过该指令,自动分包发送本块数据。
举例说明:
设备 -> App
字段 | 字节数 | 说明 |
---|---|---|
version | 1 | Bulk 大数据版本,当前固定为0x00。 |
bulk_type | 1 | Bulk 大数据类型,由具体产品定义,从 1 开始,0 表示通用类型数据。 |
block_number | 2 | 块编号:当前要传输的块编号。 |
packet_number | 2 | 当前包编号:当前块数据中的数据分包发送编号,从0开始。 |
packet_length | 2 | 当前包长度:当前包数据长度。 |
packet_data | packet_length | 当前包数据。 |
App -> 设备
字段 | 字节数 | 说明 |
---|---|---|
version | 1 | Bulk 大数据版本,当前固定为0x00。 |
bulk_type | 1 | Bulk 大数据类型,由具体产品定义,从 1 开始,0 表示通用类型数据。 |
设备 -> App
字段 | 字节数 | 说明 |
---|---|---|
version | 1 | Bulk 大数据版本,当前固定为0x00。 |
bulk_type | 1 | Bulk 大数据类型,由具体产品定义,从 1 开始,0 表示通用类型数据。 |
status | 1 | 状态
|
TLD 格式主要用于设备本地存储和 App(不包括云端)数据解析。Bulk 大数据需要按照 TLD 格式传输,才能被 App 正确解析。目前有两种格式可供选择,请根据设备实际情况来选择。
字段 | 字节数 | 说明 |
---|---|---|
Type | 1 | 格式类型
|
Len | 2 | 数据长度 |
Data | Len | 数据长度 受到每包数据最大长度限制/不受限制(传输时不考虑存储结构) |
同一时刻产生的 DP 数据( App 解析)
Data 格式:
字段 | 字节数 | 说明 |
---|---|---|
UNIX_time | 4 | UNIX时间戳 |
DP_1 | DP1数据,详见 涂鸦DP数据 | |
… | ||
DP_n | DPn数据,详见 涂鸦DP数据 |
同一时刻产生的 DP 数据(包含用于嵌入式内存对齐的无效部分,App 解析)
Data 格式:
字段 | 字节数 | 说明 |
---|---|---|
storage_header | 6 | 与嵌入式存储结构相关,App无需解析 |
valid_data_len | 2 | 指UNIX时间戳+DP数据的总长度,大端传输 |
UNIX_time | 4 | UNIX时间戳 |
DP_1 | DP1数据,详见 涂鸦DP数据 | |
… | ||
DP_n | DPn数据,详见 涂鸦DP数据 | |
invalid_data | Len-6-2-valid_data_len | 无意义的填充数据,主要用于嵌入式内存对齐 |
Dp点1的数据 | ~ | Dp点n的数据 | ||||||
---|---|---|---|---|---|---|---|---|
1 | 2 | 3-4 | 5~ | ~ | n | n+1 | n+2-n+3 | n+4~ |
Dp_id | Dp_type | Dp_len | Dp_data | ~ | Dp_id | Dp_type | Dp_len | Dp_data |
函数名 | tuya_ble_bulk_data_read_block_size_get |
---|---|
函数原型 | uint32_t tuya_ble_bulk_data_read_block_size_get(void) |
功能概述 | 读取 Bulk 大数据块长度 |
参数 | 无 |
返回值 | Bulk 大数据块长度 |
备注 | 块的大小,是通过调用 tuya_ble_bulk_data_read_block_size_get 这个函数来确定的。这个函数会根据蓝牙MTU以及堆栈的大小,来确定一个块数据大小。 |
示例:
static uint32_t bulk_data_read_block_size = 0;
void tuya_ble_app_bulk_data_handler(tuya_ble_bulk_data_request_t *p_data)
{
switch (p_data->evt)
{
case TUYA_BLE_BULK_DATA_EVT_READ_INFO: {
bulk_data_read_block_size = tuya_ble_bulk_data_read_block_size_get();
} break;
//...
}
}
函数名 | tuya_ble_bulk_data_response |
---|---|
函数原型 | tuya_ble_status_t tuya_ble_bulk_data_response(tuya_ble_bulk_data_response_t *p_data) |
功能概述 | Bulk 大数据上传响应 |
参数 | p_data[in]:bulk_data 响应数据 |
返回值 |
|
备注 | 在设备接收到 App 的 Bulk 大数据命令后,需要调用该 API 进行响应。返回的参数需要按照上述说明的 协议命令 正确返回响应数据。 |
示例:
void tuya_ble_app_bulk_data_handler(tuya_ble_bulk_data_request_t *p_data)
{
uint8_t rsp_flag = 1;
tuya_ble_bulk_data_response_t rsp_data;
switch (p_data->evt)
{
case TUYA_BLE_BULK_DATA_EVT_READ_INFO: {
//...
} break;
case TUYA_BLE_BULK_DATA_EVT_READ_BLOCK: {
//...
} break;
case TUYA_BLE_BULK_DATA_EVT_SEND_DATA: {
//...
} break;
case TUYA_BLE_BULK_DATA_EVT_ERASE: {
//...
} break;
default: {
rsp_flag = 0;
} break;
}
if (rsp_flag)
{
tuya_ble_bulk_data_response(&rsp_data);
}
}
蓝牙 SDK 通过消息(Message)或者设备应用程序注册的回调(Callback)函数向设备应用程序发送数据(状态、数据等)。
当 App 向设备发送 Bulk 大数据相关命令后,蓝牙 SDK 都会向应用程序发送如下的 Bulk 大数据回调事件。需要您添加对应回调处理函数,并在回调处理函数中对大数据协议指令针对处理。更多详情,请参考 注册消息队列。
Event | TUYA_BLE_CB_EVT_BULK_DATA |
---|---|
对应数据结构 | tuya_ble_bulk_data_request_t |
描述 | Bulk 大数据上传通道数据请求回调事件 |
备注 | 用户可在该回调事件下处理 Bulk 大数据命令 |
数据结构:
typedef enum {
TUYA_BLE_BULK_DATA_EVT_READ_INFO, /**< 读取bulk信息事件*/
TUYA_BLE_BULK_DATA_EVT_READ_BLOCK, /**< 读取 Bulk 块数据事件*/
TUYA_BLE_BULK_DATA_EVT_SEND_DATA, /**< 上报 Bulk 数据事件*/
TUYA_BLE_BULK_DATA_EVT_ERASE, /**< 擦除 Bulk 数据事件*/
TUYA_BLE_BULK_DATA_EVT_UNKONWN, /**< 未知事件*/
} tuya_ble_bulk_data_evt_type_t;
typedef struct {
uint16_t block_number;
} tuya_ble_bulk_data_evt_read_block_req_t;
typedef struct {
uint16_t block_number;
} tuya_ble_bulk_data_evt_send_data_req_t;
typedef struct {
tuya_ble_bulk_data_evt_type_t evt; //具体大数据命令
uint8_t bulk_type;
union
{
tuya_ble_bulk_data_evt_read_block_req_t block_data_req_data;
tuya_ble_bulk_data_evt_send_data_req_t send_data_req_data;
} params;
} tuya_ble_bulk_data_request_t;
示例:
static void tuya_ble_sdk_callback(tuya_ble_cb_evt_param_t *event)
{
switch (event->evt)
{
//...
case TUYA_BLE_CB_EVT_BULK_DATA: { //在事件下补充大数据处理函数
tuya_ble_app_bulk_data_handler(&event->bulk_req_data);
} break;
//...
}
}
数据结构:
typedef struct {
uint8_t status; /**< 0-成功,后跟数据有效;1-无效,后跟数据无效或无后跟数据;其他-保留*/
uint8_t flag; /**< 0-需要 App 解析大数据;1-不需要 App 解析大数据,需要面板或云端去解析*/
uint32_t bulk_data_length; /**< 数据总长度*/
uint32_t bulk_data_crc; /**< 数据总CRC32*/
uint16_t block_data_length; /**< 块长度*/
} tuya_ble_bulk_data_evt_read_info_res_t;
typedef struct {
uint8_t status; /**< 0-成功;1-Type无效;2-块号无效;其他-保留*/
uint16_t block_number; /**< 块编号*/
uint16_t block_data_length; /**< 块长度*/
uint16_t block_data_crc16; /**< 块数据CRC16*/
uint16_t max_packet_data_length; /**< 本次读取的块数据上报的分包最大长度*/
} tuya_ble_bulk_data_evt_read_block_res_t;
typedef struct {
uint16_t current_block_number; /**< 当前传输的数据块编号*/
uint16_t current_block_length; /**< 当前传输的数据块总长度*/
uint8_t *p_current_block_data; /**< 当前传输的数据块数据指针*/
} tuya_ble_bulk_data_evt_send_data_res_t;
typedef struct {
uint8_t status; /**< 0-成功;1-失败;其他-保留*/
} tuya_ble_bulk_data_evt_erase_res_t;
typedef struct {
tuya_ble_bulk_data_evt_type_t evt;
uint8_t bulk_type;
union
{
tuya_ble_bulk_data_evt_read_info_res_t bulk_info_res_data;
tuya_ble_bulk_data_evt_read_block_res_t block_res_data;
tuya_ble_bulk_data_evt_send_data_res_t send_res_data;
tuya_ble_bulk_data_evt_erase_res_t erase_res_data;
} params;
} tuya_ble_bulk_data_response_t;
示例:
void tuya_ble_app_bulk_data_handler(tuya_ble_bulk_data_request_t *p_data)
{
uint8_t rsp_flag = 1;
tuya_ble_bulk_data_response_t rsp_data;
switch (p_data->evt)
{
case TUYA_BLE_BULK_DATA_EVT_READ_INFO: {
//解析判断 p_data 等数据
//根据条件赋值 rsp_data.bulk_info_res_data 等数据
} break;
case TUYA_BLE_BULK_DATA_EVT_READ_BLOCK: {
//解析判断 p_data->params.block_data_req_data 等数据
//根据条件赋值 rsp_data.block_res_data 等数据
} break;
case TUYA_BLE_BULK_DATA_EVT_SEND_DATA: {
//解析判断 p_data->params.send_data_req_data 等数据
//根据条件赋值 rsp_data.send_res_data 等数据
} break;
case TUYA_BLE_BULK_DATA_EVT_ERASE: {
//解析判断 p_data 等数据
//根据条件赋值 rsp_data.erase_res_data 等数据
} break;
default: {
rsp_flag = 0;
} break;
}
if (rsp_flag)
{
tuya_ble_bulk_data_response(&rsp_data); // 返回应答数据
if (rsp_data.evt == TUYA_BLE_BULK_DATA_EVT_SEND_DATA) {
tuya_ble_free(rsp_data.params.send_res_data.p_current_block_data);
}
}
}
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈