Alarms Service¶
The Alarms Service (gva-alarms) is the register-side runtime that
converts LRU-reported conditions into platform alarms, keeps the
Alarm Register, and drives crew annunciation. It implements the Def
Stan 23-009 Alarms Service Specification v3.0.
Overview¶
The Alarms Service handles:
- Subscribing to alarm conditions raised by LRUs (subsystems) across the platform
- Converting condition transitions into the platform Alarm state machine
- Persisting the Alarm Register across power cycles
- Publishing the platform alarm category taxonomy (Warning / Caution / Advisory)
- Driving Annunciation LDM events (audio + visual) for crew stations
- Processing operator commands: Acknowledge, Clear, Annotate, Override, Remove Override
- Responding to every command via the Def Stan 23-009 Command Response Protocol (CRP)
The service is a headless daemon backed by PostgreSQL / PostGIS. All inter-process traffic is DDS; every DDS interaction is defined by an IDL contract in the shipped Reference Model.
Roles on the wire¶
Alarm Register)] end subgraph "HMI tier" HMI[gva-hmi] POPUP[Popup +
Annunciation] end LRU1 -->|C_Alarm_Condition| SVC LRU2 -->|C_Alarm_Condition| SVC LRU3 -->|C_Alarm_Condition| SVC LRU1 -.->|"C_Alarm_Condition_Specification
(optional)"| SVC SVC --> DB SVC -->|C_Alarm| HMI SVC -->|C_Alarm_Category_Definition| HMI SVC -->|C_Annunciation_startEvent
C_Annunciation_stopEvent| POPUP HMI -->|C_Alarm_acknowledge
C_Alarm_clearAlarm
C_Alarm_annotate
C_Alarm_Condition_override
C_Alarm_Condition_removeOverride| SVC SVC -->|Command Response| HMI
Ownership:
| Actor | Publishes | Subscribes |
|---|---|---|
| LRU | C_Alarm_Condition, optionally C_Alarm_Condition_Specification |
— |
| Alarms Service | C_Alarm, C_Alarm_Category_Definition, C_Alarm_Condition_Specification (fallback), Annunciation events, CRP responses |
C_Alarm_Condition, C_Alarm_Condition_Specification, the five command topics |
| HMI | The five command topics | C_Alarm, C_Alarm_Category_Definition, Annunciation events |
The alarms service is the sole publisher of C_Alarm. LRUs never
publish alarms directly — they publish conditions.
Alarm categories¶
The platform recognises three alarm categories, matching Def Stan
23-009 Table 3. The alarms service publishes a
C_Alarm_Category_Definition sample for each on startup so consumers
discover the category taxonomy from the wire.
| Category | Re-annunciation | Override allowed | Acknowledge required | Typical use |
|---|---|---|---|---|
| Warning | Every 15 minutes | No | Yes | Immediate crew action required — safety or mission critical |
| Caution | Every 2 hours | Yes | Yes | Attention needed — degraded capability |
| Advisory | Not re-annunciated | No | No | Information — no immediate action needed |
Re-annunciation intervals and the override rule are configurable per platform in alarm_specifications.json.
The service enforces the Def Stan 23-009 category gates:
- GVA_ALM_9 — Acknowledge is a no-op on Advisories.
- GVA_ALM_11 — Override is accepted only on Cautions.
Attempts to override a Warning or Advisory are rejected via CRP with the appropriate error code.
Conditions vs alarms¶
The v3.0 specification distinguishes two lifecycles:
- Alarm Condition (
C_Alarm_Condition) — an LRU-owned fact. "The engine is above 120 °C" is a condition. The LRU publishes it asActivewhen the fact becomes true andInactivewhen it becomes false. Conditions have specifications (C_Alarm_Condition_Specification) describing category, text and classification. - Alarm (
C_Alarm) — a register-side event. When the alarms service sees a condition go Active it raises an alarm: allocates an alarm ID, records it to the Alarm Register, publishesC_Alarm, and starts crew annunciation. Alarms have state that changes in response to operator commands and underlying condition transitions.
An LRU only ever sees C_Alarm_Condition. Only the alarms service and
HMI see C_Alarm.
Alarm state machine¶
The alarms service state chart matches Def Stan 23-009 §3.4.3:
Notes:
- Advisory alarms transition straight from
Active_UnacknowledgedtoResolvedwhen their condition clears — no Ack step. - Re-annunciation — while a Warning or Caution is in
Active_Unacknowledged, the annunciation is repeated at the category's re-annunciation interval until the crew acknowledges it. - Override — Cautions may be overridden while their condition is
still Active. Override suppresses annunciation and is cancelled by
the
Remove Overridecommand. Overrides are cleared on service restart (crew are re-annunciated on power-on). Clearedis a final wire sample, not a DDS dispose. TheCleared --> [*]transition above is a state-machine end state, not a wire-level removal of the alarm instance — the service publishes one finalC_Alarmsample withA_currentState=Clearedand does not dispose/unregister the DDS instance. A late-joiningTRANSIENT_LOCALsubscriber (e.g. a log tool that connects after the alarm was cleared) will still see the Cleared sample as the alarm's current state, not observe it disappear from the Alarm Register feed.
Alarm sequence¶
(LRU spec > override > fallback) SVC->>SVC: Allocate alarm ID
(sequential, service-owned) SVC->>SVC: Persist to Alarm Register SVC->>HMI: C_Alarm (Active_Unacknowledged) SVC->>HMI: C_Annunciation_startEvent
(audio + visual) HMI->>Op: Popup + annunciation Op->>HMI: Acknowledge button HMI->>SVC: C_Alarm_acknowledge SVC->>HMI: CRP response (success) SVC->>HMI: C_Annunciation_stopEvent SVC->>HMI: C_Alarm (Active_Acknowledged) Note over LRU: Fault resolved LRU->>SVC: C_Alarm_Condition (Inactive) SVC->>HMI: C_Alarm (Resolved)
Alarm Register persistence¶
The Alarm Register is persisted to PostGIS on every state transition (Def Stan 23-009 §7.4 / GVA_ALM_88). After a power cycle the alarms service:
- Restores every
Active_*alarm and its owning condition from the database. - Clears any
Overrideflags so the crew is re-annunciated. - Continues allocating alarm IDs above the highest restored value.
Persistence requires PostGIS. Without it, the service still runs but the register starts empty on every restart and a warning is logged; this is not a spec-compliant deployment.
Platform configuration file¶
alarm_specifications.json is a policy overlay loaded at startup. It
is not an authoritative alarm catalogue — a well-behaved LRU that
publishes its own C_Alarm_Condition_Specification overrides everything
in the file.
Resolution order (highest to lowest precedence):
-c/--config=<path>on the command line./etc/gva/alarms/alarm_specifications.local.json— operator override. Never shipped by the package, so it is never overwritten on upgrade. Use this to customise the alarm policy without editing the package-owned default in place./etc/gva/alarms/alarm_specifications.json— the packaged default, installed by thegva-alarms-servicepackage. Overwritten unconditionally on every upgrade.- Dev-tree fallbacks — only relevant when running an unpacked build out
of
build/binwithout installing.
If none of the search paths resolve, the service logs
No alarm specifications file found - using defaults and continues with
built-in defaults.
Top-level sections:
{
"alarmCategories": [ /* Warning / Caution / Advisory + re-annunciation intervals */ ],
"alarmConditionSpecifications": [ /* Legacy inline catalogue; treated as an implicit `fallbacks[]` */ ],
"fallbacks": [ /* Specs to publish when no LRU spec has been observed within 10 s */ ],
"disabled": [ /* Condition IDs the service refuses to raise alarms for */ ],
"overrides": [ /* Category remaps: LRU said Caution, this platform says Warning */ ]
}
alarmCategories[]¶
Overrides the shipped C_Alarm_Category_Definition samples:
{
"categoryId": 90001,
"name": "Warning",
"description": "Critical issues requiring immediate crew attention",
"reannunciationTimeoutMinutes": 15,
"annunciationType": "audio_visual"
}
categoryId must be above the 0–9,999 registry-reserved range
(Def Stan 23-009 §3.2.3 / GVA_PCRS_003).
fallbacks[] — safety net for silent LRUs¶
Ten seconds after startup the service walks the fallback catalogue and
publishes a C_Alarm_Condition_Specification for any condition ID
that hasn't been described by an LRU. This ensures late-joining HMIs
and log consumers see specification samples for every condition the
platform can raise, even when the LRU firmware is old or minimal.
If the LRU publishes its own spec before or after the fallback fires, the LRU's spec is authoritative from that point forward.
disabled[] — quiet a chatty LRU¶
Condition IDs listed in disabled[] are dropped at ingress. No
C_Alarm is created, no annunciation is fired, no CRP response is
emitted (nothing was commanded). Use this to gag an LRU that raises
nuisance alarms in a specific deployment without changing the LRU
firmware.
overrides[] — reclassify an LRU condition¶
An override remaps an incoming condition's effective category:
Use this when an LRU classifies a condition at (say) Caution but on
this specific platform it should be a Warning. The override wins even
when the LRU publishes its own C_Alarm_Condition_Specification.
Operator commands¶
Five DDS command topics are subscribed by the alarms service. Each
carries a T_CommandHeaderType per the Def Stan 23-009 Command
Response Protocol (CRP) and receives a matching
T_CommandResponseType reply on Alarms__CommandResponseType.
| Topic | Effect |
|---|---|
C_Alarm_acknowledge |
Marks a Warning or Caution as Active_Acknowledged; silences its annunciation. |
C_Alarm_clearAlarm |
Transitions any alarm to Cleared (operator override of the condition state). |
C_Alarm_annotate |
Attaches free-text crew annotation to an alarm. |
C_Alarm_Condition_override |
Marks a Caution's condition as overridden — suppresses further annunciations. |
C_Alarm_Condition_removeOverride |
Cancels an override. |
Authorisation. The service does not enforce crew-role authorisation on commands. Every HMI is expected to enforce Def Stan 23-009 §3.3.1.2 Table 4 (Crew Role Authorisations) itself, by enabling or disabling the on-screen buttons per the operator's current crew role. See the HMI Crew Role Manager for details.
The service does enforce category gates: Acknowledge is silently accepted-and-ignored on Advisories (GVA_ALM_9); Override is rejected with a CRP error on Warnings and Advisories (GVA_ALM_11).
Annunciation¶
The alarms service is the state-machine truth for annunciation but delegates rendering to the Annunciation LDM per §5.1.3 / §7.1.2.
- The service publishes a catalogue of
C_Annunciation_Definition,C_Audible_Tone_DefinitionandC_Visual_Annunciation_Definitionsamples at startup (TRANSIENT_LOCAL, so late-joining subscribers receive them on discovery). - When an alarm enters
Active_Unacknowledgedthe service publishesC_Annunciation_startEventon the appropriate audio + visual annunciation instances. - Only one annunciation per modality is active at a time (GVA_ALM_34 §7.3.2.4). If a higher-priority alarm arrives, the service stops the current annunciation and starts the new one.
- The HMI's
AnnunciationManagerrenders whatever the service says to render.
The default Warning tone is a two-frequency alternating pattern
(800 Hz + 1000 Hz) per GVA_ALM_58. Caution and Advisory have no audio
tone by default — they are visual-only (annunciationType: "visual"
in alarmCategories[]).
HMI display¶
Alarm popup styles¶
The GVA HMI displays alarm popups with colour-coded category indicators:
| Warning | Caution | Advisory |
|---|---|---|
![]() |
![]() |
![]() |
| Warning | Caution | Advisory |
| Immediate action required | Operator awareness needed | Informational |
When multiple alarms are queued, the display indicates pending items:

Alarms table view¶
Press F14 (Alarms) on the HMI to display the full alarms table, showing every active alarm sorted by category and time. Columns are Time, Category, State, Source (the raising resource's registered identity), and Message — see HMI — Alarms for the full column reference:

DDS quality of service¶
Every alarms topic is set up via the LDM DDS wrapper library so QoS is resolved by pattern, not per-topic. The alarms service uses:
| Message | Pattern | History | Reliability | Durability |
|---|---|---|---|---|
C_Alarm |
eAlarm |
KeepLast(256) | Reliable | TransientLocal |
C_Alarm_Condition |
eAlarm |
KeepLast(256) | Reliable | TransientLocal |
C_Alarm_Category_Definition |
eSpecification |
KeepLast(64) | Reliable | TransientLocal |
C_Alarm_Condition_Specification |
eSpecification |
KeepLast(64) | Reliable | TransientLocal |
| Command topics + CRP responses | eCommand |
KeepLast(256) | Reliable | Volatile |
| Annunciation events | eCommand |
KeepLast(256) | Reliable | Volatile |
TransientLocal durability guarantees that a late-joining HMI receives every currently-active alarm on discovery, not just alarms raised after it connected.
Database maintenance CLI¶
Two one-shot recovery actions are exposed on the gva-alarms binary.
Both perform the requested action at startup, then the service
continues normal boot; there is no separate one-shot systemd unit.
Destructive — no confirmation prompt
Both --db-truncate and --db-clear execute their delete the
moment the process starts. There is no --yes interlock and no
"are you sure?" prompt. The flag alone is the confirmation.
Never wire either flag into the ExecStart= line of the
systemd unit — you will silently wipe the Alarm Register on every
reboot. These flags are for interactive operator use only.
| Flag | Deletes | Preserves | Effect on running fleet |
|---|---|---|---|
--db-truncate[-days N] (default 90) |
Fully-closed alarms (is_resolved=true AND is_acknowledged=true) whose resolve_time is older than the cutoff, plus alarm_history audit rows of the same age |
Every active/unresolved alarm; every partially-closed alarm; the schema and indexes | None — GVA_ALM_14 clear normally removes a closed alarm's row already; this only recovers rows orphaned by a crashed LRU or service instance |
--db-clear |
Every row from every alarms-managed table (alarms, alarm_conditions, alarm_history) |
Schema, indexes | Full factory reset of the Alarm Register. Every LRU re-raises its alarms fresh on next annunciation; there is no specification file to re-publish from (alarms are not configuration data, unlike the registry) |
--db-truncate and --db-clear are mutually exclusive; passing both
together aborts with exit code 2 before any rows are touched. A
failed database connection aborts with exit code 4; a failed delete
aborts with exit code 5 — in both cases no partial action is left
running and the service does not proceed to normal boot.
Typical use cases:
- Dev / test: after a batch of simulated alarms accumulates during
a test run,
--db-truncateclears the stale closed entries without disturbing anything still active. - Crash recovery: an LRU or the service itself crashed mid-clear,
leaving closed alarms that were never garbage-collected;
--db-truncatesweeps them up on the next start. - Factory refurbishment: on a returned vehicle,
--db-cleargives a completely empty Alarm Register — every LRU re-raises its current state from scratch on next annunciation.
Both actions log every row count they delete, per table, to journald. Example:
[Alarms-DB] ✓ Purged 2 stale closed alarm(s)
[Alarms-DB] ✓ Purged 0 stale alarm_history row(s)
[Alarms-DB] ✓ purgeStaleAlarms: 2 row(s) deleted (older than 2026-08-31T05:24:52Z)
[gva-alarms] --db-truncate complete: 2 row(s) deleted. Continuing normal service boot.
For per-row surgery (clear a single alarm without touching anything
else) use the operator-facing DDS command instead — the alarm's own
clear/acknowledge lifecycle already removes its row once fully
closed (GVA_ALM_14).
Deployment¶
The alarms service ships as gva-alarms-service (systemd unit
gva-alarms.service). Ordering:
postgresql.servicegva-db-init-servicepostinst provisions thegva_alarms_dbrole/schema (viagva-db-init.sh, once, at install/upgrade)gva-registry.servicegva-alarms.service
The platform configuration file path is set via the -c / --config
command-line option (ExecStart=/usr/bin/gva-alarms --domain=0 ...),
not an environment variable.
Common environment overrides (see the shipped
/etc/default/gva-alarms, sample at
/usr/share/doc/gva-alarms-service/gva-alarms.env.example):
| Variable | Purpose |
|---|---|
ALARMS_DB_HOST / ALARMS_DB_PORT / ALARMS_DB_NAME / ALARMS_DB_USER / ALARMS_DB_PASSWORD |
PostgreSQL connection overrides for the Alarm Register |
GVA_ALARM_REANN_WARNING_MIN / GVA_ALARM_REANN_CAUTION_MIN |
Force re-annunciation intervals in minutes (lab / CI only) |
GVA_ALARM_REANN_CHECK_MS |
Sweep interval for the re-annunciation timer (lab / CI only) |
Troubleshooting¶
The HMI shows no alarms even though the LRU is publishing¶
- Confirm the LRU is publishing
C_Alarm_Condition(notC_Alarm). Under v3.0 only the service publishesC_Alarm. - Confirm the LRU's DDS domain matches the alarms service's
LDM_DOMAIN_ID. - Check that the condition ID is not listed in
disabled[]inalarm_specifications.json. - Use
astutedds-discovery-dump -d <domain>to confirm the LRU and service participants see each other and that the QoS onC_Alarm_Conditionmatches (Reliable / TransientLocal).
Alarms don't survive a service restart¶
- The Alarm Register requires PostGIS. Confirm
systemctl status postgresqlreports active. - Confirm the alarms service's PostgreSQL credentials in
/etc/default/gva-alarmsare valid. - Check the journal for
[GVA-Alarms] GVA_ALM_88: restored N alarmson start.
An LRU classifies a condition wrong for this platform¶
- Add an entry to
overrides[]inalarm_specifications.jsonmapping the condition ID to the desired category ID. The override wins even when the LRU publishes its own spec.
Duplicate or repeated annunciations¶
- Re-annunciation is by design for unacknowledged Warnings and Cautions (§GVA_ALM_30 / GVA_ALM_32). The default intervals are 15 minutes / 2 hours. Acknowledge the alarm to silence it, or override the condition (Cautions only).
Specification references¶
- Def Stan 23-009 Alarms Service Specification v3.0 — §3.4.2 (condition state machine), §3.4.3 (alarm state machine), §5.1.3 / §7.1.2 (Annunciation LDM delegation), §5.3.4 (category definitions), §7.3.2.4 (single-annunciation-per-modality), §7.4 (Alarm Register persistence).
- Def Stan 23-009 Command Response Protocol — all five command topics + CRP responses.
- Def Stan 23-009 §3.2.3 / GVA_PCRS_003 — registry-reserved identifier band (0–9,999).


