historian(sqlserver): time-weighted Part 13 aggregates #671
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?
The SQL Server backend pushes aggregates down to T-SQL using simple per-sample definitions. Average is the arithmetic mean of samples, and there is no time weighting or interpolated bounding values (see
docs/Historian.md§"SQL Server backend", aggregate table). These are not full Part 13 definitions.Scope: add
TimeAverage,TimeAverage2andInterpolative, plusTotaltime-weighted, with Part 13 bounding-value semantics, pushed down using window functions (LAG/LEAD at the bucket edges). Pin each one with hand-computed literals.Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
Implemented in
3b739b98(merged to master).Driver.Historian.Sql.Common/TimeWeightedAggregator.cs(both SQL backends, identical results) for the Part 13 time-weighted family: TimeAverage, TimeAverage2, Total, Total2, Interpolative (window + 4 bound rows streamed into C#). Sloped for numeric, stepped for Boolean; server-default AggregateConfiguration (client's ignored); status = the SDKAggregateCalculatortime-based rule (Uncertain time counts as Good); Partial bit set; reverseInterpolativeanchored at the later time.Totalis now the time-weighted integral (matching the Gateway backend), no longerSUM.ServerHistorian:MaxTimeWeightedRawRows(default 1,000,000) — past it ⇒BadTooManyOperationsfor that node.Live gate (docker-dev, gate 2) — PASS on SqlServer and QuestDB: sparse tag interpolates Good (not BadNoData); Total ≈ TimeAverage × seconds and Total2 = TimeAverage2 × good seconds; across an outage TimeAverage2/Total2 exclude the Bad span while TimeAverage interpolates, all-Bad buckets come back Bad; backends match (bucket times + statuses exact, values within ~5e-8 from QuestDB µs); reverse Interpolative anchored at the later time; the raw-row cap returns BadTooManyOperations with a WRN log while small windows are served.
Follow-ups filed: reverse anchoring for the other aggregates, per-sample Partial bit, AVEVA integral unit, client AggregateConfiguration, CLI aggregate list.