namespace ZB.MOM.WW.OtOpcUa.Core.Abstractions;
///
/// Driver capability for historical-data reads (OPC UA HistoryRead). Optional —
/// only drivers whose backends carry historian data implement this. Currently:
/// Galaxy (Wonderware Historian via the optional plugin), OPC UA Client (forward
/// to upstream server).
///
///
/// and are C# default interface
/// methods that throw — drivers opt in by overriding so
/// a raw-only driver compiles without forcing it to provide at-time / event surfaces it
/// has no backend for. The sibling server-side surface, ,
/// declares both methods as required because a registered historian owns the full read
/// surface; the asymmetry is intentional (Core.Abstractions-008).
///
public interface IHistoryProvider
{
///
/// Read raw historical samples for a single attribute over a time range.
/// The Core wraps this with continuation-point handling.
///
/// The full reference path to the attribute.
/// Inclusive lower bound on the time range (UTC).
/// Exclusive upper bound on the time range (UTC).
/// Maximum number of values to return per node.
/// A cancellation token to stop the operation.
/// A task that returns the history read result containing samples and optional continuation point.
Task ReadRawAsync(
string fullReference,
DateTime startUtc,
DateTime endUtc,
uint maxValuesPerNode,
CancellationToken cancellationToken);
///
/// Read processed (aggregated) samples — interval-bucketed average / min / max / etc.
/// Optional — drivers that only support raw history can throw .
///
/// The full reference path to the attribute.
/// Inclusive lower bound on the time range (UTC).
/// Exclusive upper bound on the time range (UTC).
/// The time interval for bucketing samples.
/// The aggregate function to apply to each bucket.
/// A cancellation token to stop the operation.
/// A task that returns the history read result containing aggregated samples and optional continuation point.
Task ReadProcessedAsync(
string fullReference,
DateTime startUtc,
DateTime endUtc,
TimeSpan interval,
HistoryAggregateType aggregate,
CancellationToken cancellationToken);
///
/// Read one sample per requested timestamp — OPC UA HistoryReadAtTime service. The
/// driver interpolates (or returns the prior-boundary sample) when no exact match
/// exists. Optional; drivers that can't interpolate throw .
///
///
/// Default implementation throws. Drivers opt in by overriding; keeps existing
/// IHistoryProvider implementations compiling without forcing a ReadAtTime path
/// they may not have a backend for.
///
/// The full reference path to the attribute.
/// The list of timestamps at which to read values.
/// A cancellation token to stop the operation.
/// A task that returns the history read result containing samples at the requested times.
Task ReadAtTimeAsync(
string fullReference,
IReadOnlyList timestampsUtc,
CancellationToken cancellationToken)
=> throw new NotSupportedException(
$"{GetType().Name} does not implement ReadAtTimeAsync. " +
"Drivers whose backends support at-time reads override this method.");
///
/// Read historical alarm/event records — OPC UA HistoryReadEvents service. Distinct
/// from the live event stream — historical rows come from an event historian (Galaxy's
/// Alarm Provider history log, etc.) rather than the driver's active subscription.
///
///
/// Optional filter: null means "all sources", otherwise restrict to events from that
/// source-object name. Drivers may ignore the filter if the backend doesn't support it.
///
/// Inclusive lower bound on EventTimeUtc.
/// Exclusive upper bound on EventTimeUtc.
///
/// Upper cap on returned events — the driver's backend enforces this. The type is
/// rather than (which the sibling raw / processed
/// reads use for maxValuesPerNode) because callers and downstream historian
/// adapters historically treat maxEvents <= 0 as a sentinel meaning
/// "use the backend's default cap" (see WonderwareHistorianClient /
/// HistorianDataSource). The asymmetry is intentional — Core.Abstractions-006.
///
/// Request cancellation.
///
/// Default implementation throws. Only drivers with an event historian (Galaxy via the
/// Wonderware Alarm & Events log) override. Modbus / the OPC UA Client driver stay
/// with the default and let callers see BadHistoryOperationUnsupported.
///
/// Note the type asymmetry with /
/// (both use uint maxValuesPerNode): event
/// readers accept a signed int maxEvents so callers can pass 0 / negative as a
/// "use default cap" sentinel without an extra parameter or overload.
///
Task ReadEventsAsync(
string? sourceName,
DateTime startUtc,
DateTime endUtc,
int maxEvents,
CancellationToken cancellationToken)
=> throw new NotSupportedException(
$"{GetType().Name} does not implement ReadEventsAsync. " +
"Drivers whose backends have an event historian override this method.");
}
/// Result of a HistoryRead call.
/// Returned samples in chronological order.
/// Opaque token for the next call when more samples are available; null when complete.
public sealed record HistoryReadResult(
IReadOnlyList Samples,
byte[]? ContinuationPoint);
/// Aggregate function for processed history reads. Mirrors OPC UA Part 13 standard aggregates.
public enum HistoryAggregateType
{
Average,
Minimum,
Maximum,
Total,
Count,
}
///
/// One row returned by — a historical
/// alarm/event record, not the OPC UA live-event stream. Fields match the minimum set the
/// Server needs to populate a HistoryEventFieldList for HistoryReadEvents responses.
///
/// Stable unique id for the event — driver-specific format.
/// Source object that emitted the event. May differ from the sourceName filter the caller passed (fuzzy matches).
/// Process-side timestamp — when the event actually occurred.
/// Historian-side timestamp — when the historian persisted the row; may lag by the historian's buffer flush cadence.
/// Human-readable message text.
/// OPC UA severity (1-1000). Drivers map their native priority scale onto this range.
public sealed record HistoricalEvent(
string EventId,
string? SourceName,
DateTime EventTimeUtc,
DateTime ReceivedTimeUtc,
string? Message,
ushort Severity);
/// Result of a call.
/// Events in chronological order by EventTimeUtc.
/// Opaque token for the next call when more events are available; null when complete.
public sealed record HistoricalEventsResult(
IReadOnlyList Events,
byte[]? ContinuationPoint);