@canboat/canboatjs 2.11.1 → 2.12.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/bin/candumpjs CHANGED
@@ -16,7 +16,8 @@ if ( argv['help'] ) {
16
16
  console.error(`Usage: ${process.argv[0]} [options] candevice
17
17
 
18
18
  Options:
19
- -h, --help output usage information`)
19
+ --format <format> json, actisense
20
+ -h, --help output usage information`)
20
21
  process.exit(1)
21
22
  }
22
23
 
@@ -25,6 +26,8 @@ if ( argv['_'].length === 0 ) {
25
26
  process.exit(1)
26
27
  }
27
28
 
29
+ const format = argv['format'] || 'json'
30
+
28
31
  /*
29
32
 
30
33
  let messageCb = (data) => {
@@ -69,8 +72,12 @@ channel.addListener('onMessage', (msg) => {
69
72
  pgn.timestamp = new Date().toISOString()
70
73
 
71
74
  let sourceString = binToActisense(pgn, msg.data, msg.data.length)
72
-
73
- parser.parse({ pgn, length: msg.data.length, data: msg.data, sourceString })
75
+
76
+ if ( format === 'json' ) {
77
+ parser.parse({ pgn, length: msg.data.length, data: msg.data, sourceString })
78
+ } else {
79
+ console.log(sourceString)
80
+ }
74
81
  })
75
82
 
76
83
  channel.start()
package/lib/canbus.js CHANGED
@@ -89,57 +89,26 @@ function CanbusStream (options) {
89
89
  }
90
90
 
91
91
  var canDevice = options.canDevice || 'can0'
92
- if ( !this.socketcan || this.options.useSocketCanWriter ) {
93
- this.socketCanWriter = null
94
- const spawn = require('child_process').spawn
95
- var hasWriter = spawn('sh', ['-c', 'which socketcan-writer'])
96
-
97
- const setProviderError = this.setProviderError.bind(this)
98
- const setProviderStatus = this.setProviderStatus.bind(this)
99
-
100
- hasWriter.on('close', code => {
101
- if ( code == 0 ) {
102
- debug('found socketcan-writer, starting...')
103
- setProviderStatus('Starting')
104
- this.socketCanWriter = spawn('sh',
105
- ['-c', `socketcan-writer ${canDevice}`])
106
- setProviderStatus(`Connected to ${canDevice}`)
107
- this.socketCanWriter.stderr.on('data', function (data) {
108
- console.error(data.toString())
109
- })
110
- this.socketCanWriter.on('close', function (code) {
111
- const msg = 'socketcan-writer process exited with code ' + code
112
- setProviderError(msg)
113
- console.error(msg)
114
- this.socketCanWriter = null
115
- })
116
- setTimeout(() => {
117
- this.candevice = new CanDevice(this, options)
118
- this.candevice.start()
119
- }, 5000)
120
- }
121
- })
122
- } else {
123
- this.connect()
124
-
125
- const noDataReceivedTimeout = typeof options.noDataReceivedTimeout !== 'undefined' ? options.noDataReceivedTimeout : -1
126
- if ( noDataReceivedTimeout > 0 ) {
127
- this.noDataInterval = setInterval(() => {
128
- if ( this.channel && this.lastDataReceived && Date.now() - this.lastDataReceived > noDataReceivedTimeout * 1000 ) {
129
- let channel = this.channel
130
- delete this.channel
131
- try {
132
- channel.stop()
133
- } catch ( error ) {
134
- }
135
- this.setProviderError('No data received, retrying...')
136
- if ( this.options.app ) {
137
- console.error('No data received, retrying...')
138
- }
139
- this.connect()
92
+
93
+ this.connect()
94
+
95
+ const noDataReceivedTimeout = typeof options.noDataReceivedTimeout !== 'undefined' ? options.noDataReceivedTimeout : -1
96
+ if ( noDataReceivedTimeout > 0 ) {
97
+ this.noDataInterval = setInterval(() => {
98
+ if ( this.channel && this.lastDataReceived && Date.now() - this.lastDataReceived > noDataReceivedTimeout * 1000 ) {
99
+ let channel = this.channel
100
+ delete this.channel
101
+ try {
102
+ channel.stop()
103
+ } catch ( error ) {
140
104
  }
141
- }, noDataReceivedTimeout * 1000)
142
- }
105
+ this.setProviderError('No data received, retrying...')
106
+ if ( this.options.app ) {
107
+ console.error('No data received, retrying...')
108
+ }
109
+ this.connect()
110
+ }
111
+ }, noDataReceivedTimeout * 1000)
143
112
  }
144
113
  }
145
114
 
@@ -181,9 +150,9 @@ CanbusStream.prototype.connect = function() {
181
150
  }
182
151
  })
183
152
  this.channel.start()
153
+ this.setProviderStatus('Connected to socketcan')
184
154
  this.candevice = new CanDevice(this, this.options)
185
155
  this.candevice.start()
186
- this.setProviderStatus('Connected')
187
156
  } catch (e) {
188
157
  console.error(`unable to open canbus ${canDevice}: ${e}`)
189
158
  console.error(e.stack)
@@ -211,9 +180,10 @@ require('util').inherits(CanbusStream, Transform)
211
180
  CanbusStream.prototype.start = function () {
212
181
  }
213
182
 
214
- CanbusStream.prototype.sendPGN = function (msg) {
183
+ CanbusStream.prototype.sendPGN = function (msg, force) {
215
184
  if ( this.candevice ) {
216
- if ( !this.candevice.cansend && (_.isString(msg) || msg.pgn !== 59904) ) {
185
+ //if ( !this.candevice.cansend && (_.isString(msg) || msg.pgn !== 59904) ) {
186
+ if ( !this.candevice.cansend && force !== true ) {
217
187
  //we have not completed address claim yet
218
188
  return
219
189
  }
@@ -279,66 +249,12 @@ CanbusStream.prototype.sendPGN = function (msg) {
279
249
  }
280
250
  }
281
251
 
282
- function readLine(that, line) {
283
- var candump_data_inc = CANDUMP_DATA_INC_3;
284
-
285
- if (line.length == 0 ) {
286
- return
287
- }
288
-
289
- if ( !that.format ) {
290
- //that.s
291
- if ( line.charAt(0) == '<' ) {
292
- that.format = FMT_1
293
- } else if ( line.charAt(0) == '(' ) {
294
- that.format = FMT_3
295
- console.error("candump format not supported")
296
- } else {
297
- that.format = FMT_2
298
- }
299
- }
300
-
301
-
302
- var canid
303
- var data
304
- var split = line.trim().split(' ').filter(s => s.length > 0)
305
- var len
306
- if ( that.format === FMT_3 ) {
307
- return
308
- } else if ( that.format === FMT_1 ) {
309
- canid = parseInt(split[0].substring(1, split[0].length-1), 16)
310
- data = split.slice(2)
311
- len = split[1].substring(1, split[1].length-1)
312
- } else if ( that.format === FMT_2 ) {
313
- canid = parseInt(split[1], 16)
314
- data = split.slice(3)
315
- len = split[2].substring(1, split[2].length-1)
316
- }
317
-
318
- //console.log(JSON.stringify(split))
319
- var pgn = parseCanId(canid)
320
-
321
- if ( that.candevice && pgn.src == that.candevice.address ) {
322
- //this is a message that we sent
323
- debug('got a message from me')
324
- return
325
- }
326
-
327
- pgn.timestamp = new Date().toISOString()
328
-
329
- that.push({ pgn: pgn, length: len, data, sourceString: line })
330
- }
331
252
 
332
253
  CanbusStream.prototype._transform = function (chunk, encoding, done) {
333
- readLine(this, chunk.toString())
334
254
  done()
335
255
  }
336
256
 
337
257
  CanbusStream.prototype.end = function () {
338
- if ( this.socketCanWriter ) {
339
- debug('end, killing socketcan-writer process')
340
- this.socketCanWriter.kill()
341
- }
342
258
  if ( this.channel ) {
343
259
  let channel = this.channel
344
260
  delete this.channel
package/lib/candevice.js CHANGED
@@ -44,7 +44,7 @@ class CanDevice extends N2kDevice {
44
44
  sendPGN(pgn, src) {
45
45
  pgn.src = src || this.address
46
46
  debug('Sending PGN %j', pgn)
47
- this.canbus.sendPGN(pgn)
47
+ this.canbus.sendPGN(pgn, true)
48
48
  }
49
49
  }
50
50
 
package/lib/n2kDevice.js CHANGED
@@ -97,6 +97,8 @@ class N2kDevice extends EventEmitter {
97
97
  this.foundConflict = false
98
98
  this.heartbeatCounter = 0
99
99
  this.devices = {}
100
+ this.sentAvailable = false
101
+ this.addressClaimDetectionTime = options.addressClaimDetectionTime !== undefined ? options.addressClaimDetectionTime : 5000
100
102
 
101
103
  if ( !options.disableDefaultTransmitPGNs ) {
102
104
  this.transmitPGNs = _.union(deviceTransmitPGNs, defaultTransmitPGNs)
@@ -117,6 +119,12 @@ class N2kDevice extends EventEmitter {
117
119
  }, 1000)
118
120
  }
119
121
 
122
+ setStatus(msg) {
123
+ if ( this.options.app && this.options.app.setPluginStatus ) {
124
+ this.options.app.setProviderStatus(this.options.providerId, msg)
125
+ }
126
+ }
127
+
120
128
  n2kMessage(pgn) {
121
129
  if ( pgn.dst == 255 || pgn.dst == this.address ) {
122
130
  try {
@@ -244,8 +252,8 @@ function handleISOAddressClaim(device, n2kMsg) {
244
252
  } else if(uint64ValueFromOurOwnClaim > uint64ValueFromReceivedClaim) {
245
253
  this.foundConflict = true
246
254
  increaseOwnAddress(device) // We have bigger address claim data -> we have to change our address
255
+ debug(`Address conflict detected! trying address ${device.address}.`)
247
256
  sendAddressClaim(device)
248
- debug(`Address conflict detected! Changed our address to ${device.address}.`)
249
257
  }
250
258
  }
251
259
 
@@ -260,7 +268,7 @@ function handleProductInformation(device, n2kMsg) {
260
268
  if ( !device.devices[n2kMsg.src] ) {
261
269
  device.devices[n2kMsg.src] = {}
262
270
  }
263
- debug('got production information %j', n2kMsg)
271
+ debug('got product information %j', n2kMsg)
264
272
  device.devices[n2kMsg.src].productInformation = n2kMsg
265
273
  }
266
274
 
@@ -289,25 +297,32 @@ function sendAddressClaim(device) {
289
297
  }
290
298
  debug(`Sending address claim ${device.address}`)
291
299
  device.sendPGN(device.addressClaim)
292
- setTimeout(() => {
293
- if ( !device.foundConflict ) {
294
- debug('no address conflics, enabling send')
300
+ device.setStatus(`Claimed address ${device.address}`)
301
+ device.addressClaimSentAt = Date.now()
302
+ if ( device.addressClaimChecker ) {
303
+ clearTimeout(device.addressClaimChecker)
304
+ }
305
+
306
+ device.addressClaimChecker = setTimeout(() => {
307
+ //if ( Date.now() - device.addressClaimSentAt > 1000 ) {
308
+ //device.addressClaimChecker = null
309
+ debug('claimed address %d', device.address)
295
310
  device.cansend = true
296
- if ( device.options.app ) {
297
- device.options.app.emit('nmea2000OutAvailable')
311
+ if ( !device.sentAvailable ) {
312
+ if ( device.options.app ) {
313
+ device.options.app.emit('nmea2000OutAvailable')
314
+ }
315
+ device.emit('nmea2000OutAvailable')
316
+ device.sentAvailable = true
298
317
  }
299
318
  sendISORequest(device, 126996)
300
- device.heartbeatInterval = setInterval(() => {
301
- sendHeartbeat(device)
302
- }, 60*1000)
303
- /*
304
- _.keys(device.devices).forEach((address) => {
305
- sendISORequest(device, 126996, undefined, address)
306
- })
307
- */
308
-
309
- }
310
- }, 250)
319
+ if ( !device.heartbeatInterval ) {
320
+ device.heartbeatInterval = setInterval(() => {
321
+ sendHeartbeat(device)
322
+ }, 60*1000)
323
+ }
324
+ //}
325
+ }, device.addressClaimDetectionTime)
311
326
  }
312
327
 
313
328
  function sendISORequest(device, pgn, src, dst=255) {
package/lib/yddevice.js CHANGED
@@ -33,7 +33,6 @@ class YdDevice extends N2kDevice {
33
33
 
34
34
  sendPGN(pgn, src) {
35
35
  pgn.src = src || this.address
36
- pgn.
37
36
  pgn.ydFullFormat = true
38
37
  debug('Sending PGN %j', pgn)
39
38
  this.app.emit(this.n2kOutEvent, pgn)
package/lib/ydgw02.js CHANGED
@@ -18,11 +18,12 @@ const debug = require('debug')('canboatjs:ydgw02')
18
18
  const Transform = require('stream').Transform
19
19
  const FromPgn = require('./fromPgn').Parser
20
20
  const Parser = require('./fromPgn').Parser
21
+ const YdDevice = require('./yddevice')
21
22
  const _ = require('lodash')
22
23
  const { defaultTransmitPGNs } = require('./codes')
23
- const { pgnToYdgwRawFormat, pgnToYdgwFullRawFormat, actisenseToYdgwRawFormat } = require('./toPgn')
24
+ const { pgnToYdgwRawFormat, pgnToYdgwFullRawFormat, actisenseToYdgwRawFormat, actisenseToYdgwFullRawFormat } = require('./toPgn')
24
25
 
25
- const pgnsSent = {}
26
+ //const pgnsSent = {}
26
27
 
27
28
  function Ydgw02Stream (options, type) {
28
29
  if (!(this instanceof Ydgw02Stream)) {
@@ -36,6 +37,7 @@ function Ydgw02Stream (options, type) {
36
37
  this.sentAvailable = false
37
38
  this.options = options
38
39
  this.outEvent = options.ydgwOutEvent || 'ydwg02-out'
40
+ this.device = undefined
39
41
 
40
42
  this.fromPgn = new FromPgn(options)
41
43
 
@@ -74,29 +76,43 @@ function Ydgw02Stream (options, type) {
74
76
  // set ydnu to RAW mode
75
77
  options.app.emit(this.outEvent, Buffer.from([0x30, 0x0a]))
76
78
  }
79
+
80
+ if ( options.createDevice === true || options.createDevice === undefined ) {
81
+ this.device = new YdDevice(options)
82
+ this.device.start()
83
+ }
84
+
77
85
  debug('started')
78
86
  }
79
87
 
80
88
  }
81
89
 
82
- Ydgw02Stream.prototype.sendString = function (msg) {
83
- debug('sending %s', msg)
84
- this.options.app.emit(this.outEvent, msg)
90
+ Ydgw02Stream.prototype.cansend = function (msg) {
91
+ return this.device ? this.device.cansend : true
92
+ }
93
+
94
+ Ydgw02Stream.prototype.sendString = function (msg, forceSend) {
95
+ if ( this.cansend() || forceSend === true ) {
96
+ debug('sending %s', msg)
97
+ this.options.app.emit(this.outEvent, msg)
98
+ }
85
99
  }
86
100
 
87
101
  Ydgw02Stream.prototype.sendPGN = function (pgn) {
88
- let now = Date.now()
89
- let lastSent = pgnsSent[pgn.pgn]
90
- let msgs
91
- if ( pgn.ydFullFormat === true ) {
92
- msgs = pgnToYdgwFullRawFormat(pgn)
93
- } else {
94
- msgs = pgnToYdgwRawFormat(pgn)
102
+ if ( this.cansend() || pgn.forceSend === true ) {
103
+ //let now = Date.now()
104
+ //let lastSent = pgnsSent[pgn.pgn]
105
+ let msgs
106
+ if ( pgn.ydFullFormat === true || this.device !== undefined ) {
107
+ msgs = pgnToYdgwFullRawFormat(pgn)
108
+ } else {
109
+ msgs = pgnToYdgwRawFormat(pgn)
110
+ }
111
+ msgs.forEach(raw => {
112
+ this.sendString(raw + '\r\n', pgn.forceSend)
113
+ })
114
+ //pgnsSent[pgn.pgn] = now
95
115
  }
96
- msgs.forEach(raw => {
97
- this.sendString(raw + '\r\n')
98
- })
99
- pgnsSent[pgn.pgn] = now
100
116
  }
101
117
 
102
118
  Ydgw02Stream.prototype.sendYdgwFullPGN = function (msgs) {
@@ -107,7 +123,15 @@ Ydgw02Stream.prototype.sendYdgwFullPGN = function (msgs) {
107
123
 
108
124
  Ydgw02Stream.prototype.sendYdgwPGN = function (msg) {
109
125
 
110
- actisenseToYdgwRawFormat(msg).forEach(raw => {
126
+ let msgs
127
+
128
+ if ( this.device != undefined ) {
129
+ msgs = actisenseToYdgwFullRawFormat(msg)
130
+ } else {
131
+ msgs = actisenseToYdgwRawFormat(msg)
132
+ }
133
+
134
+ msg.forEach(raw => {
111
135
  this.sendString(raw + '\r\n')
112
136
  })
113
137
 
@@ -143,7 +167,7 @@ Ydgw02Stream.prototype._transform = function (chunk, encoding, done) {
143
167
  let line = chunk.toString().trim()
144
168
  //line = line.substring(0, line.length) // take off the \r
145
169
 
146
- if ( !this.sentAvailable ) {
170
+ if ( this.device === undefined && !this.sentAvailable ) {
147
171
  debug('emit nmea2000OutAvailable')
148
172
  this.options.app.emit('nmea2000OutAvailable')
149
173
  this.sentAvailable = true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canboat/canboatjs",
3
- "version": "2.11.1",
3
+ "version": "2.12.0",
4
4
  "description": "Native javascript version of canboat",
5
5
  "main": "index.js",
6
6
  "scripts": {