NB-IoT 设备所有与云端的交互流程都依赖数据点功能,本文档将介绍 TuyaOS 设备数据点功能。
背景信息
根据具体的产品形态,设备数据点类型各不相同,可根据实际数据类型调用相应的编解码接口进行数据的组包或解析,同时 NB-IoT 还具备记录型数据上报的特性,可根据实际使用场景进行选择。
实现示例
多 DP 组合上报举例:
static void multi_dps_report_demo(void)
{
int max_num_dp = 7;
int dpid_cnt = 0;
lwdp_object_t* dataP = tuya_user_api_lwdp_object_new(max_num_dp);
if (dataP == NULL) {
USER_API_LOGE("lwdp obj malloc fail");
return;
}
dataP[dpid_cnt].id = 3;
tuya_user_api_lwdp_encode_string("hello world", &dataP[dpid_cnt]);
dpid_cnt++;
dataP[dpid_cnt].id = 9;
tuya_user_api_lwdp_encode_bool(true, &dataP[dpid_cnt]);
dpid_cnt++;
dataP[dpid_cnt].id = 10;
tuya_user_api_lwdp_encode_int(123, &dataP[dpid_cnt]);
dpid_cnt++;
dataP[dpid_cnt].id = 12;
tuya_user_api_lwdp_encode_enum(2, &dataP[dpid_cnt]);
dpid_cnt++;
dataP[dpid_cnt].id = 19;
tuya_user_api_lwdp_encode_map(0xff55, &dataP[dpid_cnt]);
dpid_cnt++;
tuya_user_api_dp_report(true, dpid_cnt, dataP);
tuya_user_api_lwdp_object_free(max_num_dp, dataP);
}
云端下发数据命令处理示例:
static uint8_t tuya_dp_write_cb(IN lwdp_object_t* dataP)
{
uint16_t len;
size_t str_len;
int32_t value;
if(NULL == dataP){
USER_API_LOGE("dataP NULL");
return CODE_UNKOWN_ERROR;
}
while(NULL != dataP){
com_dp_data_t* dp_data = NULL;
uint8_t* send_buffer = NULL;
uint8_t* p_dp_data_buf = NULL;
len = tuya_user_api_get_lwdp_object_length(dataP);
send_buffer = (uint8_t*)Malloc(sizeof(com_dp_data_t) + len + 1);
if (send_buffer == NULL) {
USER_API_LOGE("send_buffer is NULL");
return CODE_UNKOWN_ERROR;
}
memset(send_buffer, 0, sizeof(com_dp_data_t) + len + 1);
dp_data = (com_dp_data_t*)send_buffer;
p_dp_data_buf = (uint8_t *)dp_data + sizeof(com_dp_data_t);
switch (dataP->type) {
case DP_TYPE_BOOLEAN:
tuya_user_api_lwdp_decode_bool(dataP, (bool*)p_dp_data_buf);
break;
case DP_TYPE_INTEGER:
tuya_user_api_lwdp_decode_int(dataP, &value);
value = DWORD_SWAP(value);
memcpy(p_dp_data_buf, &value, sizeof(int32_t));
break;
case DP_TYPE_RAW:
tuya_user_api_lwdp_decode_raw(dataP, p_dp_data_buf, &str_len);
break;
case DP_TYPE_ENUM:
tuya_user_api_lwdp_decode_enum(dataP, p_dp_data_buf);
break;
case DP_TYPE_STRING:
tuya_user_api_lwdp_decode_string(dataP, (char*)p_dp_data_buf, &str_len);
break;
}
dp_data->dpid = dataP->id;
dp_data->type = dataP->type;
USER_API_LOGI("tuya_dp_write_cb DP:%d, type:%d, len:%d", dp_data->dpid, dp_data->type, len);
dp_data->len = WORD_SWAP(len);
if(DPID_HEARTBEAT_INTERVAL == dp_data->dpid){
uint32_t lifetime = 0;
if (len == 4) {
((uint8_t*)(&lifetime))[0] = p_dp_data_buf[3];
((uint8_t*)(&lifetime))[1] = p_dp_data_buf[2];
((uint8_t*)(&lifetime))[2] = p_dp_data_buf[1];
((uint8_t*)(&lifetime))[3] = p_dp_data_buf[0];
tuya_user_api_lifetime_set(lifetime);
}
}
Free(send_buffer);
dataP = dataP->next;
}
return CODE_NO_ERROR;
}
API 说明
设置云端下发数据点的回调函数
函数原型 |
int tuya_user_api_dp_write_default_cb (IN lwdp_write_callback_t cb) |
参数 |
cb:待设置的回调函数指针,具体请参照下文详细说明 |
功能 |
设置云端下发数据点的回调函数 |
头文件 |
#include <tuya_user_api.h> |
返回值 |
|
详细说明
函数指针 lwdp_write_callback_t
:
typedef uint8_t (*lwdp_write_callback_t)(lwdp_object_t* objectArrayP);
设置非记录型数据点上报结果的回调函数
函数原型 |
void tuya_user_api_dp_report_ack_register_cb (IN tuya_dp_ack_callback_t cb) |
参数 |
cb:待设置的回调函数指针,具体请参照下文详细说明 |
功能 |
设置非记录型数据点上报结果的回调函数 |
头文件 |
#include <tuya_user_api.h> |
返回值 |
|
详细说明
函数指针 tuya_dp_ack_callback_t
:
typedef void (*tuya_dp_ack_callback_t)(uint16_t msgid, uint8_t result);
获取非记录型数据的数量个数
函数原型 |
int tuya_user_api_not_record_packet_count(void) |
参数 |
无 |
功能 |
获取非记录型数据的数量 |
头文件 |
#include <tuya_user_api.h> |
返回值 |
返回非记录型数据数量 |
设置记录型数据点上报结果的回调函数
函数原型 |
void tuya_user_api_dp_report_record_ack_register_cb (IN tuya_dp_ack_callback_t cb) |
参数 |
cb :待设置用户 DP 点上报回调函数指针 |
功能 |
设置记录型数据点上报结果的回调函数 |
头文件 |
#include <tuya_user_api.h> |
返回值 |
无 |
详细说明
函数指针 tuya_dp_ack_callback_t
:
typedef void (*tuya_dp_ack_callback_t)(uint16_t msgid, uint8_t result);
数据点上报
函数原型 |
int tuya_user_api_dp_report (IN bool is_record_type, IN int size, IN lwdp_object_t* dataP) |
参数 |
is_record_type : true(记录型数据),false(非记录型数据) size : 多少个数据项 dataP : DP 点数据指针,具体请参照下文结构体[^lwdp_object_t] 的详细说明
|
功能 |
数据点上报 |
头文件 |
#include <tuya_user_api.h> |
返回值 |
|
创建数据点空间
函数原型 |
lwdp_object_t* tuya_user_api_lwdp_object_new(IN int size) |
参数 |
size : 创建数据点个数 |
功能 |
创建数据点空间 |
头文件 |
#include <tuya_user_api.h> |
返回值 |
返回 DP 点实例的指针,具体请参考详细说明结构体[^lwdp_object_t] |
释放数据点空间
函数原型 |
void tuya_user_api_lwdp_object_free (IN int size, IN lwdp_object_t* dataP) |
参数 |
size : 释放的数据点个数 dataP : 释放的数据点起始地址,具体请参考详细说明结构体[^lwdp_object_t]
|
功能 |
释放数据点空间 |
头文件 |
#include <tuya_user_api.h> |
返回值 |
DP 点实例的指针 |
获取 当前 DP 数据包的字节长度
函数原型 |
uint16_t tuya_user_api_get_lwdp_object_length (IN lwdp_object_t* dataP) |
参数 |
dataP :待获取的lwdp_object_t 对象,具体请参考详细说明结构体[^lwdp_object_t] |
功能 |
获取 当前 DP 数据包的字节长度 |
头文件 |
#include <tuya_user_api.h> |
返回值 |
无 |
解码一个布尔型数据点信息
函数原型 |
int tuya_user_api_lwdp_decode_bool (IN lwdp_object_t* dataP, OUT bool* outP) |
参数 |
dataP :待解码的lwdp_object_t 对象,具体请参考详细说明结构体[^lwdp_object_t] outP :解码出来的bool 数据
|
功能 |
解码一个布尔型数据点信息 |
头文件 |
#include <tuya_user_api.h> |
返回值 |
无 |
解码一个整型数据点信息
函数原型 |
int tuya_user_api_lwdp_decode_int (IN lwdp_object_t* dataP, OUT int32_t* outP) |
参数 |
dataP :待解码的lwdp_object_t 对象,具体请参考详细说明结构体[^lwdp_object_t] outP :解码出来的 int 数据
|
功能 |
解码一个整型数据点信息 |
头文件 |
#include <tuya_user_api.h> |
返回值 |
|
解码一个原始数据类型数据点信息
函数原型 |
int tuya_user_api_lwdp_decode_raw (IN lwdp_object_t* dataP, OUT uint8_t* outP, OUT size_t* olen) |
参数 |
dataP :待解码的lwdp_object_t 对象,具体请参考详细说明结构体[^lwdp_object_t] outP :解码出来的 raw 数据 olen :解码出来的 raw 数据字节长度
|
功能 |
解码一个原始数据类型数据点信息 |
头文件 |
#include <tuya_user_api.h> |
返回值 |
|
解码一个字符串型数据点信息
函数原型 |
int tuya_user_api_lwdp_decode_string (IN lwdp_object_t* dataP, OUT char* outP, OUT size_t* olen) |
参数 |
dataP :待解码的lwdp_object_t 对象,具体请参考详细说明结构体[^lwdp_object_t] outP :解码出来的string 字符串指针 olen :返回解码出来的string 字符串长度
|
功能 |
解码一个字符串型数据点信息 |
头文件 |
#include <tuya_user_api.h> |
返回值 |
|
解码一个枚举类型数据点信息
函数原型 |
int tuya_user_api_lwdp_decode_enum (IN lwdp_object_t* dataP, OUT uint8_t* enum_idx) |
参数 |
dataP :待解码的lwdp_object_t 对象,具体请参考详细说明结构体[^lwdp_object_t] enum_idx :解码出来的enum 枚举下标
|
功能 |
解码一个枚举类型数据点信息 |
头文件 |
#include <tuya_user_api.h> |
返回值 |
|
编码一个布尔型数据点信息
函数原型 |
void tuya_user_api_lwdp_encode_bool (IN bool value, OUT lwdp_object_t* dataP) |
参数 |
value :待编码的bool 数据 dataP :待编码的lwdp_object_t 对象,具体请参考详细说明结构体[^lwdp_object_t]
|
功能 |
编码一个布尔型数据点信息 |
头文件 |
#include <tuya_user_api.h> |
返回值 |
无 |
编码一个原始数据类型数据点信息
函数原型 |
void tuya_user_api_lwdp_encode_raw (IN uint8_t* buffer, IN size_t length, OUT lwdp_object_t* dataP) |
参数 |
buffer :待编码成 lwdp_object_t 对象的 raw 类型数据指 length :待编码的 raw 类型数据的字节长度 dataP :封装后返回的对象,具体请参考详细说明结构体[^lwdp_object_t]
|
功能 |
编码一个原始数据类型数据点信息 |
头文件 |
#include <tuya_user_api.h> |
返回值 |
无 |
编码一个字符串型数据点信息
函数原型 |
void tuya_user_api_lwdp_encode_string (IN const char* string, OUT lwdp_object_t* dataP) |
参数 |
string :待封装成lwdp_object_t 对象的string 类型数据指针 dataP :封装后返回的对象,具体请参考详细说明结构体[^lwdp_object_t]
|
功能 |
编码一个字符串型数据点信息 |
头文件 |
#include <tuya_user_api.h> |
返回值 |
无 |
编码一个字符串型数据点信息(带字符长度)
函数原型 |
void tuya_user_api_lwdp_encode_nstring (IN const char* string, IN size_t length, OUT lwdp_object_t* dataP) |
参数 |
string :待编码成lwdp_object_t 对象的 string 类型数据指针 length :待编码的string 字符串长度 dataP :封装后返回的对象,具体请参考详细说明结构体[^lwdp_object_t]
|
功能 |
编码一个字符串型数据点信息 |
头文件 |
#include <tuya_user_api.h> |
返回值 |
无 |
编码一个整型数据点信息
函数原型 |
void tuya_user_api_lwdp_encode_int (IN int32_t value, OUT lwdp_object_t* dataP) |
参数 |
value :待编码成 int 类型的数据 dataP :编码后返回的对象,具体请参考详细说明结构体[^lwdp_object_t]
|
功能 |
编码一个整型数据点信息 |
头文件 |
#include <tuya_user_api.h> |
返回值 |
无 |
编码一个枚举类型数据点信息
函数原型 |
void tuya_user_api_lwdp_encode_enum (IN uint32_t value, OUT lwdp_object_t* dataP) |
参数 |
value :待编码成枚举类型的数据 dataP :编码后返回的对象,具体请参考详细说明结构体[^lwdp_object_t]
|
功能 |
编码一个枚举类型数据点信息 |
头文件 |
#include <tuya_user_api.h> |
返回值 |
无 |
编码一个位图类型数据点信息
函数原型 |
void tuya_user_api_lwdp_encode_map (IN uint32_t value, OUT lwdp_object_t* dataP) |
参数 |
value :待编码成位图类型的数据 dataP :编码后返回的对象,具体请参考详细说明结构体[^lwdp_object_t]
|
功能 |
编码一个位图类型数据点信息 |
头文件 |
#include <tuya_user_api.h> |
返回值 |
无 |