Appearance
Reference
Everything the daemon and its tools expose, in tables. For what any of it means, see the topic chapters.
Every value here was read out of the software itself. Where a --help string and the code disagree, the code is what is documented; the discrepancies are listed in internal/open-questions.md.
Programs
| Program | Role |
|---|---|
/usr/bin/muxen-nmea2000 | the daemon, one per CAN bus |
/usr/bin/muxen-nmea2000-config | navigation source configuration, full-screen terminal |
/usr/bin/muxen-nmea2000-inventory | prints the bus device list from MQTT |
/usr/bin/muxen-nmea2000-generate-name | builds a J1939 NAME from its fields |
/usr/bin/muxen-nmea2000-simulator | transmits synthetic NMEA 2000 traffic |
The four tools are each built behind a Meson option — tool_config, tool_inventory, tool_name, tool_simulator — all on by default.
muxen-nmea2000
General
| Option | Argument | Default | Effect |
|---|---|---|---|
-v, --version | print version, exit | ||
-i, --interface | INTERFACE | can1 | CAN interface |
--state-dir | DIR | /var/lib/muxen-nmea2000 | state file directory |
--data-dir | DIR | /usr/share/muxen-nmea2000 | read-only data tables |
--deploy-config | PATH | /etc/muxen/deploy.json | deploy configuration file |
--no-deploy-config | off | skip the deploy layer | |
--ipc-socket | PATH | see below | IPC socket path |
--show-state | print the state file, exit | ||
--clear-state | delete the state file, exit |
--data-dir, when not given, is searched for in order: /usr/share/muxen-nmea2000, ./data, . — the first that contains manufacturers.json wins.
J1939 identity
| Option | Argument | Default | Effect |
|---|---|---|---|
-n, --name | NAME | (required) | 64-bit J1939 NAME, hex, 0x prefix optional |
-a, --address | ADDR | 128 | preferred source address, 0–253 |
--min-addr | MIN | 100 | lowest address for dynamic claiming, 0–253 |
--max-addr | MAX | 200 | highest address for dynamic claiming, 0–253 |
--nmea-version | VERSION | 3000 | NMEA 2000 database version reported in PGN 126996 |
--product-code | CODE | 123 | product code |
--model-id | ID | :) | model id, max 31 characters, refused if longer |
--product-name | NAME | Muxen Brain 20 | product name, max 31 characters, refused if longer |
--serial-number | SERIAL | 00:00:00 | serial code, max 31 characters, refused if longer |
--cert-level | LEVEL | 2 | 0 certified, 1 type approved, 2 not applicable |
--load-equiv | VALUE | 0 | load equivalency number |
--install-desc1 | TEXT | MUXen Brain 20 | installation description 1, max 31 characters, silently truncated |
The software version reported in PGN 126996 is the daemon's own version and is not settable.
MQTT
| Option | Argument | Default | Effect |
|---|---|---|---|
--no-mqtt | MQTT on | disable MQTT entirely | |
--mqtt-host | HOST | 127.0.0.1 | broker host |
--mqtt-port | PORT | 1883 | broker port |
--mqtt-username | USER | none | broker username |
--mqtt-password | PASS | none | broker password |
--mqtt-client-id | ID | auto-generated | MQTT client id |
--mqtt-topic-prefix | PREFIX | nmea | prefix for every topic |
--mqtt-publish-pgn | off | publish raw decoded PGNs to …/device/<addr>/pgn/<pgn> |
The broker keep-alive is 60 s and the session is clean.
Report modules
| Option | Argument | Default | Effect |
|---|---|---|---|
--enable-alarms | off | NMEA 2000 alert subsystem | |
--report-all | off | enable nav, AIS, motor, route and thruster; applied last | |
--report-nav | off | publish <prefix>/navigation | |
--nav-high-speed | off | 10 Hz instead of 1 Hz | |
--nav-config | PATH | see below | navigation source configuration file |
--wind-damping | LEVEL | 7 | 0–9, 0 = off |
--report-ais | off | publish <prefix>/ais | |
--ais-track-depth | DEPTH | 10 | track points per target, clamped 0–100 |
--report-motor | off | publish <prefix>/motor | |
--motor-high-speed | off | 10 Hz instead of 1 Hz | |
--report-thruster | off | publish <prefix>/thruster | |
--report-route | off | publish <prefix>/route | |
--route-max-waypoints | COUNT | 500 | waypoints kept per route |
--timezone-db | PATH | <data-dir>/timezone16.bin | ZoneDetect database |
--datetime-offset | MODE | nmea | nmea or auto |
--report-metadata-source | off | include source device information in report metadata |
<prefix>/datetime and <prefix>/status are always published and have no enabling flag.
GNSS source
Present only when the daemon was built with libgps.
| Option | Argument | Default | Effect |
|---|---|---|---|
--source-gpsd | off | enable the gpsd client | |
--source-gpsd-host | HOST | localhost | gpsd server |
--source-gpsd-port | PORT | 2947 | gpsd port |
--source-gpsd-device | PATH | all | restrict to one receiver |
--source-gpsd-transmit | [MODE] | off | on or failover; bare flag means on |
--source-gpsd-transmit-high-speed | off | also transmit the 10 Hz rapid-update PGNs | |
--source-gpsd-transmit-failover-delay | SECONDS | 60 | time without a valid GNSS on the bus before failover starts; 1–4 behave as 5, 0 as 60 |
Tweaks
Workarounds for chartplotter compatibility and bus recovery tuning.
| Option | Argument | Default | Effect |
|---|---|---|---|
--fp-delay | USEC | 1000 | Fast Packet inter-frame delay |
--pgn-list-fp-only | off | limit the PGN List to Fast Packet size, 74 PGNs, no ISO-TP | |
--recovery-initial-delay | MS | 1000 | first bus-recovery retry delay |
--recovery-max-delay | MS | 30000 | backoff ceiling |
--recovery-max-attempts | N | 0 | 0 = retry forever |
Verbosity
All are off by default and all write to standard error.
| Option | Covers |
|---|---|
--verbose-data | decoded PGN JSON |
--verbose-control | address claim and lifecycle |
--verbose-request | ISO requests |
--verbose-pgn-proprietary | proprietary PGNs |
--verbose-nav | navigation source selection; also adds sources and unavailableTypes to <prefix>/navigation |
--verbose-ais | AIS target lifecycle |
--verbose-ipc | IPC server |
--verbose-gpsd | gpsd connection |
--verbose-mqtt | MQTT connection |
--verbose-motor | motor report |
--verbose-route | route report |
--verbose-datetime | datetime report |
--verbose-all | all of the above |
Signals
| Signal | Effect |
|---|---|
SIGHUP | reload the navigation source configuration and republish <prefix>/config |
SIGINT, SIGTERM | graceful shutdown |
SIGPIPE | ignored — an IPC client that disconnects mid-reply must not kill the daemon |
Exit status
| Status | Meaning |
|---|---|
0 | clean shutdown, or --version / --show-state / --clear-state completed |
1 | startup refused: bad options, wrong bitrate, no NAME, lock not acquired, CAN monitor failed, --clear-state could not delete the file |
muxen-nmea2000-config
| Option | Argument | Effect |
|---|---|---|
-s, --socket | PATH | IPC socket |
-I, --instance | NAME | use /run/muxen-nmea2000-<NAME>/sources.sock |
-r, --read-only | monitor without editing | |
-h, --help | usage, exit 0 | |
-V, --version | version, exit 0 |
Exit status is 1 on a UI error, 0 otherwise. The device list refreshes every 2 s. Key bindings are in Navigation.
muxen-nmea2000-inventory
| Option | Argument | Default |
|---|---|---|
-H, --host | HOST | localhost |
-p, --port | PORT | 1883 |
-I, --instance | NAME | — |
-P, --prefix | PREFIX | nmea |
-T, --timeout | SEC | 5 |
-j, --json | formatted table | |
-c, --csv | semicolon-delimited | |
-h, --help |
muxen-nmea2000-generate-name
Builds a 64-bit J1939 NAME from its constituent fields.
| Option | Argument | Field |
|---|---|---|
-i, --identity | NUM | Identity Number |
-m, --manufacturer | NUM | Manufacturer Code |
-e, --ecu-instance | NUM | ECU Instance |
-f, --func-instance | NUM | Function Instance |
-F, --function | NUM | Function |
-v, --vehicle-system | NUM | Vehicle System |
-V, --vs-instance | NUM | Vehicle System Instance |
-g, --industry-group | NUM | Industry Group |
-a, --arbitrary | set the Arbitrary Address Capable bit | |
-h, --help |
Field meanings and their ranges are in Address claiming.
muxen-nmea2000-simulator
muxen-nmea2000-simulator [OPTIONS] [MODULE] [INTERFACE]
muxen-nmea2000-simulator --all [INTERFACE]Modules: motor, navigation (or nav), ais, route, thruster. With no module and no --all, every module runs. Default interface comes from the build; --interface beats the positional argument.
| Option | Argument | Effect |
|---|---|---|
-i, --interface | IFNAME | CAN interface |
--all | run every simulator | |
--setup | create the vcan interface first | |
--duration | SECS | run time, 0 = forever |
--cruising | cruising defaults for every module | |
--lat, --lon | DEGREES | starting position |
--cruise | motor: 3000 RPM forward | |
--maneuver | motor: cycling phases | |
--single | motor: one engine instead of two | |
--anchored | navigation: anchored | |
--sailing | navigation: sailing | |
--harbor | AIS: harbour scenario | |
--offshore | AIS: offshore scenario | |
--traffic | AIS: heavy traffic | |
--thruster-active | thruster: cycling port/starboard | |
--coastal | route: 5 waypoints | |
--passage | route: 10 waypoints | |
-v, --verbose | log every PGN sent | |
-h, --help |
MQTT topics
<prefix> is nmea by default, nmea-<instance> for a templated instance. Every payload is {"data": …, "metadata": …} unless noted. metadata always carries rxDate (ISO 8601, UTC) and rxTimestamp (Unix seconds).
Published
| Topic | Rate | QoS | Retain | expireAfterSec | Requires |
|---|---|---|---|---|---|
<prefix>/navigation | 1 Hz or 10 Hz | 0 | yes | 2 | --report-nav |
<prefix>/motor | 1 Hz or 10 Hz | 0 | no | 5 | --report-motor |
<prefix>/thruster | 1 Hz | 0 | no | 5 | --report-thruster |
<prefix>/ais | 30 s | 0 | yes | 30 | --report-ais |
<prefix>/route | 1 Hz active, 60 s idle | 0 | yes | 30 active, 70 idle | --report-route |
<prefix>/datetime | 1 Hz | 0 | yes | 5 | always |
<prefix>/status | 30 s | 0 | yes | 60 | always |
<prefix>/config | at connect, at claim, on SIGHUP | 1 | yes | 3124137600 | always |
<prefix>/interface | 10 s | 0 | yes | 10 | always |
<prefix>/devices | on change | 0 | yes | 120 | always |
<prefix>/device/<addr>/infos | on change | 0 | yes | 120 | always |
<prefix>/device/<addr>/pgn/<pgn> | on receive | 0 | yes | 60 | --mqtt-publish-pgn |
<prefix>/gpsd | on change | 0 | yes | 10 | --source-gpsd |
<prefix>/alarm/state | on transition | 0 | no | — | --enable-alarms |
<prefix>/alarm/mute/request | on PGN 126984 | 0 | no | — | --enable-alarms |
<prefix>/alarm/unmute/request | on filter expiry | 0 | no | — | --enable-alarms |
<prefix>/alarm/error | on error | 0 | no | — | --enable-alarms |
app/nmea2000/info | at connect, at exit, last will | 1 | yes | 3124137600 | always (MQTT on) |
Subscribed
| Topic | Purpose |
|---|---|
<prefix>/alarm/active | raise or update an alarm |
<prefix>/alarm/clear | clear an alarm |
<prefix>/alarm/mute/response | answer a mute request |
<prefix>/alarm/unmute/response | answer an unmute request |
All four require --enable-alarms; without it the daemon subscribes to nothing.
<prefix>/interface
json
{
"data": {
"interface": "can1",
"state": "ERROR-ACTIVE",
"up": true,
"stats": { "tx_frames": 0, "tx_bytes": 0, "rx_frames": 0, "rx_bytes": 0,
"tx_errors": 0, "rx_errors": 0, "bus_errors": 0, "restarts": 0 },
"config": { "bitrate": 250000, "sample_point": 875, "tq": 500,
"prop_seg": 6, "phase_seg1": 7, "phase_seg2": 2,
"sjw": 1, "brp": 8, "restart_ms": 100, "ctrlmode": 0 },
"recovery": { "state": "…", "stateCode": 0 }
},
"metadata": { "rxDate": "…", "rxTimestamp": 0, "expireAfterSec": 10 }
}state is one of ERROR-ACTIVE, ERROR-WARNING, ERROR-PASSIVE, BUS-OFF, STOPPED, SLEEPING, UNKNOWN. An interface that is up but exposes no CAN state to the kernel — vcan — reports ERROR-ACTIVE.
<prefix>/devices
data carries count and peers[], each peer having addr (0–253) and name (the 64-bit J1939 NAME as a number).
<prefix>/device/<addr>/infos
Everything the daemon has learned about one device: addr, name, identityNumber, manufacturerCode, manufacturer, ecuInstance, functionInstance, deviceInstance, functionCode, functionName, classCode, vehicleSystemInstance, industryGroupCode, industryGroup, arbitraryAddressCapable, and — when the device has answered the corresponding request — productInfo, txPgns[] and rxPgns[].
deviceInstance is the 8-bit NMEA 2000 device instance, ecuInstance | (functionInstance << 3). It is the value PGN 126208 changes.
<prefix>/navigation
data sections: position, speed_course, wind_apparent, wind_true, wind (deprecated), depth_water, autopilot. Selection, the true wind computation and the deprecated wind section are in Navigation.
| Path | Type | Unit | Notes |
|---|---|---|---|
data.position.hasFix | boolean | always present in position | |
data.position.latitude, .longitude | number | degrees | only when hasFix is true |
data.speed_course.sog | number or null | knots | |
data.speed_course.cog | number or null | degrees | |
data.speed_course.speedThroughWater | number | knots | only when sent |
data.speed_course.headingTrue | number | degrees | only when resolvable |
data.wind_apparent.speed | number or null | knots | |
data.wind_apparent.angle | number or null | degrees, −180…180 | relative to the bow, starboard positive |
data.wind_true.speed | number or null | knots | |
data.wind_true.angle | number or null | degrees, −180…180 | relative to the bow, starboard positive |
data.wind_true.direction | number or null | degrees, 0…360 | relative to true north |
data.wind_true.reference | string | water or ground | |
data.wind_true.computed | boolean | true when computed from apparent wind | |
data.wind.* | m/s for speeds | deprecated, removed in the next release | |
data.<section>.source | object | only with --report-metadata-source | |
metadata.expireAfterSec | integer | seconds | 2 |
<prefix>/datetime
data carries now, date, time, localTime, utcOffset, timezone, offsetSource and a source object (name, friendlyName, pgn, age).
offsetSource follows --datetime-offset: nmea takes the local offset from the bus, auto derives it from the boat's position using the bundled ZoneDetect database.
<prefix>/status
One summary of every module, every 30 seconds: a reports object with navigation, motor, thruster, ais, route and datetime sub-objects carrying running, highSpeed, counts and per-data-type selected sources (navigation: position, heading, courseSpeed, wind, windTrue, depthWater, autopilot); and a bus object with peerCount.
<prefix>/config
The resolved configuration: modules (per-module enabled flags and their settings), navSources[] (each with name, sourceAddr, friendlyName and per-data-type priorities and block flags), mqtt (topicPrefix) and version.
app/nmea2000/info
The daemon info, retained, QoS 1, in the shape every MUXEN daemon uses on app/<daemon>/info — not the {"data", "metadata"} envelope. The topic does not carry <prefix>: the primary daemon (prefix nmea) publishes on app/nmea2000/info, a templated instance (prefix nmea-<instance>) on app/nmea2000-<instance>/info, and any other prefix p on app/nmea2000-p/info with unsafe characters replaced by _. The name is always a single topic level, so one app/+/info subscription lists every daemon and every instance.
json
{
"name": "muxen-nmea2000",
"version": "v3.7.0",
"hostname": "brain-3",
"features": ["config", "interface", "devices", "datetime", "status",
"navigation", "alarms"],
"online": true,
"metadata": { "rxdate": "2026-09-22T08:04:07.966Z",
"rxTimestamp": 1790064247, "expireAfterSec": 3124137600 }
}online is true on every (re)connect, and false on a clean exit (published, then acknowledged by the broker, before disconnecting) and as the MQTT last will when the connection is lost. version is for display only: clients test features, and ignore features they do not know. The metadata key is rxdate, lowercase, unlike the envelope's rxDate: it is the fleet-wide info shape.
features lists the <prefix>/ topic families this process serves, from its resolved configuration:
| Feature | Topics | Listed when |
|---|---|---|
config, interface, devices, datetime, status | <prefix>/config, /interface, /devices and /device/<addr>/infos, /datetime, /status | always |
navigation | <prefix>/navigation | --report-nav |
motor | <prefix>/motor | --report-motor |
thruster | <prefix>/thruster | --report-thruster |
ais | <prefix>/ais | --report-ais |
route | <prefix>/route | --report-route |
pgn | <prefix>/device/<addr>/pgn/<pgn> | --mqtt-publish-pgn |
gpsd | <prefix>/gpsd | --source-gpsd, on a build with GPSD support |
alarms | <prefix>/alarm/* | --enable-alarms |
Deploy configuration parameters
Read from the NavigationInstruments device (function 12, instance 0, device id 768) in /etc/muxen/deploy.json.
| Parameter | Type | Equivalent flag |
|---|---|---|
ReportNav | bool | --report-nav |
NavHighSpeed | bool | --nav-high-speed |
WindDamping | int 0–9 | --wind-damping |
ReportMotor | bool | --report-motor |
MotorHighSpeed | bool | --motor-high-speed |
ReportThruster | bool | --report-thruster |
ReportAis | bool | --report-ais |
AisTrackDepth | int | --ais-track-depth |
ReportRoute | bool | --report-route |
RouteMaxWaypoints | int | --route-max-waypoints |
DatetimeOffset | nmea | auto | --datetime-offset |
Booleans are the strings "0" / "1"; "true" / "false" are also accepted.
Navigation source configuration file
| Key | Type | Notes |
|---|---|---|
version | int | file format version |
windDamping | int 0–9 | same meaning as the flag |
hysteresis | object | per data type, milliseconds |
warmup | object | per data type, milliseconds |
sources[] | array | at most 256 entries |
sources[].name | string | J1939 NAME in hex |
sources[].friendlyName | string | up to 64 characters |
sources[].dataTypes[].type | string | see below |
sources[].dataTypes[].priority | int 1–99 | 1 is highest; clamped |
sources[].dataTypes[].instance | int 0–7 | motor type only |
sources[].dataTypes[].blocked | bool |
Data types: position, heading, course_speed (speed_course is accepted as a synonym on read), wind (apparent wind), wind_true, depth_water, autopilot, date, motor. A source with a wind entry and no wind_true entry gets the same settings for wind_true.
Per-data-type defaults:
| Type | TTL | Hysteresis | Warm-up |
|---|---|---|---|
position | 5 s | 1000 ms | 10000 ms |
heading | 5 s | 500 ms | 10000 ms |
course_speed | 5 s | 500 ms | 10000 ms |
wind | 2 s | 300 ms | 5000 ms |
wind_true | 2 s | the wind value | the wind value |
depth_water | 5 s | 500 ms | 10000 ms |
autopilot | 5 s | 500 ms | 5000 ms |
Selection thresholds: an unconfigured priority counts as 50; at least 2 consecutive valid messages are needed; the expiration counter excludes a source at 5; a source unheard for 60 minutes is removed. The file is refused above 1 MB.
IPC
Newline-delimited JSON over a Unix stream socket.
| Property | Value |
|---|---|
| Default path | /run/muxen-nmea2000/sources.sock |
Path when RUNTIME_DIRECTORY is set | $RUNTIME_DIRECTORY/sources.sock |
| Path for a non-root user | $XDG_RUNTIME_DIR/muxen-nmea2000/sources.sock |
| Last-resort path | /tmp/muxen-nmea2000-<uid>/sources.sock |
| Socket mode | 0666 — any local user can connect |
| Directory mode | 0750 |
| Concurrent clients | 8 |
| Per-connection deadline | 5 s |
| Request and response limit | 64 KiB each |
Verbs: ping, list_sources, get_nav_config, set_config, reload_config, command_instance, command_field, get_command_status. Envelope and semantics in Navigation.
Files and directories
| Path | Content |
|---|---|
/usr/bin/muxen-nmea2000* | the daemon and the four tools |
/usr/lib/systemd/system/muxen-nmea2000*.service | the four units |
/usr/share/muxen-nmea2000/manufacturers.json | NMEA manufacturer code to name |
/usr/share/muxen-nmea2000/functionNames.json | J1939 function code to name |
/usr/share/muxen-nmea2000/pgn.json | PGN number to name |
/usr/share/muxen-nmea2000/timezone16.bin | ZoneDetect timezone database |
/usr/share/bash-completion/completions/muxen-nmea2000* | completion, one file per binary |
/etc/nginx/snippets/muxen-ws-nmea.conf | reverse-proxy snippet |
/etc/muxen/deploy.json | the boat's commissioning file |
/etc/muxen/env.<instance> | MUXEN_NMEA_INSTANCE_NAME, MUXEN_NMEA_INSTANCE_ADDRESS |
/var/lib/muxen-nmea2000/ | state directory, mode 0750 |
/var/lib/muxen-nmea2000/state | the claimed-address state file |
/var/lib/muxen-nmea2000/nav-sources.json | navigation source configuration, under systemd |
/run/muxen-nmea2000/ | runtime directory, mode 0755 |
/run/muxen-nmea2000/sources.sock | IPC socket |
The daemon reads no environment variables of its own beyond systemd's RUNTIME_DIRECTORY and STATE_DIRECTORY.
systemd units
| Unit | Enabled at install | Notes |
|---|---|---|
muxen-nmea2000.service | yes | the commissioned daemon; WantedBy=muxen.target, PartOf=muxen.target, alias muxen-nmea.service |
muxen-nmea2000@.service | no | one instance per CAN interface, started on demand |
muxen-nmea2000-simulator.service | no | the synthetic bus generator |
muxen-nmea2000-from-simulator.service | no | a daemon on vcan0 with --report-all; Conflicts=muxen-nmea2000.service |
muxen-nmea2000.service: After=sys-subsystem-net-devices-can1.device mosquitto.service, Wants= the same device, Restart=always, RestartSec=10, TimeoutStopSec=5, StartLimitIntervalSec=300, StartLimitBurst=5, ExecReload=/bin/kill -HUP $MAINPID.
muxen-nmea2000@.service adds ConditionPathExists=/sys/class/net/%i, has no [Install] section, and passes --no-deploy-config --mqtt-topic-prefix=nmea-%i --mqtt-client-id=muxen-nmea2000-%i --state-dir=%S/muxen-nmea2000-%i --enable-alarms.
All units run as User=muxen / Group=muxen with AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN, the same bounding set, ProtectSystem=strict, ProtectHome=yes, NoNewPrivileges=yes, PrivateTmp=yes, MemoryDenyWriteExecute=yes, SystemCallFilter=@system-service, SystemCallArchitectures=native, DevicePolicy=closed and RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_CAN AF_INET AF_INET6.
Packaging
Debian package muxen-nmea2000, section net, Architecture: any, Multi-Arch: foreign. Depends: muxen-systemd plus the shared-library dependencies. It ships a muxen-restart-target trigger, so an install or upgrade restarts muxen.target, and activates nginx-reload, so a running nginx reloads and serves a changed muxen-ws-nmea.conf at once.
nginx
/etc/nginx/snippets/muxen-ws-nmea.conf maps /ws/nmea to http://127.0.0.1:1884/ with WebSocket upgrade headers and a 15-day read timeout. That port is the MQTT broker's WebSocket listener, not the daemon: this is how a browser front end reaches the same topics.
TypeScript package
@muxen/nmea, in typescript/@muxen-nmea/, versioned and tagged together with the daemon. Entry points ., ./message-types, ./plugin. Peer dependencies: mqtt ^4.3.0 || ^5.0.0, and optionally vue ^3.3.0 and pinia ^2.1.0. Node 18 or later.
The store always subscribes to the daemon info of its topicPrefix (nmeaInfoTopic(), same derivation as the daemon) and exposes info, online and supports(feature), also on the useNmea() service; DaemonInfo, NMEA_INFO_TOPIC and isDaemonInfo() are exported.
Units and conventions
| Quantity | Unit in published payloads |
|---|---|
| angles | degrees |
| speed over ground, through water, wind | knots (m/s in the deprecated navigation wind section) |
| depth, altitude, cross-track error | metres (distances to waypoints in nautical miles) |
| temperature | °C |
| pressure | kPa |
| fuel rate | litres per hour |
| fuel economy | litres per nautical mile |
| engine speed | RPM |
| time | ISO 8601 UTC in rxDate, Unix seconds in rxTimestamp |
A value the sender marks as not available is published as null, never as zero.
Schemas
| File | Describes |
|---|---|
| schemas/mqtt-schemas.json | the per-device PGN topics |
| schemas/ais-schema.json | <prefix>/ais |
| schemas/ais-sample.json | a worked <prefix>/ais payload |
