namespace ZB.MOM.WW.OtOpcUa.Core.Abstractions;
///
/// Driver capability for data-change subscriptions — covers both native subscriptions
/// (Galaxy MXAccess advisory, OPC UA monitored items, TwinCAT ADS notifications) and
/// driver-internal polled subscriptions (Modbus, AB CIP, S7, FOCAS). The driver owns
/// its polling loop where applicable; the Core just sees
/// callbacks regardless of mechanism.
///
public interface ISubscribable
{
///
/// Subscribe to data changes for a batch of attributes.
/// The driver MAY fire immediately with the current value
/// (initial-data callback per OPC UA convention) and again on every change.
///
/// The full references of the attributes to subscribe to.
/// The desired interval at which to receive data change notifications.
/// A cancellation token to observe for cancellation.
/// An opaque subscription handle the caller passes to .
Task SubscribeAsync(
IReadOnlyList fullReferences,
TimeSpan publishingInterval,
CancellationToken cancellationToken);
/// Cancel a subscription returned by .
/// The subscription handle to cancel.
/// A cancellation token to observe for cancellation.
/// A task representing the asynchronous unsubscribe operation.
Task UnsubscribeAsync(ISubscriptionHandle handle, CancellationToken cancellationToken);
///
/// Server-pushed data-change notification. Fires whenever a subscribed attribute changes,
/// and (per OPC UA convention) on subscription establishment for current values.
///
event EventHandler? OnDataChange;
}
/// Opaque subscription identity returned by .
public interface ISubscriptionHandle
{
/// Driver-internal subscription identifier (for diagnostics + post-mortem).
string DiagnosticId { get; }
}
/// Event payload for .
/// The handle returned by the original call.
/// Driver-side full reference of the changed attribute.
/// New value + quality + timestamps.
public sealed record DataChangeEventArgs(
ISubscriptionHandle SubscriptionHandle,
string FullReference,
DataValueSnapshot Snapshot);
/// One changed attribute within a .
/// Driver-side full reference of the changed attribute.
/// New value + quality + timestamps.
public sealed record DataChangeItem(string FullReference, DataValueSnapshot Snapshot);
/// Event payload for — every attribute
/// that changed within ONE production burst (a poll cycle, an inbound message, a stream chunk).
/// The handle returned by the original call.
/// The changed attributes, one entry per changed tag. Never empty. Ownership transfers
/// to the consumer, which may retain the list past the raise (it is marshalled onto another thread) — so the
/// driver MUST NOT mutate or reuse the list instance after raising; allocate a fresh one per burst.
public sealed record DataChangeBatchEventArgs(
ISubscriptionHandle SubscriptionHandle,
IReadOnlyList Items);
///
/// Optional driver capability: data changes delivered one event per production burst instead of
/// one event per tag. A driver implementing this raises once per
/// burst AND continues raising the per-tag for each item
/// (legacy consumers: Galaxy cold reads, driver CLIs). A consumer subscribes to EXACTLY ONE of the
/// two events — subscribing both double-delivers. DriverInstanceActor prefers the batch event.
///
public interface IBatchSubscribable : ISubscribable
{
/// Batched data-change notification — one raise per production burst.
event EventHandler? OnDataChangeBatch;
}