night199uk - i'm trying to make some updates to...
i'm trying to make some updates to signalk-to-nmea2000 to add new PGNs (raymarine autopilot PGNs again). to get the newer PGNs that are in canboat/canboatjs, i need to update the canboatjs version that signalk-to-nmea2000 pulls in (it's an old 2.x).
i notice that canboatjs has moved to camelCase. this breaks all the tests in signalk-to-nmea2000 when updating the canboatjs version > 3.0.0.
is anyone already working on a PR for this, any guidance on a simple way to fix?
@Scott Bender probably
47 Replies
But you can still update the version, when in sk canboatjs is output it both camelCase and the old way
Thus how it is currently working in the latest sk server versions which use the latest canboatjs
yeah. updating the version within signalk-to-nmea2000 broke the other tests 🙂
will that PR landing ^^^ automagically fix the tests in signalk-to-nmea2000?
Yes
But I don’t know when I’m going to get around to finishing that…
okay, so it's not helpful for me to start working on that in signalk-to-nmea20000
is it something i could help with? now i got my boat back in the water and living aboard - i really want to get 130848 and 130918 working so i can use signalk to drive my raymarine autopilot full time.
my axiom 2 pro's SUCK and Lighthouse 4 has so many bugs and issues and i just need to get rid of them and move to signalk as my plotter.
we sail full time now and i can't deal with how bad lighthouse 4 is. 🤦‍♂️
The AP plugin does not work for you?
Sorry, on the phone, what are those pgns?
the AP plugin lets me do simple +1 / +10. but 130848 and 130918 + 129284/129285 let me follow a full pre-programmed route from signalk/freeboard.
You can update the tests to turn off camelCase
i.e. i can make a route in freeboard and then hit "track" on the AP and the boat just folllows the full track.
Or turn on camelCaseCompat mode
@Scott Bender any tips on how to do that? otherwise i can go spelunking. i am motivated to get this working and have a few weeks sat here in annapolis until the boat show.
GitHub
signalk-to-nmea2000/test/test.js at 444a955854a1159684cde0990cdec08...
Plugin to convert Signal K to NMEA2000. Contribute to SignalK/signalk-to-nmea2000 development by creating an account on GitHub.
i see, so at the parser creation we can control the mode? let me go digging on that. thanks!
const parser = new FromPgn({useCamelCompat: true})
actually, should probably
const parser = new FromPgn({useCamelCase: false})
will be sailing past Annapolis tomorrow...
okay, doesn't work off the bat, but that gets me a breadcrumb. let me work on this. would you accept an interim PR just to update package.json and enable compat?
come say hi! where you going?
Wye River
oh nice. going to the boat show in a few weeks? or heading straight past?
I am local, on the Magothy River, so I will be at the boat show
I am surprised that does not work...checking
sorry, the option is
useCamel
not useCamelCaseconst parser = new FromPgn({useCamel: false})
yup, just found. 🙂
works. there are some other minors now, but I can clean this up and PR these which will unblock me.
after updating to canboatjs > 3.x for this, i'm seeing an issue with encoding/decoding just one pgn in the test suite - 126720 (Seatalk Display Brightness)
i've simplified this to the following simple test case; which successfully encodes the PGN but fails to decode it. this is a simpler version of the test in the signalk-to-nmea2000 test suite.
trying to debug this myself but it's deeper in canboat/canboatjs so it'll take me time to understand all of whats going on there. highly suspect you could figure this out faster than me.
That’s interesting because I am having an issue with my signalk-n2k-displays plugin, but that is with changing the color.
Brightness is working b
Note that you can use that plugin to change the brightness via PUT
I suspect the two issues are related. I’ll look into it this weekend…
ahh. looking deeper, it looks like perhaps seatalk brightness is not making it into the PGNs that canboatjs knows?
oh, i don't need to change it myself. I'm just trying to get signalk-to-nmea2000 working and passing the test suite with canboatjs > 3.0.0
adding some debug in FromPgn.readPGN, i only see seatalk1PilotMode in pgnData as a possible PGN to decode 126720 to. I don't see seatalk1DisplayBrightness as a decode option.
so the issue is probably deeper in findMatchPgns somewhere. working on that.
aha. so the problem is in readPgns, findMatchPgns is only returning one entry (seatalk1PilotMode), despite there being multiple instances of 126720 in pgnList that have Match entries defined...
getting there.
find only returns the first match from the array, in this case pgnList. as far as I grok the code, we want all PGNs with a Match entry defined.
Hmm. Yeah. That would do it.
That should be filter() I think
hrm, sort of. getting close.
what is the goal of findMatchPgn?
the code expects findMatchPgn to return a singular pgn (pgnData), not a list. i changed the find to filter; which returns a list, but this breaks further down.
it would seem like the goal of findMatchPgn is to find the exact pgn, given a list of PGNs, that we should use to parse our incoming pgn. but findMatchPgns isn't complex enough to do that.
I need to take a closer look at the code. I think you are right. That should find the exact match.
I am underway now…
cool, no worries. just noodling on this.
trying to unblock myself, no rush.
is there a simple way to make canboatjs 3.x fall back on the old canboat parsing code? i guess from what i'm reading here you're moving the pgn parsing up into canboatjs./
The parsing has always been there. But this part has changed a lot
If the only thing blocking you for now is the tests. Just install and use your local version of the plugin until I figure this out?
am already doing that. just wanted to finish off this PR 🙂 also just figured i'd fix it myself & PR it instead of forcing you to work on it.
So something is wrong with that that findMatchingPGn function, I just don’t know what it is…
And it does explain my issue…
yeah.
i'm trying to figure out what findMatchPgn is trying to achieve, because we pass the full pgnList into readFields, and pgnData is just "startDef"
i assume we want to read all the fields from all of the possible PGNs in a kind of scatter approach, and then i guess we filter the list later to only output PGNs in which all the fields match
otherwise findMatchPgn needs to be much more complex, and needs to accept the incoming PGN and then actually do the matching of match fields
let me try a few things
okay, so from what i can surmise, findMatchPgn is only to get the list of PGNs with a "Match" field defined; that could possibly be candidates for decoding the PGN.
it can't go further than that as the pgn is not yet decoded. so it's to find a list of possible decoders for the pgn. therefore; it can't actually do the matching. it should return a list of possible matchPgns in my mind. this means readFields needs to change.
by the time we call findMatchPgn the pgn is not yet decoded, so we can't actually "do" the matching in findMatchPgn.
I don’t think issue is in the decoding.
It’s in the encoding
i thought that originally too. the actisense stream "looked" wrong,
but didn't dig into it enough to check.
If it was in decoding, there would tons of issues coming up
One way to check is by running the encoded data through the canboat analyzer
fair, let me try that
And part of our confusion here, I thought we were talking about encoding! 🤣
When encoding, this kind of match happens, but it’s an exact match. Where as when decoding, we are looking for the list of possible pgns as we decode more fields.
yup, that makes sense with what i read.
Seems like it might not be finding the correct pgn definition to decode?
is there a way to send an actisense string like this to canboat analyzer?
2025-09-26T15:42:18.401Z,2,126720,0,255,21,3b,9f,8c,ff,ff,01,00,00,ff,ff,ff,00,00,00,00,00,00,00,00,00,00
Yes
Just run analyzer and paste that
Same with analyzerjs
yes. what i see of the decoder is that it finds the first or any pgn with a Match field and uses that to decode the fields in the PGN. then tries to match those values against the "possibly" pgn list.
Yep
yup, canboat also doesn't decode it:
2025-09-26T15:42:18.401Z,2,126720,0,255,21,3b,9f,8c,ff,ff,01,00,00,ff,ff,ff,00,00,00,00,00,00,00,00,00,00
2025-09-26T15:42:18.401Z 2 0 255 126720 0x1EF00: Manufacturer Proprietary fast-packet addressed: Manufacturer Code = Raymarine; Industry Code = Marine; Data = 8C FF FF 01 00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00
that's the top level PGN of 126720. 126720 is heavily overloaded with manufacturer definitions it looks like, there is Garmin stuff in there, raymarine stuff in there.
so looks like there is an encoding issue for sure.
(or canboat has the same bug as canboatjs)
aha. so i went back to canboatjs 2.x and made it encode the same pgn
canboatjs 2.x:
2025-09-26T15:59:09.022Z,2,126720,0,255,9,3b,9f,8c,0c,02,01,00,55,00
canboatjs 3.x.x:
2025-09-26T15:42:18.401Z,2,126720,0,255,21,3b,9f,8c,ff,ff,01,00,00,ff,ff,ff,00,00,00,00,00,00,00,00,00,00
good call.
let me try and make canboatjs 3.x decode the canboatjs 2.x pgn
canboatjs3.x:
it's an encoding issue not a decoding one, you're right.
So my guess is that it is not finding the right pgn definition to encode
But that’s a huge guess!!
looking now
getting there...
🤦‍♂️
??
"Proprietary ID": "0x0c8c",
the original test case for Raymarine Brightness had Proprietary ID encoded like this
I don't know how this is supposed to map, but the encoder in canboatjs 3.x no longer groks this.
prop ID is meant to be a lookup value with these:
LookupEnumeration: 'SEATALK_MESSAGE_ID',
so somehow the encoder was mapping 0xc8c to that enum; or more likely encoding it literally into the field. in canboatjs 3.x that doesn't work.
changing:
"Proprietary ID": "DIsplay",
fixes it.
now with canboatjs 3.x:
2025-09-26T16:30:10.680Z,2,126720,0,255,9,3b,9f,8c,ff,02,ff,00,55,00
canboatjs 2.x:
2025-09-26T15:59:09.022Z,2,126720,0,255,9,3b,9f,8c,0c,02,01,00,55,00
still a difference, but closer.
i'm guessing the differences now are from updates to the field definition
yup, the definitions of all the seatalk commands were updated underneath and this test case wasn't updated... simple fix now.
Well, dang