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; }