Appearance
muxen-alarms — Overview
muxen-alarms is the part of the MUXEN Brain that answers one question for the whole boat: what is wrong right now?
Every MUXEN box on board — the battery bank, the generator, the motor controller, the watermaker, the air conditioning, the solar chargers — detects its own faults and reports them. Each box reports only its own, in a numeric code, and nothing on the wire says what code 17 on a solar charger means. muxen-alarms collects every one of those reports, translates the code into a sentence and a severity, and publishes a single list that the boat's screens display as the alarm page.
That list is what wakes a crew at 03:00. Everything in this manual exists to make it trustworthy: an alarm on the page means the condition is happening now, not that somebody forgot to clear an old one.
On a Brain with an audio output the daemon also speaks the alarms: each one when it appears, then the whole list again every few minutes until the condition ends or somebody acknowledges it. See The life of an alarm.
The daemon itself has no user interface.
The property that matters: alarms clear themselves
There is no "reset" button in this system, and there does not need to be one.
A device that has a fault re-reports it continuously. muxen-alarms holds each report for 15 seconds and pushes that deadline forward every time the report arrives again. Stop the reports — because the fault is gone, or the equipment was switched off — and the entry drops off the list within 15 seconds, by itself.
The consequences are worth stating plainly:
- An alarm on the screen is live. It was reported in the last 15 seconds. It is not a historical record.
- Nothing latches. A fault that came and went leaves no residue on the page, and no crew member has to clear anything to make the page usable again.
- The list is not a logbook.
muxen-alarmskeeps no history: it holds only what is currently true, in memory. A restart of the service empties it, and it refills from the live reports within seconds.
Acknowledging is muting, and it is safe
The HMI's "acknowledge" is a filter: a request to stop counting a given alarm as active for a while. It is the one thing a crew member does to this daemon, so it is worth being exact about what it does.
| It does | It does not |
|---|---|
mark the alarm muted and move it from the active count to the muted count | touch the device, the fault, or anything physical |
| expire on its own, after one hour by default | hide the alarm — it stays in the published list, flagged |
| refresh its own clock if you acknowledge again | survive a restart of the service |
Muting an alarm is therefore safe in the only sense that matters: it changes what the screen counts, and changes nothing on the boat. The equipment's own protections are inside the equipment and are unaffected. When the mute runs out, if the device is still reporting the fault, the alarm counts as active again and the boat is noisy again.
If nobody acknowledges anything, nothing bad happens here. The alarm stays active for exactly as long as the device keeps reporting it, and disappears on its own when it stops. The risk of ignoring an alarm is whatever the equipment is complaining about — never the alarm system.
The life of an alarm covers this in full.
Two alarms the daemon raises itself
Almost every alarm comes from a device. Two do not, and they are the ones that report on the reporting chain:
| Code | Meaning | Raised when |
|---|---|---|
65000 | Device not detected on CAN-Bus | a device listed in the boat's configuration did not answer the once-a-minute bus scan |
65001 | Alarm data source lost | the daemon's own link to the boat data — the MQTT broker, or the CAN interface — is down |
65001 deserves the emphasis: while it is present, the daemon can see nothing, so an empty alarm page is not evidence that the boat is healthy. That is the whole reason the alarm exists. Devices that go quiet, and the daemon's own health covers both.
What ships
Alarms ships as three Debian packages.
| Package | What it is | Contents |
|---|---|---|
muxen-alarms | the daemon and the command-line tools | muxen-alarmsd, muxen-dtc, muxen-alarms-test-audio, the systemd unit, the nginx snippets, the Swagger UI |
muxen-alarms-database | the alarm code catalogue | /usr/share/muxen-alarms/dtc.json — 265 codes: eleven equipment families plus a generic set — /usr/share/muxen-alarms/functions.json, the equipment names in the other languages, and one voice file per distinct sentence, plus the clip the speaker test plays |
muxen-alarms-mdns | the network announcement | an Avahi service file so a laptop on the same network can find this Brain's alarm interface |
muxen-alarms depends on muxen-alarms-database of the same version, so the daemon and the catalogue always move together. The database is Architecture: all and is split out precisely so a code addition ships without rebuilding the daemon.
The programs in muxen-alarms do different jobs:
muxen-alarmsdis the daemon. It is whatmuxen-alarms.serviceruns, and it owns the list, the filters, the REST API and the WebSocket.muxen-dtcis a diagnostic viewer for a shell on the Brain. It prints alarm messages as they arrive on MQTT — for one second, or until interrupted with-f. It holds no state and serves nothing.muxen-alarms-test-audioasks the daemon to play its speaker test, a short clip through the alarm output, and says whether it started.
Where it sits on the boat
MUXEN devices
|
can0 muxen-boat
| |
+─────────────────► MQTT device/<fn>/<inst>/error/<code>
|
muxen-alarmsd ──► /api/dtcs (REST)
| └──► /ws/alarms (WebSocket, on change + every 5 s)
| |
muxen-uds └──► screens, tray clients
(once a minute,
offline scan)| It reads | From | Purpose |
|---|---|---|
device/<function>/<instance>/error/<code> | MQTT | the alarm reports, in the shipped configuration |
the DTC broadcast frame, id 170 (0xAA) | can0 | the same reports, when started with --interface instead of --mqtt |
/usr/share/muxen-alarms/dtc.json | disk, once at startup | the code → description and severity catalogue |
/usr/share/muxen-alarms/functions.json | disk, once at startup | the equipment names in languages other than English. Optional |
/etc/muxen/deploy.json | disk, once per scan | which devices are supposed to be present |
muxen-uds uid --scan-to-json | a child process, once a minute | which devices actually answered |
/usr/share/muxen-alarms/sound/ | disk | the voice files, and manifest.json to find the one for a sentence |
app/alarm/settings | MQTT | turning the spoken alarms off or on, and their minimum level |
app/alarm/test, or {"type": "test-audio"} on the WebSocket | MQTT, WebSocket | a request to play the speaker test |
| It writes | To | Purpose |
|---|---|---|
| the alarm list | WebSocket /ws/alarms, on connect, on every change and every 5 s | live alarm state for screens |
| the alarm list | REST GET /api/alarms/dtcs | the same, on demand |
| the spoken alarms | the audio output (ALSA) | each alarm said out loud |
| the audio state | MQTT app/alarm/audio, retained, and the WebSocket | whether it can speak, whether it is on, what it is saying |
| its name, version, host name and features | MQTT app/alarm/info, retained, and a hello frame to each new WebSocket client | which daemon this is, whether it is running, and what a client can ask of it |
It sends no CAN frame, and the alarm list itself never goes to MQTT: the only topics it publishes are app/alarm/audio and app/alarm/info. The one thing it starts is a muxen-uds scan, once a minute, to find devices that have gone quiet.
The shipped systemd unit runs it as muxen-alarmsd --mqtt, so on a standard Brain the data comes from MQTT and the CAN path is unused. That is why the package carries Recommends: muxen-boat (>= 5.0.0): muxen-boat is the daemon that turns CAN frames into device/… topics.
The daemon binds 127.0.0.1 only. Everything reaching it from outside the Brain comes through nginx, which maps /api/alarms/ and /ws/alarms onto it. See Reference.
Document map
| Document | Content |
|---|---|
| Getting started | install, verify the service, read the list, place a first mute |
| The life of an alarm | raised, refreshed, expired, muted — and what acknowledging really does |
| Devices that go quiet, and the daemon's own health | the once-a-minute bus scan, code 65000, code 65001, per-device opt-out |
| The alarm catalogue | the code catalogue: coverage, severities, French text, unknown |
| Troubleshooting | symptom → cause → check → fix, plus FAQ and tips |
| Reference | CLI, defaults, unit, paths, ports, exit codes, MQTT and CAN inputs |
| The HTTP and WebSocket API | the REST and WebSocket wire format, for client implementers |
