@canboat/canboatjs 1.21.0 → 1.22.1

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 CHANGED
@@ -205,9 +205,9 @@ Output: `!PDGY,127245,255,/Pj/f/9///8=`
205
205
  ## Generate YDGW-02 format from canboat json
206
206
 
207
207
  ```js
208
- const pgnToYdwgRawFormat = require("./index").pgnToYdwgRawFormat;
208
+ const pgnToYdgwRawFormat = require("./index").pgnToYdgwRawFormat;
209
209
 
210
- const array = pgnToYdwgRawFormat({
210
+ const array = pgnToYdgwRawFormat({
211
211
  src: 127,
212
212
  prio: 3,
213
213
  dst: 255,
package/lib/canbus.js CHANGED
@@ -120,7 +120,7 @@ function CanbusStream (options) {
120
120
  })
121
121
  } else {
122
122
  try {
123
- this.channel = socketcan.createRawChannel(canDevice);
123
+ this.channel = socketcan.createRawChannelWithOptions(canDevice, { non_block_send: true} );
124
124
  this.channel.addListener('onMessage', (msg) => {
125
125
  var pgn = parseCanId(msg.id)
126
126
 
package/lib/candevice.js CHANGED
@@ -177,7 +177,7 @@ function handleGroupFunction(device, n2kMsg) {
177
177
  const acknowledgement = {
178
178
  pgn: 126208,
179
179
  dst: n2kMsg.src,
180
- "Function Code": 1,
180
+ "Function Code": 2,
181
181
  "PGN": n2kMsg.fields.PGN,
182
182
  "PGN error code": 4,
183
183
  "Transmission interval/Priority error code": 0,
@@ -195,7 +195,7 @@ function handleGroupFunction(device, n2kMsg) {
195
195
  const acknowledgement = {
196
196
  pgn: 126208,
197
197
  dst: n2kMsg.src,
198
- "Function Code": 1,
198
+ "Function Code": 2,
199
199
  "PGN": n2kMsg.fields.PGN,
200
200
  "PGN error code": 4,
201
201
  "Transmission interval/Priority error code": 0,
package/lib/codes.test.js CHANGED
@@ -4,6 +4,7 @@ describe('getManufacturerCode', () => {
4
4
  test('Return mfg number from name string', () => {
5
5
  expect(getManufacturerCode('Furuno')).toBe(1855)
6
6
  expect(getManufacturerCode('Yacht Devices')).toBe(717)
7
+ expect(getManufacturerCode('TJC Micro')).toBe(963)
7
8
  })
8
9
  })
9
10
 
@@ -11,5 +12,6 @@ describe('getManufacturerName', () => {
11
12
  test('Return name string from mfg number', () => {
12
13
  expect(getManufacturerName(1855)).toBe('Furuno')
13
14
  expect(getManufacturerName(717)).toBe('Yacht Devices')
15
+ expect(getManufacturerName(963)).toBe('TJC Micro')
14
16
  })
15
17
  })
@@ -136,6 +136,7 @@
136
136
  "Teleflex Marine (SeaStar Solutions)": 1850,
137
137
  "Thrane and Thrane": 351,
138
138
  "Tides Marine": 797,
139
+ "TJC Micro": 963,
139
140
  "Tohatsu Co, JP": 431,
140
141
  "Transas USA": 518,
141
142
  "Trimble": 1856,
package/lib/fromPgn.js CHANGED
@@ -39,7 +39,7 @@ const maxUint64 = new Int64LE(0xffffffff, 0xffffffff)
39
39
  const maxInt64 = new Int64LE(0x7fffffff, 0xffffffff)
40
40
 
41
41
  const FORMAT_PLAIN = 0
42
- const FORMAT_FAST = 1
42
+ const FORMAT_COALESCED = 1
43
43
 
44
44
  const FASTPACKET_INDEX = 0
45
45
  const FASTPACKET_SIZE = 1
@@ -111,14 +111,13 @@ class Parser extends EventEmitter {
111
111
  }
112
112
 
113
113
  trace(`${pgn.pgn} ${len} ${pgnData.Length} ${pgnData.RepeatingFields} ${couldBeMulti}`)
114
- if ( len > 0x8 || (this.format == FORMAT_FAST && !this.mixedFormat) ) {
115
- //if ( (len > 0x8 || pgnData.Type === 'Fast') && coalesced ) {
116
- this.format = FORMAT_FAST
114
+ if ( coalesced || len > 0x8 || (this.format == FORMAT_COALESCED && !this.mixedFormat) ) {
115
+ this.format = FORMAT_COALESCED
117
116
  if ( sourceString ) {
118
117
  pgn.input = [ sourceString ]
119
118
  }
120
- } else if ( pgnData.Length > 0x8 || (len == 0x8 && (pgnData.RepeatingFields || couldBeMulti))) {
121
- //} else if ( pgnData.Type === 'Fast' ) {
119
+ //} else if ( pgnData.Length > 0x8 || (len == 0x8 && (pgnData.RepeatingFields || couldBeMulti))) {
120
+ } else if ( pgnData.Type === 'Fast' ) {
122
121
  //partial packet
123
122
  this.format = FORMAT_PLAIN
124
123
 
@@ -138,7 +137,6 @@ class Parser extends EventEmitter {
138
137
  var start = bs.byteIndex
139
138
  var packetIndex = bs.view.buffer.readUInt8(FASTPACKET_INDEX)
140
139
  var bucket = packetIndex & FASTPACKET_MAX_INDEX;
141
- var maybeBad = false
142
140
 
143
141
  trace(`${pgn.pgn} partial ${packetIndex} ${bucket} ${packet.size}`)
144
142
 
@@ -156,14 +154,12 @@ class Parser extends EventEmitter {
156
154
  bs.view.buffer.copy(packet.buffer, 0, FASTPACKET_BUCKET_0_OFFSET, 8)
157
155
  trace(`${pgn.pgn} targetStart: 0 sourceStart: ${FASTPACKET_BUCKET_0_OFFSET}`)
158
156
  } else {
159
- if ( sourceString ) {
160
- packet.src.push(sourceString)
161
- }
162
157
  if (packet.lastPacket + 1 != packetIndex) {
163
158
  debug(`PGN ${pgn.pgn} malformed packet for ${pgn.src} received; expected ${packet.lastPacket+1} but got ${packetIndex}`)
164
159
  cb && cb(`Could not parse ${JSON.stringify(pgn)}`)
165
160
  bs.byteIndex = start
166
- maybeBad = true
161
+ delete this.devices[pgn.src][pgn.pgn]
162
+ return
167
163
  } else {
168
164
  trace(`${pgn.pgn} targetStart: ${FASTPACKET_BUCKET_0_SIZE + FASTPACKET_BUCKET_N_SIZE * (bucket-1)} sourceStart: ${FASTPACKET_BUCKET_N_OFFSET} sourceEned: ${FASTPACKET_BUCKET_N_SIZE}`)
169
165
  bs.view.buffer.copy(
@@ -173,20 +169,18 @@ class Parser extends EventEmitter {
173
169
  )
174
170
  }
175
171
  }
176
- if ( !maybeBad ) {
177
- packet.lastPacket = packetIndex;
178
- if (FASTPACKET_BUCKET_0_SIZE + FASTPACKET_BUCKET_N_SIZE * bucket < packet.size)
179
- {
180
- // Packet is not complete yet
181
- trace(`${pgn.pgn} not complete`)
182
- return;
183
- }
184
- var view = new BitView(packet.buffer)
185
- bs = new BitStream(view)
186
- trace(`${pgn.pgn} done`)
187
- pgn.input = packet.src
188
- delete this.devices[pgn.src][pgn.pgn]
172
+ packet.lastPacket = packetIndex;
173
+ if (FASTPACKET_BUCKET_0_SIZE + FASTPACKET_BUCKET_N_SIZE * bucket < packet.size)
174
+ {
175
+ // Packet is not complete yet
176
+ trace(`${pgn.pgn} not complete`)
177
+ return;
189
178
  }
179
+ var view = new BitView(packet.buffer)
180
+ bs = new BitStream(view)
181
+ trace(`${pgn.pgn} done`)
182
+ pgn.input = packet.src
183
+ delete this.devices[pgn.src][pgn.pgn]
190
184
  } else if ( sourceString ) {
191
185
  pgn.input = [ sourceString ]
192
186
  }
@@ -520,17 +514,26 @@ function readField(options, runPostProcessor, pgn, field, bs) {
520
514
  if ( field.Resolution && typeof value === 'number' ) {
521
515
  var resolution = field.Resolution
522
516
 
517
+ if ( _.isString(resolution) ) {
518
+ resolution = Number.parseFloat(resolution)
519
+ }
520
+
523
521
  value = (value * resolution)
522
+
523
+ let precision = 0;
524
+ for (let r = resolution; (r > 0.0) && (r < 1.0); r = r * 10.0)
525
+ {
526
+ precision++;
527
+ }
528
+
529
+ value = Number.parseFloat(value.toFixed(precision))
524
530
 
531
+ /*
525
532
  if ( resolution === 3.125e-8 ) {
526
533
  //yes. hack.
527
534
  resolution = "0.0000000001"
528
535
  }
529
-
530
- if ( _.isString(resolution) &&
531
- resolution.indexOf('.') != -1 ) {
532
- value = Number.parseFloat(value.toFixed(resolution.length-2))
533
- }
536
+ */
534
537
  }
535
538
 
536
539
  if (field.EnumValues &&
@@ -662,7 +665,13 @@ function readVariableLengthField(options, pgn, field, bs) {
662
665
 
663
666
  if ( refField ) {
664
667
  var bits = (refField.BitLength + 7) & ~7; // Round # of bits in field refField up to complete bytes: 1->8, 7->8, 8->8 etc.
665
- return readField(options, false, pgn, refField, bs, bits)
668
+ let res = readField(options, false, pgn, refField, bs)
669
+
670
+ if ( bits > field.BitLength ) {
671
+ bs.readBits(bits - refField.BitLength, false)
672
+ }
673
+
674
+ return res
666
675
  }
667
676
  }
668
677
 
@@ -708,7 +717,9 @@ fieldTypeReaders['ASCII string starting with length byte'] = (pgn, field, bs) =>
708
717
  fieldTypeReaders["String with start/stop byte"] = (pgn, field, bs) => {
709
718
  var len
710
719
  var first = bs.readUint8()
711
- if ( first == 0x02 ) {
720
+ if ( first == 0xff ) { // no name, stop reading
721
+ return ''
722
+ } else if ( first == 0x02 ) {
712
723
  var buf = Buffer.alloc(255)
713
724
  var c
714
725
  var idx = 0
package/lib/simpleCan.js CHANGED
@@ -27,9 +27,9 @@ SimpleCan.prototype.start = function () {
27
27
 
28
28
  pgn.timestamp = new Date().toISOString()
29
29
  if ( this.plainText ) {
30
- messageCb(binToActisense(pgn, msg.data, msg.data.length))
30
+ this.messageCb(binToActisense(pgn, msg.data, msg.data.length))
31
31
  } else {
32
- messageCb({ pgn, length: msg.data.length, data: msg.data })
32
+ this.messageCb({ pgn, length: msg.data.length, data: msg.data })
33
33
  }
34
34
  })
35
35
  }
package/lib/stringMsg.js CHANGED
@@ -49,7 +49,7 @@ exports.parseActisense = (input) => {
49
49
  buildCanId(prio, pgn, dst, src),
50
50
  'Actisense',
51
51
  Buffer.from(data.join(''), 'hex'),
52
- { len: Number(len), timestamp, coalesced: true },
52
+ { len: Number(len), timestamp },
53
53
  )
54
54
  }
55
55
  exports.encodeActisense = ({
@@ -153,12 +153,21 @@ exports.encodeMXPGN = ({ prefix = '$MXPGN', pgn, prio, src, data }) => {
153
153
  exports.isPDGY = startsWith('!PDGY,')
154
154
  exports.parsePDGY = (input) => {
155
155
  const parts = input.split(',')
156
- if ( parts.length != 7 ) return buildErr('iKonvert', 'Invalid parts.', input)
157
- const [ prefix, pgn, prio, src, dst, timer, data ] = parts
158
- return buildMsg(
159
- buildCanId(prio, pgn, dst, src), 'PDGY', Buffer.from(data, 'base64'),
160
- { timer: Number(timer), prefix },
161
- )
156
+ if ( parts.length === 7 ) {
157
+ const [ prefix, pgn, prio, src, dst, timer, data ] = parts
158
+ return buildMsg(
159
+ buildCanId(prio, pgn, dst, src), 'PDGY', Buffer.from(data, 'base64'),
160
+ { timer: Number(timer), prefix, coalesced: true },
161
+ )
162
+ } else if ( parts.length === 4 ) {
163
+ const [ prefix, pgn, dst, data ] = parts
164
+ return buildMsg(
165
+ buildCanId(0, pgn, dst, 0), 'PDGY', Buffer.from(data, 'base64'),
166
+ { coalesced: true }
167
+ )
168
+ } else {
169
+ return buildErr('iKonvert', 'Invalid parts.', input)
170
+ }
162
171
  }
163
172
  exports.encodePDGY = ({ prefix = '!PDGY', pgn, data, dst = 255}) => (
164
173
  [ prefix, pgn, dst, data.toString('base64')].join(',')
@@ -65,7 +65,6 @@ describe('parseActisense', () => {
65
65
  test('basic msg', () => {
66
66
  const msg = '2016-04-09T16:41:09.078Z,3,127257,17,255,8,00,ff,7f,52,00,21,fe,ff'
67
67
  expect(parseActisense(msg)).toEqual({
68
- coalesced: true,
69
68
  data: Buffer.from('00ff7f520021feff', 'hex'),
70
69
  dst: 255,
71
70
  len: 8,
@@ -99,6 +98,7 @@ describe('parsePDGY', () => {
99
98
  prio: 3,
100
99
  src: 2,
101
100
  timer: 0.563,
101
+ coalesced: true
102
102
  })
103
103
  })
104
104
  test('long msg', () => {
@@ -111,6 +111,7 @@ describe('parsePDGY', () => {
111
111
  prio: 3,
112
112
  src: 2,
113
113
  timer: 483.236,
114
+ coalesced: true
114
115
  })
115
116
  })
116
117
  })
package/lib/ydgw02.js CHANGED
@@ -89,7 +89,7 @@ Ydgw02Stream.prototype.sendPGN = function (pgn) {
89
89
  Ydgw02Stream.prototype.sendYdgwPGN = function (msg) {
90
90
 
91
91
  actisenseToYdgwRawFormat(msg).forEach(raw => {
92
- this.sendString(raw)
92
+ this.sendString(raw + '\r\n')
93
93
  })
94
94
 
95
95
  /*
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canboat/canboatjs",
3
- "version": "1.21.0",
3
+ "version": "1.22.1",
4
4
  "description": "Native javascript version of canboat",
5
5
  "main": "index.js",
6
6
  "scripts": {