Commit Graph

9 Commits

Author SHA1 Message Date
Joseph Doherty
415e62c585 Add security classification, alarm detection, historical data access, and primitive grouping
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>
2026-03-26 11:32:33 -04:00
Joseph Doherty
bb0a89b2a1 Publish default values for null static arrays 2026-03-25 14:12:37 -04:00
Joseph Doherty
ed42b33512 Use bracketless OPC UA node IDs for arrays 2026-03-25 12:57:05 -04:00
Joseph Doherty
4833765606 Expand XML docs across bridge and test code 2026-03-25 11:45:12 -04:00
Joseph Doherty
3f813b3869 Add OPC UA array element write integration test 2026-03-25 11:05:04 -04:00
Joseph Doherty
4351854754 Fix service deployment: set working directory for correct log paths and use MasterNodeManager for Objects→ZB reference
Windows services default to System32 as working directory, causing logs to land in the wrong location. Set Environment.CurrentDirectory to AppDomain.CurrentDomain.BaseDirectory before Serilog init. Also fix ZB root folder not appearing under Objects folder — BuildAddressSpace runs after CreateAddressSpace completes so the externalReferences dict is already consumed; use Server.NodeManager.AddReferences instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 10:57:18 -04:00
Joseph Doherty
09ed15bdda Fix second-pass review findings: subscription leak on rebuild, metrics accuracy, and MxAccess startup recovery
- Preserve and replay subscription ref counts across address space rebuilds to prevent MXAccess subscription leaks
- Mark read timeouts and write failures as unsuccessful in PerformanceMetrics for accurate health reporting
- Add deferred MxAccess reconnect path when initial connection fails at startup
- Update code review document with verified completions and new findings
- Add covering tests for all fixes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 09:41:12 -04:00
Joseph Doherty
71254e005e Fix 5 code review findings (P1-P3)
P1: Wire OPC UA monitored items to MXAccess subscriptions
  - Override OnCreateMonitoredItemsComplete/OnDeleteMonitoredItemsComplete
    in LmxNodeManager to trigger ref-counted SubscribeTag/UnsubscribeTag
  - Clients subscribing to tags now start live MXAccess data pushes

P1: Write timeout now returns false instead of true
  - Previously a missing OnWriteComplete callback was treated as success
  - Now correctly reports failure so OPC UA clients see the error

P1: Auto-reconnect retries from Error state (not just Disconnected)
  - Monitor loop now checks both Disconnected and Error states
  - Prevents permanent outages after a single failed reconnect attempt

P2: Topological sort on hierarchy before building address space
  - Parents guaranteed to appear before children regardless of input order
  - Prevents misplaced nodes when SQL returns unsorted results

P3: Skip redundant first-poll rebuild on startup
  - ChangeDetectionService accepts initial deploy time from OpcUaService
  - First poll only triggers rebuild if deploy time is actually unknown
  - Eliminates duplicate DB fetch and address space rebuild at startup

All 212 tests pass (205 unit + 7 integration).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 07:16:23 -04:00
Joseph Doherty
a7576ffb38 Implement LmxOpcUa server — all 6 phases complete
Full OPC UA server on .NET Framework 4.8 (x86) exposing AVEVA System
Platform Galaxy tags via MXAccess. Mirrors Galaxy object hierarchy as
OPC UA address space, translating contained-name browse paths to
tag-name runtime references.

Components implemented:
- Configuration: AppConfiguration with 4 sections, validator
- Domain: ConnectionState, Quality, Vtq, MxDataTypeMapper, error codes
- MxAccess: StaComThread, MxAccessClient (partial classes), MxProxyAdapter
  using strongly-typed ArchestrA.MxAccess COM interop
- Galaxy Repository: SQL queries (hierarchy, attributes, change detection),
  ChangeDetectionService with auto-rebuild on deploy
- OPC UA Server: LmxNodeManager (CustomNodeManager2), LmxOpcUaServer,
  OpcUaServerHost with programmatic config, SecurityPolicy None
- Status Dashboard: HTTP server with HTML/JSON/health endpoints
- Integration: Full 14-step startup, graceful shutdown, component wiring

175 tests (174 unit + 1 integration), all passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 05:55:27 -04:00