Posts: 30
Threads: 5
Joined: Jun 2017
Reputation:
0
2021-08-18, 01:39 PM
(This post was last modified: 2024-09-15, 09:11 AM by Sjoerd02.)
Hi all,
I have connected a YDTA-01N tankadapter on my tanksensor.
The divice seems to work OK, on the SD card it's writing the correct tank content (80% ~ 88 liter)
I connected the sensor to the N2K network.
The Shipmodule miniplex 3E N2K is getting the input from the tankmodule and from the logfile I can see for example:
$MXPGN,01F211,68BB,FF0000044C4EA800*60
The miniplex send this to UPD 10120
in the SK log I find:
Aug 17 11:54:21 2021-08-17T09:54:21.871Z canboatjs:fromPgn parsed pgn {"prio":0,"pgn":127505,"dst":255,"src":391,"input":["$MXPGN,01F211,68BB,FF0000044C4EA800*60"],"fields":{"Level":0,"Capacity":282370355.6,"Reserved1":"0"},"description":"Fluid Level","timestamp":"2021-08-17T09:54:21.871Z"}
So it look like the data is recieved in SK, however not the values like 80% and/or 88Liter
Now I have some questions:
1) How is propriatarie MXPGN recognized as N2000?
2) How is the data being read from the MXPGN sentence?
Thanks in advance
Posts: 341
Threads: 0
Joined: Apr 2016
Reputation:
23
src could never get higher than 255 but that doesn't matter.
If you change the direction of the 8 data bytes (00 A8 4E 4C 04 00 00 00 FF)
00 -> instance 0 and type of tank fuel
A8 4E = 168 + 78*256 = 20136 (this must be multiplied with 0,004) -> 80,544 % level
4C 04 00 00 = 76+1024 = 1100 (multiplied with 0,1) -> 110 liter capacity
8BB
8 - length = 8
BB - src = 187
Are you shure you have the latest version of Signal K?
File /usr/lib/node_modules/signalk-server/node_modules/@canboat/canboatjs/lib/stringMsg.js changes the data byte direction. This fix was done on Mar 3, 2021.
Posts: 30
Threads: 5
Joined: Jun 2017
Reputation:
0
Thanks E-sailing.
Got a simulair answer from Shipmodule support in meantime as well.
But always good to share some knowledge here.
I have SK version 1.40
I found the file it was timestamped 10/26/1985 09:15 so I asume the date is not valiid
The MXPGN code in my server is:
Code: // $MXPGN,01F801,2801,C1308AC40C5DE343*19
exports.isMXPGN = startsWith('$MXPGN,')
exports.parseMXPGN = (input) => {
const [ prefix, pgn, attr_word, data ] = input.split(',')
const send_prio_len = (parseInt(attr_word.substr(0,2), 16).toString(2)).padStart(8, '0');
const addr = (parseInt(attr_word.substr(2,2), 16));
const send = parseInt(send_prio_len.substr(0,1), 2);
const prio = parseInt(send_prio_len.substr(1,3), 2);
const len = parseInt(send_prio_len.substr(4,4), 2);
let src, dst;
send ? dst = addr: src = addr;
return buildMsg(
buildCanId(0, parseInt(pgn, 16), 255, parseInt(src, 16)),
'MXPGN',
Buffer.from(rmChecksum(data), 'hex'),
{ coalesced: true, prefix },
)
}
exports.encodeMXPGN = ({ prefix = '$MXPGN', pgn, prio, src, data }) => {
if (src > 255) src = 255;
if (!prio) prio = 3;
if (!src) src = 255;
const dataLength = hexByte(128 + (prio * 16) + (byteString(data, '').toUpperCase().length / 2)).toUpperCase()
const attribWord = dataLength + hexByte(src).toUpperCase()
var buff = Buffer.from(byteString(data, ''), 'Hex');
for (var i = 0, j = buff.length - 1; i < j; ++i, --j) {
var t = buff[j]
buff[j] = buff[i]
buff[i] = t
}
const sentence = [prefix, toPaddedHexString(pgn, 6), attribWord, buff.toString('Hex').toUpperCase()].join(',')
return sentence + compute0183Checksum(sentence)
}
The only reference I found on MXPGN in gethub is this commit
https://github.com/canboat/canboatjs/com...df17fa3edf
As far as I see I have this commit installed.
Posts: 341
Threads: 0
Joined: Apr 2016
Reputation:
23
If you have checked that you have the latest firmware on your shipmodul, you can try the original series (comment out two lines of the code).
Code: for (var i = 0, j = buff.length - 1; i < j; ++i, --j) {
var t = buff[j]
//buff[j] = buff[i]
//buff[i] = t
}
Posts: 30
Threads: 5
Joined: Jun 2017
Reputation:
0
2021-10-08, 10:28 PM
(This post was last modified: 2021-10-20, 10:47 PM by Sjoerd02.)
Hello,
I was having a look again in this issue tonight.
I do not understand the code.
I tried to comment-out the 2 buf lines, but it still does not give the correct result.
Actually I do not see difference in the output
Currently I have this in the log:
Code: canboatjs:fromPgn parsed pgn {"prio":0,"pgn":127505,"dst":255,"src":391,"input":["$MXPGN,01F211,68BB,FF0000044C42B600*1A"],"fields":{"Level":0,"Capacity":305779814.8,"Reserved1":"0"},"description":"Fluid Level","timestamp":"2021-10-08T20:29:06.326Z"}
As you explained before the correct translation should be:
LEVEL: 42B6=17078x0.004= 68.312%
Capacity: 044C = 1100 = 110l lit
Is there a way I can add more detailed logging in this function in order to see what happens exactly?
Thanks for your help!
Posts: 30
Threads: 5
Joined: Jun 2017
Reputation:
0
Boat is on the dry so started to use the http://localhost:3000/admin/#/serverConf...atafiddler to further investigate.
I added logging to stringMSG.js
I found exports.encodeMXPGN code mentioned above is not used.
Only exports.parseMXPGN is being used.
Also I tried to reverse the HEX words manualy so tested:
$MXPGN,01F211,68BB,004EA80000044CFF
Then I get at least some valid data:
Code: "values": [
{
"path": "tanks.fuel.0.currentLevel",
"value": 1.7234399999999999
},
{
"path": "tanks.fuel.0.capacity",
"value": 127533.056
}
]
this looks better however values not yet correct.
==> which piece of code should reverse the HEX words?
==> where are the values calculated
to be continued.
Tips are welcome
Posts: 30
Threads: 5
Joined: Jun 2017
Reputation:
0
I finally found the solution (as a non developer)
The solution by e-sailing was in the right direction but not correct.
1) the problem is in the reading, exports.parseMXPGN and not in exports.encodeMXPGN which is I assume the sending part.
2) the code for reversing the Bytes is not working.
I found a function on internet
Code: const changeEndianness = (string) => {
const result = [];
let len = string.length - 2;
while (len >= 0) {
result.push(string.substr(len, 2));
len -= 2;
}
return result.join('');
}
So added it in the stringMsg.js
And updated like:
Code: exports.parseMXPGN = (input) => {
console.log('MXpgn parse input' + input)
const [ prefix, pgn, attr_word, data ] = input.split(',')
console.log('MXpgn parse data ' + data)
var buff = changeEndianness(rmChecksum(data));
const send_prio_len = (parseInt(attr_word.substr(0,2), 16).toString(2)).padStart(8, '0');
const addr = (parseInt(attr_word.substr(2,2), 16));
const send = parseInt(send_prio_len.substr(0,1), 2);
const prio = parseInt(send_prio_len.substr(1,3), 2);
const len = parseInt(send_prio_len.substr(4,4), 2);
console.log('stringMsg:MXpgn parse: attr_word ' + attr_word)
console.log('stringMsg:MXpgn parse: ' + addr + ' ' + send + ' ' + prio + ' ' + len)
let src, dst;
send ? dst = addr: src = addr;
return buildMsg(
buildCanId(0, parseInt(pgn, 16), 255, parseInt(src, 16)),
'MXPGN',
Buffer.from(buff, 'hex'),
{ coalesced: true, prefix },
)
}
For incomming messages it's working fine now.
I did not test for outgoing yet, but I expect the same function should be used.
I will propose this change in github.
Posts: 30
Threads: 5
Joined: Jun 2017
Reputation:
0
2024-09-15, 09:17 AM
(This post was last modified: 2025-04-02, 06:21 AM by Sjoerd02.
Edit Reason: charge = change
)
Solved in 2 ways:
1) last year by Shipmodule : Added parsing to XDR sentence and so werking around the issue in SK
2) recently: the above change was finally accepteren in SK - did not test myself.
Posts: 5
Threads: 0
Joined: Feb 2025
Reputation:
0
 (2024-09-15, 09:17 AM)Sjoerd02 Wrote: Solved in 2 ways: That's Not My Neighbor
1) last year by Shipmodule : Added parsing to XDR sentence and so werking around the issue in SK
2) recently: the above charge was finally accepteren in SK - did not test myself.
Can you share more about your real-world experience using the latest solution, for example how it improves performance compared to Shipmodule’s? I’m curious because after reading it, I feel like both approaches have their strengths, but I’m not sure which one is smoother in practice!
Posts: 30
Threads: 5
Joined: Jun 2017
Reputation:
0
Typo correction charge = change
Performance is not an issue here, tank data is only send once per 10 mins by default.
I am now using the XDR sentence provided by the shipmodule, not needing the MXPGN raw data avoiding the HEX translation issue.
For other unknown PGN's the correct parsing of the HEX values will be important again using the MXPGN
|