Events

The station's record of what happened: durable alarm, occurrence and interlock timelines beside the live diagnostics console, with search, filters and CSV/JSON export.

View as Markdown

Events is the page that answers "what happened?". It sits in the foot group of the navigation rail (Validation, Events, Agent, Settings, Account) and holds four tabs: Alarms, Occurrences and Interlocks are durable timelines read from the station's event journal, and Console is the live diagnostic feed every subsystem writes into. The page header reads "Persistent alarm, occurrence and interlock histories, and the live diagnostics console."

Seeing the page takes the View events permission (System area): both the rail entry and the /events address gate on it. Every factory role holds it by default, "Not signed in" included, and Admin always does; a role created blank starts without it, and an administrator can remove it from any non-admin role. Exporting from any tab takes Export/import histories in addition.

The tabs and their addresses

Tab What it lists Address Page
Alarms The alarms waiting now, over the durable timeline of alarm state transitions /events?view=alarms Alarms
Occurrences Every occurrence edge observed during a run or by the outside-run Always watcher /events?view=occurrences Occurrences
Interlocks Every transition of a unit's stop-interlock latch /events?view=interlocks Interlocks
Console The last 500 diagnostic entries of the running program /events?view=console Console

The page opens on Alarms. Clicking a tab rewrites the address (replacing it, so the tab strip never fills the browser's back stack), and a link that carries view= lands on that tab; a value the page does not know leaves it opening on Alarms. This is how the status bar's alarm indicator (the bell with "N active (M unacked)", drawn only while an alarm is active or waiting for an acknowledgement) reaches the alarm list: it navigates to /events?view=alarms, the screen where what it is counting is both read and answered, never the Logic page where alarms are configured.

Console stays mounted behind the other tabs, so its follow-tail state and scroll position survive a switch; each of the three timelines keeps its own search, filter, rows and selection while you move between them.

Who can see and export

Permission What it opens on this page Without it
View events The rail entry, the address and every tab The entry is not drawn and the address is refused
Export/import histories Export on every tab (CSV, JSON) and Create support package on Console The Export button is not drawn; a press that reaches the handler anyway answers "Exporting events needs the Export/import histories permission." in the action feed
Operate logic Ack and Acknowledge all on the Alarms tab The verbs are not drawn; the rows stay readable
Change settings Start capture and Stop capture on Console The button is not drawn; the capture state is still announced to screen readers

The permissions are decided per connection, so a browser circuit signed in as another user sees its own set of buttons, and a sign-in, sign-out or role edit redraws them at once. The catalog is on Permissions.

How the three timelines behave

The Alarms, Occurrences and Interlocks tabs share one conduct, so switching tabs never changes the rules:

Behaviour Detail
Window Each tab lists 500 events per page, the ones matching its search, its filter and the period chosen, newest first (a tie on the timestamp is broken by insertion order). Under the list, Newer and Older walk the rest of the journal a page at a time, and the band is drawn only while there is another page to reach. The newest page follows the journal live; a page behind it stands still, so an event arriving now cannot push what you are reading down.
Date range Two date boxes, From and To, each one end of the period read. An empty box is no bound at all, so leaving both empty reads the whole journal, and the day chosen as the closing bound is included whole, to its last instant. The cross beside them clears the pair and returns the tab to the first page.
Search A text box whose placeholder names the columns it matches (name, message, source, model, unit, procedure, author, depending on the tab). The match is "contains", case-insensitive, applied 250 ms after you stop typing; leading and trailing spaces are ignored.
Level filter One list per tab: Priority on Alarms, Severity on Occurrences, Transition on Interlocks. Changing it re-reads the journal at once.
Refresh The circular-arrow button re-reads the journal on demand; its tooltip names the tab ("Refresh alarm events", "Refresh occurrences", "Refresh interlock events"). It is greyed while a read is running.
Live refresh Every event committed to the journal re-queries the open tab on its own, coalesced so a burst costs one read (about 200 ms after the last commit). A tab you are not looking at is re-read when you return to it.
Selection Clicking a row opens the detail panel on the right. The selection is kept across refreshes by its event id and dropped if the row is not on the page read; the cross in the panel head closes it.
Copy event The button at the foot of the detail panel copies the event as one line of text: full timestamp, kind, level, name, the transition summary, the message and, for occurrences and interlocks, the identities. The action feed answers "Event copied to clipboard.", or "The clipboard refused the copy." when the browser withheld it.
Export Export opens a menu with Export as CSV… and Export as JSON… for every event the search, the filter and the period match, page after page, not only the rows drawn. The button is greyed while the page is empty.
Unfiltered record The journal is not filtered by who is signed in or by what that role may see elsewhere: it is the station's technical record, and a row silently missing would make the history lie.

The list and the detail panel

Every row carries the date and time of the event in the format configured under Localization, a dot in the tone of its level, the event's name, a one-line summary of the transition and, at the right edge, the level's own word (the priority, the severity or the transition). The tones follow one scale on every surface: the critical tone for a Critical alarm, a Critical occurrence or an interlock trip; the caution tone for High, Warning and "Source safe"; the attention tone for Medium; neutral for the rest.

The detail panel opens with the level badge and the name, then the full timestamp with milliseconds, the transition summary, the message (or "No message captured." when the definition had none), an EVENT card with Level and Event ID, and one or more snapshot cards whose fields each tab's page lists.

The status line

Under every timeline: "N shown · page 1", where N counts the rows on the page open, followed by " · filtered" while a search, a level filter or a date range is in force; "N shown · refreshing…" during a re-read; on the right, "1 selected" while a row is selected and "Updated hh:mm:ss", the time of the last successful read.

Loading, empty and failed states

State What the tab shows
First read "Loading alarm events…" with "Reading the newest matching alarm events from the persistent journal." (the noun follows the tab).
Nothing recorded "No alarm events yet" with a line saying what will appear there; each tab's page quotes its own.
Nothing matches "No alarm events match these filters" with "Adjust the priority or search terms to widen this history." (priority, severity or transition, by tab).
The journal cannot be read "Alarms could not be loaded" with "The persistent journal is temporarily unavailable. Console logs are unaffected." and a Try again button; the status line reads "Alarms unavailable".
A later refresh fails The last good rows stay on screen and the action feed reports "Alarms refresh failed."

Exporting a timeline

Both formats are browser downloads, so they work on the station's own window and on a remote browser alike; the action feed answers "Exported N event(s) to" followed by the file name, or "Export failed.". The file name carries the tab and a sortable stamp: alarm-history-20260902-143000.csv, occurrence-history-<stamp>.json, interlock-history-<stamp>.csv.

Every instant is written in the configured display format, and the file declares the time reference once: the CSV names it in the header of its first column, "Timestamp (UTC-03:00)" (or "Timestamp (UTC)"), and the JSON is an envelope with a top-level TimeZone field beside an Events array. Beyond what the row shows, the columns carry the full frozen snapshot, identities included (the event id, the alarm, occurrence or observation ids, the model and unit ids), so an exported timeline can be correlated with run files and reports. A CSV cell that begins with =, +, - or @ is prefixed with an apostrophe so a spreadsheet opens it as text rather than as a formula. Each tab's page lists its columns.

What the journal keeps

The three timelines live in events.db, a database of its own in the station's data folder beside config.db and history-index.db, with one append-only table per timeline. What is written is a snapshot taken at the instant of the event (names, priority, message, model, unit, source, the observed value), so renaming, editing or deleting the definition afterwards never rewrites what the station told you at the time. Nothing on this page, or anywhere else in the app, deletes a row: retention keeps the newest 100,000 rows per timeline, pruning the oldest by insertion order with each append, so a corrected clock cannot evict a fresh event.

The journal survives a restart and a configuration restore: a backup copies the configuration database and the asset folder only, so restoring one neither carries the journal along nor rolls it back. It is a record of transitions, not of state: after a restart the alarm registry re-derives every alarm from the first sweep, acknowledgements that were pending are lost, and the timeline simply shows what happened before and after.

Events reach the journal through an ordered queue that never blocks the runtime: the producer takes the snapshot immediately, a single writer commits in arrival order, and a commit that keeps failing is retried up to ten times before the event is dropped with an Error line in Console. An occurrence observed during a run is written to that run's own file first (the source Histories and reports read) and then copied into the journal with the same event id and the run context; an observation made outside a run by an Always occurrence goes to the journal only. Interlock and alarm transitions have no record other than the journal. An agent with the Logs area open reads the same journal through event_history_read, read-only (see Allowed areas).

The console beside the record

Console is a different thing from the three timelines: a rolling 500-entry view of the program's diagnostic stream, in memory, lost at restart and emptied by Clear view. The two overlap where the runtime narrates what it is doing. An occurrence edge leaves a Console line under the Process area (an activation at the level of its severity: Critical as an error, Warning as a warning, Info as information), and so does an interlock transition (a trip as a warning, a safe source and a rearm as information). Alarm transitions do not appear in Console: the evaluator's trace is diagnostic detail that only a detailed capture records. The timelines are the typed record; Console explains the runtime around it.

What Events does not do

  • It configures nothing. Alarms are defined on Logic > Alarms, occurrences under Process > Setup > Occurrences and the stop interlock under Process > Definition > Automation.
  • It rearms no interlock: that is the Interlock component on a dashboard or the unit's own view.
  • It has no unit or run filter: search by name, or open the run in Histories for its own occurrence record.
  • It deletes nothing and edits nothing; retention alone removes rows.
  • While the runtime is stopped this page is not drawn at all: every screen except Account is replaced by the paused notice, the timelines included. The journal itself is untouched and reads exactly as it did once the runtime is restarted.