@canboat/canboatjs 3.0.0-beta.4 → 3.0.0-beta.5
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 +10 -3
- package/lib/canbus.js +23 -107
- package/lib/candevice.js +1 -1
- package/lib/n2kDevice.js +33 -18
- package/lib/yddevice.js +0 -1
- package/lib/ydgw02.js +42 -18
- package/package.json +3 -3
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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
|
-
|
|
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
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
|
|
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
|
-
|
|
293
|
-
|
|
294
|
-
|
|
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.
|
|
297
|
-
device.options.app
|
|
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
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
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
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.
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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
|
-
|
|
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": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.5",
|
|
4
4
|
"description": "Native javascript version of canboat",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -53,13 +53,14 @@
|
|
|
53
53
|
],
|
|
54
54
|
"license": "Apache-2.0",
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@canboat/pgns": "6.0.0-beta.
|
|
56
|
+
"@canboat/pgns": "6.0.0-beta.3",
|
|
57
57
|
"bit-buffer": "0.2.3",
|
|
58
58
|
"debug": "^4.3.4",
|
|
59
59
|
"dnssd": "^0.4.1",
|
|
60
60
|
"int64-buffer": "^0.1.10",
|
|
61
61
|
"lodash": "^4.17.4",
|
|
62
62
|
"minimist": "^1.2.0",
|
|
63
|
+
"moment": "^2.30.1",
|
|
63
64
|
"mqtt": "^2.18.8",
|
|
64
65
|
"split": "^1.0.1"
|
|
65
66
|
},
|
|
@@ -73,7 +74,6 @@
|
|
|
73
74
|
"chai-things": "^0.2.0",
|
|
74
75
|
"jest": "^24.7.1",
|
|
75
76
|
"mocha": "^5.0.0",
|
|
76
|
-
"moment": "^2.24.0",
|
|
77
77
|
"nyc": "^15.1.0",
|
|
78
78
|
"webpack-cli": "^5.1.4"
|
|
79
79
|
},
|