@canboat/canboatjs 3.3.3 → 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 (73) 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 +2 -0
  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/package.json +3 -2
  27. package/tsconfig.tsbuildinfo +1 -1
  28. package/.github/workflows/publish.yml +0 -32
  29. package/.github/workflows/release_on_tag.yml +0 -27
  30. package/.github/workflows/require_pr_label.yml +0 -13
  31. package/.github/workflows/test.yml +0 -28
  32. package/.github/workflows/test_canboat_changes.yml +0 -92
  33. package/examples/signalk-device-emulator/index.js +0 -1
  34. package/examples/signalk-device-emulator/package.json +0 -24
  35. package/examples/simpleCan.js +0 -42
  36. package/ios.js +0 -67
  37. package/lib/actisense-serial.ts +0 -644
  38. package/lib/bin/actisense-file.ts +0 -53
  39. package/lib/bin/actisense-n2k-tcp.ts +0 -50
  40. package/lib/bin/actisense-serialjs.ts +0 -55
  41. package/lib/bin/analyzerjs.ts +0 -91
  42. package/lib/bin/candumpjs.ts +0 -100
  43. package/lib/bin/cansend.ts +0 -131
  44. package/lib/bin/ikonvert-serial.ts +0 -44
  45. package/lib/bin/to-pgn.ts +0 -65
  46. package/lib/bin/ydvr-file +0 -33
  47. package/lib/canId.test.js +0 -61
  48. package/lib/canId.ts +0 -84
  49. package/lib/canbus.ts +0 -293
  50. package/lib/candevice.ts +0 -41
  51. package/lib/codes.ts +0 -21
  52. package/lib/discovery.ts +0 -118
  53. package/lib/fromPgn.ts +0 -1217
  54. package/lib/fromPgnStream.ts +0 -54
  55. package/lib/ikonvert.ts +0 -250
  56. package/lib/index.ts +0 -48
  57. package/lib/n2k-actisense.test.js +0 -58
  58. package/lib/n2k-actisense.ts +0 -152
  59. package/lib/n2kDevice.ts +0 -509
  60. package/lib/pgns.test.ts +0 -12
  61. package/lib/pgns.ts +0 -191
  62. package/lib/simpleCan.ts +0 -140
  63. package/lib/stringMsg.test.js +0 -288
  64. package/lib/stringMsg.ts +0 -478
  65. package/lib/toPgn.ts +0 -601
  66. package/lib/utilities.test.js +0 -8
  67. package/lib/utilities.ts +0 -169
  68. package/lib/venus-mqtt.js +0 -118
  69. package/lib/venus.js +0 -88
  70. package/lib/w2k01.ts +0 -142
  71. package/lib/yddevice.ts +0 -48
  72. package/lib/ydgw02.ts +0 -197
  73. package/lib/ydvr.js +0 -138
package/lib/stringMsg.ts DELETED
@@ -1,478 +0,0 @@
1
- import {
2
- compact,
3
- cond,
4
- isEmpty,
5
- isString,
6
- negate,
7
- overSome,
8
- startsWith,
9
- stubTrue,
10
- toNumber,
11
- zipObject
12
- } from 'lodash/fp'
13
- import {
14
- arrBuff,
15
- byteString,
16
- getPlainPGNs,
17
- rmChecksum,
18
- trimWrap,
19
- compute0183Checksum,
20
- hexByte
21
- } from './utilities'
22
- import { buildCanId, encodeCanIdString, parseCanIdStr } from './canId'
23
- import moment from 'moment'
24
-
25
- /**
26
- * Helper function that helps merge canId fields with format, data, and others.
27
- * The idea here is to reflect what was in the source and not remove or add.
28
- * If the source has a len or timestamp attribute it should be added but not created.
29
- * @param {Object} canIdInfo The result of parseCanId, parseCanIdStr, or buildCanId.
30
- * @param {string} format String that defines the source format.
31
- * @param {Buffer} data Buffer array that contains the fields data.
32
- * @param {Object} [rest={}] Anything else to be added like len, timestamp, direction.
33
- * @return {Object} All canId fields with format and data props added.
34
- */
35
- function buildMsg(
36
- _canIdInfo: any,
37
- format: string,
38
- data: Buffer,
39
- rest: any = {}
40
- ) {
41
- const canIdInfo = Object.assign({}, _canIdInfo, {
42
- format,
43
- data
44
- })
45
- for (const property in rest) {
46
- if (canIdInfo[property] === undefined) {
47
- canIdInfo[property] = rest[property]
48
- }
49
- }
50
- return canIdInfo
51
- }
52
- function buildErrMsg(msg: string, input: string | undefined) {
53
- if (input !== undefined && input.length > 0) return `${msg} - ${input}`
54
- return msg
55
- }
56
- const buildErr = (
57
- format: string,
58
- msg: string,
59
- input: string | undefined = undefined
60
- ) => {
61
- return {
62
- error: new Error(buildErrMsg(msg, input)),
63
- format,
64
- input
65
- }
66
- }
67
-
68
- function toPaddedHexString(num: number, len: number) {
69
- const str = num.toString(16).toUpperCase()
70
- return '0'.repeat(len - str.length) + str
71
- }
72
-
73
- // 2016-02-28T19:57:02.364Z,2,127250,7,255,8,ff,10,3b,ff,7f,ce,f5,fc
74
- export const isActisense = (input: string) =>
75
- (input.charAt(10) === 'T' && input.charAt(23) === 'Z') ||
76
- (input.charAt(10) === '-' && input.charAt(23) === ',')
77
-
78
- export const parseActisense = (input: string) => {
79
- const [timestamp, prio, pgn, src, dst, len, ...data] = input.split(',')
80
- return buildMsg(
81
- buildCanId(prio, pgn, dst, src),
82
- 'Actisense',
83
- Buffer.from(data.join(''), 'hex'),
84
- { len: Number(len), timestamp }
85
- )
86
- }
87
- export const encodeActisense = ({
88
- pgn,
89
- data,
90
- timestamp,
91
- prio = 2,
92
- dst = 255,
93
- src = 0
94
- }: any) =>
95
- [
96
- timestamp || new Date().toISOString(),
97
- prio,
98
- pgn,
99
- src,
100
- dst,
101
- data.length,
102
- byteString(data)
103
- ].join(',')
104
-
105
- export const toActisenseSerialFormat = (
106
- pgn: any,
107
- data: any,
108
- dst = 255,
109
- src = 0,
110
- prio = 2
111
- ) =>
112
- exports.encodeActisense({
113
- pgn,
114
- data,
115
- dst,
116
- src,
117
- prio
118
- })
119
-
120
- // A764027.880 05FF7 1EF00 E59861060202FFFFFFFF03030000FFFFFFFFFFFFFFFFFFFF0000FFFFFF7FFFFFFF7FFFFFFF7F0000FF7F
121
- export const isActisenseN2KASCII = (input: string) =>
122
- input.charAt(0) === 'A' && input.charAt(7) === '.' && input.charAt(11) === ' '
123
- export const parseActisenseN2KASCII = (input: string) => {
124
- const [timestamp, srcdstp, pgn, data] = input.split(' ')
125
- const src = parseInt(srcdstp.substring(0, 2), 16)
126
- const dst = parseInt(srcdstp.substring(2, 4), 16)
127
- const prio = parseInt(srcdstp.substring(4))
128
- return buildMsg(
129
- buildCanId(prio, parseInt(pgn, 16), dst, src),
130
- 'Actisense N2K ASCII',
131
- Buffer.from(data, 'hex'),
132
- { len: data.length, time: timestamp.substring(1) }
133
- )
134
- }
135
- export const encodeActisenseN2KACSII = ({
136
- pgn,
137
- data,
138
- timestamp,
139
- prio = 2,
140
- dst = 255,
141
- src = 0
142
- }: any) => {
143
- timestamp = 'A000000.000'
144
-
145
- const srcdstp = hexByte(src) + hexByte(dst) + prio
146
- return [
147
- timestamp,
148
- srcdstp.toUpperCase(),
149
- toPaddedHexString(pgn, 5).toUpperCase(),
150
- byteString(data, '').toUpperCase()
151
- ].join(' ')
152
- }
153
-
154
- // 16:29:27.082 R 09F8017F 50 C3 B8 13 47 D8 2B C6
155
- export const isYDRAW = (input: string) => {
156
- if (input.charAt(2) !== ':') return false
157
- const direction = input.substr(12, 3)
158
- return direction === ' R ' || direction === ' T '
159
- }
160
- export const parseYDRAW = (input: string) => {
161
- const parts = input.split(' ')
162
- if (parts.length < 4) return buildErr('YDRAW', 'Invalid parts.', input)
163
- const [time, direction, canId, ...data] = parts // time format HH:mm:ss.SSS
164
- return buildMsg(parseCanIdStr(canId), 'YDRAW', arrBuff(data), {
165
- direction,
166
- time
167
- })
168
- }
169
-
170
- export const isYDRAWOut = (input: string) => {
171
- if (input.charAt(8) !== ' ') return false
172
- return true
173
- }
174
- export const parseYDRAWOut = (input: string) => {
175
- const parts = input.split(' ')
176
- if (parts.length < 4) return buildErr('YDRAW', 'Invalid parts.', input)
177
- const [canId, ...data] = parts // time format HH:mm:ss.SSS
178
- return buildMsg(parseCanIdStr(canId), 'YDRAW', arrBuff(data))
179
- }
180
- //19F51323 01 02<CR><LF>
181
- export const encodeYDRAW = ({ data, ...canIdInfo }: any) => {
182
- const canId = encodeCanIdString(canIdInfo)
183
- const pgns =
184
- data.length > 8 || canIdInfo.pgn == 126720 ? getPlainPGNs(data) : [data]
185
- return pgns.map((buffer) => canId + ' ' + byteString(buffer, ' '))
186
- }
187
-
188
- //16:29:27.082 R 19F51323 01 02<CR><LF>
189
- export const encodeYDRAWFull = ({ data, ...canIdInfo }: any) => {
190
- const canId = encodeCanIdString(canIdInfo)
191
- const pgns =
192
- data.length > 8 || canIdInfo.pgn == 126720 ? getPlainPGNs(data) : [data]
193
- return pgns.map(
194
- (buffer) =>
195
- moment().utc().format('hh:mm:ss.SSS') +
196
- ' R ' +
197
- canId +
198
- ' ' +
199
- byteString(buffer, ' ')
200
- )
201
- }
202
-
203
- const get0183Sentence = (msg: string) => {
204
- let sentence = msg
205
- if (sentence.charAt(0) === '\\') {
206
- const split = sentence.split('\\')
207
- if (split.length < 3) {
208
- return undefined
209
- }
210
- sentence = split[2]
211
- }
212
- return sentence
213
- }
214
-
215
- // $PCDIN,01F119,00000000,0F,2AAF00D1067414FF*59
216
- export const isPCDIN = (msg: string) => {
217
- const sentence = get0183Sentence(msg)
218
- return sentence ? sentence.startsWith('$PCDIN,') : false
219
- }
220
- export const parsePCDIN = (input: string) => {
221
- const sentence = get0183Sentence(input)
222
- if (sentence) {
223
- const [prefix, pgn, timeHex, src, data] = sentence.split(',')
224
- let timer = parseInt(timeHex, 32)
225
-
226
- timer = timer / 1024
227
- timer = timer + 1262304000 // starts epoch time from 1/1/2010
228
- timer = timer * 1000
229
-
230
- return buildMsg(
231
- buildCanId(0, parseInt(pgn, 16), 255, parseInt(src, 16)),
232
- 'PCDIN',
233
- Buffer.from(rmChecksum(data), 'hex'),
234
- { coalesced: true, prefix, timer, timestamp: new Date(timer) }
235
- )
236
- }
237
- }
238
-
239
- export const encodePCDIN = ({
240
- prefix = '$PCDIN',
241
- pgn,
242
- data,
243
- dst = 255
244
- }: any) => {
245
- const sentence = [
246
- prefix,
247
- toPaddedHexString(pgn, 6),
248
- '0000180C',
249
- hexByte(dst).toUpperCase(),
250
- byteString(data, '').toUpperCase()
251
- ].join(',')
252
- return sentence + compute0183Checksum(sentence)
253
- }
254
-
255
- const changeEndianness = (string: string) => {
256
- const result = []
257
- let len = string.length - 2
258
- while (len >= 0) {
259
- result.push(string.substr(len, 2))
260
- len -= 2
261
- }
262
- return result.join('')
263
- }
264
-
265
- // $MXPGN,01F801,2801,C1308AC40C5DE343*19
266
- export const isMXPGN = (msg: string) => {
267
- const sentence = get0183Sentence(msg)
268
- return sentence ? sentence.startsWith('$MXPGN,') : false
269
- }
270
- export const parseMXPGN = (
271
- input: string,
272
- options: any | undefined = undefined
273
- ) => {
274
- const sentence = get0183Sentence(input)
275
- if (sentence) {
276
- const [prefix, pgn, attr_word, data] = sentence.split(',')
277
-
278
- const send_prio_len = parseInt(attr_word.substr(0, 2), 16)
279
- .toString(2)
280
- .padStart(8, '0')
281
- const addr = parseInt(attr_word.substr(2, 2), 16)
282
- const send = parseInt(send_prio_len.substr(0, 1), 2)
283
- const prio = parseInt(send_prio_len.substr(1, 3), 2)
284
- //const len = parseInt(send_prio_len.substr(4,4), 2);
285
- let src = 0,
286
- dst = 255
287
-
288
- send ? (dst = addr) : (src = addr)
289
-
290
- let reversed
291
-
292
- if (options && options.littleEndianMXPGN)
293
- reversed = changeEndianness(rmChecksum(data))
294
- else reversed = data
295
-
296
- return buildMsg(
297
- buildCanId(prio, parseInt(pgn, 16), dst, src),
298
- 'MXPGN',
299
- Buffer.from(reversed, 'hex'),
300
- { coalesced: true, prefix }
301
- )
302
- }
303
- }
304
-
305
- export const encodeMXPGN = ({
306
- prefix = '$MXPGN',
307
- pgn,
308
- prio,
309
- src,
310
- data
311
- }: any) => {
312
- if (src > 255) src = 255
313
- if (!prio) prio = 3
314
- if (!src) src = 255
315
- const dataLength = hexByte(
316
- 128 + prio * 16 + byteString(data, '').toUpperCase().length / 2
317
- ).toUpperCase()
318
- const attribWord = dataLength + hexByte(src).toUpperCase()
319
-
320
- const buff = Buffer.from(byteString(data, ''), 'hex')
321
- for (let i = 0, j = buff.length - 1; i < j; ++i, --j) {
322
- const t = buff[j]
323
-
324
- buff[j] = buff[i]
325
- buff[i] = t
326
- }
327
-
328
- const sentence = [
329
- prefix,
330
- toPaddedHexString(pgn, 6),
331
- attribWord,
332
- buff.toString('hex').toUpperCase()
333
- ].join(',')
334
- return sentence + compute0183Checksum(sentence)
335
- }
336
-
337
- // iKonvert
338
- // !PDGY,126992,3,2,255,0.563,d2009e45b3b8821d
339
- export const isPDGY = startsWith('!PDGY,')
340
- export const parsePDGY = (input: string) => {
341
- const parts = input.split(',')
342
- if (parts.length === 7) {
343
- const [prefix, pgn, prio, src, dst, timer, data] = parts
344
- return buildMsg(
345
- buildCanId(prio, pgn, dst, src),
346
- 'PDGY',
347
- Buffer.from(data, 'base64'),
348
- { timer: Number(timer), prefix, coalesced: true }
349
- )
350
- } else if (parts.length === 4) {
351
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
352
- const [prefix, pgn, dst, data] = parts
353
- return buildMsg(
354
- buildCanId(0, pgn, dst, 0),
355
- 'PDGY',
356
- Buffer.from(data, 'base64'),
357
- { coalesced: true }
358
- )
359
- } else {
360
- return buildErr('iKonvert', 'Invalid parts.', input)
361
- }
362
- }
363
- export const encodePDGY = ({ prefix = '!PDGY', pgn, data, dst = 255 }: any) =>
364
- [prefix, pgn, dst, data.toString('base64')].join(',')
365
-
366
- export const isPDGYdebug = startsWith('$PDGY,')
367
- export const parsePDGYdebug = (input: string) => {
368
- const [prefix, pgn, ...fieldParts] = input.split(',')
369
- const fieldVals = fieldParts.map(toNumber)
370
- const fields = zipObject(
371
- ['busLoad', 'errors', 'deviceCount', 'timer', 'gatewaySrc', 'rejectedTX'],
372
- fieldVals
373
- )
374
- const src = fields.gatewaySrc
375
- return buildMsg(
376
- buildCanId(3, pgn, src, src),
377
- 'PDGYdebug',
378
- Buffer.from(fieldVals),
379
- { fields, prefix }
380
- )
381
- }
382
-
383
- // candump1 Angstrom
384
- // <0x18eeff01> [8] 05 a0 be 1c 00 a0 a0 c0
385
- export const isCandump1 = startsWith('<0x')
386
- export const parseCandump1 = (input: string) => {
387
- const [canId, len, ...data] = input.split(' ')
388
- return buildMsg(parseCanIdStr(trimWrap(canId)), 'candump1', arrBuff(data), {
389
- len: Number(trimWrap(len))
390
- })
391
- }
392
-
393
- // candump2 Debian
394
- // can0 09F8027F [8] 00 FC FF FF 00 00 FF FF
395
- export const isCandump2 = startsWith('can')
396
- export const parseCandump2 = (input: string) => {
397
- const [bus, canId, len, ...data] = compact(input.split(' '))
398
- return buildMsg(parseCanIdStr(canId), 'candump2', arrBuff(data), {
399
- bus,
400
- len: Number(trimWrap(len))
401
- })
402
- }
403
-
404
- // candump3 log
405
- // (1502979132.106111) slcan0 09F50374#000A00FFFF00FFFF
406
- export const isCandump3 = startsWith('(')
407
- export const parseCandump3 = (input: string) => {
408
- const [timestamp, bus, canFrame] = input.split(' ')
409
- const [canId, data] = canFrame.split('#')
410
- return buildMsg(parseCanIdStr(canId), 'candump3', Buffer.from(data, 'hex'), {
411
- timestamp,
412
- bus
413
- })
414
- }
415
-
416
- const hasErr = overSome([negate(isString), isEmpty])
417
- export const parseN2kString = (str: string, options: any): any => {
418
- if (hasErr(str)) {
419
- return buildErr('INVALID', 'Input not string or empty.', str)
420
- }
421
- if (isActisense(str)) {
422
- return parseActisense(str)
423
- }
424
- if (isYDRAW(str)) {
425
- return parseYDRAW(str)
426
- }
427
- if (isYDRAWOut(str)) {
428
- return parseYDRAWOut(str)
429
- }
430
- if (isPCDIN(str)) {
431
- return parsePCDIN(str)
432
- }
433
- if (isMXPGN(str)) {
434
- return parseMXPGN(str, options)
435
- }
436
- if (isPDGY(str)) {
437
- return parsePDGY(str)
438
- }
439
- if (isCandump1(str)) {
440
- return parseCandump1(str)
441
- }
442
- if (isCandump2(str)) {
443
- return parseCandump2(str)
444
- }
445
- if (isCandump3(str)) {
446
- return parseCandump3(str)
447
- }
448
- if (isPDGYdebug(str)) {
449
- return parsePDGYdebug(str)
450
- }
451
- if (isActisenseN2KASCII(str)) {
452
- return parseActisenseN2KASCII(str)
453
- }
454
- return buildErr('MISSING_PARSER', 'Parser not found for input.', str)
455
- }
456
-
457
- export const isN2KString = cond([
458
- [hasErr, () => false],
459
- [isActisense, () => true],
460
- [isYDRAW, () => true],
461
- [isPCDIN, () => true],
462
- [isMXPGN, () => true],
463
- [isPDGY, () => true],
464
- [isCandump1, () => true],
465
- [isCandump2, () => true],
466
- [isCandump3, () => true],
467
- [isPDGYdebug, () => true],
468
- [isActisenseN2KASCII, () => true],
469
- [stubTrue, () => false]
470
- ])
471
-
472
- export const isN2KOver0183 = (msg: string) => {
473
- return isPCDIN(msg) || isMXPGN(msg)
474
- }
475
-
476
- export const parseN2KOver0183 = (msg: string) => {
477
- return parsePCDIN(msg) || parseMXPGN(msg)
478
- }