--- 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 `:`), **points** (`OPCUAC_POINT_DF`, name `:`) — 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":"
."}` | | Value of a CI Server item (by namespace id) | same | STRING | `{"0":"Value","nsid":""}` | | 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/
/…//Value`, node ID `{"0":"Value","nsid":""}`); verified by the user: *Last value* and *Data type* filled at once. Picking the item itself stores the **object** (`{"nsid":""}`), which has no value (status 13, never monitored) (ISS-033). For quick load prefer `{"0":"Value","itnm":""}`: 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 [] 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 `.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_ [].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 "\.der" -Destination "\" ``` 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\_.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%\.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.