using ScadaLink.Commons.Types.Enums; namespace ScadaLink.Commons.Interfaces.Protocol; public enum QualityCode { Good, Bad, Uncertain } public record TagValue(object? Value, QualityCode Quality, DateTimeOffset Timestamp); public record ReadResult(bool Success, TagValue? Value, string? ErrorMessage); public record WriteResult(bool Success, string? ErrorMessage); /// Callback invoked when a subscribed tag value changes. /// The tag path whose value has changed. /// The new tag value including quality and timestamp. public delegate void SubscriptionCallback(string tagPath, TagValue value); public interface IDataConnection : IAsyncDisposable { /// Establishes the protocol connection using the provided connection details. /// Protocol-specific key-value configuration pairs. /// Cancellation token. Task ConnectAsync(IDictionary connectionDetails, CancellationToken cancellationToken = default); /// Gracefully terminates the protocol connection. /// Cancellation token. Task DisconnectAsync(CancellationToken cancellationToken = default); /// Subscribes to value-change notifications for a tag path; returns a subscription ID. /// The tag path to subscribe to. /// Callback invoked on each value change. /// Cancellation token. /// A subscription ID that can be passed to . Task SubscribeAsync(string tagPath, SubscriptionCallback callback, CancellationToken cancellationToken = default); /// Cancels an active subscription by its ID. /// The subscription ID returned by . /// Cancellation token. Task UnsubscribeAsync(string subscriptionId, CancellationToken cancellationToken = default); /// Reads the current value of a single tag. /// The tag path to read. /// Cancellation token. /// The read result containing the value or an error. Task ReadAsync(string tagPath, CancellationToken cancellationToken = default); /// Reads the current values of multiple tags in a single round-trip. /// The tag paths to read. /// Cancellation token. /// A dictionary of tag paths to their read results. Task> ReadBatchAsync(IEnumerable tagPaths, CancellationToken cancellationToken = default); /// Writes a value to a single tag. /// The tag path to write. /// The value to write. /// Cancellation token. /// The write result indicating success or failure. Task WriteAsync(string tagPath, object? value, CancellationToken cancellationToken = default); /// Writes values to multiple tags in a single round-trip. /// A dictionary of tag paths to values. /// Cancellation token. /// A dictionary of tag paths to their write results. Task> WriteBatchAsync(IDictionary values, CancellationToken cancellationToken = default); /// Writes a batch of values, then writes a flag and waits for a specific response value within the timeout. /// Tag values to write before the flag. /// Tag path of the trigger flag. /// Value to write to the flag tag. /// Tag path to monitor for the expected response value. /// The response value that indicates completion. /// Maximum time to wait for the response. /// Cancellation token. /// true if the response value was observed within the timeout; otherwise false. Task WriteBatchAndWaitAsync(IDictionary values, string flagPath, object? flagValue, string responsePath, object? responseValue, TimeSpan timeout, CancellationToken cancellationToken = default); /// Current connection health status. ConnectionHealth Status { get; } /// /// Raised when the adapter detects an unexpected connection loss (e.g., gRPC stream error, /// network timeout). The DataConnectionActor listens for this to trigger reconnection /// and push bad quality to all subscribed tags. /// event Action? Disconnected; }