Files
BAT/ignition/gateway/projects/alarm-analysis/README.md
2026-09-15 13:06:45 -05:00

119 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Alarm Analysis Dashboard
A drop-in Ignition Perspective dashboard that turns the **alarm journal** into
actionable alarm-management metrics: alarm rate, MTTA/MTTR, flood episodes,
chattering and standing alarms, a Pareto of bad actors, a day/hour heatmap, and
an overall alarm-health score graded AF against ISA-18.2 style targets.
It reads the journal through `system.alarm.queryJournal` / `system.alarm.queryStatus`
only. There are **no tags, no named queries, no SQL and no database connection**
if the gateway has an alarm journal profile with data in it, the dashboard works.
---
## Requirements
* Ignition **8.1.20+** with the **Perspective** module.
* An **alarm journal profile** that is receiving data (Gateway → Config → Alarming →
Journal). Any journal store works; the resource never talks to the database directly.
* No third-party modules, no Python packages, no gateway scripting configuration.
## Install
1. In the Designer, open the project you want the resource in and choose
**File → Import…**, or use **Config → Projects → Import** on the Gateway
web page to bring the download in as its own project.
2. Import the resource. Everything lands under namespaced folders, so nothing in
an existing project is overwritten:
| Resource | Location |
|---|---|
| Views | `Exchange/AlarmAnalysis/…` |
| Style classes | `exchange/alarm-analysis/…` |
| Project library | `exchange/alarmAnalysis/{alarms, calc, fmt}` |
| Page | `/alarm-analysis``Exchange/AlarmAnalysis/Dashboard` |
3. **Save** the project.
4. Open a Perspective session and browse to **`/alarm-analysis`**.
That is the whole installation. The dashboard holds all of its own state on the
`Dashboard` view, so importing it does **not** add session custom properties,
client tags or global variables to your project.
### If you imported into an existing project
* The page URL `/alarm-analysis` is added to your project's page configuration.
If that URL is already taken, change it in **Project Browser → Perspective →
Page Configuration**; the view path it should point at is
`Exchange/AlarmAnalysis/Dashboard`.
* Nothing else in your project is touched — every resource is namespaced.
### If you want it on its own page shell
Embed `Exchange/AlarmAnalysis/Dashboard` in any view or dock. It takes no
parameters and sizes itself to its container (design size 1600×900).
## Using it
| Tab | What it shows |
|---|---|
| **Overview** | Headline KPIs vs the previous equal-length period, alarm-rate chart, priority mix, top sources, and plain-language insights. |
| **Analysis** | Day/hour heatmap, flood episodes, MTTA/MTTR trend, and priority distribution against the ISA 80/15/5 target. |
| **Bad Actors** | Pareto of the worst offenders plus chattering, standing and fleeting alarm tables. Click a row for the per-source drill-down. |
| **Journal** | Paged, filtered journal browser with CSV export and a per-event detail popup. |
* The **range selector** and **Refresh** in the header set the analysis window.
* The **filter bar** (Priority / Area / State / Search) applies to every tab except
Overview, which deliberately stays a plant-wide summary.
* **Shift Report** renders a plain-text handover summary for the previous shift,
ready to copy into a log.
* Clicking a source anywhere drills through to that source in **Bad Actors**;
clicking a Bad Actors row opens the per-source history popup.
## Tuning
All thresholds live in one place — `exchange.alarmAnalysis.calc.DEFAULTS`:
| Key | Default | Meaning |
|---|---|---|
| `target_per_hr` | `6.0` | ISA target alarm rate per operator per hour |
| `flood_per_10min` | `10` | Activations per 10 min that start a flood episode |
| `chatter_per_hr` | `10.0` | Re-triggers per hour that mark a source as chattering |
| `chatter_gap_s` | `120` | Median gap below which re-triggers count as chatter |
| `fleeting_s` | `10` | Active duration below which an alarm counts as fleeting |
| `standing_hours` | `24` | Age above which an active alarm counts as standing |
| `priority_target` | `80/15/5` | ISA low/medium/high priority mix |
| `health_weights` | see source | Weighting of the five health sub-scores |
| `max_events` | `50000` | Hard cap on journal rows read per query |
Edit the dict in the Designer's script library, or pass an override dict as the
`opts` argument of any `calc` function.
## Script library
| Module | Responsibility |
|---|---|
| `exchange.alarmAnalysis.alarms` | Talks to `system.alarm`; the only module that does I/O. Entry points used by the views: `getDashboardBundle`, `getJournalPage`, `journalCsv`, `getSourceDetail`, `getEventData`, `getShiftReportText`. |
| `exchange.alarmAnalysis.calc` | Pure analytics — correlation, binning, floods, chatter, MTTA/MTTR, Pareto, health score. No Ignition API calls, so it is unit-testable. |
| `exchange.alarmAnalysis.fmt` | Display formatting and the natural-language insight/shift-report text. |
Every public function carries a docstring, so the Designer's autocomplete
documents the API.
## Notes and limits
* The journal is queried for **twice** the selected window (current plus the
equal-length prior period) so every KPI can show a delta. A very wide range over
a busy plant is bounded by `max_events`; when that cap is hit the header shows a
*truncated* chip.
* Alarm instances are correlated by journal event id when the journal supplies
one, and by a per-source active/clear state machine otherwise. The mode in use
is reported in `bundle.meta.correlation_mode`.
* "Active now", unacked and shelved counts come from live alarm status, so they
reflect the present moment rather than the selected window.
* Scripts are Jython 2.7 compatible (no f-strings, no `typing`, no `statistics`).
## License
Provided as-is under the terms of the Ignition Exchange.