Restructure README to separate server (.NET 4.8) and client (.NET 10) sections
Prerequisites, build commands, and test instructions are now split by target framework since the server requires AVEVA/COM/Windows while the clients are cross-platform. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
137
README.md
137
README.md
@@ -1,11 +1,12 @@
|
|||||||
# LmxOpcUa Server
|
# LmxOpcUa
|
||||||
|
|
||||||
OPC UA server on .NET Framework 4.8 (x86) that exposes AVEVA System Platform (Wonderware) Galaxy tags via the MXAccess toolkit. Mirrors the Galaxy object hierarchy as an OPC UA address space, translating between contained-name browse paths and tag-name runtime references.
|
OPC UA server and cross-platform client tools for AVEVA System Platform (Wonderware) Galaxy. The server exposes Galaxy tags via MXAccess as an OPC UA address space. The client stack provides a shared library, CLI tool, and Avalonia desktop application for browsing, reading/writing, subscriptions, alarms, and historical data.
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
```
|
```
|
||||||
OPC UA Clients
|
OPC UA Clients
|
||||||
|
(CLI, Desktop UI, 3rd-party)
|
||||||
|
|
|
|
||||||
v
|
v
|
||||||
+-----------------+ +------------------+ +-----------------+
|
+-----------------+ +------------------+ +-----------------+
|
||||||
@@ -19,14 +20,6 @@ OPC UA server on .NET Framework 4.8 (x86) that exposes AVEVA System Platform (Wo
|
|||||||
+----------------+ +-------------------+
|
+----------------+ +-------------------+
|
||||||
```
|
```
|
||||||
|
|
||||||
**Galaxy Repository** queries the ZB database for the deployed object hierarchy and attribute definitions, building the OPC UA address space at startup and incrementally syncing on deploy changes.
|
|
||||||
|
|
||||||
**MXAccess Client** connects to the Galaxy runtime via COM interop on a dedicated STA thread with a Win32 message pump. Handles subscriptions, read/write, reconnection, and probe-based health monitoring.
|
|
||||||
|
|
||||||
**OPC UA Server** exposes the hierarchy as browse nodes (folders for areas, objects for containers) with variable nodes for each attribute. Clients browse using contained names but reads/writes translate to `tag_name.AttributeName` for MXAccess.
|
|
||||||
|
|
||||||
**Historian Runtime** provides historical data access via SQL queries against the Wonderware Historian `Runtime` database, serving OPC UA `HistoryRead` requests for raw and aggregate data.
|
|
||||||
|
|
||||||
## Contained Name vs Tag Name
|
## Contained Name vs Tag Name
|
||||||
|
|
||||||
| Browse Path (contained names) | Runtime Reference (tag name) |
|
| Browse Path (contained names) | Runtime Reference (tag name) |
|
||||||
@@ -34,27 +27,32 @@ OPC UA server on .NET Framework 4.8 (x86) that exposes AVEVA System Platform (Wo
|
|||||||
| `TestMachine_001/DelmiaReceiver/DownloadPath` | `DelmiaReceiver_001.DownloadPath` |
|
| `TestMachine_001/DelmiaReceiver/DownloadPath` | `DelmiaReceiver_001.DownloadPath` |
|
||||||
| `TestMachine_001/MESReceiver/MoveInBatchID` | `MESReceiver_001.MoveInBatchID` |
|
| `TestMachine_001/MESReceiver/MoveInBatchID` | `MESReceiver_001.MoveInBatchID` |
|
||||||
|
|
||||||
## Quick Start
|
---
|
||||||
|
|
||||||
### Prerequisites
|
## Server
|
||||||
|
|
||||||
|
The OPC UA server runs on .NET Framework 4.8 (x86) and bridges the Galaxy runtime to OPC UA clients.
|
||||||
|
|
||||||
|
### Server Prerequisites
|
||||||
|
|
||||||
- .NET Framework 4.8 SDK
|
- .NET Framework 4.8 SDK
|
||||||
- AVEVA System Platform with ArchestrA Framework installed
|
- AVEVA System Platform with ArchestrA Framework installed
|
||||||
- Galaxy repository database (SQL Server, Windows Auth)
|
- Galaxy repository database (SQL Server, Windows Auth)
|
||||||
- MXAccess COM registered (`LMXProxy.LMXProxyServer`)
|
- MXAccess COM registered (`LMXProxy.LMXProxyServer`)
|
||||||
- Wonderware Historian (optional, for historical data access)
|
- Wonderware Historian (optional, for historical data access)
|
||||||
|
- Windows (required for COM interop and MXAccess)
|
||||||
|
|
||||||
### Build and run
|
### Build and Run Server
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
dotnet restore ZB.MOM.WW.LmxOpcUa.slnx
|
dotnet restore ZB.MOM.WW.LmxOpcUa.slnx
|
||||||
dotnet build ZB.MOM.WW.LmxOpcUa.slnx
|
dotnet build src/ZB.MOM.WW.LmxOpcUa.Host
|
||||||
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Host
|
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Host
|
||||||
```
|
```
|
||||||
|
|
||||||
The server starts on `opc.tcp://localhost:4840/LmxOpcUa` with the `None` security profile by default. Configure `Security.Profiles` in `appsettings.json` to enable `Basic256Sha256-Sign` or `Basic256Sha256-SignAndEncrypt` for transport security. See [Security Guide](docs/security.md).
|
The server starts on `opc.tcp://localhost:4840/LmxOpcUa` with the `None` security profile by default. Configure `Security.Profiles` in `appsettings.json` to enable `Basic256Sha256-Sign` or `Basic256Sha256-SignAndEncrypt` for transport security. See [Security Guide](docs/security.md).
|
||||||
|
|
||||||
### Install as Windows service
|
### Install as Windows Service
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd src/ZB.MOM.WW.LmxOpcUa.Host/bin/Debug/net48
|
cd src/ZB.MOM.WW.LmxOpcUa.Host/bin/Debug/net48
|
||||||
@@ -62,69 +60,109 @@ ZB.MOM.WW.LmxOpcUa.Host.exe install
|
|||||||
ZB.MOM.WW.LmxOpcUa.Host.exe start
|
ZB.MOM.WW.LmxOpcUa.Host.exe start
|
||||||
```
|
```
|
||||||
|
|
||||||
### Test with CLI tool
|
### Run Server Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet test tests/ZB.MOM.WW.LmxOpcUa.Tests
|
||||||
|
dotnet test tests/ZB.MOM.WW.LmxOpcUa.IntegrationTests
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Client Stack
|
||||||
|
|
||||||
|
The client stack is cross-platform (.NET 10) and consists of three projects sharing a common `IOpcUaClientService` abstraction. No AVEVA software or COM is required — the clients connect to any OPC UA server.
|
||||||
|
|
||||||
|
### Client Prerequisites
|
||||||
|
|
||||||
|
- .NET 10 SDK
|
||||||
|
- No platform-specific dependencies (runs on Windows, macOS, Linux)
|
||||||
|
|
||||||
|
### Build All Clients
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet build src/ZB.MOM.WW.LmxOpcUa.Client.Shared
|
||||||
|
dotnet build src/ZB.MOM.WW.LmxOpcUa.Client.CLI
|
||||||
|
dotnet build src/ZB.MOM.WW.LmxOpcUa.Client.UI
|
||||||
|
```
|
||||||
|
|
||||||
|
### Run Client Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet test tests/ZB.MOM.WW.LmxOpcUa.Client.Shared.Tests
|
||||||
|
dotnet test tests/ZB.MOM.WW.LmxOpcUa.Client.CLI.Tests
|
||||||
|
dotnet test tests/ZB.MOM.WW.LmxOpcUa.Client.UI.Tests
|
||||||
|
```
|
||||||
|
|
||||||
|
### Client CLI
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Connect
|
# Connect
|
||||||
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Client.CLI -- connect -u opc.tcp://localhost:4840/LmxOpcUa
|
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Client.CLI -- connect -u opc.tcp://localhost:4840/LmxOpcUa
|
||||||
|
|
||||||
# Browse Galaxy hierarchy
|
# Browse Galaxy hierarchy
|
||||||
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Client.CLI -- browse -u opc.tcp://localhost:4840/LmxOpcUa -n "ns=1;s=ZB" -r -d 5
|
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Client.CLI -- browse -u opc.tcp://localhost:4840/LmxOpcUa -n "ns=3;s=ZB" -r -d 5
|
||||||
|
|
||||||
# Read a tag
|
# Read a tag
|
||||||
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Client.CLI -- read -u opc.tcp://localhost:4840/LmxOpcUa -n "ns=1;s=TestMachine_001.MachineID"
|
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Client.CLI -- read -u opc.tcp://localhost:4840/LmxOpcUa -n "ns=3;s=TestMachine_001.MachineID"
|
||||||
|
|
||||||
# Write a tag
|
# Write a tag
|
||||||
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Client.CLI -- write -u opc.tcp://localhost:4840/LmxOpcUa -n "ns=1;s=TestChildObject.TestString" -v "Hello"
|
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Client.CLI -- write -u opc.tcp://localhost:4840/LmxOpcUa -n "ns=3;s=TestChildObject.TestString" -v "Hello"
|
||||||
|
|
||||||
# Subscribe to changes
|
# Subscribe to changes
|
||||||
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Client.CLI -- subscribe -u opc.tcp://localhost:4840/LmxOpcUa -n "ns=1;s=TestChildObject.TestInt" -i 500
|
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Client.CLI -- subscribe -u opc.tcp://localhost:4840/LmxOpcUa -n "ns=3;s=TestChildObject.TestInt" -i 500
|
||||||
|
|
||||||
# Read historical data
|
# Read historical data
|
||||||
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Client.CLI -- historyread -u opc.tcp://localhost:4840/LmxOpcUa -n "ns=1;s=TestMachine_001.TestHistoryValue" --start "2026-03-25" --end "2026-03-30"
|
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Client.CLI -- historyread -u opc.tcp://localhost:4840/LmxOpcUa -n "ns=3;s=TestMachine_001.TestHistoryValue" --start "2026-03-25" --end "2026-03-30"
|
||||||
|
|
||||||
# Subscribe to alarm events
|
# Subscribe to alarm events
|
||||||
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Client.CLI -- alarms -u opc.tcp://localhost:4840/LmxOpcUa -n "ns=1;s=TestMachine_001" --refresh
|
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Client.CLI -- alarms -u opc.tcp://localhost:4840/LmxOpcUa -n "ns=3;s=TestMachine_001" --refresh
|
||||||
|
|
||||||
|
# Query redundancy state
|
||||||
|
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Client.CLI -- redundancy -u opc.tcp://localhost:4840/LmxOpcUa
|
||||||
```
|
```
|
||||||
|
|
||||||
### Run tests
|
### Client UI
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
dotnet test ZB.MOM.WW.LmxOpcUa.slnx
|
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Client.UI
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The desktop application provides browse tree, subscriptions, alarm monitoring, history reads, and write dialogs. See [Client UI Documentation](docs/Client.UI.md) for details.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
src/ZB.MOM.WW.LmxOpcUa.Host/
|
src/
|
||||||
|
ZB.MOM.WW.LmxOpcUa.Host/ OPC UA server (.NET Framework 4.8, x86)
|
||||||
Configuration/ Config binding and validation
|
Configuration/ Config binding and validation
|
||||||
Domain/ Interfaces, DTOs, enums, mappers
|
Domain/ Interfaces, DTOs, enums, mappers
|
||||||
Historian/ Wonderware Historian data source
|
Historian/ Wonderware Historian data source
|
||||||
Metrics/ Performance tracking (rolling P95)
|
Metrics/ Performance tracking (rolling P95)
|
||||||
MxAccess/ STA thread, COM interop, subscriptions
|
MxAccess/ STA thread, COM interop, subscriptions
|
||||||
GalaxyRepository/ SQL queries, change detection
|
GalaxyRepository/ SQL queries, change detection
|
||||||
OpcUa/ Server, node manager, address space, alarm conditions, diff
|
OpcUa/ Server, node manager, address space, alarms, diff
|
||||||
Status/ HTTP dashboard, health checks
|
Status/ HTTP dashboard, health checks
|
||||||
OpcUaService.cs Service wiring (startup/shutdown)
|
|
||||||
Program.cs TopShelf entry point
|
|
||||||
|
|
||||||
tests/ZB.MOM.WW.LmxOpcUa.Tests/
|
ZB.MOM.WW.LmxOpcUa.Client.Shared/ Shared OPC UA client library (.NET 10)
|
||||||
Domain/ Type mapping, security classification, quality tests
|
ZB.MOM.WW.LmxOpcUa.Client.CLI/ Command-line client (.NET 10)
|
||||||
Historian/ Historian quality mapping tests
|
ZB.MOM.WW.LmxOpcUa.Client.UI/ Avalonia desktop client (.NET 10)
|
||||||
Integration/ Access levels, historizing, alarm events, incremental sync
|
|
||||||
Metrics/ Performance metrics tests
|
tests/
|
||||||
MxAccess/ STA thread, connection, subscription, R/W tests
|
ZB.MOM.WW.LmxOpcUa.Tests/ Server unit + integration tests
|
||||||
GalaxyRepository/ Change detection tests
|
ZB.MOM.WW.LmxOpcUa.IntegrationTests/ Server integration tests (live DB)
|
||||||
OpcUa/ Address space build/rebuild, diff, data conversion tests
|
ZB.MOM.WW.LmxOpcUa.Client.Shared.Tests/ Shared library tests
|
||||||
Wiring/ Component integration tests
|
ZB.MOM.WW.LmxOpcUa.Client.CLI.Tests/ CLI command tests
|
||||||
|
ZB.MOM.WW.LmxOpcUa.Client.UI.Tests/ UI ViewModel + headless tests
|
||||||
|
|
||||||
src/ZB.MOM.WW.LmxOpcUa.Client.Shared/ Shared OPC UA client library
|
|
||||||
src/ZB.MOM.WW.LmxOpcUa.Client.CLI/ Command-line client (lmxopcua-cli)
|
|
||||||
src/ZB.MOM.WW.LmxOpcUa.Client.UI/ Avalonia desktop client
|
|
||||||
gr/ Galaxy repository docs, SQL queries, schema
|
gr/ Galaxy repository docs, SQL queries, schema
|
||||||
```
|
```
|
||||||
|
|
||||||
## Component Documentation
|
## Documentation
|
||||||
|
|
||||||
|
### Server
|
||||||
|
|
||||||
| Component | Description |
|
| Component | Description |
|
||||||
|---|---|
|
|---|---|
|
||||||
@@ -132,7 +170,7 @@ gr/ Galaxy repository docs, SQL queries, schema
|
|||||||
| [Address Space](docs/AddressSpace.md) | Hierarchy nodes, variable nodes, primitive grouping, NodeId scheme |
|
| [Address Space](docs/AddressSpace.md) | Hierarchy nodes, variable nodes, primitive grouping, NodeId scheme |
|
||||||
| [Galaxy Repository](docs/GalaxyRepository.md) | SQL queries, deployed package chain, change detection |
|
| [Galaxy Repository](docs/GalaxyRepository.md) | SQL queries, deployed package chain, change detection |
|
||||||
| [MXAccess Bridge](docs/MxAccessBridge.md) | STA thread, COM interop, subscriptions, reconnection |
|
| [MXAccess Bridge](docs/MxAccessBridge.md) | STA thread, COM interop, subscriptions, reconnection |
|
||||||
| [Data Type Mapping](docs/DataTypeMapping.md) | Galaxy → OPC UA types, arrays, security classification |
|
| [Data Type Mapping](docs/DataTypeMapping.md) | Galaxy to OPC UA types, arrays, security classification |
|
||||||
| [Read/Write Operations](docs/ReadWriteOperations.md) | Value reads, writes, access level enforcement, array element writes |
|
| [Read/Write Operations](docs/ReadWriteOperations.md) | Value reads, writes, access level enforcement, array element writes |
|
||||||
| [Subscriptions](docs/Subscriptions.md) | Ref-counted MXAccess subscriptions, data change dispatch |
|
| [Subscriptions](docs/Subscriptions.md) | Ref-counted MXAccess subscriptions, data change dispatch |
|
||||||
| [Alarm Tracking](docs/AlarmTracking.md) | AlarmConditionState nodes, InAlarm monitoring, event reporting |
|
| [Alarm Tracking](docs/AlarmTracking.md) | AlarmConditionState nodes, InAlarm monitoring, event reporting |
|
||||||
@@ -141,19 +179,20 @@ gr/ Galaxy repository docs, SQL queries, schema
|
|||||||
| [Configuration](docs/Configuration.md) | appsettings.json binding, feature flags, validation |
|
| [Configuration](docs/Configuration.md) | appsettings.json binding, feature flags, validation |
|
||||||
| [Status Dashboard](docs/StatusDashboard.md) | HTTP server, health checks, metrics reporting |
|
| [Status Dashboard](docs/StatusDashboard.md) | HTTP server, health checks, metrics reporting |
|
||||||
| [Service Hosting](docs/ServiceHosting.md) | TopShelf, startup/shutdown sequence, error handling |
|
| [Service Hosting](docs/ServiceHosting.md) | TopShelf, startup/shutdown sequence, error handling |
|
||||||
| [Client CLI](docs/Client.CLI.md) | Connect, browse, read, write, subscribe, historyread, alarms, redundancy commands |
|
|
||||||
| [Client UI](docs/Client.UI.md) | Avalonia desktop client: browse, subscribe, alarms, history, write values |
|
|
||||||
| [Security](docs/security.md) | Transport security profiles, certificate trust, production hardening |
|
| [Security](docs/security.md) | Transport security profiles, certificate trust, production hardening |
|
||||||
| [Redundancy](docs/Redundancy.md) | Non-transparent warm/hot redundancy, ServiceLevel, paired deployment |
|
| [Redundancy](docs/Redundancy.md) | Non-transparent warm/hot redundancy, ServiceLevel, paired deployment |
|
||||||
|
|
||||||
## Related Documentation
|
### Client
|
||||||
|
|
||||||
|
| Component | Description |
|
||||||
|
|---|---|
|
||||||
|
| [Client CLI](docs/Client.CLI.md) | Connect, browse, read, write, subscribe, historyread, alarms, redundancy commands |
|
||||||
|
| [Client UI](docs/Client.UI.md) | Avalonia desktop client: browse, subscribe, alarms, history, write values |
|
||||||
|
|
||||||
|
### Reference
|
||||||
|
|
||||||
- [Galaxy Repository Queries](gr/CLAUDE.md) — SQL queries for hierarchy, attributes, and change detection
|
- [Galaxy Repository Queries](gr/CLAUDE.md) — SQL queries for hierarchy, attributes, and change detection
|
||||||
- [Data Type Mapping](gr/data_type_mapping.md) — Galaxy to OPC UA type mapping with security classification
|
- [Data Type Mapping](gr/data_type_mapping.md) — Galaxy to OPC UA type mapping with security classification
|
||||||
- [Alarm Plan](hda_plan.md) — Alarm detection and OPC UA alarm condition design
|
|
||||||
- [Historian Plan](historian_plan.md) — Historical data access via Wonderware Historian
|
|
||||||
- [Incremental Sync Plan](partial_update.md) — Subtree-level address space sync design
|
|
||||||
- [Galaxy Security](gr_security.md) — Users, roles, and permissions in the Galaxy repository
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user