示例

本文以温湿度传感器产品为例,介绍使用 WebSocket 协议通道,通过 DTS 进行实体反控的配置与调试流程。

[!IMPORTANT] 生产架构与调试说明 * 在生产环境/实际使用时:建立 WebSocket 连接的客户端应当是运行在您真实物理设备或边缘网关上的连接代码(例如使用 Python/C++/Java 编写的 WebSocket Client 进程)。设备上电启动后需自动建立与 DTS 平台内置 WebSocket 服务端(由网关通信模块承载)的连接,以便持续监听并接收控制指令。 * 在本文教程中:为了方便您在没有真实物理硬件的情况下能闭环体验并测试 WebSocket 控制通道的配置链路,我们采用 APIFox (或网页端 WebSocket 调试工具) 作为客户端模拟器,来手动发起连接并查看 DTS 下发的控制消息。这仅作为本地联调和数据报文解析的手段,实际生产开发时请替换为您的真实设备客户端代码。

生产环境与调试环境配置对照:

配置项 / 概念 本文调试阶段(以 APIFox 为例) 实际生产阶段(以温湿度传感器客户端为例)
WebSocket 客户端 APIFox WebSocket 调试界面 运行在温湿度传感器设备(或网关)上的 Python/C++/Java 客户端程序
网络连接建立 读者在客户端中手动输入 URL 并点击“连接” 设备上电后,客户端程序自动发起并建立向 DTS 的 WebSocket 长连接
指令接收与处理 在 APIFox 的发送与接收日志面板中查看 JSON 报文 设备程序监听该长连接,解析收到的 JSON 报文并调用底层硬件接口执行物理操作

反控配置流程包含以下几个主要步骤:

null

准备事项

1.注册数字孪生服务DTService(以下简称DTS)账户 2.准备APIFox,用于模拟接收设备反向控制的指令和数据上报。 3.已成功创建需要进行反控的产品”温湿度传感器“。请参考HTTP协议实体接入 4.已成功创建需要进行反控的实体。

定义产品Profile

需在产品Profile中定义实体支持的服务。服务执行后,根据使用场景选择结果返回方式:

在产品Profile所有编辑完成后,需点击发布。发布后的产品Profile才能被DTS识别。智能插座的数据格式为“BV JSON”,示例默认都使用BV JSON进行数据交互。无论数据格式是BV JSON或透传/自定义流程类似,BV JSON无需写消息解析脚本。

定义产品Profile(服务)

  1. 进入实体管理模块,选择产品。
  2. 选择“温湿度传感器”产品,点击编辑进入产品的详情页面->选择产品Profile Tab页面。
  3. 点击编辑草稿,选择添加功能,选择功能类型为服务 。
  4. 输入功能名称为”重启复位“,设置标识符为resetDeviceWS。
  5. 服务地址选择”DTS 内置服务”,显示接口地址“/{productid}/{identifier}”。
  6. 根据“重启复位服务”服务设置输入参数deviceid 。
  7. 根据需要设定选择结果返回方式为属性上报or事件上报。

图1

图1:采用属性上报返回结果

图2

图2:采用事件上报返回结果

同步方式为立即返回结果,异步方式可有延迟。DTS会携带回调参数发送到服务。

方式1:结果返回方式为属性

定义产品Profile(属性)

  1. 进入实体管理模块,选择产品。
  2. 选择“智能插座”产品,点击编辑进入产品的详情页面->选择产品Profile Tab页面。
  3. 点击编辑草稿,选择添加功能,选择功能类型为属性 。
  4. 输入功能名称为”重启状态“,设置标识符为status。
  5. 确定保存属性。 null

方式2:结果返回方式为事件

定义产品Profile(事件)

  1. 进入实体管理模块,选择产品。
  2. 选择“智能插座”产品,点击编辑进入产品的详情页面->选择产品Profile Tab页面。
  3. 点击编辑草稿,选择添加功能,选择功能类型为事件 。
  4. 输入功能名称为”获取重启状态“,设置标识符为getResult。
  5. 设置输出参数 status 。
  6. 确定保存事件。 null

配置消息解析脚本

仅需为使用透传/自定义协议的产品实体配置。

消息解析脚本示例

/**
 * 将透传/自定义数据格式转换为DTS平台的BV JSON数据格式,实体注册、属性、事件上报到DTS时调用。
 * @param {JSONObject} body - 入参
 * @param {JSONObject} body._bv_callback_message - 服务回调参数(回调时携带)
 * @param {string} body._bv_callback_message.productId - 产品编号
 * @param {string} body._bv_callback_message.deviceId - 实体编号
 * @param {string} body._bv_callback_message.identifier - 事件的唯一标识符(回调方式为事件上报时携带)
 * @param {JSONObject} body._bv_callback_message._bv_service_callback - 服务调用参数
 * @param {string} body._bv_callback_message._bv_service_callback.requestId - 用于标记请求
 * @param {string} body._bv_callback_message._bv_service_callback.identifier - 服务唯一标识符
 * @param {string} body._bv_callback_message._bv_service_callback.version - 消息格式版本
 * @param {number} body._bv_callback_message._bv_service_callback.timestamp - 服务调用时间
 * @param {number} flag - 入参类型标识,0=实体注册,1=属性上报,2=事件上报
 * @returns {JSONObject} 出参,BV JSON数据格式,不能为空
 */
function rawDataToProtocol(body, flag) {
    var inputData = body;
    var jsonObj = {};
    if (flag === 0) {
        /**
         * @returns {string} return.deviceId - 实体编号,需保证全局唯一性,必传
         * @returns {string} return.deviceName - 实体名称(最大长度255),必传
         * @returns {number} return.deviceStatus - 实体状态, 0=禁用,1=启用(默认),非必传
         * @returns {number} return.deviceType - 实体类型,0=动态资源,1=静态资源,必传
         * @returns {string} return.location - 实体位置(默认0 0 0),格式:纬度 经度 高程,非必传
         * @returns {string} return.version - 版本号(默认default),非必传
         * @returns {JSONObject} return.payload - 扩展数据,用于更新实体属性值,数据基于产品 Profile 定义的属性过滤(已定义属性对应的数据保留,未定义属性对应的数据弃用),非必传
         */
        jsonObj['deviceId'] = inputData.guid;
        jsonObj['deviceName'] = inputData.name;
          jsonObj['deviceStatus'] = inputData.status;
          jsonObj['payload'] = inputData;
        return jsonObj;
    }
    if (flag === 1) {
        /**
         * @returns {string} return.deviceId - 实体编号,需保证全局唯一性,必传
         * @returns {string} return.deviceSecret - 实体签名(不传时将系统匹配),非必传
         * @returns {string} return.deviceName - 实体名称(最大长度255),非必传
         * @returns {number} return.deviceStatus - 实体状态, 0=禁用,1=启用(默认),非必传
         * @returns {string} return.location - 实体位置(默认0 0 0),格式:纬度 经度 高程,非必传
         * @returns {number} return.timestamp - 上行数据传输时间戳。格式为数值,值为从UTC 1970-01-01 00:00:00开始到当前时刻的毫秒数,非必传
         * @returns {string} return.version - 版本号(默认default),非必传
         * @returns {JSONObject} return.payload - 扩展数据,用于更新实体属性值,数据基于产品 Profile 定义的属性过滤(已定义属性对应的数据保留,未定义属性对应的数据弃用),非必传
         */

        jsonObj['deviceId'] = inputData.guid;
        jsonObj['deviceStatus'] = inputData.status;
        jsonObj['payload'] = inputData;
        return jsonObj;
    }
    if (flag === 2) {
        /**
         * @returns {string} return.deviceId - 实体编号,需保证全局唯一性,必传
         * @returns {string} return.deviceSecret - 实体签名(不传时将系统匹配),非必传
         * @returns {string} return.deviceName - 实体名称(最大长度255),非必传
         * @returns {number} return.deviceStatus - 实体状态, 0=禁用,1=启用(默认),非必传
         * @returns {string} return.location - 实体位置(默认0 0 0),格式:纬度 经度 高程,非必传
         * @returns {string} return.identifier - 事件的唯一标识符,必传
         * @returns {number} return.timestamp - 上行数据传输时间戳。格式为数值,值为从UTC 1970-01-01 00:00:00开始到当前时刻的毫秒数,非必传
         * @returns {string} return.version - 版本号(默认default),非必传
         * @returns {JSONObject} return.payload - 扩展数据,事件的输出参数,数据基于产品 Profile 定义的事件输出参数过滤(已定义输出参数对应的数据保留,未定义输出参数对应的数据弃用),非必传
         */
        jsonObj['deviceId'] = inputData.guid;
          jsonObj['identifier'] = inputData.notificationType;
        jsonObj['payload'] = inputData.content;
          jsonObj['timestamp'] = inputData.timestamp;
        return jsonObj;
    }

}

建立WebSocket连接(调试步骤,若已有真实设备客户端可跳过)

使用APIFox模拟WebSocket客户端,模拟接收实体反向控制的服务“温度调节服务”的通知。模拟接收设置某个冰箱设备的温度调节指令。

  1. 点击新建一个WebSocket接口,命名为“温湿度传感器”。
  2. 在连接地址中输入完整的ws地址。如ws地址为“ws://192.168.100.37:44050/Re8agKekkXw8Oczi/resetDeviceWS” 。 注意:“/{productid}/{identifier}”需使用正确的产品ID productid 服务标识符 identifier替换。
  3. 点击“连接”,查看是否能正确连接到DTS内置的WebSocket服务端。
  4. 连接成功,等待DTS发送需执行服务的通知。

null

创建任务

  1. 在任务管理页面,创建一个任务名为“温度调节服务“的场景。

任务逻辑

每个工作日晚上18点 触发 执行任务 重启复位服务

  1. 创建完成后,进入编辑页面。根据任务逻辑编辑对应的规则。设定触发条件为每个工作日18点,添加执行任务类型为”服务调用“,选择温度传感器产品下的某一实体或全部实体,执行服务”重启复位服务”。

null

设置服务调用的参数

  1. 设置服务调用的参数,deviceid使用插入变量的方式,设置其值为温湿度传感器下的当前实体(执行此任务的实体)。

null

  1. 保存任务,启动任务。手动执行任务,进行任务的检查。
  2. 前往任务-执行日志,查看任务的执行情况。

APIFox查看请求

在APIFox的“智能冰箱”WebSocket中查看是否接收到来自DTS的请求执行服务的数据。_bv_callback_message发送的回执参数。从中可获取到结果返回的方式 _bv_callback_method以及结果返回地址 _bv_callback_url。请求体中还有执行此次服务的输入参数。

null

若服务端并未收到来自DTS的服务请求,请检查服务定义以及目标服务与DTS之间的网络是否通畅。

APIFox模拟设备端上报

  1. 根据HTTP协议的HTTP协议实体接入(BV JSON数据格式)-属性上报接口、HTTP协议实体接入(BV JSON数据格式)-事件上报接口,在APIFox中编写返回结果。
  2. 接口地址填写_bv_callback_url的值,请求体中productId identifier deviceId均来自_bv_callback_message。
  3. 接口准备完毕,点击发送。

属性上报发送请求体示例

{
    "method": 0,
    "productId": "MNGRcylFFmLxxvJh",
    "deviceId": "407ddc2c-1860-4afe-a26a-cfb06228016c",
    "deviceStatus": 0,
    "payload": {
        "status": true
    }
}

事件上报发送请求体示例

{
    "method": 1,
    "productId": "MNGRcylFFmLxxvJh",
    "deviceId": "407ddc2c-1860-4afe-a26a-cfb06228016c",
    "identifier": "getResult",
    "deviceStatus": 0,
    "payload": {
        "status": true
    }
}

若数据格式为透传/自定义,则需根据HTTP协议实体接入(透传/自定义)-属性上报接口、HTTP协议实体接入(透传/自定义)-事件上报接口,在APIFox中编写返回结果。

返回服务结果时,尽量携带回执参数。在透传/自定义数据格式下,可根据回执参数进行特殊的处理逻辑。

属性上报发送请求体示例

{
        "guid": "970bdf41-7818-4718-b00e-eb14a08b6372",
        "status": 0,
        "resetStatus": true,
        "_bv_callback_message": {
                "_bv_service_callback": {
                        "identifier": "resetDevice",
                        "requestId": "0d6b56b5fafd4510bf1c4339a137e91c",
                        "version": "default",
                        "timestamp": 1752051738967
                },
                "productId": "Re8agKekkXw8Oczi",
                "deviceId": "970bdf41-7818-4718-b00e-eb14a08b6372"
        }
}

事件上报发送请求体示例

{
    "deviceType": "SmartRefrigerator",
    "guid": "970bdf41-7818-4718-b00e-eb14a08b6372",
    "notificationType": "getResult",
    "content": {
        "status": true
    },
    "timestamp": 1752053423202,
    "_bv_callback_message": {
        "identifier": "getResult",
        "_bv_service_callback": {
            "identifier": "resetDevice",
            "requestId": "662f7c9a02084672ad02d3e650776cca",
            "version": "default",
            "timestamp": 1752053377098
        },
        "productId": "Re8agKekkXw8Oczi",
        "deviceId": "970bdf41-7818-4718-b00e-eb14a08b6372"
    }
}

结果验证

属性上报的结果可以在实体状态中直接查看,也可以经过订阅管理将向DTS订阅实体的属性变化 and 事件发生的数据,订阅端收到数据之后进行可视化处理便能对设备进行实时数据监控。DTS数据孪生架构提供快速接入查看DTS设备数据的平台功能低代码设计器(无需订阅),详细可视化功能可查看《BigView低代码设计器教程》