using System.Collections.Frozen; using Opc.Ua; using ZB.MOM.WW.OtOpcUa.Core.Abstractions; namespace ZB.MOM.WW.OtOpcUa.OpcUaServer; /// /// The one table between OPC UA Part 13 standard aggregate-function NodeIds (ObjectIds.AggregateFunction_*) /// and . HistoryRead-Processed maps a request's aggregate through it, and the /// advertised AggregateFunctions folders map a backend's served set back through it — one table, so a /// NodeId the server can dispatch is exactly a NodeId it can advertise. /// internal static class AggregateFunctionMap { /// NodeId ⇒ aggregate, for every aggregate the server can name to a backend. public static readonly FrozenDictionary ByNodeId = new Dictionary { [ObjectIds.AggregateFunction_Average] = HistoryAggregateType.Average, [ObjectIds.AggregateFunction_Minimum] = HistoryAggregateType.Minimum, [ObjectIds.AggregateFunction_Maximum] = HistoryAggregateType.Maximum, [ObjectIds.AggregateFunction_Total] = HistoryAggregateType.Total, [ObjectIds.AggregateFunction_Count] = HistoryAggregateType.Count, [ObjectIds.AggregateFunction_Interpolative] = HistoryAggregateType.Interpolative, [ObjectIds.AggregateFunction_TimeAverage] = HistoryAggregateType.TimeAverage, [ObjectIds.AggregateFunction_Start] = HistoryAggregateType.Start, [ObjectIds.AggregateFunction_End] = HistoryAggregateType.End, [ObjectIds.AggregateFunction_Delta] = HistoryAggregateType.Delta, [ObjectIds.AggregateFunction_Range] = HistoryAggregateType.Range, [ObjectIds.AggregateFunction_MinimumActualTime] = HistoryAggregateType.MinimumActualTime, [ObjectIds.AggregateFunction_MaximumActualTime] = HistoryAggregateType.MaximumActualTime, [ObjectIds.AggregateFunction_StartBound] = HistoryAggregateType.StartBound, [ObjectIds.AggregateFunction_EndBound] = HistoryAggregateType.EndBound, [ObjectIds.AggregateFunction_DeltaBounds] = HistoryAggregateType.DeltaBounds, [ObjectIds.AggregateFunction_DurationGood] = HistoryAggregateType.DurationGood, [ObjectIds.AggregateFunction_DurationBad] = HistoryAggregateType.DurationBad, [ObjectIds.AggregateFunction_PercentGood] = HistoryAggregateType.PercentGood, [ObjectIds.AggregateFunction_PercentBad] = HistoryAggregateType.PercentBad, [ObjectIds.AggregateFunction_WorstQuality] = HistoryAggregateType.WorstQuality, [ObjectIds.AggregateFunction_NumberOfTransitions] = HistoryAggregateType.NumberOfTransitions, [ObjectIds.AggregateFunction_AnnotationCount] = HistoryAggregateType.AnnotationCount, [ObjectIds.AggregateFunction_StandardDeviationPopulation] = HistoryAggregateType.StandardDeviationPopulation, [ObjectIds.AggregateFunction_VariancePopulation] = HistoryAggregateType.VariancePopulation, [ObjectIds.AggregateFunction_TimeAverage2] = HistoryAggregateType.TimeAverage2, [ObjectIds.AggregateFunction_Total2] = HistoryAggregateType.Total2, }.ToFrozenDictionary(); /// /// Map a request's aggregate-function NodeId to ; null for one the server /// cannot name to any backend (the caller answers BadAggregateNotSupported). /// /// The per-node aggregate-function NodeId from the request. /// The mapped aggregate, or null. public static HistoryAggregateType? Map(NodeId? aggregateNodeId) => aggregateNodeId is { } nodeId && ByNodeId.TryGetValue(nodeId, out var aggregate) ? aggregate : null; }