7.4 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Goal
Build an OPC UA server on .NET Framework 4.8 (32-bit) that exposes AVEVA System Platform (Wonderware) Galaxy tags via the MXAccess toolkit. The server mirrors the Galaxy object hierarchy as an OPC UA address space, translating between contained-name browse paths and tag-name runtime references.
Architecture Overview
Data Flow
- Galaxy Repository DB (ZB) — SQL Server database holding the deployed object hierarchy and attribute definitions. Queried at startup and on change detection to build/rebuild the OPC UA address space.
- MXAccess COM API — Runtime data access layer. Subscribes to Galaxy tag attributes for live read/write. Requires a dedicated STA thread with a Win32 message pump for COM callbacks.
- OPC UA Server — Exposes the hierarchy as browse nodes and attributes as variable nodes. Clients browse via contained names but reads/writes are translated to
tag_name.AttributeNameformat for MXAccess.
Key Concept: Contained Name vs Tag Name
Galaxy objects have two names:
- contained_name — human-readable name scoped to parent (used for OPC UA browse tree)
- tag_name — globally unique system name (used for MXAccess read/write)
Example: browsing TestMachine_001/DelmiaReceiver/DownloadPath translates to MXAccess reference DelmiaReceiver_001.DownloadPath.
See gr/layout.md for the full mapping and target OPC UA structure.
Data Type Mapping
Galaxy mx_data_type values map to OPC UA types (Boolean, Int32, Float, Double, String, DateTime, etc.). Array attributes use ValueRank=1 with ArrayDimensions from the Galaxy attribute definition. Full mapping in gr/data_type_mapping.md.
Change Detection
Poll galaxy.time_of_last_deploy in the ZB database to detect redeployments, then rebuild the address space. See gr/build_layout_plan.md for the step-by-step plan.
Reference Implementation
An existing MXAccess client implementation is at:
C:\Users\dohertj2\Desktop\scadalink-design\lmxproxy\src\ZB.MOM.WW.LmxProxy.Host
Key patterns from that codebase:
- StaComThread — Dedicated STA thread with Win32 message pump (
GetMessage/DispatchMessageloop). All MXAccess COM objects must be created and called on this thread. UsesPostThreadMessage(WM_APP)to marshal work items. - LMXProxyServer COM object —
Register(clientName)returns a connection handle.AddItem(handle, address)+AdviseSupervisory(handle, itemHandle)for subscriptions.OnDataChange/OnWriteCompleteevents for callbacks. - Reconnect — Stored subscriptions are replayed after reconnect. A probe tag subscription monitors connection health.
- COM cleanup —
Marshal.ReleaseComObject()on disconnect. Event handlers must be unwired before unregister.
MXAccess Documentation
mxaccess_documentation.md in the project root contains the full ArchestrA MXAccess Toolkit User's Guide. Key API: ArchestrA.MxAccess namespace, LMXProxyServer class. The toolkit DLLs are in Program Files (x86)\ArchestrA\Framework\bin.
Galaxy Repository Database
Connection: sqlcmd -S localhost -d ZB -E (Windows Auth). See gr/connectioninfo.md.
The gr/ folder contains:
queries/— SQL for hierarchy extraction, attribute lookup, and change detectionddl/tables/andddl/views/— Schema definitionsschema.md— Full table/view referencebuild_layout_plan.md— Step-by-step plan for building the OPC UA address space from DB queriesgr/CLAUDE.md— Detailed guidance for working within thegr/subfolder
Key tables: gobject (hierarchy/deployment), template_definition (object categories), dynamic_attribute (user-defined attributes), primitive_instance (primitive-to-attribute links), galaxy (change detection).
Build Commands
dotnet restore ZB.MOM.WW.LmxOpcUa.slnx
dotnet build ZB.MOM.WW.LmxOpcUa.slnx
dotnet test ZB.MOM.WW.LmxOpcUa.slnx # all tests
dotnet test tests/ZB.MOM.WW.LmxOpcUa.Tests # unit tests only
dotnet test tests/ZB.MOM.WW.LmxOpcUa.IntegrationTests # integration tests only
dotnet test --filter "FullyQualifiedName~MyTestClass.MyMethod" # single test
Build & Runtime Constraints
- Language: C#, .NET Framework 4.8, x86 (32-bit) platform target — required for MXAccess COM interop
- MXAccess requires a deployed ArchestrA Platform on the machine running the server
- COM apartment: MXAccess objects must live on an STA thread with a message pump
Transport Security
The server supports configurable OPC UA transport security via the Security section in appsettings.json. Phase 1 profiles: None (default), Basic256Sha256-Sign, Basic256Sha256-SignAndEncrypt. Security profiles are resolved by SecurityProfileResolver at startup. The server certificate is always created even for None-only deployments because UserName token encryption depends on it. See docs/security.md for the full guide.
Redundancy
The server supports non-transparent warm/hot redundancy via the Redundancy section in appsettings.json. Two instances share the same Galaxy DB and MXAccess runtime but have unique ApplicationUri values. Each exposes RedundancySupport, ServerUriArray, and a dynamic ServiceLevel based on role and runtime health. The primary advertises a higher ServiceLevel than the secondary. See docs/Redundancy.md for the full guide.
LDAP Authentication
The server uses LDAP-based user authentication via the Authentication.Ldap section in appsettings.json. When enabled, credentials are validated by LDAP bind against a GLAuth server (installed at C:\publish\glauth\), and LDAP group membership maps to OPC UA permissions: ReadOnly (browse/read), WriteOperate (write FreeAccess/Operate attributes), WriteTune (write Tune attributes), WriteConfigure (write Configure attributes), AlarmAck (alarm acknowledgment). LdapAuthenticationProvider implements both IUserAuthenticationProvider and IRoleProvider. See docs/Security.md for the full guide and C:\publish\glauth\auth.md for LDAP user/group reference.
Library Preferences
- Logging: Serilog with rolling daily file sink
- Unit tests: xUnit + Shouldly for assertions
- Service hosting: TopShelf (Windows service install/uninstall/run as console)
- OPC UA: OPC Foundation UA .NET Standard stack (https://github.com/opcfoundation/ua-.netstandard) — NuGet:
OPCFoundation.NetStandard.Opc.Ua.Server
OPC UA .NET Standard Documentation
Use the DeepWiki MCP (mcp__deepwiki) to query documentation for the OPC UA .NET Standard stack: https://deepwiki.com/OPCFoundation/UA-.NETStandard. Tools: read_wiki_structure, read_wiki_contents, and ask_question with repo OPCFoundation/UA-.NETStandard.
Testing
Use the Client CLI at src/ZB.MOM.WW.LmxOpcUa.Client.CLI/ for manual testing against the running OPC UA server. Supports connect, read, write, browse, subscribe, historyread, alarms, and redundancy commands. See docs/Client.CLI.md for full documentation.
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Client.CLI -- connect -u opc.tcp://localhost:4840
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Client.CLI -- browse -u opc.tcp://localhost:4840 -r -d 3
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Client.CLI -- read -u opc.tcp://localhost:4840 -n "ns=2;s=SomeNode"
dotnet run --project src/ZB.MOM.WW.LmxOpcUa.Client.CLI -- subscribe -u opc.tcp://localhost:4840 -n "ns=2;s=SomeNode" -i 500