@canboat/canboatjs 3.0.0-beta.1 → 3.0.0-beta.10

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.
@@ -11,13 +11,13 @@ jobs:
11
11
  with:
12
12
  node-version: '18.x'
13
13
  registry-url: 'https://registry.npmjs.org'
14
- run: |
14
+ - run: |
15
15
  npm ci && npm cache clean --force
16
16
  if [[ "$tag" == *beta* ]];
17
17
  then
18
18
  npm publish --tag beta
19
19
  else
20
- npm publish
20
+ npm publish --access public
21
21
  fi
22
22
  env:
23
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
23
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/bin/analyzerjs CHANGED
@@ -2,10 +2,7 @@
2
2
 
3
3
  const argv = require('minimist')(process.argv.slice(2), {
4
4
  alias: { h: 'help' },
5
- boolean: ['n'],
6
- boolean: ['r'],
7
- boolean: ['camel'],
8
- boolean: ['camel-compat']
5
+ boolean: ['n', 'r', 'camel', 'camel-compat']
9
6
  })
10
7
 
11
8
  if ( argv['help'] ) {
package/bin/candumpjs CHANGED
@@ -4,7 +4,7 @@ const canboatjs = require('../index')
4
4
  const Parser = require('../index').FromPgn
5
5
  const { parseCanId } = require('../lib/canId')
6
6
  const socketcan = require('socketcan')
7
-
7
+ const { binToActisense } = require('../lib/utilities')
8
8
  var parser = new canboatjs.FromPgn()
9
9
 
10
10
 
@@ -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,23 +72,14 @@ 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()
77
84
 
78
85
 
79
- function binToActisense(pgn, data, length) {
80
- return (
81
- pgn.timestamp +
82
- `,${pgn.prio},${pgn.pgn},${pgn.src},${pgn.dst},${length},` +
83
- new Uint32Array(data)
84
- .reduce(function(acc, i) {
85
- acc.push(i.toString(16));
86
- return acc;
87
- }, [])
88
- .map(x => (x.length === 1 ? "0" + x : x))
89
- .join(",")
90
- );
91
- }
package/bin/cansend ADDED
@@ -0,0 +1,130 @@
1
+ #!/usr/bin/env node
2
+
3
+ const canboatjs = require('../index')
4
+ const Parser = require('../index').FromPgn
5
+ const { parseCanId } = require('../lib/canId')
6
+ const { parseActisense } = require('../lib/stringMsg')
7
+
8
+ const { toPgn } = require('../lib/toPgn')
9
+ const { getPlainPGNs, binToActisense } = require('../lib/utilities')
10
+ const { encodeCanId } = require('../lib/canId')
11
+
12
+ const argv = require('minimist')(process.argv.slice(2), {
13
+ boolean: ['test', 'log-output'],
14
+ string: ['src'],
15
+ alias: { h: 'help' }
16
+ })
17
+
18
+ if ( argv['help'] ) {
19
+ console.error(`Usage: ${process.argv[0]} [options] candevice
20
+
21
+ Options:
22
+ --src <src> use src for all messages
23
+ --log-output log messages sent
24
+ --test don't connect or send any data
25
+ -h, --help output usage information`)
26
+ process.exit(1)
27
+ }
28
+
29
+ if ( argv['_'].length === 0 ) {
30
+ console.error('Please specify a device')
31
+ process.exit(1)
32
+ }
33
+
34
+ const canDevice = argv['_'][0]
35
+ const srcArg = argv.src
36
+ const logOut = argv['log-output']
37
+ const test = argv.test
38
+
39
+ let channel
40
+
41
+ if ( !test ) {
42
+ const socketcan = require('socketcan')
43
+ channel = socketcan.createRawChannel(canDevice);
44
+
45
+ channel.addListener('onStopped', (msg) => {
46
+ console.error('socketcan stopped')
47
+ })
48
+
49
+ channel.start()
50
+ }
51
+
52
+ var readline = require('readline')
53
+ var rl = readline.createInterface({
54
+ input: process.stdin,
55
+ output: process.stdout,
56
+ terminal: false
57
+ })
58
+
59
+ var input = []
60
+
61
+ rl.on('line', function (line) {
62
+ if ( line.length === 0 ) {
63
+ return
64
+ }
65
+
66
+ let msg = line[0] === '{' ? JSON.parse(line) : line
67
+
68
+ if ( typeof msg === 'string' ) {
69
+ var split = msg.split(',')
70
+ if ( srcArg !== undefined ) {
71
+ split[3] = srcArg
72
+ }
73
+ msg = split.join(',')
74
+ } else {
75
+ if ( msg.prio === undefined ) {
76
+ msg.prio = 3
77
+ }
78
+ if ( msg.dst === undefined ) {
79
+ msg.dst = 255
80
+ }
81
+ if ( srcArg !== undefined ) {
82
+ msg.src = srcArg
83
+ }
84
+ if ( msg.src === undefined ) {
85
+ msg.src = 100
86
+ }
87
+ }
88
+
89
+ var pgn, canid, buffer
90
+ if ( typeof msg === 'object' ) {
91
+ canid = encodeCanId(msg)
92
+ buffer = toPgn(msg)
93
+ if ( buffer === undefined ) {
94
+ console.error('invalid input: %s', line)
95
+ return
96
+ }
97
+ pgn = msg
98
+ } else {
99
+ pgn = parseActisense(msg)
100
+
101
+ if ( isNaN(pgn.prio) || isNaN(pgn.pgn) || isNaN(pgn.dst) || isNaN(pgn.src) ) {
102
+ console.error('invalid input: ' + line)
103
+ return
104
+ }
105
+
106
+ canid = encodeCanId(pgn)
107
+ buffer = pgn.data
108
+ }
109
+
110
+ pgn.timestamp = new Date().toISOString()
111
+
112
+ if ( buffer.length > 8 || pgn.pgn == 126720 ) {
113
+ var 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, 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, buffer, buffer.length))
128
+ }
129
+ }
130
+ })
package/bin/to-pgn CHANGED
@@ -4,14 +4,14 @@ const argv = require('minimist')(process.argv.slice(2), {
4
4
  string: ['format'],
5
5
  alias: { h: 'help' }
6
6
  })
7
- const { pgnToActisenseSerialFormat, pgnToActisenseN2KAsciiFormat, pgnToiKonvertSerialFormat, pgnToYdgwRawFormat, pgnToPCDIN, pgnToMXPGN } = require('../index')
7
+ const { pgnToActisenseSerialFormat, pgnToActisenseN2KAsciiFormat, pgnToiKonvertSerialFormat, pgnToYdgwRawFormat, pgnToYdgwFullRawFormat, pgnToPCDIN, pgnToMXPGN } = require('../index')
8
8
  const { toActisenseSerialFormat } = require('../lib/stringMsg')
9
9
 
10
10
  if ( argv['help'] ) {
11
11
  console.error(`Usage: ${process.argv[0]} [options]
12
12
 
13
13
  Options:
14
- --format <format> actisense, actisensen2kascii, ikconvert, ydgw, pcdin, mxpgn
14
+ --format <format> actisense, actisensen2kascii, ikconvert, ydgw, yd-full, pcdin, mxpgn
15
15
  -h, --help output usage information`)
16
16
  process.exit(1)
17
17
  }
@@ -23,7 +23,8 @@ const formatters = {
23
23
  ikconvert: pgnToiKonvertSerialFormat,
24
24
  ydgw: pgnToYdgwRawFormat,
25
25
  'pcdin': pgnToPCDIN,
26
- 'mxpgn': pgnToMXPGN
26
+ 'mxpgn': pgnToMXPGN,
27
+ 'yd-full': pgnToYdgwFullRawFormat
27
28
  }
28
29
 
29
30
  const format = argv['format'] || 'actisense'
@@ -0,0 +1 @@
1
+ module.exports = require('./dist/').default
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "signalk-device-emulator",
3
+ "version": "1.0.0",
4
+ "description": "Signal K Plugin which emulates a device",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "format": "prettier-standard 'src/*.ts'",
8
+ "build": "tsc",
9
+ "watch": "npm run build -- -w"
10
+ },
11
+ "keywords": [
12
+ "signalk-node-server-plugin"
13
+ ],
14
+ "author": "scott@scottbender.net",
15
+ "license": "Apache-2.0",
16
+ "dependencies": {
17
+ "@canboat/canboatjs": "^2.10.0"
18
+ },
19
+ "devDependencies": {
20
+ "@types/node": "^14.14.10",
21
+ "prettier-standard": "^16.4.1",
22
+ "typescript": "^4.1.2"
23
+ }
24
+ }
package/index.js CHANGED
@@ -28,6 +28,7 @@ module.exports = {
28
28
  pgnToActisenseN2KAsciiFormat: require('./lib/toPgn').pgnToActisenseN2KAsciiFormat,
29
29
  pgnToiKonvertSerialFormat: require('./lib/toPgn').pgnToiKonvertSerialFormat,
30
30
  pgnToYdgwRawFormat: require('./lib/toPgn').pgnToYdgwRawFormat,
31
+ pgnToYdgwFullRawFormat: require('./lib/toPgn').pgnToYdgwFullRawFormat,
31
32
  pgnToPCDIN: require('./lib/toPgn').pgnToPCDIN,
32
33
  pgnToMXPGN: require('./lib/toPgn').pgnToMXPGN,
33
34
  canbus: require('./lib/canbus'),
@@ -39,6 +40,7 @@ module.exports = {
39
40
  VenusMQTT: require('./lib/venus-mqtt'),
40
41
  discover: require('./lib/discovery'),
41
42
  SimpleCan: require('./lib/simpleCan'),
43
+ YdDevice: require('./lib/yddevice'),
42
44
  addCustomPgns: pgns.addCustomPgns,
43
45
  lookupEnumerationValue: pgns.lookupEnumerationValue,
44
46
  lookupEnumerationName: pgns.lookupEnumerationName
@@ -48,3 +50,4 @@ try {
48
50
  module.exports.serial = require('./lib/serial')
49
51
  } catch ( ex ) {
50
52
  }
53
+
package/lib/canbus.js CHANGED
@@ -23,7 +23,7 @@ const { toPgn } = require('./toPgn')
23
23
  const Parser = require('./fromPgn').Parser
24
24
  const _ = require('lodash')
25
25
  const CanDevice = require('./candevice')
26
- const { getPlainPGNs } = require('./utilities')
26
+ const { getPlainPGNs, binToActisense } = require('./utilities')
27
27
  const { encodeCanId, parseCanId } = require('./canId')
28
28
  const { toActisenseSerialFormat, parseActisense } = require('./stringMsg')
29
29
 
@@ -73,7 +73,7 @@ function CanbusStream (options) {
73
73
  this.socketcan = require('socketcan')
74
74
  } catch ( err ) {
75
75
  console.error(err)
76
- var msg = 'WARNING unable to load native socketcan interface'
76
+ var msg = 'unable to load native socketcan interface'
77
77
  console.error(msg)
78
78
  }
79
79
 
@@ -89,62 +89,38 @@ 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
+ if ( this.connect() == false ) {
94
+ return
95
+ }
96
+
97
+ const noDataReceivedTimeout = typeof options.noDataReceivedTimeout !== 'undefined' ? options.noDataReceivedTimeout : -1
98
+ if ( noDataReceivedTimeout > 0 ) {
99
+ this.noDataInterval = setInterval(() => {
100
+ if ( this.channel && this.lastDataReceived && Date.now() - this.lastDataReceived > noDataReceivedTimeout * 1000 ) {
101
+ let channel = this.channel
102
+ delete this.channel
103
+ try {
104
+ channel.stop()
105
+ } catch ( error ) {
140
106
  }
141
- }, noDataReceivedTimeout * 1000)
142
- }
107
+ this.setProviderError('No data received, retrying...')
108
+ if ( this.options.app ) {
109
+ console.error('No data received, retrying...')
110
+ }
111
+ this.connect()
112
+ }
113
+ }, noDataReceivedTimeout * 1000)
143
114
  }
144
115
  }
145
116
 
146
117
  CanbusStream.prototype.connect = function() {
147
118
  try {
119
+ if ( this.socketcan === undefined ) {
120
+ this.setProviderError('unable to load native socketcan interface')
121
+ return false
122
+ }
123
+
148
124
  var that = this
149
125
  var canDevice = this.options.canDevice || 'can0'
150
126
  this.channel = this.socketcan.createRawChannelWithOptions(canDevice, { non_block_send: true} );
@@ -181,39 +157,27 @@ CanbusStream.prototype.connect = function() {
181
157
  }
182
158
  })
183
159
  this.channel.start()
160
+ this.setProviderStatus('Connected to socketcan')
184
161
  this.candevice = new CanDevice(this, this.options)
185
162
  this.candevice.start()
186
- this.setProviderStatus('Connected')
163
+ return true
187
164
  } catch (e) {
188
165
  console.error(`unable to open canbus ${canDevice}: ${e}`)
189
166
  console.error(e.stack)
190
167
  this.setProviderError(e.message)
168
+ return false
191
169
  }
192
170
  }
193
171
 
194
- function binToActisense(pgn, data, length) {
195
- return (
196
- pgn.timestamp +
197
- `,${pgn.prio},${pgn.pgn},${pgn.src},${pgn.dst},${length},` +
198
- new Uint32Array(data)
199
- .reduce(function(acc, i) {
200
- acc.push(i.toString(16));
201
- return acc;
202
- }, [])
203
- .map(x => (x.length === 1 ? "0" + x : x))
204
- .join(",")
205
- );
206
- }
207
-
208
-
209
172
  require('util').inherits(CanbusStream, Transform)
210
173
 
211
174
  CanbusStream.prototype.start = function () {
212
175
  }
213
176
 
214
- CanbusStream.prototype.sendPGN = function (msg) {
177
+ CanbusStream.prototype.sendPGN = function (msg, force) {
215
178
  if ( this.candevice ) {
216
- if ( !this.candevice.cansend && (_.isString(msg) || msg.pgn !== 59904) ) {
179
+ //if ( !this.candevice.cansend && (_.isString(msg) || msg.pgn !== 59904) ) {
180
+ if ( !this.candevice.cansend && force !== true ) {
217
181
  //we have not completed address claim yet
218
182
  return
219
183
  }
@@ -279,66 +243,12 @@ CanbusStream.prototype.sendPGN = function (msg) {
279
243
  }
280
244
  }
281
245
 
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
246
 
332
247
  CanbusStream.prototype._transform = function (chunk, encoding, done) {
333
- readLine(this, chunk.toString())
334
248
  done()
335
249
  }
336
250
 
337
251
  CanbusStream.prototype.end = function () {
338
- if ( this.socketCanWriter ) {
339
- debug('end, killing socketcan-writer process')
340
- this.socketCanWriter.kill()
341
- }
342
252
  if ( this.channel ) {
343
253
  let channel = this.channel
344
254
  delete this.channel