@canboat/canboatjs 3.3.3 → 3.3.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/dist/bin/actisense-file.js +2 -0
- package/dist/bin/actisense-file.js.map +1 -1
- package/dist/bin/actisense-n2k-tcp.js +2 -0
- package/dist/bin/actisense-n2k-tcp.js.map +1 -1
- package/dist/bin/actisense-serialjs.js +2 -0
- package/dist/bin/actisense-serialjs.js.map +1 -1
- package/dist/bin/analyzerjs.js +2 -0
- package/dist/bin/analyzerjs.js.map +1 -1
- package/dist/bin/candumpjs.js +7 -4
- package/dist/bin/candumpjs.js.map +1 -1
- package/dist/bin/cansend.js +2 -0
- package/dist/bin/cansend.js.map +1 -1
- package/dist/bin/to-pgn.js +2 -0
- package/dist/bin/to-pgn.js.map +1 -1
- package/dist/bin/utils.d.ts +4 -0
- package/dist/bin/utils.d.ts.map +1 -0
- package/dist/bin/utils.js +15 -0
- package/dist/bin/utils.js.map +1 -0
- package/dist/bin/ydvr-file.d.ts +3 -0
- package/dist/bin/ydvr-file.d.ts.map +1 -0
- package/dist/bin/ydvr-file.js +31 -0
- package/dist/bin/ydvr-file.js.map +1 -0
- package/dist/fromPgn.d.ts.map +1 -1
- package/dist/fromPgn.js +1 -0
- package/dist/fromPgn.js.map +1 -1
- package/package.json +4 -3
- package/tsconfig.tsbuildinfo +1 -1
- package/.github/workflows/publish.yml +0 -32
- package/.github/workflows/release_on_tag.yml +0 -27
- package/.github/workflows/require_pr_label.yml +0 -13
- package/.github/workflows/test.yml +0 -28
- package/.github/workflows/test_canboat_changes.yml +0 -92
- package/examples/signalk-device-emulator/index.js +0 -1
- package/examples/signalk-device-emulator/package.json +0 -24
- package/examples/simpleCan.js +0 -42
- package/ios.js +0 -67
- package/lib/actisense-serial.ts +0 -644
- package/lib/bin/actisense-file.ts +0 -53
- package/lib/bin/actisense-n2k-tcp.ts +0 -50
- package/lib/bin/actisense-serialjs.ts +0 -55
- package/lib/bin/analyzerjs.ts +0 -91
- package/lib/bin/candumpjs.ts +0 -100
- package/lib/bin/cansend.ts +0 -131
- package/lib/bin/ikonvert-serial.ts +0 -44
- package/lib/bin/to-pgn.ts +0 -65
- package/lib/bin/ydvr-file +0 -33
- package/lib/canId.test.js +0 -61
- package/lib/canId.ts +0 -84
- package/lib/canbus.ts +0 -293
- package/lib/candevice.ts +0 -41
- package/lib/codes.ts +0 -21
- package/lib/discovery.ts +0 -118
- package/lib/fromPgn.ts +0 -1217
- package/lib/fromPgnStream.ts +0 -54
- package/lib/ikonvert.ts +0 -250
- package/lib/index.ts +0 -48
- package/lib/n2k-actisense.test.js +0 -58
- package/lib/n2k-actisense.ts +0 -152
- package/lib/n2kDevice.ts +0 -509
- package/lib/pgns.test.ts +0 -12
- package/lib/pgns.ts +0 -191
- package/lib/simpleCan.ts +0 -140
- package/lib/stringMsg.test.js +0 -288
- package/lib/stringMsg.ts +0 -478
- package/lib/toPgn.ts +0 -601
- package/lib/utilities.test.js +0 -8
- package/lib/utilities.ts +0 -169
- package/lib/venus-mqtt.js +0 -118
- package/lib/venus.js +0 -88
- package/lib/w2k01.ts +0 -142
- package/lib/yddevice.ts +0 -48
- package/lib/ydgw02.ts +0 -197
- package/lib/ydvr.js +0 -138
package/lib/actisense-serial.ts
DELETED
|
@@ -1,644 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright 2018 Scott Bender (scott@scottbender.net)
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import { PGN } from '@canboat/ts-pgns'
|
|
18
|
-
import { createDebug } from './utilities'
|
|
19
|
-
import util from 'util'
|
|
20
|
-
import { Transform } from 'stream'
|
|
21
|
-
import { BitStream, BitView } from 'bit-buffer'
|
|
22
|
-
import { toPgn } from './toPgn'
|
|
23
|
-
import { encodeActisense } from './stringMsg'
|
|
24
|
-
import { defaultTransmitPGNs } from './codes'
|
|
25
|
-
import _ from 'lodash'
|
|
26
|
-
import { Parser as FromPgn } from './fromPgn'
|
|
27
|
-
|
|
28
|
-
/* ASCII characters used to mark packet start/stop */
|
|
29
|
-
|
|
30
|
-
const STX = 0x02 /* Start packet */
|
|
31
|
-
const ETX = 0x03 /* End packet */
|
|
32
|
-
const DLE = 0x10 /* Start pto encode a STX or ETX send DLE+STX or DLE+ETX */
|
|
33
|
-
const ESC = 0x1b /* Escape */
|
|
34
|
-
|
|
35
|
-
/* Actisense message structure is:
|
|
36
|
-
|
|
37
|
-
DLE STX <command> <len> [<data> ...] <checksum> DLE ETX
|
|
38
|
-
|
|
39
|
-
<command> is a byte from the list below.
|
|
40
|
-
In <data> any DLE characters are double escaped (DLE DLE).
|
|
41
|
-
<len> encodes the unescaped length.
|
|
42
|
-
<checksum> is such that the sum of all unescaped data bytes plus the command
|
|
43
|
-
byte plus the length adds up to zero, modulo 256.
|
|
44
|
-
*/
|
|
45
|
-
|
|
46
|
-
const N2K_MSG_RECEIVED = 0x93 /* Receive standard N2K message */
|
|
47
|
-
const N2K_MSG_SEND = 0x94 /* Send N2K message */
|
|
48
|
-
const NGT_MSG_RECEIVED = 0xa0 /* Receive NGT specific message */
|
|
49
|
-
const NGT_MSG_SEND = 0xa1 /* Send NGT message */
|
|
50
|
-
|
|
51
|
-
const MSG_START = 1
|
|
52
|
-
const MSG_ESCAPE = 2
|
|
53
|
-
const MSG_MESSAGE = 3
|
|
54
|
-
|
|
55
|
-
const NGT_STARTUP_MSG = new Uint8Array([0x11, 0x02, 0x00])
|
|
56
|
-
|
|
57
|
-
export function ActisenseStream(this: any, options: any) {
|
|
58
|
-
if (this === undefined) {
|
|
59
|
-
return new (ActisenseStream as any)(options)
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
this.debugOut = createDebug('canboatjs:actisense-out', options)
|
|
63
|
-
this.debug = createDebug('canboatjs:actisense-serial', options)
|
|
64
|
-
|
|
65
|
-
Transform.call(this, {
|
|
66
|
-
objectMode: true
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
this.debug('options: %j', options)
|
|
70
|
-
|
|
71
|
-
this.reconnect = options.reconnect || true
|
|
72
|
-
this.serial = null
|
|
73
|
-
this.options = options
|
|
74
|
-
this.transmitPGNRetries = 2
|
|
75
|
-
|
|
76
|
-
this.transmitPGNs = defaultTransmitPGNs
|
|
77
|
-
if (this.options.transmitPGNs) {
|
|
78
|
-
this.transmitPGNs = _.union(this.transmitPGNs, this.options.transmitPGNs)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
this.options.disableSetTransmitPGNs = true
|
|
82
|
-
|
|
83
|
-
if (process.env.DISABLESETTRANSMITPGNS) {
|
|
84
|
-
this.options.disableSetTransmitPGNs = true
|
|
85
|
-
}
|
|
86
|
-
if (process.env.ENABLESETTRANSMITPGNS) {
|
|
87
|
-
this.options.disableSetTransmitPGNs = false
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
this.start()
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
util.inherits(ActisenseStream, Transform)
|
|
94
|
-
|
|
95
|
-
ActisenseStream.prototype.start = function (this: any) {
|
|
96
|
-
if (this.serial !== null) {
|
|
97
|
-
this.serial.unpipe(this)
|
|
98
|
-
this.serial.removeAllListeners()
|
|
99
|
-
this.serial = null
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (this.reconnect === false) {
|
|
103
|
-
return
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const setProviderStatus =
|
|
107
|
-
this.options.app && this.options.app.setProviderStatus
|
|
108
|
-
? (msg: string) => {
|
|
109
|
-
this.options.app.setProviderStatus(this.options.providerId, msg)
|
|
110
|
-
}
|
|
111
|
-
: () => {}
|
|
112
|
-
const setProviderError =
|
|
113
|
-
this.options.app && this.options.app.setProviderError
|
|
114
|
-
? (msg: string) => {
|
|
115
|
-
this.options.app.setProviderError(this.options.providerId, msg)
|
|
116
|
-
}
|
|
117
|
-
: () => {}
|
|
118
|
-
this.setProviderStatus = setProviderStatus
|
|
119
|
-
|
|
120
|
-
this.buffer = Buffer.alloc(500)
|
|
121
|
-
this.bufferOffset = 0
|
|
122
|
-
this.isFile = false
|
|
123
|
-
this.state = MSG_START
|
|
124
|
-
|
|
125
|
-
if (typeof this.reconnectDelay === 'undefined') {
|
|
126
|
-
this.reconnectDelay = 1000
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (!this.options.fromFile) {
|
|
130
|
-
try {
|
|
131
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
132
|
-
const { SerialPort } = require('serialport')
|
|
133
|
-
this.serial = new SerialPort({
|
|
134
|
-
path: this.options.device,
|
|
135
|
-
baudRate: this.options.baudrate || 115200
|
|
136
|
-
})
|
|
137
|
-
} catch (err) {
|
|
138
|
-
setProviderError('serialport module not available')
|
|
139
|
-
console.error(err)
|
|
140
|
-
return
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
this.serial.on('data', (data: Buffer) => {
|
|
144
|
-
try {
|
|
145
|
-
readData(this, data)
|
|
146
|
-
} catch (err: any) {
|
|
147
|
-
setProviderError(err.message)
|
|
148
|
-
console.error(err)
|
|
149
|
-
}
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
if (this.options.app) {
|
|
153
|
-
const writeString = (msg: string) => {
|
|
154
|
-
this.debugOut(`sending ${msg}`)
|
|
155
|
-
let buf = parseInput(msg)
|
|
156
|
-
buf = composeMessage(N2K_MSG_SEND, buf, buf.length)
|
|
157
|
-
this.debugOut(buf)
|
|
158
|
-
this.serial.write(buf)
|
|
159
|
-
this.options.app.emit('connectionwrite', {
|
|
160
|
-
providerId: this.options.providerId
|
|
161
|
-
})
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
const writeObject = (msg: PGN) => {
|
|
165
|
-
const data = toPgn(msg)
|
|
166
|
-
const actisense = encodeActisense({ pgn: msg.pgn, data, dst: msg.dst })
|
|
167
|
-
this.debugOut(`sending ${actisense}`)
|
|
168
|
-
let buf = parseInput(actisense)
|
|
169
|
-
buf = composeMessage(N2K_MSG_SEND, buf, buf.length)
|
|
170
|
-
this.debugOut(buf)
|
|
171
|
-
this.serial.write(buf)
|
|
172
|
-
this.options.app.emit('connectionwrite', {
|
|
173
|
-
providerId: this.options.providerId
|
|
174
|
-
})
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
this.options.app.on(
|
|
178
|
-
this.options.outEevent || 'nmea2000out',
|
|
179
|
-
(msg: string) => {
|
|
180
|
-
if (this.outAvailable) {
|
|
181
|
-
if (typeof msg === 'string') {
|
|
182
|
-
writeString(msg)
|
|
183
|
-
} else {
|
|
184
|
-
writeObject(msg)
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
)
|
|
189
|
-
|
|
190
|
-
this.options.app.on(
|
|
191
|
-
this.options.jsonOutEvent || 'nmea2000JsonOut',
|
|
192
|
-
(msg: PGN) => {
|
|
193
|
-
if (this.outAvailable) {
|
|
194
|
-
writeObject(msg)
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
)
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
this.outAvailable = false
|
|
201
|
-
|
|
202
|
-
this.serial.on('error', (err: any) => {
|
|
203
|
-
setProviderError(err.message)
|
|
204
|
-
console.log(err)
|
|
205
|
-
this.scheduleReconnect()
|
|
206
|
-
})
|
|
207
|
-
this.serial.on('close', () => {
|
|
208
|
-
setProviderError('Closed, reconnecting...')
|
|
209
|
-
//this.start.bind(this)
|
|
210
|
-
this.scheduleReconnect()
|
|
211
|
-
})
|
|
212
|
-
this.serial.on('open', () => {
|
|
213
|
-
try {
|
|
214
|
-
this.reconnectDelay = 1000
|
|
215
|
-
setProviderStatus(`Connected to ${this.options.device}`)
|
|
216
|
-
const buf = composeMessage(
|
|
217
|
-
NGT_MSG_SEND,
|
|
218
|
-
Buffer.from(NGT_STARTUP_MSG),
|
|
219
|
-
NGT_STARTUP_MSG.length
|
|
220
|
-
)
|
|
221
|
-
this.debugOut(buf)
|
|
222
|
-
this.serial.write(buf)
|
|
223
|
-
this.debug('sent startup message')
|
|
224
|
-
this.gotStartupResponse = false
|
|
225
|
-
if (this.options.disableSetTransmitPGNs) {
|
|
226
|
-
enableOutput(this)
|
|
227
|
-
} else {
|
|
228
|
-
setTimeout(() => {
|
|
229
|
-
if (this.gotStartupResponse === false) {
|
|
230
|
-
this.debug('retry startup message...')
|
|
231
|
-
this.debugOut(buf)
|
|
232
|
-
this.serial.write(buf)
|
|
233
|
-
}
|
|
234
|
-
}, 5000)
|
|
235
|
-
}
|
|
236
|
-
} catch (err: any) {
|
|
237
|
-
setProviderError(err.message)
|
|
238
|
-
console.error(err)
|
|
239
|
-
console.error(err.stack)
|
|
240
|
-
}
|
|
241
|
-
})
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
ActisenseStream.prototype.scheduleReconnect = function () {
|
|
246
|
-
this.reconnectDelay *= this.reconnectDelay < 60 * 1000 ? 1.5 : 1
|
|
247
|
-
const msg = `Not connected (retry delay ${(
|
|
248
|
-
this.reconnectDelay / 1000
|
|
249
|
-
).toFixed(0)} s)`
|
|
250
|
-
this.debug(msg)
|
|
251
|
-
this.setProviderStatus(msg)
|
|
252
|
-
setTimeout(this.start.bind(this), this.reconnectDelay)
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
function readData(that: any, data: Buffer) {
|
|
256
|
-
for (let i = 0; i < data.length; i++) {
|
|
257
|
-
//console.log(data[i])
|
|
258
|
-
read1Byte(that, data[i])
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
function read1Byte(that: any, c: any) {
|
|
263
|
-
let noEscape = false
|
|
264
|
-
|
|
265
|
-
//debug("received byte %02x state=%d offset=%d\n", c, state, head - buf);
|
|
266
|
-
|
|
267
|
-
if (that.stat == MSG_START) {
|
|
268
|
-
if (c == ESC && that.isFile) {
|
|
269
|
-
noEscape = true
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
if (that.stat == MSG_ESCAPE) {
|
|
274
|
-
if (c == ETX) {
|
|
275
|
-
if (!that.options.outputOnly) {
|
|
276
|
-
if (that.buffer[0] == N2K_MSG_RECEIVED) {
|
|
277
|
-
processN2KMessage(that, that.buffer, that.bufferOffset)
|
|
278
|
-
} else if (that.buffer[0] == NGT_MSG_RECEIVED) {
|
|
279
|
-
processNTGMessage(that, that.buffer, that.bufferOffset)
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
that.bufferOffset = 0
|
|
283
|
-
that.stat = MSG_START
|
|
284
|
-
} else if (c == STX) {
|
|
285
|
-
that.bufferOffset = 0
|
|
286
|
-
that.stat = MSG_MESSAGE
|
|
287
|
-
} else if (c == DLE || (c == ESC && that.isFile) || that.noEscape) {
|
|
288
|
-
that.buffer.writeUInt8(c, that.bufferOffset)
|
|
289
|
-
that.bufferOffset++
|
|
290
|
-
that.stat = MSG_MESSAGE
|
|
291
|
-
} else {
|
|
292
|
-
console.error('DLE followed by unexpected char , ignore message')
|
|
293
|
-
that.stat = MSG_START
|
|
294
|
-
}
|
|
295
|
-
} else if (that.stat == MSG_MESSAGE) {
|
|
296
|
-
if (c == DLE) {
|
|
297
|
-
that.stat = MSG_ESCAPE
|
|
298
|
-
} else if (that.isFile && c == ESC && !noEscape) {
|
|
299
|
-
that.stat = MSG_ESCAPE
|
|
300
|
-
} else {
|
|
301
|
-
that.buffer.writeUInt8(c, that.bufferOffset)
|
|
302
|
-
that.bufferOffset++
|
|
303
|
-
}
|
|
304
|
-
} else {
|
|
305
|
-
if (c == DLE) {
|
|
306
|
-
that.stat = MSG_ESCAPE
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
function enableTXPGN(that: any, pgn: number) {
|
|
312
|
-
that.debug('enabling pgn %d', pgn)
|
|
313
|
-
const msg = composeEnablePGN(pgn)
|
|
314
|
-
that.debugOut(msg)
|
|
315
|
-
that.serial.write(msg)
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
function enableOutput(that: any) {
|
|
319
|
-
that.debug('outputEnabled')
|
|
320
|
-
that.outAvailable = true
|
|
321
|
-
if (that.options.app) {
|
|
322
|
-
that.options.app.emit('nmea2000OutAvailable')
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
function requestTransmitPGNList(that: any) {
|
|
327
|
-
that.debug('request tx pgns...')
|
|
328
|
-
const requestMsg = composeRequestTXPGNList()
|
|
329
|
-
that.debugOut(requestMsg)
|
|
330
|
-
that.serial.write(requestMsg)
|
|
331
|
-
setTimeout(() => {
|
|
332
|
-
if (!that.gotTXPGNList) {
|
|
333
|
-
if (that.transmitPGNRetries-- > 0) {
|
|
334
|
-
that.debug('did not get tx pgn list, retrying...')
|
|
335
|
-
requestTransmitPGNList(that)
|
|
336
|
-
} else {
|
|
337
|
-
const msg = 'could not set transmit pgn list'
|
|
338
|
-
that.options.app.setProviderStatus(msg)
|
|
339
|
-
console.warn(msg)
|
|
340
|
-
enableOutput(that)
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
}, 10000)
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
function processNTGMessage(that: any, buffer: Buffer, len: number) {
|
|
347
|
-
let checksum = 0
|
|
348
|
-
|
|
349
|
-
for (let i = 0; i < len; i++) {
|
|
350
|
-
checksum = addUInt8(checksum, buffer[i])
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
const command = buffer[2]
|
|
354
|
-
|
|
355
|
-
if (checksum != 0) {
|
|
356
|
-
that.debug('received message with invalid checksum (%d,%d)', command, len)
|
|
357
|
-
return
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
if (that.options.sendNetworkStats || that.debug.enabled) {
|
|
361
|
-
const newbuf = Buffer.alloc(len + 7)
|
|
362
|
-
const bs = new BitStream(newbuf)
|
|
363
|
-
const pgn = 0x40000 + buffer[2]
|
|
364
|
-
bs.writeUint8(0) //prio
|
|
365
|
-
bs.writeUint8(pgn)
|
|
366
|
-
bs.writeUint8(pgn >> 8)
|
|
367
|
-
bs.writeUint8(pgn >> 16)
|
|
368
|
-
bs.writeUint8(0) //dst
|
|
369
|
-
bs.writeUint8(0) //src
|
|
370
|
-
bs.writeUint32(0) //timestamp
|
|
371
|
-
bs.writeUint8(len - 4)
|
|
372
|
-
buffer.copy(bs.view.buffer, bs.byteIndex, 3)
|
|
373
|
-
|
|
374
|
-
if (that.options.plainText) {
|
|
375
|
-
that.push(binToActisense(bs.view.buffer)) //, len + 7))
|
|
376
|
-
} else {
|
|
377
|
-
that.push(bs.view.buffer, len + 7)
|
|
378
|
-
}
|
|
379
|
-
if (that.debug.enabled && command != 0xf2) {
|
|
380
|
-
//don't log system status
|
|
381
|
-
if (!that.parser) {
|
|
382
|
-
that.parser = new FromPgn({})
|
|
383
|
-
}
|
|
384
|
-
const js = that.parser.parseBuffer(bs.view.buffer)
|
|
385
|
-
if (js) {
|
|
386
|
-
that.debug('got ntg message: %j', js)
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
if (command === 0x11) {
|
|
392
|
-
//confirm startup
|
|
393
|
-
that.gotStartupResponse = true
|
|
394
|
-
that.debug('got startup response')
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
if (!that.outAvailable) {
|
|
398
|
-
if (command === 0x11) {
|
|
399
|
-
that.gotTXPGNList = false
|
|
400
|
-
setTimeout(() => {
|
|
401
|
-
requestTransmitPGNList(that)
|
|
402
|
-
}, 2000)
|
|
403
|
-
} else if (command === 0x49 && buffer[3] === 1) {
|
|
404
|
-
that.gotTXPGNList = true
|
|
405
|
-
const pgnCount = buffer[14]
|
|
406
|
-
const bv = new BitView(buffer.slice(15, that.bufferOffset))
|
|
407
|
-
const bs = new BitStream(bv)
|
|
408
|
-
const pgns: number[] = []
|
|
409
|
-
for (let i = 0; i < pgnCount; i++) {
|
|
410
|
-
pgns.push(bs.readUint32())
|
|
411
|
-
}
|
|
412
|
-
that.debug('tx pgns: %j', pgns)
|
|
413
|
-
|
|
414
|
-
that.neededTransmitPGNs = that.transmitPGNs.filter((pgn: number) => {
|
|
415
|
-
return pgns.indexOf(pgn) == -1
|
|
416
|
-
})
|
|
417
|
-
that.debug('needed pgns: %j', that.neededTransmitPGNs)
|
|
418
|
-
} else if (command === 0x49 && buffer[3] === 4) {
|
|
419
|
-
//I think this means done receiving the pgns list
|
|
420
|
-
if (that.neededTransmitPGNs) {
|
|
421
|
-
if (that.neededTransmitPGNs.length) {
|
|
422
|
-
enableTXPGN(that, that.neededTransmitPGNs[0])
|
|
423
|
-
} else {
|
|
424
|
-
enableOutput(that)
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
} else if (command === 0x47) {
|
|
428
|
-
//response from enable a pgn
|
|
429
|
-
if (buffer[3] === 1) {
|
|
430
|
-
that.debug('enabled %d', that.neededTransmitPGNs[0])
|
|
431
|
-
that.neededTransmitPGNs = that.neededTransmitPGNs.slice(1)
|
|
432
|
-
if (that.neededTransmitPGNs.length === 0) {
|
|
433
|
-
const commitMsg = composeCommitTXPGN()
|
|
434
|
-
that.debugOut(commitMsg)
|
|
435
|
-
that.serial.write(commitMsg)
|
|
436
|
-
} else {
|
|
437
|
-
enableTXPGN(that.serial, that.neededTransmitPGNs[0])
|
|
438
|
-
}
|
|
439
|
-
} else {
|
|
440
|
-
that.debug('bad response from Enable TX: %d', buffer[3])
|
|
441
|
-
}
|
|
442
|
-
} else if (command === 0x01) {
|
|
443
|
-
that.debug('commited tx list')
|
|
444
|
-
const activateMsg = composeActivateTXPGN()
|
|
445
|
-
that.debugOut(activateMsg)
|
|
446
|
-
that.serial.write(activateMsg)
|
|
447
|
-
} else if (command === 0x4b) {
|
|
448
|
-
that.debug('activated tx list')
|
|
449
|
-
enableOutput(that)
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
function addUInt8(num: number, add: number) {
|
|
455
|
-
if (num + add > 255) {
|
|
456
|
-
num = add - (256 - num)
|
|
457
|
-
} else {
|
|
458
|
-
num += add
|
|
459
|
-
}
|
|
460
|
-
return num
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
function processN2KMessage(that: any, buffer: Buffer, len: number) {
|
|
464
|
-
let checksum = 0
|
|
465
|
-
|
|
466
|
-
for (let i = 0; i < len; i++) {
|
|
467
|
-
checksum = addUInt8(checksum, buffer[i])
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
if (checksum != 0) {
|
|
471
|
-
that.debug('received message with invalid checksum')
|
|
472
|
-
return
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
if (that.options.plainText) {
|
|
476
|
-
that.push(binToActisense(buffer.slice(2, len)))
|
|
477
|
-
} else {
|
|
478
|
-
that.push(buffer.slice(2, len))
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
function binToActisense(buffer: Buffer) {
|
|
483
|
-
const bv = new BitView(buffer)
|
|
484
|
-
const bs = new BitStream(bv)
|
|
485
|
-
|
|
486
|
-
const pgn = {
|
|
487
|
-
prio: bs.readUint8(),
|
|
488
|
-
pgn: bs.readUint8() + 256 * (bs.readUint8() + 256 * bs.readUint8()),
|
|
489
|
-
dst: bs.readUint8(),
|
|
490
|
-
src: bs.readUint8(),
|
|
491
|
-
timestamp: bs.readUint32()
|
|
492
|
-
}
|
|
493
|
-
const len = bs.readUint8()
|
|
494
|
-
const arr: string[] = []
|
|
495
|
-
return (
|
|
496
|
-
new Date().toISOString() +
|
|
497
|
-
`,${pgn.prio},${pgn.pgn},${pgn.src},${pgn.dst},${len},` +
|
|
498
|
-
new Uint32Array(buffer.slice(11, 11 + len))
|
|
499
|
-
.reduce(function (acc, i) {
|
|
500
|
-
acc.push(i.toString(16))
|
|
501
|
-
return acc
|
|
502
|
-
}, arr)
|
|
503
|
-
.map((x) => (x.length === 1 ? '0' + x : x))
|
|
504
|
-
.join(',')
|
|
505
|
-
)
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
function composeMessage(command: number, buffer: Buffer, len: number) {
|
|
509
|
-
const outBuf = Buffer.alloc(500)
|
|
510
|
-
const out = new BitStream(outBuf)
|
|
511
|
-
|
|
512
|
-
out.writeUint8(DLE)
|
|
513
|
-
out.writeUint8(STX)
|
|
514
|
-
out.writeUint8(command)
|
|
515
|
-
|
|
516
|
-
const lenPos = out.byteIndex
|
|
517
|
-
out.writeUint8(0) //length. will update later
|
|
518
|
-
let crc = command
|
|
519
|
-
|
|
520
|
-
for (let i = 0; i < len; i++) {
|
|
521
|
-
const c = buffer.readUInt8(i)
|
|
522
|
-
if (c == DLE) {
|
|
523
|
-
out.writeUint8(DLE)
|
|
524
|
-
}
|
|
525
|
-
out.writeUint8(c)
|
|
526
|
-
crc = addUInt8(crc, c)
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
crc = addUInt8(crc, len)
|
|
530
|
-
|
|
531
|
-
out.writeUint8(256 - crc)
|
|
532
|
-
out.writeUint8(DLE)
|
|
533
|
-
out.writeUint8(ETX)
|
|
534
|
-
|
|
535
|
-
out.view.buffer.writeUInt8(len, lenPos)
|
|
536
|
-
|
|
537
|
-
//that.debug(`command ${out.view.buffer[2]} ${lenPos} ${len} ${out.view.buffer[lenPos]} ${out.view.buffer.length} ${out.byteIndex}`)
|
|
538
|
-
|
|
539
|
-
return out.view.buffer.slice(0, out.byteIndex)
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
function parseInput(msg: string) {
|
|
543
|
-
const split = msg.split(',')
|
|
544
|
-
const buffer = Buffer.alloc(500)
|
|
545
|
-
const bs = new BitStream(buffer)
|
|
546
|
-
|
|
547
|
-
const prio = Number(split[1])
|
|
548
|
-
const pgn = Number(split[2])
|
|
549
|
-
const dst = Number(split[4])
|
|
550
|
-
const bytes = Number(split[5])
|
|
551
|
-
|
|
552
|
-
bs.writeUint8(prio)
|
|
553
|
-
bs.writeUint8(pgn)
|
|
554
|
-
bs.writeUint8(pgn >> 8)
|
|
555
|
-
bs.writeUint8(pgn >> 16)
|
|
556
|
-
bs.writeUint8(dst)
|
|
557
|
-
|
|
558
|
-
/*
|
|
559
|
-
bs.writeUint8(split[3])
|
|
560
|
-
bs.writeUint32(0)
|
|
561
|
-
*/
|
|
562
|
-
|
|
563
|
-
bs.writeUint8(bytes)
|
|
564
|
-
|
|
565
|
-
for (let i = 6; i < bytes + 6; i++) {
|
|
566
|
-
bs.writeUint8(parseInt('0x' + split[i], 16))
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
return bs.view.buffer.slice(0, bs.byteIndex)
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
function composeCommitTXPGN() {
|
|
573
|
-
const msg = new Uint32Array([0x01])
|
|
574
|
-
return composeMessage(NGT_MSG_SEND, Buffer.from(msg), msg.length)
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
function composeActivateTXPGN() {
|
|
578
|
-
const msg = new Uint32Array([0x4b])
|
|
579
|
-
return composeMessage(NGT_MSG_SEND, Buffer.from(msg), msg.length)
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
function composeRequestTXPGNList() {
|
|
583
|
-
const msg = new Uint32Array([0x49])
|
|
584
|
-
return composeMessage(NGT_MSG_SEND, Buffer.from(msg), msg.length)
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
function composeEnablePGN(pgn: number) {
|
|
588
|
-
const outBuf = Buffer.alloc(14)
|
|
589
|
-
const out = new BitStream(outBuf)
|
|
590
|
-
out.writeUint8(0x47)
|
|
591
|
-
out.writeUint32(pgn)
|
|
592
|
-
out.writeUint8(1) //enabled
|
|
593
|
-
|
|
594
|
-
out.writeUint32(0xfffffffe)
|
|
595
|
-
out.writeUint32(0xfffffffe)
|
|
596
|
-
|
|
597
|
-
const res = composeMessage(
|
|
598
|
-
NGT_MSG_SEND,
|
|
599
|
-
out.view.buffer.slice(0, out.byteIndex),
|
|
600
|
-
out.byteIndex
|
|
601
|
-
)
|
|
602
|
-
|
|
603
|
-
//that.debug('composeEnablePGN: %o', res)
|
|
604
|
-
|
|
605
|
-
return res
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
/*
|
|
609
|
-
function composeDisablePGN(pgn) {
|
|
610
|
-
var outBuf = Buffer.alloc(14);
|
|
611
|
-
let out = new BitStream(outBuf)
|
|
612
|
-
out.writeUint8(0x47)
|
|
613
|
-
out.writeUint32(pgn)
|
|
614
|
-
out.writeUint8(0) //disabled
|
|
615
|
-
|
|
616
|
-
//disbale system time
|
|
617
|
-
//10 02 a1 0e 47 10 10 f0 01 00 00 e8 03 00 00 00 00 00 00 1e 10 03
|
|
618
|
-
|
|
619
|
-
out.writeUint32(0x000003e8) //???
|
|
620
|
-
out.writeUint32(0x00)
|
|
621
|
-
|
|
622
|
-
let res = composeMessage(NGT_MSG_SEND, out.view.buffer.slice(0, out.byteIndex), out.byteIndex)
|
|
623
|
-
|
|
624
|
-
that.debug('composeDisablePGN: %o', res)
|
|
625
|
-
|
|
626
|
-
return res;
|
|
627
|
-
}
|
|
628
|
-
*/
|
|
629
|
-
|
|
630
|
-
ActisenseStream.prototype.end = function () {
|
|
631
|
-
if (this.serial) {
|
|
632
|
-
this.serial.close()
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
ActisenseStream.prototype._transform = function (
|
|
637
|
-
chunk: any,
|
|
638
|
-
encoding: string,
|
|
639
|
-
done: any
|
|
640
|
-
) {
|
|
641
|
-
this.debug(`got data ${typeof chunk}`)
|
|
642
|
-
readData(this, chunk)
|
|
643
|
-
done()
|
|
644
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { EventEmitter } from 'node:events'
|
|
4
|
-
import minimist from 'minimist'
|
|
5
|
-
import { serial } from '../index'
|
|
6
|
-
import { Transform } from 'stream'
|
|
7
|
-
import fs from 'fs'
|
|
8
|
-
|
|
9
|
-
const argv = minimist(process.argv.slice(2), {
|
|
10
|
-
alias: { h: 'help' }
|
|
11
|
-
})
|
|
12
|
-
|
|
13
|
-
if (argv['help']) {
|
|
14
|
-
console.error(`Usage: ${process.argv[0]} file
|
|
15
|
-
|
|
16
|
-
Options:
|
|
17
|
-
-h, --help output usage information`)
|
|
18
|
-
process.exit(1)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (argv['_'].length === 0) {
|
|
22
|
-
console.error('Please specify a file')
|
|
23
|
-
process.exit(1)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const app = new EventEmitter()
|
|
27
|
-
|
|
28
|
-
const actisense = new (serial as any)({
|
|
29
|
-
app: app,
|
|
30
|
-
plainText: true,
|
|
31
|
-
disableSetTransmitPGNs: true,
|
|
32
|
-
fromFile: true
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
const toStringTr = new Transform({
|
|
36
|
-
objectMode: true,
|
|
37
|
-
|
|
38
|
-
transform(chunk: any, encoding: string, callback: any) {
|
|
39
|
-
this.push(chunk + '\n')
|
|
40
|
-
callback()
|
|
41
|
-
}
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
actisense.pipe(toStringTr).pipe(process.stdout)
|
|
45
|
-
|
|
46
|
-
const filestream = fs.createReadStream(argv['_'][0])
|
|
47
|
-
filestream.on('error', (err) => {
|
|
48
|
-
console.error(err.message)
|
|
49
|
-
})
|
|
50
|
-
filestream.on('end', () => {
|
|
51
|
-
process.exit(0)
|
|
52
|
-
})
|
|
53
|
-
filestream.pipe(actisense)
|