@canboat/canboatjs 3.0.2 → 3.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/publish.yml +18 -9
- package/.github/workflows/test.yml +2 -2
- package/.github/workflows/test_canboat_changes.yml +91 -0
- package/.husky/pre-commit +4 -0
- package/.mocharc.js +7 -0
- package/.prettierrc.json +5 -0
- package/README.md +5 -14
- package/dist/actisense-serial.d.ts +17 -0
- package/dist/actisense-serial.d.ts.map +1 -0
- package/dist/actisense-serial.js +569 -0
- package/dist/actisense-serial.js.map +1 -0
- package/dist/bin/actisense-file.d.ts +3 -0
- package/dist/bin/actisense-file.d.ts.map +1 -0
- package/dist/bin/actisense-file.js +49 -0
- package/dist/bin/actisense-file.js.map +1 -0
- package/dist/bin/actisense-n2k-tcp.d.ts +3 -0
- package/dist/bin/actisense-n2k-tcp.d.ts.map +1 -0
- package/dist/bin/actisense-n2k-tcp.js +46 -0
- package/dist/bin/actisense-n2k-tcp.js.map +1 -0
- package/dist/bin/actisense-serialjs.d.ts +3 -0
- package/dist/bin/actisense-serialjs.d.ts.map +1 -0
- package/dist/bin/actisense-serialjs.js +51 -0
- package/dist/bin/actisense-serialjs.js.map +1 -0
- package/dist/bin/analyzerjs.d.ts +3 -0
- package/dist/bin/analyzerjs.d.ts.map +1 -0
- package/dist/bin/analyzerjs.js +61 -0
- package/dist/bin/analyzerjs.js.map +1 -0
- package/dist/bin/candumpjs.d.ts +3 -0
- package/dist/bin/candumpjs.d.ts.map +1 -0
- package/dist/bin/candumpjs.js +73 -0
- package/dist/bin/candumpjs.js.map +1 -0
- package/dist/bin/cansend.d.ts +3 -0
- package/dist/bin/cansend.d.ts.map +1 -0
- package/dist/bin/cansend.js +123 -0
- package/dist/bin/cansend.js.map +1 -0
- package/dist/bin/ikonvert-serial.d.ts +3 -0
- package/dist/bin/ikonvert-serial.d.ts.map +1 -0
- package/dist/bin/ikonvert-serial.js +36 -0
- package/dist/bin/ikonvert-serial.js.map +1 -0
- package/dist/bin/to-pgn.d.ts +3 -0
- package/dist/bin/to-pgn.d.ts.map +1 -0
- package/dist/bin/to-pgn.js +57 -0
- package/dist/bin/to-pgn.js.map +1 -0
- package/dist/canId.d.ts +21 -0
- package/dist/canId.d.ts.map +1 -0
- package/dist/canId.js +66 -0
- package/dist/canId.js.map +1 -0
- package/dist/canId.test.d.ts +2 -0
- package/dist/canId.test.d.ts.map +1 -0
- package/dist/canId.test.js +58 -0
- package/dist/canId.test.js.map +1 -0
- package/dist/canbus.d.ts +17 -0
- package/dist/canbus.d.ts.map +1 -0
- package/dist/canbus.js +261 -0
- package/dist/canbus.js.map +1 -0
- package/dist/candevice.d.ts +23 -0
- package/dist/candevice.d.ts.map +1 -0
- package/dist/candevice.js +36 -0
- package/dist/candevice.js.map +1 -0
- package/dist/codes.d.ts +2 -0
- package/dist/codes.d.ts.map +1 -0
- package/dist/codes.js +24 -0
- package/dist/codes.js.map +1 -0
- package/dist/discovery.d.ts +17 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +119 -0
- package/dist/discovery.js.map +1 -0
- package/dist/fromPgn.d.ts +51 -0
- package/dist/fromPgn.d.ts.map +1 -0
- package/dist/fromPgn.js +989 -0
- package/dist/fromPgn.js.map +1 -0
- package/dist/fromPgnStream.d.ts +17 -0
- package/dist/fromPgnStream.d.ts.map +1 -0
- package/dist/fromPgnStream.js +47 -0
- package/dist/fromPgnStream.js.map +1 -0
- package/dist/ikonvert.d.ts +17 -0
- package/dist/ikonvert.d.ts.map +1 -0
- package/dist/ikonvert.js +224 -0
- package/dist/ikonvert.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/n2k-actisense.d.ts +24 -0
- package/dist/n2k-actisense.d.ts.map +1 -0
- package/dist/n2k-actisense.js +126 -0
- package/dist/n2k-actisense.js.map +1 -0
- package/dist/n2k-actisense.test.d.ts +2 -0
- package/dist/n2k-actisense.test.d.ts.map +1 -0
- package/dist/n2k-actisense.test.js +49 -0
- package/dist/n2k-actisense.test.js.map +1 -0
- package/dist/n2kDevice.d.ts +44 -0
- package/dist/n2kDevice.d.ts.map +1 -0
- package/dist/n2kDevice.js +436 -0
- package/dist/n2kDevice.js.map +1 -0
- package/dist/pgns.d.ts +22 -0
- package/dist/pgns.d.ts.map +1 -0
- package/dist/pgns.js +157 -0
- package/dist/pgns.js.map +1 -0
- package/dist/pgns.test.d.ts +2 -0
- package/dist/pgns.test.d.ts.map +1 -0
- package/dist/pgns.test.js +14 -0
- package/dist/pgns.test.js.map +1 -0
- package/dist/simpleCan.d.ts +17 -0
- package/dist/simpleCan.d.ts.map +1 -0
- package/dist/simpleCan.js +125 -0
- package/dist/simpleCan.js.map +1 -0
- package/dist/stringMsg.d.ts +33 -0
- package/dist/stringMsg.d.ts.map +1 -0
- package/dist/stringMsg.js +359 -0
- package/dist/stringMsg.js.map +1 -0
- package/dist/stringMsg.test.d.ts +2 -0
- package/dist/stringMsg.test.d.ts.map +1 -0
- package/dist/stringMsg.test.js +244 -0
- package/dist/stringMsg.test.js.map +1 -0
- package/dist/toPgn.d.ts +34 -0
- package/dist/toPgn.d.ts.map +1 -0
- package/dist/toPgn.js +500 -0
- package/dist/toPgn.js.map +1 -0
- package/dist/utilities.d.ts +28 -0
- package/dist/utilities.d.ts.map +1 -0
- package/dist/utilities.js +159 -0
- package/dist/utilities.js.map +1 -0
- package/dist/utilities.test.d.ts +2 -0
- package/dist/utilities.test.d.ts.map +1 -0
- package/dist/utilities.test.js +9 -0
- package/dist/utilities.test.js.map +1 -0
- package/dist/venus-mqtt.d.ts +11 -0
- package/dist/venus-mqtt.d.ts.map +1 -0
- package/dist/venus-mqtt.js +100 -0
- package/dist/venus-mqtt.js.map +1 -0
- package/dist/venus.d.ts +11 -0
- package/dist/venus.d.ts.map +1 -0
- package/dist/venus.js +71 -0
- package/dist/venus.js.map +1 -0
- package/dist/w2k01.d.ts +17 -0
- package/dist/w2k01.d.ts.map +1 -0
- package/dist/w2k01.js +119 -0
- package/dist/w2k01.js.map +1 -0
- package/dist/yddevice.d.ts +25 -0
- package/dist/yddevice.d.ts.map +1 -0
- package/dist/yddevice.js +43 -0
- package/dist/yddevice.js.map +1 -0
- package/dist/ydgw02.d.ts +17 -0
- package/dist/ydgw02.d.ts.map +1 -0
- package/dist/ydgw02.js +163 -0
- package/dist/ydgw02.js.map +1 -0
- package/dist/ydvr.d.ts +17 -0
- package/dist/ydvr.d.ts.map +1 -0
- package/dist/ydvr.js +120 -0
- package/dist/ydvr.js.map +1 -0
- package/eslint.config.js +58 -0
- package/jest.config.js +5 -0
- package/lib/actisense-serial.ts +644 -0
- package/lib/bin/actisense-file.ts +53 -0
- package/lib/bin/actisense-n2k-tcp.ts +50 -0
- package/lib/bin/actisense-serialjs.ts +55 -0
- package/{bin/analyzerjs → lib/bin/analyzerjs.ts} +16 -15
- package/{bin/candumpjs → lib/bin/candumpjs.ts} +19 -20
- package/lib/bin/cansend.ts +131 -0
- package/lib/bin/ikonvert-serial.ts +44 -0
- package/{bin/to-pgn → lib/bin/to-pgn.ts} +23 -17
- package/lib/bin/ydvr-file +33 -0
- package/lib/canId.test.js +35 -15
- package/lib/canId.ts +84 -0
- package/lib/canbus.ts +293 -0
- package/lib/candevice.ts +41 -0
- package/lib/codes.ts +21 -0
- package/lib/{discovery.js → discovery.ts} +32 -30
- package/lib/fromPgn.ts +1207 -0
- package/lib/{fromPgnStream.js → fromPgnStream.ts} +17 -12
- package/lib/{ikonvert.js → ikonvert.ts} +99 -94
- package/lib/index.ts +48 -0
- package/lib/n2k-actisense.test.js +31 -32
- package/lib/n2k-actisense.ts +152 -0
- package/lib/n2kDevice.ts +516 -0
- package/lib/pgns.test.ts +12 -0
- package/lib/pgns.ts +191 -0
- package/lib/simpleCan.ts +140 -0
- package/lib/stringMsg.test.js +58 -41
- package/lib/stringMsg.ts +464 -0
- package/lib/toPgn.ts +597 -0
- package/lib/utilities.ts +169 -0
- package/lib/venus-mqtt.js +69 -73
- package/lib/venus.js +8 -8
- package/lib/w2k01.ts +142 -0
- package/lib/{yddevice.js → yddevice.ts} +18 -16
- package/lib/{ydgw02.js → ydgw02.ts} +58 -51
- package/lib/ydvr.js +65 -147
- package/package.json +54 -18
- package/tsconfig.json +19 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/CHANGELOG.md +0 -101
- package/bin/actisense-file +0 -47
- package/bin/actisense-n2k-tcp +0 -45
- package/bin/actisense-serialjs +0 -52
- package/bin/candumpanalyzerjs +0 -29
- package/bin/cansend +0 -130
- package/bin/ikonvert-serial +0 -50
- package/bin/ydgw-analyzerjs +0 -36
- package/bin/ydvr-file +0 -33
- package/index.js +0 -53
- package/ios_canboat.js/main.js +0 -2
- package/ios_canboat.js/main.js.LICENSE.txt +0 -17
- package/ios_canboat.js/main.js.map +0 -1
- package/lib/canId.js +0 -64
- package/lib/canbus.js +0 -278
- package/lib/candevice.js +0 -51
- package/lib/codes.js +0 -69
- package/lib/codes.test.js +0 -17
- package/lib/codesMfgs.json +0 -166
- package/lib/fromPgn.js +0 -1027
- package/lib/n2k-actisense.js +0 -108
- package/lib/n2kDevice.js +0 -390
- package/lib/pgns.js +0 -196
- package/lib/pgns.test.js +0 -13
- package/lib/serial.js +0 -647
- package/lib/simpleCan.js +0 -105
- package/lib/stringMsg.js +0 -339
- package/lib/toPgn.js +0 -518
- package/lib/utilities.js +0 -111
- package/lib/w2k01.js +0 -129
package/lib/simpleCan.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
const CanDevice = require('./candevice')
|
|
2
|
-
const debug = require('debug')('canboatjs:simpleCan')
|
|
3
|
-
const { encodeCanId, parseCanId } = require('./canId')
|
|
4
|
-
const { toActisenseSerialFormat, parseActisense } = require('./stringMsg')
|
|
5
|
-
const { toPgn } = require('./toPgn')
|
|
6
|
-
const { getPlainPGNs, binToActisense } = require('./utilities')
|
|
7
|
-
const _ = require('lodash')
|
|
8
|
-
|
|
9
|
-
function SimpleCan (options, messageCb) {
|
|
10
|
-
this.options = options
|
|
11
|
-
this.messageCb = messageCb
|
|
12
|
-
this.plainText = false
|
|
13
|
-
this.socketcan = require('socketcan')
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
SimpleCan.prototype.start = function () {
|
|
17
|
-
const canDevice = this.options.canDevice || 'can0'
|
|
18
|
-
|
|
19
|
-
this.channel = this.socketcan.createRawChannel(canDevice);
|
|
20
|
-
if ( this.messageCb ) {
|
|
21
|
-
this.channel.addListener('onMessage', (msg) => {
|
|
22
|
-
var pgn = parseCanId(msg.id)
|
|
23
|
-
|
|
24
|
-
if ( this.candevice && this.candevice.cansend && pgn.src == this.candevice.address ) {
|
|
25
|
-
return
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
pgn.timestamp = new Date().toISOString()
|
|
29
|
-
if ( this.plainText ) {
|
|
30
|
-
this.messageCb(binToActisense(pgn, msg.data, msg.data.length))
|
|
31
|
-
} else {
|
|
32
|
-
this.messageCb({ pgn, length: msg.data.length, data: msg.data })
|
|
33
|
-
}
|
|
34
|
-
})
|
|
35
|
-
}
|
|
36
|
-
this.channel.start()
|
|
37
|
-
this.candevice = new CanDevice(this,
|
|
38
|
-
{...this.options,
|
|
39
|
-
disableDefaultTransmitPGNs: true,
|
|
40
|
-
disableNAKs: true
|
|
41
|
-
},
|
|
42
|
-
)
|
|
43
|
-
this.candevice.start()
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
SimpleCan.prototype.sendPGN = function (msg) {
|
|
47
|
-
if ( this.candevice ) {
|
|
48
|
-
if ( !this.candevice.cansend && msg.pgn !== 59904 && msg.pgn !== 60928 && msg.pgn !== 126996 ) {
|
|
49
|
-
debug('ignoring %j', msg)
|
|
50
|
-
return
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
debug('sending %j', msg)
|
|
54
|
-
|
|
55
|
-
let src = msg.pgn === 59904 || msg.forceSrc ? msg.src : this.candevice.address
|
|
56
|
-
if ( _.isString(msg) ) {
|
|
57
|
-
var split = msg.split(',')
|
|
58
|
-
split[3] = src
|
|
59
|
-
msg = split.join(',')
|
|
60
|
-
} else {
|
|
61
|
-
msg.src = src
|
|
62
|
-
if ( _.isUndefined(msg.prio) ) {
|
|
63
|
-
msg.prio = 3
|
|
64
|
-
}
|
|
65
|
-
if ( _.isUndefined(msg.dst) ) {
|
|
66
|
-
msg.dst = 255
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
var canid
|
|
71
|
-
var buffer
|
|
72
|
-
|
|
73
|
-
var pgn
|
|
74
|
-
if ( _.isObject(msg) ) {
|
|
75
|
-
canid = encodeCanId(msg)
|
|
76
|
-
buffer = toPgn(msg)
|
|
77
|
-
pgn = msg
|
|
78
|
-
} else {
|
|
79
|
-
pgn = parseActisense(msg)
|
|
80
|
-
canid = encodeCanId(pgn)
|
|
81
|
-
buffer = pgn.data
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if ( debug.enabled ) {
|
|
85
|
-
var str = toActisenseSerialFormat(pgn.pgn, buffer, pgn.dst, pgn.src)
|
|
86
|
-
debug(str)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
//seems as though 126720 should always be encoded this way
|
|
90
|
-
if ( buffer.length > 8 || pgn.pgn == 126720 ) {
|
|
91
|
-
var pgns = getPlainPGNs(buffer)
|
|
92
|
-
pgns.forEach(pbuffer => {
|
|
93
|
-
this.channel.send({id: canid, ext:true, data: pbuffer})
|
|
94
|
-
})
|
|
95
|
-
} else {
|
|
96
|
-
this.channel.send({id: canid, ext:true, data: buffer})
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
SimpleCan.prototype.sendActisenseFormat = function (msg) {
|
|
102
|
-
this.sendPGN(msg)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
module.exports = SimpleCan
|
package/lib/stringMsg.js
DELETED
|
@@ -1,339 +0,0 @@
|
|
|
1
|
-
const {
|
|
2
|
-
compact, cond, constant, curry, flow, isEmpty,
|
|
3
|
-
isString, negate, overSome, startsWith, stubTrue, toNumber, zipObject
|
|
4
|
-
} = require('lodash/fp')
|
|
5
|
-
const {
|
|
6
|
-
arrBuff, byteString, getPlainPGNs, rmChecksum, trimWrap, compute0183Checksum, hexByte
|
|
7
|
-
} = require('./utilities')
|
|
8
|
-
const {
|
|
9
|
-
buildCanId, encodeCanIdString, parseCanId, parseCanIdStr,
|
|
10
|
-
} = require('./canId')
|
|
11
|
-
const moment = require('moment')
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Helper function that helps merge canId fields with format, data, and others.
|
|
15
|
-
* The idea here is to reflect what was in the source and not remove or add.
|
|
16
|
-
* If the source has a len or timestamp attribute it should be added but not created.
|
|
17
|
-
* @param {Object} canIdInfo The result of parseCanId, parseCanIdStr, or buildCanId.
|
|
18
|
-
* @param {string} format String that defines the source format.
|
|
19
|
-
* @param {Buffer} data Buffer array that contains the fields data.
|
|
20
|
-
* @param {Object} [rest={}] Anything else to be added like len, timestamp, direction.
|
|
21
|
-
* @return {Object} All canId fields with format and data props added.
|
|
22
|
-
*/
|
|
23
|
-
function buildMsg(_canIdInfo, format, data, rest = {}) {
|
|
24
|
-
const canIdInfo = Object.assign({}, _canIdInfo, {
|
|
25
|
-
format,
|
|
26
|
-
data
|
|
27
|
-
})
|
|
28
|
-
for (const property in rest) {
|
|
29
|
-
if (canIdInfo[property] === undefined) {
|
|
30
|
-
canIdInfo[property] = rest[property]
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return canIdInfo
|
|
34
|
-
}
|
|
35
|
-
function buildErrMsg(msg, input) {
|
|
36
|
-
if (input && isString(input)) return `${msg} - ${input}`
|
|
37
|
-
return msg
|
|
38
|
-
}
|
|
39
|
-
const buildErr = curry((format, msg, input) => ({
|
|
40
|
-
error: new Error(buildErrMsg(msg, input)), format, input,
|
|
41
|
-
}))
|
|
42
|
-
|
|
43
|
-
function toPaddedHexString(num, len) {
|
|
44
|
-
str = num.toString(16).toUpperCase();
|
|
45
|
-
return "0".repeat(len - str.length) + str;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// 2016-02-28T19:57:02.364Z,2,127250,7,255,8,ff,10,3b,ff,7f,ce,f5,fc
|
|
49
|
-
exports.isActisense = input => (input.charAt(10) === 'T' && input.charAt(23) === 'Z') || (input.charAt(10) === '-' && input.charAt(23) === ',')
|
|
50
|
-
|
|
51
|
-
exports.parseActisense = (input) => {
|
|
52
|
-
const [ timestamp, prio, pgn, src, dst, len, ...data ] = input.split(',')
|
|
53
|
-
return buildMsg(
|
|
54
|
-
buildCanId(prio, pgn, dst, src),
|
|
55
|
-
'Actisense',
|
|
56
|
-
Buffer.from(data.join(''), 'hex'),
|
|
57
|
-
{ len: Number(len), timestamp },
|
|
58
|
-
)
|
|
59
|
-
}
|
|
60
|
-
exports.encodeActisense = ({
|
|
61
|
-
pgn, data, timestamp, prio = 2, dst = 255, src = 0 }) => ([
|
|
62
|
-
timestamp || new Date().toISOString(),
|
|
63
|
-
prio, pgn, src, dst, data.length,
|
|
64
|
-
byteString(data)
|
|
65
|
-
].join(','))
|
|
66
|
-
|
|
67
|
-
exports.toActisenseSerialFormat = (pgn, data, dst=255, src=0, prio=2) => exports.encodeActisense({
|
|
68
|
-
pgn, data, dst, src, prio
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
// A764027.880 05FF7 1EF00 E59861060202FFFFFFFF03030000FFFFFFFFFFFFFFFFFFFF0000FFFFFF7FFFFFFF7FFFFFFF7F0000FF7F
|
|
72
|
-
exports.isActisenseN2KASCII = input => input.charAt(0) === 'A' && input.charAt(7) === '.' && input.charAt(11) === ' '
|
|
73
|
-
exports.parseActisenseN2KASCII = (input) => {
|
|
74
|
-
const [ timestamp, srcdstp, pgn, data ] = input.split(' ')
|
|
75
|
-
const src = parseInt(srcdstp.substring(0, 2), 16)
|
|
76
|
-
const dst = parseInt(srcdstp.substring(2,4), 16)
|
|
77
|
-
const prio = parseInt(srcdstp.substring(4))
|
|
78
|
-
return buildMsg(
|
|
79
|
-
buildCanId(prio, parseInt(pgn, 16), dst, src),
|
|
80
|
-
'Actisense N2K ASCII',
|
|
81
|
-
Buffer.from(data, 'hex'),
|
|
82
|
-
{ len: data.length, time: timestamp.substring(1) },
|
|
83
|
-
)
|
|
84
|
-
}
|
|
85
|
-
exports.encodeActisenseN2KACSII = ({
|
|
86
|
-
pgn, data, timestamp, prio = 2, dst = 255, src = 0 }) => {
|
|
87
|
-
timestamp = 'A000000.000'
|
|
88
|
-
|
|
89
|
-
const srcdstp = hexByte(src) + hexByte(dst) + prio
|
|
90
|
-
return ([
|
|
91
|
-
timestamp,
|
|
92
|
-
srcdstp.toUpperCase(),
|
|
93
|
-
toPaddedHexString(pgn, 5).toUpperCase(),
|
|
94
|
-
byteString(data, '').toUpperCase()
|
|
95
|
-
].join(' '))
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
// 16:29:27.082 R 09F8017F 50 C3 B8 13 47 D8 2B C6
|
|
100
|
-
exports.isYDRAW = (input) => {
|
|
101
|
-
if (input.charAt(2) !== ':') return false
|
|
102
|
-
const direction = input.substr(12, 3)
|
|
103
|
-
return direction === ' R ' || direction === ' T '
|
|
104
|
-
}
|
|
105
|
-
exports.parseYDRAW = (input) => {
|
|
106
|
-
const parts = input.split(' ')
|
|
107
|
-
if ( parts.length < 4 ) return buildErr('YDRAW', 'Invalid parts.', input)
|
|
108
|
-
const [ time, direction, canId, ...data ] = parts // time format HH:mm:ss.SSS
|
|
109
|
-
return buildMsg(
|
|
110
|
-
parseCanIdStr(canId), 'YDRAW', arrBuff(data),
|
|
111
|
-
{ direction, time }
|
|
112
|
-
)
|
|
113
|
-
}
|
|
114
|
-
//19F51323 01 02<CR><LF>
|
|
115
|
-
exports.encodeYDRAW = ({ data, ...canIdInfo }) => {
|
|
116
|
-
const canId = encodeCanIdString(canIdInfo)
|
|
117
|
-
const pgns = data.length > 8 || canIdInfo.pgn == 126720 ? getPlainPGNs(data) : [ data ]
|
|
118
|
-
return pgns.map(buffer => canId + ' ' + byteString(buffer, ' '))
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
//16:29:27.082 R 19F51323 01 02<CR><LF>
|
|
122
|
-
exports.encodeYDRAWFull = ({ data, ...canIdInfo }) => {
|
|
123
|
-
const canId = encodeCanIdString(canIdInfo)
|
|
124
|
-
const pgns = data.length > 8 || canIdInfo.pgn == 126720 ? getPlainPGNs(data) : [ data ]
|
|
125
|
-
return pgns.map(buffer =>
|
|
126
|
-
moment().utc().format('hh:mm:ss.SSS')
|
|
127
|
-
+ ' R '
|
|
128
|
-
+ canId + ' '
|
|
129
|
-
+ byteString(buffer, ' '))
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const get0183Sentence = (msg) => {
|
|
133
|
-
let sentence = msg
|
|
134
|
-
if (sentence.charAt(0) === '\\') {
|
|
135
|
-
split = sentence.split('\\')
|
|
136
|
-
if ( split.length < 3 ) {
|
|
137
|
-
return false
|
|
138
|
-
}
|
|
139
|
-
sentence = split[2]
|
|
140
|
-
}
|
|
141
|
-
return sentence
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// $PCDIN,01F119,00000000,0F,2AAF00D1067414FF*59
|
|
145
|
-
exports.isPCDIN = (msg) => {
|
|
146
|
-
const sentence = get0183Sentence(msg)
|
|
147
|
-
return sentence.startsWith('$PCDIN,')
|
|
148
|
-
}
|
|
149
|
-
exports.parsePCDIN = (input) => {
|
|
150
|
-
const sentence = get0183Sentence(input)
|
|
151
|
-
const [ prefix, pgn, timeHex, src, data ] = sentence.split(',')
|
|
152
|
-
let timer = parseInt(timeHex, 32)
|
|
153
|
-
|
|
154
|
-
timer = timer / 1024
|
|
155
|
-
timer = timer + 1262304000 // starts epoch time from 1/1/2010
|
|
156
|
-
timer = timer * 1000
|
|
157
|
-
|
|
158
|
-
return buildMsg(
|
|
159
|
-
buildCanId(0, parseInt(pgn, 16), 255, parseInt(src, 16)),
|
|
160
|
-
'PCDIN',
|
|
161
|
-
Buffer.from(rmChecksum(data), 'hex'),
|
|
162
|
-
{ coalesced: true, prefix, timer, timestamp: new Date(timer) },
|
|
163
|
-
)
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
exports.encodePCDIN = ({ prefix = '$PCDIN', pgn, data, dst = 255}) => {
|
|
167
|
-
const sentence = [ prefix, toPaddedHexString(pgn, 6), '0000180C', hexByte(dst).toUpperCase(), byteString(data, '').toUpperCase()].join(',')
|
|
168
|
-
return sentence + compute0183Checksum(sentence)
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const changeEndianness = (string) => {
|
|
172
|
-
const result = [];
|
|
173
|
-
let len = string.length - 2;
|
|
174
|
-
while (len >= 0) {
|
|
175
|
-
result.push(string.substr(len, 2));
|
|
176
|
-
len -= 2;
|
|
177
|
-
}
|
|
178
|
-
return result.join('');
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// $MXPGN,01F801,2801,C1308AC40C5DE343*19
|
|
182
|
-
exports.isMXPGN = (msg) => {
|
|
183
|
-
const sentence = get0183Sentence(msg)
|
|
184
|
-
return sentence.startsWith('$MXPGN,')
|
|
185
|
-
}
|
|
186
|
-
exports.parseMXPGN = (input, options) => {
|
|
187
|
-
const sentence = get0183Sentence(input)
|
|
188
|
-
const [ prefix, pgn, attr_word, data ] = sentence.split(',')
|
|
189
|
-
|
|
190
|
-
const send_prio_len = (parseInt(attr_word.substr(0,2), 16).toString(2)).padStart(8, '0');
|
|
191
|
-
const addr = (parseInt(attr_word.substr(2,2), 16));
|
|
192
|
-
const send = parseInt(send_prio_len.substr(0,1), 2);
|
|
193
|
-
const prio = parseInt(send_prio_len.substr(1,3), 2);
|
|
194
|
-
const len = parseInt(send_prio_len.substr(4,4), 2);
|
|
195
|
-
let src, dst;
|
|
196
|
-
send ? dst = addr: src = addr;
|
|
197
|
-
|
|
198
|
-
let reversed
|
|
199
|
-
|
|
200
|
-
if ( options && options.littleEndianMXPGN )
|
|
201
|
-
reversed = changeEndianness(rmChecksum(data))
|
|
202
|
-
else
|
|
203
|
-
reversed = data
|
|
204
|
-
|
|
205
|
-
return buildMsg(
|
|
206
|
-
buildCanId(0, parseInt(pgn, 16), 255, parseInt(src, 16)),
|
|
207
|
-
'MXPGN',
|
|
208
|
-
Buffer.from(reversed, 'hex'),
|
|
209
|
-
{ coalesced: true, prefix },
|
|
210
|
-
)
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
exports.encodeMXPGN = ({ prefix = '$MXPGN', pgn, prio, src, data }) => {
|
|
214
|
-
if (src > 255) src = 255;
|
|
215
|
-
if (!prio) prio = 3;
|
|
216
|
-
if (!src) src = 255;
|
|
217
|
-
const dataLength = hexByte(128 + (prio * 16) + (byteString(data, '').toUpperCase().length / 2)).toUpperCase()
|
|
218
|
-
const attribWord = dataLength + hexByte(src).toUpperCase()
|
|
219
|
-
|
|
220
|
-
var buff = Buffer.from(byteString(data, ''), 'Hex');
|
|
221
|
-
for (var i = 0, j = buff.length - 1; i < j; ++i, --j) {
|
|
222
|
-
var t = buff[j]
|
|
223
|
-
|
|
224
|
-
buff[j] = buff[i]
|
|
225
|
-
buff[i] = t
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
const sentence = [prefix, toPaddedHexString(pgn, 6), attribWord, buff.toString('Hex').toUpperCase()].join(',')
|
|
229
|
-
return sentence + compute0183Checksum(sentence)
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// iKonvert
|
|
233
|
-
// !PDGY,126992,3,2,255,0.563,d2009e45b3b8821d
|
|
234
|
-
exports.isPDGY = startsWith('!PDGY,')
|
|
235
|
-
exports.parsePDGY = (input) => {
|
|
236
|
-
const parts = input.split(',')
|
|
237
|
-
if ( parts.length === 7 ) {
|
|
238
|
-
const [ prefix, pgn, prio, src, dst, timer, data ] = parts
|
|
239
|
-
return buildMsg(
|
|
240
|
-
buildCanId(prio, pgn, dst, src), 'PDGY', Buffer.from(data, 'base64'),
|
|
241
|
-
{ timer: Number(timer), prefix, coalesced: true },
|
|
242
|
-
)
|
|
243
|
-
} else if ( parts.length === 4 ) {
|
|
244
|
-
const [ prefix, pgn, dst, data ] = parts
|
|
245
|
-
return buildMsg(
|
|
246
|
-
buildCanId(0, pgn, dst, 0), 'PDGY', Buffer.from(data, 'base64'),
|
|
247
|
-
{ coalesced: true }
|
|
248
|
-
)
|
|
249
|
-
} else {
|
|
250
|
-
return buildErr('iKonvert', 'Invalid parts.', input)
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
exports.encodePDGY = ({ prefix = '!PDGY', pgn, data, dst = 255}) => (
|
|
254
|
-
[ prefix, pgn, dst, data.toString('base64')].join(',')
|
|
255
|
-
)
|
|
256
|
-
|
|
257
|
-
exports.isPDGYdebug = startsWith('$PDGY,')
|
|
258
|
-
exports.parsePDGYdebug = (input) => {
|
|
259
|
-
const [ prefix, pgn, ...fieldParts ] = input.split(',')
|
|
260
|
-
const fieldVals = fieldParts.map(toNumber)
|
|
261
|
-
const fields = zipObject([
|
|
262
|
-
'busLoad', 'errors', 'deviceCount', 'timer', 'gatewaySrc', 'rejectedTX',
|
|
263
|
-
], fieldVals)
|
|
264
|
-
const src = fields.gatewaySrc
|
|
265
|
-
return buildMsg(
|
|
266
|
-
buildCanId(3, pgn, src, src), 'PDGYdebug', Buffer.from(fieldVals),
|
|
267
|
-
{ fields, prefix },
|
|
268
|
-
)
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// candump1 Angstrom
|
|
272
|
-
// <0x18eeff01> [8] 05 a0 be 1c 00 a0 a0 c0
|
|
273
|
-
exports.isCandump1 = startsWith('<0x')
|
|
274
|
-
exports.parseCandump1 = (input) => {
|
|
275
|
-
const [ canId, len, ...data ] = input.split(' ')
|
|
276
|
-
return buildMsg(
|
|
277
|
-
parseCanIdStr(trimWrap(canId)), 'candump1', arrBuff(data),
|
|
278
|
-
{ len: Number(trimWrap(len)) },
|
|
279
|
-
)
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// candump2 Debian
|
|
283
|
-
// can0 09F8027F [8] 00 FC FF FF 00 00 FF FF
|
|
284
|
-
exports.isCandump2 = startsWith('can')
|
|
285
|
-
exports.parseCandump2 = (input) => {
|
|
286
|
-
const [ bus, canId, len, ...data ] = compact(input.split(' '))
|
|
287
|
-
return buildMsg(
|
|
288
|
-
parseCanIdStr(canId), 'candump2', arrBuff(data),
|
|
289
|
-
{ bus, len: Number(trimWrap(len)) },
|
|
290
|
-
)
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// candump3 log
|
|
294
|
-
// (1502979132.106111) slcan0 09F50374#000A00FFFF00FFFF
|
|
295
|
-
exports.isCandump3 = startsWith('(')
|
|
296
|
-
exports.parseCandump3 = (input) => {
|
|
297
|
-
const [ timestamp, bus, canFrame ] = input.split(' ')
|
|
298
|
-
const [ canId, data ] = canFrame.split('#')
|
|
299
|
-
return buildMsg(
|
|
300
|
-
parseCanIdStr(canId), 'candump3', Buffer.from(data, 'hex'), { timestamp, bus }
|
|
301
|
-
)
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
const hasErr = overSome([negate(isString), isEmpty])
|
|
305
|
-
exports.parseN2kString = cond([
|
|
306
|
-
[hasErr, buildErr('INVALID', 'Input not string or empty.')],
|
|
307
|
-
[exports.isActisense, exports.parseActisense],
|
|
308
|
-
[exports.isYDRAW, exports.parseYDRAW],
|
|
309
|
-
[exports.isPCDIN, exports.parsePCDIN],
|
|
310
|
-
[exports.isMXPGN, exports.parseMXPGN],
|
|
311
|
-
[exports.isPDGY, exports.parsePDGY],
|
|
312
|
-
[exports.isCandump1, exports.parseCandump1],
|
|
313
|
-
[exports.isCandump2, exports.parseCandump2],
|
|
314
|
-
[exports.isCandump3, exports.parseCandump3],
|
|
315
|
-
[exports.isPDGYdebug, exports.parsePDGYdebug],
|
|
316
|
-
[exports.isActisenseN2KASCII, exports.parseActisenseN2KASCII],
|
|
317
|
-
[stubTrue, buildErr('MISSING_PARSER', 'Parser not found for input.')],
|
|
318
|
-
])
|
|
319
|
-
|
|
320
|
-
exports.isN2KString = cond([
|
|
321
|
-
[hasErr, () => false],
|
|
322
|
-
[exports.isActisense, () => true],
|
|
323
|
-
[exports.isYDRAW, () => true],
|
|
324
|
-
[exports.isPCDIN, () => true],
|
|
325
|
-
[exports.isMXPGN, () => true],
|
|
326
|
-
[exports.isPDGY, () => true],
|
|
327
|
-
[exports.isCandump1, () => true],
|
|
328
|
-
[exports.isCandump2, () => true],
|
|
329
|
-
[exports.isCandump3, () => true],
|
|
330
|
-
[exports.isPDGYdebug, () => true],
|
|
331
|
-
[exports.isActisenseN2KASCII, () => true],
|
|
332
|
-
[stubTrue, () => false],
|
|
333
|
-
])
|
|
334
|
-
|
|
335
|
-
exports.isN2KOver0183 = (msg) => { return exports.isPCDIN(msg) || exports.isMXPGN(msg) }
|
|
336
|
-
|
|
337
|
-
exports.parseN2KOver0183 = (msg) => { return exports.parsePCDIN(msg) || exports.parseMXPGN(msg) }
|
|
338
|
-
|
|
339
|
-
|