Add README with architecture, usage, and configuration docs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joseph Doherty
2026-03-25 05:57:05 -04:00
parent a7576ffb38
commit e9a146d273

166
README.md Normal file
View File

@@ -0,0 +1,166 @@
# LmxOpcUa Server
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.
## Architecture
```
OPC UA Clients
|
v
+-----------------+ +------------------+ +-----------------+
| Galaxy Repo DB |---->| OPC UA Server |<--->| MXAccess Client |
| (SQL Server) | | (address space) | | (STA + COM) |
+-----------------+ +------------------+ +-----------------+
|
+-------+--------+
| Status Dashboard|
| (HTTP/JSON) |
+----------------+
```
**Galaxy Repository** queries the ZB database for the deployed object hierarchy and attribute definitions, building the OPC UA address space at startup and rebuilding 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.
## Contained Name vs Tag Name
| Browse Path (contained names) | Runtime Reference (tag name) |
|-------------------------------|------------------------------|
| `TestMachine_001/DelmiaReceiver/DownloadPath` | `DelmiaReceiver_001.DownloadPath` |
| `TestMachine_001/MESReceiver/MoveInBatchID` | `MESReceiver_001.MoveInBatchID` |
## Quick Start
### Prerequisites
- .NET Framework 4.8 SDK
- AVEVA System Platform with ArchestrA Framework installed
- Galaxy repository database (SQL Server, Windows Auth)
- MXAccess COM registered (`LMXProxy.LMXProxyServer`)
### Build & Run
```bash
dotnet restore ZB.MOM.WW.LmxOpcUa.slnx
dotnet build ZB.MOM.WW.LmxOpcUa.slnx
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Host
```
The server starts on `opc.tcp://localhost:4840/LmxOpcUa` with SecurityPolicy None.
### Install as Windows Service
```bash
cd src/ZB.MOM.WW.LmxOpcUa.Host/bin/Debug/net48
ZB.MOM.WW.LmxOpcUa.Host.exe install
ZB.MOM.WW.LmxOpcUa.Host.exe start
```
### Test with CLI Tool
```bash
# Connect
dotnet run --project tools/opcuacli-dotnet -- connect -u opc.tcp://localhost:4840/LmxOpcUa
# Browse Galaxy hierarchy
dotnet run --project tools/opcuacli-dotnet -- browse -u opc.tcp://localhost:4840/LmxOpcUa -n "ns=1;s=ZB" -r -d 5
# Read a tag
dotnet run --project tools/opcuacli-dotnet -- read -u opc.tcp://localhost:4840/LmxOpcUa -n "ns=1;s=TestMachine_001.MachineID"
# Write a tag
dotnet run --project tools/opcuacli-dotnet -- write -u opc.tcp://localhost:4840/LmxOpcUa -n "ns=1;s=TestChildObject.TestString" -v "Hello"
# Subscribe to changes
dotnet run --project tools/opcuacli-dotnet -- subscribe -u opc.tcp://localhost:4840/LmxOpcUa -n "ns=1;s=TestChildObject.TestInt" -i 500
```
### Run Tests
```bash
dotnet test ZB.MOM.WW.LmxOpcUa.slnx
```
## Configuration
All settings in `appsettings.json`, overridable via environment variables:
| Section | Key | Default | Description |
|---------|-----|---------|-------------|
| OpcUa | Port | 4840 | OPC UA server port |
| OpcUa | EndpointPath | /LmxOpcUa | Endpoint path |
| OpcUa | GalaxyName | ZB | Galaxy name (used in namespace URI) |
| OpcUa | MaxSessions | 100 | Maximum concurrent sessions |
| MxAccess | ClientName | LmxOpcUa | MXAccess registration name |
| MxAccess | AutoReconnect | true | Auto-reconnect on disconnect |
| MxAccess | ProbeTag | null | Tag for connection health probing |
| GalaxyRepository | ConnectionString | Server=localhost;Database=ZB;... | ZB database connection |
| GalaxyRepository | ChangeDetectionIntervalSeconds | 30 | Deploy change polling interval |
| Dashboard | Enabled | true | Enable HTTP status dashboard |
| Dashboard | Port | 8081 | Dashboard port |
## Project Structure
```
src/ZB.MOM.WW.LmxOpcUa.Host/
Configuration/ Config binding and validation
Domain/ Interfaces, DTOs, enums, mappers
Metrics/ Performance tracking (rolling P95)
MxAccess/ STA thread, COM interop, subscriptions
GalaxyRepository/ SQL queries, change detection
OpcUa/ Server, node manager, address space
Status/ HTTP dashboard, health checks
OpcUaService.cs Service wiring (startup/shutdown)
Program.cs TopShelf entry point
tests/ZB.MOM.WW.LmxOpcUa.Tests/
Configuration/ Config binding tests
Domain/ Type mapping, quality, error code tests
Metrics/ Performance metrics tests
MxAccess/ STA thread, connection, subscription, R/W tests
GalaxyRepository/ Change detection tests
OpcUa/ Address space build/rebuild, data conversion tests
Status/ Health check, dashboard, web server tests
Wiring/ Component integration tests
EndToEnd/ Full data flow smoke test
tools/opcuacli-dotnet/ OPC UA CLI test tool
gr/ Galaxy repository docs, SQL queries, schema
```
## Data Type Mapping
| Galaxy Type | mx_data_type | OPC UA Type | NodeId |
|-------------|-------------|-------------|--------|
| Boolean | 1 | Boolean | i=1 |
| Integer | 2 | Int32 | i=6 |
| Float | 3 | Float | i=10 |
| Double | 4 | Double | i=11 |
| String | 5 | String | i=12 |
| DateTime | 6 | DateTime | i=13 |
| ElapsedTime | 7 | Double (seconds) | i=11 |
| Reference | 8 | String | i=12 |
| Enumeration | 13 | Int32 | i=6 |
| InternationalizedString | 15 | LocalizedText | i=21 |
Array attributes use `ValueRank=1` with `ArrayDimensions` from the Galaxy attribute definition.
## Startup Sequence
1. Load and validate configuration
2. Register `AppDomain.UnhandledException` handler
3. Create performance metrics
4. Connect MXAccess (STA thread + COM registration)
5. Start MXAccess monitor loop
6. Test Galaxy database connection
7. Start OPC UA server with programmatic config
8. Query hierarchy + attributes, build address space
9. Start change detection polling (rebuilds on deploy)
10. Start status dashboard (HTML + JSON + health endpoint)
## License
Internal use only.