fix(historian): refuse native Gateway TimeAverage/Total until historiangw#27 (lmxopcua#746)

AVEVA's native TimeAverage / Total are answered with Good-status wrong values
while the gateway sends the interval in the wrong unit (historiangw#27): one
whole-span value on the earliest interval, the rest absent. Nothing on the
wire marks the answer as degraded.

Both are now refused BadAggregateNotSupported (unsent, not counted as a
backend failure, not advertised in AggregateFunctions) unless
ServerHistorian:Gateway:EnableNativeTimeWeighted is true. The default
Gateway set is the ten raw-evaluated aggregates
(GatewayHistorianDataSource.RawEvaluatedAggregates); ServedAggregates stays
the 12 the backend can serve with the flag on. The native-path tests opt in.

Also documents the ServerHistorian:Gateway sub-section (EventDrainBudget from
the previous commit) and the events drain in docs/Historian.md.

Rebased from the unpushed remed/lane-H2 branch (originally authored 2026-10-22
in session_01Ub9hGmYLQvn9XETzw7CMsT) onto current master.

Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
This commit is contained in:
Joseph Doherty
2026-10-22 16:30:19 -04:00
parent 24609ececa
commit 0b85c499e3
11 changed files with 157 additions and 16 deletions
@@ -282,4 +282,13 @@ public sealed class GatewayHistorianSettings
/// does not stream the whole window. Default 10 000; 0 = abandon at the cap (the previous behaviour).
/// </summary>
public int EventDrainBudget { get; init; } = DefaultEventDrainBudget;
/// <summary>
/// Serve HistoryRead-Processed <c>TimeAverage</c> / <c>Total</c> through AVEVA's native retrieval modes. Default
/// <c>false</c>: the gateway hands AVEVA the interval in the wrong unit (historiangw#27), so AVEVA answers ONE
/// Good-status whole-span value on the earliest interval and nothing for the rest — wrong values a client cannot
/// tell from right ones. Off, both are <c>BadAggregateNotSupported</c> and are not advertised (like the other five
/// time-weighted aggregates on this backend). Turn it on only once a fixed gateway is live-verified.
/// </summary>
public bool EnableNativeTimeWeighted { get; init; }
}