DP Development Considerations

Last Updated on : 2024-06-25 03:38:05download

Data point (DP) is a data model defined by the Tuya Developer Platform to describe the functions of a product. TuyaOS can determine a device’s capabilities using the DP’s schema file and then parse the schema to instantiate the device. This topic describes the considerations you should take into account when developing DPs.

For more information about DP, see DP Model and Control Protocol.

Reporting frequency

To maintain system and service stability, Tuya has a limit on the number of times a device can report data. Take care of the reporting frequency when developing the reporting function.

The traffic for a gateway and its sub-devices is counted separately.

  • For non-sensor devices, it is recommended that a single device report DP data up to 300 times per day.
  • For sensor devices, properly control the data accuracy and avoid millisecond or second-level reporting. It is recommended that a single sensor device report DP data up to 3,500 times per day.
  • If a device reports DP data more than 3,500 times per day, the cloud server may activate DP data throttling, which can cause anomalies in the device’s functionality. Consistently frequent reporting can ultimately cause a device not to work properly.

Group reporting

Group reporting applies to object-type DPs.

  • The raw-type DP and the object-type DP cannot be grouped together for reporting.
  • Multiple raw-type DPs cannot be grouped together for reporting.

The device will wait for an acknowledgment (ACK) message from the cloud after reporting DP data. If the device fails to receive an ACK within the timeout period, it will retransmit the packet. This process is time-consuming and resource-intensive. It is recommended to group data from multiple DPs into one packet for reporting, if possible.

Advantages:

  • Reduce the latency of data reporting. It can be time-consuming to report one by one when network conditions are poor.
  • Reduce memory footprint. During asynchronous reporting, the framework will enqueue the data to be reported and wait for the sending task to retrieve the data. The larger the waiting queue, the more memory is used.
  • Reduce the failure rate of reporting. Due to the limited capacity of the waiting queue, excessive calls to an asynchronous reporting API can fill up the queue, causing the subsequent data not to be reported as they cannot be enqueued.

Example

See the quick start tuyaos_demo_quickstart included in the framework for the complete example code.

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

Asynchronous/synchronous reporting

The TuyaOS framework allows you to report DP data in a synchronous or asynchronous manner.

Asynchronous reporting

A call to the asynchronous reporting API triggers DP data reporting. The framework caches the data to be reported and delivers it when the reporting thread is scheduled, without blocking the application thread. If you only need the last reporting to reflect the actual status of the device and do not care about how many times DP data is reported, you can choose this reporting method. For example, report on/off state.

  • An API marked as async is used for asynchronous reporting.
  • The TuyaOS framework takes care of the result of DP data reporting.
  • Asynchronous reporting typically applies to real-time object-type DPs.

Synchronous reporting

After a synchronous reporting API is called, the framework instantly reports data, but this can block the application thread and does not filter out identical DP values. Use this reporting method if you need to control the number of times DP is reported and the application requires immediate knowledge of the reporting result to respond accordingly. For example, when measurement data such as electricity usage fails to be reported, the application caches the data and reports it next time.

  • An API marked as sync is used for synchronous reporting.
  • You handle the result of DP data reporting. In the case of a failure, you need to cache the data and report it again.
  • The synchronous reporting API can block the application thread, requiring a large stack depth of the application.
  • Synchronous reporting typically applies to raw-type DPs or record-type object-type DPs.
  • Try to avoid frequent data reporting because synchronous reporting APIs do not filter out duplicate values.
  • DP data is reported to the cloud over MQTT. Do not call the synchronous reporting API in the MQTT callback, as this can cause thread blocking. To prevent the device from going offline due to MQTT timeout, it is recommended to enqueue the synchronous reporting task instead of executing it directly in the MQTT thread.
  • Do not call the synchronous reporting API in the DP query processing callback, because the DP query is sent over MQTT and the callback is executed in the MQTT thread.
  • The callbacks for processing object-type and raw-type DPs are not executed in the MQTT thread but in the queue thread. Therefore, calling the synchronous reporting API in these two callbacks will not cause the device to go offline.

Example

This section describes the two types of data reporting, using an energy metering socket with a power switch as an example.

The API for reporting real-time object-type DPs is suitable for the power switch DP.

void switch_status_upload(UINT status)
{
    OPERATE_RET rt = OPRT_OK;
    TY_OBJ_DP_S obj_dp = {0};

    obj_dp.dpid = 1;
    obj_dp.type = PROP_BOOL;
    obj_dp.value.dp_bool = status;
    obj_dp.time_stamp = 0;
    TUYA_CALL_ERR_LOG(dev_report_dp_json_async(NULL, &obj_dp, 1));

    return;
}

The API for reporting record-type object-type DPs is suitable for the energy consumption DP.

When the measured energy consumption meets the preset condition, the electrical parameters during the measurement period will be reported. To avoid duplicate or missing energy consumption reporting, use the synchronous reporting API. If the device fails to report data, it will store the current timestamp and the accumulated energy consumption in the flash and wait to report them when the network is available. If the cached data is reported successfully, it will be deleted from the flash. Otherwise, it will be retained.

void electric_quantity_upload(UINT add_value)
{
    OPERATE_RET rt = OPRT_OK;
    TIME_T time_stamp = 0;
    TY_OBJ_DP_S obj_dp = {0};

    // Get the current timestamp.
    time_stamp = tal_time_get_posix();

    obj_dp.dpid = xx;
    obj_dp.type = PROP_VALUE;
    obj_dp.value.dp_value = add_value;
    obj_dp.time_stamp = time_stamp;
    rt = dev_report_dp_stat_sync_extend(NULL, &obj_dp, 1, 5, TRUE); // Synchronous reporting.
    if (rt != OPRT_OK) {
        // Reporting failed. Save timestamp and data to flash.
    } else {
        // Reporting succeeded. Check if there is retained data in the flash. If so, report them.
        // Data in the flash is reported. Remove it from flash.
        // Data in the flash failed to be reported. Retain it in the flash.
    }

    return;
}

Forced reporting on demand

  • Forced reporting is used to report object-type DPs asynchronously. Filtering does not apply when you report raw-type or object-type DPs synchronously.
  • When forced reporting is enabled, do not exceed the limit of the reporting frequency.

When the application calls the DP reporting API, the framework will verify the DP. The framework will filter out and not report the value if it is identical to the current value. To report duplicate values, two options are available.

  • When you define the DP, select Repeated Reporting in Special Configuration.

    DP Development Considerations
  • Call the forced reporting API.

Reporting with timestamp

By default, the cloud takes the time when the DP data arrives as the occurrence time of the DP event. However, when the device reports the retained data, the time received by the cloud is not the actual time when the event occurred. In this case, you need to pass in the timestamp of the event occurrence when calling the reporting API.

  • The real-time object-type DPs do not support reporting with timestamps.

  • The raw-type DPs provide the timestamp in string format through the parameter time_str.

    // Use dev_report_dp_raw_sync_with_time to report raw-type DPs synchronously with timestamp.
    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)
    
  • The record-type object-type DPs provide occurrence timestamp by setting the time_stamp member in the TY_OBJ_DP_S struct.

    // Use dev_report_dp_stat_sync to report record-type object-type DPs synchronously. The member of time_stamp of dp_data determines whether to include the timestamp.
    typedef struct {
        /** dp ID */
        BYTE_T dpid;
        /** dp type, see DP_PROP_TP_E */
        DP_PROP_TP_E type;
        /** dp value, see TY_OBJ_DP_VALUE_U */
        TY_OBJ_DP_VALUE_U value;
        /** dp happen time. if 0, mean now */
        UINT_T time_stamp;
    } TY_OBJ_DP_S;
    
    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)
    

Limit on DP quantity

The schema file will be larger with more DPs. If the schema file is larger than 8 KB, some products with an RTOS system might fail to download it, causing device activation to fail. When data exchange over HTTPS exceeds 8 KB, the chunked mode will be enabled in the cloud. However, the device does not support the chunked mode. The following errors will be output in the local logs:

chunked err

On the Tuya Developer Platform, there was a note suggesting the number of device DPs should not exceed 40. This limitation is to restrict the size of the schema file.

The 8 KB limit on the schema file does not apply to TuyaOS 3.5.0 and later. Increasing the number of DPs will lead to a larger schema file and higher memory usage. Therefore, set an appropriate number of DPs based on your specific needs.

FAQs

Why does the device go offline briefly the moment the app panel is opened?

Check if the device firmware calls the synchronous reporting API in the DP query processing callback. If so, MQTT thread blocking can occur, causing the MQTT disconnection due to failing to receive a response. See synchronous reporting for details.