fix(historian): #680 lane A — time-weighted aggregates follow Part 13

TimeAverage/Total: Uncertain when a Bad value is skipped, an Uncertain value
is used, the value is extrapolated or the interval is not covered; an
interval wholly inside an outage bridges (Uncertain); Total integrates only
the covered part. TimeAverage2/Total2 stop at the end of the data (Partial,
then BadNoData). PercentGood/PercentBad become duration-based and move to
the time-weighted family (now subject to MaxTimeWeightedRawRows). Reverse
reads set Partial on the interval holding the latest sample when nothing
follows (SDK m_startOfData). Parity tests gain end-of-data and outage
datasets; pre-existing #680 masks removed.
This commit is contained in:
Joseph Doherty
2026-10-11 15:52:30 -04:00
parent 19a4c093be
commit b61975f7d7
7 changed files with 645 additions and 173 deletions
@@ -11,10 +11,12 @@ public sealed class ProcessedReadTests
public void Every_enum_member_is_either_served_or_refused()
{
// Seventeen served (#671 added TimeAverage, TimeAverage2, Interpolative and Total2, and moved Total to the
// time-weighted family); anything appended to the enum later falls to the refusal (total default).
// time-weighted family; #680 moved PercentGood/PercentBad there too — they are duration-based); anything appended to
// the enum later falls to the refusal (total default).
Enum.GetValues<HistoryAggregateType>().Count(a => AggregateFamilies.FamilyOf(a) is not null).ShouldBe(17);
Enum.GetValues<HistoryAggregateType>().Where(a => AggregateFamilies.FamilyOf(a) == AggregateFamily.TimeWeighted)
.ShouldBe([HistoryAggregateType.Total, HistoryAggregateType.Interpolative, HistoryAggregateType.TimeAverage,
HistoryAggregateType.TimeAverage2, HistoryAggregateType.Total2]);
HistoryAggregateType.PercentGood, HistoryAggregateType.PercentBad, HistoryAggregateType.TimeAverage2,
HistoryAggregateType.Total2]);
}
}