ci-server-engineer/.claude/skills/data-access/tasks/opcua-client.md
cliu 679c7755fe ISS-033: OPC UA browse works when the Value node is picked
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 18:41:55 +10:00

130 lines
6.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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