using Opc.Ua;
using Opc.Ua.Server;
namespace ZB.MOM.WW.OtOpcUa.OpcUaServer.Compatibility.Aggregates;
/// Adapts the versioned baseline algorithms to the SDK 2 calculator protocol without a second SDK runtime.
internal static class CompatibilityAggregateFactory
{
internal static IAggregateCalculator Create(NodeId id, DateTimeUtc start, DateTimeUtc end, double interval,
bool stepped, AggregateConfiguration configuration, ITelemetryContext telemetry) =>
new Adapter(Aggregators.CreateStandardCalculator(id, (DateTime)start, (DateTime)end, interval, stepped, configuration, telemetry)
?? throw new ArgumentOutOfRangeException(nameof(id), "Unsupported baseline aggregate."));
/// Replaces exactly the existing standard factories; no aggregate IDs are added or removed.
internal static async ValueTask RegisterAsync(AggregateManager manager, CancellationToken ct)
{
foreach (var id in Aggregators.SupportedIds)
await manager.RegisterFactoryAsync(id, Aggregators.GetNameForStandardAggregate(id).Name!, Create, ct).ConfigureAwait(false);
}
private sealed class Adapter(AggregateCalculator calculator) : IAggregateCalculator
{
public NodeId AggregateId => calculator.AggregateId;
public bool QueueRawValue(Opc.Ua.DataValue value) => calculator.QueueRawValue(LegacyDataValue.FromSdk(value));
public bool HasEndTimePassed(DateTimeUtc currentTime) => calculator.HasEndTimePassed((DateTime)currentTime);
public bool TryGetProcessedValue(bool returnPartial, out Opc.Ua.DataValue value)
{
var processed = calculator.GetProcessedValue(returnPartial);
value = processed is null ? default : processed.ToSdk();
return processed is not null;
}
}
}