设备 DP

更新时间:2024-03-07 07:03:57下载pdf

Data Point(DP),也叫功能点,是描述一个设备所具有的功能。涂鸦 IoT 开发平台 将设备的功能都抽象成功能点,支持数值型、布尔型、枚举型、字符串型、故障型以及 RAW 透传数据。

本文介绍基于激光扫地机 DP 的注意事项。关于功能点的基本概念、功能描述及 API 接口等,参考 DP 模型与控制协议

实现方法

以下回调函数都是注册在 TuyaOS SDK 里:

  • ty_cmd_handle_dp_cmd_objs:通知您有 Obj 类型 DP 指令下发。
  • robotics_app_dp_raw_objs:通知您有 Raw 类型 DP 指令下发。
  • robotics_app_dp_query_objs:通知您需要查询指定 DP 的当前状态。
  • 在以上回调函数中获取到的 DP 仅进行基本的数据解析,避免复杂操作。请将具体的执行步骤迁移到其他任务中执行。
  • 在激光扫地机的 DP 交互逻辑中,App 下发 DP 数据后,需要依赖设备上报对应的 DP 数据,才会更新 App 端的 DP 值。

实现示例

/**
 * @brief  设备上线,DP 同步
 * @param  [unsigned char*] p_obj_dp
 * @param  [unsigned int] len
 * @return [*]
 */
OPERATE_RET dp_handle_sync_to_cloud(void)
{
    /*****
     * 可以做相对应的业务处理
     * 云端限制:一天不要超过 3500 条,10 分钟内上报的 DP 数量不要超过 1200 条,这是云端对 DP 上报数量的限流。
     * 因此,将其组合上报,可解决上述问题
     *******/

    PR_DEBUG("update all dp to cloud");
    OPERATE_RET ret = 0;
    TY_OBJ_DP_S *dp_obj_buf = NULL;

    char num = 5;

    dp_obj_buf = malloc(num * sizeof(TY_OBJ_DP_S));
    if(dp_obj_buf == NULL) {
        PR_ERR("ty_sdk_adapter_dp_num_report malloc error");
    }

    memset(dp_obj_buf, 0, num * sizeof(TY_OBJ_DP_S));

    TY_OBJ_DP_S* obj_data_tmp = dp_obj_buf;

//switch go DP 
    obj_data_tmp->dpid = TUYA_DP_SWITCH_GO;
    obj_data_tmp->type = PROP_BOOL;
    obj_data_tmp->value.dp_bool = 1;

    obj_data_tmp += 1;

//pause DP 
    obj_data_tmp->dpid = TUYA_DP_PAUSE;
    obj_data_tmp->type = PROP_BOOL;
    obj_data_tmp->value.dp_bool = 0;

    obj_data_tmp += 1;

//switch charge DP 
    obj_data_tmp->dpid = TUYA_DP_SWITCH_CHARGE;
    obj_data_tmp->type = PROP_BOOL;
    obj_data_tmp->value.dp_bool = 0;

    obj_data_tmp += 1;

//work mode DP 
    obj_data_tmp->dpid = TUYA_DP_WORK_MODE;
    obj_data_tmp->type = PROP_ENUM;
    obj_data_tmp->value.dp_enum = 0;

    obj_data_tmp += 1;

//status DP 
    obj_data_tmp->dpid = TUYA_DP_STATUS;
    obj_data_tmp->type = PROP_ENUM;
    obj_data_tmp->value.dp_enum = DP_ST_STANDBY;

    obj_data_tmp += 1;

    ret = dev_report_dp_json_async(NULL, dp_obj_buf, num);

    if(dp_obj_buf) {
        free(dp_obj_buf);
        dp_obj_buf = NULL;
    }
}
/**
 * @brief  接收 obj DP 函数
 * @param  [TY_RECV_OBJ_DP_S*] p_obj_dp
 * @param  [*]
 * @return [*]
 */
VOID robotics_app_dp_cmd_objs(IN CONST TY_RECV_OBJ_DP_S* dp_rev)
{
    TY_OBJ_DP_S* dp_data = (TY_OBJ_DP_S*)(dp_rev->dps);
    UINT_T cnt = dp_rev->dps_cnt;
    INT_T table_idx = 0;
    INT_T table_count = (sizeof(s_dp_table) / sizeof(s_dp_table[0]));
    INT_T index = 0;
    for (index = 0; index < cnt; index++) {
        TY_OBJ_DP_S* p_dp_obj = dp_data + index;
        PR_DEBUG("recv dpid:[%d]\r\n", p_dp_obj->dpid);
       /*接收到的数据仅可进行简单解析处理。具体操作需要在另一个任务中执行*/
    }
}

/**
 * @brief  接收 raw DP 函数
 * @param  [TY_RECV_RAW_DP_S*] p_obj_dp
 * @return [*]
 */
VOID robotics_app_dp_raw_objs(IN CONST TY_RECV_RAW_DP_S* dp_rev)
{
    unsigned char * dp_data = dp_rev->data;
    int table_idx = 0;
    int table_count = (sizeof(s_raw_dp_table) / sizeof(s_raw_dp_table[0]));

    PR_DEBUG("dpid:%d cmd_tp:%d", dp_rev->dpid, dp_rev->cmd_tp);
    for (table_idx = 0; table_idx < table_count; table_idx++) {
        /*接收到的数据仅可进行简单解析处理。具体操作需要在另一个任务中执行*/
        /*接收到的数据可参考涂鸦激光扫地机的协议*/
    }
}

/**
 * @brief  接收查询 DP 函数
 * @param  [TY_DP_QUERY_S*] p_obj_dp
 * @param  [*]
 * @return [*]
 */
VOID robotics_app_dp_query_objs(IN CONST TY_DP_QUERY_S* dp_query)
{
    if (!dp_query->cnt) {
        PR_DEBUG("recv query objs cnt = 0");
        return;
    }
    dp_handle_sync_to_cloud();   //扫地机的查询 DP 指令,一般需要设备端将 DP 同步给 App
}
   /**
* @brief main 初始化
* @param [*]
* @return [*]
*/
OPERATE_RET main(void)
{
   char s_mqtt_online_status = FALSE;
    TY_IOT_CBS_S iot_cbs = {0};
    iot_cbs.dev_obj_dp_cb   = ty_cmd_handle_dp_cmd_objs;     //注册 obj DP 接收通道接口
    iot_cbs.dev_raw_dp_cb   = ty_cmd_handle_dp_raw_objs;     //注册 raw DP 接收通道接口
    iot_cbs.dev_dp_query_cb = ty_cmd_handle_dp_query_objs;   //注册查询 DP 接口
    //要等设备上线之后调用,同步设备 DP
    if(TRUE == s_mqtt_online_status) {
       OPERATE_RET ret = dp_handle_sync_to_cloud();
       if(ret != OPRT_OK) {
          PR_ERR("dp sync to cloud err %d", ret);
          return ret;
       }
       //不同类型 DP 和 RAW DP 的接收及上报,参考 Demo 里的实现。
    }
}

API 说明

异步上报 Obj DP

/**
 * @brief dev_report_dp_json_async
 * @desc report dp info a-synced.
 *
 * @param[in] dev_id: if sub-device, then devid = sub-device_id
 *                if gateway/soc/mcu, then devid = NULL
 * @param[in] dp_data: dp array header
 * @param[in] cnt: dp array count
 *
 * @return OPRT_OK: success, other: fail
 */
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);

同步上报 RAW DP

/**
 * @brief dev_report_dp_raw_sync_extend
 * @desc report dp raw info synced.
 *
 * @param[in] dev_id: if sub-device, then devid = sub-device_id
 *                if gateway/soc/mcu, then devid = NULL
 * @param[in] dpid: raw dp id
 * @param[in] data: raw data
 * @param[in] len: len of raw data
 * @param[in] timeout: function blocks until timeout seconds
 * @param[in] enable_auto_retrans
 *
 * @return OPRT_OK: success, other: fail
 */
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);

异步上报查询的 OBJ DP


/**
 * @brief dev_query_dp_json_async
 * @desc report dp info a-synced.
 *
 * @param[in] dev_id: if sub-device, then devid = sub-device_id
 *                if gateway/soc/mcu, then devid = NULL
 * @param[in] dp_data: dp array header
 * @param[in] cnt: dp array count
 *
 * @return OPRT_OK: success, other: fail
 */
OPERATE_RET dev_query_dp_json_async(IN CONST CHAR_T *dev_id, IN CONST TY_OBJ_DP_S *dp_data, IN CONST UINT_T cnt);

同步上报记录型 OBJ DP

/**
 * @brief dev_report_dp_stat_sync_extend
 * @desc: report dp status info synced.
 *        if time_stamp==0, time_stamp = time of msg arrival of the server
 *
 * @param[in] dev_id: if sub-device, then devid = sub-device_id
 *                    if gateway/soc/mcu, then devid = NULL
 * @param[in] dp_data: dp status array header
 * @param[in] cnt: dp status array count
 * @param[in] timeout: function blocks until timeout seconds
 * @param[in] enable_auto_retrans
 *
 * @return OPRT_OK: success, other: fail
 */
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);