跳到主要内容

OPC-UA 驱动

概览​

基于 OPC Unified Architecture (IEC 62541) 的工业数据标准协议。

项目值
opc_typeOPCUA
实现类plantpulse.driver.protocol.opcua.OPCUA_34_Driver
库Eclipse Milo (milo-sdk-client)
read✅
write✅ (node.writeValue)
安全用户认证 Anonymous, Username/Password。通道安全 None · Sign · SignAndEncrypt · auto

与 Kepware, Matrikon, Prosys 等绝大多数 OPC-UA 服务器兼容。


OPC 注册表单​

字段含义示例
opc_agent_ipOPC-UA 服务器 IP192.168.0.40
opc_agent_portOPC-UA 服务器 TCP 端口49320 (Kepware 默认)
timecycle采集周期 (ms)1000
options.servernameendpoint 末尾的服务器名称(Kepware 则留空)
options.username认证用户kopens
options.password认证密码***
options.discovery若为 true,则在连接时从 RootFolder 开始浏览整个节点树并记录在日志中(非端点搜索 — 端点请使用界面的 [查询端点])false (建议)
options.security_mode通道安全模式。None(默认) · Sign · SignAndEncrypt · auto(在 Sign · SignAndEncrypt 中选择最强模式)。若非 None,则不会降级为 None。忽略大小写,未知值设为 OPCUA_SECURITY_CONFIG_INVALIDSignAndEncrypt
options.security_policyauto(默认) · Basic256Sha256 · Aes128_Sha256_RsaOaep · Aes256_Sha256_RsaPss。auto 的优先级为 Aes256_Sha256_RsaPss > Basic256Sha256 > Aes128_Sha256_RsaOaep。若安全模式为 None 则忽略auto
options.allow_deprecated_policy若为 true,则允许已弃用的 Basic256 · Basic128Rsa15 (auto 进入候选并可明确指定)。除 true/false 外的值为 OPCUA_SECURITY_CONFIG_INVALIDfalse

生成的 endpoint URL 格式:

opc.tcp://<opc_agent_ip>:<opc_agent_port>/<servername>

若 username + password 同时存在则使用 UsernameProvider,否则使用 AnonymousProvider。

pki_dir(客户端证书与信任列表目录)并非输入框。仅在 edge-web 安全模式不为 None 时插入 $PE_DATA_DIR/pp-data/opcua-client,连接行中保存的值将被舍弃。

端点选择:

  • security_mode=None (OPCUA_34_Driver.selectEndpoint) — 仅在服务器公布的列表中选择 MessageSecurityMode.None 的项。优先选择公布了所用令牌类型 (UserName / Anonymous) 的端点,若无则选择第一个 None 端点。
  • 其他模式 (OpcuaEndpointSelector.selectSecure) — 在同时满足接受模式、策略及所用令牌类型的端点中,选择最强的一个。若无,则不降级至 None,而是以 OPCUA_NO_MATCHING_ENDPOINT 失败。

所选端点 URL 的主机将替换为 opc_agent_ip(端口和路径使用服务器公布的值)。已知原因的失败(证书 · 安全设置 · 无匹配端点)将记录一行 OPCUA connect refused: error_code=<코드> opc_id=<OPC ID> ... WARN(同一原因仅记录一次)。OPCUA_CONNECT_FAILED · OPCUA_PKI_ERROR 每次均记录 OPCUA connect failed: ... ERROR 及堆栈信息。

安全连接的界面流程

服务器证书信任、Edge 证书下载及错误提示请参阅 OPC-UA 连接 — 安全连接。首次见到的服务器证书将被拒绝(首次连接无自动信任),需在界面由操作员信任后方可连接。


标签 plc_address 格式​

OPC-UA 标准 NodeId 表示法。例如:

表示法含义
ns=2;s=Simulator.Sine1命名空间 2, 字符串标识符 Simulator.Sine1
ns=2;i=1234数值标识符 1234
ns=3;g=09087e75-8e5e-499b-954f-f2a8624db28aGUID 标识符
ns=2;b=Mb=不透明 (bytestring) 标识符

对于 Kepware,通常采用 ns=2;s=<Channel>.<Device>.<Tag> 格式。


data_type / format 映射​

将 OPC-UA 变量节点的 Value 转换为 String 后返回。data_type 由后续阶段 (PLCValueFomula, Sparkplug 发布等) 用于转换。

data_type动作
Float / Double数值原样返回
Int / Integer / Int32 / Short / Long数值原样返回
Boolean / Booltrue/false 字符串
String / TextUTF-8 字符串
DateTimeISO 字符串

format 在 OPC-UA 中通常不使用。如需后处理公式,请使用 fomula。


常见错误 + 解决​

消息 / 症状原因解决
connection refused服务器未运行,端口被封锁通过 telnet <ip> <port> 确认通信
Bad_UserAccessDenied用户名/密码错误,禁止匿名访问在服务器端注册用户或激活 anonymous
OPCUA_CLIENT_CERT_REJECTED (Bad_SecurityChecksFailed 等)服务器不信任 Edge 客户端证书将 Edge 证书 (.der) 加入服务器信任列表
OPCUA_NO_MATCHING_ENDPOINT服务器未公布该模式·策略·令牌的端点通过界面的 [查询端点] 确认服务器提供的组合并进行匹配
端口不匹配导致连接失败驱动仅将公布端点的主机更改为 opc_agent_ip,端口和路径维持原样若通过 NAT·端口转发更改端口公开,请将其配置为与服务器公布的端口一致。无需 hosts 映射
值始终为 0 / nullNodeId 拼写错误,命名空间编号不一致使用 UA Expert 等客户端验证相同 NodeId 的 read 操作

curl 注册示例​

curl -X POST http://<edge-host>/api/v1/opc \
-H "Content-Type: application/json" \
-d '{
"opc_id": "OPC_UA_Kepware",
"opc_type": "OPCUA",
"opc_name": "Kepware",
"opc_agent_ip": "192.168.0.40",
"opc_agent_port": "49320",
"site_id": "SITE_00001",
"auto_collect": true,
"timecycle": 1000,
"options": {
"username": "kopens",
"password": "***",
"discovery": "false"
},
"tag_list": [
{
"tag_id": "OPC_UA_Kepware_TAG_00001",
"tag_name": "Sine1",
"plc_address": "ns=2;s=Simulator.Sine1",
"data_type": "Float",
"description": "Sine wave"
},
{
"tag_id": "OPC_UA_Kepware_TAG_00002",
"tag_name": "Random1",
"plc_address": "ns=2;s=Simulator.Random1",
"data_type": "Integer"
}
]
}'

读取值:

curl -s http://<edge-host>/api/v1/tag/OPC_UA_Kepware_TAG_00001/value | jq

参考:Kepware 快速配置指南​

  1. Kepware Server → Project → 添加通道 (例如:Simulator)。
  2. 添加设备 (例如:Simulator) → 型号 = 16 Bit Device。
  3. 添加标签 → Sine1, 类型 Float, 扫描率 100ms 等。
  4. 在 Project Properties → OPC UA → Server Endpoint 中激活端口 49320。
  5. 激活 Anonymous 或用户账户。若为安全连接,请在端点安全策略中开启 Basic256Sha256 以上级别及 Sign and Encrypt,并将 Edge 证书加入信任列表。

→ Edge 注册表单:

字段值
opc_agent_ipKepware 服务器 IP
opc_agent_port49320
options.servername(留空)
options.username/password上述创建的账户
plc_addressns=2;s=Simulator.Simulator.Sine1

示例集 (按数据类型)​

OPC-UA 将变量节点的值 (Variant) 转换为 String 后返回。data_type 由后处理 (PLCValueFomula, Sparkplug DataTypeMapper) 用于转换。format 通常不使用。

Boolean​

data_typeplc_address 示例备注
Booleanns=2;s=Simulator.Boolean1Kepware Simulator 的 Boolean 标签
Booleanns=2;s=PLC.Status.RunningKepware Channel.Device.Tag
Booleanns=2;i=1003数值型 NodeId

16/32-bit 整数​

data_typeplc_address 示例备注
Integerns=2;s=Simulator.Random1随机整数模拟
Integerns=2;s=Simulator.Counter1计数器
Integerns=2;s=PLC.D100Kepware MELSEC 通道公开

64-bit 整数​

data_typeplc_address 示例备注
Longns=2;s=Simulator.LongCounterUInt64 / Int64 节点
Longns=2;s=PLC.Cycle.Total累积计数器

浮点数​

data_typeplc_address 示例备注
Floatns=2;s=Simulator.Sine1正弦波模拟
Floatns=2;s=Simulator.Ramp1锯齿波
Doublens=2;s=PLC.Pressure精密测量值

字符串​

data_typeplc_address 示例备注
Stringns=2;s=Simulator.User1.Name字符串节点
Stringns=2;s=PLC.Recipe.Active配方名称

按 NodeId 格式​

标识符类型plc_address 示例
String (s=)ns=2;s=Simulator.Sine1
Numeric (i=)ns=2;i=1234
GUID (g=)ns=3;g=09087e75-8e5e-499b-954f-f2a8624db28a
Opaque (b=)ns=2;b=Mb=

计算公式应用​

用途data_typefomula备注
单位转换Float${VALUE}*0.001g → kg 等
零点校准Float${VALUE}-${TAG_ZERO}可引用其他 OPCUA 标签
类型转换Float${VALUE}*1.0强制 Integer → Float
多项式Float${VALUE}*${VALUE}*0.0001非线性

curl 综合示例 (所有类型)​

curl -X POST http://<edge-host>/api/v1/opc \
-H "Content-Type: application/json" \
-d '{
"opc_id": "OPC_UA_FULL",
"opc_type": "OPCUA",
"opc_name": "Kepware Full",
"opc_agent_ip": "192.168.0.40",
"opc_agent_port": "49320",
"site_id": "SITE_00001",
"auto_collect": true,
"timecycle": 1000,
"options": { "discovery": "false" },
"tag_list": [
{"tag_id":"OPC_UA_FULL_T01", "tag_name":"BoolTag", "plc_address":"ns=2;s=Simulator.Boolean1", "data_type":"Boolean"},
{"tag_id":"OPC_UA_FULL_T02", "tag_name":"IntTag", "plc_address":"ns=2;s=Simulator.Random1", "data_type":"Integer"},
{"tag_id":"OPC_UA_FULL_T03", "tag_name":"LongTag", "plc_address":"ns=2;s=Simulator.LongCounter", "data_type":"Long"},
{"tag_id":"OPC_UA_FULL_T04", "tag_name":"FloatTag", "plc_address":"ns=2;s=Simulator.Sine1", "data_type":"Float"},
{"tag_id":"OPC_UA_FULL_T05", "tag_name":"DoubleTag", "plc_address":"ns=2;s=PLC.Pressure", "data_type":"Double"},
{"tag_id":"OPC_UA_FULL_T06", "tag_name":"StringTag", "plc_address":"ns=2;s=Simulator.User1.Name", "data_type":"String"},
{"tag_id":"OPC_UA_FULL_T07", "tag_name":"NumIdTag", "plc_address":"ns=2;i=1234", "data_type":"Integer"},
{"tag_id":"OPC_UA_FULL_T08", "tag_name":"ScaledTag", "plc_address":"ns=2;s=Simulator.Sine1", "data_type":"Float", "fomula":"${VALUE}*100"}
]
}'