Skip to content

muxen-nmea2000 — Overview ​

muxen-nmea2000 is what puts position, heading, wind, depth, engine data and AIS traffic on the boat's screens.

Almost none of that data belongs to MUXEN. It comes from the boat's own instruments — a GPS antenna, a masthead wind vane, a depth transducer, an autopilot, an engine gateway, an AIS transponder — and they all speak NMEA 2000, the marine bus every manufacturer agrees on. That bus is a single yellow cable running the length of the boat, and everything on it shouts its readings into the void several times a second.

muxen-nmea2000 listens. It joins the bus as an ordinary device, decodes the traffic, decides which instrument to believe when two of them disagree, and republishes the result as a small number of tidy summaries the boat's screens subscribe to. It also works the other way round: data the Brain has and the bus does not — a position from a USB GPS receiver, for instance — is transmitted onto the bus so that a chartplotter from any manufacturer sees it.

The daemon has no user interface of its own. What the crew sees is the navigation page, the engine page and the AIS overlay drawing themselves from what it publishes.

The problem it solves ​

An NMEA 2000 bus is a crowd, not a source of truth.

  • Several instruments answer the same question. A boat routinely carries two GPS receivers, a fluxgate compass and a satellite compass, a paddlewheel log and a Doppler log. Each broadcasts position or heading with equal confidence, and nothing on the wire says which one to trust.
  • Nothing has a name. A device identifies itself by a 64-bit J1939 NAME and an address it negotiates at power-up. That address can change between one trip and the next. "The masthead unit" is not a concept the bus has.
  • The units are the standard's, not yours. Angles arrive in radians, speeds in metres per second, temperatures in kelvin, positions in ten-millionths of a degree.
  • Data goes stale silently. An instrument that stops transmitting leaves its last value on the wire in every reader's memory. A frozen depth reading looks exactly like a correct one.

muxen-nmea2000 resolves all four. It maintains a registry of every device it has seen, with its NAME, its manufacturer and its product information; it lets the installer rank sources per data type, so the satellite compass wins heading and the paddlewheel loses to the Doppler; it converts everything into degrees, knots, metres and Celsius; and it ages every field out, so a field that stops arriving becomes null rather than a lie.

Where it sits on the boat ​

   masthead    GPS     depth    autopilot   engines    AIS
       │        │        │          │          │        │
       └────────┴────────┴──── can1 ┴──────────┴────────┘   NMEA 2000, 250 kbit/s
                                 │
                          muxen-nmea2000
                        (one per CAN bus)
                                 │
                    ┌────────────┼─────────────┐
                    │            │             │
              MQTT  nmea/…   gpsd (optional)   NMEA 2000 transmit
                    │                          (back onto can1)
              boat screens, @muxen/nmea,
              other muxen-* services
It readsFromPurpose
NMEA 2000 / J1939 framesthe CAN interface, can1 by defaultevery instrument reading on the bus
/etc/muxen/deploy.jsondisk, at startupwhich report modules the boat wants
nav-sources.jsonthe state directoryper-source priorities and friendly names
gpsdTCP localhost:2947, optionala GPS receiver wired to the Brain, not to the bus
{prefix}/alarm/…MQTTalarm acknowledge and mute commands from the HMI
It writesToPurpose
nmea/navigation, nmea/motor, nmea/ais, …MQTT, retainedthe summaries the screens draw
nmea/device/…, nmea/devices, nmea/interfaceMQTT, retainedper-device raw data, bus inventory, link health
NMEA 2000 framesthe CAN interfaceaddress claim, product information, GNSS PGNs, alerts

It is a full participant on the bus, not a listener: it claims an address, answers ISO requests about itself, and emits a heartbeat. See Address claiming.

What it publishes ​

Everything the daemon produces lands under one MQTT prefix, nmea by default. There are two layers.

The reports are the ones a screen subscribes to. Each is a single retained JSON document, rebuilt on a timer, with a data object and a metadata object carrying the time it was built and how long it stays meaningful.

TopicContentChapter
nmea/navigationposition, heading, COG/SOG, wind, depth, autopilot03
nmea/motorper-engine RPM, temperatures, pressures, fuel, warnings04
nmea/thrusterbow and stern thruster state04
nmea/aisAIS targets, aids to navigation, SAR aircraft, safety messages05
nmea/routethe active route or GoTo, cross-track error, waypoints06
nmea/datetimeUTC and local date and time11
nmea/statusone summary of every module's health10

The bus view is the raw layer underneath: nmea/devices (who is on the bus), nmea/device/<addr>/infos (what each of them says it is), nmea/device/<addr>/pgn/<pgn> (decoded messages, off by default) and nmea/interface (CAN link health and error counters). Full topic list and payload shapes: Reference.

Report modules are opt-in ​

Out of the box the daemon claims an address, publishes the bus view and nothing else. Each report is enabled deliberately — on the boat by the commissioning file /etc/muxen/deploy.json, on the bench by a command line flag. That is why a fresh install can look silent: it is doing exactly what it was asked.

The two exceptions are nmea/datetime and nmea/status, which are always on.

Configuration covers the layering: built-in defaults, then deploy.json, then the command line, with --report-all on top.

More than one bus ​

Some boats have more than one NMEA 2000 segment, and some maintenance work needs a daemon on a bus that is not the commissioned one. muxen-nmea2000@.service is a templated unit whose instance name is the CAN interface:

sh
systemctl start muxen-nmea2000@can0

An instance deliberately ignores /etc/muxen/deploy.json, publishes under nmea-can0/ instead of nmea/, and carries a J1939 NAME that always loses arbitration to the commissioned daemon. It can therefore never disturb the boat's own gateway. This is the part installers get wrong most often — More than one bus.

What it does not do ​

  • It does not steer, and it does not command. The daemon transmits its own identity, GNSS data when configured to, and alert acknowledgements. It never sends an autopilot command, an engine command or a device configuration write. Configuring MUXEN devices is muxen-uds's job.
  • It does not persist history. Everything is current state. The one thing it keeps across restarts is the address it claimed, in a 32-byte state file (The state file).
  • It does not authenticate. Anyone who can reach the MQTT broker sees every report and can send alarm commands. The broker and the reverse proxy are the access boundary.
  • It does not tolerate the wrong bitrate. NMEA 2000 is 250 kbit/s. The daemon reads the interface's configured bitrate at startup and refuses to run on anything else, because a mismatched node is worse for the bus than an absent one.

Document map ​

DocumentContent
Getting startedinstall, verify, first data, a real templated instance
Configurationthe three configuration layers, deploy.json, environment files
Navigationthe navigation report, source selection, muxen-nmea2000-config
Engines and thrustersthe motor and thruster reports
AISAIS targets, aids to navigation, safety messages
Routes and waypointsthe active route, GoTo, cross-track error
GNSS and gpsda GPS on the Brain: reading it, and transmitting it to the bus
Alarmsthe NMEA 2000 alert subsystem
More than one busmuxen-nmea2000@<iface>, second buses, the tools
Troubleshootingsymptom → cause → check → fix, FAQ, tips
ReferenceCLI, MQTT topics and payloads, units, paths, exit status
Address claimingthe J1939 NAME, preferred address, address ranges
The address claim state machinethe address claim state machine, in detail
The state filethe persisted address, its format and its management commands
PGN referenceevery PGN decoded and transmitted, Fast Packet, proprietary ranges

JSON Schemas for the published payloads: MQTT payloads, AIS targets, with an AIS sample.

Integration of multiplexed solutions
MUXEN and the MUXEN logo are trademarks of MUXEN SAS.