Generate high-level requirements and 10 component documents derived from source code and protocol specs. Uses lmxproxy_updates.md (v2 TypedValue/QualityCode) as the source of truth, with v1 string-based encoding documented as legacy context. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4.5 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
What This Is
LmxProxy is a gRPC proxy that bridges ScadaLink's Data Connection Layer to AVEVA System Platform via the ArchestrA MXAccess COM API. It has two projects:
- Host (
ZB.MOM.WW.LmxProxy.Host) — .NET Framework 4.8, x86-only Windows service. Hosts a gRPC server (Grpc.Core) that fronts an MxAccessClient talking to ArchestrA MXAccess. Runs as a Windows service via Topshelf. - Client (
ZB.MOM.WW.LmxProxy.Client) — .NET 10, AnyCPU library. Code-first gRPC client (protobuf-net.Grpc) consumed by ScadaLink's DCL. This is a NuGet-packable library.
The two projects use different gRPC stacks: Host uses proto-file-generated code (Grpc.Core + Grpc.Tools), Client uses code-first contracts (protobuf-net.Grpc with [DataContract]/[ServiceContract] attributes). They are wire-compatible because both target the same scada.ScadaService gRPC service.
Build Commands
dotnet build ZB.MOM.WW.LmxProxy.slnx # Build entire solution
dotnet build src/ZB.MOM.WW.LmxProxy.Host # Host only (requires x86 platform)
dotnet build src/ZB.MOM.WW.LmxProxy.Client # Client only
The Host project requires the ArchestrA.MXAccess.dll COM interop assembly in lib/. It targets x86 exclusively (MXAccess is 32-bit COM).
Architecture
Host Service Startup Chain
Program.Main → Topshelf HostFactory → LmxProxyService.Start() which:
- Validates configuration (
appsettings.jsonbound toLmxProxyConfiguration) - Creates
MxAccessClient(theIScadaClientimpl that wraps ArchestrA.MXAccess COM) - Connects to MxAccess synchronously at startup
- Starts connection monitor loop (auto-reconnect)
- Creates
SubscriptionManager,SessionManager,PerformanceMetrics,ApiKeyService - Creates
ScadaGrpcService(the proto-generated service impl) with all dependencies - Starts Grpc.Core
Serveron configured port (default 50051) - Starts HTTP status web server (default port 8080)
Key Host Components
MxAccessClient— Partial class split across 6 files (Connection, ReadWrite, Subscription, EventHandlers, NestedTypes, main). WrapsLMXProxyServerCOM object. Uses semaphores for concurrency control.ScadaGrpcService— Inherits proto-generatedScadaService.ScadaServiceBase. All RPCs validate session first, then delegate toIScadaClient. Values are string-serialized on the wire (v1 protocol).SessionManager— Tracks client sessions by GUID.SubscriptionManager— Manages MxAccess subscriptions, fans out updates viaSystem.Threading.Channels.ApiKeyInterceptor— gRPC server interceptor for API key validation.
Client Architecture
ILmxProxyClient— Public interface for consumers. Connect/Read/Write/Subscribe/Dispose.LmxProxyClient— Partial class split across multiple files (Connection, Subscription, Metrics, etc.). Usesprotobuf-net.Grpccode-first contracts (IScadaServiceinDomain/ScadaContracts.cs).LmxProxyClientBuilder— Fluent builder for configuring client instances.Domain/ScadaContracts.cs— All gRPC message types as[DataContract]POCOs and theIScadaServiceinterface with[ServiceContract].- Value conversion: Client parses string values from wire using double → bool → string heuristic in
ConvertToVtq(). Writes use.ToString()viaConvertToString().
Protocol
Proto definition: src/ZB.MOM.WW.LmxProxy.Host/Grpc/Protos/scada.proto
Currently v1 protocol (string-encoded values, string quality). A v2 protocol spec exists in docs/lmxproxy_updates.md that introduces TypedValue (protobuf oneof) and QualityCode (OPC UA status codes) — not yet implemented.
RPCs: Connect, Disconnect, GetConnectionState, Read, ReadBatch, Write, WriteBatch, WriteBatchAndWait, Subscribe (server streaming), CheckApiKey.
Configuration
Host configured via appsettings.json bound to LmxProxyConfiguration. Key sections: GrpcPort, Connection (timeouts, auto-reconnect), Subscription (channel capacity), Tls, WebServer, Serilog, RetryPolicies, HealthCheck.
Important Constraints
- Host must target x86 and .NET Framework 4.8 (ArchestrA.MXAccess is 32-bit COM interop).
- Host uses
Grpc.Core(the deprecated C-core gRPC library), notGrpc.Net. This is required because .NET 4.8 doesn't supportGrpc.Net.Server. - Client uses
Grpc.Net.Clientand targets .NET 10 — it runs in the ScadaLink central/site clusters. - The solution file is
.slnxformat (XML-based, not the older text format).