docs(DV-6): document Debug View tabbed-tree layout, native placeholders, and new AlarmStateChanged fields
- Component-CentralUI.md: replace flat-table Debug View section with tabbed tree layout (Attributes + Alarms tabs, TreeView<TItem> reuse, hierarchy from canonical names, branch roll-up, all-configured-alarms rule, native source binding nodes with quiet-binding placeholder rows, per-leaf rendering detail) - Component-SiteRuntime.md (Instance Actor Wiring): add idle-binding placeholder emission via BuildAlarmStatesSnapshot(), _nativeAlarmKinds map, and NativeSourceCanonicalName stamping on live native events - Component-SiteRuntime.md (Enriched AlarmStateChanged): document two new additive fields — NativeSourceCanonicalName (string?) and IsConfiguredPlaceholder (bool) — plus their gRPC proto fields 22/23 and StreamRelayActor/SiteStreamGrpcClient pack/unpack - Component-Commons.md (Attribute Stream DTOs): extend AlarmStateChanged bullet with the same two additive fields and proto field numbers
This commit is contained in:
@@ -136,20 +136,38 @@ Central cluster only. Sites have no user interface.
|
||||
- Ongoing events (`AttributeValueChanged`, `AlarmStateChanged`) flow via the gRPC stream directly to the bridge actor — they do not pass through ClusterClient.
|
||||
- Events are delivered to the Blazor component via callbacks, which call `InvokeAsync(StateHasChanged)` to push UI updates through the built-in SignalR circuit.
|
||||
- A pulsing "Live" indicator replaces the static "Connected" badge when streaming is active.
|
||||
- Stream includes attribute values formatted as `[InstanceUniqueName].[AttributePath].[AttributeName]` and alarm states formatted as `[InstanceUniqueName].[AlarmName]`.
|
||||
- Subscribe-on-demand — stream starts when opened, stops when closed.
|
||||
- Read-only per-instance view (one instance per connection); no alarm acknowledgement is available from Debug View.
|
||||
|
||||
#### Alarm Table (Computed + Native)
|
||||
#### Tabbed Layout
|
||||
|
||||
The DebugView alarm table is the **only** runtime surface for native OPC UA Alarms & Conditions and MxAccess Gateway alarms (no dedicated operator/alarm-summary page). Native alarms are a **read-only mirror** of source-reported state — the source system owns the alarm lifecycle (ack / shelve / suppress), so the table never offers ack-back or any command action. Both enriched `AlarmStateChanged` events (live, via the gRPC stream) and the initial `DebugViewSnapshot` (via ClusterClient) carry the unified alarm shape, so native alarms appear on the first paint and update in place. The table is a custom Blazor + Bootstrap component (no third-party grid).
|
||||
The Debug View page uses a **two-tab layout** — an **Attributes** tab and an **Alarms** tab — replacing the earlier side-by-side flat tables. Each tab renders its data as a **collapsible hierarchy tree** using the existing generic `TreeView<TItem>` component.
|
||||
|
||||
- **Kind column** — a badge distinguishing **Computed** alarms from native ones (an **OPC UA** or **MxAccess** badge), driven by the event's `AlarmKind` discriminator.
|
||||
- **Sev column** — the unified **0–1000 severity** (`AlarmConditionState.Severity`) shown for every row. Computed rows surface their integer priority on the same scale.
|
||||
- **Source reference subtitle** — for native rows, the `SourceReference` (e.g. `Tank01.Level.HiHi`) renders as a **monospace subtitle under the alarm name**. Computed rows have no subtitle and render exactly as before this change.
|
||||
- **State cell composite badges** — the orthogonal condition sub-states roll up into badges shown beside the active/normal state: **Unacked**, **Shelved**, and **Suppressed** appear only when the corresponding `AlarmConditionState` flag is set. Computed alarms are auto-acked and never shelved/suppressed, so they show none of these.
|
||||
- **Row tooltip** — hovering a row surfaces the native metadata that does not warrant its own column: alarm type (`AlarmTypeName`), category, operator user and comment (source-supplied ack metadata, display-only), original raise time, and the current/limit value.
|
||||
- **Filter** — the existing alarm filter additionally matches the native `SourceReference` (in addition to the alarm name), so operators can find a mirrored condition by its source path.
|
||||
- **Computed alarms render unchanged** — no Kind badge styling change, no subtitle, no new state badges beyond what the unified model implies; the enrichment is purely additive for native rows.
|
||||
**Tree hierarchy** — the hierarchy is derived from the path-qualified canonical names already present in the debug snapshot (e.g. `Motor1.Compressor.Pump`). The instance is the root node; composed modules are collapsible branch nodes; individual attributes (Attributes tab) or alarms/native-source bindings (Alarms tab) are leaf nodes.
|
||||
|
||||
**Branch-level status roll-up** — a collapsed branch shows a summary badge so the operator can assess health without expanding:
|
||||
- *Alarms tab*: worst alarm state among descendants + count of active conditions.
|
||||
- *Attributes tab*: a bad/uncertain-quality indicator when any descendant attribute has non-Good quality.
|
||||
|
||||
#### Attributes Tab
|
||||
|
||||
Displays all attribute values for the instance in the collapsible tree. Each leaf shows the attribute value, quality, and timestamp. The existing `[InstanceUniqueName].[AttributePath].[AttributeName]` canonical path is the basis for the tree structure.
|
||||
|
||||
#### Alarms Tab (Computed + Native)
|
||||
|
||||
The Alarms tab is the **only** runtime surface for native OPC UA Alarms & Conditions and MxAccess Gateway alarms (no dedicated operator/alarm-summary page). **All configured alarms are shown with current status, even when quiet/Normal** — no alarm is hidden simply because it has not fired.
|
||||
|
||||
Both enriched `AlarmStateChanged` events (live, via the gRPC stream) and the initial `DebugViewSnapshot` (via ClusterClient) carry the unified alarm shape, so all alarms appear on the first paint and update in place. Native alarms are a **read-only mirror** — the source system owns the alarm lifecycle (ack / shelve / suppress); the Debug View never offers ack-back or any command action.
|
||||
|
||||
**Native source binding nodes** — a configured native alarm source binding is itself a tree node, placed by its canonical name in the hierarchy. Its live mirrored conditions nest as child rows beneath it. A quiet binding (no currently active conditions) renders a "no active conditions" placeholder row — it is never hidden, so the operator can see every configured binding regardless of alarm state. This requires the backend to emit a placeholder `AlarmStateChanged` with `IsConfiguredPlaceholder = true` for each idle binding (see Component-SiteRuntime.md — Instance Actor Wiring). The `NativeSourceCanonicalName` field on `AlarmStateChanged` events identifies which binding node a live condition belongs to.
|
||||
|
||||
Per-leaf alarm rendering (leaf nodes are individual conditions for native alarms, and the alarm itself for computed alarms):
|
||||
- **Kind badge** — distinguishes **Computed** alarms from native ones (**OPC UA** or **MxAccess**), driven by the event's `AlarmKind` discriminator.
|
||||
- **Sev** — the unified **0–1000 severity** (`AlarmConditionState.Severity`). Computed rows surface their integer priority on the same scale.
|
||||
- **Source reference subtitle** — for native rows, the `SourceReference` (e.g. `Tank01.Level.HiHi`) renders as a monospace subtitle. Computed rows have no subtitle.
|
||||
- **State badges** — orthogonal condition sub-states: **Unacked**, **Shelved**, and **Suppressed** appear only when the corresponding `AlarmConditionState` flag is set. Computed alarms are auto-acked and never shelved/suppressed.
|
||||
- **Row tooltip** — surfaces native metadata not warranting its own column: `AlarmTypeName`, category, operator user and comment, original raise time, current/limit value.
|
||||
- **Computed alarms render unchanged** from the prior flat-table style; the enrichment is purely additive for native rows.
|
||||
|
||||
### Parked Message Management (Deployment Role)
|
||||
- Query sites for parked messages (external system calls, cached DB writes). (Parked notifications are managed centrally on the Notification Outbox page, not here.)
|
||||
|
||||
Reference in New Issue
Block a user