Conversation
|
This PR is getting to the "too many things to digest at once" category. Would it make sense to split it up:
I am open to other ways to split it up.
Also there's now confusion about naming: what is priority and what is ranking? |
|
Hmmm, maybe it was me misunderstandding the N2K CAN name related comments, screenshots show the real thing. |
All of it plays hand in hand and has dependencies. I spent > 16 hours in the QA already. Splitting this would mean this effort by 3-4 times again. Now for each individul PR in every possible configurtion. I am not really motivated just for a nice split in the PR history to go trough this. |
26fd4a0 to
a867d4e
Compare
103d708 to
7a8eae6
Compare
NoteFor the Victron MPPT changes I used: |
|
I have some very interesting beta tester feedback and want to analyze this first. |
7a8eae6 to
6910045
Compare
7455663 to
738331e
Compare
db29a98 to
035267c
Compare
035267c to
a0dd137
Compare
|
Note:Currently Once PR canboat/ts-pgns#44 is merged and released this will be reduced to — ~0.115 MB raw. Note on |
197d084 to
a04a051
Compare
|
Way too much for this PR - must be discussed separately if still relevant. |
Use the device's unique CAN Name (from ISO Address Claim) as the primary identifier in $source instead of the volatile source address. Auto-migrate sourceRef in source labels and priorities when a device's CAN name changes (e.g. firmware update alters the name string).
…e delta cache Add source ranking (global priority list) and path-level source priorities with timeout-based fallback. Extend delta cache to store all sources. Add sourcePolicy to subscriptions. Add N2K device discovery and configuration endpoints. Fix phantom source metadata in notification alarms.
… management Add Source Priority page with global ranking and path-level overrides. Add Data Browser with virtualized table and granular subscriptions. Add Source Discovery with N2K device table, instance conflict detection (using compound instance+source keys for temperature/humidity PGNs), device configuration, online/offline badges, manufacturer warnings, and read-only mode for WS-proxied connections.
… docs Add setup guides for source priority and N2K device management. Update plugin docs for sourcePolicy and PUT handler permissions. Add cross-references from existing pages.
Replace hardcoded PGN instance sets and temperature/humidity enum maps with runtime derivation from @canboat/ts-pgns metadata. Upstream canboat now has complete Maretron PGN definitions including 130823, making local hardcoding unnecessary.
Numeric string values like N2K source addresses were sorted
lexicographically ("2", "248", "48") instead of numerically.
…iles The test config only disabled the base `no-unused-expressions` rule, leaving the TypeScript variant active. This prevented `.ts` test files from using chai property assertions like `.to.be.true` or `.to.exist`.
a04a051 to
05676b5
Compare
The sidebar badge count included ignored conflicts because it called detectInstanceConflicts without filtering. Move ignoredInstanceConflicts from local component state to the Zustand store so the sidebar can exclude them from the count.
n2kMapper.requestMetaData() crashes on address changes when N2K output is not available (e.g. UDP receive-only) because n2kListener is undefined. Provide a no-op emitter as safe default until the real listener is registered.
85a5ea7 to
3b43ada
Compare
deviceInstance from canboatjs PGN 60928 disagrees with the sub-fields deviceInstanceLower/deviceInstanceUpper. Compute it from sub-fields (DIL + DIU * 8) when available. Proprietary PGNs (>=130816) without instance data were flagged conservatively as conflicts. Skip them since they can't be verified.
3b43ada to
9aef01b
Compare
…covery Data Instance (a per-PGN field in data messages) is unrelated to deviceInstanceLower (ECU Instance from PGN 60928 NAME). The column was confusing and showed the wrong concept. Dev Instance already shows the correct combined device instance.
The CAN Name (raw PGN 60928 bytes) is the authoritative source for device instance sub-fields. Parsed fields from canboatjs can be stale after a device instance change because FullSignalK merges old values via _.assign. Prefer CAN Name over parsed fields since it always reflects the latest Address Claim.


Summary
This PR reworks how Signal K Server handles multiple data sources. On any boat with more than one GPS, a mix of NMEA 2000 and NMEA 0183 devices, or plugins that calculate derived values, the server receives the same data path from several sources. Until now, managing this was difficult: sources were identified by unstable addresses, lower-priority data was silently discarded, and there was no way to see what was actually happening on the bus.
This started from issue #2162 and the discussion with @tkurki, @macjl, and @KEGustafsson. It implements all seven phases from the revised plan, plus N2K device management that came up along the way.
What changed
Stable source identification
NMEA 2000 sources are now identified by their CAN Name — a globally unique identifier from the device's ISO Address Claim — instead of the source address. A Furuno SCX-20 shows up as
can0.Furuno_SCX-20regardless of what address it happens to claim on the bus. No more broken priority configurations after adding or removing a device.For NMEA 0183, a new talker group configuration lets you tell the server that talker IDs GP, GL, and GN on serial0 are all the same GPS. Without this, a multi-constellation receiver looks like three separate sources.
All source data is preserved
Previously,
toPreferredDelta()stripped non-preferred values from deltas before they entered the delta chain. Lower-priority sensors were invisible — the server, the UI, and all clients had no idea they existed.Now all source data flows into the delta cache and data model. Priority filtering moved to the subscription layer: WebSocket clients and plugins receive preferred-source data by default, but can opt in to everything with
sourcePolicy=all. This means you can actually see what all your sensors are reporting, compare readings, and debug issues — while the default behavior still delivers clean, prioritized data.Source ranking
A new global source ranking lets you say "always prefer GPS A over GPS B for everything they both provide." This covers the common case without configuring every path individually. Path-level overrides still exist for the exceptions. Sources can be disabled entirely, and each fallback source has a configurable timeout.
N2K device discovery and instance management
The Source Discovery page shows every NMEA 2000 device on the bus in a sortable table with manufacturer, model, serial number, firmware version, and device class. You can edit device instances, data instances, battery instances (PGN 127508), DC instances (PGN 127506), and installation descriptions — directly from the browser, without needing an Actisense NGT-1 or dedicated PC software.
The server automatically detects instance conflicts — two devices with the same instance transmitting overlapping PGNs — and shows them as warnings with one-click filtering to the conflicting pair. This is a real time-saver on boats with multiple Victron MPPTs or similar devices that all default to instance 0.
Reorganized Data menu
The Data menu now has dedicated pages:
The Data Browser dropped its virtual table implementation. The previous approach added complexity without meaningful benefit for the data volumes involved. The WebSocket subscription model was also reworked — instead of subscribing to everything and filtering client-side, it uses granular subscriptions with
announceNewPathsto discover available paths while only receiving continuous updates for visible ones.Developer API
Plugins can use
sourcePolicy: 'all'in their subscription options to receive data from every source. WebSocket clients can pass?sourcePolicy=allas a query parameter. The default remainspreferredso existing clients are unaffected.Breaking changes
Two things that existing users may need to update:
N2K
$sourceformat changed — fromcan0.22tocan0.Furuno_SCX-20. ExistingsourcePrioritiesentries in settings.json that reference old-style addresses will no longer match. The Source Priority UI makes it easy to reconfigure.All source data is now visible in the data model — plugins and clients that query the REST API or data model directly may see additional sources they didn't see before. WebSocket subscriptions are not affected unless
sourcePolicy=allis explicitly requested.Both are documented in
docs/breaking_changes.md.Not in this PR
Two items from the original discussion are natural follow-ups but separate in scope:
Tests
Manual tests
Automatic Tests
Six test files with 1100+ new lines covering the priority engine (ranking, timeouts, disabled sources, fallback), delta cache (multi-source tracking, source removal, preferred source selection), NMEA 0183 talker groups, WebSocket sourcePolicy integration, source label resolution, and priorities store actions.
All 141 existing tests continue to pass.
Images
See #2162 (comment)*
Fixes: #2162
Fixes: #1916
Fixes: #1885
Fixes: #1768 - Workflow superseeded
Fixes: #1754
Fixes: #1747
Fixes: #1571
Fixes: #1555
Fixes: #1369
Fixes: #1327
Fixes: #1272
Fixes: #1258
Fixes: #1183
Fixes: #2474