132 lines
8.0 KiB
C#
132 lines
8.0 KiB
C#
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Protocol;
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Types.Alarms;
|
|
|
|
namespace ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Adapters;
|
|
|
|
/// <summary>Connection parameters resolved from the flat config dict.</summary>
|
|
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);
|
|
|
|
/// <summary>One advised-tag value change pushed from the gateway event stream.</summary>
|
|
public record MxValueUpdate(string TagPath, object? Value, QualityCode Quality, DateTimeOffset Timestamp);
|
|
|
|
/// <summary>Per-tag read outcome.</summary>
|
|
public record MxReadOutcome(string TagPath, bool Success, object? Value, QualityCode Quality, DateTimeOffset Timestamp, string? Error);
|
|
|
|
/// <summary>Per-tag write outcome.</summary>
|
|
public record MxWriteOutcome(string TagPath, bool Success, string? Error);
|
|
|
|
/// <summary>Per-tag outcome of a bulk subscribe (AddItem + Advise in one gateway command).</summary>
|
|
/// <param name="TagPath">The requested tag address.</param>
|
|
/// <param name="Success">Whether the item was added and advised.</param>
|
|
/// <param name="SubscriptionId">Gateway item handle (as a string) when successful.</param>
|
|
/// <param name="Error">Per-tag failure reason when not successful.</param>
|
|
public record MxSubscribeOutcome(string TagPath, bool Success, string? SubscriptionId, string? Error);
|
|
|
|
/// <summary>One node in a Galaxy browse level.</summary>
|
|
public record MxBrowseChild(string NodeId, string DisplayName, BrowseNodeClass NodeClass, bool HasChildren, string? DataType = null);
|
|
|
|
/// <summary>
|
|
/// Seam over the MxAccess Gateway .NET client + Galaxy repository client. Decouples
|
|
/// <see cref="MxGatewayDataConnection"/> from the generated gRPC/protobuf types so the
|
|
/// adapter is unit-testable with a fake. The real implementation lives in
|
|
/// <c>RealMxGatewayClient</c>.
|
|
/// </summary>
|
|
public interface IMxGatewayClient : IAsyncDisposable
|
|
{
|
|
/// <summary>Opens the gateway session and registers the client (Register → serverHandle held internally).</summary>
|
|
/// <param name="options">Resolved connection parameters.</param>
|
|
/// <param name="ct">Cancellation token.</param>
|
|
/// <returns>A task that represents the asynchronous operation.</returns>
|
|
Task ConnectAsync(MxGatewayConnectionOptions options, CancellationToken ct = default);
|
|
|
|
/// <summary>Closes the session.</summary>
|
|
/// <param name="ct">Cancellation token.</param>
|
|
/// <returns>A task that represents the asynchronous operation.</returns>
|
|
Task DisconnectAsync(CancellationToken ct = default);
|
|
|
|
/// <summary>AddItem + Advise; returns the gateway item handle (as a string subscription id).</summary>
|
|
/// <param name="tagPath">Tag address to subscribe to.</param>
|
|
/// <param name="ct">Cancellation token.</param>
|
|
/// <returns>A task that resolves to the gateway item handle (subscription id).</returns>
|
|
Task<string> SubscribeAsync(string tagPath, CancellationToken ct = default);
|
|
|
|
/// <summary>UnAdvise + RemoveItem for a previously returned subscription id.</summary>
|
|
/// <param name="subscriptionId">Subscription id returned by <see cref="SubscribeAsync"/>.</param>
|
|
/// <param name="ct">Cancellation token.</param>
|
|
/// <returns>A task that represents the asynchronous operation.</returns>
|
|
Task UnsubscribeAsync(string subscriptionId, CancellationToken ct = default);
|
|
|
|
/// <summary>
|
|
/// Adds and advises MANY tags in as few gateway commands as the worker allows —
|
|
/// ONE <c>SubscribeBulk</c> round trip in plain-advise mode, or one
|
|
/// <c>AddItemBulk</c> 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.
|
|
/// </summary>
|
|
/// <param name="tagPaths">Tag addresses to subscribe.</param>
|
|
/// <param name="ct">Cancellation token.</param>
|
|
/// <returns>One outcome per requested tag path, in request order.</returns>
|
|
Task<IReadOnlyList<MxSubscribeOutcome>> SubscribeBulkAsync(
|
|
IReadOnlyList<string> tagPaths, CancellationToken ct = default);
|
|
|
|
/// <summary>UnAdvise + RemoveItem for many subscription ids in one gateway command.</summary>
|
|
/// <param name="subscriptionIds">Subscription ids previously returned by a subscribe call.</param>
|
|
/// <param name="ct">Cancellation token.</param>
|
|
/// <returns>A task that represents the asynchronous operation.</returns>
|
|
Task UnsubscribeBulkAsync(IReadOnlyList<string> subscriptionIds, CancellationToken ct = default);
|
|
|
|
/// <summary>Snapshot read of one or more tags (ReadBulk).</summary>
|
|
/// <param name="tagPaths">Tag addresses to read.</param>
|
|
/// <param name="ct">Cancellation token.</param>
|
|
/// <returns>A task that resolves to one outcome per requested tag path.</returns>
|
|
Task<IReadOnlyList<MxReadOutcome>> ReadAsync(IReadOnlyList<string> tagPaths, CancellationToken ct = default);
|
|
|
|
/// <summary>Write one or more tag/value pairs (WriteBulk with the configured WriteUserId).</summary>
|
|
/// <param name="writes">Tag/value pairs to write.</param>
|
|
/// <param name="ct">Cancellation token.</param>
|
|
/// <returns>A task that resolves to one outcome per requested write.</returns>
|
|
Task<IReadOnlyList<MxWriteOutcome>> WriteAsync(IReadOnlyList<(string TagPath, object? Value)> writes, CancellationToken ct = default);
|
|
|
|
/// <summary>One Galaxy browse level (BrowseChildren). <paramref name="parentNodeId"/> null → root.</summary>
|
|
/// <param name="parentNodeId">Parent node id (Galaxy contained path), or null for root.</param>
|
|
/// <param name="ct">Cancellation token.</param>
|
|
/// <returns>A task that resolves to the child nodes and a flag indicating whether the result was truncated.</returns>
|
|
Task<(IReadOnlyList<MxBrowseChild> Children, bool Truncated)> BrowseChildrenAsync(string? parentNodeId, CancellationToken ct = default);
|
|
|
|
/// <summary>
|
|
/// Long-running event consumer. Invokes <paramref name="onUpdate"/> 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.
|
|
/// </summary>
|
|
/// <param name="onUpdate">Callback invoked per advised-tag value change.</param>
|
|
/// <param name="ct">Cancellation token; ends the loop when cancelled.</param>
|
|
/// <returns>A task that represents the asynchronous operation.</returns>
|
|
Task RunEventLoopAsync(Action<MxValueUpdate> onUpdate, CancellationToken ct = default);
|
|
|
|
/// <summary>
|
|
/// 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 <paramref name="ct"/> is cancelled.
|
|
/// </summary>
|
|
/// <param name="alarmFilterPrefix">Optional source-reference prefix to scope the feed; null = gateway-wide.</param>
|
|
/// <param name="onTransition">Callback invoked per native alarm transition.</param>
|
|
/// <param name="ct">Cancellation token; ends the loop when cancelled.</param>
|
|
/// <returns>A task that represents the asynchronous operation.</returns>
|
|
Task RunAlarmStreamAsync(string? alarmFilterPrefix, Action<NativeAlarmTransition> onTransition, CancellationToken ct = default);
|
|
}
|
|
|
|
/// <summary>Builds <see cref="IMxGatewayClient"/> instances.</summary>
|
|
public interface IMxGatewayClientFactory
|
|
{
|
|
/// <summary>Creates a new, unconnected client instance.</summary>
|
|
/// <returns>A new <see cref="IMxGatewayClient"/> ready to be connected.</returns>
|
|
IMxGatewayClient Create();
|
|
}
|