Skip to content

OPCUA

概述

OPC UA(Open Platform Communications Unified Architecture)是一种工业自动化领域的跨平台通信协议,支持数据访问、报警与事件、历史数据等功能。本控制器支持作为 OPC UA 客户端连接远程服务器,同时也可作为 OPC UA 服务器供其他设备访问,实现双向数据交互。

核心功能

功能说明
连接管理支持客户端/服务器双模式,可独立启停
节点读写读写 OPC UA 服务器中的变量节点
订阅监控订阅节点数据变化,实时推送更新
安全认证支持用户名/密码认证方式

工作模式

  • 客户端模式:控制器作为 OPC UA 客户端,连接外部 OPC UA 服务器,读写对方提供的变量节点
  • 服务器模式:控制器作为 OPC UA 服务器,开放本地变量供外部客户端访问

上位机设置 OPCUA 参数

命令字: 0x7350

参数说明

字段类型必填描述
clientobject客户端参数
client.enablebool客户端连接使能,true-开启,false-关闭
client.ipstringOPC UA 服务器 IP 地址
client.portint服务器端口号,范围 [0, 65535],默认 4840
client.resourcestring服务器资源路径/名称
client.usernamestring登录用户名(需服务器支持)
client.passwordstring登录密码
client.securitystring安全策略,可选 "None" / "Basic256Sha256" / "Basic128Rsa15"
serverobject服务器参数
server.enablebool服务器使能,true-开启,false-关闭
server.ipstring控制器用作服务器时的 IP 地址
server.portint服务器端口号,范围 [0, 65535],默认 4840

配置说明

  • client.enableserver.enable 可以同时开启,控制器将同时运行客户端和服务端
  • 客户端模式下,client.ipclient.port 必须指向有效的 OPC UA 服务器
  • 若服务器需要认证,需同时填写 client.usernameclient.password
  • 安全策略选择需与目标服务器支持的策略一致

请求示例

json
{
  "client":
  {
    "enable": true,
    "ip": "192.168.1.240",
    "port": 49400,
    "resource": "ProsysServer",
    "username": "admin",
    "password": "123456",
    "security": "None"
  },
  "server":
  {
    "enable": true,
    "ip": "192.168.0.229",
    "port": 4840
  }
}

上位机查询 OPCUA 参数

命令字: 0x7351

请求示例

json
{}

控制器回复上位机 OPCUA 参数

命令字: 0x7352

参数说明

字段类型描述
clientobject客户端参数
client.enablebool连接使能
client.ipstring服务器 IP 地址
client.portint端口号
client.resourcestring服务器名称
client.connectedbool客户端连接状态,true-已连接,false-未连接
serverobject服务器参数
server.enablebool服务器使能
server.ipstring控制器用作服务器时的 IP 地址
server.portint端口号
server.connectedbool是否有客户端连接,true-有客户端连接,false-无连接

响应示例

json
{
  "client":
  {
    "enable": true,
    "ip": "192.168.1.240",
    "port": 49400,
    "resource": "ProsysServer",
    "connected": true
  },
  "server":
  {
    "enable": true,
    "ip": "192.168.0.229",
    "port": 4840,
    "connected": false
  }
}

OPC UA 节点读写

控制器作为客户端连接 OPC UA 服务器后,可读写服务器中的变量节点。

上位机请求读取节点

命令字: 0x7353

参数说明

字段类型必填描述
nodeIdstring目标节点的 NodeId,如 "ns=2;s=Temperature"
nodeIdTypeintNodeId 类型,0-字符串,1-数字,2-GUID,3-Opaque,默认 0
namespaceint命名空间索引,默认 0

节点标识说明

OPC UA 节点通过以下方式定位:

标识方式格式示例说明
字符串 IDns=2;s=MyVariable使用字符串标识
数字 IDns=2;i=1001使用数字标识
GUIDns=2;g=ABC123...使用 GUID
浏览路径/Objects/MyDevice/Temperature使用路径浏览

请求示例

json
{
  "nodeId": "ns=2;s=Temperature",
  "nodeIdType": 0,
  "namespace": 2
}

控制器回复节点读取结果

命令字: 0x7354

参数说明
字段类型描述
nodeIdstring读取的节点 ID
valuevariant节点当前值
dataTypestring数据类型,如 "Int32" / "Double" / "Boolean" / "String"
timestampstring数据时间戳(ISO 8601 格式)
statusint读取状态,0-成功,非0-失败
errorMsgstring错误信息(仅失败时返回)
响应示例
json
{
  "nodeId": "ns=2;s=Temperature",
  "value": 25.6,
  "dataType": "Double",
  "timestamp": "2024-03-15T10:30:00Z",
  "status": 0
}

上位机请求写入节点

命令字: 0x7355

参数说明

字段类型必填描述
nodeIdstring目标节点的 NodeId
valuevariant要写入的值
dataTypestring写入值的数据类型

请求示例

json
{
  "nodeId": "ns=2;s=SetPoint",
  "value": 100.0,
  "dataType": "Double"
}

控制器回复节点写入结果

命令字: 0x7356

参数说明

字段类型描述
nodeIdstring写入的节点 ID
statusint写入状态,0-成功,非0-失败
errorMsgstring错误信息(仅失败时返回)

响应示例

json
{
  "nodeId": "ns=2;s=SetPoint",
  "status": 0
}

批量读写节点

命令字: 0x7357

参数说明

字段类型必填描述
operationsobject[]批量操作列表
operations[].opTypestring操作类型,"read"-读取,"write"-写入
operations[].nodeIdstring节点 ID
operations[].valuevariant写入值(opType="write" 时必填)

请求示例

json
{
  "operations": [
    { "opType": "read", "nodeId": "ns=2;s=Temperature" },
    { "opType": "read", "nodeId": "ns=2;s=Pressure" },
    { "opType": "write", "nodeId": "ns=2;s=SetPoint", "value": 50.0 }
  ]
}

OPC UA 订阅机制

订阅功能允许控制器持续监控 OPC UA 服务器中的指定节点,当节点值发生变化时,服务器主动推送更新数据,无需轮询。

上位机创建订阅

命令字: 0x7358

参数说明

字段类型必填描述
subscriptionIdstring订阅唯一标识符,用于后续管理
publishingIntervalint发布间隔(毫秒),服务器以此周期检查并推送变化数据
lifetimeCountint订阅生存周期计数,默认 10000
maxKeepAliveCountint最大保活计数,默认 3000
monitoredItemsobject[]监控项列表
monitoredItems[].nodeIdstring要监控的节点 ID
monitoredItems[].samplingIntervalint采样间隔(毫秒)
monitoredItems[].queueSizeint队列大小,默认 1
monitoredItems[].discardOldestbool队列满时是否丢弃最旧数据,默认 true
monitoredItems[].deadbandTypeint死区类型,0-无,1-绝对值,2-百分比
monitoredItems[].deadbandValuedouble死区值,仅当值变化超过此阈值时才触发通知

订阅参数建议

参数推荐值说明
publishingInterval100~1000 ms发布周期,越小实时性越好但网络负载越大
samplingIntervalpublishingInterval 的 1/2 ~ 1/5采样周期应小于发布周期
queueSize1~10数据变化队列,应对突发变化
lifetimeCount≥ 3 × maxKeepAliveCount订阅有效期,超时无保活则自动清理
deadbandValue根据精度需求设定变化阈值,过滤微小波动

请求示例

json
{
  "subscriptionId": "sub_temp_001",
  "publishingInterval": 200,
  "lifetimeCount": 10000,
  "maxKeepAliveCount": 3000,
  "monitoredItems": [
    {
      "nodeId": "ns=2;s=Temperature",
      "samplingInterval": 100,
      "queueSize": 5,
      "discardOldest": true,
      "deadbandType": 1,
      "deadbandValue": 0.5
    },
    {
      "nodeId": "ns=2;s=Pressure",
      "samplingInterval": 200,
      "queueSize": 1
    }
  ]
}

控制器上报订阅数据

命令字: 0x7359

当订阅的节点数据发生变化时,控制器主动推送数据至上位机。

参数说明

字段类型描述
subscriptionIdstring订阅 ID
dataChangesobject[]变化的数据列表
dataChanges[].nodeIdstring节点 ID
dataChanges[].valuevariant节点当前值
dataChanges[].timestampstring时间戳
sequenceNumberint序列号,递增

响应示例

json
{
  "subscriptionId": "sub_temp_001",
  "dataChanges": [
    {
      "nodeId": "ns=2;s=Temperature",
      "value": 26.8,
      "timestamp": "2024-03-15T10:30:01Z"
    }
  ],
  "sequenceNumber": 42
}

上位机修改订阅

命令字: 0x735A

修改已有订阅的监控项或发布参数。

参数说明

字段类型必填描述
subscriptionIdstring要修改的订阅 ID
publishingIntervalint新的发布间隔
addItemsobject[]新增监控项列表
removeItemsstring[]移除监控项的 nodeId 列表

请求示例

json
{
  "subscriptionId": "sub_temp_001",
  "publishingInterval": 500,
  "addItems": [
    { "nodeId": "ns=2;s=Humidity", "samplingInterval": 500 }
  ],
  "removeItems": ["ns=2;s=Pressure"]
}

上位机删除订阅

命令字: 0x735B

停止并删除指定订阅。

参数说明

字段类型必填描述
subscriptionIdstring要删除的订阅 ID

请求示例

json
{
  "subscriptionId": "sub_temp_001"
}

连接状态管理

控制器主动上报连接状态

命令字: 0x735C

当 OPC UA 客户端或服务器连接状态发生变化时,控制器主动推送状态更新。

参数说明

字段类型描述
rolestring角色,"client" / "server"
statusint状态码:0-已断开,1-连接中,2-已连接,3-连接失败
errorMsgstring错误描述(连接失败时返回)
timestampstring状态变化时间

响应示例

json
{
  "role": "client",
  "status": 2,
  "timestamp": "2024-03-15T10:29:55Z"
}

常见问题

连接失败排查

现象可能原因解决方案
客户端无法连接IP/端口错误检查 client.ipclient.port 是否正确
客户端无法连接安全策略不匹配确认 client.security 与服务器一致
客户端无法连接网络不通用 ping 测试网络连通性
节点读取失败NodeId 格式错误确认 nodeId 格式,如 ns=2;s=xxx
节点读取失败命名空间索引错误确认 namespace 值匹配服务器实际命名空间
写入失败权限不足确认服务器对目标节点开放了写入权限
订阅无数据推送发布间隔过大减小 publishingInterval
订阅无数据推送死区设置过大减小 deadbandValue 或关闭死区

性能建议

  • 批量操作优先使用批量读写命令(0x7357),减少通信开销
  • 订阅监控项不宜过多,建议单个订阅不超过 50 个节点
  • 采样间隔应根据数据变化频率合理设置,避免过度采样
  • 发布间隔不宜过小,推荐 100ms ~ 1000ms