OPC-UA Driver
Overview
Industrial data standard protocol based on OPC Unified Architecture (IEC 62541).
| Item | Value |
|---|---|
opc_type | OPCUA |
| Implementation Class | plantpulse.driver.protocol.opcua.OPCUA_34_Driver |
| Library | Eclipse Milo (milo-sdk-client) |
| read | ✅ |
| write | ✅ (node.writeValue) |
| Security | User Authentication Anonymous, Username/Password. Channel Security None · Sign · SignAndEncrypt · auto |
Compatible with most OPC-UA servers, including Kepware, Matrikon, and Prosys.
OPC Registration Form
| Field | Meaning | Example |
|---|---|---|
opc_agent_ip | OPC-UA Server IP | 192.168.0.40 |
opc_agent_port | OPC-UA Server TCP Port | 49320 (Kepware default) |
timecycle | Polling Cycle (ms) | 1000 |
options.servername | Server Name at the end of endpoint | (Leave blank for Kepware) |
options.username | Authentication User | kopens |
options.password | Authentication Password | *** |
options.discovery | If true, browse the entire node tree from RootFolder during connection and log it (Not endpoint discovery — use [Endpoint Lookup] on screen for endpoints) | false (Recommended) |
options.security_mode | Channel security mode. None (Default) · Sign · SignAndEncrypt · auto (Strongest among Sign·SignAndEncrypt). If not None, it will not downgrade to None. Case-insensitive; unknown values become OPCUA_SECURITY_CONFIG_INVALID | SignAndEncrypt |
options.security_policy | auto (Default) · Basic256Sha256 · Aes128_Sha256_RsaOaep · Aes256_Sha256_RsaPss. auto follows the order Aes256_Sha256_RsaPss > Basic256Sha256 > Aes128_Sha256_RsaOaep. Ignored if security mode is None | auto |
options.allow_deprecated_policy | If true, allow deprecated Basic256 · Basic128Rsa15 (Included in auto candidates and can be specified). Values other than true/false become OPCUA_SECURITY_CONFIG_INVALID | false |
Generated endpoint URL format:
opc.tcp://<opc_agent_ip>:<opc_agent_port>/<servername>
If both username + password exist, use UsernameProvider; otherwise, use AnonymousProvider.
pki_dir (Client certificate and trust list directory) is not an input field. edge-web inserts $PE_DATA_DIR/pp-data/opcua-client only when the security mode is not None, and values stored in the connection row are discarded.
Endpoint Selection:
security_mode=None(OPCUA_34_Driver.selectEndpoint) — Selects only those that areMessageSecurityMode.Nonefrom the list advertised by the server. The endpoint that advertises the token type to be used (UserName / Anonymous) takes priority; otherwise, the first None endpoint is selected.- Other modes (
OpcuaEndpointSelector.selectSecure) — Selects the strongest endpoint that satisfies both the accepting mode/policy and the token type to be used. If none exist, it does not downgrade to None and fails withOPCUA_NO_MATCHING_ENDPOINT.
The host of the selected endpoint URL is replaced by opc_agent_ip (Ports and paths are values advertised by the server). Failures with known causes (Certificate · Security Setting · No Matching Endpoint) leave a single line of OPCUA connect refused: error_code=<코드> opc_id=<OPC ID> ... WARN (only once for the same cause). OPCUA_CONNECT_FAILED · OPCUA_PKI_ERROR leave OPCUA connect failed: ... ERROR and a stack trace every time.
Refer to OPC-UA Connection — Secure Connection for server certificate trust, downloading edge certificates, and error messages. First-time server certificates are rejected (no automatic trust on first connection) and are connected after the operator trusts them on the screen.
Tag plc_address Format
Standard OPC-UA NodeId notation. Example:
| Notation | Meaning |
|---|---|
ns=2;s=Simulator.Sine1 | namespace 2, string identifier Simulator.Sine1 |
ns=2;i=1234 | numeric identifier 1234 |
ns=3;g=09087e75-8e5e-499b-954f-f2a8624db28a | GUID identifier |
ns=2;b=Mb= | opaque (bytestring) identifier |
For Kepware, usually in ns=2;s=<Channel>.<Device>.<Tag> format.
data_type / format Mapping
Returns the Value of the OPC-UA variable node after casting it to a String. data_type is used for casting in subsequent stages (PLCValueFomula, Sparkplug publishing, etc.).
data_type | Operation |
|---|---|
Float / Double | Number as-is |
Int / Integer / Int32 / Short / Long | Number as-is |
Boolean / Bool | true/false string |
String / Text | UTF-8 string |
DateTime | ISO string |
format is generally not used in OPC-UA. Use fomula if post-processing formulas are required.
Common Errors + Troubleshooting
| Message / Symptom | Cause | Resolution |
|---|---|---|
connection refused | Server not running, port blocked | Verify communication via telnet <ip> <port> |
Bad_UserAccessDenied | Username/password error, anonymous not allowed | Register user on server or enable anonymous |
OPCUA_CLIENT_CERT_REJECTED (Bad_SecurityChecksFailed etc.) | Server does not trust the edge client certificate | Add edge certificate (.der) to server trust list |
OPCUA_NO_MATCHING_ENDPOINT | Server does not advertise an endpoint with that mode/policy/token | Verify available combinations via [Endpoint Lookup] on screen and match |
| Connection failure due to incorrect port | Driver replaces only the host of the advertised endpoint with opc_agent_ip; ports/paths are used as-is | If port is exposed via NAT/port forwarding, match it to the port advertised by the server. No hosts mapping required |
| Value is always 0 / null | NodeId typo, namespace number mismatch | Verify NodeId read using clients like UA Expert |
curl Registration Example
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"
}
]
}'
Read value:
curl -s http://<edge-host>/api/v1/tag/OPC_UA_Kepware_TAG_00001/value | jq
Reference: Kepware Quick Setup Guide
- Kepware Server → Project → Add Channel (e.g.,
Simulator). - Add Device (e.g.,
Simulator) → Model =16 Bit Device. - Add Tags →
Sine1, typeFloat, scan rate100ms, etc. - Enable port
49320inProject Properties → OPC UA → Server Endpoint. - Enable Anonymous or user account. For secure connections, enable Sign and Encrypt with
Basic256Sha256or higher in the endpoint security policy and add the edge certificate to the trust list.
→ Edge Registration Form:
| Field | Value |
|---|---|
| opc_agent_ip | Kepware Server IP |
| opc_agent_port | 49320 |
| options.servername | (Leave blank) |
| options.username/password | Account created above |
| plc_address | ns=2;s=Simulator.Simulator.Sine1 |
Example Collection (by Data Type)
OPC-UA returns the value (Variant) of the variable node after casting it to a String. data_type is used for casting during post-processing (PLCValueFomula, Sparkplug DataTypeMapper). format is generally not used.
Boolean
data_type | plc_address Example | Note |
|---|---|---|
Boolean | ns=2;s=Simulator.Boolean1 | Kepware Simulator Boolean tag |
Boolean | ns=2;s=PLC.Status.Running | Kepware Channel.Device.Tag |
Boolean | ns=2;i=1003 | numeric NodeId |
16/32-bit Integer
data_type | plc_address Example | Note |
|---|---|---|
Integer | ns=2;s=Simulator.Random1 | Random integer simulation |
Integer | ns=2;s=Simulator.Counter1 | Counter |
Integer | ns=2;s=PLC.D100 | Kepware MELSEC channel exposure |
64-bit Integer
data_type | plc_address Example | Note |
|---|---|---|
Long | ns=2;s=Simulator.LongCounter | UInt64 / Int64 node |
Long | ns=2;s=PLC.Cycle.Total | Cumulative counter |
Floating Point
data_type | plc_address Example | Note |
|---|---|---|
Float | ns=2;s=Simulator.Sine1 | sine wave simulation |
Float | ns=2;s=Simulator.Ramp1 | ramp wave |
Double | ns=2;s=PLC.Pressure | Precision measurement value |
String
data_type | plc_address Example | Note |
|---|---|---|
String | ns=2;s=Simulator.User1.Name | String node |
String | ns=2;s=PLC.Recipe.Active | Recipe name |
By NodeId Format
| identifier type | plc_address Example |
|---|---|
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= |
Formula Utilization
| Usage | data_type | fomula | Note |
|---|---|---|---|
| Unit Conversion | Float | ${VALUE}*0.001 | g → kg, etc. |
| Zero Point Calibration | Float | ${VALUE}-${TAG_ZERO} | Other OPCUA tags can be referenced |
| Type Conversion | Float | ${VALUE}*1.0 | Force Integer → Float |
| Polynomial | Float | ${VALUE}*${VALUE}*0.0001 | Non-linear |
Comprehensive curl Example (All Types)
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"}
]
}'