fix(historian): #685 Gateway native TimeAverage/Total — drop AVEVA's pre-window row, keep Uncertain values

AVEVA answers one extra row for the interval before the window; it was mapped as
a result stamped before StartTime (N+1 values). Rows whose interval lies outside
the requested span (either direction) are now dropped after the drained stream.
An Uncertain (opc 64-191) interval kept no value (opc >= 192 was the only data
test); it now carries its value as UncertainDataSubNormal | Calculated.
Docs: AVEVA's TWA excludes NULL-gap time while the SQL backends bridge it;
end-to-end per-interval values also need historiangw#27.
This commit is contained in:
Joseph Doherty
2026-10-12 14:31:31 -04:00
parent 9ced6455ad
commit 44a03bedc0
5 changed files with 249 additions and 24 deletions
@@ -136,7 +136,8 @@ public sealed class GatewayHistorianDataSource : IHistorianDataSource, IAsyncDis
/// </para>
/// <para>
/// <b>TimeAverage / Total</b> stay native AVEVA retrieval modes (<see cref="AggregateModeMapper"/>), stamped with
/// the interval start and the Calculated bit. Everything else is <see cref="HistoryAggregateNotSupportedException"/>
/// the interval start and the Calculated bit; AVEVA's extra row for the interval before the window is dropped and
/// an Uncertain interval keeps its value (#685, <see cref="SampleMapper.ToAggregateSnapshots"/>). Everything else is <see cref="HistoryAggregateNotSupportedException"/>
/// (see <see cref="ServedAggregates"/>).
/// </para>
/// </remarks>
@@ -165,7 +166,8 @@ public sealed class GatewayHistorianDataSource : IHistorianDataSource, IAsyncDis
buckets.Add(bucket);
}
var snapshots = SampleMapper.ToAggregateSnapshots(buckets);
// Filtered while mapping, after the stream was drained (#685: AVEVA's extra pre-window row).
var snapshots = SampleMapper.ToAggregateSnapshots(buckets, startUtc, endUtc);
RecordOutcome(success: true, error: null);
return new HistoryReadResult(snapshots, ContinuationPoint: null);
}