DP Model and Control Protocol

Last Updated on : 2023-12-19 08:36:57download

Data point (DP) is a data model defined by the Tuya IoT Development Platform to describe the functions of a product. The abstract descriptions of device properties and functions help to standardize and manage a myriad of smart devices in a unified way. Describing a device with a set of DPs can shield the differences between underlying hardware for low coupling.

Concepts

When adding a DP on the Tuya IoT Development Platform, you can choose its data type and data transfer type.

  • DP data types:

    • Object type:

      • Boolean

        Represent the values that can be only true or false. For example, the on and off state for a switch.

      • Value

        Represent the values that can be linearly adjusted. For example, the temperature ranges from 20°C to 40°C.

      • Enum

        A custom finite set of values. For example, operation modes can be low, medium, and high.

      • Bitmap

        Report multiple states, specifically for device faults.

      • String

        Transfer data in string format with a maximum of 255 bytes, typically used for complex features.

    • Raw type

      Transfer data in hexadecimal format, typically used for complex features.

  • Extended DP properties:

    • Passive reporting

      The module can report DP data only when it receives a command. This can avoid frequent data reporting.

    • Repeated reporting

      Enabling this feature allows the DP to repeatedly report identical values. Otherwise, the framework will filter them out.

    • DP routing

      Control which channel a cellular and Bluetooth combo device uses for DP data transmission.

      • If it is not specified, the cellular network is preferred. If the cellular network is not available, Bluetooth is used.

      • 1: Bluetooth is preferred. If Bluetooth is disconnected, the cellular network is used.

      • 2: Force the use of Bluetooth. If Bluetooth LE is disconnected, the app panel will display an error message.

  • DP data transfer type:

    • Read only (RO): report only One-way data transmission. Data can only be sent from the device to the cloud.
    • Write only (WR): send only One-way data transmission. Data can only be sent from the cloud to the device.
    • Read write (RW): send and report Two-way data transmission between the device and the cloud.
  • DP timeliness:

    • Real-time DP:

      This type of DP is time-critical, used to report or receive real-time DP data. The time at which the DP data is generated is exactly when it is reported. For example, control the on/off state of a switch and then synchronize the current state with the cloud and client.

    • Record-type DP:

      This type of DP is used to record the device status and the generated data. The time at which the DP data is generated does not align with when it is reported. For example, the door unlocking records, alerts, and power usage.

Feature description

Report DP data

You can call data reporting APIs provided by the framework to synchronize the status of devices and local data, such as on/off state and battery level, with the cloud and client.

The APIs will verify the validity of the DP and automatically determine the reporting channel based on network conditions. The DP data can be reported either synchronously or asynchronously.

  • Asynchronous 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.

  • Synchronous reporting

    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 report, the application caches the data and reports it next time.

    DPs of raw type only support synchronous reporting.

Send DP commands

The framework uses callbacks to notify the application that there are DP commands to handle. There are three callbacks used for the object-type DP, raw-type DP, and DP query respectively. They are registered by the application during device initialization.

Synchronize DP data

The data packet to synchronize includes a synchronization identifier to differentiate it from the proactively reported one, preventing unintended triggering of scene linkage.

The device needs to periodically synchronize its status with the cloud and client to maintain consistency. The device can either proactively synchronize its status or respond to a status query.

  • Proactive synchronization

    In the following cases, the device proactively synchronizes the cached object-type DP data.

    Proactive synchronization does not apply to the raw-type DP data because it cannot be cached.

    • MQTT is connected for the first time after the device is started or reconnected following a disconnection.
    • Bluetooth is connected.
    • When the device fails to report or synchronize data, a 2-second timer is started to trigger synchronous reporting until the data is reported.
  • Query-triggered synchronization

    The device responds to the query from the cloud or client with the status of the specified DP. The framework notifies the application of the query through the DP query processing callback. The application calls the appropriate query-triggered reporting API to report data.

DP throttling

Repeatedly reporting data of a DP within a time period can cause a waste of cloud resources. To prevent this, DP throttling limits the number of DP reporting requests allowed within a specific time window.

A single DP can be reported up to 200 times within 60 seconds by default. When this limit is reached, throttling will be triggered to prevent further data reporting. Reporting will resume when the next cycle starts.

Process

Report DP data

DP Model and Control Protocol

Verify DP data

DP Model and Control Protocol

Send DP command

After receiving the object-type DP command, the framework compares the received DP value with the cached one. If they are consistent, the framework will start synchronizing DP data, without invoking a callback to notify the application.

If it is raw-type data or no valid cached value exists in the framework, the application will get notified to handle the subsequent process.

DP Model and Control Protocol

Synchronize DP data

DP Model and Control Protocol

Data structure

Data struct of a DP

The rule to specify the timestamp when reporting DP data:

  • To report real-time DP, set the timestamp to 0. The framework will automatically use the time when data is reported as the timestamp.

  • To report record-type DP, set the time when the DP record is generated as the timestamp.

/**
 * @brief Definition of dp property type
 */
typedef BYTE_T DP_PROP_TP_E;
#define PROP_BOOL 0
#define PROP_VALUE 1
#define PROP_STR 2
#define PROP_ENUM 3
#define PROP_BITMAP 4

// A union of DP values
typedef union {
    INT_T dp_value;             // valid when dp type is value
    UINT_T dp_enum;             // valid when dp type is enum
    CHAR_T *dp_str;             // valid when dp type is str
    BOOL_T dp_bool;             // valid when dp type is bool
    UINT_T dp_bitmap;           // valid when dp type is bitmap
} TY_OBJ_DP_VALUE_U;

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;

Struct of the received DP data

After receiving the DP command notification, the application can get information about the command from the struct, such as the command source and transfer type.

  • cid:

    • A common device

      cid is fixed to NULL.

    • A gateway device

      When cid is NULL, the DP command is intended for the gateway.

      When cid has a value, the value is the ID of a sub-device and the DP command is intended for this sub-device.

  • mb_id:

    The group ID, used for gateway devices.

/**
 * @brief tuya sdk dp cmd type
 */
typedef BYTE_T DP_CMD_TYPE_E;
#define DP_CMD_LAN                  0   // cmd from LAN
#define DP_CMD_MQ                   1   // cmd from MQTT
#define DP_CMD_TIMER                2   // cmd from Local Timer
#define DP_CMD_SCENE_LINKAGE        3   // cmd from scene linkage
#define DP_CMD_RELIABLE_TRANSFER    4   // cmd from reliable transfer
#define DP_CMD_BT                   5   // cmd from bt
#define DP_CMD_SCENE_LINKAGE_LAN    6   // cmd from lan scene linkage
#define DP_CMD_FFC                  7   // cmd from ffc

/**
 * @brief tuya sdk dp trans type
 */
typedef BYTE_T DP_TRANS_TYPE_T;
#define DTT_SCT_UNC     0   // unicast
#define DTT_SCT_BNC     1   // boardcast
#define DTT_SCT_MNC     2   // multicast
#define DTT_SCT_SCENE   3   // scene

/**
 * @brief Definition of recved structured dp
 */
typedef struct {
    /** see DP_CMD_TYPE_E */
    DP_CMD_TYPE_E cmd_tp;
    /** see DP_TRANS_TYPE_T */
    DP_TRANS_TYPE_T dtt_tp;
    /** if(NULL == cid) then the cid represents gwid */
    CHAR_T *cid;
    /** mb ID */
    CHAR_T *mb_id;
    /** count of dp */
    UINT_T dps_cnt;
    /** the dp data */
    TY_OBJ_DP_S dps[0];
} TY_RECV_OBJ_DP_S;

/**
 * @brief Definition of recved raw dp
 */
typedef struct {
    /** see DP_CMD_TYPE_E */
    DP_CMD_TYPE_E cmd_tp;
    /** see DP_TRANS_TYPE_T */
    DP_TRANS_TYPE_T dtt_tp;
    /** if(NULL == cid) then the cid represents gwid */
    CHAR_T *cid;
    /** dp ID */
    BYTE_T dpid;
    /** mb ID */
    CHAR_T *mb_id;
    /** data len */
    UINT_T len;
    /** the data */
    BYTE_T data[0];
} TY_RECV_RAW_DP_S;

Struct of a DP query

/**
 * @brief Definition of dp report type
 */
typedef BYTE_T DP_REPT_TYPE_E;
#define T_OBJ_REPT      0           // dp is value,str,enum,bool,bitmap
#define T_RAW_REPT      1           // raw type
#define T_STAT_REPT     2           // stat type
#define T_RE_TRANS_REPT 10          // repeat report

typedef struct {
    /** report type, see DP_REPT_TYPE_E */
    DP_REPT_TYPE_E dp_rept_type;
    /** obj: is TY_OBJ_DP_REPT_S, stat: dp is TY_STAT_DP_REPT_S, RAW: TY_RAW_DP_REPT_S */
    VOID_T*         dp_data;
    /** Json decoded dp string */
    CHAR_T*         dp_data_json;
    /** is query or not */
    BYTE_T          is_query;
} DP_REPT_CB_DATA;

Development guide

Reference the header

  • tuya_iot_com_api.h

How to

  • Report DP data

    After device initialization, call the appropriate reporting API to report DP data.

  • Process received DP commands

    During device initialization, the application registers the callbacks for processing object-type and raw-type DP commands.

  • Respond to DP queries

    During device initialization, the application registers the callback for processing DP queries. In the callback, the query-triggered reporting API is called to return DP data.

API description

Report object-type DPs asynchronously

The asynchronous reporting API verifies the DP data and, if successful, updates the cached data. It then assembles a packet and triggers the appropriate reporting event.

A successful response from the asynchronous reporting API only indicates that the reporting event was triggered successfully. It does not necessarily mean that the DP data has been successfully reported.

Method 1: Standard reporting

The API enables/disables filtering based on the configuration of repeated reporting on the Tuya IoT Development Platform.

/**
 * @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);

Method 2: Forced reporting

This API does not enable filtering. It reports data regardless of the configuration of repeated reporting on the Tuya IoT Development Platform.

/**
 * @brief dev_report_dp_json_async_force
 * @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_force(IN CONST CHAR_T *dev_id, IN CONST TY_OBJ_DP_S *dp_data, IN CONST UINT_T cnt);

Report object-type DP synchronously and report record-type data

The synchronous reporting API verifies the DP data and, if successful, reports the DP data immediately. The return value of the API call can indicate if the data is successfully reported. Record-type data is typically reported using this API. If the data fails to report, you need to store or accumulate it. Then, start a thread or timer to attempt reporting periodically. Repeat this process until data is successfully reported, and then delete the record or clear the data.

The synchronous reporting API can block the application thread, requiring a large stack depth of the application. The blocking time can be specified with the API parameter, usually set to five seconds.

/**
 * @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)

Respond to object-type DP queries

This API is used to report data in response to an object-type DP query. The data packet includes a synchronization identifier to differentiate it from the proactively reported one, preventing unintended triggering of scene linkage.

/**
 * @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);

/**
 * @brief dev_query_dp_json_async_force
 * @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_force(IN CONST CHAR_T *dev_id, IN CONST TY_OBJ_DP_S *dp_data, IN CONST UINT_T cnt);

Report raw-type DP synchronously

The raw-type DP only supports synchronous reporting, and the framework does not cache the raw-type DP data. Therefore, filtering and data synchronization mechanism do not apply.

Method 1: Without timestamp

Scenario: The time at which the DP data is generated is exactly when it is reported.

/**
 * @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)

Method 2: With timestamp

Scenario: The time at which the DP data is generated does not align with when it is reported.

/**
 * @brief dev_report_dp_raw_sync_extend_with_time
 * @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
 * @param[in] time_str
 *
 * @return OPRT_OK: success Other: fail
 */
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)

FAQs

What is the value range for different types of DP?

  • Boolean DP: true or false.

  • Value DP: stored and transmitted as an integer. The range of values is from -2147483648 to 2147483647.

  • Enum DP: 0 to (the number of enum objects − 1).

  • String DP: no more than 255 bytes.

  • Raw DP: typically, no more than 255 bytes. But the maximum length can be 1,024 bytes.

After I modify the DP on the Tuya IoT Development Platform, when do changes take effect on the device side?

Modifying the DP after mass production is not recommended, as it can cause certain functions of the device not to work or make the device completely unusable.

  • TuyaOS v3.3.0 or later supports adding DP on the fly. The changes take effect after the device is restarted.

  • If your framework is earlier than v3.3.0, or if you delete or modify a DP, the changes take effect after the device is reset and paired.

How to define a DP of the floating-point value type?

The device processes the DP of the value type as integers. It expands a value with a fractional part to write it as an integer.

You can set the scale of a DP on the Tuya IoT Development Platform to enable the client to divide the received value by the scale to get the original value. Suppose that the actual value has three decimal places. You can set scale to 3. The client divides the received value by 1,000 and displays the result.