@canboat/canboatjs 3.3.2 → 3.3.4

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.
Files changed (79) hide show
  1. package/dist/bin/actisense-file.js +2 -0
  2. package/dist/bin/actisense-file.js.map +1 -1
  3. package/dist/bin/actisense-n2k-tcp.js +2 -0
  4. package/dist/bin/actisense-n2k-tcp.js.map +1 -1
  5. package/dist/bin/actisense-serialjs.js +2 -0
  6. package/dist/bin/actisense-serialjs.js.map +1 -1
  7. package/dist/bin/analyzerjs.js +35 -8
  8. package/dist/bin/analyzerjs.js.map +1 -1
  9. package/dist/bin/candumpjs.js +7 -4
  10. package/dist/bin/candumpjs.js.map +1 -1
  11. package/dist/bin/cansend.js +2 -0
  12. package/dist/bin/cansend.js.map +1 -1
  13. package/dist/bin/to-pgn.js +2 -0
  14. package/dist/bin/to-pgn.js.map +1 -1
  15. package/dist/bin/utils.d.ts +4 -0
  16. package/dist/bin/utils.d.ts.map +1 -0
  17. package/dist/bin/utils.js +15 -0
  18. package/dist/bin/utils.js.map +1 -0
  19. package/dist/bin/ydvr-file.d.ts +3 -0
  20. package/dist/bin/ydvr-file.d.ts.map +1 -0
  21. package/dist/bin/ydvr-file.js +31 -0
  22. package/dist/bin/ydvr-file.js.map +1 -0
  23. package/dist/fromPgn.d.ts.map +1 -1
  24. package/dist/fromPgn.js +1 -0
  25. package/dist/fromPgn.js.map +1 -1
  26. package/dist/stringMsg.d.ts +2 -0
  27. package/dist/stringMsg.d.ts.map +1 -1
  28. package/dist/stringMsg.js +18 -1
  29. package/dist/stringMsg.js.map +1 -1
  30. package/dist/stringMsg.test.js +15 -1
  31. package/dist/stringMsg.test.js.map +1 -1
  32. package/package.json +3 -2
  33. package/tsconfig.tsbuildinfo +1 -1
  34. package/.github/workflows/publish.yml +0 -32
  35. package/.github/workflows/release_on_tag.yml +0 -27
  36. package/.github/workflows/require_pr_label.yml +0 -13
  37. package/.github/workflows/test.yml +0 -28
  38. package/.github/workflows/test_canboat_changes.yml +0 -92
  39. package/examples/signalk-device-emulator/index.js +0 -1
  40. package/examples/signalk-device-emulator/package.json +0 -24
  41. package/examples/simpleCan.js +0 -42
  42. package/ios.js +0 -67
  43. package/lib/actisense-serial.ts +0 -644
  44. package/lib/bin/actisense-file.ts +0 -53
  45. package/lib/bin/actisense-n2k-tcp.ts +0 -50
  46. package/lib/bin/actisense-serialjs.ts +0 -55
  47. package/lib/bin/analyzerjs.ts +0 -66
  48. package/lib/bin/candumpjs.ts +0 -100
  49. package/lib/bin/cansend.ts +0 -131
  50. package/lib/bin/ikonvert-serial.ts +0 -44
  51. package/lib/bin/to-pgn.ts +0 -65
  52. package/lib/bin/ydvr-file +0 -33
  53. package/lib/canId.test.js +0 -61
  54. package/lib/canId.ts +0 -84
  55. package/lib/canbus.ts +0 -293
  56. package/lib/candevice.ts +0 -41
  57. package/lib/codes.ts +0 -21
  58. package/lib/discovery.ts +0 -118
  59. package/lib/fromPgn.ts +0 -1217
  60. package/lib/fromPgnStream.ts +0 -54
  61. package/lib/ikonvert.ts +0 -250
  62. package/lib/index.ts +0 -48
  63. package/lib/n2k-actisense.test.js +0 -58
  64. package/lib/n2k-actisense.ts +0 -152
  65. package/lib/n2kDevice.ts +0 -509
  66. package/lib/pgns.test.ts +0 -12
  67. package/lib/pgns.ts +0 -191
  68. package/lib/simpleCan.ts +0 -140
  69. package/lib/stringMsg.test.js +0 -273
  70. package/lib/stringMsg.ts +0 -464
  71. package/lib/toPgn.ts +0 -601
  72. package/lib/utilities.test.js +0 -8
  73. package/lib/utilities.ts +0 -169
  74. package/lib/venus-mqtt.js +0 -118
  75. package/lib/venus.js +0 -88
  76. package/lib/w2k01.ts +0 -142
  77. package/lib/yddevice.ts +0 -48
  78. package/lib/ydgw02.ts +0 -197
  79. package/lib/ydvr.js +0 -138
@@ -1,50 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { createDebug } from '../utilities'
4
- import net from 'net'
5
- import { readN2KActisense } from '../n2k-actisense'
6
- import minimist from 'minimist'
7
-
8
- const debug = createDebug('canboatjs:w2k01')
9
-
10
- const argv = minimist(process.argv.slice(2), {
11
- alias: { h: 'help' }
12
- })
13
-
14
- function help() {
15
- console.error(`Usage: ${process.argv[0]} [options] host port
16
-
17
- Options:
18
- -h, --help output usage information`)
19
- process.exit(1)
20
- }
21
-
22
- if (argv['help']) {
23
- help()
24
- }
25
-
26
- if (argv['_'].length < 2) {
27
- console.error('Please specify a host and port')
28
- help()
29
- }
30
-
31
- const client = new net.Socket()
32
- client.connect(Number(argv['_'][1]), argv['_'][0], function () {
33
- debug('Connected')
34
- })
35
-
36
- const context = {}
37
- client.on('data', function (data) {
38
- readN2KActisense(data, true, context, (result) => {
39
- console.log(result)
40
- })
41
- })
42
-
43
- client.on('close', function () {
44
- debug('Connection closed')
45
- })
46
-
47
- process.on('SIGINT', () => {
48
- debug('SIGINT signal received.')
49
- client.destroy()
50
- })
@@ -1,55 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { EventEmitter } from 'node:events'
4
- import minimist from 'minimist'
5
- import readline from 'readline'
6
- import { serial } from '../index'
7
- import { Transform } from 'stream'
8
-
9
- const argv = minimist(process.argv.slice(2), {
10
- boolean: ['disable-output'],
11
- alias: { h: 'help' }
12
- })
13
-
14
- if (argv['help']) {
15
- console.error(`Usage: ${process.argv[0]} [options] device_path
16
-
17
- Options:
18
- --disable-output don't output pgns
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
- const app = new EventEmitter()
29
-
30
- const actisense = new (serial as any)({
31
- app: app,
32
- device: argv['_'][0],
33
- plainText: true,
34
- disableSetTransmitPGNs: true,
35
- outputOnly: argv['disable-output']
36
- })
37
- const toStringTr = new Transform({
38
- objectMode: true,
39
-
40
- transform(chunk: any, encoding: string, callback: any) {
41
- this.push(chunk + '\n')
42
- callback()
43
- }
44
- })
45
-
46
- const rl = readline.createInterface({
47
- input: process.stdin,
48
- terminal: false
49
- })
50
-
51
- rl.on('line', (line) => {
52
- app.emit('nmea2000out', line)
53
- })
54
-
55
- actisense.pipe(toStringTr).pipe(process.stdout)
@@ -1,66 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { PGN } from '@canboat/ts-pgns'
4
- import { Parser } from '../fromPgn'
5
- import minimist from 'minimist'
6
- import readline from 'readline'
7
-
8
- const argv = minimist(process.argv.slice(2), {
9
- alias: { h: 'help' },
10
- boolean: ['n', 'r', 'camel', 'camel-compat', 'show-non-matches']
11
- })
12
-
13
- if (argv['help']) {
14
- console.error(`Usage: ${process.argv[1]} [options]
15
-
16
- Options:
17
- -c don't check for invalid values
18
- -n output null values
19
- -r parse $MXPGN as little endian
20
- --camel output field names in camelCase
21
- --camel-compat output field names in camelCase and regular
22
- --show-non-matches show pgn data without any matches
23
- -h, --help output usage information`)
24
- process.exit(1)
25
- }
26
-
27
- const parser = new Parser({
28
- returnNulls: argv['n'] === true,
29
- littleEndianMXPGN: argv['r'] === true,
30
- checkForInvalidFields: argv['c'] !== true,
31
- useCamel: argv['camel'],
32
- useCamelCompat: argv['camel-compat'],
33
- returnNonMatches: argv['show-non-matches']
34
- })
35
-
36
- parser.on('error', (pgn: PGN, error: any) => {
37
- console.error(`Error parsing ${pgn.pgn} ${error}`)
38
- console.error(error.stack)
39
- })
40
-
41
- parser.on('warning', (_pgn: PGN, _error: any) => {
42
- //console.error(`Warning parsing ${pgn.pgn} ${error}`)
43
- })
44
-
45
- parser.on('pgn', (pgn: PGN) => {
46
- console.log(JSON.stringify(pgn))
47
- })
48
-
49
- const rl = readline.createInterface({
50
- input: process.stdin,
51
- output: process.stdout,
52
- terminal: false
53
- })
54
-
55
- rl.on('line', (line: string) => {
56
- if (argv['log-input']) {
57
- console.log(line)
58
- }
59
- if (line.length > 13 && line.charAt(13) === ';') {
60
- if (line.charAt(14) === 'A') {
61
- parser.parseString(line.substring(16))
62
- }
63
- } else {
64
- parser.parseString(line.trim())
65
- }
66
- })
@@ -1,100 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { FromPgn } from '../index'
4
- import { parseCanId } from '../canId'
5
- import minimist from 'minimist'
6
- import { binToActisense } from '../utilities'
7
-
8
- // eslint-disable-next-line @typescript-eslint/no-require-imports
9
- const socketcan = require('socketcan')
10
-
11
- const argv = minimist(process.argv.slice(2), {
12
- alias: {
13
- h: 'help',
14
- boolean: ['n', 'r', 'camel', 'camel-compat', 'show-non-matches']
15
- }
16
- })
17
-
18
- if (argv['help']) {
19
- console.error(`Usage: ${process.argv[0]} [options] candevice
20
-
21
- Options:
22
- --format <format> json, actisense
23
- -c don't check for invalid values
24
- -n output null values
25
- -r parse $MXPGN as little endian
26
- --camel output field names in camelCase
27
- --camel-compat output field names in camelCase and regular
28
- --show-non-matches show pgn data without any matches
29
- -h, --help output usage information`)
30
- process.exit(1)
31
- }
32
-
33
- if (argv['_'].length === 0) {
34
- console.error('Please specify a device')
35
- process.exit(1)
36
- }
37
-
38
- const parser = new FromPgn({
39
- returnNulls: argv['n'] === true,
40
- littleEndianMXPGN: argv['r'] === true,
41
- checkForInvalidFields: argv['c'] !== true,
42
- useCamel: argv['camel'],
43
- useCamelCompat: argv['camel-compat'],
44
- returnNonMatches: argv['show-non-matches']
45
- })
46
-
47
- const format = argv['format'] || 'json'
48
-
49
- /*
50
-
51
- let messageCb = (data) => {
52
- let jsonData = parser.parse(data, (err) => { if ( err ) console.error(err) })
53
- if ( jsonData ) {
54
- console.log(data)
55
- }
56
- }
57
-
58
- let simpleCan = new canboatjs.SimpleCan({
59
- canDevice: argv['_'][0],
60
- preferredAddress: 35,
61
- disableDefaultTransmitPGNs: true,
62
- transmitPGNs: [],
63
- }, messageCb)
64
-
65
- simpleCan.start()
66
-
67
- */
68
-
69
- parser.on('error', (pgn, error) => {
70
- console.error(`Error parsing ${pgn.pgn} ${error}`)
71
- console.error(error.stack)
72
- })
73
-
74
- parser.on('pgn', (pgn) => {
75
- console.log(JSON.stringify(pgn))
76
- })
77
-
78
- const canDevice = argv['_'][0]
79
-
80
- const channel = socketcan.createRawChannel(canDevice)
81
-
82
- channel.addListener('onStopped', (msg: any) => {
83
- console.error(`socketcan stopped ${msg}`)
84
- })
85
-
86
- channel.addListener('onMessage', (msg: any) => {
87
- const pgn = parseCanId(msg.id)
88
-
89
- const timestamp = new Date().toISOString()
90
-
91
- const sourceString = binToActisense(pgn, timestamp, msg.data, msg.data.length)
92
-
93
- if (format === 'json') {
94
- parser.parse({ pgn, length: msg.data.length, data: msg.data, sourceString })
95
- } else {
96
- console.log(sourceString)
97
- }
98
- })
99
-
100
- channel.start()
@@ -1,131 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { parseActisense } from '../stringMsg'
4
- import { toPgn } from '../toPgn'
5
- import { getPlainPGNs, binToActisense } from '../utilities'
6
- import { encodeCanId } from '../canId'
7
- import readline from 'readline'
8
- import minimist from 'minimist'
9
-
10
- const argv = minimist(process.argv.slice(2), {
11
- boolean: ['test', 'log-output'],
12
- string: ['src'],
13
- alias: { h: 'help' }
14
- })
15
-
16
- if (argv['help']) {
17
- console.error(`Usage: ${process.argv[0]} [options] candevice
18
-
19
- Options:
20
- --src <src> use src for all messages
21
- --log-output log messages sent
22
- --test don't connect or send any data
23
- -h, --help output usage information`)
24
- process.exit(1)
25
- }
26
-
27
- if (argv['_'].length === 0) {
28
- console.error('Please specify a device')
29
- process.exit(1)
30
- }
31
-
32
- const canDevice = argv['_'][0]
33
- const srcArg = argv.src
34
- const logOut = argv['log-output']
35
- const test = argv.test
36
-
37
- let channel: any
38
-
39
- if (!test) {
40
- // eslint-disable-next-line @typescript-eslint/no-require-imports
41
- const socketcan = require('socketcan')
42
- channel = socketcan.createRawChannel(canDevice)
43
-
44
- channel.addListener('onStopped', (msg: any) => {
45
- console.error(`socketcan stopped ${msg}`)
46
- })
47
-
48
- channel.start()
49
- }
50
-
51
- const rl = readline.createInterface({
52
- input: process.stdin,
53
- output: process.stdout,
54
- terminal: false
55
- })
56
-
57
- rl.on('line', function (line) {
58
- if (line.length === 0) {
59
- return
60
- }
61
-
62
- let msg = line[0] === '{' ? JSON.parse(line) : line
63
-
64
- if (typeof msg === 'string') {
65
- const split = msg.split(',')
66
- if (srcArg !== undefined) {
67
- split[3] = srcArg
68
- }
69
- msg = split.join(',')
70
- } else {
71
- if (msg.prio === undefined) {
72
- msg.prio = 3
73
- }
74
- if (msg.dst === undefined) {
75
- msg.dst = 255
76
- }
77
- if (srcArg !== undefined) {
78
- msg.src = srcArg
79
- }
80
- if (msg.src === undefined) {
81
- msg.src = 100
82
- }
83
- }
84
-
85
- let pgn: any, canid: number, buffer: Buffer | undefined
86
- if (typeof msg === 'object') {
87
- canid = encodeCanId(msg)
88
- buffer = toPgn(msg)
89
- if (buffer === undefined) {
90
- console.error('invalid input: %s', line)
91
- return
92
- }
93
- pgn = msg
94
- } else {
95
- pgn = parseActisense(msg)
96
-
97
- if (isNaN(pgn.prio) || isNaN(pgn.pgn) || isNaN(pgn.dst) || isNaN(pgn.src)) {
98
- console.error('invalid input: ' + line)
99
- return
100
- }
101
-
102
- canid = encodeCanId(pgn)
103
- buffer = pgn.data
104
- }
105
-
106
- const timestamp = new Date().toISOString()
107
-
108
- if (buffer == undefined) {
109
- console.error('unable to encode: %s', line)
110
- return
111
- } else {
112
- if (buffer.length > 8 || pgn.pgn == 126720) {
113
- const pgns = getPlainPGNs(buffer)
114
- pgns.forEach((pbuffer) => {
115
- if (!test) {
116
- channel.send({ id: canid, ext: true, data: pbuffer })
117
- }
118
- if (logOut) {
119
- console.log(binToActisense(pgn, timestamp, pbuffer, pbuffer.length))
120
- }
121
- })
122
- } else {
123
- if (!test) {
124
- channel.send({ id: canid, ext: true, data: buffer })
125
- }
126
- if (logOut) {
127
- console.log(binToActisense(pgn, timestamp, buffer, buffer.length))
128
- }
129
- }
130
- }
131
- })
@@ -1,44 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { Transform } from 'stream'
4
- // eslint-disable-next-line @typescript-eslint/no-require-imports
5
- const { SerialPort } = require('serialport')
6
-
7
- if (process.argv.length < 3) {
8
- console.error('Please specify a device')
9
- console.error('usage: ikonvert-serial [device] [baud,default:230400]')
10
- process.exit(1)
11
- }
12
-
13
- const device = process.argv[2]
14
-
15
- const baud = process.argv.length > 3 ? Number(process.argv[3]) : 230400
16
-
17
- const serial = new SerialPort({
18
- path: device,
19
- baudRate: baud
20
- })
21
-
22
- const toStringTr = new Transform({
23
- objectMode: true,
24
-
25
- transform(line, encoding, callback) {
26
- //this.push(JSON.stringify(chunk) + "\n");
27
- console.log(line)
28
-
29
- if (line.startsWith('$PDGY,000000,,,,,')) {
30
- serial.write('$PDGY,N2NET_INIT,ALL\r\n')
31
- }
32
-
33
- callback()
34
- }
35
- })
36
-
37
- serial.on('open', function () {
38
- const parser = new SerialPort.parsers.Readline()
39
- serial.pipe(parser).pipe(toStringTr)
40
- })
41
-
42
- serial.on('error', (x: any) => {
43
- console.log(x)
44
- })
package/lib/bin/to-pgn.ts DELETED
@@ -1,65 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import minimist from 'minimist'
4
- import readline from 'readline'
5
- import {
6
- pgnToActisenseSerialFormat,
7
- pgnToActisenseN2KAsciiFormat,
8
- pgnToiKonvertSerialFormat,
9
- pgnToYdgwRawFormat,
10
- pgnToYdgwFullRawFormat,
11
- pgnToPCDIN,
12
- pgnToMXPGN
13
- } from '../index'
14
-
15
- const argv = minimist(process.argv.slice(2), {
16
- string: ['format'],
17
- alias: { h: 'help' }
18
- })
19
-
20
- if (argv['help']) {
21
- console.error(`Usage: ${process.argv[0]} [options]
22
-
23
- Options:
24
- --format <format> actisense, actisensen2kascii, ikconvert, ydgw, yd-full, pcdin, mxpgn
25
- -h, --help output usage information`)
26
- process.exit(1)
27
- }
28
-
29
- const formatters: { [key: string]: any } = {
30
- actisense: pgnToActisenseSerialFormat,
31
- n2kascii: pgnToActisenseN2KAsciiFormat,
32
- ikconvert: pgnToiKonvertSerialFormat,
33
- ydgw: pgnToYdgwRawFormat,
34
- pcdin: pgnToPCDIN,
35
- mxpgn: pgnToMXPGN,
36
- 'yd-full': pgnToYdgwFullRawFormat
37
- }
38
-
39
- const format = argv['format'] || 'actisense'
40
- const formatter = formatters[format]
41
- if (!formatter) {
42
- console.error(`unknown format: ${argv['format']}`)
43
- process.exit(1)
44
- }
45
-
46
- const rl = readline.createInterface({
47
- input: process.stdin,
48
- output: process.stdout,
49
- terminal: false
50
- })
51
-
52
- rl.on('line', function (line) {
53
- const msg = JSON.parse(line)
54
- const res = formatter(msg)
55
- if (Array.isArray(res)) {
56
- res.forEach((m) => {
57
- console.log(m)
58
- })
59
- } else {
60
- console.log(res)
61
- }
62
- //console.log(pgnToActisenseSerialFormat(msg))
63
- //console.log(pgnToiKonvertSerialFormat(pgn))
64
- //console.log(pgnToYdgwRawFormat(msg))
65
- })
package/lib/bin/ydvr-file DELETED
@@ -1,33 +0,0 @@
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
- })
package/lib/canId.test.js DELETED
@@ -1,61 +0,0 @@
1
- const { encodeCanId, parseCanId, parseEncode } = require('./canId')
2
-
3
- /* globals describe test expect */
4
-
5
- describe('parseCanId', () => {
6
- test('Return object with canId broken into properties', () => {
7
- expect(parseCanId(0x18eeff01)).toEqual({
8
- canId: 0x18eeff01,
9
- dst: 255,
10
- src: 1,
11
- pgn: 60928,
12
- prio: 6
13
- })
14
- expect(parseCanId(0xcf004ee)).toEqual({
15
- canId: 0xcf004ee,
16
- dst: 255,
17
- src: 0xee,
18
- pgn: 0xf004,
19
- prio: 0xc >> 2
20
- })
21
- expect(parseCanId(0x18ea2301)).toEqual({
22
- canId: 0x18ea2301,
23
- dst: 35,
24
- src: 0x01,
25
- pgn: 0xea00,
26
- prio: 6
27
- })
28
- expect(parseCanId(0x09f8017f)).toEqual({
29
- canId: 0x09f8017f,
30
- dst: 255,
31
- src: 127,
32
- pgn: 129025,
33
- prio: 2
34
- })
35
- expect(parseCanId(0x0df8057f)).toEqual({
36
- canId: 0x0df8057f,
37
- dst: 255,
38
- src: 127,
39
- pgn: 129029,
40
- prio: 3
41
- })
42
- })
43
- })
44
- describe('encodeCanId', () => {
45
- test('Return canId number from object', () => {
46
- expect(
47
- encodeCanId({ src: 1, pgn: 60928, prio: 6, dst: 255 }).toString(2)
48
- ).toBe((0x18eeff01).toString(2))
49
- expect(encodeCanId({ src: 238, pgn: 61444, prio: 3 })).toBe(0xcf004ee)
50
- })
51
- })
52
-
53
- describe('parseEncode', () => {
54
- test('Return exactly same number after parse and encode', () => {
55
- expect(parseEncode(0x18eeff01)).toBe(0x18eeff01)
56
- expect(parseEncode(0xcf004ee)).toBe(0xcf004ee)
57
- expect(parseEncode(0x18ea2301)).toBe(0x18ea2301)
58
- expect(parseEncode(0x09f8017f)).toBe(0x09f8017f)
59
- expect(parseEncode(0x0df8057f)).toBe(0x0df8057f)
60
- })
61
- })
package/lib/canId.ts DELETED
@@ -1,84 +0,0 @@
1
- import { flow } from 'lodash/fp'
2
-
3
- export type ParsedCanID = {
4
- canId: number
5
- prio: number
6
- src: number
7
- pgn: number
8
- dst: number
9
- }
10
-
11
- export type CanID = {
12
- prio: number
13
- src: number
14
- pgn: number
15
- dst: number
16
- }
17
-
18
- // Decode CAN Identifier (canId). ISO 11783 (CAN 2.0 B Extended Frame Format)
19
- export const parseCanId = (id: number): ParsedCanID => {
20
- const PF = (id >> 16) & 0xff // PDU Format
21
- const PS = (id >> 8) & 0xff // PDU Specific
22
- const DP = (id >> 24) & 1 // Data Page
23
-
24
- let dst: number, pgn: number
25
-
26
- if (PF < 240) {
27
- /* PDU1 format, the PS contains the destination address */
28
- dst = PS
29
- pgn = (DP << 16) + (PF << 8)
30
- } else {
31
- /* PDU2 format, the destination is implied global and the PGN is extended */
32
- dst = 0xff
33
- pgn = (DP << 16) + (PF << 8) + PS
34
- }
35
- return {
36
- canId: id, // Include original canId in return object.
37
- prio: (id >> 26) & 0x7, // Priority
38
- src: id & 0xff, // Source Address (SA),
39
- pgn,
40
- dst
41
- }
42
- }
43
- // canId should be a hex encoded string without spaces or commas.
44
- export const parseCanIdStr = (canId: string) => parseCanId(parseInt(canId, 16))
45
-
46
- export const buildCanId = (
47
- prio: string | number,
48
- pgn: string | number,
49
- dst: string | number,
50
- src: string | number
51
- ): CanID => ({
52
- prio: Number(prio),
53
- pgn: Number(pgn),
54
- dst: Number(dst),
55
- src: Number(src)
56
- })
57
-
58
- // Encode CAN Identifier (canId)
59
- export const encodeCanId = (id: CanID) => {
60
- let canId = id.src & 0xff
61
-
62
- //I can't get this to work, but things seem ok??
63
- //let canId = ((src & 0xff) | 0x80000000)) // src bits are the lowest ones of the CAN ID. Also set the highest bit to 1 as n2k uses
64
- // only extended frames (EFF bit).
65
-
66
- const PF = (id.pgn >> 8) & 0xff
67
-
68
- if (PF < 240) {
69
- // PDU 1
70
- canId = canId | ((id.dst & 0xff) << 8)
71
- canId = canId | (id.pgn << 8)
72
- } else {
73
- // PDU 2
74
- canId = canId | (id.pgn << 8)
75
- }
76
- canId = canId | (id.prio << 26)
77
-
78
- return canId
79
- }
80
- export const canIdString = (canId: number) =>
81
- canId.toString(16).padStart(8, '0')
82
- export const encodeCanIdString = flow(encodeCanId, canIdString)
83
- // Utility function that parses and re-encodes. Compare result to original.
84
- export const parseEncode = (x: number) => encodeCanId(parseCanId(x))