设备数据点

更新时间:2023-05-12 08:08:02

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;
    }

    // String DP
    dataP[dpid_cnt].id = 3;
    tuya_user_api_lwdp_encode_string("hello world", &dataP[dpid_cnt]);
    dpid_cnt++;

    // Bool DP
    dataP[dpid_cnt].id = 9;
    tuya_user_api_lwdp_encode_bool(true, &dataP[dpid_cnt]);
    dpid_cnt++;

    // Integer DP
    dataP[dpid_cnt].id = 10;
    tuya_user_api_lwdp_encode_int(123, &dataP[dpid_cnt]);
    dpid_cnt++;

    // Enum DP
    dataP[dpid_cnt].id = 12;
    tuya_user_api_lwdp_encode_enum(2, &dataP[dpid_cnt]);
    dpid_cnt++;

    // MAP DP
    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);
	        }
        }

        //TODO:这里开始可以处理下发的数据包 dp_data.....

        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>
返回值
  • 0:函数执行正常
  • 其它:函数执行异常

详细说明

函数指针 lwdp_write_callback_t

// 用户根据此定义,定义自己的一个函数实现,并传入相应 API 接口
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>
返回值
  • 0:函数执行正常
  • 其它:函数执行异常

详细说明

函数指针 tuya_dp_ack_callback_t

// 用户根据此定义,定义自己的一个函数实现,并传入相应 API 接口
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

// 用户根据此定义,定义自己的一个函数实现,并传入相应 API 接口
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>
返回值
  • 0:正常
  • 其它值:异常,数据不可用

创建数据点空间

函数原型 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>
返回值
  • 0:函数执行正常
  • 其它函数执行异常,数据不可用

解码一个原始数据类型数据点信息

函数原型 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>
返回值
  • 0:函数执行正常
  • 其它函数执行异常,数据不可用

解码一个字符串型数据点信息

函数原型 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>
返回值
  • 0:函数执行正常
  • 其它:函数执行异常,数据不可用

解码一个枚举类型数据点信息

函数原型 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>
返回值
  • 0:函数执行正常
  • 其它:函数执行异常,数据不可用

编码一个布尔型数据点信息

函数原型 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>
返回值