Files
softbus_OPC/docs/softbus_opcua.md
2026-06-09 17:27:24 +08:00

9.0 KiB
Raw Permalink Blame History

softbus_opcua

路径: src/softbus_opcua
构建目标: softbus_opcuaSTATIC 库)
依赖: open62541 v1.4.6
层级: L2 服务层

1. 概述

softbus_opcua 基于 open62541 封装 OPC UA 服务端,将 SoftBus 对象模型动态映射为 OPC UA 地址空间,实现:

  • ObjectModelTree 动态构建地址空间节点树
  • DOMMessage 实时绑定到 UA Variable 节点
  • 暴露 ExecuteCommand 为 OPC UA Method(反向控制入口)

Phase 1 范围: 动态地址空间、Double Variable、ExecuteCommand MethodTLS 与 Event 为 stub。

2. CONSTRAINTS

  • OPC UA 层不得引入 SoftBus 业务逻辑,仅负责地址空间构建、值绑定与方法转发。
  • NodeId 策略统一Namespace Index = 1Identifier 类型 = String值为 objectRef.toPath()
  • 所有 open62541 调用须包裹 #if SOFTBUS_HAS_OPCUA 条件编译。
  • Method 入参/出参均使用 JSON 字符串UA Stringsoftbus_api::ExecuteCommand 对齐。
  • Event 发射 Phase 1 为 stub仅打日志不得伪装为已生效功能。
  • Phase 2 静态 NodeSetconfig/ua_model.xml)导入时,不得破坏动态构建的 NodeId 约定。

3. 组件架构

UaServerEngine          ← open62541 生命周期管理
    │
    ├── UaAddressSpaceBuilder   ← JSON 模型 → UA 节点树
    ├── UaModelBinder           ← DOMMessage → Variable 写值
    ├── UaMethodBinder          ← ExecuteCommand Method 回调
    └── UaEventBridge           ← Event 发射Phase 1 stub

4. UaServerEngine

4.1 职责

管理 UA_Server 实例的创建、配置、运行与销毁。

4.2 公共 API

方法 入参 返回 说明
start(port, applicationName, security) 端口、应用名、安全配置 bool 启动 OPC UA 服务
stop() void 停止服务
iterate() void 驱动事件循环(主循环调用)
isRunning() bool 运行状态
nativeServer() UA_Server* 获取原生服务器指针

4.3 SecurityConfig

字段 类型 Phase 1
enableTls bool 未实现,忽略
certPath string 未实现
keyPath string 未实现
trustListPath string 未实现

Phase 1 使用 UA_ServerConfig_setMinimal() 创建无安全策略的服务端。

4.4 配置来源

字段 配置路径 默认值
端口 daemon_profile.jsonopcua.port 4840
应用名 daemon_profile.jsonopcua.applicationName SoftBusDaemon
TLS daemon_profile.jsonsecurity.* 关闭

连接端点: opc.tcp://localhost:4840

5. 地址空间

5.1 节点树结构

ObjectsFolder (NS0, 标准节点)
├── SoftBusControl (Object, NS1)
│   └── ExecuteCommand (Method, NS1)
│       ├── InputArguments:  commandJson (String)
│       └── OutputArguments: resultJson (String)
└── {Site} (Object, NS1)
    └── {System} (Object, NS1)
        └── {Asset} (Object, NS1)
            └── {stableDeviceKey} (Object, NS1)
                └── {pointName} (Variable, NS1, Double, R/W)

5.2 示例(基于默认模型)

ObjectsFolder
├── SoftBusControl
│   └── ExecuteCommand
└── DemoSite
    └── DemoSystem
        └── DemoAsset
            └── SimModbusDevice
                └── Temperature (Double, 初始值 0.0)

5.3 NodeId 约定

节点类型 Namespace Identifier 类型 Identifier 值
Site 1 String {siteName}
System 1 String {systemName}
Asset 1 String {assetName}
Device 1 String {stableDeviceKey}
Point (Variable) 1 String {objectRef.toPath()}
SoftBusControl 1 String SoftBusControl
ExecuteCommand 1 String ExecuteCommand

Point 节点完整路径示例:

NodeId: ns=1;s=DemoSite/DemoSystem/DemoAsset/SimModbusDevice/Temperature

5.4 Variable 属性

属性
DataType Double (UA_TYPES_DOUBLE)
AccessLevel Read + Write
TypeDefinition BaseDataVariableType
初始值 0.0
ReferenceType HasComponent

5.5 模型映射规则

softbus_model.json 字段 OPC UA 节点
site Site Object
system System ObjectSite 子节点)
asset Asset ObjectSystem 子节点)
devices[].stableDeviceKey Device ObjectAsset 子节点)
devices[].points[].name VariableDevice 子节点)

构建完成后,UaModelBinder::registerPointNode(objectRef, nodeId) 建立 objectRef → UA_NodeId 映射。

6. UaModelBinder

6.1 职责

维护 objectRef → UA_NodeId 映射表,将 DOMMessage 实时写入对应 Variable。

6.2 公共 API

方法 说明
registerPointNode(objectRef, nodeId) 注册映射(构建阶段调用)
bind(DOMMessage) 写值到 OPC UA Variable

6.3 绑定逻辑

  1. 查找键 = message.id(非空时)或 message.sourceId
  2. message.value 提取数值:
    • 优先 value["value"]
    • 备选 value["registerValue"]
  3. 调用 UA_Server_writeValue(server, nodeId, doubleValue)

6.4 数据流

PipelineEngine::process(RawPacket)
  → ModbusParser → DOMMessage
  → UaModelBinder::bind(DOMMessage)
  → UA_Server_writeValue
  → OPC UA Client 可读

7. UaMethodBinder — ExecuteCommand Method

7.1 Method 定义

属性
BrowseName ExecuteCommand
Parent Object SoftBusControl
InputArguments commandJson (String) — JSON 格式的 ExecuteCommand
OutputArguments resultJson (String) — JSON 格式响应

7.2 入参 JSON Schema

{
  "traceId": "string (required)",
  "objectRef": "string (required, 五层路径)",
  "command": "string (required)",
  "params": "object (required)"
}

OPC UA Method 入参不含 type 字段,由 ExecuteCommand::fromJson() 直接解析。

7.3 出参 JSON Schema

成功:

{"success": true}

失败:

{"success": false, "error": "错误描述"}

7.4 调用流程

OPC UA Client 调用 ExecuteCommand(commandJson)
  → executeCommandMethod() 回调
  → nlohmann::json::parse(commandJson)
  → ExecuteCommand::fromJson() + validate()
  → dispatchCommand() → handler_(cmd)
  → CommandDispatcher → TCP 下行
  → 返回 resultJson

7.5 客户端调用示例UaExpert

  1. 连接 opc.tcp://localhost:4840
  2. 浏览至 Objects → SoftBusControl → ExecuteCommand
  3. 右键调用 Method输入
{"traceId":"trace-ua-001","objectRef":"DemoSite/DemoSystem/DemoAsset/SimModbusDevice/Temperature","command":"write","params":{"value":42.5}}

8. UaEventBridgePhase 1 stub

方法 说明 Phase 1 行为
emitHeartbeat() 心跳事件 仅日志
emitDeviceOnline(objectRef) 设备上线 仅日志
emitDeviceOffline(objectRef) 设备离线 仅日志
emitParseError(traceId, detail) 解析错误 仅日志

9. UaAddressSpaceBuilder

9.1 职责

ObjectModelTree 递归创建 OPC UA 对象树与 Variable 节点。

9.2 构建流程

  1. 获取 ObjectsFolder 标准节点作为根
  2. 创建 SoftBusControl Object 与 ExecuteCommand Method
  3. 按 Site → System → Asset → Device → Point 层级递归 UA_Server_addObjectNode / addVariableNode
  4. 每个 Point 调用 binder->registerPointNode(objectRef, nodeId)

10. 条件编译

说明
SOFTBUS_HAS_OPCUA CMake 选项 SOFTBUS_WITH_OPCUA=ON 时定义
SOFTBUS_WITH_OPCUA CMake option默认 ON

未启用时,所有 OPC UA 方法返回 false 或空操作。

11. open62541 配置

CMake 通过 SoftbusThirdParty.cmake 以 vendor 方式引入 third_party/open62541v1.4.6

选项 说明
UA_ENABLE_SUBSCRIPTIONS ON 订阅支持
UA_ENABLE_METHODCALLS ON 方法调用
UA_ENABLE_DISCOVERY ON 发现服务
UA_ENABLE_ENCRYPTION OFF Phase 1 无加密

12. Phase 路线图

阶段 功能 状态
Phase 1 动态地址空间、Double Variable、ExecuteCommand、无 TLS 当前
Phase 2 ua_model.xml NodeSet2 导入、TLS/mTLS、StatusCode 映射 规划
Phase 2 真实 Event 发射DeviceOnline/Offline、ParseError 规划
Phase 3 Subscription 优化、历史数据、多 DataType 支持 规划

12.1 Phase 2 NodeSet 占位

config/ua_model.xml 当前为空 shell注释标明 Phase 2 可能导入静态 NodeSet2 XML届时与动态构建策略需协调 NodeId 一致性。

13. 依赖

  • softbus_coreObjectModelTree, DOMMessage, ObjectRef
  • softbus_apiExecuteCommand
  • open62541(条件依赖)
  • 被依赖: softbus_daemon