130 lines
6.4 KiB
Markdown
130 lines
6.4 KiB
Markdown
---
|
||
task: OPC UA client to an OPC UA server by quick load (loopback to CI Server's own OPC UA server)
|
||
version: R1.03
|
||
source: IM 36K10L45-01EN §9, §10; IM 36K10E20-01EN §2; practiced on CI-Eng-Sample 2026-10-01 (station CIENG_UA; full remove/reload; point also configured in the Engineering Module by the user and compared)
|
||
status: verified
|
||
---
|
||
|
||
# OPC UA client to an OPC UA server
|
||
|
||
Worked example: CI-Eng-Sample station `CIENG_UA`, CI Server's OPC UA client reading
|
||
`CI-Eng-Sample.TANK1.LEVEL` back through CI Server's **own** OPC UA server
|
||
(`examples/CI-Eng-Sample/12_`–`15_*.qli`, removal `76_`–`78_`). For a real server, replace the
|
||
endpoint, security settings and node IDs.
|
||
|
||
## 1. Server side: make the data visible
|
||
|
||
On the CI Server OPC UA server an item is reachable only when the item has **OPC visible** and
|
||
**Read** (Write to allow writing) and every parent section is OPC visible
|
||
(`12_opc_visible_df.qli`, loaded with `dssqld -m`):
|
||
|
||
```
|
||
@FIELDS
|
||
NAME,OPC_VISIBLE
|
||
|
||
@SECTION_DF
|
||
"CI-Eng-Sample",1
|
||
"CI-Eng-Sample.TANK1",1
|
||
|
||
@FIELDS
|
||
NAME,OPC_VISIBLE,OPC_READ,OPC_WRITE
|
||
|
||
@ITEM_DF
|
||
"CI-Eng-Sample.TANK1.LEVEL",1,1,0
|
||
```
|
||
|
||
Visible without Read: the item shows when browsing, but browsing into it fails
|
||
(`UncertainNotAllNodesAvailable`, client message `OPXC-E-BRW_NODE`; verified). By the manual,
|
||
Read is also what allows reading the value.
|
||
These flags also apply to the OPC DA and A&E servers.
|
||
|
||
## 2. Client configuration (quick load, in this order)
|
||
|
||
1. **Line** (`OPCUAC_LINE_DF`): loading it creates and starts the client process
|
||
`EQUIPMENT_MAN` (must start with `OPX`, ≤ 11 characters) — wait ~10 s before the station.
|
||
```
|
||
"CIENG_UA_LINE","CI-Eng-Sample OPC UA loopback line","OPXCIENG"
|
||
```
|
||
2. **Station** (`OPCUAC_STATION_DF`), **subscription** (`OPCUAC_SUBSCRIPTION_DF`, name
|
||
`<station>:<subscription>`), **points** (`OPCUAC_POINT_DF`, name `<station>:<point>`) —
|
||
see `14_opcua_station_df.qli`:
|
||
- Station: `LINE`, `USER_ANONYMOUS` 1 (or `USER_NAME`/`USER_PASSWORD`),
|
||
`MSG_SECURITY_01_MODE` `SignAndEncrypt`, `MSG_SECURITY_01_POLICY` `Basic256Sha256`,
|
||
`SERVER_01_ENDPOINT` `opc.tcp://localhost:34493`, `STATUS_ITEM` (Boolean item, 1 =
|
||
connected). `SERVER_01_NAME`/`_URI` may stay empty.
|
||
- Subscription: `REQUESTED_PUBLISH_INTERVAL` 1000.
|
||
- Point: `SUBSCRIPTION`, `EXTERNAL_RELATION` (`Input`, `Output`, `Input + Output`),
|
||
`OPC_NAMESPACE` (namespace **URI**, not index), `OPC_NODE_ID_TYPE` (`STRING`, `NUMERIC`,
|
||
`GUID`), `OPC_NODE_ID`.
|
||
3. **Items** (`ITEM_DF` with `STATION` and `POINT`), e.g. `CI-Eng-Sample.UA.LEVEL_COPY` →
|
||
`CIENG_UA`, `LEVEL`.
|
||
|
||
## 3. Node IDs
|
||
|
||
| Target | Namespace | Type | Node ID |
|
||
|---|---|---|---|
|
||
| Value of a CI Server item (by name — survives recreating the item) | `urn:Yokogawa:CI_SERVER_OPC_UA_SERVER` | STRING | `{"0":"Value","itnm":"<Section>.<Tag>"}` |
|
||
| Value of a CI Server item (by namespace id) | same | STRING | `{"0":"Value","nsid":"<n>"}` |
|
||
| Server state (any OPC UA server; good connection test, 0 = Running) | `http://opcfoundation.org/UA/` | NUMERIC | `2259` |
|
||
|
||
In a `.qli` file double the quotes inside the field:
|
||
`"{""0"":""Value"",""itnm"":""CI-Eng-Sample.TANK1.LEVEL""}"`.
|
||
|
||
Pitfalls found on the test system:
|
||
- Namespace `http://www.yokogawa.com/CI_Server/` (the one the manual shows) holds only the
|
||
**types**; with it the point is silently not monitored (ISS-032).
|
||
- In the Engineering Module's *Browse path*, **expand the item and pick its `Value` node**
|
||
(`Objects/<Section>/…/<Tag>/Value`, node ID `{"0":"Value","nsid":"<n>"}`); verified by the
|
||
user: *Last value* and *Data type* filled at once. Picking the item itself stores the
|
||
**object** (`{"nsid":"<n>"}`), which has no value (status 13, never monitored) (ISS-033).
|
||
For quick load prefer `{"0":"Value","itnm":"<item>"}`: it does not depend on `nsid`.
|
||
- `nsid` numbers change when the item is deleted and created again (e.g. sample reload).
|
||
|
||
A point that is not accepted shows `REVISED_SAMPLING_INTERVAL` 0 in `OPCUAC_POINT_DF` and the
|
||
log line `Can't find Point [<point>] in subscription` when changed; a monitored point gets the
|
||
revised interval (e.g. 1000).
|
||
|
||
**Browse the server from the command line** (station connected): export `OPCUAC_TAG_DF` with
|
||
a filter; start with an empty path, then `Objects`:
|
||
|
||
```
|
||
@SELECT
|
||
'OPC_STATION_NAME = "CIENG_UA" and OPC_TAG_PATH = "Objects"'
|
||
@OPCUAC_TAG_DF
|
||
```
|
||
|
||
Each record shows display name, namespace URI and node ID (inside `OPC_TAG_INFO`). Deeper
|
||
paths were not found yet (`Objects.CI-Eng-Sample` returned nothing).
|
||
|
||
## 4. Certificate exchange (first connection; the user does it)
|
||
|
||
| Step | Where it shows | What the user does |
|
||
|---|---|---|
|
||
| 1. Client rejects the server | `OPXC-E-CER_NO_TRU … BadCertificateUntrusted` in `umhlog.log`; file `<thumbprint>.der` in `%TLS_ALLUSERS_PATH%\pki\opxuac\pkiclient\rejected` | Trust it: Engineering Module *OPC UA Client → Certificates → Rejected* → *Trusted*, or move the file to `…\pkiclient\trusted\certs` |
|
||
| 2. Server rejects the client | client log `BadSecurityChecksFailed`; file `CI_SERVER_OPCUA_CLIENT_<PROCESS> [<thumbprint>].der` in `…\pki\opxuas\pkiserver\rejected` (folder created now) | Move it to `…\pki\opxuas\pkiserver\trusted\certs` |
|
||
|
||
PowerShell: file names with `[ ]` need `-LiteralPath`, otherwise `Move-Item` silently does
|
||
nothing:
|
||
|
||
```powershell
|
||
Move-Item -LiteralPath "<rejected folder>\<file>.der" -Destination "<trusted folder>\"
|
||
```
|
||
|
||
The client retries every ~35 s (`OPXC_STATION_CON_TRY_INTERVAL` 30 s); then `OPXC-I-SRV_CONN`
|
||
and the status item goes to 1. Certificates and trust stay when the line is removed and loaded
|
||
again (verified: reload connected within 5 s without a new exchange). For an external server,
|
||
its certificate arrives the same way; the client certificate
|
||
(`…\pkiclient\own\certs\<host>_<PROCESS>.der`) must be trusted on that server.
|
||
|
||
## 5. Check
|
||
|
||
- `itmval -g -n CI-Eng-Sample.UA.COMM_OK` → 1; `UA.SRV_STATE` → 0 status 9;
|
||
`UA.LEVEL_COPY` follows `TANK1.LEVEL` within ~1 s (verified 55, 62.5, 71, 33, 44.4).
|
||
- Client log: `%TLS_LOG_PATH%\<PROCESS>.log` (`Successfully connected station`, errors with
|
||
status codes); server logs `OPXUAS.log`, `OpxUas_Sdk.log` (`CreateMonitoredItems`).
|
||
- Off-scan/on-scan: `OPCUAC_STATION_DF` `ON_SCAN` 0/1 with `dssqld -m` disconnects/reconnects.
|
||
|
||
## 6. Remove
|
||
|
||
Items (`76_`), then points, subscription, station (`77_`), then the line (`78_`, stops the
|
||
client process). Reset the OPC flags only if they were not there before.
|