feat(centralui): operator Alarm Summary page + per-instance snapshot fan-out (T13)
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Messages.DebugView;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Streaming;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Read-only operator service that aggregates the current alarm picture across
|
||||
/// all Enabled instances of a single site (M7 T13 — Operator Alarm Summary).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// There is no central alarm store. The summary is assembled at query time by
|
||||
/// fanning out one <see cref="DebugViewSnapshot"/> request per Enabled instance
|
||||
/// (via the injected <see cref="IInstanceSnapshotClient"/>, which delegates to
|
||||
/// the existing single-shot
|
||||
/// <see cref="ZB.MOM.WW.ScadaBridge.Communication.CommunicationService.RequestDebugSnapshotAsync"/>
|
||||
/// Ask) and flattening every snapshot's <see cref="DebugViewSnapshot.AlarmStates"/>
|
||||
/// into <see cref="AlarmSummaryRow"/>s. The fan-out is best-effort: an instance
|
||||
/// whose snapshot fetch throws, times out, or reports
|
||||
/// <see cref="DebugViewSnapshot.InstanceNotFound"/> is recorded in
|
||||
/// <see cref="AlarmSummaryResult.NotReportingInstances"/> and never aborts the
|
||||
/// whole call.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The page is read-only — there are no ack / shelve / write operations. All
|
||||
/// filtering and roll-up math happens client-side from the returned rows.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public interface IAlarmSummaryService
|
||||
{
|
||||
/// <summary>
|
||||
/// Fetches and aggregates the current alarms across every Enabled instance of
|
||||
/// the given site.
|
||||
/// </summary>
|
||||
/// <param name="siteId">The site primary key.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="AlarmSummaryResult"/> with one <see cref="AlarmSummaryRow"/>
|
||||
/// per active/mirrored alarm condition plus the unique names of any instances
|
||||
/// whose snapshot could not be obtained.
|
||||
/// </returns>
|
||||
Task<AlarmSummaryResult> GetSiteAlarmsAsync(int siteId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Pure roll-up over a set of <see cref="AlarmSummaryRow"/>s. Exposed so the
|
||||
/// page (and tests) can recompute the headline tiles without re-querying.
|
||||
/// </summary>
|
||||
/// <param name="rows">The alarm rows to summarize.</param>
|
||||
/// <returns>The aggregated roll-up.</returns>
|
||||
AlarmRollup ComputeRollup(IReadOnlyList<AlarmSummaryRow> rows);
|
||||
}
|
||||
|
||||
/// <summary>The result of a site alarm-summary query.</summary>
|
||||
/// <param name="Alarms">One row per alarm condition reported across the site's Enabled instances.</param>
|
||||
/// <param name="NotReportingInstances">
|
||||
/// Unique names of Enabled instances whose snapshot could not be obtained
|
||||
/// (fetch threw, timed out, or returned <see cref="DebugViewSnapshot.InstanceNotFound"/>).
|
||||
/// </param>
|
||||
public sealed record AlarmSummaryResult(
|
||||
IReadOnlyList<AlarmSummaryRow> Alarms,
|
||||
IReadOnlyList<string> NotReportingInstances);
|
||||
|
||||
/// <summary>
|
||||
/// One alarm condition paired with the instance it belongs to. The
|
||||
/// <see cref="AlarmStateChanged"/> carries everything the
|
||||
/// <c>AlarmStateBadges</c> component needs to render.
|
||||
/// </summary>
|
||||
/// <param name="InstanceUniqueName">Unique name of the owning instance.</param>
|
||||
/// <param name="Alarm">The alarm condition (state / kind / severity / level / native sub-state).</param>
|
||||
public sealed record AlarmSummaryRow(
|
||||
string InstanceUniqueName,
|
||||
AlarmStateChanged Alarm);
|
||||
|
||||
/// <summary>
|
||||
/// Pure point-in-time roll-up over a set of <see cref="AlarmSummaryRow"/>s.
|
||||
/// </summary>
|
||||
/// <param name="TotalActive">Count of rows whose <see cref="AlarmStateChanged.State"/> is <see cref="AlarmState.Active"/>.</param>
|
||||
/// <param name="WorstSeverity">Highest <see cref="Commons.Types.Alarms.AlarmConditionState.Severity"/> among active rows; 0 when none active.</param>
|
||||
/// <param name="UnackedCount">Active, unacknowledged native conditions (<c>Kind != Computed</c>).</param>
|
||||
/// <param name="CountsByKind">Per-<see cref="AlarmKind"/> row counts (only kinds with at least one row appear).</param>
|
||||
public sealed record AlarmRollup(
|
||||
int TotalActive,
|
||||
int WorstSeverity,
|
||||
int UnackedCount,
|
||||
IReadOnlyDictionary<AlarmKind, int> CountsByKind);
|
||||
Reference in New Issue
Block a user