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