Gateway historian: Count and Average mapped to AVEVA modes with different semantics (Counter delta, time-weighted average) #679
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found while investigating #677 (2026-10-11). The Gateway historian backend maps two OPC UA aggregates onto AVEVA retrieval modes with different semantics, so Gateway results disagree with the SqlServer/QuestDB backends for the same aggregate:
AggregateModeMapper.cs:36—Count → RetrievalMode.Counter. AVEVA's Counter mode is the rollover-counter delta, not a sample count. OPC UACountis the number of raw values in the interval.AggregateModeMapper.cs:32—Average → TimeWeightedAverage. OPC UAAverageis the arithmetic mean of the raw values (what the SQL backends compute);TimeAverageis the time-weighted one.Fix direction: map
CountandAverageto the AVEVA modes that match (or returnBadAggregateNotSupportedwhere none matches), and mapTimeAverage→TimeWeightedAverage. Needs the VPN towonder-sql-vd03to verify against the real historian (a constant/known-sample sandbox tag, compare against the SQL backends).Related: #677 (IntegralDivisor for
Total).Fixed —
fb5ec80f(merged19a4c093).AVEVA's 15 retrieval modes include no arithmetic mean and no sample count, so the Gateway backend no longer returns a different statistic under the requested name:
AverageTimeWeightedAverageBadAggregateNotSupported(no gateway call, not counted as a backend fault)CountCounter(rollover-counter increase)BadAggregateNotSupportedTimeAverageTimeWeightedAverage(the numberAverageused to return)⚠️ Client-visible: a client reading
Averageon a Gateway node must switch toTimeAveragefor the old number; there is no Gateway sample count. ScadaBridge does not issue processed reads.Verification: mapper + data-source tests (red first, falsified by restoring the old mapping); live gate 8 D4 on docker-dev with an unreachable gateway:
Average/Count⇒0x80D50000with zero backend-fault logs,TimeAverage/Minimum/Maximum/Totalreach the backend.Not verified (VPN to wonder-sql-vd03 needed): TimeAverage magnitude, NULL-gap handling and bucket timestamp (Gateway stamps the interval END). Follow-ups: #681 (compute per-sample aggregates — true Average/Count — from raw reads on Gateway), #682 (advertise only the aggregates the backend serves).
Live AVEVA leg (2026-10-12, VPN).
TimeAverage→ AVEVATimeWeightedAverage: magnitude PASS — AVEVA's TWA on a Float tag is sloped (trapezoidal; 22.5 where stepped would be 17.5), identical to the SqlServer/QuestDBTimeAverageon all-Good spans; the bucket stamp is the interval start (verified the histsdktail+43orientation). NULL-gap handling differs from the SQL backends (AVEVA excludes gap time; SQL bridges it, Uncertain) — documented as part of #685.End-to-end results through OtOpcUa are currently broken by the gateway interval bug (historiangw#27) and #685 (pre-window row, Uncertain value dropped). Since #681 Gateway also serves a true
Average/Countfrom raw. Closing.