6.7 KiB
ZB.MOM.WW.SPHistorianClient — Design
Date: 2026-06-19 Status: Approved — proceeding to implementation plan.
Goal
Repackage the proven, pure-managed .NET 10 AVEVA.Historian.Client SDK (delivered in
HistorianSDK_2023R2/histsdk-migration.zip from 10.100.0.48) as the family-branded shared
library ZB.MOM.WW.SPHistorianClient (System Platform Historian Client), following the same
conventions as the other ZB.MOM.WW.* shared libraries in this repo.
Context — what the source bundle contains
histsdk-migration.zip → histsdk-migration/:
histsdk/— the SDK git repo.src/AVEVA.Historian.Client/is a pure-managed .NET 10 client for AVEVA Historian (noaahClientManaged.dll/aahClient.dll/ native AVEVA runtime — the wire protocol is reverse-engineered and re-implemented in C#). ~165–188 unit + gated-live tests pass.analysis-2023r2/— reverse-engineering analysis (recovered protos, decompiled stock contract, transport writeup). Kept separate from the repo on purpose.
Two transport families exist in the SDK:
| Transport | Protocol | Platform | Verification |
|---|---|---|---|
LocalPipe, RemoteTcpIntegrated, RemoteTcpCertificate |
WCF/MDAS (2020) | Windows-only | live-verified: raw/aggregate(16 modes)/at-time/event reads, browse, metadata, status, EnsureTag/DeleteTag |
RemoteGrpc |
gRPC (2023 R2) | cross-platform (Grpc.Net.Client/.Web) | unit-tested; not yet live-verified against a real 2023 R2 server (ExchangeKey auth step unproven) |
Decisions (locked)
- Approach: port + rebrand. Copy the SDK source into
ZB.MOM.WW.SPHistorianClient, rename the root namespace, adopt ZB conventions, bring the unit tests, drop non-shippable artifacts. One coherent shared library — a published package should not ship a third-party (AVEVA) namespace or non-redistributable reverse-engineering artifacts. - Transports: both WCF + gRPC. Ship everything that works. WCF members keep
[SupportedOSPlatform("windows")]; the gRPC path runs anywhere. No working code discarded. - Not a "component normalization." There is no duplicated historian code across the three apps to converge — this is a net-new shared library that simply follows ZB packaging conventions.
Repository layout
Plain files committed into this repo (NOT a nested git repo — see the
shared-libs-are-plain-files-not-nested-repos convention):
ZB.MOM.WW.SPHistorianClient/
Directory.Build.props # net10.0, Nullable, ImplicitUsings, LangVersion latest, Version 0.1.0, central pkg mgmt
Directory.Packages.props # central PackageVersion entries
ZB.MOM.WW.SPHistorianClient.slnx
CLAUDE.md README.md .gitignore
src/ZB.MOM.WW.SPHistorianClient/ # the single package
HistorianClient.cs, HistorianClientOptions.cs, HistorianTransport.cs
Models/ Protocol/ Transport/ Wcf/ Wcf/Contracts/ Grpc/ Grpc/Protos/*.proto
DependencyInjection/AddZbSpHistorianClient (ZB-idiomatic DI extension)
tests/ZB.MOM.WW.SPHistorianClient.Tests/ # offline unit/golden-byte + gated-live integration
artifacts/ # dotnet pack output
Port mechanics
- Copy
src/AVEVA.Historian.Client/andtests/AVEVA.Historian.Client.Tests/from the bundle. - Rename the C# root namespace
AVEVA.Historian.Client→ZB.MOM.WW.SPHistorianClientacross all files: 74namespacedeclarations spanning the root + 6 sub-namespaces (.Models,.Wcf,.Wcf.Contracts,.Protocol,.Transport,.Grpc), allusingdirectives, and theInternalsVisibleToto the test assembly. Drop theInternalsVisibleTotoAVEVA.Historian.ReverseEngineering(tool not shipped). - Leave the proto wire contracts untouched: the 6
Grpc/Protos/*.protokeepoption csharp_namespace = "ArchestrA.Grpc.Contract.*"— that is AVEVA's wire contract, not ours.Grpc.Toolskeeps generating the client stubs at build. - Convert inline
PackageReferenceversions to central management inDirectory.Packages.props, matching theZB.MOM.WW.Telemetrytemplate.
Dependencies
- Library:
Google.Protobuf,Grpc.Net.Client,Grpc.Net.Client.Web,Grpc.Tools(build-only,PrivateAssets=all),System.ServiceModel.NetNamedPipe,System.ServiceModel.NetTcp,System.Security.Cryptography.Xml. AddMicrosoft.Extensions.DependencyInjection.Abstractions+Microsoft.Extensions.Optionsfor the DI extension. - Tests:
xunit,xunit.runner.visualstudio,Microsoft.NET.Test.Sdk,coverlet.collector,Microsoft.Data.SqlClient(SQL post-check tests).
Excluded (safety / non-redistributable / Windows-native)
tools/reverse-engineering harnesses (.NET Framework, reference native AVEVA binaries).analysis-2023r2/decompiled/— proprietary AVEVA decompilations (not redistributable).scripts/— Frida / PowerShell / Python capture tooling.docs/reverse-engineering/— identity-bearing.ndjson/ capture evidence.
Kept: the recovered .proto files (needed to build), the offline unit tests, and a sanitized
architecture/surface summary folded into CLAUDE.md / README.md. .gitignore blocks the
identity-bearing patterns (*.ndjson, current/, aveva-install-*/, artifacts/-raw, etc.).
Public surface (preserved 1:1)
HistorianClient + HistorianClientOptions façade; Models/*; HistorianTransport enum
(LocalPipe / RemoteTcpIntegrated / RemoteTcpCertificate / RemoteGrpc); operations:
ProbeAsync, ReadRawAsync / ReadAggregateAsync / ReadAtTimeAsync, ReadEventsAsync,
BrowseTagNamesAsync, GetTagMetadataAsync, status calls, EnsureTagAsync / DeleteTagAsync.
One ZB-idiomatic addition: AddZbSpHistorianClient(...) DI extension mirroring AddZbTelemetry
— thin: binds HistorianClientOptions and registers HistorianClient. Optional to consumers.
Cross-platform & testing posture
- WCF members already carry
[SupportedOSPlatform("windows")]; the library builds and unit-tests on macOS/Linux. gRPC path is portable. - Offline unit/golden-byte tests run anywhere. Live integration tests stay gated by
HISTORIAN_*env vars and skip cleanly when unset. - Verify
dotnet build+dotnet testpass locally (macOS) before finishing.
Packaging
dotnet pack -c Release -o ./artifacts → ZB.MOM.WW.SPHistorianClient.0.1.0.nupkg. Gitea URLs in
package metadata. Not pushed/published to any feed unless explicitly requested.
Out of scope (this pass)
- Wiring
ZB.MOM.WW.SPHistorianClientinto any consumer (e.g. OtOpcUa Phase C HistoryRead) — a separate follow-on. - Live-verifying the gRPC
RemoteGrpcpath against a real 2023 R2 server. - Writing samples (
AddS2) — architecturally blocked in the source SDK; remains out of scope.