Wire Galaxy security_classification to OPC UA AccessLevel (ReadOnly for SecuredWrite/VerifiedWrite/ViewOnly). Use deployed package chain for attribute queries to exclude undeployed attributes. Group primitive attributes under their parent variable node (merged Variable+Object). Add is_historized and is_alarm detection via HistoryExtension/AlarmExtension primitives. Implement OPC UA HistoryRead backed by Wonderware Historian Runtime database. Implement AlarmConditionState nodes driven by InAlarm with condition refresh support. Add historyread and alarms CLI commands for testing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
169 lines
4.4 KiB
Markdown
169 lines
4.4 KiB
Markdown
# OPC UA CLI Tool (.NET)
|
|
|
|
Command-line utility for testing OPC UA server functions. Built with the [OPC Foundation UA .NET Standard](https://github.com/OPCFoundation/UA-.NETStandard) client library and [CliFx](https://github.com/Tyrrrz/CliFx).
|
|
|
|
- **Runtime**: .NET 10
|
|
- **OPC UA Client**: OPCFoundation.NetStandard.Opc.Ua.Client
|
|
|
|
## Build & Run
|
|
|
|
```bash
|
|
cd tools/opcuacli-dotnet
|
|
dotnet build
|
|
dotnet run -- <command> [options]
|
|
```
|
|
|
|
## Commands
|
|
|
|
### connect
|
|
|
|
Test connection to an OPC UA server:
|
|
|
|
```
|
|
dotnet run -- connect -u opc.tcp://localhost:4840
|
|
```
|
|
|
|
| Flag | Description |
|
|
|------|-------------|
|
|
| `-u` | OPC UA server endpoint URL (required) |
|
|
|
|
### read
|
|
|
|
Read a value from a node:
|
|
|
|
```
|
|
dotnet run -- read -u opc.tcp://localhost:4840 -n "ns=2;s=MyNode"
|
|
```
|
|
|
|
| Flag | Description |
|
|
|------|-------------|
|
|
| `-u` | OPC UA server endpoint URL (required) |
|
|
| `-n` | Node ID to read (required) |
|
|
|
|
### write
|
|
|
|
Write a value to a node (auto-detects the data type from the current value):
|
|
|
|
```
|
|
dotnet run -- write -u opc.tcp://localhost:4840 -n "ns=2;s=MyNode" -v 42
|
|
```
|
|
|
|
| Flag | Description |
|
|
|------|-------------|
|
|
| `-u` | OPC UA server endpoint URL (required) |
|
|
| `-n` | Node ID to write to (required) |
|
|
| `-v` | Value to write (required) |
|
|
|
|
### subscribe
|
|
|
|
Monitor a node for value changes:
|
|
|
|
```
|
|
dotnet run -- subscribe -u opc.tcp://localhost:4840 -n "ns=2;s=MyNode" -i 500
|
|
```
|
|
|
|
| Flag | Description |
|
|
|------|-------------|
|
|
| `-u` | OPC UA server endpoint URL (required) |
|
|
| `-n` | Node ID to monitor (required) |
|
|
| `-i` | Polling interval in milliseconds (default: 1000) |
|
|
|
|
### browse
|
|
|
|
Browse the OPC UA address space:
|
|
|
|
```bash
|
|
# Browse top-level Objects folder
|
|
dotnet run -- browse -u opc.tcp://localhost:4840
|
|
|
|
# Browse a specific node
|
|
dotnet run -- browse -u opc.tcp://localhost:4840 -n "ns=2;s=MyFolder"
|
|
|
|
# Browse recursively (depth 3)
|
|
dotnet run -- browse -u opc.tcp://localhost:4840 -r -d 3
|
|
```
|
|
|
|
| Flag | Description |
|
|
|------|-------------|
|
|
| `-u` | OPC UA server endpoint URL (required) |
|
|
| `-n` | Node ID to browse (default: Objects folder) |
|
|
| `-d` | Maximum browse depth (default: 1) |
|
|
| `-r` | Browse recursively using `--depth` as max depth |
|
|
|
|
### historyread
|
|
|
|
Read historical data from a node:
|
|
|
|
```
|
|
dotnet run -- historyread -u opc.tcp://localhost:4840/LmxOpcUa -n "ns=1;s=TestMachine_001.TestHistoryValue" --start "2026-03-25" --end "2026-03-30"
|
|
```
|
|
|
|
Read with aggregate (1-hour average):
|
|
|
|
```
|
|
dotnet run -- historyread -u opc.tcp://localhost:4840/LmxOpcUa -n "ns=1;s=TestMachine_001.TestHistoryValue" --start "2026-03-25" --end "2026-03-30" --aggregate Average --interval 3600000
|
|
```
|
|
|
|
| Flag | Description |
|
|
|------|-------------|
|
|
| `-u` | OPC UA server endpoint URL (required) |
|
|
| `-n` | Node ID to read history for (required) |
|
|
| `--start` | Start time (default: 24 hours ago) |
|
|
| `--end` | End time (default: now) |
|
|
| `--max` | Maximum number of values (default: 1000) |
|
|
| `--aggregate` | Aggregate function: Average, Minimum, Maximum, Count |
|
|
| `--interval` | Processing interval in ms for aggregates (default: 3600000) |
|
|
|
|
### alarms
|
|
|
|
Subscribe to alarm events on a node:
|
|
|
|
```
|
|
dotnet run -- alarms -u opc.tcp://localhost:4840/LmxOpcUa -n "ns=1;s=TestMachine_001"
|
|
```
|
|
|
|
With condition refresh to get current alarm states:
|
|
|
|
```
|
|
dotnet run -- alarms -u opc.tcp://localhost:4840/LmxOpcUa -n "ns=1;s=TestMachine_001" --refresh
|
|
```
|
|
|
|
| Flag | Description |
|
|
|------|-------------|
|
|
| `-u` | OPC UA server endpoint URL (required) |
|
|
| `-n` | Node ID to monitor for events (default: Server node) |
|
|
| `-i` | Publishing interval in milliseconds (default: 1000) |
|
|
| `--refresh` | Request a ConditionRefresh after subscribing |
|
|
|
|
## Example: Testing the LmxOpcUa Server
|
|
|
|
```bash
|
|
cd tools/opcuacli-dotnet
|
|
|
|
# Connect to the local OPC UA server
|
|
dotnet run -- connect -u opc.tcp://localhost:4840
|
|
|
|
# Browse the address space
|
|
dotnet run -- browse -u opc.tcp://localhost:4840 -r -d 3
|
|
|
|
# Read a tag value
|
|
dotnet run -- read -u opc.tcp://localhost:4840 -n "ns=2;s=TestMachine_001.SomeAttribute"
|
|
|
|
# Subscribe to live updates
|
|
dotnet run -- subscribe -u opc.tcp://localhost:4840 -n "ns=2;s=TestMachine_001.SomeAttribute" -i 500
|
|
```
|
|
|
|
## Example: Testing with the OPC PLC Sample Server
|
|
|
|
```bash
|
|
# Start the sample server (from another terminal)
|
|
cd tools/opcsampleserver/publish
|
|
dotnet opcplc.dll --pn=50000 --autoaccept --unsecuretransport
|
|
|
|
# Browse the sample server
|
|
dotnet run -- browse -u opc.tcp://localhost:50000 -r -d 2
|
|
|
|
# Read a sample node
|
|
dotnet run -- read -u opc.tcp://localhost:50000 -n "ns=2;s=SlowUInt1"
|
|
```
|