133 lines
6.9 KiB
Markdown
133 lines
6.9 KiB
Markdown
# ProdDash Alerts
|
|||
|
|
|
||
|
|
A module that sees something a tech must act on *now* — a timer overrun,
|
||
|
|
a meter past its limit, timecode gone — raises an **alert**, and every
|
||
|
|
dashboard listening to its channel flashes until it is over. This page is
|
||
|
|
the whole feature: what an operator sees and sets, and what a module does
|
||
|
|
to raise one. The module-side contract also lives in the
|
||
|
|
[Module Guide](MODULE-GUIDE.md#raising-alerts), which is the authority on
|
||
|
|
how modules are written.
|
||
|
|
|
||
|
|
## What an alert looks like
|
||
|
|
|
||
|
|
On a dashboard that listens to the alert's channel:
|
||
|
|
|
||
|
|
- The **menu bar** flashes between two colours, with the alert's text in
|
||
|
|
bold across its middle (and a small boxed number saying which channel it
|
||
|
|
came on). If the bar was hidden — by its notch, or because the screen is
|
||
|
|
in fullscreen — it comes out for the alert and goes back when it ends.
|
||
|
|
- A **frame round the whole screen** flashes with it, so a fullscreen wall
|
||
|
|
where the bar is the only chrome still carries the flash to its edges.
|
||
|
|
- For **low** and **medium**, that is all: the tiles and the board they sit
|
||
|
|
on are left alone. A **critical** alert floods the **board behind the
|
||
|
|
tiles** as well — in a muted cut of its two colours, mixed well toward the
|
||
|
|
page background and showing faintly through the tiles' own panels — so
|
||
|
|
the flash reaches the middle of a screen the tiles cover entirely, while
|
||
|
|
everything written on a tile keeps its contrast. A module's content is
|
||
|
|
never recoloured.
|
||
|
|
|
||
|
|
The **level** sets the cadence. The two colours each level flashes between
|
||
|
|
are the admin's choice (below).
|
||
|
|
|
||
|
|
| Level | Cadence | For |
|
||
|
|
| --- | --- | --- |
|
||
|
|
| **Low** | a slow fade between the two colours, about three seconds a cycle; bar and frame only | something to know about |
|
||
|
|
| **Medium** | a faster fade, about one second a cycle; bar and frame only | something to deal with soon |
|
||
|
|
| **Critical** | no fade — the colours snap, twice a second; bar, frame and the board behind the tiles | something to deal with now |
|
||
|
|
|
||
|
|
When several alerts a dashboard listens to are on at once, the bar shows
|
||
|
|
the most severe (the newest among equals) and a **+1** says how many more
|
||
|
|
there are.
|
||
|
|
|
||
|
|
## Channels
|
||
|
|
|
||
|
|
There are **six channels**, numbered 1 to 6, and nothing else: a channel
|
||
|
|
carries no meaning of its own. A booth gives them meaning — "1 is the
|
||
|
|
stage, 2 is video, 3 is the lobby" — by pointing modules at them (a module
|
||
|
|
that raises alerts makes its channel an admin setting) and by choosing
|
||
|
|
which channels each dashboard listens to.
|
||
|
|
|
||
|
|
**Choosing channels:** on the dashboard, open the Layouts menu (the grid
|
||
|
|
icon) and the **Alerts** row — it says which channels this screen listens
|
||
|
|
to and opens to six numbered buttons that toggle them. The choice is part
|
||
|
|
of the arrangement, like the grid size and auto-hide: it saves with this
|
||
|
|
browser's layout and with a named layout on the server, so a booth that
|
||
|
|
loads its "Stage" layout gets the stage's channels with it. A fresh
|
||
|
|
dashboard listens to nothing.
|
||
|
|
|
||
|
|
## One alert per channel
|
||
|
|
|
||
|
|
A channel shows one alert at a time. A new alert on a channel replaces
|
||
|
|
whatever was on it, whoever raised it; clearing a channel ends whatever is
|
||
|
|
on it. Two modules pointed at one channel will talk over each other — give
|
||
|
|
them channels of their own.
|
||
|
|
|
||
|
|
An alert ends when its **duration** runs out (1 to 600 seconds; 15 when the
|
||
|
|
module gives none), or when the module that raised it clears it early, or
|
||
|
|
when that module stops (a disable, an uninstall, a config save that re-inits
|
||
|
|
it): a module's alerts never outlive it. A module may hold an alert **until
|
||
|
|
cleared** (duration 0) for a condition it will notice ending — timecode
|
||
|
|
lost, a feed down — and clear it when the condition does.
|
||
|
|
|
||
|
|
## Admin → Alerts
|
||
|
|
|
||
|
|
The admin page's **Alerts** section (folded by default, near the bottom)
|
||
|
|
holds two colour pickers per level — the two colours that level flashes
|
||
|
|
between — with a swatch beside each row running that level's cadence, so a
|
||
|
|
pair can be judged before it is tried. A change saves when the picker
|
||
|
|
closes and reaches every open dashboard at once. The row below sends a
|
||
|
|
**test alert** of any level on any channel: eight seconds of whatever the
|
||
|
|
dashboards listening to that channel will see.
|
||
|
|
|
||
|
|
The colours are kept as `alerts.colors` in the data directory's
|
||
|
|
`proddash.json` (see the README's *Where settings are kept*); they hold
|
||
|
|
across restarts and updates. The defaults are a blue pair for low, amber
|
||
|
|
for medium and red against near-black for critical.
|
||
|
|
|
||
|
|
## For module authors
|
||
|
|
|
||
|
|
Raise from the server entry, which is where a condition is usually noticed
|
||
|
|
— `shell.alert({ channel, level, text, duration })` and
|
||
|
|
`shell.clearAlert(channel)` on the `shell` object `init()`, `routes()` and
|
||
|
|
`tiles()` receive — or from a tile with `moduleApi.alert(...)` and
|
||
|
|
`moduleApi.clearAlert(...)`, which go through the server. The fields, what
|
||
|
|
each is for, and the rules that keep alerts worth looking at (raise on the
|
||
|
|
transition, make it a setting, it is not a status) are in the
|
||
|
|
[Module Guide](MODULE-GUIDE.md#raising-alerts).
|
||
|
|
|
||
|
|
## The HTTP API
|
||
|
|
|
||
|
|
Everything above rides on three public routes and two admin ones. They are
|
||
|
|
open to anything that can reach ProdDash, like a module's own routes:
|
||
|
|
an alert is a flash on screens in this building and nothing more.
|
||
|
|
|
||
|
|
| Route | Does |
|
||
|
|
| --- | --- |
|
||
|
|
| `GET /api/alerts` | `{ channels: 6, levels, colors: { low: [a, b], … }, active: [ … ] }` — what is flashing and the colours. Dashboards read it on load and whenever their stream reconnects. |
|
||
|
|
| `POST /api/alerts` | `{ channel, level, text, duration?, source? }` as `application/json`. Answers `200 { ok, alert }` or `400 { error }` saying what was wrong. `source` is the module id (anything else is recorded as `api`). |
|
||
|
|
| `DELETE /api/alerts/<channel>` | Ends the alert on that channel. `{ ok, cleared }` — `cleared` is false when nothing was on it. |
|
||
|
|
| `POST /api/admin/alerts` | `{ colors: { low: [a, b], medium: [a, b], critical: [a, b] } }` — a missing or malformed colour takes its default. Behind the admin PIN. |
|
||
|
|
| `POST /api/admin/alerts/test` | `{ level, channel }` — an eight-second test alert. Behind the admin PIN. |
|
||
|
|
|
||
|
|
Open dashboards learn of changes over the shell stream (`/api/events`):
|
||
|
|
`alert` carries an alert as raised (`{ id, channel, level, text, source,
|
||
|
|
startedAt, duration, endsAt, remainingMs }` — a browser counts down from
|
||
|
|
`remainingMs`, so the clocks need not agree), `alert-clear` carries
|
||
|
|
`{ channel, id }` when one ends, and `alerts-config` carries `{ colors }`
|
||
|
|
when the admin changes them.
|
||
|
|
|
||
|
|
## Trying it
|
||
|
|
|
||
|
|
With ProdDash running, from the repo:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
node tools/alert.js -c 1 -l critical "LTC lost"
|
||
|
|
```
|
||
|
|
|
||
|
|
raises a critical alert on channel 1 for the default 15 seconds; `-d 0`
|
||
|
|
holds it, `node tools/alert.js -c 1 --clear` ends it, `--list` shows what
|
||
|
|
is on. Open a dashboard, choose channel 1 in its Layouts menu → Alerts, and
|
||
|
|
watch; a second browser listening to channel 2 should stay quiet. The admin
|
||
|
|
page's **Test** buttons do the same from the browser.
|
||
|
|
`node tools/alerts.test.js` runs the server's side of all this end to end.
|