queclink-parser 1.3.20

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/src/gv600w.js ADDED
@@ -0,0 +1,997 @@
1
+ 'use strict'
2
+ const utils = require('./utils.js')
3
+
4
+ /*
5
+ Parses messages data from GV800W devices
6
+ */
7
+ const parse = raw => {
8
+ raw = raw.substr(0, raw.length - 1)
9
+
10
+ const parsedData = raw.split(',')
11
+ const command = parsedData[0].split(':')
12
+
13
+ let history = false
14
+ if (utils.patterns.buffer.test(command[0])) {
15
+ history = true
16
+ }
17
+
18
+ let data = {
19
+ raw: `${raw.toString()}$`,
20
+ manufacturer: 'queclink',
21
+ device: 'Queclink-GV600W',
22
+ type: 'data',
23
+ imei: parsedData[2],
24
+ protocolVersion: utils.getProtocolVersion(parsedData[1]),
25
+ temperature: null,
26
+ history: history,
27
+ sentTime: utils.parseDate(parsedData[parsedData.length - 2]),
28
+ serialId: parseInt(parsedData[parsedData.length - 1], 16)
29
+ }
30
+
31
+ // Gps
32
+ if (command[1] === 'GTFRI') {
33
+ try {
34
+ data = Object.assign(data, {
35
+ alarm: utils.getAlarm(command[1], null),
36
+ loc: {
37
+ type: 'Point',
38
+ coordinates: [parseFloat(parsedData[11]), parseFloat(parsedData[12])]
39
+ },
40
+ speed: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
41
+ gpsStatus: utils.checkGps(
42
+ parseFloat(parsedData[11]),
43
+ parseFloat(parsedData[12])
44
+ ),
45
+ hdop: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
46
+ status: {
47
+ // parsedData[24]
48
+ raw: parsedData[24],
49
+ sos: false,
50
+ input: {
51
+ '1':
52
+ utils.nHexDigit(
53
+ utils.hex2bin(parsedData[24].substring(2, 4)),
54
+ 6
55
+ )[5] === '1',
56
+ '2':
57
+ utils.nHexDigit(
58
+ utils.hex2bin(parsedData[24].substring(2, 4)),
59
+ 6
60
+ )[4] === '1',
61
+ '3':
62
+ utils.nHexDigit(
63
+ utils.hex2bin(parsedData[24].substring(2, 4)),
64
+ 6
65
+ )[3] === '1',
66
+ '4':
67
+ utils.nHexDigit(
68
+ utils.hex2bin(parsedData[24].substring(2, 4)),
69
+ 6
70
+ )[2] === '1',
71
+ '5':
72
+ utils.nHexDigit(
73
+ utils.hex2bin(parsedData[24].substring(2, 4)),
74
+ 6
75
+ )[1] === '1',
76
+ '6':
77
+ utils.nHexDigit(
78
+ utils.hex2bin(parsedData[24].substring(2, 4)),
79
+ 6
80
+ )[0] === '1'
81
+ },
82
+ output: {
83
+ '1':
84
+ utils.nHexDigit(
85
+ utils.hex2bin(parsedData[24].substring(4, 6)),
86
+ 5
87
+ )[4] === '1',
88
+ '2':
89
+ utils.nHexDigit(
90
+ utils.hex2bin(parsedData[24].substring(4, 6)),
91
+ 5
92
+ )[3] === '1',
93
+ '3':
94
+ utils.nHexDigit(
95
+ utils.hex2bin(parsedData[24].substring(4, 6)),
96
+ 5
97
+ )[2] === '1',
98
+ '4':
99
+ utils.nHexDigit(
100
+ utils.hex2bin(parsedData[24].substring(4, 6)),
101
+ 5
102
+ )[1] === '1',
103
+ '5':
104
+ utils.nHexDigit(
105
+ utils.hex2bin(parsedData[24].substring(4, 6)),
106
+ 5
107
+ )[0] === '1'
108
+ },
109
+ charge: parseFloat(parsedData[4]) > 5,
110
+ state:
111
+ utils.nHexDigit(parsedData[24], 6).substring(0, 2) !== ''
112
+ ? utils.states[utils.nHexDigit(parsedData[24], 6).substring(0, 2)]
113
+ : null
114
+ },
115
+ azimuth: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
116
+ altitude: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
117
+ datetime:
118
+ parsedData[13] !== '' ? utils.parseDate(parsedData[13]) : null,
119
+ voltage: {
120
+ battery: parsedData[23] !== '' ? parseFloat(parsedData[23]) : null, // percentage
121
+ inputCharge:
122
+ parsedData[4] !== '' ? parseFloat(parsedData[4]) / 1000 : null,
123
+ ada: parsedData[21] !== '' ? parseFloat(parsedData[21]) / 1000 : null,
124
+ adb: null,
125
+ adc: null,
126
+ add: null
127
+ },
128
+ mcc: parsedData[14] !== '' ? parseInt(parsedData[14], 10) : null,
129
+ mnc: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null,
130
+ lac: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
131
+ cid: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
132
+ odometer: parsedData[19] !== '' ? parseFloat(parsedData[19]) : null,
133
+ hourmeter:
134
+ parsedData[20] !== ''
135
+ ? utils.getHoursForHourmeter(parsedData[20])
136
+ : null
137
+ })
138
+ } catch (err) {
139
+ return { type: 'UNKNOWN', raw: data.raw.toString() }
140
+ }
141
+ } else if (command[1] === 'GTERI') {
142
+ // GPS with AC100 Devices Connected
143
+ data = Object.assign(data, {
144
+ alarm: utils.getAlarm(command[1], null),
145
+ loc: {
146
+ type: 'Point',
147
+ coordinates: [parseFloat(parsedData[12]), parseFloat(parsedData[13])]
148
+ },
149
+ speed: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
150
+ gpsStatus: utils.checkGps(
151
+ parseFloat(parsedData[12]),
152
+ parseFloat(parsedData[13])
153
+ ),
154
+ hdop: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
155
+ status: {
156
+ // parsedData[24]
157
+ raw: parsedData[25],
158
+ sos: false,
159
+ input: {
160
+ '1':
161
+ utils.nHexDigit(
162
+ utils.hex2bin(parsedData[25].substring(2, 4)),
163
+ 6
164
+ )[5] === '1',
165
+ '2':
166
+ utils.nHexDigit(
167
+ utils.hex2bin(parsedData[25].substring(2, 4)),
168
+ 6
169
+ )[4] === '1',
170
+ '3':
171
+ utils.nHexDigit(
172
+ utils.hex2bin(parsedData[25].substring(2, 4)),
173
+ 6
174
+ )[3] === '1',
175
+ '4':
176
+ utils.nHexDigit(
177
+ utils.hex2bin(parsedData[25].substring(2, 4)),
178
+ 6
179
+ )[2] === '1',
180
+ '5':
181
+ utils.nHexDigit(
182
+ utils.hex2bin(parsedData[25].substring(2, 4)),
183
+ 6
184
+ )[1] === '1',
185
+ '6':
186
+ utils.nHexDigit(
187
+ utils.hex2bin(parsedData[25].substring(2, 4)),
188
+ 6
189
+ )[0] === '1'
190
+ },
191
+ output: {
192
+ '1':
193
+ utils.nHexDigit(
194
+ utils.hex2bin(parsedData[25].substring(4, 6)),
195
+ 5
196
+ )[4] === '1',
197
+ '2':
198
+ utils.nHexDigit(
199
+ utils.hex2bin(parsedData[25].substring(4, 6)),
200
+ 5
201
+ )[3] === '1',
202
+ '3':
203
+ utils.nHexDigit(
204
+ utils.hex2bin(parsedData[25].substring(4, 6)),
205
+ 5
206
+ )[2] === '1',
207
+ '4':
208
+ utils.nHexDigit(
209
+ utils.hex2bin(parsedData[25].substring(4, 6)),
210
+ 5
211
+ )[1] === '1',
212
+ '5':
213
+ utils.nHexDigit(
214
+ utils.hex2bin(parsedData[25].substring(4, 6)),
215
+ 5
216
+ )[0] === '1'
217
+ },
218
+ charge: parseFloat(parsedData[4]) > 5,
219
+ state:
220
+ utils.nHexDigit(parsedData[25], 6).substring(0, 2) !== ''
221
+ ? utils.states[utils.nHexDigit(parsedData[25], 6).substring(0, 2)]
222
+ : null
223
+ },
224
+ azimuth: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
225
+ altitude: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
226
+ datetime: parsedData[14] !== '' ? utils.parseDate(parsedData[14]) : null,
227
+ voltage: {
228
+ battery: parsedData[24] !== '' ? parseFloat(parsedData[24]) : null, // percentage
229
+ inputCharge:
230
+ parsedData[5] !== '' ? parseFloat(parsedData[5]) / 1000 : null,
231
+ ada: parsedData[22] !== '' ? parseFloat(parsedData[22]) / 1000 : null,
232
+ adb: null,
233
+ adc: null,
234
+ add: null
235
+ },
236
+ mcc: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null,
237
+ mnc: parsedData[16] !== '' ? parseInt(parsedData[16], 10) : null,
238
+ lac: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
239
+ cid: parsedData[18] !== '' ? parseInt(parsedData[18], 16) : null,
240
+ odometer: parsedData[20] !== '' ? parseFloat(parsedData[20]) : null,
241
+ hourmeter:
242
+ parsedData[21] !== ''
243
+ ? utils.getHoursForHourmeter(parsedData[21])
244
+ : null
245
+ })
246
+ // External Data
247
+
248
+ const oneWire = utils.nHexDigit(utils.hex2bin(parsedData[4]), 8)[7] !== '0'
249
+ const oneWireConnected = oneWire ? parseInt(parsedData[27], 10) : 0
250
+
251
+ let externalData = {
252
+ eriMask: {
253
+ raw: parsedData[4],
254
+ oneWire: oneWire,
255
+ digitFuelSensor: false,
256
+ rpm: false,
257
+ rf: false
258
+ },
259
+ uartDeviceType: null
260
+ }
261
+ if (oneWire) {
262
+ let oneWireDevices = []
263
+ let count = 28
264
+ for (var k = 0; k < oneWireConnected; k++) {
265
+ oneWireDevices.push({
266
+ deviceNumber: parsedData[count],
267
+ deviceType: parsedData[count + 1],
268
+ deviceData: parsedData[count + 2]
269
+ ? utils.getTempInCelciousDegrees(parsedData[count + 2])
270
+ : null
271
+ })
272
+ count += 3
273
+ }
274
+ externalData = Object.assign(externalData, {
275
+ fuelSensorData: null,
276
+ AC100Devices: oneWireDevices
277
+ })
278
+ }
279
+ data = Object.assign(data, {
280
+ externalData: externalData
281
+ })
282
+ } else if (command[1] === 'GTHBD') {
283
+ // Heartbeat. It must response an ACK command
284
+ data = Object.assign(data, {
285
+ alarm: utils.getAlarm(command[1], null)
286
+ })
287
+ } else if (
288
+ command[1] === 'GTTOW' ||
289
+ command[1] === 'GTDIS' ||
290
+ command[1] === 'GTIOB' ||
291
+ command[1] === 'GTSPD' ||
292
+ command[1] === 'GTSOS' ||
293
+ command[1] === 'GTRTL' ||
294
+ command[1] === 'GTPNL' ||
295
+ command[1] === 'GTDOG' ||
296
+ command[1] === 'GTIGL' ||
297
+ command[1] === 'GTHBM'
298
+ ) {
299
+ // Common Alarms
300
+ data = Object.assign(data, {
301
+ alarm: utils.getAlarm(command[1], parsedData[5], 'gv600w'),
302
+ loc: {
303
+ type: 'Point',
304
+ coordinates: [parseFloat(parsedData[11]), parseFloat(parsedData[12])]
305
+ },
306
+ speed: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
307
+ gpsStatus: utils.checkGps(
308
+ parseFloat(parsedData[11]),
309
+ parseFloat(parsedData[12])
310
+ ),
311
+ hdop: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
312
+ status: null,
313
+ azimuth: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
314
+ altitude: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
315
+ datetime: parsedData[13] !== '' ? utils.parseDate(parsedData[13]) : null,
316
+ voltage: {
317
+ battery: null,
318
+ inputCharge: null,
319
+ ada: null,
320
+ adb: null,
321
+ adc: null,
322
+ add: null
323
+ },
324
+ mcc: parsedData[14] !== '' ? parseInt(parsedData[14], 10) : null,
325
+ mnc: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null,
326
+ lac: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
327
+ cid: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
328
+ odometer: parsedData[19] !== '' ? parseFloat(parsedData[19]) : null,
329
+ hourmeter: null
330
+ })
331
+ } else if (command[1] === 'GTEPS' || command[1] === 'GTAIS') {
332
+ // External low battery and Low voltage for analog input
333
+ data = Object.assign(data, {
334
+ alarm: utils.getAlarm(command[1], parsedData[5]),
335
+ loc: {
336
+ type: 'Point',
337
+ coordinates: [parseFloat(parsedData[11]), parseFloat(parsedData[12])]
338
+ },
339
+ speed: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
340
+ gpsStatus: utils.checkGps(
341
+ parseFloat(parsedData[11]),
342
+ parseFloat(parsedData[12])
343
+ ),
344
+ hdop: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
345
+ status: null,
346
+ azimuth: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
347
+ altitude: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
348
+ datetime: parsedData[13] !== '' ? utils.parseDate(parsedData[13]) : null,
349
+ voltage: {
350
+ battery: null, // percentage
351
+ inputCharge:
352
+ parsedData[4] !== '' ? parseFloat(parsedData[4]) / 1000 : null,
353
+ ada: null,
354
+ adb: null,
355
+ adc: null,
356
+ add: null
357
+ },
358
+ mcc: parsedData[14] !== '' ? parseInt(parsedData[14], 10) : null,
359
+ mnc: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null,
360
+ lac: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
361
+ cid: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
362
+ odometer: parsedData[19] !== '' ? parseFloat(parsedData[19]) : null,
363
+ hourmeter: null
364
+ })
365
+ } else if (
366
+ command[1] === 'GTPNA' ||
367
+ command[1] === 'GTPFA' ||
368
+ command[1] === 'GTPDP'
369
+ ) {
370
+ // Event report (It uses the last GPS data and MCC info)
371
+ data = Object.assign(data, {
372
+ alarm: utils.getAlarm(command[1], null),
373
+ loc: null,
374
+ speed: null,
375
+ gpsStatus: null,
376
+ hdop: null,
377
+ status: null,
378
+ azimuth: null,
379
+ altitude: null,
380
+ datetime: parsedData[4] !== '' ? utils.parseDate(parsedData[4]) : null,
381
+ voltage: {
382
+ battery: null,
383
+ inputCharge: null,
384
+ ada: null,
385
+ adb: null
386
+ },
387
+ mcc: null,
388
+ mnc: null,
389
+ lac: null,
390
+ cid: null,
391
+ odometer: null,
392
+ hourmeter: null
393
+ })
394
+ } else if (
395
+ command[1] === 'GTMPN' ||
396
+ command[1] === 'GTMPF' ||
397
+ command[1] === 'GTBTC' ||
398
+ command[1] === 'GTCRA' ||
399
+ command[1] === 'GTJDR'
400
+ ) {
401
+ data = Object.assign(data, {
402
+ alarm: utils.getAlarm(command[1], null),
403
+ loc: {
404
+ type: 'Point',
405
+ coordinates: [parseFloat(parsedData[8]), parseFloat(parsedData[9])]
406
+ },
407
+ speed: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
408
+ gpsStatus: utils.checkGps(
409
+ parseFloat(parsedData[8]),
410
+ parseFloat(parsedData[9])
411
+ ),
412
+ hdop: parsedData[4] !== '' ? parseFloat(parsedData[4]) : null,
413
+ status: null,
414
+ azimuth: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
415
+ altitude: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
416
+ datetime: parsedData[10] !== '' ? utils.parseDate(parsedData[10]) : null,
417
+ voltage: {
418
+ battery: null,
419
+ inputCharge: null,
420
+ ada: null,
421
+ adb: null,
422
+ adc: null,
423
+ add: null
424
+ },
425
+ mcc: parsedData[11] !== '' ? parseInt(parsedData[11], 10) : null,
426
+ mnc: parsedData[12] !== '' ? parseInt(parsedData[12], 10) : null,
427
+ lac: parsedData[13] !== '' ? parseInt(parsedData[13], 16) : null,
428
+ cid: parsedData[14] !== '' ? parseInt(parsedData[14], 16) : null,
429
+ odometer: null,
430
+ hourmeter: null
431
+ })
432
+ } else if (
433
+ command[1] === 'GTJDS' ||
434
+ command[1] === 'GTANT' ||
435
+ command[1] === 'GTRMD'
436
+ ) {
437
+ data = Object.assign(data, {
438
+ alarm: utils.getAlarm(command[1], parsedData[4]),
439
+ loc: {
440
+ type: 'Point',
441
+ coordinates: [parseFloat(parsedData[9]), parseFloat(parsedData[10])]
442
+ },
443
+ speed: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
444
+ gpsStatus: utils.checkGps(
445
+ parseFloat(parsedData[9]),
446
+ parseFloat(parsedData[10])
447
+ ),
448
+ hdop: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
449
+ status: null,
450
+ azimuth: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
451
+ altitude: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
452
+ datetime: parsedData[11] !== '' ? utils.parseDate(parsedData[11]) : null,
453
+ voltage: {
454
+ battery: null,
455
+ inputCharge: null,
456
+ ada: null,
457
+ adb: null,
458
+ adc: null,
459
+ add: null
460
+ },
461
+ mcc: parsedData[12] !== '' ? parseInt(parsedData[12], 10) : null,
462
+ mnc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
463
+ lac: parsedData[14] !== '' ? parseInt(parsedData[14], 16) : null,
464
+ cid: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
465
+ odometer: null,
466
+ hourmeter: null
467
+ })
468
+ } else if (command[1] === 'GTBPL') {
469
+ data = Object.assign(data, {
470
+ alarm: utils.getAlarm(command[1], null),
471
+ loc: {
472
+ type: 'Point',
473
+ coordinates: [parseFloat(parsedData[9]), parseFloat(parsedData[10])]
474
+ },
475
+ speed: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
476
+ gpsStatus: utils.checkGps(
477
+ parseFloat(parsedData[9]),
478
+ parseFloat(parsedData[10])
479
+ ),
480
+ hdop: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
481
+ status: null,
482
+ azimuth: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
483
+ altitude: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
484
+ datetime: parsedData[11] !== '' ? utils.parseDate(parsedData[11]) : null,
485
+ voltage: {
486
+ battery: parsedData[4] !== '' ? parseFloat(parsedData[4]) : null,
487
+ inputCharge: null,
488
+ ada: null,
489
+ adb: null,
490
+ adc: null,
491
+ add: null
492
+ },
493
+ mcc: parsedData[12] !== '' ? parseInt(parsedData[12], 10) : null,
494
+ mnc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
495
+ lac: parsedData[14] !== '' ? parseInt(parsedData[14], 16) : null,
496
+ cid: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
497
+ odometer: null,
498
+ hourmeter: null
499
+ })
500
+ } else if (command[1] === 'GTIGN' || command[1] === 'GTIGF') {
501
+ data = Object.assign(data, {
502
+ alarm: utils.getAlarm(command[1], parsedData[4]),
503
+ loc: {
504
+ type: 'Point',
505
+ coordinates: [parseFloat(parsedData[9]), parseFloat(parsedData[10])]
506
+ },
507
+ speed: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
508
+ gpsStatus: utils.checkGps(
509
+ parseFloat(parsedData[9]),
510
+ parseFloat(parsedData[10])
511
+ ),
512
+ hdop: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
513
+ status: null,
514
+ azimuth: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
515
+ altitude: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
516
+ datetime: parsedData[11] !== '' ? utils.parseDate(parsedData[11]) : null,
517
+ voltage: {
518
+ battery: null,
519
+ inputCharge: null,
520
+ ada: null,
521
+ adb: null,
522
+ adc: null,
523
+ add: null
524
+ },
525
+ mcc: parsedData[12] !== '' ? parseInt(parsedData[12], 10) : null,
526
+ mnc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
527
+ lac: parsedData[14] !== '' ? parseInt(parsedData[14], 16) : null,
528
+ cid: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
529
+ odometer: parsedData[18] !== '' ? parseFloat(parsedData[18]) : null,
530
+ hourmeter:
531
+ parsedData[17] !== ''
532
+ ? utils.getHoursForHourmeter(parsedData[17])
533
+ : null
534
+ })
535
+ } else if (command[1] === 'GTIDN' || command[1] === 'GTIDF') {
536
+ data = Object.assign(data, {
537
+ alarm: utils.getAlarm(command[1], parsedData[5]),
538
+ loc: {
539
+ type: 'Point',
540
+ coordinates: [parseFloat(parsedData[10]), parseFloat(parsedData[11])]
541
+ },
542
+ speed: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
543
+ gpsStatus: utils.checkGps(
544
+ parseFloat(parsedData[10]),
545
+ parseFloat(parsedData[11])
546
+ ),
547
+ hdop: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
548
+ status: null,
549
+ azimuth: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
550
+ altitude: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
551
+ datetime: parsedData[12] !== '' ? utils.parseDate(parsedData[12]) : null,
552
+ voltage: {
553
+ battery: null,
554
+ inputCharge: null,
555
+ ada: null,
556
+ adb: null,
557
+ adc: null,
558
+ add: null
559
+ },
560
+ mcc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
561
+ mnc: parsedData[14] !== '' ? parseInt(parsedData[14], 10) : null,
562
+ lac: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
563
+ cid: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
564
+ odometer: parsedData[18] !== '' ? parseFloat(parsedData[18]) : null,
565
+ hourmeter: null
566
+ })
567
+ } else if (
568
+ command[1] === 'GTSTR' ||
569
+ command[1] === 'GTSTP' ||
570
+ command[1] === 'GTLSP'
571
+ ) {
572
+ data = Object.assign(data, {
573
+ alarm: utils.getAlarm(command[1], null),
574
+ loc: {
575
+ type: 'Point',
576
+ coordinates: [parseFloat(parsedData[10]), parseFloat(parsedData[11])]
577
+ },
578
+ speed: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
579
+ gpsStatus: utils.checkGps(
580
+ parseFloat(parsedData[10]),
581
+ parseFloat(parsedData[11])
582
+ ),
583
+ hdop: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
584
+ status: null,
585
+ azimuth: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
586
+ altitude: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
587
+ datetime: parsedData[12] !== '' ? utils.parseDate(parsedData[12]) : null,
588
+ voltage: {
589
+ battery: null,
590
+ inputCharge: null,
591
+ ada: null,
592
+ adb: null,
593
+ adc: null,
594
+ add: null
595
+ },
596
+ mcc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
597
+ mnc: parsedData[14] !== '' ? parseInt(parsedData[14], 10) : null,
598
+ lac: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
599
+ cid: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
600
+ odometer: parsedData[18] !== '' ? parseFloat(parsedData[18]) : null,
601
+ hourmeter: null
602
+ })
603
+ } else if (command[1] === 'GTSTT') {
604
+ // Motion State Changed
605
+ data = Object.assign(data, {
606
+ alarm: utils.getAlarm(command[1], null),
607
+ loc: {
608
+ type: 'Point',
609
+ coordinates: [parseFloat(parsedData[9]), parseFloat(parsedData[10])]
610
+ },
611
+ speed: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
612
+ gpsStatus: utils.checkGps(
613
+ parseFloat(parsedData[9]),
614
+ parseFloat(parsedData[10])
615
+ ),
616
+ hdop: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
617
+ status: null,
618
+ azimuth: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
619
+ altitude: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
620
+ datetime: parsedData[11] !== '' ? utils.parseDate(parsedData[11]) : null,
621
+ voltage: {
622
+ battery: null,
623
+ inputCharge: null,
624
+ ada: null,
625
+ adb: null,
626
+ adc: null,
627
+ add: null
628
+ },
629
+ mcc: parsedData[12] !== '' ? parseInt(parsedData[12], 10) : null,
630
+ mnc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
631
+ lac: parsedData[14] !== '' ? parseInt(parsedData[14], 16) : null,
632
+ cid: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
633
+ odometer: null,
634
+ hourmeter: null
635
+ })
636
+ } else if (command[1] === 'GTGPJ') {
637
+ data = Object.assign(data, {
638
+ alarm: utils.getAlarm(command[1], parsedData[5]),
639
+ loc: {
640
+ type: 'Point',
641
+ coordinates: [parseFloat(parsedData[10]), parseFloat(parsedData[11])]
642
+ },
643
+ speed: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
644
+ gpsStatus: utils.checkGps(
645
+ parseFloat(parsedData[10]),
646
+ parseFloat(parsedData[11])
647
+ ),
648
+ hdop: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
649
+ status: null,
650
+ azimuth: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
651
+ altitude: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
652
+ datetime: parsedData[12] !== '' ? utils.parseDate(parsedData[12]) : null,
653
+ voltage: {
654
+ battery: null,
655
+ inputCharge: null,
656
+ ada: null,
657
+ adb: null
658
+ },
659
+ mcc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
660
+ mnc: parsedData[14] !== '' ? parseInt(parsedData[14], 10) : null,
661
+ lac: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
662
+ cid: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
663
+ odometer: null,
664
+ hourmeter: null
665
+ })
666
+ } else if (command[1] === 'GTGSS') {
667
+ // GPS Status
668
+ data = Object.assign(data, {
669
+ alarm: utils.getAlarm(command[1], parsedData[4]),
670
+ loc: {
671
+ type: 'Point',
672
+ coordinates: [parseFloat(parsedData[12]), parseFloat(parsedData[13])]
673
+ },
674
+ speed: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
675
+ gpsStatus: utils.checkGps(
676
+ parseFloat(parsedData[12]),
677
+ parseFloat(parsedData[13])
678
+ ),
679
+ hdop: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
680
+ status: null,
681
+ azimuth: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
682
+ altitude: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
683
+ datetime: parsedData[14] !== '' ? utils.parseDate(parsedData[14]) : null,
684
+ voltage: {
685
+ battery: null,
686
+ inputCharge: null,
687
+ ada: null,
688
+ adb: null,
689
+ adc: null,
690
+ add: null
691
+ },
692
+ mcc: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null,
693
+ mnc: parsedData[16] !== '' ? parseInt(parsedData[16], 10) : null,
694
+ lac: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
695
+ cid: parsedData[18] !== '' ? parseInt(parsedData[18], 16) : null,
696
+ odometer: null,
697
+ hourmeter: null
698
+ })
699
+ } else if (command[1] === 'GTIDA') {
700
+ data = Object.assign(data, {
701
+ alarm: utils.getAlarm(command[1], `${parsedData[5]},${parsedData[6]}`),
702
+ loc: {
703
+ type: 'Point',
704
+ coordinates: [parseFloat(parsedData[12]), parseFloat(parsedData[13])]
705
+ },
706
+ speed: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
707
+ gpsStatus: utils.checkGps(
708
+ parseFloat(parsedData[12]),
709
+ parseFloat(parsedData[13])
710
+ ),
711
+ hdop: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
712
+ status: null,
713
+ azimuth: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
714
+ altitude: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
715
+ datetime: parsedData[14] !== '' ? utils.parseDate(parsedData[14]) : null,
716
+ voltage: {
717
+ battery: null,
718
+ inputCharge: null,
719
+ ada: null,
720
+ adb: null,
721
+ adc: null,
722
+ add: null
723
+ },
724
+ mcc: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null,
725
+ mnc: parsedData[16] !== '' ? parseInt(parsedData[16], 10) : null,
726
+ lac: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
727
+ cid: parsedData[18] !== '' ? parseInt(parsedData[18], 16) : null,
728
+ odometer: parsedData[20] !== '' ? parseFloat(parsedData[20]) : null,
729
+ hourmeter: null
730
+ })
731
+ } else if (command[1] === 'GTTMP') {
732
+ // Temperature Alarm
733
+ data = Object.assign(data, {
734
+ alarm: utils.getAlarm(command[1], parsedData[6], [
735
+ parsedData[30],
736
+ parsedData[32]
737
+ ]),
738
+ loc: {
739
+ type: 'Point',
740
+ coordinates: [parseFloat(parsedData[11]), parseFloat(parsedData[12])]
741
+ },
742
+ speed: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
743
+ gpsStatus: utils.checkGps(
744
+ parseFloat(parsedData[11]),
745
+ parseFloat(parsedData[12])
746
+ ),
747
+ hdop: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
748
+ status: {
749
+ // parsedData[24]
750
+ raw: parsedData[25] + parsedData[26],
751
+ sos: utils.nHexDigit(utils.hex2bin(parsedData[27]), 6)[4] === '1',
752
+ input: {
753
+ '1': utils.nHexDigit(utils.hex2bin(parsedData[27]), 6)[5] === '1',
754
+ '2': utils.nHexDigit(utils.hex2bin(parsedData[27]), 6)[4] === '1',
755
+ '3': utils.nHexDigit(utils.hex2bin(parsedData[27]), 6)[3] === '1',
756
+ '4': utils.nHexDigit(utils.hex2bin(parsedData[27]), 6)[2] === '1',
757
+ '5': utils.nHexDigit(utils.hex2bin(parsedData[27]), 6)[1] === '1',
758
+ '6': utils.nHexDigit(utils.hex2bin(parsedData[27]), 6)[0] === '1'
759
+ },
760
+ output: {
761
+ '1': utils.nHexDigit(utils.hex2bin(parsedData[27]), 5)[4] === '1',
762
+ '2': utils.nHexDigit(utils.hex2bin(parsedData[27]), 5)[3] === '1',
763
+ '3': utils.nHexDigit(utils.hex2bin(parsedData[27]), 5)[2] === '1',
764
+ '4': utils.nHexDigit(utils.hex2bin(parsedData[27]), 5)[1] === '1',
765
+ '5': utils.nHexDigit(utils.hex2bin(parsedData[27]), 5)[0] === '1'
766
+ },
767
+ charge: parseFloat(parsedData[4]) > 5
768
+ },
769
+ azimuth: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
770
+ altitude: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
771
+ datetime: parsedData[13] !== '' ? utils.parseDate(parsedData[13]) : null,
772
+ voltage: {
773
+ battery: null, // percentage
774
+ inputCharge:
775
+ parsedData[5] !== '' ? parseFloat(parsedData[4]) / 1000 : null,
776
+ ada: parsedData[21] !== '' ? parseFloat(parsedData[21]) / 1000 : null,
777
+ adb: parsedData[22] !== '' ? parseFloat(parsedData[22]) / 1000 : null,
778
+ adc: parsedData[23] !== '' ? parseFloat(parsedData[23]) / 1000 : null,
779
+ add: parsedData[24] !== '' ? parseFloat(parsedData[24]) / 1000 : null
780
+ },
781
+ mcc: parsedData[14] !== '' ? parseInt(parsedData[14], 10) : null,
782
+ mnc: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null,
783
+ lac: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
784
+ cid: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
785
+ odometer: parsedData[19] !== '' ? parseFloat(parsedData[19]) : null,
786
+ hourmeter:
787
+ parsedData[20] !== ''
788
+ ? utils.getHoursForHourmeter(parsedData[20])
789
+ : null
790
+ })
791
+ } else if (command[1] === 'GTCAN') {
792
+ data = Object.assign(data, {
793
+ alarm: utils.getAlarm(command[1], parsedData[4]),
794
+ loc: {
795
+ type: 'Point',
796
+ coordinates: [parseFloat(parsedData[59]), parseFloat(parsedData[60])]
797
+ },
798
+ speed: parsedData[56] !== '' ? parseFloat(parsedData[56]) : null,
799
+ gpsStatus: utils.checkGps(
800
+ parseFloat(parsedData[59]),
801
+ parseFloat(parsedData[60])
802
+ ),
803
+ hdop: parsedData[55] !== '' ? parseFloat(parsedData[55]) : null,
804
+ status: null,
805
+ azimuth: parsedData[57] !== '' ? parseFloat(parsedData[57]) : null,
806
+ altitude: parsedData[58] !== '' ? parseFloat(parsedData[58]) : null,
807
+ datetime: parsedData[61] !== '' ? utils.parseDate(parsedData[61]) : null,
808
+ voltage: {
809
+ battery: null,
810
+ inputCharge: null,
811
+ ada: null,
812
+ adb: null,
813
+ adc: null,
814
+ add: null
815
+ },
816
+ mcc: parsedData[62] !== '' ? parseInt(parsedData[62], 10) : null,
817
+ mnc: parsedData[63] !== '' ? parseInt(parsedData[63], 10) : null,
818
+ lac: parsedData[64] !== '' ? parseInt(parsedData[64], 16) : null,
819
+ cid: parsedData[65] !== '' ? parseInt(parsedData[65], 16) : null,
820
+ odometer: null,
821
+ hourmeter: null,
822
+ can: {
823
+ mask: '',
824
+ comunicationOk: parsedData[5] === '1',
825
+ vin: parsedData[7] !== '' ? parsedData[7] : null,
826
+ ignitionKey: parsedData[8] !== '' ? parseInt(parsedData[8], 10) : null,
827
+ distance: parsedData[9] !== '' ? parsedData[9] : null,
828
+ fuelUsed: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null, // float
829
+ rpm: parsedData[11] !== '' ? parseInt(parsedData[11], 10) : null, // int
830
+ speed: parsedData[12] !== '' ? parseFloat(parsedData[12]) : null,
831
+ coolantTemp:
832
+ parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
833
+ fuelConsumption: parsedData[14] !== '' ? parsedData[14] : null,
834
+ fuelLevel: parsedData[15] !== '' ? parsedData[15] : null,
835
+ range: parsedData[16] !== '' ? parsedData[16] : null,
836
+ acceleratorPressure:
837
+ parsedData[17] !== '' ? parseFloat(parsedData[17]) : null, // %
838
+ engineHours: parsedData[18] !== '' ? parseFloat(parsedData[18]) : null, // hours
839
+ drivingTime: parsedData[19] !== '' ? parseFloat(parsedData[19]) : null, // hours
840
+ idleTime: parsedData[20] !== '' ? parseFloat(parsedData[20]) : null, // hours
841
+ idleFuelUsed: parsedData[21] !== '' ? parseFloat(parsedData[21]) : null, // liters
842
+ axleWight: parsedData[22] !== '' ? parseFloat(parsedData[22]) : null, // kg
843
+ tachograph: parsedData[23] !== '' ? parsedData[23] : null,
844
+ detailedInfo: parsedData[24] !== '' ? parsedData[24] : null,
845
+ lights: parsedData[25] !== '' ? parsedData[25] : null,
846
+ doors: parsedData[26] !== '' ? parsedData[26] : null,
847
+ overSpeedTime:
848
+ parsedData[27] !== '' ? parseFloat(parsedData[27]) : null, // hours
849
+ overSpeedEngineTime:
850
+ parsedData[28] !== '' ? parseFloat(parsedData[28]) : null, // hours
851
+ expansionMask: parsedData[29] !== '' ? parsedData[29] : null,
852
+ addBlueLevel: parsedData[30] !== '' ? parsedData[30] : null,
853
+ axleWight1st: parsedData[31] !== '' ? parsedData[31] : null,
854
+ axleWight3rd: parsedData[32] !== '' ? parsedData[32] : null,
855
+ axleWight4rd: parsedData[33] !== '' ? parsedData[33] : null,
856
+ tachographOverSpeedSignal:
857
+ parsedData[34] !== '' ? parsedData[34] : null,
858
+ tachographMotionState: parsedData[35] !== '' ? parsedData[35] : null,
859
+ tachographDrivingDirection:
860
+ parsedData[36] !== '' ? parsedData[36] : null,
861
+ analogInput: parsedData[37] !== '' ? parsedData[37] : null,
862
+ engineBrakingFactor: parsedData[38] !== '' ? parsedData[38] : null,
863
+ pedalBrakingFactor: parsedData[39] !== '' ? parsedData[39] : null,
864
+ totalAcceleratorKickDowns:
865
+ parsedData[40] !== '' ? parseInt(parsedData[40], 10) : null,
866
+ totalEffectiveEngineSpeedTime:
867
+ parsedData[41] !== '' ? parseFloat(parsedData[41]) : null, // hours
868
+ totalCruiseControlTime:
869
+ parsedData[42] !== '' ? parseFloat(parsedData[42]) : null, // hours
870
+ totalAcceleratorKickDownTime:
871
+ parsedData[43] !== '' ? parseFloat(parsedData[43]) : null, // hours
872
+ totalBrakeApplications:
873
+ parsedData[44] !== '' ? parseInt(parsedData[44]) : null,
874
+ tachographDriver1Number: parsedData[45] !== '' ? parsedData[45] : null,
875
+ tachographDriver2Number: parsedData[46] !== '' ? parsedData[46] : null,
876
+ tachographDriver1Name: parsedData[47] !== '' ? parsedData[47] : null,
877
+ tachographDriver2Name: parsedData[48] !== '' ? parsedData[48] : null,
878
+ registrationNumber: parsedData[49] !== '' ? parsedData[49] : null,
879
+ expansionInformation: parsedData[50] !== '' ? parsedData[50] : null,
880
+ rapidBraking: parsedData[51] !== '' ? parsedData[51] : null,
881
+ rapidAccelerations: parsedData[52] !== '' ? parsedData[52] : null
882
+ }
883
+ })
884
+ } else if (command[1] === 'GTDAT') {
885
+ if (parsedData.length > 8) {
886
+ // Long format
887
+ data = Object.assign(data, {
888
+ loc: {
889
+ type: 'Point',
890
+ coordinates: [parseFloat(parsedData[12]), parseFloat(parsedData[13])]
891
+ },
892
+ speed: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
893
+ gpsStatus: utils.checkGps(
894
+ parseFloat(parsedData[12]),
895
+ parseFloat(parsedData[13])
896
+ ),
897
+ hdop: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
898
+ status: null,
899
+ azimuth: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
900
+ altitude: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
901
+ datetime:
902
+ parsedData[14] !== '' ? utils.parseDate(parsedData[14]) : null,
903
+ voltage: {
904
+ battery: null,
905
+ inputCharge: null,
906
+ ada: null,
907
+ adb: null,
908
+ adc: null,
909
+ add: null
910
+ },
911
+ mcc: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null,
912
+ mnc: parsedData[16] !== '' ? parseInt(parsedData[16], 10) : null,
913
+ lac: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
914
+ cid: parsedData[18] !== '' ? parseInt(parsedData[18], 16) : null,
915
+ odometer: null,
916
+ hourmeter: null,
917
+ serialData: parsedData[7] !== '' ? parsedData[7] : null
918
+ })
919
+ } else {
920
+ // Short format
921
+ data = Object.assign(data, {
922
+ loc: null,
923
+ speed: null,
924
+ gpsStatus: null,
925
+ hdop: null,
926
+ status: null,
927
+ azimuth: null,
928
+ altitude: null,
929
+ datetime: null,
930
+ voltage: null,
931
+ mcc: null,
932
+ mnc: null,
933
+ lac: null,
934
+ cid: null,
935
+ odometer: null,
936
+ hourmeter: null,
937
+ serialData: parsedData[4] !== '' ? parsedData[4] : null
938
+ })
939
+ }
940
+
941
+ data = Object.assign(data, {
942
+ alarm: utils.getAlarm(command[1], null)
943
+ })
944
+ } else if (command[1] === 'GTDOS') {
945
+ data = Object.assign(data, {
946
+ alarm: utils.getAlarm(command[1], `${parsedData[4]},${parsedData[5]}`),
947
+ loc: {
948
+ type: 'Point',
949
+ coordinates: [parseFloat(parsedData[10]), parseFloat(parsedData[11])]
950
+ },
951
+ speed: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
952
+ gpsStatus: utils.checkGps(
953
+ parseFloat(parsedData[10]),
954
+ parseFloat(parsedData[11])
955
+ ),
956
+ hdop: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
957
+ status: null,
958
+ azimuth: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
959
+ altitude: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
960
+ datetime: parsedData[12] !== '' ? utils.parseDate(parsedData[12]) : null,
961
+ voltage: {
962
+ battery: null,
963
+ inputCharge: null,
964
+ ada: null,
965
+ adb: null,
966
+ adc: null,
967
+ add: null
968
+ },
969
+ mcc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
970
+ mnc: parsedData[14] !== '' ? parseInt(parsedData[14], 10) : null,
971
+ lac: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
972
+ cid: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
973
+ odometer: null,
974
+ hourmeter: null
975
+ })
976
+ } else {
977
+ data = Object.assign(data, {
978
+ alarm: utils.getAlarm(command[1], null)
979
+ })
980
+ }
981
+ // Check gps data
982
+ if (data.loc !== null && typeof data.loc !== 'undefined') {
983
+ if (
984
+ data.loc.coordinates[0] === 0 ||
985
+ isNaN(data.loc.coordinates[0]) ||
986
+ data.loc.coordinates[1] === 0 ||
987
+ isNaN(data.loc.coordinates[1])
988
+ ) {
989
+ data.loc = null
990
+ }
991
+ }
992
+ return data
993
+ }
994
+
995
+ module.exports = {
996
+ parse: parse
997
+ }