Files
BAT/dist/INSTALL.md
2026-09-15 13:06:45 -05:00

130 lines
5.8 KiB
Markdown

# Alarm Dashboard — install guide
A single Perspective dashboard that scores an alarm system against ISA-18.2 metrics
(rate, flood, chattering, standing, priority mix) and shows what to fix first.
Ships as one file: `AlarmDashboard.zip` (a standard Ignition project export).
## Requirements
- Ignition **8.3** or later, with the **Perspective** module.
- An **alarm journal** profile that stores events (Config → Alarming → Journal).
Any name, any datasource, any table prefix.
- Nothing else. No third-party modules, no extra database, no tags, no scripts to
install on the gateway, no images to copy.
## Install
1. Gateway web UI → **Config → Projects → Import Project** (or Designer →
**File → Import Project**), choose `AlarmDashboard.zip`.
2. Name the project anything you like — the project name is not referenced
internally, so `AlarmDashboard`, `PlantAlarms`, or a site code all work.
3. Open the dashboard: `http://<gateway>:8088/data/perspective/client/<ProjectName>`
That is the whole install on a gateway with one alarm journal.
## If the gateway has more than one alarm journal
Ignition rejects a journal query that does not name a profile when several exist
(`IllegalArgumentException: No alarm journal profile specified`), so the dashboard
must be told which journal to read. The dashboard will show this in its header
error chip, naming the fix.
Designer → **Project Library → AlarmDashboard → alarms**, set the constant at the
top of the script to the profile name from Config → Alarming → Journal:
```python
JOURNAL_NAME = "PlantJournal" # "" = single-journal gateway, let the gateway resolve it
```
Save the project. This is the **only** install-time setting in the whole project.
## Area grouping — match the site's tag structure
Every per-area metric (Areas tab, the area filter, a flood's "top area", per-area bad
actors) groups on **one folder of the alarm's tag path**. Two settings at the top of
Project Library → `AlarmDashboard``calc` control it.
`AREA_SEGMENT` picks which folder, counting from the top of the tag path:
```
prov:FW:/tag:PS/EAS/PMP1/Alarms/Change-of-State:/alm:active
│ │
│ └─ AREA_SEGMENT = 1 -> "EAS" (the individual site)
└──── AREA_SEGMENT = 0 -> "PS" (the site type) <- default
```
`AREA_NAMES` maps the raw folder to the name shown in the UI. **Several codes mapping
to the same name are summed into one area** — that is how the pump station variants
roll up:
```python
AREA_SEGMENT = 0
AREA_NAMES = {
"EST": "Elevated Storage Tank",
"PS": "Pump Station",
"PSR": "Pump Station", # rolls up
"PSR2": "Pump Station", # rolls up
"PSR_STP": "Pump Station", # rolls up
"LS": "Sewage Lift Station",
"VS": "Valve Site",
"FWC": "Customer Cities - Fresh Water",
"WWC": "Customer Cities - Waste Water",
}
```
Folders not listed appear exactly as they are in the tag path, so a new site type shows
up as its raw code rather than vanishing — add it to `AREA_NAMES` when you see it. A tag
path with fewer folders than `AREA_SEGMENT` falls back to its first folder.
### What the Source / Alarm columns show
The alarm identity in every Source column (Bad Actors, Pareto) and the Journal's Alarm
column is **the rest of the path after the area folder**, so two sites running the same
alarm are distinguishable:
```
prov:FW:/tag:PS/EAS/PMP1/Alarms/Change-of-State:/alm:active
└─ area: Pump Station
└──────────────────────────────────── Source: EAS/PMP1/Alarms/Change-of-State/active
```
`AREA_SEGMENT` drives this too — the label always starts one folder after the area. If an
alarm has a **Display Path** configured, that is used verbatim instead, which is the way
to override any of this per alarm. The raw journal source string is preserved untouched
behind the scenes as the drill-down key, so click-through to source detail is unaffected.
## Settings worth checking on the customer's journal
- **Minimum priority** should be `Diagnostic` (store everything). If the journal
drops low-priority events, the ISA 80/15/5 priority-mix score reads as badly
skewed toward high-priority alarms through no fault of the site.
- **Journal retention**: the dashboard's range presets go out to 7 days, so keep at
least that much history for the trend and comparison ("vs previous period") views.
## What the dashboard reads, and what it never touches
Reads, through the alarm API only:
- `system.alarm.queryJournal` — all history, KPIs, trends, bad actors, journal table
- `system.alarm.queryStatus` — currently active / unacked / standing alarms
- `system.alarm.getShelvedPaths` — shelved count
It issues **no SQL**, holds **no datasource reference**, reads **no tags**, and needs
no `system.db.*` access — so it cannot be broken by a schema, table-prefix, or
tag-provider difference between sites. Plant areas are derived from the alarm's
source path, so they follow whatever tag folder structure the site already uses.
## Verified before release
- Imports via the gateway API onto a project name it has never used, starts with no
errors, and serves its Perspective client (HTTP 200).
- Strict project lint: 0 failures, 0 warnings (22 views, 32 style classes).
- Data layer verified live against a real journal: bundle computed with no error,
full KPI/health output, all plant areas resolved.
- Multi-journal behavior tested on a gateway with two journal profiles: unnamed
query fails as documented above, and setting `JOURNAL_NAME` restores full data.
- Export scanned for environment coupling: no company branding, no datasource names,
no tag paths, no absolute paths, no host addresses, no gateway image references.