【技术干货】DP 开发帮助

Wi-Fi 设备、Wi-Fi 低功耗设备、Wi-Fi BLE 双模设备、Ethernet设备、Ethernet+Wi-Fi设备等
Post Reply
yangjie
Posts: 145

DP模型说明

DP模型是涂鸦平台设备模型,通过DP点来描述设备的能力。TuyaOS通过DP点的组合文件(schema文件),即可知道设备的能力,然后解析schema文件,将设备实例化。所以DP的开发是TuyaOS开发的非常重要的部分,影响到设备能否正常、文档、一致。本文档将汇聚DP开发过程中的一些注意点,希望能够帮助开发者快速的了解、掌握DP点开发过程中的窍门。

关于 DP 更多信息可以点击查看DP 模型与控制协议

DP 上报频率

涂鸦平台规定,一台设备上报DP数量不超过3500次/天,超过这个频率的DP有可能被云端丢弃,导致设备功能异常;同时频繁上报可能导致一些系统异常,使得设备无法正常工作。所以在DP开发过程中需要避免频繁上报,合理就好。

OBJ DP、Stat OBJ DP和RAW DP

  • OBJ DP 是对象型DP,支持数据类型为:value、bool、enum、string、bitmap。一般用来处理简单的功能。OBJ DP上报的时候使用异步上报接口,TuyaOS 内部会对这些DP进行合法校验、缓存,上报失败也会进行重传。

    Code: Select all

     // 异步上报,是否带时间戳,由dp_data的time_stamp成员确定
     OPERATE_RET dev_report_dp_json_async(IN CONST CHAR_T *dev_id, IN CONST TY_OBJ_DP_S *dp_data, IN CONST UINT_T cnt);
  • Stat OBJ DP 是对象型 DP,用于记录某一时刻的设备状态和产生的数据,此时 DP 的时间是表示产生这条 DP 记录的时间而非上报时间。如门锁解锁记录上报,告警,电量统计等 DP。Stat OBJ DP 使用同步上报,TuyaOS 内部不会对这些DP进行合法校验、缓存,上报失败需要开发者自行处理。因为同步上报能够知道这次上报是否成功上报到了云端,这样才能够避免数据的漏报或者重复上报。

    Code: Select all

     // 同步上报STAT OBJ DP,是否带时间戳,由dp_data的time_stamp成员确定  
     OPERATE_RET dev_report_dp_stat_sync_extend(IN CONST CHAR_T *dev_id, IN CONST TY_OBJ_DP_S *dp_data,
                                                  IN CONST UINT_T cnt, IN CONST UINT_T timeout, IN CONST BOOL_T enable_auto_retrans);
     #define dev_report_dp_stat_sync(dev_id, dp_data, cnt, timeout) \
           dev_report_dp_stat_sync_extend(dev_id, dp_data, cnt, timeout, TRUE)
  • RAW DP是原始型DP,他的数据是复合型的,允许开发者自行定义DP的长度,以及DP每个bit、byte的含义,从而使得DP可以处理复杂的功能、协议。RAW DP上报的时候使用同步上报接口,TuyaOS 内部不会对这些DP进行合法校验、缓存,上报失败需要开发者自行处理,比如说重试。

    Code: Select all

     // 同步上报RAW DP   
     OPERATE_RET dev_report_dp_raw_sync_extend(IN CONST CHAR_T *dev_id, IN CONST BYTE_T dpid,
                                                 IN CONST BYTE_T *data, IN CONST UINT_T len,
                                                 IN CONST UINT_T timeout, IN CONST BOOL_T enable_auto_retrans);
     #define dev_report_dp_raw_sync(dev_id, dpid, data, len, timeout) \
           dev_report_dp_raw_sync_extend(dev_id, dpid, data, len, timeout, TRUE)
     
     // 同步上报RAW DP,带时间戳
     OPERATE_RET dev_report_dp_raw_sync_extend_with_time(IN CONST CHAR_T *dev_id, IN CONST BYTE_T dpid,
                                                           IN CONST BYTE_T *data, IN CONST UINT_T len,
                                                           IN CONST UINT_T timeout, IN CONST BOOL_T enable_auto_retrans,
                                                           IN CONST CHAR_T *time_str);
     #define dev_report_dp_raw_sync_with_time(dev_id, dpid, data, len, timeout, time_str) \
           dev_report_dp_raw_sync_extend_with_time(dev_id, dpid, data, len, timeout, TRUE, time_str)

DP 组合上报

TuyaOS DP上报每次接口调用,都会有队列机制等待涂鸦云确认上报成功/超时,频繁的接口调用会导致队列被占用完毕,使得后续的DP上报失败。因此一次性上报多个DP的时候,可以把多个DP组合成一个DP数组,然后调用接口上报,可以参考以下代码。

注意:RAW DP和OBJ DP不能组合一次上报。

Code: Select all

    OPERATE_RET rt = OPRT_OK;
    TY_OBJ_DP_S all_report_data[2];
    memset(all_report_data, 0, 2*SIZEOF(TY_OBJ_DP_S));

    /* bool type data */
    all_report_data[0].dpid = DPID_SWITCH;
    all_report_data[0].type = PROP_BOOL;
    all_report_data[0].value.dp_bool = light.switch_status;
    all_report_data[0].time_stamp = 0;

    /* enum type data */
    all_report_data[1].dpid = DPID_MODE;
    all_report_data[1].type = PROP_ENUM;
    all_report_data[1].value.dp_enum = light.mode;
    all_report_data[1].time_stamp = 0;

    TUYA_CALL_ERR_LOG(dev_report_dp_json_async(NULL, all_report_data, 2));

DP 低功耗缓存

一些低功耗设备,因为工作机制的限制,模组大部分时间处于休眠状态,不能实时响应 APP 的DP下发。可以通过低功耗DP缓存的方式,把在模组休眠的时候缓存相关的DP下发,并在模组唤醒的时候,获取并执行缓存的DP。获取低功耗缓存DP的接口和使用示例如下:

Code: Select all

/** 
 * @brief tuya_iot_dp_low_power_query
 *
 * @param[in] dps: data of DP
 * @param[in] cnt: count of DP
 * @param[out] obj_dps: get object type DP
 * @param[out] raw_dps: get raw type DP
 *
 * @return OPRT_OK: success  Other: fail
 */
 OPERATE_RET tuya_iot_dp_low_power_query(IN CONST UCHAR_T *dps, IN CONST UINT_T cnt, OUT TY_RECV_OBJ_DP_S **obj_dps, OUT                                                  TY_RECV_MULTI_RAW_DP_S **raw_dps);

// 使用tuya_iot_dp_low_power_query获取缓存DP
VOID example_get_cached_dp() 
{
    OPERATE_RET op_ret = OPRT_OK;
    UCHAR_T dps = [1,3,4,6,7]; // 想要从云端拉取的dp id列表,由应用决定
    UINT_T cnt = CNTSOF(dps); // cnt=0 表示查询所有缓存的DP
    TY_RECV_OBJ_DP_S *obj_dps = NULL; 
    TY_RECV_RAW_DP_S *raw_dps = NULL; // 只会返回一个raw型dp,所以RAW DP最好和OBJ分开,并且一个一个的去获取

    op_ret = tuya_iot_dp_low_power_query(dps, cnt, &obj_dps, &raw_dps);
    /*
    * TODO:根据应用场景,处理返回的dp列表
    * 与正常的dp指令,即DEV_OBJ_DP_CMD_CB以及DEV_RAW_DP_CMD_CB的处理类似
    */
    
    Free(obj_dps);
    Free(raw_dps);
}

使用低功耗DP缓存功能,需要注意以下几点:

  • PID上开启低功耗DP缓存下发的高级功能
  • 面板需要定制,需要缓存的DP在下发的时候加入缓存。这样会导致该DP无法正常从MQTT下发,只能通过缓存机制下发。上报则没有差别。

Image


Tags:
Post Reply