# OPC UA Connects to **OPC UA servers** — the standard interface of modern PLCs, CNCs, and SCADA systems. Values can be polled or subscribed to (server-side monitored items), the address space can be browsed, and nodes can be written. | | | |---|---| | Connection string | `opc.tcp://HOST:PORT[/path]` | | Reads | ✔ (poll) | | Writes | ✔ | | Subscriptions | ✔ (`options.useSubscription`) | | Browsing | ✔ (node tree) | ## Device options | Key | Type | Meaning | |---|---|---| | `security` | string[] | Allowed security policies: `Aes128_Sha256_RsaOaep`, `Aes256_Sha256_RsaPss`, `Basic128Rsa15`, `Basic256`, `Basic256Sha256`, `None`. If omitted, all of these are enabled. `None` is always added. | | `useSubscription` | boolean | `true` → use monitored-item subscriptions instead of polling. | | `opc_user` | string | If present (with `opc_password`), authenticate with username/password. Otherwise the connection is anonymous. | | `opc_password` | string | Password for the username authentication. | The client identifies itself with a self-signed certificate; the server certificate is trusted on first connect (stored under the `security/` directory of the instance). ## Address format ``` NAMESPACEINDEX::IDENTIFIER ``` - `IDENTIFIER` may be numeric or a string (string identifiers may themselves contain `::`). - A trailing `[n]` selects a single element of an array node. Without an index, array values are expanded into one dimension per element. Examples: | Address | Node | |---|---| | `2::MyTag` | `ns=2;s=MyTag` | | `0::2258` | `ns=0;i=2258` (server time) | | `2::MyArray::[3]` | Element 3 of the array node `ns=2;s=MyArray` | ## Example configuration ```json { "devices": [ { "objectId": "opc1", "name": "Machine OPC UA", "connectionString": "opc.tcp://10.0.0.30:4840", "interval": 5000, "enabled": true, "options": { "security": ["Basic256Sha256", "None"], "useSubscription": false, "opc_user": "reader", "opc_password": "secret" }, "extraOptions": { "host": "broker:1883", "clientId": "openconnect" } } ], "items": [ { "objectId": "speed", "DeviceID": { "objectId": "opc1" }, "address": "2::Machine/Spindle/Speed", "label": "Spindle speed", "type": "Number", "unit": "rpm", "source": { "tag": "hall2/machine1" }, "enabled": true, "onChange": true, "extraOptions": {} } ] } ``` ## Writes The write topic is a node address in the same `NAMESPACEINDEX::IDENTIFIER` format; the payload is the value. The node is read first to determine its type, and the payload is coerced accordingly — booleans also accept `0`/`1`, integral types accept decimal notation like `5.0`, unsigned types are handled. A trailing `[n]` writes a single element of an array node (read-modify-write of the full array). ```bash # HTTP — write 42 to ns=2;s=MyTag curl -X POST "http://openconnect:8080/write/opc1/2::MyTag" \ -H "Authorization: Bearer $TOKEN" -d '42' # HTTP — write only element 3 of an array node curl -X POST "http://openconnect:8080/write/opc1/2::MyArray::[3]" \ -H "Authorization: Bearer $TOKEN" -d '1.5' # MQTT (capability mqttwrite) mosquitto_pub -t 'write/opc1/2::MyTag' -m '42' ``` See the [write API](../write-api.md) for authentication and the MQTT setup. ## Node browsing `GET /browse?connectorId=<device objectId>&identifier=root` (capability `api`) walks the server's address space level by level; variable nodes carry an `address` that is directly usable as item address. The same browser is available in the [management UI](../management-ui.md). ## Testing without hardware The public Eclipse Milo demo server can be polled directly: `opc.tcp://milo.digitalpetri.com:62541/milo`.