# 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`.