子设备标准场景

更新时间:2024-06-25 06:00:49下载pdf

如果一个物联网(IoT)协议支持场景功能,则可以实现多个设备的联动控制。这种协议上的场景,涂鸦称之为 标准场景。涂鸦 App 支持在场景面板设备上,创建标准场景,TuyaOS 综合 SDK 提供了标准场景相关的接口。您可以根据本文描述实现标准场景功能。

适用产品

因为标准场景是绑定到场景面板设备上的,通过场景面板触发场景联动。所以,在 涂鸦开发者平台 上创建的子设备产品为 场景中控 时,才支持创建标准场景。如下图所示:

子设备标准场景

开发说明

创建标准场景的入口在场景设备的页面上,标准场景创建过程包含验证步骤。验证步骤的目的是让动作里面的子设备把当前状态关联到场景 ID,当场景执行时恢复到该状态,从而实现联动功能。

验证步骤分两步:

  1. 执行动作。执行动作和普通控制的流程是一致的,TuyaOS SDK 触发 DP 控制回调,不同的是 DP 数据结构体 .dtt_tp 的值,验证流程下发的控制指令 .dtt_tpDTT_SCT_SCENE
  2. 关联场景 ID。关联场景 ID,TuyaOS SDK 触发场景回调,包含了 Group ID 和 Scene ID。成功时,回调接口需要返回 0

标准场景创建成功后,App 下发 DP17 给场景设备,让场景设备也关联 Group ID 和 Scene ID,用于触发联动。关联后,需要通过 DP17 上报关联的结果,0 表示成功,非 0 表示失败。

DP17 的数据类型为 Raw 类型,格式如下所示,并需要注意大端模式对齐:

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

工作流程

创建流程图如下:

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

执行流程图如下:

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

使用方法

  • 通过 tuya_subdev_user_sigle_type_reg 注册子设备管理接口。
  • 实现子设备 DP 和场景处理。

数据类型

TY_GW_SUBDEV_MGR_CBS_S

/**
 * @brief subdevice 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
}TY_GW_SUBDEV_MGR_CBS_S;

API 说明

tuya_subdev_user_sigle_type_reg

/**
  * @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];
} SCENE_DP_S;

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
    }
}

STATIC OPERATE_RET __dev_sce_cb(CONST SCE_ACTION_E action, CONST CHAR_T *dev_id,\
                                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);
}