@canboat/canboatjs 1.22.2 → 1.24.0
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/README.md +6 -0
- package/W2K_NOTES +5 -0
- package/bin/actisense-n2k-tcp +45 -0
- package/bin/candumpjs +70 -0
- package/bin/to-pgn +3 -2
- package/bin/ydvr-file +33 -0
- package/examples/simpleCan.js +42 -0
- package/index.js +2 -0
- package/lib/fromPgn.js +25 -2
- package/lib/n2k-actisense.js +124 -0
- package/lib/n2k-actisense.test.js +59 -0
- package/lib/stringMsg.js +30 -0
- package/lib/stringMsg.test.js +27 -1
- package/lib/toPgn.js +16 -1
- package/lib/w2k01.js +127 -0
- package/lib/ydvr.js +204 -0
- package/n2ka.js +123 -0
- package/package.json +2 -2
- package/wk2.out +224 -0
package/README.md
CHANGED
|
@@ -50,6 +50,12 @@ This program takes input in the candump format and outputs canboat json format
|
|
|
50
50
|
|
|
51
51
|
Example: `candump can0 | candumpanalyzerjs`
|
|
52
52
|
|
|
53
|
+
## ydvr-file
|
|
54
|
+
|
|
55
|
+
This program takes input in the [YDVR](https://www.yachtd.com/products/recorder.html) file format and outputs canboat json format
|
|
56
|
+
|
|
57
|
+
Example: `ydvr-file <file>`
|
|
58
|
+
|
|
53
59
|
# Usage
|
|
54
60
|
|
|
55
61
|
## Installation
|
package/W2K_NOTES
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const debug = require('debug')('canboatjs:w2k01')
|
|
4
|
+
const net = require('net');
|
|
5
|
+
const { readN2KActisense } = require('../lib/n2k-actisense')
|
|
6
|
+
|
|
7
|
+
const argv = require('minimist')(process.argv.slice(2), {
|
|
8
|
+
alias: { h: 'help' }
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
if ( argv['help'] ) {
|
|
12
|
+
console.error(`Usage: ${process.argv[0]} [options] host port
|
|
13
|
+
|
|
14
|
+
Options:
|
|
15
|
+
-h, --help output usage information`)
|
|
16
|
+
process.exit(1)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if ( argv['_'].length < 2 ) {
|
|
20
|
+
console.error('Please specify a host and port')
|
|
21
|
+
process.exit(1)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
var client = new net.Socket();
|
|
26
|
+
client.connect(argv['_'][1], argv['_'][0], function() {
|
|
27
|
+
debug('Connected');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const context = {}
|
|
31
|
+
client.on('data', function(data) {
|
|
32
|
+
readN2KActisense(data, true, context, (result) => {
|
|
33
|
+
console.log(result)
|
|
34
|
+
})
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
client.on('close', function() {
|
|
38
|
+
debug('Connection closed');
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
process.on('SIGINT', () => {
|
|
42
|
+
debug('SIGINT signal received.');
|
|
43
|
+
client.destroy()
|
|
44
|
+
});
|
|
45
|
+
|
package/bin/candumpjs
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const canboatjs = require('../index')
|
|
4
|
+
const Parser = require('../index').FromPgn
|
|
5
|
+
const { parseCanId } = require('../lib/canId')
|
|
6
|
+
const socketcan = require('socketcan')
|
|
7
|
+
|
|
8
|
+
var parser = new canboatjs.FromPgn()
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
const argv = require('minimist')(process.argv.slice(2), {
|
|
12
|
+
alias: { h: 'help' }
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
if ( argv['help'] ) {
|
|
16
|
+
console.error(`Usage: ${process.argv[0]} [options] candevice
|
|
17
|
+
|
|
18
|
+
Options:
|
|
19
|
+
-h, --help output usage information`)
|
|
20
|
+
process.exit(1)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if ( argv['_'].length === 0 ) {
|
|
24
|
+
console.error('Please specify a device')
|
|
25
|
+
process.exit(1)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/*
|
|
29
|
+
|
|
30
|
+
let messageCb = (data) => {
|
|
31
|
+
let jsonData = parser.parse(data, (err) => { if ( err ) console.error(err) })
|
|
32
|
+
if ( jsonData ) {
|
|
33
|
+
console.log(data)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let simpleCan = new canboatjs.SimpleCan({
|
|
38
|
+
canDevice: argv['_'][0],
|
|
39
|
+
preferredAddress: 35,
|
|
40
|
+
disableDefaultTransmitPGNs: true,
|
|
41
|
+
transmitPGNs: [],
|
|
42
|
+
}, messageCb)
|
|
43
|
+
|
|
44
|
+
simpleCan.start()
|
|
45
|
+
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
parser.on('error', (pgn, error) => {
|
|
49
|
+
console.error(`Error parsing ${pgn.pgn} ${error}`)
|
|
50
|
+
console.error(error.stack)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
parser.on('pgn', (pgn) => {
|
|
54
|
+
console.log(JSON.stringify(pgn))
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
const canDevice = argv['_'][0]
|
|
59
|
+
|
|
60
|
+
this.channel = socketcan.createRawChannel(canDevice);
|
|
61
|
+
|
|
62
|
+
this.channel.addListener('onMessage', (msg) => {
|
|
63
|
+
var pgn = parseCanId(msg.id)
|
|
64
|
+
|
|
65
|
+
pgn.timestamp = new Date().toISOString()
|
|
66
|
+
|
|
67
|
+
parser.parse({ pgn, length: msg.data.length, data: msg.data })
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
this.channel.start()
|
package/bin/to-pgn
CHANGED
|
@@ -4,14 +4,14 @@ const argv = require('minimist')(process.argv.slice(2), {
|
|
|
4
4
|
string: ['format'],
|
|
5
5
|
alias: { h: 'help' }
|
|
6
6
|
})
|
|
7
|
-
const { pgnToActisenseSerialFormat, pgnToiKonvertSerialFormat, pgnToYdgwRawFormat, pgnToPCDIN, pgnToMXPGN } = require('../index')
|
|
7
|
+
const { pgnToActisenseSerialFormat, pgnToActisenseN2KAsciiFormat, pgnToiKonvertSerialFormat, pgnToYdgwRawFormat, pgnToPCDIN, pgnToMXPGN } = require('../index')
|
|
8
8
|
const { toActisenseSerialFormat } = require('../lib/stringMsg')
|
|
9
9
|
|
|
10
10
|
if ( argv['help'] ) {
|
|
11
11
|
console.error(`Usage: ${process.argv[0]} [options]
|
|
12
12
|
|
|
13
13
|
Options:
|
|
14
|
-
--format <format> actisense, ikconvert, ydgw, pcdin, mxpgn
|
|
14
|
+
--format <format> actisense, actisensen2kascii, ikconvert, ydgw, pcdin, mxpgn
|
|
15
15
|
-h, --help output usage information`)
|
|
16
16
|
process.exit(1)
|
|
17
17
|
}
|
|
@@ -19,6 +19,7 @@ Options:
|
|
|
19
19
|
|
|
20
20
|
const formatters = {
|
|
21
21
|
actisense: pgnToActisenseSerialFormat,
|
|
22
|
+
'n2kascii': pgnToActisenseN2KAsciiFormat,
|
|
22
23
|
ikconvert: pgnToiKonvertSerialFormat,
|
|
23
24
|
ydgw: pgnToYdgwRawFormat,
|
|
24
25
|
'pcdin': pgnToPCDIN,
|
package/bin/ydvr-file
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const YdvrStream = require('../lib/ydvr.js');
|
|
4
|
+
|
|
5
|
+
const argv = require('minimist')(process.argv.slice(2), {
|
|
6
|
+
alias: { h: 'help' },
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
if (argv['help']) {
|
|
10
|
+
console.error(`Usage: ${process.argv[0]} file
|
|
11
|
+
|
|
12
|
+
Options:
|
|
13
|
+
-h, --help output usage information`);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (argv['_'].length === 0) {
|
|
18
|
+
console.error('Please specify a file');
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const serial = YdvrStream();
|
|
23
|
+
|
|
24
|
+
filestream = require('fs').createReadStream(argv['_'][0]);
|
|
25
|
+
filestream.on('error', (err) => {
|
|
26
|
+
console.error(err.message);
|
|
27
|
+
});
|
|
28
|
+
filestream.on('end', () => {
|
|
29
|
+
process.exit(0);
|
|
30
|
+
});
|
|
31
|
+
filestream.pipe(serial).on("data", (chunk) => {
|
|
32
|
+
console.log(JSON.stringify(chunk));
|
|
33
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
|
|
2
|
+
const canboatjs = require('../index')
|
|
3
|
+
//const canboatjs = require('@canboat/canboatjs')
|
|
4
|
+
const Parser = require('../index').FromPgn
|
|
5
|
+
var parser = new canboatjs.FromPgn()
|
|
6
|
+
|
|
7
|
+
let messageCb = (data) => {
|
|
8
|
+
let jsonData = parser.parse(data, (err) => { if ( err ) console.error(err) })
|
|
9
|
+
if ( jsonData ) {
|
|
10
|
+
//process
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let simpleCan = new canboatjs.SimpleCan({
|
|
15
|
+
canDevice: 'can0',
|
|
16
|
+
preferredAddress: 35,
|
|
17
|
+
disableDefaultTransmitPGNs: true,
|
|
18
|
+
transmitPGNs: [],
|
|
19
|
+
addressClaim: {
|
|
20
|
+
"Unique Number": 139725,
|
|
21
|
+
"Manufacturer Code": 'Fusion Electronics',
|
|
22
|
+
"Device Function": 130,
|
|
23
|
+
"Device Class": 'Entertainment',
|
|
24
|
+
"Device Instance Lower": 0,
|
|
25
|
+
"Device Instance Upper": 0,
|
|
26
|
+
"System Instance": 0,
|
|
27
|
+
"Industry Group": 'Marine'
|
|
28
|
+
},
|
|
29
|
+
productInfo: {
|
|
30
|
+
"NMEA 2000 Version": 1300,
|
|
31
|
+
"Product Code": 667,
|
|
32
|
+
"Model ID": "MS-UD650",
|
|
33
|
+
"Software Version Code": "1.0",
|
|
34
|
+
"Model Version": "1.0",
|
|
35
|
+
"Model Serial Code": "123456",
|
|
36
|
+
"Certification Level": 0,
|
|
37
|
+
"Load Equivalency": 1
|
|
38
|
+
}
|
|
39
|
+
}, messageCb)
|
|
40
|
+
|
|
41
|
+
simpleCan.start()
|
|
42
|
+
|
package/index.js
CHANGED
|
@@ -23,6 +23,7 @@ module.exports = {
|
|
|
23
23
|
toPgn: require('./lib/toPgn').toPgn,
|
|
24
24
|
toActisenseSerialFormat: require('./lib/stringMsg').toActisenseSerialFormat,
|
|
25
25
|
pgnToActisenseSerialFormat: require('./lib/toPgn').pgnToActisenseSerialFormat,
|
|
26
|
+
pgnToActisenseN2KAsciiFormat: require('./lib/toPgn').pgnToActisenseN2KAsciiFormat,
|
|
26
27
|
pgnToiKonvertSerialFormat: require('./lib/toPgn').pgnToiKonvertSerialFormat,
|
|
27
28
|
pgnToYdgwRawFormat: require('./lib/toPgn').pgnToYdgwRawFormat,
|
|
28
29
|
pgnToPCDIN: require('./lib/toPgn').pgnToPCDIN,
|
|
@@ -31,6 +32,7 @@ module.exports = {
|
|
|
31
32
|
iKonvert: require('./lib/ikonvert'),
|
|
32
33
|
Ydwg02: require('./lib/ydgw02'),
|
|
33
34
|
Ydgw02: require('./lib/ydgw02'),
|
|
35
|
+
W2k01: require('./lib/w2k01'),
|
|
34
36
|
Venus: require('./lib/venus'),
|
|
35
37
|
VenusMQTT: require('./lib/venus-mqtt'),
|
|
36
38
|
discover: require('./lib/discovery'),
|
package/lib/fromPgn.js
CHANGED
|
@@ -29,7 +29,7 @@ const { parse: parseDate } = require('date-fns')
|
|
|
29
29
|
const { getPGNFromCanId } = require('./utilities')
|
|
30
30
|
const { getIndustryName, getManufacturerName } = require('./codes')
|
|
31
31
|
const { parseCanId } = require('./canId')
|
|
32
|
-
const { parseN2kString, parseYDRAW, isN2KOver0183, parseN2KOver0183, parsePDGY } = require('./stringMsg')
|
|
32
|
+
const { parseN2kString, parseYDRAW, isN2KOver0183, parseN2KOver0183, parsePDGY, parseActisenseN2KASCII } = require('./stringMsg')
|
|
33
33
|
|
|
34
34
|
var fieldTypeReaders = {}
|
|
35
35
|
var fieldTypePostProcessors = {}
|
|
@@ -299,7 +299,7 @@ class Parser extends EventEmitter {
|
|
|
299
299
|
} else if ( _.isBuffer(data) ) {
|
|
300
300
|
return this.parseBuffer(data, cb)
|
|
301
301
|
} else {
|
|
302
|
-
return this.parsePgnData(data.pgn, data.length, data.data,
|
|
302
|
+
return this.parsePgnData(data.pgn, data.length, data.data, data.coalesced === true)
|
|
303
303
|
}
|
|
304
304
|
}
|
|
305
305
|
|
|
@@ -381,6 +381,29 @@ class Parser extends EventEmitter {
|
|
|
381
381
|
return undefined
|
|
382
382
|
}
|
|
383
383
|
|
|
384
|
+
//Yacht Devices NMEA2000 Wifi gateway
|
|
385
|
+
parseActisenceN2KAscii(pgn_data, cb) {
|
|
386
|
+
try {
|
|
387
|
+
const { data, error, ...pgn } = parseActisenseN2KASCII(pgn_data)
|
|
388
|
+
if (!error ) {
|
|
389
|
+
const bs = new BitStream(data)
|
|
390
|
+
delete pgn.format
|
|
391
|
+
const res = this._parse(pgn, bs, data.length, false, cb, pgn_data)
|
|
392
|
+
if ( res ) {
|
|
393
|
+
debug('parsed n2k ascii pgn %j', pgn_data)
|
|
394
|
+
return res
|
|
395
|
+
}
|
|
396
|
+
} else if ( error ) {
|
|
397
|
+
cb && cb(error)
|
|
398
|
+
this.emit('error', pgn_data, error)
|
|
399
|
+
}
|
|
400
|
+
} catch ( error ) {
|
|
401
|
+
cb && cb(error)
|
|
402
|
+
this.emit('error', pgn_data, error)
|
|
403
|
+
}
|
|
404
|
+
return undefined
|
|
405
|
+
}
|
|
406
|
+
|
|
384
407
|
parsePDGY(pgn_data, cb) {
|
|
385
408
|
if ( pgn_data[0] != '!') {
|
|
386
409
|
return
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
const debug = require('debug')('canboatjs:w2k01')
|
|
2
|
+
const debugData = require('debug')('canboatjs:w2k01-data')
|
|
3
|
+
const { parseCanId, encodeCanId } = require('./canId')
|
|
4
|
+
const BitStream = require('bit-buffer').BitStream
|
|
5
|
+
|
|
6
|
+
exports.readN2KActisense = function (data, plainText, context, cb) {
|
|
7
|
+
const inBuf = Buffer.from(data)
|
|
8
|
+
let inOffset = 0
|
|
9
|
+
let last
|
|
10
|
+
|
|
11
|
+
if ( debugData.enabled ) {
|
|
12
|
+
debugData('Received: (' + data.length + ') ' + Buffer.from(data).toString('hex'))
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
while ( true ) {
|
|
17
|
+
let len = inBuf.readUInt16LE(inOffset+3)
|
|
18
|
+
|
|
19
|
+
if ( inBuf.length < inOffset + 5 + len ) {
|
|
20
|
+
/*
|
|
21
|
+
I've never seen this happen
|
|
22
|
+
context.lastChunk = Buffer.alloc(inBuf.length - inOffset)
|
|
23
|
+
inBuf.copy(context.lastChunk, 0, inOffset, inBuf.length-1)
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
if ( debug.enabled ) {
|
|
27
|
+
debug('incomplete packet: (' + len + ') ' + inBuf.toString('hex', inOffset))
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return
|
|
31
|
+
} else if ( inBuf[inOffset + 5 + len -1] != 0x03 ||
|
|
32
|
+
inBuf[inOffset + 5 + len -2] != 0x10 ) {
|
|
33
|
+
if ( debug.enabled ) {
|
|
34
|
+
debug('bad packet: (' + len + ') ' + inBuf.toString('hex', inOffset))
|
|
35
|
+
}
|
|
36
|
+
//context.lastChunk = null
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let buf = Buffer.alloc(len)
|
|
41
|
+
inBuf.copy(buf, 0, inOffset+5, inOffset+len+5)
|
|
42
|
+
|
|
43
|
+
//console.log('NextBuf: (' + buf.length + ') ' + buf.toString('hex'))
|
|
44
|
+
|
|
45
|
+
let offset = 0
|
|
46
|
+
let dst = buf.readUInt8(offset)
|
|
47
|
+
offset += 1
|
|
48
|
+
let canid = buf.readUInt32LE(offset)
|
|
49
|
+
offset += 4
|
|
50
|
+
let timestamp = buf.readUInt32LE(offset)
|
|
51
|
+
offset += 4
|
|
52
|
+
let mhs = buf.readUInt8(offset)
|
|
53
|
+
offset += 1
|
|
54
|
+
|
|
55
|
+
let info = parseCanId(canid)
|
|
56
|
+
|
|
57
|
+
//console.log(`${len} ${mhs} ${dst} (${info.src}, ${info.dst}) ${info.pgn} ${timestamp}`)
|
|
58
|
+
|
|
59
|
+
let pgnData = Buffer.alloc(len-offset-3)
|
|
60
|
+
buf.copy(pgnData, 0, offset, len-3)
|
|
61
|
+
info.timestamp = new Date().toISOString()
|
|
62
|
+
|
|
63
|
+
if ( plainText ) {
|
|
64
|
+
last = binToActisense(info, pgnData, pgnData.length)
|
|
65
|
+
cb && cb(last)
|
|
66
|
+
} else {
|
|
67
|
+
last = { pgn:info, length: pgnData.length, data: pgnData, coalesced: true }
|
|
68
|
+
cb && cb(last)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
inOffset += len + 5
|
|
72
|
+
if ( inOffset == inBuf.length ) {
|
|
73
|
+
return last
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
} catch ( error ) {
|
|
77
|
+
debug(`[error] ${error}`)
|
|
78
|
+
//context.lastChunk = null
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
exports.encodeN2KActisense = ({
|
|
84
|
+
pgn, data, timestamp, prio = 2, dst = 255, src = 0 }) => {
|
|
85
|
+
const bs = new BitStream(Buffer.alloc(18 + data.length))
|
|
86
|
+
|
|
87
|
+
bs.writeUint8(0x10) //BST Message ID
|
|
88
|
+
bs.writeUint8(0x02)
|
|
89
|
+
bs.writeUint8(0xd0)
|
|
90
|
+
|
|
91
|
+
bs.writeUint16(13 + data.length) //len
|
|
92
|
+
bs.writeUint8(dst)
|
|
93
|
+
bs.writeUint32(encodeCanId({dst, pgn, prio, src}))
|
|
94
|
+
bs.writeUint32(0) //timestamp
|
|
95
|
+
bs.writeUint8(0) //mhs
|
|
96
|
+
data.copy(bs.view.buffer, bs.byteIndex, 0)
|
|
97
|
+
bs.byteIndex += data.length
|
|
98
|
+
bs.writeUint8(0) // ??
|
|
99
|
+
bs.writeUint8(0x10)
|
|
100
|
+
bs.writeUint8(0x03)
|
|
101
|
+
|
|
102
|
+
if ( debugData.enabled ) {
|
|
103
|
+
debugData('encoded: ' + bs.view.buffer.toString('hex'))
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return bs.view.buffer
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
function binToActisense(pgn, data, length) {
|
|
111
|
+
return (
|
|
112
|
+
pgn.timestamp +
|
|
113
|
+
`,${pgn.prio},${pgn.pgn},${pgn.src},${pgn.dst},${length},` +
|
|
114
|
+
new Uint32Array(data)
|
|
115
|
+
.reduce(function(acc, i) {
|
|
116
|
+
acc.push(i.toString(16));
|
|
117
|
+
return acc;
|
|
118
|
+
}, [])
|
|
119
|
+
.map(x => (x.length === 1 ? "0" + x : x))
|
|
120
|
+
.join(",")
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const { readN2KActisense, encodeN2KActisense } = require('./n2k-actisense')
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
describe('readN2KActisense', () => {
|
|
5
|
+
test('basic msg', () => {
|
|
6
|
+
const buffer = Buffer.from('1002d01500ff0502f809004c86fe00fffccba56800ffff7310031002d01500ff0501f809004c86fe000d474717e2da69d29c1003', 'hex')
|
|
7
|
+
const res = readN2KActisense(buffer, false, {})
|
|
8
|
+
delete res.pgn.timestamp
|
|
9
|
+
expect(res).toEqual({
|
|
10
|
+
"coalesced": true,
|
|
11
|
+
"data": Buffer.from('0d474717e2da69d2', 'hex'),
|
|
12
|
+
"length": 8,
|
|
13
|
+
"pgn": {
|
|
14
|
+
"canId": 167248133,
|
|
15
|
+
"dst": 255,
|
|
16
|
+
"pgn": 129025,
|
|
17
|
+
"prio": 2,
|
|
18
|
+
"src": 5,
|
|
19
|
+
}
|
|
20
|
+
})
|
|
21
|
+
})
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
describe('encodeN2KActisense', () => {
|
|
26
|
+
test('basic msg', () => {
|
|
27
|
+
const expected = '1002d01500ff0501f80900000000000d474717e2da69d2001003'
|
|
28
|
+
const pgn = {
|
|
29
|
+
"data": Buffer.from('0d474717e2da69d2', 'hex'),
|
|
30
|
+
"dst": 255,
|
|
31
|
+
"pgn": 129025,
|
|
32
|
+
"prio": 2,
|
|
33
|
+
"src": 5,
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const encoded = encodeN2KActisense(pgn)
|
|
37
|
+
expect(encoded).toEqual(Buffer.from(expected, 'hex'))
|
|
38
|
+
|
|
39
|
+
const read = readN2KActisense(encoded, false, {})
|
|
40
|
+
delete read.pgn.timestamp
|
|
41
|
+
|
|
42
|
+
expect(read).toEqual({
|
|
43
|
+
"coalesced": true,
|
|
44
|
+
"data": Buffer.from('0d474717e2da69d2', 'hex'),
|
|
45
|
+
"length": 8,
|
|
46
|
+
"pgn": {
|
|
47
|
+
"canId": 167248133,
|
|
48
|
+
"dst": 255,
|
|
49
|
+
"pgn": 129025,
|
|
50
|
+
"prio": 2,
|
|
51
|
+
"src": 5,
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
|
package/lib/stringMsg.js
CHANGED
|
@@ -63,6 +63,34 @@ exports.toActisenseSerialFormat = (pgn, data, dst=255, src=0) => exports.encodeA
|
|
|
63
63
|
pgn, data, dst, src,
|
|
64
64
|
})
|
|
65
65
|
|
|
66
|
+
// A764027.880 05FF7 1EF00 E59861060202FFFFFFFF03030000FFFFFFFFFFFFFFFFFFFF0000FFFFFF7FFFFFFF7FFFFFFF7F0000FF7F
|
|
67
|
+
exports.isActisenseN2KASCII = input => input.charAt(0) === 'A' && input.charAt(7) === '.' && input.charAt(11) === ' '
|
|
68
|
+
exports.parseActisenseN2KASCII = (input) => {
|
|
69
|
+
const [ timestamp, srcdstp, pgn, data ] = input.split(' ')
|
|
70
|
+
const src = parseInt(srcdstp.substring(0, 2), 16)
|
|
71
|
+
const dst = parseInt(srcdstp.substring(2,4), 16)
|
|
72
|
+
const prio = parseInt(srcdstp.substring(4))
|
|
73
|
+
return buildMsg(
|
|
74
|
+
buildCanId(prio, parseInt(pgn, 16), dst, src),
|
|
75
|
+
'Actisense N2K ASCII',
|
|
76
|
+
Buffer.from(data, 'hex'),
|
|
77
|
+
{ len: data.length, time: timestamp.substring(1) },
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
exports.encodeActisenseN2KACSII = ({
|
|
81
|
+
pgn, data, timestamp, prio = 2, dst = 255, src = 0 }) => {
|
|
82
|
+
timestamp = 'A000000.000'
|
|
83
|
+
|
|
84
|
+
const srcdstp = hexByte(src) + hexByte(dst) + prio
|
|
85
|
+
return ([
|
|
86
|
+
timestamp,
|
|
87
|
+
srcdstp.toUpperCase(),
|
|
88
|
+
toPaddedHexString(pgn, 5).toUpperCase(),
|
|
89
|
+
byteString(data, '').toUpperCase()
|
|
90
|
+
].join(' '))
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
|
|
66
94
|
// 16:29:27.082 R 09F8017F 50 C3 B8 13 47 D8 2B C6
|
|
67
95
|
exports.isYDRAW = (input) => {
|
|
68
96
|
if (input.charAt(2) !== ':') return false
|
|
@@ -232,6 +260,7 @@ exports.parseN2kString = cond([
|
|
|
232
260
|
[exports.isCandump2, exports.parseCandump2],
|
|
233
261
|
[exports.isCandump3, exports.parseCandump3],
|
|
234
262
|
[exports.isPDGYdebug, exports.parsePDGYdebug],
|
|
263
|
+
[exports.isActisenseN2KASCII, exports.parseActisenseN2KASCII],
|
|
235
264
|
[stubTrue, buildErr('MISSING_PARSER', 'Parser not found for input.')],
|
|
236
265
|
])
|
|
237
266
|
|
|
@@ -246,6 +275,7 @@ exports.isN2KString = cond([
|
|
|
246
275
|
[exports.isCandump2, () => true],
|
|
247
276
|
[exports.isCandump3, () => true],
|
|
248
277
|
[exports.isPDGYdebug, () => true],
|
|
278
|
+
[exports.isActisenseN2KASCII, () => true],
|
|
249
279
|
[stubTrue, () => false],
|
|
250
280
|
])
|
|
251
281
|
|
package/lib/stringMsg.test.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const {
|
|
2
2
|
encodeActisense, encodeYDRAW, parseActisense, parseCandump1, parseCandump2,
|
|
3
|
-
parsePCDIN, parsePDGY, parseN2kString, parsePDGYdebug, parseYDRAW,
|
|
3
|
+
parsePCDIN, parsePDGY, parseN2kString, parsePDGYdebug, parseYDRAW, encodeActisenseN2KACSII, parseActisenseN2KASCII
|
|
4
4
|
} = require('./stringMsg')
|
|
5
5
|
|
|
6
6
|
/* globals describe test expect */
|
|
@@ -185,6 +185,32 @@ describe('encodeYDRAW', () => {
|
|
|
185
185
|
])
|
|
186
186
|
})
|
|
187
187
|
})
|
|
188
|
+
|
|
189
|
+
describe('parseActisenseN2KASCII', () => {
|
|
190
|
+
test('basic msg', () => {
|
|
191
|
+
const msg = 'A000021.293 05FF2 1F802 FFFC289A1600FFFF'
|
|
192
|
+
expect(parseActisenseN2KASCII(msg)).toEqual({
|
|
193
|
+
data: Buffer.from('FFFC289A1600FFFF', 'hex'),
|
|
194
|
+
"dst": 255,
|
|
195
|
+
"format": "Actisense N2K ASCII",
|
|
196
|
+
"len": 16,
|
|
197
|
+
"pgn": 129026,
|
|
198
|
+
"prio": 2,
|
|
199
|
+
"src": 5,
|
|
200
|
+
"time": "000021.293"
|
|
201
|
+
})
|
|
202
|
+
})
|
|
203
|
+
})
|
|
204
|
+
describe('encodeActisenseN2KACSII', () => {
|
|
205
|
+
test('basic msg', () => {
|
|
206
|
+
const msg = 'A000000.000 05FF2 1F802 FFFC289A1600FFFF'
|
|
207
|
+
const n2k = parseActisenseN2KASCII(msg)
|
|
208
|
+
const res = encodeActisenseN2KACSII(n2k)
|
|
209
|
+
expect(res).toEqual(msg)
|
|
210
|
+
})
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
|
|
188
214
|
describe('parseN2kString', () => {
|
|
189
215
|
test('empty string or not string', () => {
|
|
190
216
|
const emptyMsg = 'Input not string or empty.'
|
package/lib/toPgn.js
CHANGED
|
@@ -21,7 +21,8 @@ const BitStream = require('bit-buffer').BitStream
|
|
|
21
21
|
const Int64LE = require('int64-buffer').Int64LE
|
|
22
22
|
const Uint64LE = require('int64-buffer').Uint64LE
|
|
23
23
|
const { getPlainPGNs } = require('./utilities')
|
|
24
|
-
const { encodeActisense, encodeYDRAW, parseActisense, encodePCDIN, encodeMXPGN, encodePDGY } = require('./stringMsg')
|
|
24
|
+
const { encodeActisense, encodeActisenseN2KACSII, encodeYDRAW, parseActisense, encodePCDIN, encodeMXPGN, encodePDGY } = require('./stringMsg')
|
|
25
|
+
const { encodeN2KActisense } = require('./n2k-actisense')
|
|
25
26
|
const { encodeCanId } = require('./canId')
|
|
26
27
|
const { getIndustryCode, getManufacturerCode } = require('./codes')
|
|
27
28
|
const debug = require('debug')('canboatjs:toPgn')
|
|
@@ -291,6 +292,14 @@ function pgnToActisenseSerialFormat(pgn) {
|
|
|
291
292
|
return encodeActisense({ pgn: pgn.pgn, data: toPgn(pgn), dst: pgn.dst})
|
|
292
293
|
}
|
|
293
294
|
|
|
295
|
+
function pgnToActisenseN2KAsciiFormat(pgn) {
|
|
296
|
+
return encodeActisenseN2KACSII({ pgn: pgn.pgn, data: toPgn(pgn), dst: pgn.dst})
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function pgnToN2KActisenseFormat(pgn) {
|
|
300
|
+
return encodeN2KActisense({ pgn: pgn.pgn, data: toPgn(pgn), dst: pgn.dst})
|
|
301
|
+
}
|
|
302
|
+
|
|
294
303
|
function toiKonvertSerialFormat(pgn, data, dst=255) {
|
|
295
304
|
return `!PDGY,${pgn},${dst},${data.toString('base64')}`
|
|
296
305
|
}
|
|
@@ -315,6 +324,8 @@ const actisenseToYdgwRawFormat = _.flow(parseActisense, encodeYDRAW)
|
|
|
315
324
|
const actisenseToPCDIN = _.flow(parseActisense, encodePCDIN)
|
|
316
325
|
const actisenseToMXPGN = _.flow(parseActisense, encodeMXPGN)
|
|
317
326
|
const actisenseToiKonvert = _.flow(parseActisense, encodePDGY)
|
|
327
|
+
const actisenseToN2KAsciiFormat = _.flow(parseActisense, encodeActisenseN2KACSII)
|
|
328
|
+
const actisenseToN2KActisenseFormat = _.flow(parseActisense, encodeN2KActisense)
|
|
318
329
|
|
|
319
330
|
fieldTypeWriters['ASCII text'] = (pgn, field, value, bs) => {
|
|
320
331
|
|
|
@@ -431,8 +442,12 @@ module.exports.pgnToiKonvertSerialFormat = pgnToiKonvertSerialFormat
|
|
|
431
442
|
module.exports.pgnToYdgwRawFormat = pgnToYdgwRawFormat
|
|
432
443
|
module.exports.actisenseToYdgwRawFormat = actisenseToYdgwRawFormat
|
|
433
444
|
module.exports.pgnToActisenseSerialFormat = pgnToActisenseSerialFormat
|
|
445
|
+
module.exports.pgnToActisenseN2KAsciiFormat = pgnToActisenseN2KAsciiFormat
|
|
446
|
+
module.exports.pgnToN2KActisenseFormat = pgnToN2KActisenseFormat
|
|
434
447
|
module.exports.pgnToPCDIN = pgnToPCDIN
|
|
435
448
|
module.exports.actisenseToPCDIN = actisenseToPCDIN
|
|
436
449
|
module.exports.pgnToMXPGN = pgnToMXPGN
|
|
437
450
|
module.exports.actisenseToMXPGN = actisenseToMXPGN
|
|
438
451
|
module.exports.actisenseToiKonvert = actisenseToiKonvert
|
|
452
|
+
module.exports.actisenseToN2KAsciiFormat = actisenseToN2KAsciiFormat
|
|
453
|
+
module.exports.actisenseToN2KActisenseFormat = actisenseToN2KActisenseFormat
|
package/lib/w2k01.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2018 Scott Bender (scott@scottbender.net)
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const debug = require('debug')('canboatjs:w2k01')
|
|
18
|
+
const debugData = require('debug')('canboatjs:w2k01-data')
|
|
19
|
+
const Transform = require('stream').Transform
|
|
20
|
+
const _ = require('lodash')
|
|
21
|
+
const { pgnToActisenseN2KAsciiFormat, actisenseToN2KAsciiFormat, pgnToN2KActisenseFormat, actisenseToN2KActisenseFormat } = require('./toPgn')
|
|
22
|
+
const { readN2KActisense, encodeN2KActisense } = require('./n2k-actisense')
|
|
23
|
+
|
|
24
|
+
const pgnsSent = {}
|
|
25
|
+
|
|
26
|
+
const N2K_ASCII = 0
|
|
27
|
+
const N2K_ACTISENSE = 1
|
|
28
|
+
|
|
29
|
+
function W2K01Stream (options, type, outEvent) {
|
|
30
|
+
if (!(this instanceof W2K01Stream)) {
|
|
31
|
+
return new W2K01Stream(options)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Transform.call(this, {
|
|
35
|
+
objectMode: true
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
this.sentAvailable = false
|
|
39
|
+
this.options = options
|
|
40
|
+
this.outEvent = outEvent || 'w2k-1-out'
|
|
41
|
+
|
|
42
|
+
this.format = type === 'ascii' ? N2K_ASCII : N2K_ACTISENSE
|
|
43
|
+
|
|
44
|
+
if ( this.format === N2K_ASCII ) {
|
|
45
|
+
if ( options.app ) {
|
|
46
|
+
options.app.on(this.options.outEevent || 'nmea2000out', (msg) => {
|
|
47
|
+
if ( typeof msg === 'string' ) {
|
|
48
|
+
this.sendW2KPGN(msg)
|
|
49
|
+
} else {
|
|
50
|
+
this.sendPGN(msg)
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
options.app.on('nmea2000JsonOut', (msg) => {
|
|
55
|
+
this.sendPGN(msg)
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
debug('started')
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
W2K01Stream.prototype.send = function (msg) {
|
|
64
|
+
debug('sending %s', msg)
|
|
65
|
+
this.options.app.emit(this.outEvent, msg)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
W2K01Stream.prototype.sendPGN = function (pgn) {
|
|
69
|
+
let now = Date.now()
|
|
70
|
+
let lastSent = pgnsSent[pgn.pgn]
|
|
71
|
+
if ( this.format === N2K_ASCII ) {
|
|
72
|
+
let ascii = pgnToActisenseN2KAsciiFormat(pgn)
|
|
73
|
+
this.send(ascii + '\r\n')
|
|
74
|
+
} else {
|
|
75
|
+
let buf = pgnToN2KActisenseFormat(pgn)
|
|
76
|
+
this.send(buf)
|
|
77
|
+
}
|
|
78
|
+
pgnsSent[pgn.pgn] = now
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
W2K01Stream.prototype.sendW2KPGN = function (msg) {
|
|
82
|
+
if ( this.format === N2K_ASCII ) {
|
|
83
|
+
let ascii = actisenseToN2KAsciiFormat(msg)
|
|
84
|
+
this.send(ascii + '\r\n')
|
|
85
|
+
} else {
|
|
86
|
+
let buf = actisenseToN2KActisenseFormat
|
|
87
|
+
this.send(buf)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
require('util').inherits(W2K01Stream, Transform)
|
|
92
|
+
|
|
93
|
+
W2K01Stream.prototype._transform = function (chunk, encoding, done) {
|
|
94
|
+
if ( !this.sentAvailable && this.format === N2K_ASCII ) {
|
|
95
|
+
debug('emit nmea2000OutAvailable')
|
|
96
|
+
this.options.app.emit('nmea2000OutAvailable')
|
|
97
|
+
this.sentAvailable = true
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if ( this.format === N2K_ASCII ) {
|
|
101
|
+
if ( debugData.enabled ) {
|
|
102
|
+
debugData('Received: ' + chunk)
|
|
103
|
+
}
|
|
104
|
+
this.push(chunk)
|
|
105
|
+
} else {
|
|
106
|
+
readN2KActisense(chunk, this.plainText, this, (data) => {
|
|
107
|
+
this.push(data)
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
done()
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
W2K01Stream.prototype.pipe = function (pipeTo) {
|
|
115
|
+
if ( !pipeTo.fromPgn ) {
|
|
116
|
+
this.plainText = true
|
|
117
|
+
} else {
|
|
118
|
+
this.plainText = false
|
|
119
|
+
}
|
|
120
|
+
return W2K01Stream.super_.prototype.pipe.call(this, pipeTo)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
W2K01Stream.prototype.end = function () {
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
module.exports = W2K01Stream
|
package/lib/ydvr.js
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
const BitStream = require('bit-buffer').BitStream;
|
|
2
|
+
const Transform = require('stream').Transform;
|
|
3
|
+
const FromPgn = require('./fromPgn').Parser
|
|
4
|
+
const parseCanId = require('./canId').parseCanId;
|
|
5
|
+
|
|
6
|
+
// https://www.yachtd.com/downloads/ydvr04.pdf Appendix D
|
|
7
|
+
var sequencePgns = new Set([
|
|
8
|
+
65240,
|
|
9
|
+
126208,
|
|
10
|
+
126464,
|
|
11
|
+
126720,
|
|
12
|
+
126983,
|
|
13
|
+
126984,
|
|
14
|
+
126985,
|
|
15
|
+
126986,
|
|
16
|
+
126987,
|
|
17
|
+
126988,
|
|
18
|
+
126996,
|
|
19
|
+
126998,
|
|
20
|
+
127233,
|
|
21
|
+
127237,
|
|
22
|
+
127489,
|
|
23
|
+
127496,
|
|
24
|
+
127497,
|
|
25
|
+
127498,
|
|
26
|
+
127503,
|
|
27
|
+
127504,
|
|
28
|
+
127506,
|
|
29
|
+
127507,
|
|
30
|
+
127509,
|
|
31
|
+
127510,
|
|
32
|
+
127511,
|
|
33
|
+
127512,
|
|
34
|
+
127513,
|
|
35
|
+
127514,
|
|
36
|
+
128275,
|
|
37
|
+
128520,
|
|
38
|
+
129029,
|
|
39
|
+
129038,
|
|
40
|
+
129039,
|
|
41
|
+
129040,
|
|
42
|
+
129041,
|
|
43
|
+
129044,
|
|
44
|
+
129045,
|
|
45
|
+
129284,
|
|
46
|
+
129285,
|
|
47
|
+
129301,
|
|
48
|
+
129302,
|
|
49
|
+
129538,
|
|
50
|
+
129540,
|
|
51
|
+
129541,
|
|
52
|
+
129542,
|
|
53
|
+
129545,
|
|
54
|
+
129547,
|
|
55
|
+
129549,
|
|
56
|
+
129551,
|
|
57
|
+
129556,
|
|
58
|
+
129792,
|
|
59
|
+
129793,
|
|
60
|
+
129794,
|
|
61
|
+
129795,
|
|
62
|
+
129796,
|
|
63
|
+
129797,
|
|
64
|
+
129798,
|
|
65
|
+
129799,
|
|
66
|
+
129800,
|
|
67
|
+
129801,
|
|
68
|
+
129802,
|
|
69
|
+
129803,
|
|
70
|
+
129804,
|
|
71
|
+
129805,
|
|
72
|
+
129806,
|
|
73
|
+
129807,
|
|
74
|
+
129808,
|
|
75
|
+
129809,
|
|
76
|
+
129810,
|
|
77
|
+
130052,
|
|
78
|
+
130053,
|
|
79
|
+
130054,
|
|
80
|
+
130060,
|
|
81
|
+
130061,
|
|
82
|
+
130064,
|
|
83
|
+
130065,
|
|
84
|
+
130066,
|
|
85
|
+
130067,
|
|
86
|
+
130068,
|
|
87
|
+
130069,
|
|
88
|
+
130070,
|
|
89
|
+
130071,
|
|
90
|
+
130072,
|
|
91
|
+
130073,
|
|
92
|
+
130074,
|
|
93
|
+
130320,
|
|
94
|
+
130321,
|
|
95
|
+
130322,
|
|
96
|
+
130323,
|
|
97
|
+
130324,
|
|
98
|
+
130567,
|
|
99
|
+
130577,
|
|
100
|
+
130578,
|
|
101
|
+
130816,
|
|
102
|
+
]);
|
|
103
|
+
|
|
104
|
+
function YdvrStream() {
|
|
105
|
+
if (!(this instanceof YdvrStream)) {
|
|
106
|
+
return new YdvrStream();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
this.parser = new FromPgn();
|
|
110
|
+
|
|
111
|
+
this.parser.on('error', (pgn, error) => {
|
|
112
|
+
console.error(`Error parsing ${pgn.pgn} ${error}`);
|
|
113
|
+
console.error(error.stack);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
this.parser.on('warning', (pgn, error) => {
|
|
117
|
+
//console.error(`Warning parsing ${pgn.pgn} ${error}`)
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// this.parser.on('pgn', (pgn) => {
|
|
121
|
+
// console.log(JSON.stringify(pgn));
|
|
122
|
+
// });
|
|
123
|
+
|
|
124
|
+
Transform.call(this, {
|
|
125
|
+
objectMode: true,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
require('util').inherits(YdvrStream, Transform);
|
|
130
|
+
|
|
131
|
+
YdvrStream.prototype.end = function () {
|
|
132
|
+
// console.log('end');
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
YdvrStream.prototype.parseNextRecord = function () {
|
|
136
|
+
if (this.bs.bitsLeft < 6 * 8) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
var time = this.bs.readUint16();
|
|
141
|
+
let timeAbsolute;
|
|
142
|
+
if (this.lastTime != null && time < this.lastTime) {
|
|
143
|
+
this.timeOffset = (this.timeOffset || 0) + 60000;
|
|
144
|
+
timeAbsolute = time + timeOffset;
|
|
145
|
+
} else {
|
|
146
|
+
timeAbsolute = time;
|
|
147
|
+
}
|
|
148
|
+
this.lastTime = time;
|
|
149
|
+
|
|
150
|
+
var identifier = this.bs.readUint32();
|
|
151
|
+
if (identifier === 0xffffffff) {
|
|
152
|
+
// service record
|
|
153
|
+
var srData = this.bs.readArrayBuffer(8);
|
|
154
|
+
} else {
|
|
155
|
+
const pgn = parseCanId(identifier);
|
|
156
|
+
|
|
157
|
+
var bodyLen;
|
|
158
|
+
if (pgn.pgn == 59904) {
|
|
159
|
+
bodyLen = 3;
|
|
160
|
+
} else if (sequencePgns.has(pgn.pgn)) {
|
|
161
|
+
var seq = this.bs.readUint8();
|
|
162
|
+
bodyLen = this.bs.readUint8();
|
|
163
|
+
} else {
|
|
164
|
+
bodyLen = 8;
|
|
165
|
+
}
|
|
166
|
+
var body = this.bs.readArrayBuffer(bodyLen);
|
|
167
|
+
|
|
168
|
+
const parsed = this.parser.parsePgnData(
|
|
169
|
+
{ ...pgn, time: new Date(time).toISOString().slice(11, 23) },
|
|
170
|
+
bodyLen,
|
|
171
|
+
Buffer.from(body),
|
|
172
|
+
false,
|
|
173
|
+
undefined
|
|
174
|
+
);
|
|
175
|
+
if (parsed) {
|
|
176
|
+
this.push(parsed);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
YdvrStream.prototype._transform = function (chunk, encoding, done) {
|
|
184
|
+
if (this.bs == null) {
|
|
185
|
+
this.bs = new BitStream(chunk);
|
|
186
|
+
} else {
|
|
187
|
+
var remainingBuffer = this.bs.view.buffer.subarray(this.bs.byteIndex);
|
|
188
|
+
this.bs = new BitStream(Buffer.concat([remainingBuffer, chunk]));
|
|
189
|
+
}
|
|
190
|
+
while (true) {
|
|
191
|
+
var startIndex = this.bs.byteIndex
|
|
192
|
+
let parsed = false;
|
|
193
|
+
try {
|
|
194
|
+
parsed = this.parseNextRecord();
|
|
195
|
+
} catch (ex) { }
|
|
196
|
+
if (!parsed) {
|
|
197
|
+
this.bs.byteIndex = startIndex;
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
done();
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
module.exports = YdvrStream
|
package/n2ka.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
var net = require('net');
|
|
2
|
+
const BitStream = require('bit-buffer').BitStream
|
|
3
|
+
const BitView = require('bit-buffer').BitView
|
|
4
|
+
const cid = require('./lib/canId')
|
|
5
|
+
const FromPgn = require('./lib/fromPgn').Parser
|
|
6
|
+
const debug = require('debug')('canboatjs:w2k01')
|
|
7
|
+
|
|
8
|
+
var client = new net.Socket();
|
|
9
|
+
client.connect(60003, '192.168.1.145', function() {
|
|
10
|
+
console.log('Connected');
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
client.on('data', function(data) {
|
|
14
|
+
const parser = new FromPgn()
|
|
15
|
+
|
|
16
|
+
/*
|
|
17
|
+
var obuf = Buffer.from(data)
|
|
18
|
+
let len = obuf.readUInt16LE(3)
|
|
19
|
+
|
|
20
|
+
let buf = Buffer.alloc(len)
|
|
21
|
+
obuf.copy(buf, 0, 5, len+5)
|
|
22
|
+
console.log('New Buf: ' + buf.toString('hex'))
|
|
23
|
+
let offset = 0
|
|
24
|
+
let dst = buf.readUInt8(offset)
|
|
25
|
+
offset += 1
|
|
26
|
+
let canid = buf.readUInt32LE(offset)
|
|
27
|
+
offset += 4
|
|
28
|
+
let timestamp = buf.readUInt32LE(offset)
|
|
29
|
+
offset += 4
|
|
30
|
+
let mhs = buf.readUInt8(offset)
|
|
31
|
+
offset += 1
|
|
32
|
+
|
|
33
|
+
let info = cid.parseCanId(canid)
|
|
34
|
+
|
|
35
|
+
console.log(`(${len}, ${data.length}) (${info.src}, ${info.dst}) ${info.pgn} ${timestamp}`)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
let pgnData = Buffer.alloc(len-offset-2)
|
|
40
|
+
buf.copy(pgnData, 0, offset, len-2)
|
|
41
|
+
console.log('pgnData: ' + pgnData.toString('hex'))
|
|
42
|
+
let pgn = parser.parsePgnData(info, pgnData.length, pgnData, true)
|
|
43
|
+
console.log(pgn)
|
|
44
|
+
} catch (error) {
|
|
45
|
+
|
|
46
|
+
console.log(error)
|
|
47
|
+
}
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
debug('Received: (' + data.length + ') ' + Buffer.from(data).toString('hex'))
|
|
51
|
+
|
|
52
|
+
var inBuf = Buffer.from(data)
|
|
53
|
+
var inOffset = 0
|
|
54
|
+
|
|
55
|
+
while ( true ) {
|
|
56
|
+
let len = inBuf.readUInt16LE(inOffset+3)
|
|
57
|
+
|
|
58
|
+
if ( inBuf.length < inOffset + 5 + len ) {
|
|
59
|
+
console.log('PARTIAL PGN')
|
|
60
|
+
this.lastChunk = Buffer.alloc(inBuf.length - inOffset)
|
|
61
|
+
inBuf.copy(this.lastChunk, 0, inOffset, inBuf.length-1)
|
|
62
|
+
return
|
|
63
|
+
} else if ( inBuf[inOffset + 5 + len -1] != 0x03 ||
|
|
64
|
+
inBuf[inOffset + 5 + len -2] != 0x10 ) {
|
|
65
|
+
//console.log('Received: (' + data.length + ') ' + Buffer.from(data).toString('hex'))
|
|
66
|
+
//console.log('LENGTH MISMATCH ' + inBuf[inOffset + 5 + len -1])
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let buf = Buffer.alloc(len)
|
|
71
|
+
inBuf.copy(buf, 0, inOffset+5, inOffset+len+5)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
let offset = 0
|
|
75
|
+
let dst = buf.readUInt8(offset)
|
|
76
|
+
offset += 1
|
|
77
|
+
let canid = buf.readUInt32LE(offset)
|
|
78
|
+
offset += 4
|
|
79
|
+
let timestamp = buf.readUInt32LE(offset)
|
|
80
|
+
offset += 4
|
|
81
|
+
let mhs = buf.readUInt8(offset)
|
|
82
|
+
offset += 1
|
|
83
|
+
|
|
84
|
+
let info = cid.parseCanId(canid)
|
|
85
|
+
|
|
86
|
+
if ( info.pgn != 129025)
|
|
87
|
+
return
|
|
88
|
+
|
|
89
|
+
let pgnData = Buffer.alloc(len-offset-3)
|
|
90
|
+
buf.copy(pgnData, 0, offset, len-3)
|
|
91
|
+
|
|
92
|
+
/*
|
|
93
|
+
console.log('inputLen: ' + inBuf.length)
|
|
94
|
+
console.log('NextBuf: (' + buf.length + ') ' + buf.toString('hex'))
|
|
95
|
+
console.log('pgnData: (' + pgnData.length + ') ' + pgnData.toString('hex'))
|
|
96
|
+
|
|
97
|
+
console.log(`${len} ${mhs} ${dst} (${info.src}, ${info.dst}) ${info.pgn} ${timestamp}`)
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
let pgn = parser.parsePgnData(info, pgnData.length, pgnData, true)
|
|
101
|
+
if ( pgn ) {
|
|
102
|
+
//console.log(JSON.stringify(pgn))
|
|
103
|
+
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
inOffset += len + 5
|
|
107
|
+
//console.log(`inOffset ${inOffset} `)
|
|
108
|
+
if ( inOffset >= inBuf.length ) {
|
|
109
|
+
return
|
|
110
|
+
}
|
|
111
|
+
break
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
client.on('close', function() {
|
|
116
|
+
console.log('Connection closed');
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
process.on('SIGINT', () => {
|
|
120
|
+
console.info('SIGINT signal received.');
|
|
121
|
+
client.destroy()
|
|
122
|
+
});
|
|
123
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canboat/canboatjs",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.24.0",
|
|
4
4
|
"description": "Native javascript version of canboat",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"@canboat/pgns": "^1.4.0",
|
|
54
54
|
"bit-buffer": "0.2.3",
|
|
55
55
|
"date-fns": "2.0.0-alpha.27",
|
|
56
|
-
"debug": "^4.
|
|
56
|
+
"debug": "^4.3.4",
|
|
57
57
|
"dnssd": "^0.4.1",
|
|
58
58
|
"int64-buffer": "^0.1.10",
|
|
59
59
|
"lodash": "^4.17.4",
|
package/wk2.out
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
A000021.144 05FF2 1F801 F04E4717B2E569D2
|
|
2
|
+
A000021.244 05FF2 1F801 EF4E4717B3E569D2
|
|
3
|
+
A000021.293 05FF2 1F802 FFFC289A1600FFFF
|
|
4
|
+
A000021.344 05FF2 1F801 EF4E4717B3E569D2
|
|
5
|
+
A000021.355 05FF7 1EF00 E59861060202FFFFFFFF03030000FFFFFFFFFFFFFFFFFFFF0000FFFFFF7FFFFFFF7FFFFFFF7F0000FF7F
|
|
6
|
+
A000021.360 05FF7 1EF00 E59812070202FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF7F
|
|
7
|
+
A000021.363 05FF3 1F904 FFFFFFFFFF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF7FFF7F
|
|
8
|
+
A000021.367 05FF3 1F903 FFF0FFFFFF7FFFFF
|
|
9
|
+
A000021.444 05FF2 1F801 EE4E4717B4E569D2
|
|
10
|
+
A000021.544 05FF2 1F802 FFFC289A1700FFFF
|
|
11
|
+
A000021.544 05FF2 1F801 F04E4717AFE569D2
|
|
12
|
+
A000021.644 05FF2 1F801 F14E4717ABE569D2
|
|
13
|
+
A000021.700 05FF7 1EF00 E598E708000A0301030DDDB7C684051101
|
|
14
|
+
A000021.744 05FF2 1F801 F24E4717A8E569D2
|
|
15
|
+
A000021.794 05FF2 1F802 FFFC289A1900FFFF
|
|
16
|
+
A000021.844 05FF2 1F801 F34E4717A4E569D2
|
|
17
|
+
A000021.944 05FF2 1F801 F34E4717A1E569D2
|
|
18
|
+
A000022.041 05FF7 1EF00 E5984819020203030101030F08FF0F00303CA31C0113C6A90F
|
|
19
|
+
A000022.044 05FF3 1F805 FFDB4BA48A7822C068149B75826B05808477E7A7D762F5998A99000000000014FC06CD002A03AAF2FFFF00
|
|
20
|
+
A000022.046 05FF6 1F11A FFF2DB4B69F8FFFF
|
|
21
|
+
A000022.068 05FF6 1FA03 FFDACD0010036F02
|
|
22
|
+
A000022.068 05FF7 1EF00 E5981700040453487B42F4D0E942AFB70443000000000000000000000000000000000000000000000000F29C0340CE06FB4022C10141BA7EC74000000000
|
|
23
|
+
A000022.073 05FF2 1F802 FFFC289A1D00FFFF
|
|
24
|
+
A000022.073 05FF2 1F801 F44E47179EE569D2
|
|
25
|
+
A000022.144 05FF2 1F801 F14E471797E569D2
|
|
26
|
+
A000022.244 05FF2 1F801 EC4E471799E569D2
|
|
27
|
+
A000022.294 05FF2 1F802 FFFC289A2800FFFF
|
|
28
|
+
A000022.344 05FF2 1F801 E74E47179BE569D2
|
|
29
|
+
A000022.355 05FF7 1EF00 E59861060202FFFFFFFF03030000FFFFFFFFFFFFFFFFFFFF0000FFFFFF7FFFFFFF7FFFFFFF7F0000FF7F
|
|
30
|
+
A000022.360 05FF7 1EF00 E59812070202FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF7F
|
|
31
|
+
A000022.362 05FF3 1F904 FFFFFFFFFF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF7FFF7F
|
|
32
|
+
A000022.366 05FF3 1F903 FFF0FFFFFF7FFFFF
|
|
33
|
+
A000022.387 05FF7 1EF00 E598E008020203090012E8071900
|
|
34
|
+
A000022.389 05FF7 1EF00 E598E008020203090112E8071900
|
|
35
|
+
A000022.391 05FF7 1EF00 E598E008020203090B11011900
|
|
36
|
+
A000022.392 05FF7 1EF00 E598E008020203090C12E8071900
|
|
37
|
+
A000022.444 05FF2 1F801 E04E47179CE569D2
|
|
38
|
+
A000022.544 05FF2 1F802 FFFC289A3200FFFF
|
|
39
|
+
A000022.544 05FF2 1F801 F54E471771E569D2
|
|
40
|
+
A000022.644 05FF2 1F801 ED4E471772E569D2
|
|
41
|
+
A000022.700 05FF7 1EF00 E598E708000A0301030DDDB7C684051101
|
|
42
|
+
A000022.744 05FF2 1F801 E54E471772E569D2
|
|
43
|
+
A000022.794 05FF2 1F802 FFFC289A4600FFFF
|
|
44
|
+
A000022.844 05FF2 1F801 DB4E471772E569D2
|
|
45
|
+
A000022.944 05FF2 1F801 D24E471771E569D2
|
|
46
|
+
A000023.044 05FF3 1F805 FFDB4BDBB17822804FA0566B826B0580C203F09CD762F53F9891000000000014FC06CD002A03AAF2FFFF00
|
|
47
|
+
A000023.049 05FF6 1F11A FFF2DB4B69F8FFFF
|
|
48
|
+
A000023.068 05FF6 1FA03 FFDACD0010036F02
|
|
49
|
+
A000023.068 05FF7 1EF00 E598170004043EAD77420D9DE84217C303430000000000000000000000000000000000000000000000007193034085F4FA40B0B701418E6FC74000000000
|
|
50
|
+
A000023.072 05FF2 1F802 FFFC289A5300FFFF
|
|
51
|
+
A000023.072 05FF2 1F801 C84E47176FE569D2
|
|
52
|
+
A000023.144 05FF2 1F801 C24E47176DE569D2
|
|
53
|
+
A000023.244 05FF2 1F801 B84E47176BE569D2
|
|
54
|
+
A000023.294 05FF2 1F802 FFFC289A5900FFFF
|
|
55
|
+
A000023.344 05FF2 1F801 AE4E471769E569D2
|
|
56
|
+
A000023.355 05FF7 1EF00 E59861060202FFFFFFFF03030000FFFFFFFFFFFFFFFFFFFF0000FFFFFF7FFFFFFF7FFFFFFF7F0000FF7F
|
|
57
|
+
A000023.360 05FF7 1EF00 E59812070202FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF7F
|
|
58
|
+
A000023.362 05FF3 1F904 FFFFFFFFFF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF7FFF7F
|
|
59
|
+
A000023.366 05FF3 1F903 FFF0FFFFFF7FFFFF
|
|
60
|
+
A000023.443 05FF2 1F801 9E4E471764E569D2
|
|
61
|
+
A000023.541 05FF7 1EF00 E5984719020206030101030F08FF0F00303CA31C011100190022904E2B9EA10C
|
|
62
|
+
A000023.544 05FF2 1F802 FFFC8B956500FFFF
|
|
63
|
+
A000023.545 05FF2 1F801 914E471761E569D2
|
|
64
|
+
A000023.644 05FF2 1F801 984E471762E569D2
|
|
65
|
+
A000023.700 05FF7 1EF00 E598E708000A0301030DDDB7C684051101
|
|
66
|
+
A000023.744 05FF2 1F801 3A4E471754E569D2
|
|
67
|
+
A000023.794 05FF2 1F802 FFFC488E6900FFFF
|
|
68
|
+
A000023.844 05FF2 1F801 314E471752E569D2
|
|
69
|
+
A000023.944 05FF2 1F801 2A4E471752E569D2
|
|
70
|
+
A000024.041 05FF7 1EF00 E5984819020203030101030F08FF0F00303CA31C0113C7A90F
|
|
71
|
+
A000024.044 05FF3 1F805 FFDB4BC4D87822C0589B0945826B0500F03E8196D762F52BF085000000000014FC06CD002A03AAF2FFFF00
|
|
72
|
+
A000024.048 05FF6 1F11A FFF2DB4B69F8FFFF
|
|
73
|
+
A000024.068 05FF6 1FA03 FFDACD0010036F02
|
|
74
|
+
A000024.068 05FF7 1EF00 E59817000404AF8B764259E0E742CB4D0343000000000000000000000000000000000000000000000000EB8903401DE2FA402EAE01414C60C74000000000
|
|
75
|
+
A000024.071 05FF2 1F802 FFFCDE896200FFFF
|
|
76
|
+
A000024.075 05FF2 1F801 234E471753E569D2
|
|
77
|
+
A000024.144 05FF2 1F801 204E471754E569D2
|
|
78
|
+
A000024.244 05FF2 1F801 1D4E471754E569D2
|
|
79
|
+
A000024.294 05FF2 1F802 FFFC78865600FFFF
|
|
80
|
+
A000024.344 05FF2 1F801 1A4E471754E569D2
|
|
81
|
+
A000024.354 05FF7 1EF00 E59861060202FFFFFFFF03030000FFFFFFFFFFFFFFFFFFFF0000FFFFFF7FFFFFFF7FFFFFFF7F0000FF7F
|
|
82
|
+
A000024.360 05FF7 1EF00 E59812070202FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF7F
|
|
83
|
+
A000024.362 05FF3 1F904 FFFFFFFFFF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF7FFF7F
|
|
84
|
+
A000024.364 05FF3 1F903 FFF0FFFFFF7FFFFF
|
|
85
|
+
A000024.387 05FF7 1EF00 E598E008020203090012E8071900
|
|
86
|
+
A000024.389 05FF7 1EF00 E598E008020203090112E8071900
|
|
87
|
+
A000024.391 05FF7 1EF00 E598E008020203090B11011900
|
|
88
|
+
A000024.392 05FF7 1EF00 E598E008020203090C12E8071900
|
|
89
|
+
A000024.444 05FF2 1F801 174E471755E569D2
|
|
90
|
+
A000024.544 05FF2 1F802 FFFC78865000FFFF
|
|
91
|
+
A000024.545 05FF2 1F801 144E471755E569D2
|
|
92
|
+
A000024.644 05FF2 1F801 114E471756E569D2
|
|
93
|
+
A000024.700 05FF7 1EF00 E598E708000A0301030DDDB7C684051101
|
|
94
|
+
A000024.744 05FF2 1F801 074E471756E569D2
|
|
95
|
+
A000024.794 05FF2 1F802 FFFC78864900FFFF
|
|
96
|
+
A000024.844 05FF2 1F801 FF4D471755E569D2
|
|
97
|
+
A000024.944 05FF2 1F801 F84D471755E569D2
|
|
98
|
+
A000025.044 05FF3 1F805 FFDB4BD4FF7822C025B34D38826B0500CB59C196D762F5753F7F000000000014FC06CD002A03AAF2FFFF00
|
|
99
|
+
A000025.049 05FF6 1F11A FFF2DB4B69F8FFFF
|
|
100
|
+
A000025.066 05FF6 1FA03 FFDACD000F036E02
|
|
101
|
+
A000025.068 05FF7 1EF00 E59817000404677C7742E7F1E742D47103430000000000000000000000000000000000000000000000005F800340A2CFFA40A3A40141F950C74000000000
|
|
102
|
+
A000025.072 05FF2 1F802 FFFC78864500FFFF
|
|
103
|
+
A000025.072 05FF2 1F801 EC4D471754E569D2
|
|
104
|
+
A000025.144 05FF2 1F801 E14D471754E569D2
|
|
105
|
+
A000025.244 05FF2 1F801 D64D471754E569D2
|
|
106
|
+
A000025.294 05FF2 1F802 FFFC78864300FFFF
|
|
107
|
+
A000025.344 05FF2 1F801 CB4D471754E569D2
|
|
108
|
+
A000025.355 05FF7 1EF00 E59861060202FFFFFFFF03030000FFFFFFFFFFFFFFFFFFFF0000FFFFFF7FFFFFFF7FFFFFFF7F0000FF7F
|
|
109
|
+
A000025.360 05FF7 1EF00 E59812070202FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF7F
|
|
110
|
+
A000025.362 05FF3 1F904 FFFFFFFFFF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF7FFF7F
|
|
111
|
+
A000025.365 05FF3 1F903 FFF0FFFFFF7FFFFF
|
|
112
|
+
A000025.444 05FF2 1F801 C04D471754E569D2
|
|
113
|
+
A000025.544 05FF2 1F802 FFFC78864000FFFF
|
|
114
|
+
A000025.544 05FF2 1F801 B54D471754E569D2
|
|
115
|
+
A000025.644 05FF2 1F801 AA4D471754E569D2
|
|
116
|
+
A000025.700 05FF7 1EF00 E598E708000A0301030DDDB7C684051101
|
|
117
|
+
A000025.744 05FF2 1F801 A44D471755E569D2
|
|
118
|
+
A000025.794 05FF2 1F802 FFFC78863E00FFFF
|
|
119
|
+
A000025.844 05FF2 1F801 9E4D471755E569D2
|
|
120
|
+
A000025.944 05FF2 1F801 7A4D471756E569D2
|
|
121
|
+
A000026.044 05FF3 1F805 FFDB4B0B277922005557F01B826B05004210BF97D762F528937E000000000014FC06CD002A03AAF2FFFF00
|
|
122
|
+
A000026.049 05FF6 1F11A FFF2DB4B69F8FFFF
|
|
123
|
+
A000026.063 05FF6 1FA03 FFDACD000F036E02
|
|
124
|
+
A000026.068 05FF7 1EF00 E59817000404E2F8784290E3E84238090443000000000000000000000000000000000000000000000000CB76034014BDFA400E9B01419741C74000000000
|
|
125
|
+
A000026.073 05FF2 1F802 FFFC78864200FFFF
|
|
126
|
+
A000026.073 05FF2 1F801 734D471759E569D2
|
|
127
|
+
A000026.073 05FF7 1EF00 E5984719020206030101030F08FF0F00303CA31C011100190022904E2B9FA10C
|
|
128
|
+
A000026.078 05FF7 1EF00 E5984819020203030101030F08FF0F00303CA31C0113C8A90F
|
|
129
|
+
A000026.144 05FF2 1F801 6A4D47175BE569D2
|
|
130
|
+
A000026.244 05FF2 1F801 614D47175EE569D2
|
|
131
|
+
A000026.294 05FF2 1F802 FFFC78865300FFFF
|
|
132
|
+
A000026.344 05FF2 1F801 574D471760E569D2
|
|
133
|
+
A000026.355 05FF7 1EF00 E59861060202FFFFFFFF03030000FFFFFFFFFFFFFFFFFFFF0000FFFFFF7FFFFFFF7FFFFFFF7F0000FF7F
|
|
134
|
+
A000026.360 05FF7 1EF00 E59812070202FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF7F
|
|
135
|
+
A000026.362 05FF3 1F904 FFFFFFFFFF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF7FFF7F
|
|
136
|
+
A000026.365 05FF3 1F903 FFF0FFFFFF7FFFFF
|
|
137
|
+
A000026.387 05FF7 1EF00 E598E008020203090012E8071900
|
|
138
|
+
A000026.389 05FF7 1EF00 E598E008020203090112E8071900
|
|
139
|
+
A000026.391 05FF7 1EF00 E598E008020203090B11011900
|
|
140
|
+
A000026.392 05FF7 1EF00 E598E008020203090C12E8071900
|
|
141
|
+
A000026.444 05FF2 1F801 4C4D471763E569D2
|
|
142
|
+
A000026.544 05FF2 1F802 FFFCE6846100FFFF
|
|
143
|
+
A000026.544 05FF2 1F801 464D471763E569D2
|
|
144
|
+
A000026.644 05FF2 1F801 404D471762E569D2
|
|
145
|
+
A000026.700 05FF7 1EF00 E598E708000A0301030DDDB7C684051101
|
|
146
|
+
A000026.744 05FF2 1F801 394D471761E569D2
|
|
147
|
+
A000026.794 05FF2 1F802 FFFC38826B00FFFF
|
|
148
|
+
A000026.844 05FF2 1F801 324D471760E569D2
|
|
149
|
+
A000026.944 05FF2 1F801 2B4D471760E569D2
|
|
150
|
+
A000027.044 05FF3 1F805 FFDB4BF44D7922402890A309826B0580C6D36299D762F5B41E7E000000000014FC06CD002903AAF2FFFF00
|
|
151
|
+
A000027.048 05FF6 1F11A FFF2DB4B69F8FFFF
|
|
152
|
+
A000027.065 05FF6 1FA03 FFDACD000F036E02
|
|
153
|
+
A000027.065 05FF7 1EF00 E5981700040469777B42F0FAE942BFCF04430000000000000000000000000000000000000000000000002F6D034068AAFA406B9101411E32C74000000000
|
|
154
|
+
A000027.072 05FF2 1F802 FFFCC07E7800FFFF
|
|
155
|
+
A000027.072 05FF2 1F801 244D471760E569D2
|
|
156
|
+
A000027.144 05FF2 1F801 184D47175FE569D2
|
|
157
|
+
A000027.244 05FF2 1F801 0B4D47175FE569D2
|
|
158
|
+
A000027.294 05FF2 1F802 FFFC6F7C7D00FFFF
|
|
159
|
+
A000027.344 05FF2 1F801 FE4C47175EE569D2
|
|
160
|
+
A000027.355 05FF7 1EF00 E59861060202FFFFFFFF03030000FFFFFFFFFFFFFFFFFFFF0000FFFFFF7FFFFFFF7FFFFFFF7F0000FF7F
|
|
161
|
+
A000027.360 05FF7 1EF00 E59812070202FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF7F
|
|
162
|
+
A000027.362 05FF3 1F904 FFFFFFFFFF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF7FFF7F
|
|
163
|
+
A000027.366 05FF3 1F903 FFF0FFFFFF7FFFFF
|
|
164
|
+
A000027.444 05FF2 1F801 F34C47175FE569D2
|
|
165
|
+
A000027.544 05FF2 1F802 FFFC5E7A8000FFFF
|
|
166
|
+
A000027.544 05FF2 1F801 C34C47175FE569D2
|
|
167
|
+
A000027.642 05FF2 1F801 B64C471760E569D2
|
|
168
|
+
A000027.707 05FF7 1EF00 E598E708000A0301030DDDB7C684051101
|
|
169
|
+
A000027.744 05FF2 1F801 AA4C47175FE569D2
|
|
170
|
+
A000027.794 05FF2 1F802 FFFC177A8700FFFF
|
|
171
|
+
A000027.844 05FF2 1F801 A24C47175EE569D2
|
|
172
|
+
A000027.944 05FF2 1F801 874C47175FE569D2
|
|
173
|
+
A000028.041 05FF7 1EF00 E5984819020203030101030F08FF0F00303CA31C0113C9A90F
|
|
174
|
+
A000028.044 05FF3 1F805 FFDB4B0475792200D0CA4FE2816B0580641E6B99D762F5ACF17D000000000014FC06CD002903AAF2FFFF00
|
|
175
|
+
A000028.048 05FF6 1F11A FFF2DB4B69F8FFFF
|
|
176
|
+
A000028.068 05FF6 1FA03 FFDACD000F036E02
|
|
177
|
+
A000028.068 05FF7 1EF00 E598170004049E9A7E42D81AEB42C6AD05430000000000000000000000000000000000000000000000008A630340A097FA40B88701418E22C74000000000
|
|
178
|
+
A000028.074 05FF2 1F802 FFFC92798600FFFF
|
|
179
|
+
A000028.074 05FF2 1F801 7B4C471760E569D2
|
|
180
|
+
A000028.144 05FF2 1F801 764C471762E569D2
|
|
181
|
+
A000028.244 05FF2 1F801 714C471764E569D2
|
|
182
|
+
A000028.294 05FF2 1F802 FFFCFA768000FFFF
|
|
183
|
+
A000028.344 05FF2 1F801 5C4C47176BE569D2
|
|
184
|
+
A000028.355 05FF7 1EF00 E59861060202FFFFFFFF03030000FFFFFFFFFFFFFFFFFFFF0000FFFFFF7FFFFFFF7FFFFFFF7F0000FF7F
|
|
185
|
+
A000028.359 05FF7 1EF00 E59812070202FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF7F
|
|
186
|
+
A000028.362 05FF3 1F904 FFFFFFFFFF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF7FFF7F
|
|
187
|
+
A000028.367 05FF3 1F903 FFF0FFFFFF7FFFFF
|
|
188
|
+
A000028.386 05FF7 1EF00 E598E008020203090012E8071900
|
|
189
|
+
A000028.389 05FF7 1EF00 E598E008020203090112E8071900
|
|
190
|
+
A000028.391 05FF7 1EF00 E598E008020203090B11011900
|
|
191
|
+
A000028.392 05FF7 1EF00 E598E008020203090C12E8071900
|
|
192
|
+
A000028.444 05FF2 1F801 584C47176EE569D2
|
|
193
|
+
A000028.541 05FF7 1EF00 E5984719020206030101030F08FF0F00303CA31C011100190022904E2BA0A10C
|
|
194
|
+
A000028.544 05FF2 1F802 FFFC82737900FFFF
|
|
195
|
+
A000028.545 05FF2 1F801 4C4C471778E569D2
|
|
196
|
+
A000028.644 05FF2 1F801 464C471780E569D2
|
|
197
|
+
A000028.707 05FF7 1EF00 E598E708000A0301030DDDB7C684051101
|
|
198
|
+
A000028.744 05FF2 1F801 404C47177EE569D2
|
|
199
|
+
A000028.794 05FF2 1F802 FFFC146C6C00FFFF
|
|
200
|
+
A000028.844 05FF2 1F801 3C4C471780E569D2
|
|
201
|
+
A000028.944 05FF2 1F801 354C471787E569D2
|
|
202
|
+
A000029.044 05FF3 1F805 FFDB4B149C7922801525F6D0816B050017A601A3D762F5F8567D000000000014FC06CD002903AAF2FFFF00
|
|
203
|
+
A000029.048 05FF6 1F11A FFF2DB4B69F8FFFF
|
|
204
|
+
A000029.067 05FF6 1FA03 FFDACD000E036E02
|
|
205
|
+
A000029.068 05FF7 1EF00 E598170004045FD480425FF3EB424A6A0643000000000000000000000000000000000000000000000000D75A0340A886FA40F67E01417F14C74000000000
|
|
206
|
+
A000029.074 05FF2 1F802 FFFCCE696A00FFFF
|
|
207
|
+
A000029.074 05FF2 1F801 314C471789E569D2
|
|
208
|
+
A000029.144 05FF2 1F801 2C4C47178BE569D2
|
|
209
|
+
A000029.244 05FF2 1F801 254C471792E569D2
|
|
210
|
+
A000029.293 05FF2 1F802 FFFCE0646700FFFF
|
|
211
|
+
A000029.344 05FF2 1F801 294C47178CE569D2
|
|
212
|
+
A000029.355 05FF7 1EF00 E59861060202FFFFFFFF03030000FFFFFFFFFFFFFFFFFFFF0000FFFFFF7FFFFFFF7FFFFFFF7F0000FF7F
|
|
213
|
+
A000029.359 05FF7 1EF00 E59812070202FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF7F
|
|
214
|
+
A000029.362 05FF3 1F904 FFFFFFFFFF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF7FFF7F
|
|
215
|
+
A000029.362 05FF3 1F903 FFF0FFFFFF7FFFFF
|
|
216
|
+
A000029.444 05FF2 1F801 244C471790E569D2
|
|
217
|
+
A000029.544 05FF2 1F802 FFFCB0636800FFFF
|
|
218
|
+
A000029.544 05FF2 1F801 1B4C471796E569D2
|
|
219
|
+
A000029.644 05FF2 1F801 134C47179CE569D2
|
|
220
|
+
A000029.708 05FF7 1EF00 E598E708000A0301030DDDB7C684051101
|
|
221
|
+
A000029.744 05FF2 1F801 0A4C4717A3E569D2
|
|
222
|
+
A000029.792 05FF2 1F802 FFFC74656800FFFF
|
|
223
|
+
A000029.844 05FF2 1F801 004C4717A9E569D2
|
|
224
|
+
A000029.944 05FF2 1F801 F64B4717AEE569D2
|