v0.3.1
Released March 10, 2026. GitHub Release | Full Changelog
56 commits since v0.2.0.
Highlights
PGN Code Generator & Decoder Library
A complete NMEA 2000 PGN code generation system (pgngen) that reads .pgn DSL definitions and generates Go structs, decoders, encoders, Protobuf definitions, and JSON Schema. The DSL supports enums, lookup tables, value-based dispatch for proprietary PGNs, repeated fields (repeat=), struct definitions, STRING_LAU, dynamic repeats, string trimming (trim=), name-only PGNs, unknown field markers, and draft annotations.
New PGN definitions:
| Category | PGNs |
|---|---|
| AIS | 129038 (Class A Position), 129039 (Class B Position), 129041 (AtoN), 129793 (UTC/Date), 129794 (Static/Voyage), 129809 (Static Part A), 129810 (Static Part B) |
| Navigation | 129285 (Route WP Information), 129026 (COG/SOG with change-tracking tolerances) |
| GNSS | 129540 (Sats in View), Distance Log, Magnetic Variation, GNSS DOPs |
| Engine/Electrical | 127489 (Engine Parameters Dynamic), 127506 (DC Source Status), 127509 (Inverter Status), 127513 (Battery Config), 127750 (Converter Status) |
| AC Power | 65010-65016 (Utility Power Monitoring) |
| Misc | 126993 (Heartbeat), Binary Switch Bank |
Change Tracking
New ChangeTracker with field-level tolerance-aware diffing. Detects meaningful data changes while ignoring noise within configured tolerances. Available in lplex via the --changes flag. Tolerances are defined per-field in the PGN DSL using the tolerance= attribute.
lplex dump --changes --decode
Display Filter Expressions
BPF-inspired display filter expressions for lplex via the --where flag. Supports header fields (pgn, src, dst, prio), decoded struct fields by JSON tag, and lookup sub-accessors (register.name).
lplex dump --where "pgn == 129025"
lplex dump --where "sog > 5.0"
lplex dump --where "register.name == 'Battery Voltage'"
Send Policy & On-Demand Queries
Gated /send and /query endpoints with configurable send policies. The /query endpoint issues ISO Request (PGN 59904) to solicit on-demand PGN responses from devices. Rules support PGN values, ranges, comma-separated lists, and name-based filtering with deny/allow semantics.
Smart Boat Discovery
New --boat flag in lplex for automatic server discovery: tries mDNS on the local network first, falls back to cloud if available.
lplex dump --boat myboat # mDNS first, cloud fallback
Auto-Reconnecting Subscriptions
Watch API in the Go client library (lplexc) with exponential backoff for automatic reconnection on connection loss.
Monitoring & Health
- Prometheus metrics endpoint (
GET /metrics) - Health check endpoint (
GET /healthz) - Bus silence alerting to detect CAN bus disconnection
Decoded Values Endpoint
GET /values now returns field-level decoded PGN values, not just raw bytes.
Exclusion Filters
exclude-pgnandexclude-namefilters across the HTTP API, sessions, andlplex- Client-side PGN filtering in
lplexandlplex.conf
Replication Improvements
- Configurable resource protections (limits on per-instance memory and goroutines)
- End-to-end integration test covering boat lplex-server -> cloud lplex-cloud -> SSE
Output Improvements
- Enum values serialized as JSON strings for known labels, numbers for unknown
- Lookup fields displayed as
{id, name}objects in decoded output - Decode errors shown in red, decoded data on same line in
lplex
Documentation
Documentation site moved into website/ with Docusaurus, deployed to GitHub Pages.
Bug Fixes
- Fix cloud journal archival to S3
- Fix exclude-pgn filter dropped in buffered session creation
- Fix incorrect padding in PGN 130310 and 130311 definitions
- Fix WaterDepth PGN definition
- Fix proprietary PGN registry description for dispatched PGNs
- Fix broken doc links
- Fix Docker build for multi-platform images (TARGETARCH)
- Pad short PGN data with 0xFF instead of erroring
- Return (nil, nil) for unknown proprietary PGN discriminator values
Security
- Fix CVE in serialize-javascript dependency
- Fix uncontrolled slice allocation in
EventLog.Recent(multiple rounds of hardening) - Break CodeQL taint chain for slice allocation
Install / Upgrade
Homebrew (lplex client only):
brew install sixfathoms/tap/lplex
Debian/Ubuntu (server):
# Download .deb from GitHub Releases
sudo dpkg -i lplex_0.3.1_linux_*.deb
sudo systemctl restart lplex-server
Docker:
docker pull ghcr.io/sixfathoms/lplex:v0.3.1