Speculative-items sweep: IntegralDivisor, cert tests, D3/D1/D2 findings
Plan: docs/plans/speculative-items-sweep.md (also covers parallelism + findings). Implemented: - C3: HistorianTagDefinition.IntegralDivisor (default 1.0). Wire bytes flip per the captured native serializer; live probe shows the server stores IntegralDivisor on EngineeringUnit (shared) rather than per-tag, so the value is accepted on the wire but doesn't visibly persist for the test EU. Documented in the property's doc-comment. - E: HistorianWcfCertOptionTests (5 tests) covering AllowUntrustedServer- Certificate validator installation + ServerDnsIdentity propagation through CreateEndpointAddress and CreateBindingPair. Investigated + documented (deferred): - D3: Discrete/String/Int1/Int8/UInt8 EnsT2 root cause — server-side ValidationFailed: "Transaction validation failed". Native AddTag's validator rejects non-analog types; not a wire-format issue. To unlock, need to capture a working native flow via a different code path (likely SMC's tag-import path or AddTagExtendedProperties carrying type-specific metadata). Defer until a customer asks. - D1: AddTagExtendedProperties feasibility — managed surface confirmed (ArchestrA.HistorianAccess.AddTagExtendedProperties + WCF op AddTagExtendedPropertyGroups). Cost estimated at 1-2 days of focused RE work due to CTagExtendedPropertyGroup payload complexity. Defer. - D2: AddRevisionValuesBegin/Value/End — sub-plan written at docs/plans/revision-write-path.md with 5-step capture sequence, workstream estimates, and risk register. Implementation deferred. 177/177 tests pass (was 172; +5 cert tests + 1 IntegralDivisor unit test, harness probe results not committed). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -69,4 +69,16 @@ public sealed record HistorianTagDefinition
|
||||
/// (Cyclic = 1, Delta = 2).
|
||||
/// </summary>
|
||||
public HistorianStorageType StorageType { get; init; } = HistorianStorageType.Cyclic;
|
||||
|
||||
/// <summary>
|
||||
/// Divisor applied when storing integral values for trend integration. Default 1.0.
|
||||
/// Wire bytes flip correctly per the captured native serializer, but live testing
|
||||
/// 2026-05-05 showed the server stores <c>IntegralDivisor</c> on
|
||||
/// <c>EngineeringUnit</c> (shared across all tags using that EU) rather than
|
||||
/// per-tag — so a non-default value sent here is accepted on the wire but does
|
||||
/// not visibly persist in <c>EngineeringUnit.IntegralDivisor</c> for the test
|
||||
/// EU. Exposed for completeness and forward-compatibility; check your server's
|
||||
/// behavior before relying on it.
|
||||
/// </summary>
|
||||
public double IntegralDivisor { get; init; } = 1.0;
|
||||
}
|
||||
|
||||
@@ -145,7 +145,8 @@ internal static class HistorianTagWriteProtocol
|
||||
double maxRaw = DefaultMaxRaw,
|
||||
uint storageRateMs = DefaultStorageRateMs,
|
||||
bool applyScaling = false,
|
||||
Models.HistorianStorageType storageType = Models.HistorianStorageType.Cyclic)
|
||||
Models.HistorianStorageType storageType = Models.HistorianStorageType.Cyclic,
|
||||
double integralDivisor = 1.0)
|
||||
{
|
||||
if (storageRateMs == 0)
|
||||
{
|
||||
@@ -188,7 +189,7 @@ internal static class HistorianTagWriteProtocol
|
||||
|
||||
WriteCompactAscii(w, engineeringUnit ?? string.Empty); // var
|
||||
w.Write(IntegralDivisorMagic); // uint32 (purpose unclear — captured constant)
|
||||
w.Write(1.0); // double
|
||||
w.Write(integralDivisor); // double IntegralDivisor (default 1.0)
|
||||
w.Write(applyScaling ? AnalogTrailerScalingEnabled : AnalogTrailerScalingDisabled);
|
||||
|
||||
return ms.ToArray();
|
||||
|
||||
@@ -110,7 +110,8 @@ internal sealed class HistorianWcfTagWriteOrchestrator
|
||||
maxRaw: definition.MaxRaw,
|
||||
storageRateMs: definition.StorageRateMs,
|
||||
applyScaling: definition.ApplyScaling,
|
||||
storageType: definition.StorageType);
|
||||
storageType: definition.StorageType,
|
||||
integralDivisor: definition.IntegralDivisor);
|
||||
|
||||
bool ok = historyChannel.EnsureTags2(
|
||||
handle: handle,
|
||||
|
||||
Reference in New Issue
Block a user