Sub-Device Standard Scene

Last Updated on : 2023-09-06 10:18:45download

IoT protocols with scene support can enable control of multiple devices at once. A scene created on top of a protocol is called a standard scene in Tuya. Tuya-based mobile apps support creating scenes for scene switches. TuyaOS Integrated SDK provides the APIs for implementing the standard scene feature.


The standard scene created using the mobile app is associated with a scene switch, which triggers the scene. Creation of standard scenes is only supported by sub-device products created under the Scene Controller category on the Tuya IoT Development Platform. As shown in the following figure:

Sub-Device Standard Scene

Development instructions

A standard scene is created on the page of the scene switch in the mobile app. The process includes verification. In the verification step, associate the settings for sub-devices in the scene with the scene ID. When the scene is triggered, the sub-devices can execute the specified commands.

Verification step has two parts:

  1. Execute commands. TuyaOS SDK triggers DP control callback and sends DTT_SCT_SCENE in the DP data struct .dtt_tp to the sub-device.
  2. Associate with scene IDs. TuyaOS SDK triggers scene callback, including the group ID and scene ID.

After a standard scene is created, DP 17 is sent to the scene switch to associate with the group ID and scene ID for triggering the scene.

DP 17 is of raw data type, in big-endian format, as shown below.

Button ID | Group ID | Scene ID | Scene Name
 4Bytes      4Bytes     4Bytes      5Bytes


Create a scene:

AppSDKApplicationSub-deviceCloudSend DP CommandDP CallbackSend DataReport DataReport DPReport DPRequest Group ID and Scene IDGroup ID and Scene IDGroup ID and Scene IDScene Add CallbackScene AddSuccessScene Add Callback return 0SuccessVerify OKDP17 CommandDP17 CommandSend DataReport DataReport DP17Report DP17Create Automation RuleUpdate Automation RuleStore RuleAppSDKApplicationSub-deviceCloud

Run a scene:

AppSDKApplicationSub-deviceGroup ID and Scene IDScene Execute CallbackBroadcast Scene IDUpdate StateReport DataReport DPReport DPAppSDKApplicationSub-device

How to

  • Call tuya_subdev_user_sigle_type_reg to register the sub-device management interface.
  • Implement the processing of sub-device DPs and scenes.

Data type


 * @brief Sub-device management callback
typedef struct __ty_gw_subdev_mgr_cbs_s {
    GW_PERMIT_ADD_DEV_CB                dev_add;            // permit joining callback, see GW_PERMIT_ADD_DEV_CB
    GW_DEV_DEL_CB                       dev_del;            // remove callback, see GW_DEV_DEL_CB
    DEV_RESET_IFM_CB                    dev_reset;          // reset callback, see DEV_RESET_IFM_CB
    GW_BIND_DEV_INFORM_CB               dev_bind;           // bind result callback, see GW_BIND_DEV_INFORM_CB

    DEV_OBJ_DP_CMD_CB                   dp_cmd_obj;         // obj DP command, see DEV_OBJ_DP_CMD_CB
    DEV_RAW_DP_CMD_CB                   dp_cmd_raw;         // raw DP command, see DEV_RAW_DP_CMD_CB
    DEV_DP_QUERY_CB                     dp_query;           // DP query, see DEV_DP_QUERY_CB

    DEV_HEARTBEAT_SEND_CB               dev_hb;             // heartbeat query callback, see DEV_HEARTBEAT_SEND_CB
    DEV_UG_INFORM_CB                    dev_upgrade;        // upgrade callback, see DEV_UG_INFORM_CB
    GW_DEV_WAKEUP_CB                    dev_wakeup;         // low power device wakeup callback, see GW_DEV_WAKEUP_CB
    GW_DEV_GRP_INFM_CB                  dev_grp_info;       // group control callback, see GW_DEV_GRP_INFM_CB
    GW_DEV_SCENE_INFM_CB                dev_sce_info;       // scene control callback, see GW_DEV_SCENE_INFM_CB

    GW_DEV_SIGMESH_TOPO_UPDAET_CB       bt_topo_update;     // Bluetooth LE device added callback, see GW_DEV_SIGMESH_TOPO_UPDAET_CB
    GW_DEV_SIGMESH_DEV_CACHE_DEL_CB     bt_cache_del;       // Bluetooth LE device removed callback, see GW_DEV_SIGMESH_DEV_CACHE_DEL_CB
    GW_DEV_SIGMESH_CONN_CB              bt_conn;            // Bluetooth LE device event callback, see GW_DEV_SIGMESH_CONN_CB

    DEV_ONLINE_STAT_SEND_CB             dev_online;         // online state changed callback, see DEV_ONLINE_STAT_SEND_CB

API description


  * @brief register callback with protocol type
  * @param[in] p_user_dev_node_cbs callback, see TY_GW_SUBDEV_MGR_CBS_S
  * @param[in] user_dev_type       custom protocol type, range from 10 to 19
  * @return OPRT_OK on success. Others on error, please refer to tuya_error_code.h
OPERATE_RET tuya_subdev_user_sigle_type_reg(TY_GW_SUBDEV_MGR_CBS_S *p_user_dev_node_cbs, BYTE_T user_dev_type);


typedef struct
    INT_T btn_id;
    INT_T grp_id;
    INT_T sce_id;
    CHAR_T sce_name[5];

STATIC VOID __dev_cmd_raw_cb(CONST TY_RECV_RAW_DP_S *cmd)
    PR_DEBUG("dev_id: %s, cmd_tp: %d, dtt_tp: %d, dpid: %d, len: %u", cmd->cid, cmd->cmd_tp, cmd->dtt_tp, cmd->dpid, cmd->len);

    if ((cmd->dpid == 17) && (cmd->len == 17)) {
        BYTE_T response = 0x00;
        // For scene selector device
        SCENE_DP_S sce_dp;
        memset(&sce_dp, 0, SIZEOF(SCENE_DP_S));
        memcpy(&sce_dp, dp->raw_dp->data, SIZEOF(SCENE_DP_S));

        sce_dp.btn_id = UNI_NTOHL(sce_dp.btn_id);
        sce_dp.grp_id = UNI_NTOHL(sce_dp.grp_id);
        sce_dp.sce_id = UNI_NTOHL(sce_dp.sce_id);

        PR_DEBUG("btn id: %d", btn_sce.btn);
        PR_DEBUG("grp id: %d", btn_sce.grp);
        PR_DEBUG("sce id: %d", btn_sce.sce);

        dev_report_dp_raw_sync(cmd->cid, 17, &response, 1, 0);

STATIC VOID __dev_cmd_obj_cb(CONST TY_RECV_OBJ_DP_S *cmd)
    PR_DEBUG("dev_id: %s, cmd_tp: %d, dtt_tp: %d, dps_cnt: %u", cmd->cid, cmd->cmd_tp, cmd->dtt_tp, cmd->dps_cnt);

    if (cmd->dtt_tp == DTT_SCT_SCENE) {
        // Scene

                                CONST CHAR_T *grp_id, CONST CHAR_T *sce_id)
    PR_DEBUG("dev_sce_cb action: %d, dev_id: %s, grp_id: %s, sce_id: %s", action, dev_id, grp_id, sce_id);

    if (action == SCE_ADD) {
        // Scene Add
    } else if (action == SCE_DEL) {
        // Scene Delete
    } else if (action == SCE_EXEC) {
        // Scene Execute
    } else {
        return OPRT_INVALID_PARM;

    return OPRT_OK;

STATIC VOID scene_demo(VOID) {
    TY_GW_SUBDEV_MGR_CBS_S dev_cbs = {
        .dp_cmd_raw   = __dev_cmd_raw_cb,
        .dp_cmd_obj   = __dev_cmd_obj_cb,
        .dev_sce_info = __dev_sce_cb,

    tuya_subdev_user_sigle_type_reg(&dev_cbs , DEV_ATTACH_MOD_1);
```_cmd_raw   = __dev_cmd_raw_cb,
        .dp_cmd_obj   = __dev_cmd_obj_cb,
        .dev_sce_info = __dev_sce_cb,

    tuya_subdev_user_sigle_type_reg(&dev_cbs , DEV_ATTACH_MOD_1);