using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Protocol; using ZB.MOM.WW.ScadaBridge.Commons.Types.Alarms; namespace ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Adapters; /// Connection parameters resolved from the flat config dict. public record MxGatewayConnectionOptions( string Endpoint, string ApiKey, string ClientName, int WriteUserId, bool UseTls, string? CaFile, string? ServerName, int ReadTimeoutMs, // Maximum in-flight supervisory advise commands on the bulk-subscribe path when // WriteUserId == 0 (the gateway worker has no BULK supervisory advise). Sourced from // DataConnectionOptions.MxSupervisoryAdviseParallelism. int SupervisoryAdviseParallelism = 16); /// One advised-tag value change pushed from the gateway event stream. public record MxValueUpdate(string TagPath, object? Value, QualityCode Quality, DateTimeOffset Timestamp); /// Per-tag read outcome. public record MxReadOutcome(string TagPath, bool Success, object? Value, QualityCode Quality, DateTimeOffset Timestamp, string? Error); /// Per-tag write outcome. public record MxWriteOutcome(string TagPath, bool Success, string? Error); /// Per-tag outcome of a bulk subscribe (AddItem + Advise in one gateway command). /// The requested tag address. /// Whether the item was added and advised. /// Gateway item handle (as a string) when successful. /// Per-tag failure reason when not successful. public record MxSubscribeOutcome(string TagPath, bool Success, string? SubscriptionId, string? Error); /// One node in a Galaxy browse level. public record MxBrowseChild(string NodeId, string DisplayName, BrowseNodeClass NodeClass, bool HasChildren, string? DataType = null); /// /// Seam over the MxAccess Gateway .NET client + Galaxy repository client. Decouples /// from the generated gRPC/protobuf types so the /// adapter is unit-testable with a fake. The real implementation lives in /// RealMxGatewayClient. /// public interface IMxGatewayClient : IAsyncDisposable { /// Opens the gateway session and registers the client (Register → serverHandle held internally). /// Resolved connection parameters. /// Cancellation token. /// A task that represents the asynchronous operation. Task ConnectAsync(MxGatewayConnectionOptions options, CancellationToken ct = default); /// Closes the session. /// Cancellation token. /// A task that represents the asynchronous operation. Task DisconnectAsync(CancellationToken ct = default); /// AddItem + Advise; returns the gateway item handle (as a string subscription id). /// Tag address to subscribe to. /// Cancellation token. /// A task that resolves to the gateway item handle (subscription id). Task SubscribeAsync(string tagPath, CancellationToken ct = default); /// UnAdvise + RemoveItem for a previously returned subscription id. /// Subscription id returned by . /// Cancellation token. /// A task that represents the asynchronous operation. Task UnsubscribeAsync(string subscriptionId, CancellationToken ct = default); /// /// Adds and advises MANY tags in as few gateway commands as the worker allows — /// ONE SubscribeBulk round trip in plain-advise mode, or one /// AddItemBulk plus bounded-parallel supervisory advises when the connection /// has no write-user context (the worker has no bulk supervisory advise). /// Replaces the historical 2-RPC-per-tag AddItem + Advise pair. /// /// Tag addresses to subscribe. /// Cancellation token. /// One outcome per requested tag path, in request order. Task> SubscribeBulkAsync( IReadOnlyList tagPaths, CancellationToken ct = default); /// UnAdvise + RemoveItem for many subscription ids in one gateway command. /// Subscription ids previously returned by a subscribe call. /// Cancellation token. /// A task that represents the asynchronous operation. Task UnsubscribeBulkAsync(IReadOnlyList subscriptionIds, CancellationToken ct = default); /// Snapshot read of one or more tags (ReadBulk). /// Tag addresses to read. /// Cancellation token. /// A task that resolves to one outcome per requested tag path. Task> ReadAsync(IReadOnlyList tagPaths, CancellationToken ct = default); /// Write one or more tag/value pairs (WriteBulk with the configured WriteUserId). /// Tag/value pairs to write. /// Cancellation token. /// A task that resolves to one outcome per requested write. Task> WriteAsync(IReadOnlyList<(string TagPath, object? Value)> writes, CancellationToken ct = default); /// One Galaxy browse level (BrowseChildren). null → root. /// Parent node id (Galaxy contained path), or null for root. /// Cancellation token. /// A task that resolves to the child nodes and a flag indicating whether the result was truncated. Task<(IReadOnlyList Children, bool Truncated)> BrowseChildrenAsync(string? parentNodeId, CancellationToken ct = default); /// /// Long-running event consumer. Invokes for each advised-tag /// data change. Resumes from the last delivered worker sequence on reconnect. Completes /// (or throws) when the stream ends — the adapter treats that as a disconnect. /// /// Callback invoked per advised-tag value change. /// Cancellation token; ends the loop when cancelled. /// A task that represents the asynchronous operation. Task RunEventLoopAsync(Action onUpdate, CancellationToken ct = default); /// /// Long-running consumer of the gateway's session-less StreamAlarms feed. Emits a /// Snapshot…SnapshotComplete replay of active alarms then live transitions. Re-opens /// the stream internally on transport faults (the source replays a fresh snapshot). /// Completes only when is cancelled. /// /// Optional source-reference prefix to scope the feed; null = gateway-wide. /// Callback invoked per native alarm transition. /// Cancellation token; ends the loop when cancelled. /// A task that represents the asynchronous operation. Task RunAlarmStreamAsync(string? alarmFilterPrefix, Action onTransition, CancellationToken ct = default); } /// Builds instances. public interface IMxGatewayClientFactory { /// Creates a new, unconnected client instance. /// A new ready to be connected. IMxGatewayClient Create(); }