queclink-parser 1.9.25 → 1.9.26

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.
@@ -0,0 +1,3053 @@
1
+ 'use strict'
2
+ const utils = require('./utils.js')
3
+
4
+ /*
5
+ Parses messages data from GV350CEU 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-GV350CEU',
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
+ // Gps
31
+ if (command[1] === 'GTFRI') {
32
+ try {
33
+ let number = parsedData[6] !== '' ? parseInt(parsedData[6], 10) : 1
34
+ let satelliteInfo = utils.includeSatellites(parsedData[18])
35
+ let gnnsTriggerType = utils.includeGnssTrigger(parsedData[18])
36
+ let jammingSate = utils.includeJammingSate(parsedData[18])
37
+ let index =
38
+ 6 + (12 + satelliteInfo + gnnsTriggerType + jammingSate) * number
39
+
40
+ data = Object.assign(data, {
41
+ alarm: utils.getAlarm(command[1], null),
42
+ loc: {
43
+ type: 'Point',
44
+ coordinates: [parseFloat(parsedData[11]), parseFloat(parsedData[12])]
45
+ },
46
+ speed: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
47
+ gpsStatus: utils.checkGps(
48
+ parseFloat(parsedData[11]),
49
+ parseFloat(parsedData[12])
50
+ ),
51
+ hdop: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
52
+ status: {
53
+ raw: parsedData[index + 7],
54
+ sos: false,
55
+ input: {
56
+ '1':
57
+ utils.nHexDigit(
58
+ utils.hex2bin(
59
+ utils.nHexDigit(parsedData[index + 7], 10).substring(6, 8)
60
+ ),
61
+ 4
62
+ )[3] === '1',
63
+ '2':
64
+ utils.nHexDigit(
65
+ utils.hex2bin(
66
+ utils.nHexDigit(parsedData[index + 7], 10).substring(6, 8)
67
+ ),
68
+ 4
69
+ )[2] === '1',
70
+ '3':
71
+ utils.nHexDigit(
72
+ utils.hex2bin(
73
+ utils.nHexDigit(parsedData[index + 7], 10).substring(6, 8)
74
+ ),
75
+ 4
76
+ )[1] === '1',
77
+ '4':
78
+ utils.nHexDigit(
79
+ utils.hex2bin(
80
+ utils.nHexDigit(parsedData[index + 7], 10).substring(6, 8)
81
+ ),
82
+ 4
83
+ )[0] === '1'
84
+ },
85
+ output: {
86
+ '1':
87
+ utils.nHexDigit(
88
+ utils.hex2bin(
89
+ utils.nHexDigit(parsedData[index + 7], 10).substring(8, 10)
90
+ ),
91
+ 3
92
+ )[2] === '1',
93
+ '2':
94
+ utils.nHexDigit(
95
+ utils.hex2bin(
96
+ utils.nHexDigit(parsedData[index + 7], 10).substring(8, 10)
97
+ ),
98
+ 3
99
+ )[1] === '1',
100
+ '3':
101
+ utils.nHexDigit(
102
+ utils.hex2bin(
103
+ utils.nHexDigit(parsedData[index + 7], 10).substring(8, 10)
104
+ ),
105
+ 3
106
+ )[0] === '1'
107
+ },
108
+ charge: parseFloat(parsedData[4]) > 5,
109
+ state:
110
+ utils.nHexDigit(parsedData[index + 7], 10).substring(4, 6) !== ''
111
+ ? utils.states[ // eslint-disable-line
112
+ utils.nHexDigit(parsedData[index + 7], 10).substring(4, 6)
113
+ ]
114
+ : null
115
+ },
116
+ azimuth: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
117
+ altitude: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
118
+ datetime:
119
+ parsedData[13] !== '' ? utils.parseDate(parsedData[13]) : null,
120
+ voltage: {
121
+ battery:
122
+ parsedData[index + 6] !== ''
123
+ ? parseFloat(parsedData[index + 6])
124
+ : null, // percentage
125
+ inputCharge:
126
+ parsedData[4] !== '' ? parseFloat(parsedData[4]) / 1000 : null,
127
+ ada:
128
+ parsedData[index + 3] !== ''
129
+ ? parseFloat(parsedData[index + 3]) / 1000
130
+ : null,
131
+ adb:
132
+ parsedData[index + 4] !== ''
133
+ ? parseFloat(parsedData[index + 4]) / 1000
134
+ : null,
135
+ adc:
136
+ parsedData[index + 5] !== ''
137
+ ? parseFloat(parsedData[index + 5]) / 1000
138
+ : null
139
+ },
140
+ mcc:
141
+ parsedData[14] !== ''
142
+ ? utils.latamMcc[parseInt(parsedData[14], 10)]
143
+ : null,
144
+ mnc:
145
+ parsedData[15] !== ''
146
+ ? utils.getMNC(parsedData[14], parsedData[15])
147
+ : null,
148
+ lac: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
149
+ cid: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
150
+ satellites:
151
+ satelliteInfo &&
152
+ parsedData[
153
+ index - (satelliteInfo + gnnsTriggerType + jammingSate) + 1
154
+ ] !== ''
155
+ ? parseInt(
156
+ parsedData[
157
+ index - (satelliteInfo + gnnsTriggerType + jammingSate) + 1
158
+ ],
159
+ 10
160
+ )
161
+ : null,
162
+ triggerType:
163
+ gnnsTriggerType &&
164
+ parsedData[index - (jammingSate + gnnsTriggerType) + 1] !== ''
165
+ ? utils.gnssTriggerTypes[
166
+ parsedData[index - (jammingSate + gnnsTriggerType) + 1]
167
+ ]
168
+ : null,
169
+ jammingSate:
170
+ jammingSate && parsedData[index - jammingSate + 1] !== ''
171
+ ? utils.jammingSateTypes[parsedData[index - jammingSate + 1]]
172
+ : null,
173
+ odometer:
174
+ parsedData[index + 1] !== ''
175
+ ? parseFloat(parsedData[index + 1])
176
+ : null,
177
+ hourmeter:
178
+ parsedData[index + 2] !== ''
179
+ ? utils.getHoursForHourmeter(parsedData[index + 2])
180
+ : null
181
+ })
182
+
183
+ // More than 1 GNSS report in data
184
+ if (number > 1) {
185
+ let moreData = []
186
+ for (let i = 1; i < number; i++) {
187
+ let gnssIx =
188
+ 7 + (12 + satelliteInfo + gnnsTriggerType + jammingSate) * i
189
+ moreData.push({
190
+ index: i,
191
+ loc: {
192
+ type: 'Point',
193
+ coordinates: [
194
+ parseFloat(parsedData[gnssIx + 4]),
195
+ parseFloat(parsedData[gnssIx + 5])
196
+ ]
197
+ },
198
+ speed:
199
+ parsedData[gnssIx + 1] !== ''
200
+ ? parseFloat(parsedData[gnssIx + 1])
201
+ : null,
202
+ gpsStatus: utils.checkGps(
203
+ parseFloat(parsedData[gnssIx + 4]),
204
+ parseFloat(parsedData[gnssIx + 5])
205
+ ),
206
+ hdop:
207
+ parsedData[gnssIx] !== '' ? parseFloat(parsedData[gnssIx]) : null,
208
+ azimuth:
209
+ parsedData[gnssIx + 2] !== ''
210
+ ? parseFloat(parsedData[gnssIx + 2])
211
+ : null,
212
+ altitude:
213
+ parsedData[gnssIx + 3] !== ''
214
+ ? parseFloat(parsedData[gnssIx + 3])
215
+ : null,
216
+ datetime:
217
+ parsedData[gnssIx + 6] !== ''
218
+ ? utils.parseDate(parsedData[gnssIx + 6])
219
+ : null,
220
+ mcc:
221
+ parsedData[gnssIx + 7] !== ''
222
+ ? parseInt(parsedData[gnssIx + 7], 10)
223
+ : null,
224
+ mnc:
225
+ parsedData[gnssIx + 8] !== ''
226
+ ? parseInt(parsedData[gnssIx + 8], 10)
227
+ : null,
228
+ lac:
229
+ parsedData[gnssIx + 9] !== ''
230
+ ? parseInt(parsedData[gnssIx + 9], 16)
231
+ : null,
232
+ cid:
233
+ parsedData[gnssIx + 10] !== ''
234
+ ? parseInt(parsedData[gnssIx + 10], 16)
235
+ : null,
236
+ satellites:
237
+ satelliteInfo &&
238
+ parsedData[
239
+ gnssIx + (satelliteInfo + gnnsTriggerType + jammingSate) + 12
240
+ ] !== ''
241
+ ? parseInt(parsedData[gnssIx + 12], 10)
242
+ : null,
243
+ gnssTriggerType:
244
+ gnnsTriggerType &&
245
+ parsedData[gnssIx + (jammingSate + gnnsTriggerType) + 1] !== ''
246
+ ? utils.gnssTriggerTypes[
247
+ parsedData[gnssIx + (jammingSate + gnnsTriggerType) + 1]
248
+ ]
249
+ : null,
250
+ jammingSate:
251
+ jammingSate && parsedData[gnssIx + jammingSate + 1] !== ''
252
+ ? utils.jammingSateTypes[parsedData[gnssIx + jammingSate + 1]]
253
+ : null
254
+ })
255
+ }
256
+
257
+ data = Object.assign(data, { moreData: moreData })
258
+ }
259
+ } catch (err) {
260
+ return { type: 'UNKNOWN', raw: data.raw.toString() }
261
+ }
262
+ } else if (command[1] === 'GTERI') {
263
+ // GPS with AC100 and/or Bluetoth Devices Connected
264
+ let number = parsedData[7] !== '' ? parseInt(parsedData[7], 10) : 1
265
+ let satelliteInfo = utils.includeSatellites(parsedData[18])
266
+ let gnnsTriggerType = utils.includeGnssTrigger(parsedData[18])
267
+ let jammingSate = utils.includeJammingSate(parsedData[18])
268
+ let index =
269
+ 7 + (12 + satelliteInfo + gnnsTriggerType + jammingSate) * number
270
+
271
+ // External Data
272
+ const digitFuelSensor =
273
+ utils.nHexDigit(utils.hex2bin(parsedData[4]), 11)[10] === '1'
274
+ const AC100 = utils.nHexDigit(utils.hex2bin(parsedData[4]), 11)[9] === '1'
275
+ const canData = utils.nHexDigit(utils.hex2bin(parsedData[4]), 11)[8] === '1'
276
+ const fuelLevelPercentage =
277
+ utils.nHexDigit(utils.hex2bin(parsedData[4]), 11)[7] === '1'
278
+ const fuelVolume =
279
+ utils.nHexDigit(utils.hex2bin(parsedData[4]), 11)[6] === '1'
280
+ const bluetoothAccessory =
281
+ utils.nHexDigit(utils.hex2bin(parsedData[4]), 11)[2] === '1'
282
+
283
+ data = Object.assign(data, {
284
+ alarm: utils.getAlarm(command[1], null),
285
+ loc: {
286
+ type: 'Point',
287
+ coordinates: [parseFloat(parsedData[12]), parseFloat(parsedData[13])]
288
+ },
289
+ speed: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
290
+ gpsStatus: utils.checkGps(
291
+ parseFloat(parsedData[12]),
292
+ parseFloat(parsedData[13])
293
+ ),
294
+ hdop: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
295
+ status: {
296
+ // parsedData[index + 7]
297
+ raw: parsedData[index + 7],
298
+ sos: false,
299
+ input: {
300
+ '1':
301
+ utils.nHexDigit(
302
+ utils.hex2bin(
303
+ utils.nHexDigit(parsedData[index + 7], 10).substring(6, 8)
304
+ ),
305
+ 4
306
+ )[3] === '1',
307
+ '2':
308
+ utils.nHexDigit(
309
+ utils.hex2bin(
310
+ utils.nHexDigit(parsedData[index + 7], 10).substring(6, 8)
311
+ ),
312
+ 4
313
+ )[2] === '1',
314
+ '3':
315
+ utils.nHexDigit(
316
+ utils.hex2bin(
317
+ utils.nHexDigit(parsedData[index + 7], 10).substring(6, 8)
318
+ ),
319
+ 4
320
+ )[1] === '1',
321
+ '4':
322
+ utils.nHexDigit(
323
+ utils.hex2bin(
324
+ utils.nHexDigit(parsedData[index + 7], 10).substring(6, 8)
325
+ ),
326
+ 4
327
+ )[0] === '1'
328
+ },
329
+ output: {
330
+ '1':
331
+ utils.nHexDigit(
332
+ utils.hex2bin(
333
+ utils.nHexDigit(parsedData[index + 7], 10).substring(8, 10)
334
+ ),
335
+ 3
336
+ )[2] === '1',
337
+ '2':
338
+ utils.nHexDigit(
339
+ utils.hex2bin(
340
+ utils.nHexDigit(parsedData[index + 7], 10).substring(8, 10)
341
+ ),
342
+ 3
343
+ )[1] === '1',
344
+ '3':
345
+ utils.nHexDigit(
346
+ utils.hex2bin(
347
+ utils.nHexDigit(parsedData[index + 7], 10).substring(8, 10)
348
+ ),
349
+ 3
350
+ )[0] === '1'
351
+ },
352
+ charge: parseFloat(parsedData[5]) > 5,
353
+ state:
354
+ utils.nHexDigit(parsedData[index + 7], 10).substring(4, 6) !== ''
355
+ ? utils.states[ // eslint-disable-line
356
+ utils.nHexDigit(parsedData[index + 7], 10).substring(4, 6)
357
+ ]
358
+ : null
359
+ },
360
+ azimuth: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
361
+ altitude: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
362
+ datetime: parsedData[14] !== '' ? utils.parseDate(parsedData[14]) : null,
363
+ voltage: {
364
+ battery:
365
+ parsedData[index + 6] !== ''
366
+ ? parseFloat(parsedData[index + 6])
367
+ : null, // percentage
368
+ inputCharge:
369
+ parsedData[5] !== '' ? parseFloat(parsedData[5]) / 1000 : null,
370
+ ada:
371
+ parsedData[index + 3] !== ''
372
+ ? parseFloat(parsedData[index + 3]) / 1000
373
+ : null,
374
+ adb:
375
+ parsedData[index + 4] !== ''
376
+ ? parseFloat(parsedData[index + 4]) / 1000
377
+ : null,
378
+ adc:
379
+ parsedData[index + 5] !== ''
380
+ ? parseFloat(parsedData[index + 5]) / 1000
381
+ : null
382
+ },
383
+ mcc:
384
+ parsedData[15] !== ''
385
+ ? utils.latamMcc[parseInt(parsedData[15], 10)]
386
+ : null,
387
+ mnc:
388
+ parsedData[16] !== ''
389
+ ? utils.getMNC(parsedData[15], parsedData[16])
390
+ : null,
391
+ lac: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
392
+ cid: parsedData[18] !== '' ? parseInt(parsedData[18], 16) : null,
393
+ satellites:
394
+ satelliteInfo &&
395
+ parsedData[
396
+ index - (satelliteInfo + gnnsTriggerType + jammingSate) + 1
397
+ ] !== ''
398
+ ? parseInt(
399
+ parsedData[
400
+ index - (satelliteInfo + gnnsTriggerType + jammingSate) + 1
401
+ ]
402
+ )
403
+ : null,
404
+ triggerType:
405
+ gnnsTriggerType &&
406
+ parsedData[index - (jammingSate + gnnsTriggerType) + 1] !== ''
407
+ ? utils.gnssTriggerTypes[
408
+ parsedData[index - (jammingSate + gnnsTriggerType) + 1]
409
+ ]
410
+ : null,
411
+ jammingSate:
412
+ jammingSate && parsedData[index - jammingSate + 1] !== ''
413
+ ? utils.jammingSateTypes[parsedData[index - jammingSate + 1]]
414
+ : null,
415
+ odometer:
416
+ parsedData[index + 1] !== '' ? parseFloat(parsedData[index + 1]) : null,
417
+ hourmeter:
418
+ parsedData[index + 2] !== ''
419
+ ? utils.getHoursForHourmeter(parsedData[index + 2])
420
+ : null
421
+ })
422
+
423
+ const fuelSensorData = digitFuelSensor ? parsedData[index + 9] : null
424
+ const ac100DevicesConnected =
425
+ AC100 && digitFuelSensor
426
+ ? parseInt(parsedData[index + 10], 10)
427
+ : AC100 && !digitFuelSensor ? parseInt(parsedData[index + 9], 10) : 0
428
+ // Review when RF433 devices are implemented
429
+ // eslint-disable-next-line no-unused-vars
430
+ const rf433DevicesConnected =
431
+ parsedData[index + 8] === '7' ? parseInt(parsedData[index + 9]) : 0
432
+
433
+ let externalData = {
434
+ eriMask: {
435
+ raw: parsedData[4],
436
+ digitFuelSensor: digitFuelSensor,
437
+ AC100: AC100,
438
+ canData: canData,
439
+ fuelLevelPercentage: fuelLevelPercentage,
440
+ fuelVolume: fuelVolume,
441
+ bluetoothAccessory: bluetoothAccessory
442
+ },
443
+ uartDeviceType:
444
+ parsedData[index + 8] !== ''
445
+ ? utils.uartDeviceTypes[parsedData[index + 8]]
446
+ : null
447
+ }
448
+
449
+ if (parsedData[index + 8] === '1') {
450
+ // Fuel Sensor
451
+ if (digitFuelSensor && !AC100) {
452
+ externalData = Object.assign(externalData, {
453
+ fuelSensorData: {
454
+ data: fuelSensorData,
455
+ sensorType: parsedData[index + 11],
456
+ percentage:
457
+ fuelLevelPercentage && parsedData[index + 12] !== ''
458
+ ? parseInt(parsedData[index + 12], 10)
459
+ : null,
460
+ volume:
461
+ fuelVolume && fuelLevelPercentage && parsedData[index + 12] !== ''
462
+ ? parseInt(parsedData[index + 13], 10)
463
+ : fuelVolume &&
464
+ !fuelLevelPercentage &&
465
+ parsedData[index + 12] !== ''
466
+ ? parseInt(parsedData[index + 12], 10)
467
+ : null
468
+ },
469
+ AC100Devices: null
470
+ })
471
+ } else if (!digitFuelSensor && AC100) {
472
+ let ac100Devices = []
473
+ let count = index + 11
474
+ for (var i = 0; i < ac100DevicesConnected; i++) {
475
+ ac100Devices.push({
476
+ deviceNumber: parsedData[count],
477
+ deviceType: parsedData[count + 1],
478
+ deviceData: parsedData[count + 2]
479
+ ? utils.getTempInCelciousDegrees(parsedData[count + 2])
480
+ : null
481
+ })
482
+ count += 3
483
+ }
484
+
485
+ externalData = Object.assign(externalData, {
486
+ fuelSensorData: null,
487
+ AC100Devices: ac100Devices
488
+ })
489
+ } else if (digitFuelSensor && AC100) {
490
+ let ac100Devices = []
491
+ let count =
492
+ fuelVolume && fuelLevelPercentage
493
+ ? 33
494
+ : fuelVolume && !fuelLevelPercentage ? index + 13 : index + 12
495
+ for (var j = 0; j < ac100DevicesConnected; j++) {
496
+ ac100Devices.push({
497
+ deviceNumber: parsedData[count],
498
+ deviceType: parsedData[count + 1],
499
+ deviceData: parsedData[count + 2]
500
+ ? utils.getTempInCelciousDegrees(parsedData[count + 2])
501
+ : null
502
+ })
503
+ count += 3
504
+ }
505
+ externalData = Object.assign(externalData, {
506
+ fuelSensorData: {
507
+ data: fuelSensorData,
508
+ sensorType: parsedData[index + 11],
509
+ percentage:
510
+ fuelLevelPercentage && parsedData[index + 12] !== ''
511
+ ? parseInt(parsedData[index + 12], 10)
512
+ : null,
513
+ volume:
514
+ fuelVolume && fuelLevelPercentage && parsedData[index + 13] !== ''
515
+ ? parseInt(parsedData[index + 13], 10)
516
+ : fuelVolume &&
517
+ !fuelLevelPercentage &&
518
+ parsedData[index + 12] !== ''
519
+ ? parseInt(parsedData[index + 12], 10)
520
+ : null
521
+ },
522
+ AC100Devices: ac100Devices
523
+ })
524
+ }
525
+ } else if (parsedData[index + 8] === '2') {
526
+ // AC100 1 Wire Bus
527
+ if (!digitFuelSensor && AC100) {
528
+ let ac100Devices = []
529
+ let count = index + 10
530
+ for (var k = 0; k < ac100DevicesConnected; k++) {
531
+ ac100Devices.push({
532
+ deviceNumber: parsedData[count],
533
+ deviceType: parsedData[count + 1],
534
+ deviceData: parsedData[count + 2]
535
+ ? utils.getTempInCelciousDegrees(parsedData[count + 2])
536
+ : null
537
+ })
538
+ count += 3
539
+ }
540
+ externalData = Object.assign(externalData, {
541
+ fuelSensorData: null,
542
+ AC100Devices: ac100Devices
543
+ })
544
+ } else if (digitFuelSensor && !AC100) {
545
+ externalData = Object.assign(externalData, {
546
+ fuelSensorData: {
547
+ data: fuelSensorData,
548
+ sensorType: null,
549
+ percentage: null,
550
+ volume: null
551
+ },
552
+ AC100Devices: null
553
+ })
554
+ } else if (digitFuelSensor && AC100) {
555
+ let ac100Devices = []
556
+ let count = index + 12
557
+ for (var l = 0; l < ac100DevicesConnected; l++) {
558
+ ac100Devices.push({
559
+ deviceNumber: parsedData[count],
560
+ deviceType: parsedData[count + 1],
561
+ deviceData: parsedData[count + 2]
562
+ ? utils.getTempInCelciousDegrees(parsedData[count + 2])
563
+ : null
564
+ })
565
+ count += 3
566
+ }
567
+ externalData = Object.assign(externalData, {
568
+ fuelSensorData: {
569
+ data: fuelSensorData,
570
+ sensorType: null,
571
+ percentage: null,
572
+ volume: null
573
+ },
574
+ AC100Devices: ac100Devices
575
+ })
576
+ }
577
+ // } else if (parsedData[index + 8] === '7') {
578
+ // index += 1
579
+ // // RF433 Devices
580
+ // let rf433Devices = []
581
+ // // Review when RF433 devices are implemented
582
+ // let count = index + 9
583
+ // for (var l = 0; l < rf433DevicesConnected; l++) {
584
+ // rf433Devices.push({
585
+ // // deviceNumber: parsedData[count],
586
+ // // deviceType: parsedData[count + 1],
587
+ // // deviceData: parsedData[count + 2]
588
+ // // ? utils.getTempInCelciousDegrees(parsedData[count + 2])
589
+ // // : null
590
+ // deviceData: parsedData[count]
591
+ // })
592
+ // count += 1
593
+ // // count += 3
594
+ // }
595
+ // externalData = Object.assign(externalData, {
596
+ // rf433Devices: rf433Devices
597
+ // })
598
+ }
599
+
600
+ if (canData) {
601
+ let newIndex =
602
+ digitFuelSensor && !AC100
603
+ ? index + 9 + 1
604
+ : !digitFuelSensor && AC100
605
+ ? index + 9 + 4
606
+ : digitFuelSensor && AC100 ? index + 9 + 5 : index + 9
607
+ let parsedCanData = utils.getCanData(parsedData, newIndex, command[1], {
608
+ deviceType: 'GV350CEU'
609
+ })
610
+ let canInfo = parsedCanData[3]
611
+ index = parsedCanData[0]
612
+ if (Object.keys(canInfo).length > 0) {
613
+ data = Object.assign(data, { can: canInfo })
614
+ // index = parsedCanData[0]
615
+
616
+ if (canInfo && canInfo.comunicationOk) {
617
+ if (typeof canInfo.totalDistance === 'number') {
618
+ data.gpsOdometer = data.odometer
619
+ data.odometer = canInfo.totalDistance
620
+ }
621
+
622
+ if (typeof canInfo.engineHours === 'number') {
623
+ data.gpsHourmeter = data.hourmeter
624
+ data.hourmeter = canInfo.engineHours
625
+ }
626
+
627
+ if (typeof canInfo.speed === 'number' && canInfo.speed > 0) {
628
+ data.gpsSpeed = data.speed
629
+ data.speed = canInfo.speed
630
+ }
631
+ }
632
+ }
633
+ }
634
+
635
+ // Bluetooth Accessories
636
+ if (bluetoothAccessory) {
637
+ // let btIndex = digitFuelSensor ? index + 1 : index
638
+ let btIndex = canData ? index : index + 9
639
+ let btDevices = utils.getBleData(parsedData, btIndex)
640
+ externalData = Object.assign(externalData, {
641
+ btDevices: btDevices
642
+ })
643
+ }
644
+
645
+ data = Object.assign(data, {
646
+ externalData: externalData
647
+ })
648
+
649
+ // More than 1 GNSS report in data
650
+ if (number > 1) {
651
+ let moreData = []
652
+ const optionalLen = satelliteInfo + gnnsTriggerType + jammingSate
653
+ for (let i = 1; i < number; i++) {
654
+ let gnssIx = 7 + (12 + optionalLen) * i
655
+ moreData.push({
656
+ index: i,
657
+ loc: {
658
+ type: 'Point',
659
+ coordinates: [
660
+ parseFloat(parsedData[gnssIx + 4]),
661
+ parseFloat(parsedData[gnssIx + 5])
662
+ ]
663
+ },
664
+ speed:
665
+ parsedData[gnssIx + 1] !== ''
666
+ ? parseFloat(parsedData[gnssIx + 1])
667
+ : null,
668
+ gpsStatus: utils.checkGps(
669
+ parseFloat(parsedData[gnssIx + 4]),
670
+ parseFloat(parsedData[gnssIx + 5])
671
+ ),
672
+ hdop:
673
+ parsedData[gnssIx] !== '' ? parseFloat(parsedData[gnssIx]) : null,
674
+ azimuth:
675
+ parsedData[gnssIx + 2] !== ''
676
+ ? parseFloat(parsedData[gnssIx + 2])
677
+ : null,
678
+ altitude:
679
+ parsedData[gnssIx + 3] !== ''
680
+ ? parseFloat(parsedData[gnssIx + 3])
681
+ : null,
682
+ datetime:
683
+ parsedData[gnssIx + 6] !== ''
684
+ ? utils.parseDate(parsedData[gnssIx + 6])
685
+ : null,
686
+ mcc:
687
+ parsedData[gnssIx + 7] !== ''
688
+ ? parseInt(parsedData[gnssIx + 7], 10)
689
+ : null,
690
+ mnc:
691
+ parsedData[gnssIx + 8] !== ''
692
+ ? parseInt(parsedData[gnssIx + 8], 10)
693
+ : null,
694
+ lac:
695
+ parsedData[gnssIx + 9] !== ''
696
+ ? parseInt(parsedData[gnssIx + 9], 16)
697
+ : null,
698
+ cid:
699
+ parsedData[gnssIx + 10] !== ''
700
+ ? parseInt(parsedData[gnssIx + 10], 16)
701
+ : null,
702
+ satellites:
703
+ satelliteInfo && parsedData[gnssIx + 12] !== ''
704
+ ? parseInt(parsedData[gnssIx + 12], 10)
705
+ : null,
706
+ triggerType:
707
+ gnnsTriggerType && parsedData[gnssIx + 12 + satelliteInfo] !== ''
708
+ ? utils.gnssTriggerTypes[parsedData[gnssIx + 12 + satelliteInfo]]
709
+ : null,
710
+ jammingSate:
711
+ jammingSate &&
712
+ parsedData[gnssIx + 12 + satelliteInfo + gnnsTriggerType] !== ''
713
+ ? utils.jammingSateTypes[
714
+ parsedData[gnssIx + 12 + satelliteInfo + gnnsTriggerType]
715
+ ]
716
+ : null
717
+ })
718
+ }
719
+
720
+ data = Object.assign(data, { moreData: moreData })
721
+ }
722
+ } else if (command[1] === 'GTHBD') {
723
+ // Heartbeat. It must response an ACK command
724
+ data = Object.assign(data, {
725
+ alarm: utils.getAlarm(command[1], null)
726
+ })
727
+ } else if (command[1] === 'GTINF') {
728
+ // General Info Report
729
+ data = Object.assign(data, {
730
+ alarm: utils.getAlarm(command[1], null),
731
+ state: utils.states[parsedData[4]],
732
+ gsmInfo: {
733
+ SIM_ICC: parsedData[5] !== '' ? parsedData[5] : null,
734
+ networkType:
735
+ parsedData[10] !== '' ? utils.networkTypes[parsedData[10]] : null,
736
+ RSSI: parsedData[6] !== '' ? parseInt(parsedData[6], 10) : null,
737
+ RSSI_quality:
738
+ parsedData[10] !== ''
739
+ ? utils.getSignalStrength(
740
+ utils.networkTypes[parsedData[10]],
741
+ parseInt(parsedData[6], 10)
742
+ )
743
+ : null, // Signal Strength
744
+ RSSI_percentage:
745
+ parsedData[10] !== ''
746
+ ? utils.getSignalPercentage(
747
+ utils.networkTypes[parsedData[10]],
748
+ parseInt(parsedData[6], 10)
749
+ )
750
+ : null, // Signal Percetange
751
+ GSM_quality:
752
+ parsedData[7] !== ''
753
+ ? 100 * parseInt(parseFloat(parsedData[7]) / 7, 10)
754
+ : null // Percentage
755
+ },
756
+ backupBattery: {
757
+ using: parsedData[11] !== '' && parseFloat(parsedData[11]) < 4.5,
758
+ voltage: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
759
+ charging: parsedData[12] === '1'
760
+ },
761
+ externalGPSAntenna: utils.externalGPSAntennaOptions[parsedData[15]],
762
+ status: {
763
+ raw: parsedData[18] + parsedData[19] + parsedData[20],
764
+ sos: false,
765
+ input: {
766
+ '4': utils.nHexDigit(utils.hex2bin(parsedData[21][1]), 4)[0] === '1',
767
+ '3': utils.nHexDigit(utils.hex2bin(parsedData[21][1]), 4)[1] === '1',
768
+ '2': utils.nHexDigit(utils.hex2bin(parsedData[21][1]), 4)[2] === '1',
769
+ '1': utils.nHexDigit(utils.hex2bin(parsedData[21][1]), 4)[3] === '1'
770
+ },
771
+ output: {
772
+ '4': utils.nHexDigit(utils.hex2bin(parsedData[22][1]), 4)[0] === '1',
773
+ '3': utils.nHexDigit(utils.hex2bin(parsedData[22][1]), 4)[1] === '1',
774
+ '2': utils.nHexDigit(utils.hex2bin(parsedData[22][1]), 4)[2] === '1',
775
+ '1': utils.nHexDigit(utils.hex2bin(parsedData[22][1]), 4)[3] === '1'
776
+ },
777
+ charge: parsedData[12] === '1'
778
+ },
779
+ voltage: {
780
+ battery:
781
+ parsedData[11] !== ''
782
+ ? parseInt(100 * (parseFloat(parsedData[11]) / 4.5), 10)
783
+ : null, // percentage
784
+ inputCharge:
785
+ parsedData[9] !== '' ? parseFloat(parsedData[9]) / 1000 : null,
786
+ ada: parsedData[18] !== '' ? parseFloat(parsedData[18]) / 1000 : null,
787
+ adb: parsedData[19] !== '' ? parseFloat(parsedData[19]) / 1000 : null,
788
+ adc: parsedData[20] !== '' ? parseFloat(parsedData[20]) / 1000 : null
789
+ },
790
+ lastFixUTCTime:
791
+ parsedData[16] !== '' ? utils.parseDate(parsedData[16]) : null,
792
+ timezoneOffset: parsedData[23]
793
+ })
794
+ } else if (
795
+ command[1] === 'GTTOW' ||
796
+ command[1] === 'GTDIS' ||
797
+ command[1] === 'GTIOB' ||
798
+ command[1] === 'GTSPD' ||
799
+ command[1] === 'GTSOS' ||
800
+ command[1] === 'GTRTL' ||
801
+ command[1] === 'GTDOG' ||
802
+ command[1] === 'GTIGL' ||
803
+ command[1] === 'GTVGL' ||
804
+ command[1] === 'GTHBM'
805
+ ) {
806
+ // Common Alarms
807
+ let number = parsedData[6] !== '' ? parseInt(parsedData[6], 10) : 1
808
+ let posAppendMask = parsedData[18]
809
+ ? utils.nHexDigit(utils.hex2bin(parsedData[18]), 8)
810
+ : null
811
+
812
+ // If get satellites is configured
813
+ let satelliteInfo = posAppendMask && posAppendMask[7] === '1' ? 1 : 0
814
+ let jammingSate = posAppendMask && posAppendMask[3] === '1' ? 1 : 0
815
+ let index = 6 + (12 + satelliteInfo + jammingSate) * number
816
+
817
+ data = Object.assign(data, {
818
+ alarm: utils.getAlarm(command[1], parsedData[5], 'gv310lau'),
819
+ loc: {
820
+ type: 'Point',
821
+ coordinates: [parseFloat(parsedData[11]), parseFloat(parsedData[12])]
822
+ },
823
+ speed: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
824
+ gpsStatus: utils.checkGps(
825
+ parseFloat(parsedData[11]),
826
+ parseFloat(parsedData[12])
827
+ ),
828
+ hdop: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
829
+ status: null,
830
+ azimuth: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
831
+ altitude: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
832
+ datetime: parsedData[13] !== '' ? utils.parseDate(parsedData[13]) : null,
833
+ voltage: {
834
+ battery: null,
835
+ inputCharge: null,
836
+ ada: null,
837
+ adb: null,
838
+ adc: null
839
+ },
840
+ mcc:
841
+ parsedData[14] !== ''
842
+ ? utils.latamMcc[parseInt(parsedData[14], 10)]
843
+ : null,
844
+ mnc:
845
+ parsedData[15] !== ''
846
+ ? utils.getMNC(parsedData[14], parsedData[15])
847
+ : null,
848
+ lac: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
849
+ cid: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
850
+ satellites:
851
+ satelliteInfo &&
852
+ parsedData[index - (satelliteInfo + jammingSate) + 1] !== ''
853
+ ? parseInt(parsedData[index - (satelliteInfo + jammingSate) + 1])
854
+ : null,
855
+ jammingSate:
856
+ jammingSate && parsedData[index - jammingSate + 1] !== ''
857
+ ? utils.jammingSateTypes[parsedData[index - jammingSate + 1]]
858
+ : null,
859
+ odometer:
860
+ parsedData[index + 1] !== '' ? parseFloat(parsedData[index + 1]) : null,
861
+ overspeedStatus:
862
+ parseInt(parsedData[4], 10) === 1 || parseInt(parsedData[4], 10) === 3
863
+ ? parsedData[index + 2] === '1'
864
+ : null,
865
+ lastSpeedStateDuration:
866
+ parseInt(parsedData[4], 10) === 2
867
+ ? parsedData[index + 2]
868
+ : parseInt(parsedData[4], 10) === 3 ? parsedData[index + 3] : null,
869
+ hourmeter: null
870
+ })
871
+ } else if (command[1] === 'GTEPS' || command[1] === 'GTAIS') {
872
+ // External low battery and voltage for analog input
873
+ let number = parsedData[6] !== '' ? parseInt(parsedData[6], 10) : 1
874
+ let satelliteInfo = utils.includeSatellites(parsedData[18])
875
+ let jammingSate = utils.includeJammingSate(parsedData[18])
876
+ let index = 6 + (12 + satelliteInfo + jammingSate) * number // position append mask
877
+
878
+ data = Object.assign(data, {
879
+ alarm: utils.getAlarm(command[1], parsedData[5]),
880
+ loc: {
881
+ type: 'Point',
882
+ coordinates: [parseFloat(parsedData[11]), parseFloat(parsedData[12])]
883
+ },
884
+ speed: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
885
+ gpsStatus: utils.checkGps(
886
+ parseFloat(parsedData[11]),
887
+ parseFloat(parsedData[12])
888
+ ),
889
+ hdop: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
890
+ status: null,
891
+ azimuth: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
892
+ altitude: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
893
+ datetime: parsedData[13] !== '' ? utils.parseDate(parsedData[13]) : null,
894
+ voltage: {
895
+ battery: parsedData[4] !== '' ? parseFloat(parsedData[4]) / 1000 : null,
896
+ inputCharge: null,
897
+ ada: null,
898
+ adb: null,
899
+ adc: null
900
+ },
901
+ mcc:
902
+ parsedData[14] !== ''
903
+ ? utils.latamMcc[parseInt(parsedData[14], 10)]
904
+ : null,
905
+ mnc:
906
+ parsedData[15] !== ''
907
+ ? utils.getMNC(parsedData[14], parsedData[15])
908
+ : null,
909
+ lac: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
910
+ cid: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
911
+ satellites:
912
+ satelliteInfo &&
913
+ parsedData[index - (satelliteInfo + jammingSate) + 1] !== ''
914
+ ? parseInt(parsedData[index - (satelliteInfo + jammingSate) + 1])
915
+ : null,
916
+ jammingSate:
917
+ jammingSate && parsedData[index - jammingSate + 1] !== ''
918
+ ? utils.jammingSateTypes[parsedData[index - jammingSate + 1]]
919
+ : null,
920
+ odometer:
921
+ parsedData[index + 1] !== '' ? parseFloat(parsedData[index + 1]) : null,
922
+ hourmeter: null
923
+ })
924
+ } else if (command[1] === 'GTTMP') {
925
+ // Temperature Alarm
926
+ let number = parsedData[7] !== '' ? parseInt(parsedData[7], 10) : 1
927
+ let satelliteInfo = utils.includeSatellites(parsedData[19])
928
+ let jammingSate = utils.includeJammingSate(parsedData[19])
929
+ let index = 7 + (12 + satelliteInfo + jammingSate) * number // position append mask
930
+
931
+ data = Object.assign(data, {
932
+ alarm: utils.getAlarm(command[1], parsedData[6], [
933
+ parsedData[index + 11],
934
+ parsedData[index + 13]
935
+ ]),
936
+ loc: {
937
+ type: 'Point',
938
+ coordinates: [parseFloat(parsedData[12]), parseFloat(parsedData[13])]
939
+ },
940
+ speed: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
941
+ gpsStatus: utils.checkGps(
942
+ parseFloat(parsedData[12]),
943
+ parseFloat(parsedData[13])
944
+ ),
945
+ hdop: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
946
+ status: {
947
+ // parsedData[24]
948
+ raw: `${parsedData[index + 6]}${parsedData[index + 7]}`,
949
+ sos: false,
950
+ input: {
951
+ '4':
952
+ utils.nHexDigit(utils.hex2bin(parsedData[index + 6][1]), 4)[0] ===
953
+ '1',
954
+ '3':
955
+ utils.nHexDigit(utils.hex2bin(parsedData[index + 6][1]), 4)[1] ===
956
+ '1',
957
+ '2':
958
+ utils.nHexDigit(utils.hex2bin(parsedData[index + 6][1]), 4)[2] ===
959
+ '1',
960
+ '1':
961
+ utils.nHexDigit(utils.hex2bin(parsedData[index + 6][1]), 4)[3] ===
962
+ '1'
963
+ },
964
+ output: {
965
+ '3':
966
+ utils.nHexDigit(utils.hex2bin(parsedData[index + 7][1]), 4)[1] ===
967
+ '1',
968
+ '2':
969
+ utils.nHexDigit(utils.hex2bin(parsedData[index + 7][1]), 4)[2] ===
970
+ '1',
971
+ '1':
972
+ utils.nHexDigit(utils.hex2bin(parsedData[index + 7][1]), 4)[3] ===
973
+ '1'
974
+ },
975
+ charge: parseFloat(parsedData[5]) > 5,
976
+ state: null
977
+ },
978
+ azimuth: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
979
+ altitude: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
980
+ datetime: parsedData[14] !== '' ? utils.parseDate(parsedData[14]) : null,
981
+ voltage: {
982
+ battery: null, // percentage
983
+ inputCharge:
984
+ parsedData[5] !== '' ? parseFloat(parsedData[5]) / 1000 : null,
985
+ ada:
986
+ parsedData[index + 3] !== ''
987
+ ? parseFloat(parsedData[index + 3]) / 1000
988
+ : null,
989
+ adb:
990
+ parsedData[index + 4] !== ''
991
+ ? parseFloat(parsedData[index + 4]) / 1000
992
+ : null,
993
+ adc:
994
+ parsedData[index + 5] !== ''
995
+ ? parseFloat(parsedData[index + 5]) / 1000
996
+ : null
997
+ },
998
+ mcc:
999
+ parsedData[15] !== ''
1000
+ ? utils.latamMcc[parseInt(parsedData[15], 10)]
1001
+ : null,
1002
+ mnc:
1003
+ parsedData[16] !== ''
1004
+ ? utils.getMNC(parsedData[15], parsedData[16])
1005
+ : null,
1006
+ lac: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
1007
+ cid: parsedData[18] !== '' ? parseInt(parsedData[18], 16) : null,
1008
+ satellites:
1009
+ satelliteInfo &&
1010
+ parsedData[index - (satelliteInfo + jammingSate) + 1] !== ''
1011
+ ? parseInt(parsedData[index - (satelliteInfo + jammingSate) + 1], 10)
1012
+ : null,
1013
+ jammingSate:
1014
+ jammingSate && parsedData[index - jammingSate + 1] !== ''
1015
+ ? utils.jammingSateTypes[parsedData[index - jammingSate + 1]]
1016
+ : null,
1017
+ odometer:
1018
+ parsedData[index + 1] !== '' ? parseFloat(parsedData[index + 1]) : null,
1019
+ hourmeter:
1020
+ parsedData[index + 2] !== ''
1021
+ ? utils.getHoursForHourmeter(parsedData[index + 2])
1022
+ : null
1023
+ })
1024
+ } else if (
1025
+ command[1] === 'GTPNA' ||
1026
+ command[1] === 'GTPFA' ||
1027
+ command[1] === 'GTPDP'
1028
+ ) {
1029
+ // Event report (It uses the last GPS data and MCC info)
1030
+ data = Object.assign(data, {
1031
+ alarm: utils.getAlarm(command[1], null),
1032
+ loc: null,
1033
+ speed: null,
1034
+ gpsStatus: null,
1035
+ hdop: null,
1036
+ status: null,
1037
+ azimuth: null,
1038
+ altitude: null,
1039
+ datetime: parsedData[4] !== '' ? utils.parseDate(parsedData[4]) : null,
1040
+ voltage: {
1041
+ battery: null,
1042
+ inputCharge: null,
1043
+ ada: null,
1044
+ adb: null,
1045
+ adc: null
1046
+ },
1047
+ mcc: null,
1048
+ mnc: null,
1049
+ lac: null,
1050
+ cid: null,
1051
+ odometer: null,
1052
+ hourmeter: null
1053
+ })
1054
+ } else if (command[1] === 'GTPNR' || command[1] === 'GTPFR') {
1055
+ // Power on/off reason
1056
+ data = Object.assign(data, {
1057
+ alarm: utils.getAlarm(command[1], parsedData[4]),
1058
+ loc: null,
1059
+ speed: null,
1060
+ gpsStatus: null,
1061
+ hdop: null,
1062
+ status: null,
1063
+ azimuth: null,
1064
+ altitude: null,
1065
+ datetime: parsedData[9] !== '' ? utils.parseDate(parsedData[9]) : null,
1066
+ voltage: {
1067
+ battery: null,
1068
+ inputCharge: null,
1069
+ ada: null,
1070
+ adb: null,
1071
+ adc: null
1072
+ },
1073
+ mcc: null,
1074
+ mnc: null,
1075
+ lac: null,
1076
+ cid: null,
1077
+ odometer: null,
1078
+ hourmeter: null
1079
+ })
1080
+ } else if (
1081
+ command[1] === 'GTMPN' ||
1082
+ command[1] === 'GTMPF' ||
1083
+ command[1] === 'GTBTC'
1084
+ ) {
1085
+ let satelliteInfo = utils.includeSatellites(parsedData[15])
1086
+ let jammingSate = utils.includeJammingSate(parsedData[15])
1087
+ let index = 15 // position append mask
1088
+
1089
+ data = Object.assign(data, {
1090
+ alarm: utils.getAlarm(command[1], null),
1091
+ loc: {
1092
+ type: 'Point',
1093
+ coordinates: [parseFloat(parsedData[8]), parseFloat(parsedData[9])]
1094
+ },
1095
+ speed: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
1096
+ gpsStatus: utils.checkGps(
1097
+ parseFloat(parsedData[8]),
1098
+ parseFloat(parsedData[9])
1099
+ ),
1100
+ hdop: parsedData[4] !== '' ? parseFloat(parsedData[4]) : null,
1101
+ status: null,
1102
+ azimuth: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
1103
+ altitude: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
1104
+ datetime: parsedData[10] !== '' ? utils.parseDate(parsedData[10]) : null,
1105
+ voltage: {
1106
+ battery: null,
1107
+ inputCharge: null,
1108
+ ada: null,
1109
+ adb: null,
1110
+ adc: null
1111
+ },
1112
+ mcc:
1113
+ parsedData[11] !== ''
1114
+ ? utils.latamMcc[parseInt(parsedData[11], 10)]
1115
+ : null,
1116
+ mnc:
1117
+ parsedData[12] !== ''
1118
+ ? utils.getMNC(parsedData[11], parsedData[12])
1119
+ : null,
1120
+ lac: parsedData[13] !== '' ? parseInt(parsedData[13], 16) : null,
1121
+ cid: parsedData[14] !== '' ? parseInt(parsedData[14], 16) : null,
1122
+ satellites:
1123
+ satelliteInfo &&
1124
+ parsedData[index - (satelliteInfo + jammingSate) + 1] !== ''
1125
+ ? parseInt(parsedData[index - (satelliteInfo + jammingSate) + 1])
1126
+ : null,
1127
+ jammingSate:
1128
+ jammingSate && parsedData[index - jammingSate + 1] !== ''
1129
+ ? utils.jammingSateTypes[parsedData[index - jammingSate + 1]]
1130
+ : null,
1131
+ odometer: null,
1132
+ hourmeter: null
1133
+ })
1134
+ } else if (
1135
+ command[1] === 'GTJDR' ||
1136
+ command[1] === 'GTANT' ||
1137
+ command[1] === 'GTRMD' ||
1138
+ command[1] === 'GTCRA' ||
1139
+ command[1] === 'GTBPL' ||
1140
+ command[1] === 'GTSTT' ||
1141
+ command[1] === 'GTAVC' ||
1142
+ command[1] === 'GTWPB'
1143
+ ) {
1144
+ let satelliteInfo = utils.includeSatellites(parsedData[16])
1145
+ let jammingSate = utils.includeJammingSate(parsedData[16])
1146
+ let index = 16 // position append mask
1147
+
1148
+ data = Object.assign(data, {
1149
+ alarm: utils.getAlarm(command[1], parsedData[4]),
1150
+ loc: {
1151
+ type: 'Point',
1152
+ coordinates: [parseFloat(parsedData[9]), parseFloat(parsedData[10])]
1153
+ },
1154
+ speed: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
1155
+ gpsStatus: utils.checkGps(
1156
+ parseFloat(parsedData[9]),
1157
+ parseFloat(parsedData[10])
1158
+ ),
1159
+ hdop: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
1160
+ status: null,
1161
+ azimuth: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
1162
+ altitude: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
1163
+ datetime: parsedData[11] !== '' ? utils.parseDate(parsedData[11]) : null,
1164
+ voltage: {
1165
+ battery: null,
1166
+ inputCharge: null,
1167
+ ada: null,
1168
+ adb: null,
1169
+ adc: null
1170
+ },
1171
+ mcc:
1172
+ parsedData[12] !== ''
1173
+ ? utils.latamMcc[parseInt(parsedData[12], 10)]
1174
+ : null,
1175
+ mnc:
1176
+ parsedData[13] !== ''
1177
+ ? utils.getMNC(parsedData[12], parsedData[13])
1178
+ : null,
1179
+ lac: parsedData[14] !== '' ? parseInt(parsedData[14], 16) : null,
1180
+ cid: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
1181
+ satellites:
1182
+ satelliteInfo &&
1183
+ parsedData[index - (satelliteInfo + jammingSate) + 1] !== ''
1184
+ ? parseInt(parsedData[index - (satelliteInfo + jammingSate) + 1], 10)
1185
+ : null,
1186
+ jammingSate:
1187
+ jammingSate && parsedData[index - jammingSate + 1] !== ''
1188
+ ? utils.jammingSateTypes[parsedData[index - jammingSate + 1]]
1189
+ : null,
1190
+ odometer: null,
1191
+ hourmeter: null
1192
+ })
1193
+ } else if (command[1] === 'GTCRG') {
1194
+ let number = parsedData[5] !== '' ? parseInt(parsedData[5]) : 1
1195
+ let start = 6
1196
+
1197
+ data = Object.assign(data, {
1198
+ alarm: utils.getAlarm(command[1], parsedData[4]),
1199
+ voltage: {
1200
+ battery: null,
1201
+ inputCharge: null,
1202
+ ada: null,
1203
+ adb: null,
1204
+ adc: null
1205
+ }
1206
+ })
1207
+
1208
+ let more = []
1209
+ for (let i = 1; i <= number; i++) {
1210
+ more.push({
1211
+ id: parsedData[start] !== '' ? parseInt(parsedData[start]) : null,
1212
+ loc: {
1213
+ type: 'Point',
1214
+ coordinates: [
1215
+ parseFloat(parsedData[start + 5]),
1216
+ parseFloat(parsedData[start + 6])
1217
+ ]
1218
+ },
1219
+ speed:
1220
+ parsedData[start + 2] !== ''
1221
+ ? parseFloat(parsedData[start + 2])
1222
+ : null,
1223
+ gpsStatus: utils.checkGps(
1224
+ parseFloat(parsedData[start + 5]),
1225
+ parseFloat(parsedData[start + 6])
1226
+ ),
1227
+ hdop:
1228
+ parsedData[start + 1] !== ''
1229
+ ? parseFloat(parsedData[start + 1])
1230
+ : null,
1231
+ azimuth:
1232
+ parsedData[start + 3] !== ''
1233
+ ? parseFloat(parsedData[start + 3])
1234
+ : null,
1235
+ altitude:
1236
+ parsedData[start + 4] !== ''
1237
+ ? parseFloat(parsedData[start + 4])
1238
+ : null,
1239
+ datetime:
1240
+ parsedData[start + 7] !== ''
1241
+ ? utils.parseDate(parsedData[start + 7])
1242
+ : null
1243
+ })
1244
+ start += 8
1245
+ }
1246
+
1247
+ data = Object.assign(data, {
1248
+ gnssData: more
1249
+ })
1250
+ } else if (command[1] === 'GTJDS') {
1251
+ let index = 17 // position append mask
1252
+ let satelliteInfo = utils.includeSatellites(parsedData[17])
1253
+ let jammingSate = utils.includeJammingSate(parsedData[17])
1254
+
1255
+ data = Object.assign(data, {
1256
+ alarm: utils.getAlarm(command[1], parsedData[4]),
1257
+ loc: {
1258
+ type: 'Point',
1259
+ coordinates: [parseFloat(parsedData[10]), parseFloat(parsedData[11])]
1260
+ },
1261
+ speed: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
1262
+ gpsStatus: utils.checkGps(
1263
+ parseFloat(parsedData[10]),
1264
+ parseFloat(parsedData[11])
1265
+ ),
1266
+ hdop: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
1267
+ status: null,
1268
+ azimuth: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
1269
+ altitude: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
1270
+ datetime: parsedData[12] !== '' ? utils.parseDate(parsedData[12]) : null,
1271
+ voltage: {
1272
+ battery: null,
1273
+ inputCharge: null,
1274
+ ada: null,
1275
+ adb: null,
1276
+ adc: null
1277
+ },
1278
+ mcc:
1279
+ parsedData[13] !== ''
1280
+ ? utils.latamMcc[parseInt(parsedData[13], 10)]
1281
+ : null,
1282
+ mnc:
1283
+ parsedData[14] !== ''
1284
+ ? utils.getMNC(parsedData[13], parsedData[14])
1285
+ : null,
1286
+ lac: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
1287
+ cid: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
1288
+ satellites:
1289
+ satelliteInfo &&
1290
+ parsedData[index - (satelliteInfo + jammingSate) + 1] !== ''
1291
+ ? parseInt(parsedData[index - (satelliteInfo + jammingSate) + 1], 10)
1292
+ : null,
1293
+ jammingSate:
1294
+ jammingSate && parsedData[index - jammingSate + 1] !== ''
1295
+ ? utils.jammingSateTypes[parsedData[index - jammingSate + 1]]
1296
+ : null,
1297
+ odometer: null,
1298
+ hourmeter: null
1299
+ })
1300
+ } else if (command[1] === 'GTIGN' || command[1] === 'GTIGF') {
1301
+ let index = 16 // position append mask
1302
+ let satelliteInfo = utils.includeSatellites(parsedData[16])
1303
+ let jammingSate = utils.includeJammingSate(parsedData[16])
1304
+
1305
+ data = Object.assign(data, {
1306
+ alarm: utils.getAlarm(command[1], parsedData[4]),
1307
+ loc: {
1308
+ type: 'Point',
1309
+ coordinates: [parseFloat(parsedData[9]), parseFloat(parsedData[10])]
1310
+ },
1311
+ speed: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
1312
+ gpsStatus: utils.checkGps(
1313
+ parseFloat(parsedData[9]),
1314
+ parseFloat(parsedData[10])
1315
+ ),
1316
+ hdop: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
1317
+ status: null,
1318
+ azimuth: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
1319
+ altitude: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
1320
+ datetime: parsedData[11] !== '' ? utils.parseDate(parsedData[11]) : null,
1321
+ voltage: {
1322
+ battery: null,
1323
+ inputCharge: null,
1324
+ ada: null,
1325
+ adb: null,
1326
+ adc: null
1327
+ },
1328
+ mcc:
1329
+ parsedData[12] !== ''
1330
+ ? utils.latamMcc[parseInt(parsedData[12], 10)]
1331
+ : null,
1332
+ mnc:
1333
+ parsedData[13] !== ''
1334
+ ? utils.getMNC(parsedData[12], parsedData[13])
1335
+ : null,
1336
+ lac: parsedData[14] !== '' ? parseInt(parsedData[14], 16) : null,
1337
+ cid: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
1338
+ satellites:
1339
+ satelliteInfo &&
1340
+ parsedData[index - (satelliteInfo + jammingSate) + 1] !== ''
1341
+ ? parseInt(parsedData[index - (satelliteInfo + jammingSate) + 1], 10)
1342
+ : null,
1343
+ jammingSate:
1344
+ jammingSate && parsedData[index - jammingSate + 1] !== ''
1345
+ ? utils.jammingSateTypes[parsedData[index - jammingSate + 1]]
1346
+ : null,
1347
+ odometer:
1348
+ parsedData[index + 2] !== '' ? parseFloat(parsedData[index + 2]) : null,
1349
+ hourmeter:
1350
+ parsedData[index + 1] !== ''
1351
+ ? utils.getHoursForHourmeter(parsedData[index + 1])
1352
+ : null
1353
+ })
1354
+ } else if (command[1] === 'GTIDN' || command[1] === 'GTIDF') {
1355
+ let index = 17 // position append mask
1356
+ let satelliteInfo = utils.includeSatellites(parsedData[17])
1357
+ let jammingSate = utils.includeJammingSate(parsedData[17])
1358
+
1359
+ data = Object.assign(data, {
1360
+ alarm: utils.getAlarm(command[1], parsedData[5]),
1361
+ loc: {
1362
+ type: 'Point',
1363
+ coordinates: [parseFloat(parsedData[10]), parseFloat(parsedData[11])]
1364
+ },
1365
+ speed: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
1366
+ gpsStatus: utils.checkGps(
1367
+ parseFloat(parsedData[10]),
1368
+ parseFloat(parsedData[11])
1369
+ ),
1370
+ hdop: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
1371
+ status: null,
1372
+ azimuth: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
1373
+ altitude: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
1374
+ datetime: parsedData[12] !== '' ? utils.parseDate(parsedData[12]) : null,
1375
+ voltage: {
1376
+ battery: null,
1377
+ inputCharge: null,
1378
+ ada: null,
1379
+ adb: null,
1380
+ adc: null
1381
+ },
1382
+ mcc:
1383
+ parsedData[13] !== ''
1384
+ ? utils.latamMcc[parseInt(parsedData[13], 10)]
1385
+ : null,
1386
+ mnc:
1387
+ parsedData[14] !== ''
1388
+ ? utils.getMNC(parsedData[13], parsedData[14])
1389
+ : null,
1390
+ lac: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
1391
+ cid: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
1392
+ satellites:
1393
+ satelliteInfo &&
1394
+ parsedData[index - (satelliteInfo + jammingSate) + 1] !== ''
1395
+ ? parseInt(parsedData[index - (satelliteInfo + jammingSate) + 1], 10)
1396
+ : null,
1397
+ jammingSate:
1398
+ jammingSate && parsedData[index - jammingSate + 1] !== ''
1399
+ ? utils.jammingSateTypes[parsedData[index - jammingSate + 1]]
1400
+ : null,
1401
+ odometer:
1402
+ parsedData[index + 1] !== '' ? parseFloat(parsedData[index + 1]) : null,
1403
+ hourmeter: null
1404
+ })
1405
+ } else if (
1406
+ command[1] === 'GTSTR' ||
1407
+ command[1] === 'GTSTP' ||
1408
+ command[1] === 'GTLSP'
1409
+ ) {
1410
+ let satelliteInfo = utils.includeSatellites(parsedData[17])
1411
+ let jammingSate = utils.includeJammingSate(parsedData[17])
1412
+ let index = 17 + (satelliteInfo + jammingSate)
1413
+
1414
+ data = Object.assign(data, {
1415
+ alarm: utils.getAlarm(command[1], null),
1416
+ loc: {
1417
+ type: 'Point',
1418
+ coordinates: [parseFloat(parsedData[10]), parseFloat(parsedData[11])]
1419
+ },
1420
+ speed: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
1421
+ gpsStatus: utils.checkGps(
1422
+ parseFloat(parsedData[10]),
1423
+ parseFloat(parsedData[11])
1424
+ ),
1425
+ hdop: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
1426
+ status: null,
1427
+ azimuth: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
1428
+ altitude: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
1429
+ datetime: parsedData[12] !== '' ? utils.parseDate(parsedData[12]) : null,
1430
+ voltage: {
1431
+ battery: null,
1432
+ inputCharge: null,
1433
+ ada: null,
1434
+ adb: null,
1435
+ adc: null
1436
+ },
1437
+ mcc:
1438
+ parsedData[13] !== ''
1439
+ ? utils.latamMcc[parseInt(parsedData[13], 10)]
1440
+ : null,
1441
+ mnc:
1442
+ parsedData[14] !== ''
1443
+ ? utils.getMNC(parsedData[13], parsedData[14])
1444
+ : null,
1445
+ lac: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
1446
+ cid: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
1447
+ satellites:
1448
+ satelliteInfo &&
1449
+ parsedData[index - (satelliteInfo + jammingSate) + 1] !== ''
1450
+ ? parseInt(parsedData[index - (satelliteInfo + jammingSate) + 1], 10)
1451
+ : null,
1452
+ jammingSate:
1453
+ jammingSate && parsedData[index - jammingSate + 1] !== ''
1454
+ ? utils.jammingSateTypes[parsedData[index - jammingSate + 1]]
1455
+ : null,
1456
+ odometer:
1457
+ parsedData[index + 1] !== '' ? parseFloat(parsedData[index + 1]) : null,
1458
+ hourmeter: null
1459
+ })
1460
+ } else if (command[1] === 'GTGSS') {
1461
+ // GPS Status
1462
+ let satelliteInfo = utils.includeSatellites(parsedData[19])
1463
+ let jammingSate = utils.includeJammingSate(parsedData[19])
1464
+ let index = 19 + (satelliteInfo + jammingSate)
1465
+
1466
+ data = Object.assign(data, {
1467
+ alarm: utils.getAlarm(command[1], parsedData[4]),
1468
+ loc: {
1469
+ type: 'Point',
1470
+ coordinates: [parseFloat(parsedData[12]), parseFloat(parsedData[13])]
1471
+ },
1472
+ speed: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
1473
+ gpsStatus: utils.checkGps(
1474
+ parseFloat(parsedData[12]),
1475
+ parseFloat(parsedData[13])
1476
+ ),
1477
+ hdop: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
1478
+ status: null,
1479
+ azimuth: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
1480
+ altitude: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
1481
+ datetime: parsedData[14] !== '' ? utils.parseDate(parsedData[14]) : null,
1482
+ voltage: {
1483
+ battery: null,
1484
+ inputCharge: null,
1485
+ ada: null,
1486
+ adb: null,
1487
+ adc: null
1488
+ },
1489
+ mcc:
1490
+ parsedData[15] !== ''
1491
+ ? utils.latamMcc[parseInt(parsedData[15], 10)]
1492
+ : null,
1493
+ mnc:
1494
+ parsedData[16] !== ''
1495
+ ? utils.getMNC(parsedData[15], parsedData[16])
1496
+ : null,
1497
+ lac: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
1498
+ cid: parsedData[18] !== '' ? parseInt(parsedData[18], 16) : null,
1499
+ usedSatellites: parsedData[5] !== '' ? parseInt(parsedData[5], 16) : null,
1500
+ satellites:
1501
+ satelliteInfo &&
1502
+ parsedData[index - (satelliteInfo + jammingSate) + 1] !== ''
1503
+ ? parseInt(parsedData[index - (satelliteInfo + jammingSate) + 1], 10)
1504
+ : null,
1505
+ jammingSate:
1506
+ jammingSate && parsedData[index - jammingSate + 1] !== ''
1507
+ ? utils.jammingSateTypes[parsedData[index - jammingSate + 1]]
1508
+ : null,
1509
+ odometer: null,
1510
+ hourmeter: null
1511
+ })
1512
+ } else if (command[1] === 'GTIDA') {
1513
+ // iButton
1514
+ let number = parsedData[7] !== '' ? parseInt(parsedData[7], 10) : 1
1515
+ let satelliteInfo = utils.includeSatellites(parsedData[19])
1516
+ let jammingSate = utils.includeJammingSate(parsedData[19])
1517
+ let index = 7 + (12 + satelliteInfo + jammingSate) * number
1518
+
1519
+ data = Object.assign(data, {
1520
+ alarm: utils.getAlarm(command[1], `${parsedData[5]},${parsedData[6]}`),
1521
+ loc: {
1522
+ type: 'Point',
1523
+ coordinates: [parseFloat(parsedData[12]), parseFloat(parsedData[13])]
1524
+ },
1525
+ speed: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
1526
+ gpsStatus: utils.checkGps(
1527
+ parseFloat(parsedData[12]),
1528
+ parseFloat(parsedData[13])
1529
+ ),
1530
+ hdop: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
1531
+ status: null,
1532
+ azimuth: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
1533
+ altitude: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
1534
+ datetime: parsedData[14] !== '' ? utils.parseDate(parsedData[14]) : null,
1535
+ voltage: {
1536
+ battery: null,
1537
+ inputCharge: null,
1538
+ ada: null,
1539
+ adb: null,
1540
+ adc: null
1541
+ },
1542
+ mcc:
1543
+ parsedData[15] !== ''
1544
+ ? utils.latamMcc[parseInt(parsedData[15], 10)]
1545
+ : null,
1546
+ mnc:
1547
+ parsedData[16] !== ''
1548
+ ? utils.getMNC(parsedData[15], parsedData[16])
1549
+ : null,
1550
+ lac: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
1551
+ cid: parsedData[18] !== '' ? parseInt(parsedData[18], 16) : null,
1552
+ satellites:
1553
+ satelliteInfo &&
1554
+ parsedData[index - (satelliteInfo + jammingSate) + 1] !== ''
1555
+ ? parseInt(parsedData[index - (satelliteInfo + jammingSate) + 1], 10)
1556
+ : null,
1557
+ jammingSate:
1558
+ jammingSate && parsedData[index - jammingSate + 1] !== ''
1559
+ ? utils.jammingSateTypes[parsedData[index - jammingSate + 1]]
1560
+ : null,
1561
+ odometer:
1562
+ parsedData[index + 1] !== '' ? parseFloat(parsedData[index + 1]) : null,
1563
+ hourmeter: null
1564
+ })
1565
+ } else if (command[1] === 'GTCAN') {
1566
+ let canData = utils.getCanData(parsedData, 5, command[1], {
1567
+ deviceType: 'GV350CEU'
1568
+ })
1569
+ let satelliteInfo = utils.includeSatellites(parsedData[canData[0]])
1570
+ let jammingSate = utils.includeJammingSate(parsedData[canData[0]])
1571
+ let index = canData[0] + (satelliteInfo ? 1 : 0) + (jammingSate ? 1 : 0)
1572
+
1573
+ data = Object.assign(data, {
1574
+ alarm: utils.getAlarm(command[1], parsedData[4]),
1575
+ status: null,
1576
+ voltage: {
1577
+ battery: null,
1578
+ inputCharge: null,
1579
+ ada: null,
1580
+ adb: null,
1581
+ adc: null
1582
+ },
1583
+ satellites:
1584
+ satelliteInfo &&
1585
+ parsedData[index - (satelliteInfo + jammingSate) + 1] !== ''
1586
+ ? parseInt(parsedData[index - (satelliteInfo + jammingSate) + 1], 10)
1587
+ : null,
1588
+ jammingSate:
1589
+ jammingSate && parsedData[index - jammingSate + 1] !== ''
1590
+ ? utils.jammingSateTypes[parsedData[index - jammingSate + 1]]
1591
+ : null,
1592
+ odometer: null,
1593
+ hourmeter: null,
1594
+ can: canData[3]
1595
+ })
1596
+
1597
+ data = Object.assign(data, canData[1], canData[2])
1598
+ } else if (command[1] === 'GTDAT') {
1599
+ let dataIndex = 4
1600
+ // Short format
1601
+ if (parsedData.length === 7) {
1602
+ data = Object.assign(data, {
1603
+ loc: null,
1604
+ speed: null,
1605
+ gpsStatus: null,
1606
+ hdop: null,
1607
+ status: null,
1608
+ azimuth: null,
1609
+ altitude: null,
1610
+ datetime: null,
1611
+ voltage: {
1612
+ battery: null,
1613
+ inputCharge: null,
1614
+ ada: null,
1615
+ adb: null,
1616
+ adc: null
1617
+ },
1618
+ mcc: null,
1619
+ mnc: null,
1620
+ lac: null,
1621
+ cid: null,
1622
+ satellites: null,
1623
+ jammingSate: null,
1624
+ odometer: null,
1625
+ hourmeter: null
1626
+ })
1627
+ } else {
1628
+ dataIndex = 7
1629
+ data = Object.assign(data, {
1630
+ loc: {
1631
+ type: 'Point',
1632
+ coordinates: [parseFloat(parsedData[12]), parseFloat(parsedData[13])]
1633
+ },
1634
+ speed: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
1635
+ gpsStatus: utils.checkGps(
1636
+ parseFloat(parsedData[12]),
1637
+ parseFloat(parsedData[13])
1638
+ ),
1639
+ hdop: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
1640
+ status: null,
1641
+ azimuth: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
1642
+ altitude: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
1643
+ datetime:
1644
+ parsedData[14] !== '' ? utils.parseDate(parsedData[14]) : null,
1645
+ voltage: {
1646
+ battery: null,
1647
+ inputCharge: null,
1648
+ ada: null,
1649
+ adb: null,
1650
+ adc: null
1651
+ },
1652
+ mcc:
1653
+ parsedData[15] !== ''
1654
+ ? utils.latamMcc[parseInt(parsedData[15], 10)]
1655
+ : null,
1656
+ mnc:
1657
+ parsedData[16] !== ''
1658
+ ? utils.getMNC(parsedData[15], parsedData[16])
1659
+ : null,
1660
+ lac: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
1661
+ cid: parsedData[18] !== '' ? parseInt(parsedData[18], 16) : null,
1662
+ satellites: null,
1663
+ jammingSate: null,
1664
+ odometer: null,
1665
+ hourmeter: null
1666
+ })
1667
+ }
1668
+
1669
+ // Checks if its a temperature GTDAT -> DT
1670
+ if (/^>DT/.test(parsedData[7])) {
1671
+ const parsedSerialData =
1672
+ parsedData[7] !== '' ? parsedData[7].split('|') : ''
1673
+ let externalData = {
1674
+ eriMask: {
1675
+ raw: '00000000',
1676
+ digitFuelSensor: false,
1677
+ AC100: false,
1678
+ reserved: false,
1679
+ fuelLevelPercentage: false,
1680
+ fuelVolume: false
1681
+ },
1682
+ uartDeviceType: 'Camaleon',
1683
+ fuelSensorData: null
1684
+ }
1685
+ let AC100Devices = [
1686
+ {
1687
+ deviceNumber: `${parsedData[2]}|1`,
1688
+ deviceType: '1',
1689
+ deviceData:
1690
+ parsedSerialData[3] !== '' ? parseFloat(parsedSerialData[3]) : null
1691
+ }
1692
+ ]
1693
+ if (parsedSerialData[4] !== '') {
1694
+ AC100Devices.push({
1695
+ deviceNumber: `${parsedData[2]}|2`,
1696
+ deviceType: '1',
1697
+ deviceData:
1698
+ parsedSerialData[4] !== '' ? parseFloat(parsedSerialData[4]) : null
1699
+ })
1700
+ }
1701
+ externalData = Object.assign(externalData, {
1702
+ AC100Devices: AC100Devices
1703
+ })
1704
+ data = Object.assign(data, {
1705
+ alarm: utils.getAlarm('GTERI', null),
1706
+ externalData: externalData
1707
+ })
1708
+ } else if (/^>ET/.test(parsedData[7])) {
1709
+ // Temp Alarms
1710
+ // GTTMP
1711
+ const parsedSerialData =
1712
+ parsedData[7] !== '' ? parsedData[7].split('|') : ''
1713
+ const alarm = utils.getAlarm('GTTMP', `${parsedSerialData[2]}0`, [
1714
+ `${parsedData[2]}|${parsedSerialData[2]}`,
1715
+ parsedSerialData[4]
1716
+ ])
1717
+ data = Object.assign(data, {
1718
+ alarm: alarm
1719
+ })
1720
+ } else if (/^>ID/.test(parsedData[7])) {
1721
+ // Checks if its a iButton GTDAT -> DT
1722
+ const parsedSerialData =
1723
+ parsedData[7] !== '' ? parsedData[7].split('|') : ''
1724
+ const driverID = parsedSerialData[2] ? parsedSerialData[2] : ''
1725
+ const alarm = utils.getAlarm('GTIDA', `${driverID},1`)
1726
+ data = Object.assign(data, {
1727
+ alarm: alarm
1728
+ })
1729
+ } else {
1730
+ // Normal GTDAT
1731
+ data = Object.assign(data, {
1732
+ alarm: utils.getAlarm(command[1], parsedData[dataIndex])
1733
+ })
1734
+ }
1735
+ } else if (command[1] === 'GTDOS') {
1736
+ let satelliteInfo = utils.includeSatellites(parsedData[17])
1737
+ let jammingSate = utils.includeJammingSate(parsedData[17])
1738
+ let index = 17 + (satelliteInfo ? 1 : 0) + (jammingSate ? 1 : 0)
1739
+
1740
+ data = Object.assign(data, {
1741
+ alarm: utils.getAlarm(command[1], `${parsedData[4]},${parsedData[5]}`),
1742
+ loc: {
1743
+ type: 'Point',
1744
+ coordinates: [parseFloat(parsedData[10]), parseFloat(parsedData[11])]
1745
+ },
1746
+ speed: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
1747
+ gpsStatus: utils.checkGps(
1748
+ parseFloat(parsedData[10]),
1749
+ parseFloat(parsedData[11])
1750
+ ),
1751
+ hdop: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
1752
+ status: null,
1753
+ azimuth: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
1754
+ altitude: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
1755
+ datetime: parsedData[12] !== '' ? utils.parseDate(parsedData[12]) : null,
1756
+ voltage: {
1757
+ battery: null,
1758
+ inputCharge: null,
1759
+ ada: null,
1760
+ adb: null,
1761
+ adc: null
1762
+ },
1763
+ mcc:
1764
+ parsedData[13] !== ''
1765
+ ? utils.latamMcc[parseInt(parsedData[13], 10)]
1766
+ : null,
1767
+ mnc:
1768
+ parsedData[14] !== ''
1769
+ ? utils.getMNC(parsedData[13], parsedData[14])
1770
+ : null,
1771
+ lac: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
1772
+ cid: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
1773
+ satellites:
1774
+ satelliteInfo &&
1775
+ parsedData[index - (satelliteInfo + jammingSate) + 1] !== ''
1776
+ ? parseInt(parsedData[index - (satelliteInfo + jammingSate) + 1], 10)
1777
+ : null,
1778
+ jammingSate:
1779
+ jammingSate && parsedData[index - jammingSate + 1] !== ''
1780
+ ? utils.jammingSateTypes[parsedData[index - jammingSate + 1]]
1781
+ : null,
1782
+ odometer: null,
1783
+ hourmeter: null
1784
+ })
1785
+ } else if (command[1] === 'GTVER') {
1786
+ data = Object.assign(data, {
1787
+ alarm: utils.getAlarm(
1788
+ command[1],
1789
+ [parsedData[5], parsedData[6]],
1790
+ 'gv310lau'
1791
+ ),
1792
+ loc: {
1793
+ type: 'Point',
1794
+ coordinates: [null, null]
1795
+ },
1796
+ speed: null,
1797
+ gpsStatus: null,
1798
+ hdop: null,
1799
+ status: null,
1800
+ azimuth: null,
1801
+ altitude: null,
1802
+ datetime: parsedData[7] !== '' ? utils.parseDate(parsedData[7]) : null,
1803
+ voltage: {
1804
+ battery: null,
1805
+ inputCharge: null,
1806
+ ada: null,
1807
+ adb: null,
1808
+ adc: null
1809
+ },
1810
+ mcc: null,
1811
+ mnc: null,
1812
+ lac: null,
1813
+ cid: null,
1814
+ satellites: null,
1815
+ jammingSate: null,
1816
+ odometer: null,
1817
+ hourmeter: null
1818
+ })
1819
+ } else if (command[1] === 'GTBCS' || command[1] === 'GTBDS') {
1820
+ // Bluetooth connection/desconnection
1821
+ let satelliteInfo = utils.includeSatellites(parsedData[16])
1822
+ let jammingSate = utils.includeJammingSate(parsedData[16])
1823
+ let index = 16 + (satelliteInfo ? 1 : 0) + (jammingSate ? 1 : 0)
1824
+
1825
+ data = Object.assign(data, {
1826
+ alarm: utils.getAlarm(command[1], null, 'gv310lau'),
1827
+ loc: {
1828
+ type: 'Point',
1829
+ coordinates: [parseFloat(parsedData[9]), parseFloat(parsedData[10])]
1830
+ },
1831
+ speed: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
1832
+ gpsStatus: utils.checkGps(
1833
+ parseFloat(parsedData[9]),
1834
+ parseFloat(parsedData[10])
1835
+ ),
1836
+ hdop: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
1837
+ status: null,
1838
+ azimuth: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
1839
+ altitude: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
1840
+ datetime: parsedData[11] !== '' ? utils.parseDate(parsedData[11]) : null,
1841
+ voltage: {
1842
+ battery: null,
1843
+ inputCharge: null,
1844
+ ada: null,
1845
+ adb: null,
1846
+ adc: null
1847
+ },
1848
+ mcc:
1849
+ parsedData[12] !== ''
1850
+ ? utils.latamMcc[parseInt(parsedData[12], 10)]
1851
+ : null,
1852
+ mnc:
1853
+ parsedData[13] !== ''
1854
+ ? utils.getMNC(parsedData[12], parsedData[13])
1855
+ : null,
1856
+ lac: parsedData[14] !== '' ? parseInt(parsedData[14], 16) : null,
1857
+ cid: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
1858
+ satellites:
1859
+ satelliteInfo && parsedData[index] !== ''
1860
+ ? parseInt(parsedData[index - (satelliteInfo + jammingSate) + 1])
1861
+ : null,
1862
+ jammingSate:
1863
+ jammingSate && parsedData[index] !== ''
1864
+ ? utils.jammingSateTypes[parsedData[index - jammingSate + 1]]
1865
+ : null,
1866
+ odometer: null,
1867
+ hourmeter: null,
1868
+ bluetooth: {
1869
+ raw: parsedData[index + 1],
1870
+ connected: parsedData[index + 6] !== '',
1871
+ bluetoothInfo: {
1872
+ name:
1873
+ parsedData[index + 2] !== '' &&
1874
+ utils.nHexDigit(utils.hex2bin(parsedData[index + 1]), 16)[15] ===
1875
+ '1'
1876
+ ? parsedData[index + 2]
1877
+ : null,
1878
+ mac:
1879
+ parsedData[index + 3] !== '' &&
1880
+ utils.nHexDigit(utils.hex2bin(parsedData[index + 1]), 16)[14] ===
1881
+ '1'
1882
+ ? parsedData[index + 3]
1883
+ : null
1884
+ },
1885
+ accessoryInfo: {
1886
+ accessory: null,
1887
+ model: null,
1888
+ name: null,
1889
+ role:
1890
+ parsedData[index + 4] !== '' &&
1891
+ utils.nHexDigit(utils.hex2bin(parsedData[index + 1]), 16)[7] === '1'
1892
+ ? utils.peerRoles[parsedData[index + 4]]
1893
+ : null,
1894
+ type:
1895
+ parsedData[index + 5] !== '' &&
1896
+ utils.nHexDigit(utils.hex2bin(parsedData[index + 1]), 16)[5] === '1'
1897
+ ? utils.peerAddressesTypes[parsedData[index + 5]]
1898
+ : null,
1899
+ mac:
1900
+ parsedData[index + 6] !== '' &&
1901
+ utils.nHexDigit(utils.hex2bin(parsedData[index + 1]), 16)[4] === '1'
1902
+ ? parsedData[index + 6]
1903
+ : null
1904
+ },
1905
+ accessoryData: {
1906
+ temperature: null,
1907
+ humidity: null,
1908
+ mode: null,
1909
+ event: null,
1910
+ tirePresure: null,
1911
+ timestamp: null,
1912
+ enhancedTemperature: null,
1913
+ magDevice: {
1914
+ id: null,
1915
+ eventCounter: null,
1916
+ magnetState: null
1917
+ },
1918
+ relay: {
1919
+ configResult: null,
1920
+ state: null
1921
+ }
1922
+ },
1923
+ disconnectionReason:
1924
+ parsedData[index + 7] !== '' && command[1] === 'GTBDS'
1925
+ ? utils.disconnectionReasons[parsedData[index + 7]]
1926
+ : null
1927
+ }
1928
+ })
1929
+ } else if (command[1] === 'GTBAA') {
1930
+ // Bluetooth alarms
1931
+ let satelliteInfo = false
1932
+ let jammingSate = false
1933
+ let appendIx = 8
1934
+ let appendMask = utils.nHexDigit(utils.hex2bin(parsedData[appendIx]), 16)
1935
+ let btAccessory = parsedData[5]
1936
+ let aNameIx = appendIx + parseInt(appendMask[15])
1937
+ let aMacIx = aNameIx + parseInt(appendMask[14])
1938
+ let aStatIx = aMacIx + parseInt(appendMask[13])
1939
+ let aBatIx = aStatIx + parseInt(appendMask[12])
1940
+ let aTmpIx = aBatIx + parseInt(appendMask[11])
1941
+ let aHumIx = aTmpIx + parseInt(appendMask[10])
1942
+ let ioIx = aHumIx + parseInt(appendMask[8])
1943
+ let aEvIx =
1944
+ appendMask[8] === '1' && appendMask[7] === '1'
1945
+ ? ioIx + 3
1946
+ : ioIx + parseInt(appendMask[7])
1947
+ let pressIx =
1948
+ appendMask[7] === '1' && appendMask[6] === '1'
1949
+ ? aEvIx + 2
1950
+ : aEvIx + parseInt(appendMask[6])
1951
+ let timeIx = pressIx + parseInt(appendMask[5])
1952
+ let eTmpIx = timeIx + parseInt(appendMask[4])
1953
+ let magIx = eTmpIx + parseInt(appendMask[3])
1954
+ let aBatpIx =
1955
+ appendMask[3] === '1' && appendMask[2] === '1'
1956
+ ? magIx + 3
1957
+ : magIx + parseInt(appendMask[2])
1958
+ let relIx = aBatpIx + parseInt(appendMask[1])
1959
+
1960
+ let newIndex = relIx + 1 + parseInt(appendMask[1])
1961
+ let satIndex = newIndex + 11
1962
+
1963
+ // If get satellites is configured
1964
+ if (utils.includeSatellites(parsedData[satIndex])) {
1965
+ satIndex += 1
1966
+ satelliteInfo = true
1967
+ }
1968
+
1969
+ // If get jamming state is configured
1970
+ if (utils.includeJammingSate(parsedData[satIndex])) {
1971
+ satIndex += 1
1972
+ jammingSate = true
1973
+ }
1974
+
1975
+ let bleInfo = {
1976
+ accesory:
1977
+ btAccessory !== '' ? utils.bluetoothAccessories[btAccessory] : null,
1978
+ model: parsedData[6] !== '' ? parseInt(parsedData[6]) : null,
1979
+ name:
1980
+ parsedData[aNameIx] !== '' && appendMask[15] === '1'
1981
+ ? parsedData[aNameIx]
1982
+ : null,
1983
+ role: null,
1984
+ type: null,
1985
+ mac:
1986
+ parsedData[aMacIx] !== '' && appendMask[14] === '1'
1987
+ ? parsedData[aMacIx]
1988
+ : null,
1989
+ status:
1990
+ parsedData[aStatIx] !== '' && appendMask[13] === '1'
1991
+ ? parseInt(parsedData[aStatIx])
1992
+ : null,
1993
+ batteryLevel:
1994
+ parsedData[aBatIx] !== '' && appendMask[12] === '1'
1995
+ ? parseInt(parsedData[aBatIx])
1996
+ : null,
1997
+ batteryPercentage:
1998
+ parsedData[aBatpIx] !== '' && appendMask[2] === '1'
1999
+ ? parseFloat(parsedData[aBatpIx])
2000
+ : null
2001
+ }
2002
+
2003
+ let bleData = {
2004
+ temperature:
2005
+ parsedData[aTmpIx] !== '' && appendMask[11] === '1'
2006
+ ? parseInt(parsedData[aTmpIx])
2007
+ : null,
2008
+ humidity:
2009
+ parsedData[aHumIx] !== '' && appendMask[10] === '1'
2010
+ ? parseInt(parsedData[aHumIx])
2011
+ : null,
2012
+ event:
2013
+ parsedData[aEvIx] !== '' && appendMask[7] === '1'
2014
+ ? parseInt(parsedData[aEvIx])
2015
+ : null,
2016
+ tirePresure:
2017
+ parsedData[pressIx] !== '' && appendMask[6] === '1'
2018
+ ? parseInt(parsedData[pressIx]) / 6.895
2019
+ : null,
2020
+ timestamp:
2021
+ parsedData[timeIx] !== '' && appendMask[5] === '1'
2022
+ ? utils.parseDate(parsedData[timeIx])
2023
+ : null,
2024
+ enhancedTemperature:
2025
+ parsedData[eTmpIx] !== '' && appendMask[4] === '1'
2026
+ ? parseFloat(parsedData[eTmpIx])
2027
+ : null,
2028
+ magDevice: {
2029
+ id:
2030
+ parsedData[magIx] !== '' && appendMask[3] === '1'
2031
+ ? parsedData[magIx]
2032
+ : null,
2033
+ eventCounter:
2034
+ parsedData[magIx + 1] !== '' && appendMask[3] === '1'
2035
+ ? parseInt(parsedData[magIx + 1])
2036
+ : null,
2037
+ magnetState:
2038
+ parsedData[magIx + 2] !== '' && appendMask[3] === '1'
2039
+ ? parseInt(parsedData[magIx + 2])
2040
+ : null
2041
+ },
2042
+ relay: {
2043
+ configResult:
2044
+ parsedData[relIx] !== '' && appendMask[1] === '1'
2045
+ ? utils.relayBLEResults[parsedData[relIx]]
2046
+ : null,
2047
+ state:
2048
+ parsedData[relIx + 1] !== '' && appendMask[1] === '1'
2049
+ ? parseInt(parsedData[relIx + 1])
2050
+ : null
2051
+ }
2052
+ }
2053
+
2054
+ data = Object.assign(data, {
2055
+ alarm: utils.getAlarm(command[1], parsedData[7], [
2056
+ parsedData[4],
2057
+ bleInfo.mac,
2058
+ bleData
2059
+ ]),
2060
+ loc: {
2061
+ type: 'Point',
2062
+ coordinates: [
2063
+ parseFloat(parsedData[newIndex + 4]),
2064
+ parseFloat(parsedData[newIndex + 5])
2065
+ ]
2066
+ },
2067
+ speed:
2068
+ parsedData[newIndex + 1] !== ''
2069
+ ? parseFloat(parsedData[newIndex + 1])
2070
+ : null,
2071
+ gpsStatus: utils.checkGps(
2072
+ parseFloat(parsedData[newIndex + 4]),
2073
+ parseFloat(parsedData[newIndex + 5])
2074
+ ),
2075
+ hdop:
2076
+ parsedData[newIndex] !== '' ? parseFloat(parsedData[newIndex]) : null,
2077
+ status: null,
2078
+ azimuth:
2079
+ parsedData[newIndex + 2] !== ''
2080
+ ? parseFloat(parsedData[newIndex + 2])
2081
+ : null,
2082
+ altitude:
2083
+ parsedData[newIndex + 3] !== ''
2084
+ ? parseFloat(parsedData[newIndex + 3])
2085
+ : null,
2086
+ datetime:
2087
+ parsedData[newIndex + 6] !== ''
2088
+ ? utils.parseDate(parsedData[newIndex + 6])
2089
+ : null,
2090
+ voltage: {
2091
+ battery: null,
2092
+ inputCharge: null,
2093
+ ada: null,
2094
+ adb: null,
2095
+ adc: null
2096
+ },
2097
+ mcc:
2098
+ parsedData[newIndex + 7] !== ''
2099
+ ? parseInt(parsedData[newIndex + 7], 10)
2100
+ : null,
2101
+ mnc:
2102
+ parsedData[newIndex + 8] !== ''
2103
+ ? parseInt(parsedData[newIndex + 8], 10)
2104
+ : null,
2105
+ lac:
2106
+ parsedData[newIndex + 9] !== ''
2107
+ ? parseInt(parsedData[newIndex + 9], 16)
2108
+ : null,
2109
+ cid:
2110
+ parsedData[newIndex + 10] !== ''
2111
+ ? parseInt(parsedData[newIndex + 10], 16)
2112
+ : null,
2113
+ satellites:
2114
+ satelliteInfo &&
2115
+ parsedData[satIndex - (satelliteInfo + jammingSate) + 1] !== ''
2116
+ ? parseInt(parsedData[satIndex - (satelliteInfo + jammingSate) + 1])
2117
+ : null,
2118
+ jammingSate:
2119
+ jammingSate && parsedData[satIndex - jammingSate + 1] !== ''
2120
+ ? utils.jammingSateTypes[parsedData[satIndex - jammingSate + 1]]
2121
+ : null,
2122
+ odometer: null,
2123
+ hourmeter: null,
2124
+ bluetooth: {
2125
+ raw: null,
2126
+ connected: btAccessory !== '',
2127
+ bluetoothInfo: {
2128
+ name:
2129
+ parsedData[aNameIx] !== '' && appendMask[15] === '1'
2130
+ ? parsedData[aNameIx]
2131
+ : null,
2132
+ mac:
2133
+ parsedData[aMacIx] !== '' && appendMask[14] === '1'
2134
+ ? parsedData[aMacIx]
2135
+ : null
2136
+ },
2137
+ accessoryInfo: bleInfo,
2138
+ accessoryData: bleData
2139
+ }
2140
+ })
2141
+ } else if (command[1] === 'GTBID') {
2142
+ // Bluetooth beacon detection
2143
+ let index = 4
2144
+ let number = parsedData[index] !== '' ? parseInt(parsedData[index]) : 1
2145
+
2146
+ let btDevices = []
2147
+ for (let i = 1; i <= number; i++) {
2148
+ let appendMask = utils.nHexDigit(utils.hex2bin(parsedData[index + 2]), 8)
2149
+ let nmIx = index + 2 + parseInt(appendMask[7])
2150
+ let macIx = nmIx + parseInt(appendMask[6])
2151
+ let batIx = macIx + parseInt(appendMask[4])
2152
+ let sigIx = batIx + parseInt(appendMask[1])
2153
+ let typeIx = sigIx + parseInt(appendMask[0])
2154
+ btDevices.push({
2155
+ model:
2156
+ parsedData[index + 1] !== ''
2157
+ ? utils.beaconModels[parsedData[index + 1]]
2158
+ : null,
2159
+ appendMask: parsedData[index + 2] !== '' ? parsedData[index + 2] : null,
2160
+ name:
2161
+ appendMask[7] === '1' && parsedData[nmIx] !== ''
2162
+ ? parsedData[nmIx]
2163
+ : null,
2164
+ mac:
2165
+ appendMask[6] === '1' && parsedData[macIx] !== ''
2166
+ ? parsedData[macIx]
2167
+ : null,
2168
+ battery:
2169
+ appendMask[4] === '1' && parsedData[batIx] !== ''
2170
+ ? parseInt(parsedData[batIx]) / 1000
2171
+ : null,
2172
+ signalStrength:
2173
+ appendMask[1] === '1' && parsedData[sigIx] !== ''
2174
+ ? parseInt(parsedData[sigIx])
2175
+ : null,
2176
+ type:
2177
+ appendMask[0] === '1' && parsedData[typeIx] !== ''
2178
+ ? utils.beaconTypes[parsedData[typeIx]]
2179
+ : null,
2180
+ data:
2181
+ appendMask[0] === '1' && parsedData[typeIx + 1] !== ''
2182
+ ? {
2183
+ idMfrData:
2184
+ parsedData[typeIx] === '0' && parsedData[typeIx + 1] !== ''
2185
+ ? parsedData[typeIx + 1]
2186
+ : null,
2187
+ uuid:
2188
+ parsedData[typeIx] === '1' && parsedData[typeIx + 1] !== ''
2189
+ ? parsedData[typeIx + 1]
2190
+ : null,
2191
+ major:
2192
+ parsedData[typeIx] === '1' && parsedData[typeIx + 2] !== ''
2193
+ ? parsedData[typeIx + 2]
2194
+ : null,
2195
+ minor:
2196
+ parsedData[typeIx] === '1' && parsedData[typeIx + 3] !== ''
2197
+ ? parsedData[typeIx + 3]
2198
+ : null,
2199
+ nid:
2200
+ parsedData[typeIx] === '2' && parsedData[typeIx + 1] !== ''
2201
+ ? parsedData[typeIx + 1]
2202
+ : null,
2203
+ bid:
2204
+ parsedData[typeIx] === '2' && parsedData[typeIx + 2] !== ''
2205
+ ? parsedData[typeIx + 2]
2206
+ : null
2207
+ }
2208
+ : null
2209
+ })
2210
+ let extra =
2211
+ parsedData[typeIx] === '0'
2212
+ ? 1
2213
+ : parsedData[typeIx] === '1' ? 3 : parsedData[typeIx] === '2' ? 2 : 0
2214
+ index = typeIx + 1 + extra
2215
+ }
2216
+
2217
+ let satelliteInfo = utils.includeSatellites(parsedData[index + 12])
2218
+ let jammingSate = utils.includeJammingSate(parsedData[index + 12])
2219
+ let satIndex = index + 12 + satelliteInfo + jammingSate
2220
+
2221
+ data = Object.assign(data, {
2222
+ alarm: utils.getAlarm(command[1], null, 'gv310lau'),
2223
+ loc: {
2224
+ type: 'Point',
2225
+ coordinates: [
2226
+ parseFloat(parsedData[index + 5]),
2227
+ parseFloat(parsedData[index + 6])
2228
+ ]
2229
+ },
2230
+ speed:
2231
+ parsedData[index + 2] !== '' ? parseFloat(parsedData[index + 2]) : null,
2232
+ gpsStatus: utils.checkGps(
2233
+ parseFloat(parsedData[index + 5]),
2234
+ parseFloat(parsedData[index + 6])
2235
+ ),
2236
+ hdop:
2237
+ parsedData[index + 1] !== '' ? parseFloat(parsedData[index + 1]) : null,
2238
+ status: null,
2239
+ azimuth:
2240
+ parsedData[index + 3] !== '' ? parseFloat(parsedData[index + 3]) : null,
2241
+ altitude:
2242
+ parsedData[index + 4] !== '' ? parseFloat(parsedData[index + 4]) : null,
2243
+ datetime:
2244
+ parsedData[index + 7] !== ''
2245
+ ? utils.parseDate(parsedData[index + 7])
2246
+ : null,
2247
+ voltage: {
2248
+ battery: null,
2249
+ inputCharge: null,
2250
+ ada: null,
2251
+ adb: null,
2252
+ adc: null
2253
+ },
2254
+ mcc:
2255
+ parsedData[index + 8] !== ''
2256
+ ? parseInt(parsedData[index + 8], 10)
2257
+ : null,
2258
+ mnc:
2259
+ parsedData[index + 9] !== ''
2260
+ ? parseInt(parsedData[index + 9], 10)
2261
+ : null,
2262
+ lac:
2263
+ parsedData[index + 10] !== ''
2264
+ ? parseInt(parsedData[index + 10], 16)
2265
+ : null,
2266
+ cid:
2267
+ parsedData[index + 11] !== ''
2268
+ ? parseInt(parsedData[index + 11], 16)
2269
+ : null,
2270
+ satellites:
2271
+ satelliteInfo &&
2272
+ parsedData[satIndex - (satelliteInfo + jammingSate) + 1] !== ''
2273
+ ? parseInt(parsedData[satIndex - (satelliteInfo + jammingSate) + 1])
2274
+ : null,
2275
+ odometer: null,
2276
+ hourmeter: null
2277
+ })
2278
+
2279
+ let bluetoothData = {
2280
+ connectedDevices: number,
2281
+ btDevices: btDevices
2282
+ }
2283
+
2284
+ data = Object.assign(data, {
2285
+ bluetoothData: bluetoothData
2286
+ })
2287
+ } else if (command[1] === 'GTVGN' || command[1] === 'GTVGF') {
2288
+ // Virtual ignition
2289
+ let satelliteInfo = utils.includeSatellites(parsedData[18])
2290
+ let jammingSate = utils.includeJammingSate(parsedData[18])
2291
+ let index = 18 + satelliteInfo + jammingSate
2292
+
2293
+ data = Object.assign(data, {
2294
+ alarm: utils.getAlarm(command[1], [parsedData[6], parsedData[5]]),
2295
+ loc: {
2296
+ type: 'Point',
2297
+ coordinates: [parseFloat(parsedData[11]), parseFloat(parsedData[12])]
2298
+ },
2299
+ speed: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
2300
+ gpsStatus: utils.checkGps(
2301
+ parseFloat(parsedData[11]),
2302
+ parseFloat(parsedData[12])
2303
+ ),
2304
+ hdop: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
2305
+ status: null,
2306
+ azimuth: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
2307
+ altitude: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
2308
+ datetime: parsedData[13] !== '' ? utils.parseDate(parsedData[13]) : null,
2309
+ voltage: {
2310
+ battery: null,
2311
+ inputCharge: null,
2312
+ ada: null,
2313
+ adb: null,
2314
+ adc: null
2315
+ },
2316
+ mcc:
2317
+ parsedData[14] !== ''
2318
+ ? utils.latamMcc[parseInt(parsedData[14], 10)]
2319
+ : null,
2320
+ mnc:
2321
+ parsedData[15] !== ''
2322
+ ? utils.getMNC(parsedData[14], parsedData[15])
2323
+ : null,
2324
+ lac: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
2325
+ cid: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
2326
+ satellites:
2327
+ satelliteInfo &&
2328
+ parsedData[index - (satelliteInfo + jammingSate) + 1] !== ''
2329
+ ? parseInt(parsedData[index - (satelliteInfo + jammingSate) + 1])
2330
+ : null,
2331
+ jammingSate:
2332
+ jammingSate && parsedData[index - jammingSate + 1] !== ''
2333
+ ? utils.jammingSateTypes[parsedData[index - jammingSate + 1]]
2334
+ : null,
2335
+ odometer:
2336
+ parsedData[index + 1] !== '' ? parseFloat(parsedData[index + 1]) : null,
2337
+ hourmeter: parsedData[index] !== '' ? parsedData[index] : null
2338
+ })
2339
+ } else if (command[1] === 'GTGSM') {
2340
+ data = Object.assign(data, {
2341
+ alarm: utils.getAlarm(command[1], null),
2342
+ fixType: parsedData[3] !== '' ? parsedData[3] : null
2343
+ })
2344
+ let antData = []
2345
+ var index = 4
2346
+ for (let i = 0; i < 6; i++) {
2347
+ antData.push({
2348
+ mcc: parsedData[index] !== '' ? parseInt(parsedData[index], 10) : null,
2349
+ mnc:
2350
+ parsedData[index + 1] !== ''
2351
+ ? parseInt(parsedData[index + 1], 10)
2352
+ : null,
2353
+ lac:
2354
+ parsedData[index + 2] !== '' ||
2355
+ parsedData[index + 2].toUpperCase() === 'FFFF'
2356
+ ? parseInt(parsedData[index + 2], 16)
2357
+ : null,
2358
+ cid:
2359
+ parsedData[index + 3] !== '' ||
2360
+ parsedData[index + 3].toUpperCase() === 'FFFF'
2361
+ ? parseInt(parsedData[index + 3], 16)
2362
+ : null,
2363
+ rxLevel:
2364
+ parsedData[index + 4] !== ''
2365
+ ? utils.getSignalStrength(
2366
+ 'GSM',
2367
+ parseInt(parsedData[index + 4], 10)
2368
+ )
2369
+ : null,
2370
+ rxSignalPercentage:
2371
+ parsedData[index + 4] !== ''
2372
+ ? utils.getSignalPercentage(
2373
+ 'GSM',
2374
+ parseInt(parsedData[index + 4], 10)
2375
+ )
2376
+ : null
2377
+ })
2378
+ index += 6
2379
+ }
2380
+ data = Object.assign(data, {
2381
+ neighborCells: antData,
2382
+ mcc: parsedData[index] !== '' ? parseInt(parsedData[index], 10) : null,
2383
+ mnc:
2384
+ parsedData[index + 1] !== ''
2385
+ ? parseInt(parsedData[index + 1], 10)
2386
+ : null,
2387
+ lac:
2388
+ parsedData[index + 2] !== '' ||
2389
+ parsedData[index + 2].toUpperCase() === 'FFFF'
2390
+ ? parseInt(parsedData[index + 2], 16)
2391
+ : null,
2392
+ cid:
2393
+ parsedData[index + 3] !== '' ||
2394
+ parsedData[index + 3].toUpperCase() === 'FFFF'
2395
+ ? parseInt(parsedData[index + 3], 16)
2396
+ : null,
2397
+ rxLevel:
2398
+ parsedData[index + 4] !== ''
2399
+ ? utils.getSignalStrength('GSM', parseInt(parsedData[index + 4], 10))
2400
+ : null,
2401
+ rxSignalPercentage:
2402
+ parsedData[index + 4] !== ''
2403
+ ? utils.getSignalPercentage(
2404
+ 'GSM',
2405
+ parseInt(parsedData[index + 4], 10)
2406
+ )
2407
+ : null
2408
+ })
2409
+ } else if (command[1] === 'GTCLT') {
2410
+ // CANBUS Alarm
2411
+ let index = 71 // position append mask
2412
+ let satelliteInfo = false
2413
+
2414
+ // If get satellites is configured
2415
+ if (utils.includeSatellites(parsedData[index])) {
2416
+ index += 1
2417
+ satelliteInfo = true
2418
+ }
2419
+
2420
+ let alarmMask1 =
2421
+ parsedData[5] !== ''
2422
+ ? utils
2423
+ .nHexDigit(utils.hex2bin(parsedData[5]), 32)
2424
+ .split('')
2425
+ .reverse()
2426
+ .join('')
2427
+ : null
2428
+ let alarmMask2 =
2429
+ parsedData[6] !== ''
2430
+ ? utils
2431
+ .nHexDigit(utils.hex2bin(parsedData[6]), 32)
2432
+ .split('')
2433
+ .reverse()
2434
+ .join('')
2435
+ : null
2436
+ let alarmMask3 =
2437
+ parsedData[7] !== ''
2438
+ ? utils
2439
+ .nHexDigit(utils.hex2bin(parsedData[7]), 32)
2440
+ .split('')
2441
+ .reverse()
2442
+ .join('')
2443
+ : null
2444
+ let inicatorsBin =
2445
+ parsedData[28] !== ''
2446
+ ? utils.nHexDigit(utils.hex2bin(parsedData[28]), 16)
2447
+ : null
2448
+ let lights =
2449
+ parsedData[29] !== ''
2450
+ ? utils.nHexDigit(utils.hex2bin(parsedData[29]), 8)
2451
+ : null
2452
+ let doors =
2453
+ parsedData[30] !== ''
2454
+ ? utils.nHexDigit(utils.hex2bin(parsedData[30]), 8)
2455
+ : null
2456
+ let canExpansionMask =
2457
+ parsedData[33] !== ''
2458
+ ? utils
2459
+ .nHexDigit(utils.hex2bin(parsedData[33]), 32)
2460
+ .split('')
2461
+ .reverse()
2462
+ .join('')
2463
+ : null
2464
+ let expansionBin =
2465
+ parsedData[54] !== ''
2466
+ ? utils
2467
+ .nHexDigit(utils.hex2bin(parsedData[54]), 16)
2468
+ .split('')
2469
+ .reverse()
2470
+ .join('')
2471
+ : null
2472
+ let tachographBin =
2473
+ parsedData[27] !== ''
2474
+ ? utils
2475
+ .nHexDigit(utils.hex2bin(parsedData[27]), 8)
2476
+ .split('')
2477
+ .reverse()
2478
+ .join('')
2479
+ : null
2480
+ data = Object.assign(data, {
2481
+ alarm: utils.getAlarm(command[1], parsedData[6], [
2482
+ parsedData[index + 11],
2483
+ parsedData[index + 13]
2484
+ ]),
2485
+ loc: {
2486
+ type: 'Point',
2487
+ coordinates: [parseFloat(parsedData[64]), parseFloat(parsedData[65])]
2488
+ },
2489
+ speed: parsedData[61] !== '' ? parseFloat(parsedData[61]) : null,
2490
+ gpsStatus: utils.checkGps(
2491
+ parseFloat(parsedData[64]),
2492
+ parseFloat(parsedData[65])
2493
+ ),
2494
+ hdop: parsedData[60] !== '' ? parseFloat(parsedData[60]) : null,
2495
+ canBusDataMask: parsedData[10] !== '' ? parsedData[10] : null,
2496
+ azimuth: parsedData[62] !== '' ? parseFloat(parsedData[62]) : null,
2497
+ altitude: parsedData[63] !== '' ? parseFloat(parsedData[63]) : null,
2498
+ datetime: parsedData[66] !== '' ? utils.parseDate(parsedData[66]) : null,
2499
+ mcc:
2500
+ parsedData[67] !== ''
2501
+ ? utils.latamMcc[parseInt(parsedData[67], 10)]
2502
+ : null,
2503
+ mnc:
2504
+ parsedData[68] !== ''
2505
+ ? utils.getMNC(parsedData[67], parsedData[68])
2506
+ : null,
2507
+ lac: parsedData[69] !== '' ? parseInt(parsedData[69], 16) : null,
2508
+ cid: parsedData[70] !== '' ? parseInt(parsedData[70], 16) : null,
2509
+ satellites:
2510
+ satelliteInfo && parsedData[index] !== ''
2511
+ ? parseInt(parsedData[index], 10)
2512
+ : null,
2513
+ odometer: null,
2514
+ hourmeter: null,
2515
+ configuredAlarms: {
2516
+ alarm1: {
2517
+ raw: parsedData[5] !== '' ? parsedData[5] : null,
2518
+ oilLevelLowIndicator: alarmMask1 ? alarmMask1[28] === '1' : null,
2519
+ serviceCallIndicator: alarmMask1 ? alarmMask1[27] === '1' : null,
2520
+ airbagsIndicator: alarmMask1 ? alarmMask1[26] === '1' : null,
2521
+ checkEngineIndicator: alarmMask1 ? alarmMask1[25] === '1' : null,
2522
+ ABSFailureIndicator: alarmMask1 ? alarmMask1[23] === '1' : null,
2523
+ engineHotIndicator: alarmMask1 ? alarmMask1[22] === '1' : null,
2524
+ oilPressureIndicator: alarmMask1 ? alarmMask1[21] === '1' : null,
2525
+ brakeSystemFailureIndicator: alarmMask1
2526
+ ? alarmMask1[20] === '1'
2527
+ : null,
2528
+ batteryIndicator: alarmMask1 ? alarmMask1[19] === '1' : null,
2529
+ coolantLevelLowIndicator: alarmMask1 ? alarmMask1[18] === '1' : null,
2530
+ brakeFluidLowIndicator: alarmMask1 ? alarmMask1[17] === '1' : null,
2531
+ webcastIndicator: alarmMask1 ? alarmMask1[16] === '1' : null,
2532
+ trunkIndicator: alarmMask1 ? alarmMask1[15] === '1' : null,
2533
+ doorsIndicator: alarmMask1 ? alarmMask1[14] === '1' : null,
2534
+ frontFogLightsIndicator: alarmMask1 ? alarmMask1[13] === '1' : null,
2535
+ rearFogLightsIndicator: alarmMask1 ? alarmMask1[12] === '1' : null,
2536
+ highBeamsIndicator: alarmMask1 ? alarmMask1[11] === '1' : null,
2537
+ lowBeamsIndicator: alarmMask1 ? alarmMask1[10] === '1' : null,
2538
+ runningLightsIndicator: alarmMask1 ? alarmMask1[9] === '1' : null,
2539
+ reverseGearIndicator: alarmMask1 ? alarmMask1[8] === '1' : null,
2540
+ centralLockIndicator: alarmMask1 ? alarmMask1[7] === '1' : null,
2541
+ handbrakeIndicator: alarmMask1 ? alarmMask1[6] === '1' : null,
2542
+ clutchPedalIndicator: alarmMask1 ? alarmMask1[5] === '1' : null,
2543
+ brakePedalIndicator: alarmMask1 ? alarmMask1[4] === '1' : null,
2544
+ cruiseControlIndicator: alarmMask1 ? alarmMask1[3] === '1' : null,
2545
+ airConditioningIndicator: alarmMask1 ? alarmMask1[2] === '1' : null,
2546
+ driverSeatbeltIndicator: alarmMask1 ? alarmMask1[1] === '1' : null,
2547
+ fuelLowIndicator: alarmMask1 ? alarmMask1[0] === '1' : null
2548
+ },
2549
+ alarm2: {
2550
+ raw: parsedData[6] !== '' ? parsedData[6] : null,
2551
+ hood: alarmMask2 ? alarmMask2[21] === '1' : null,
2552
+ trunk: alarmMask2 ? alarmMask2[20] === '1' : null,
2553
+ rearRightDoor: alarmMask2 ? alarmMask2[19] === '1' : null,
2554
+ rearLeftDoor: alarmMask2 ? alarmMask2[18] === '1' : null,
2555
+ passengeDoor: alarmMask2 ? alarmMask2[17] === '1' : null,
2556
+ driverDoor: alarmMask2 ? alarmMask2[16] === '1' : null,
2557
+ hazadrLights: alarmMask2 ? alarmMask2[5] === '1' : null,
2558
+ readFogLights: alarmMask2 ? alarmMask2[4] === '1' : null,
2559
+ fronFogLights: alarmMask2 ? alarmMask2[3] === '1' : null,
2560
+ highBeam: alarmMask2 ? alarmMask2[2] === '1' : null,
2561
+ lowBeam: alarmMask2 ? alarmMask2[1] === '1' : null,
2562
+ runningLights: alarmMask2 ? alarmMask2[0] === '1' : null
2563
+ },
2564
+ alarm3: {
2565
+ raw: parsedData[7] !== '' ? parsedData[7] : null,
2566
+ overHighRPM: alarmMask3 ? alarmMask3[3] === '1' : null,
2567
+ underHighRPM: alarmMask3 ? alarmMask3[2] === '1' : null,
2568
+ overLowRPM: alarmMask3 ? alarmMask3[1] === '1' : null,
2569
+ underLowRPM: alarmMask3 ? alarmMask3[0] === '1' : null
2570
+ }
2571
+ },
2572
+ can: {
2573
+ vin: parsedData[11] !== '' ? parseInt(parsedData[11]) : null,
2574
+ ignitionKey:
2575
+ parsedData[12] !== '' ? parseInt(parsedData[12], 10) : null,
2576
+ distance: parsedData[13] !== '' ? parsedData[13] : null,
2577
+ fuelUsed: parsedData[14] !== '' ? parseFloat(parsedData[14]) : null, // float
2578
+ rpm: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null, // int
2579
+ speed: parsedData[16] !== '' ? parseFloat(parsedData[16]) : null,
2580
+ coolantTemp:
2581
+ parsedData[17] !== '' ? parseInt(parsedData[17], 10) : null,
2582
+ fuelConsumption: parsedData[18] !== '' ? parsedData[18] : null,
2583
+ fuelLevel: parsedData[19] !== '' ? parsedData[19] : null,
2584
+ range: parsedData[20] !== '' ? parsedData[20] : null,
2585
+ acceleratorPressure:
2586
+ parsedData[21] !== '' ? parseFloat(parsedData[21]) : null, // %
2587
+ engineHours: parsedData[22] !== '' ? parseFloat(parsedData[22]) : null,
2588
+ drivingTime: parsedData[23] !== '' ? parseFloat(parsedData[23]) : null,
2589
+ idleTime: parsedData[24] !== '' ? parseFloat(parsedData[24]) : null,
2590
+ idleFuelUsed: parsedData[25] !== '' ? parseFloat(parsedData[25]) : null,
2591
+ axleWight2: parsedData[26] !== '' ? parseInt(parsedData[26]) : null,
2592
+ tachograph: {
2593
+ raw: parsedData[27] !== '' ? parsedData[27] : null,
2594
+ validDriverData: tachographBin ? tachographBin[7] === '1' : null,
2595
+ insertedDriverCard: tachographBin ? tachographBin[5] === '1' : null,
2596
+ driverWorkingState: tachographBin
2597
+ ? utils.dWorkingStates[parseInt(tachographBin.substring(3, 5), 2)]
2598
+ : null,
2599
+ drivingTimeState: tachographBin
2600
+ ? utils.dTimeStates[parseInt(tachographBin.substring(5, 8), 2)]
2601
+ : null
2602
+ },
2603
+ indicators: {
2604
+ raw: parsedData[28] !== '' ? parsedData[28] : null,
2605
+ lowFuel: inicatorsBin ? inicatorsBin[0] === '1' : null,
2606
+ driverSeatbelt: inicatorsBin ? inicatorsBin[1] === '1' : null,
2607
+ airConditioning: inicatorsBin ? inicatorsBin[2] === '1' : null,
2608
+ cruiseControl: inicatorsBin ? inicatorsBin[3] === '1' : null,
2609
+ brakePedal: inicatorsBin ? inicatorsBin[4] === '1' : null,
2610
+ clutchPedal: inicatorsBin ? inicatorsBin[5] === '1' : null,
2611
+ handbrake: inicatorsBin ? inicatorsBin[6] === '1' : null,
2612
+ centralLock: inicatorsBin ? inicatorsBin[7] === '1' : null,
2613
+ reverseGear: inicatorsBin ? inicatorsBin[8] === '1' : null,
2614
+ runningLights: inicatorsBin ? inicatorsBin[9] === '1' : null,
2615
+ lowBeams: inicatorsBin ? inicatorsBin[10] === '1' : null,
2616
+ highBeams: inicatorsBin ? inicatorsBin[11] === '1' : null,
2617
+ rearFogLights: inicatorsBin ? inicatorsBin[12] === '1' : null,
2618
+ frontFogLights: inicatorsBin ? inicatorsBin[13] === '1' : null,
2619
+ doors: inicatorsBin ? inicatorsBin[14] === '1' : null,
2620
+ trunk: inicatorsBin ? inicatorsBin[15] === '1' : null
2621
+ },
2622
+ lights: {
2623
+ raw: parsedData[29] !== '' ? parsedData[29] : null,
2624
+ running: lights ? lights[0] === '1' : null,
2625
+ lowBeams: lights ? lights[1] === '1' : null,
2626
+ frontFog: lights ? lights[2] === '1' : null,
2627
+ rearFog: lights ? lights[3] === '1' : null,
2628
+ hazard: lights ? lights[4] === '1' : null
2629
+ },
2630
+ doors: {
2631
+ raw: parsedData[30] !== '' ? parsedData[30] : null,
2632
+ driver: doors ? doors[0] === '1' : null,
2633
+ passenger: doors ? doors[1] === '1' : null,
2634
+ rearLeft: doors ? doors[2] === '1' : null,
2635
+ rearRight: doors ? doors[3] === '1' : null,
2636
+ trunk: doors ? doors[4] === '1' : null,
2637
+ hood: doors ? doors[5] === '1' : null
2638
+ },
2639
+ overSpeedTime: parsedData[31] !== '' ? parsedData[31] : null,
2640
+ overSpeedEngineTime: parsedData[32] !== '' ? parsedData[32] : null,
2641
+ canReportExpansionMask: {
2642
+ raw: parsedData[33] !== '' ? parsedData[33] : null,
2643
+ engineTorque: canExpansionMask ? canExpansionMask[23] === '1' : null,
2644
+ rapidAccelerations: canExpansionMask
2645
+ ? canExpansionMask[22] === '1'
2646
+ : null,
2647
+ rapidBrakings: canExpansionMask ? canExpansionMask[21] === '1' : null,
2648
+ expansionInformation: canExpansionMask
2649
+ ? canExpansionMask[20] === '1'
2650
+ : null,
2651
+ registrationNumber: canExpansionMask
2652
+ ? canExpansionMask[19] === '1'
2653
+ : null,
2654
+ tachographDriver2Name: canExpansionMask
2655
+ ? canExpansionMask[18] === '1'
2656
+ : null,
2657
+ tachographDriver1Name: canExpansionMask
2658
+ ? canExpansionMask[17] === '1'
2659
+ : null,
2660
+ tachographDriver2Card: canExpansionMask
2661
+ ? canExpansionMask[16] === '1'
2662
+ : null,
2663
+ tachographDriver1Card: canExpansionMask
2664
+ ? canExpansionMask[15] === '1'
2665
+ : null,
2666
+ totalBrakeApplications: canExpansionMask
2667
+ ? canExpansionMask[14] === '1'
2668
+ : null,
2669
+ totalAcceleratorKickDownTime: canExpansionMask
2670
+ ? canExpansionMask[13] === '1'
2671
+ : null,
2672
+ totalCruiseControlTime: canExpansionMask
2673
+ ? canExpansionMask[12] === '1'
2674
+ : null,
2675
+ totalEffectiveEngineSpeedTime: canExpansionMask
2676
+ ? canExpansionMask[11] === '1'
2677
+ : null,
2678
+ totalAcceleratorKickDown: canExpansionMask
2679
+ ? canExpansionMask[10] === '1'
2680
+ : null,
2681
+ pedalBrakingFactor: canExpansionMask
2682
+ ? canExpansionMask[9] === '1'
2683
+ : null,
2684
+ engineBrakingFactor: canExpansionMask
2685
+ ? canExpansionMask[8] === '1'
2686
+ : null,
2687
+ analogInputValue: canExpansionMask
2688
+ ? canExpansionMask[7] === '1'
2689
+ : null,
2690
+ tachographDrivingDirection: canExpansionMask
2691
+ ? canExpansionMask[6] === '1'
2692
+ : null,
2693
+ tachographVehicleMotionSignal: canExpansionMask
2694
+ ? canExpansionMask[5] === '1'
2695
+ : null,
2696
+ tachographOverspeedSignal: canExpansionMask
2697
+ ? canExpansionMask[4] === '1'
2698
+ : null,
2699
+ AxleWeight4: canExpansionMask ? canExpansionMask[3] === '1' : null,
2700
+ AxleWeight3: canExpansionMask ? canExpansionMask[2] === '1' : null,
2701
+ AxleWeight1: canExpansionMask ? canExpansionMask[1] === '1' : null,
2702
+ adBlueLevel: canExpansionMask ? canExpansionMask[0] === '1' : null
2703
+ },
2704
+ canExpanded: {
2705
+ adBlueLevel:
2706
+ parsedData[34] !== '' ? parseFloat(parsedData[34]) : null,
2707
+ axleWeight1: parsedData[35] !== '' ? parseInt(parsedData[35]) : null,
2708
+ axleWeight3: parsedData[36] !== '' ? parseInt(parsedData[36]) : null,
2709
+ axleWeight4: parsedData[37] !== '' ? parseInt(parsedData[37]) : null,
2710
+ tachographOverspeedSignal:
2711
+ parsedData[38] !== '' ? parseInt(parsedData[38]) : null,
2712
+ tachographVehicleMotionSignal:
2713
+ parsedData[39] !== '' ? parseInt(parsedData[39]) : null,
2714
+ tachographDrivingDirection:
2715
+ parsedData[40] !== '' ? parseInt(parsedData[40]) : null,
2716
+ analogInputValue:
2717
+ parsedData[41] !== '' ? parseInt(parsedData[41]) : null,
2718
+ engineBrakingFactor:
2719
+ parsedData[42] !== '' ? parseInt(parsedData[42]) : null,
2720
+ pedalBrakingFactor:
2721
+ parsedData[43] !== '' ? parseInt(parsedData[43]) : null,
2722
+ totalAcceleratorKickDown:
2723
+ parsedData[44] !== '' ? parseInt(parsedData[44]) : null,
2724
+ totalEffectiveEngineSpeedTime:
2725
+ parsedData[45] !== '' ? parseFloat(parsedData[45]) : null,
2726
+ totalCruiseControlTime:
2727
+ parsedData[46] !== '' ? parseFloat(parsedData[46]) : null,
2728
+ totalAcceleratorKickDownTime:
2729
+ parsedData[47] !== '' ? parseFloat(parsedData[47]) : null,
2730
+ totalBrakeApplications:
2731
+ parsedData[48] !== '' ? parseInt(parsedData[48]) : null,
2732
+ tachographDriver1Card:
2733
+ parsedData[49] !== '' ? parseInt(parsedData[49]) : null,
2734
+ tachographDriver2Card:
2735
+ parsedData[50] !== '' ? parseInt(parsedData[50]) : null,
2736
+ tachographDriver1Name: parsedData[51] !== '' ? parsedData[51] : null,
2737
+ tachographDriver2Name: parsedData[52] !== '' ? parsedData[52] : null,
2738
+ registrationNumber:
2739
+ parsedData[53] !== '' ? parseInt(parsedData[53]) : null,
2740
+ expansionInformation: {
2741
+ raw: parsedData[54] !== '' ? parsedData[54] : null,
2742
+ webasto: expansionBin ? expansionBin[0] === '1' : null,
2743
+ brakeFluidLowIndicator: expansionBin
2744
+ ? expansionBin[1] === '1'
2745
+ : null,
2746
+ coolantLevelLowIndicator: expansionBin
2747
+ ? expansionBin[2] === '1'
2748
+ : null,
2749
+ batteryIndicator: expansionBin ? expansionBin[3] === '1' : null,
2750
+ brakeSystemFailureIndicator: expansionBin
2751
+ ? expansionBin[4] === '1'
2752
+ : null,
2753
+ oilPressureIndicator: expansionBin ? expansionBin[5] === '1' : null,
2754
+ engineHotIndicator: expansionBin ? expansionBin[6] === '1' : null,
2755
+ ABSFailureIndicator: expansionBin ? expansionBin[7] === '1' : null,
2756
+ checkEngineIndicator: expansionBin ? expansionBin[9] === '1' : null,
2757
+ airbagsIndicator: expansionBin ? expansionBin[10] === '1' : null,
2758
+ serviceCallIndicator: expansionBin
2759
+ ? expansionBin[11] === '1'
2760
+ : null,
2761
+ oilLevelLowIndicator: expansionBin ? expansionBin[12] === '1' : null
2762
+ },
2763
+ rapidBrakings:
2764
+ parsedData[55] !== '' ? parseInt(parsedData[55]) : null,
2765
+ rapidAccelerations:
2766
+ parsedData[56] !== '' ? parseInt(parsedData[56]) : null,
2767
+ engineTorque:
2768
+ parsedData[57] !== '' ? parseFloat(parsedData[57]) : null
2769
+ }
2770
+ }
2771
+ })
2772
+ } else if (command[1] === 'GTSVR') {
2773
+ // Primary Stolen Vehicle Recovery
2774
+ // Primary: GV350CEU - Ghost: GV58LAU
2775
+ let satelliteInfo = utils.includeSatellites(parsedData[18])
2776
+ let jammingState = utils.includeJammingSate(parsedData[18])
2777
+ let index = 18 + satelliteInfo + jammingState
2778
+
2779
+ data = Object.assign(data, {
2780
+ alarm: utils.getAlarm(command[1], parsedData[4]),
2781
+ loc: {
2782
+ type: 'Point',
2783
+ coordinates: [parseFloat(parsedData[12]), parseFloat(parsedData[13])]
2784
+ },
2785
+ speed: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
2786
+ gpsStatus: utils.checkGps(
2787
+ parseFloat(parsedData[12]),
2788
+ parseFloat(parsedData[13])
2789
+ ),
2790
+ hdop: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
2791
+ status: null,
2792
+ azimuth: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
2793
+ altitude: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
2794
+ datetime: parsedData[14] !== '' ? utils.parseDate(parsedData[14]) : null,
2795
+ voltage: {
2796
+ battery: null,
2797
+ inputCharge: null,
2798
+ ada: null,
2799
+ adb: null,
2800
+ adc: null
2801
+ },
2802
+ mcc:
2803
+ parsedData[15] !== ''
2804
+ ? utils.latamMcc[parseInt(parsedData[15], 10)]
2805
+ : null,
2806
+ mnc:
2807
+ parsedData[16] !== ''
2808
+ ? utils.getMNC(parsedData[15], parsedData[16])
2809
+ : null,
2810
+ lac: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
2811
+ cid: parsedData[18] !== '' ? parseInt(parsedData[18], 16) : null,
2812
+ satellites:
2813
+ satelliteInfo &&
2814
+ parsedData[index - (satelliteInfo + jammingState) - 1] !== ''
2815
+ ? parseInt(parsedData[index - (satelliteInfo + jammingState) - 1])
2816
+ : null,
2817
+ jammingState:
2818
+ jammingState && parsedData[index - satelliteInfo - 1] !== ''
2819
+ ? utils.jammingSateTypes[parsedData[index - satelliteInfo - 1]]
2820
+ : null,
2821
+ odometer:
2822
+ parsedData[index + 1] !== '' ? parseFloat(parsedData[index + 1]) : null,
2823
+ hourmeter: parsedData[index] !== '' ? parsedData[index] : null,
2824
+ bluetooth: {
2825
+ mac: parsedData[5] !== '' ? parsedData[5] : null,
2826
+ svrInfo: parsedData[6] !== '' ? parsedData[6] : null
2827
+ }
2828
+ })
2829
+ } else if (command[1] === 'GTLBA') {
2830
+ // Low Battery for FR433 devices
2831
+ let satelliteInfo = utils.includeSatellites(parsedData[17])
2832
+ let jammingState = utils.includeJammingSate(parsedData[17])
2833
+ let index = 17 + satelliteInfo + jammingState
2834
+
2835
+ data = Object.assign(data, {
2836
+ alarm: utils.getAlarm(command[1], [parsedData[4], parsedData[5]]),
2837
+ loc: {
2838
+ type: 'Point',
2839
+ coordinates: [parseFloat(parsedData[10]), parseFloat(parsedData[11])]
2840
+ },
2841
+ speed: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
2842
+ gpsStatus: utils.checkGps(
2843
+ parseFloat(parsedData[10]),
2844
+ parseFloat(parsedData[11])
2845
+ ),
2846
+ hdop: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
2847
+ status: null,
2848
+ azimuth: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
2849
+ altitude: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
2850
+ datetime: parsedData[12] !== '' ? utils.parseDate(parsedData[12]) : null,
2851
+ voltage: {
2852
+ battery: null,
2853
+ inputCharge: null,
2854
+ ada: null,
2855
+ adb: null,
2856
+ adc: null
2857
+ },
2858
+ mcc:
2859
+ parsedData[13] !== ''
2860
+ ? utils.latamMcc[parseInt(parsedData[13], 10)]
2861
+ : null,
2862
+ mnc:
2863
+ parsedData[14] !== ''
2864
+ ? utils.getMNC(parsedData[13], parsedData[14])
2865
+ : null,
2866
+ lac: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
2867
+ cid: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
2868
+ satellites:
2869
+ satelliteInfo &&
2870
+ parsedData[index - (satelliteInfo + jammingState) + 1] !== ''
2871
+ ? parseInt(parsedData[index - (satelliteInfo + jammingState) + 1])
2872
+ : null,
2873
+ jammingState:
2874
+ jammingState && parsedData[index - satelliteInfo + 1] !== ''
2875
+ ? utils.jammingSateTypes[parsedData[index - satelliteInfo + 1]]
2876
+ : null,
2877
+ odometer: null,
2878
+ hourmeter: null
2879
+ })
2880
+ } else if (command[1] === 'GTASC') {
2881
+ // Calibrarion data for XYZ-axis acceleration sensor
2882
+ let satelliteInfo = utils.includeSatellites(parsedData[24])
2883
+ let jammingState = utils.includeJammingSate(parsedData[24])
2884
+ let index = 24 + satelliteInfo + jammingState
2885
+
2886
+ data = Object.assign(data, {
2887
+ alarm: utils.getAlarm(command[1], null),
2888
+ loc: {
2889
+ type: 'Point',
2890
+ coordinates: [parseFloat(parsedData[17]), parseFloat(parsedData[18])]
2891
+ },
2892
+ speed: parsedData[14] !== '' ? parseFloat(parsedData[14]) : null,
2893
+ gpsStatus: utils.checkGps(
2894
+ parseFloat(parsedData[17]),
2895
+ parseFloat(parsedData[18])
2896
+ ),
2897
+ hdop: parsedData[13] !== '' ? parseFloat(parsedData[13]) : null,
2898
+ status: null,
2899
+ azimuth: parsedData[15] !== '' ? parseFloat(parsedData[15]) : null,
2900
+ altitude: parsedData[16] !== '' ? parseFloat(parsedData[16]) : null,
2901
+ datetime: parsedData[19] !== '' ? utils.parseDate(parsedData[19]) : null,
2902
+ voltage: {
2903
+ battery: null,
2904
+ inputCharge: null,
2905
+ ada: null,
2906
+ adb: null,
2907
+ adc: null
2908
+ },
2909
+ mcc:
2910
+ parsedData[20] !== ''
2911
+ ? utils.latamMcc[parseInt(parsedData[20], 10)]
2912
+ : null,
2913
+ mnc:
2914
+ parsedData[21] !== ''
2915
+ ? utils.getMNC(parsedData[20], parsedData[21])
2916
+ : null,
2917
+ lac: parsedData[22] !== '' ? parseInt(parsedData[22], 16) : null,
2918
+ cid: parsedData[23] !== '' ? parseInt(parsedData[23], 16) : null,
2919
+ satellites:
2920
+ satelliteInfo &&
2921
+ parsedData[index - (satelliteInfo + jammingState) + 1] !== ''
2922
+ ? parseInt(parsedData[index - (satelliteInfo + jammingState) + 1])
2923
+ : null,
2924
+ jammingState:
2925
+ jammingState && parsedData[index - satelliteInfo + 1] !== ''
2926
+ ? utils.jammingSateTypes[parsedData[index - satelliteInfo + 1]]
2927
+ : null,
2928
+ calibration: {
2929
+ xForward: parsedData[4] !== '' ? parseFloat(parsedData[4]) : null,
2930
+ yForward: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
2931
+ zForward: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
2932
+ xSide: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
2933
+ ySide: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
2934
+ zSide: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
2935
+ xVertical: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
2936
+ yVertical: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
2937
+ zVertical: parsedData[12] !== '' ? parseFloat(parsedData[12]) : null
2938
+ },
2939
+ odometer: null,
2940
+ hourmeter: null
2941
+ })
2942
+ } else if (command[1] === 'GTHBE') {
2943
+ // Harsh Behavior Information
2944
+ // Only works when GTHBM is in mode 5
2945
+ let satelliteInfo = utils.includeSatellites(parsedData[18])
2946
+ let jammingState = utils.includeJammingSate(parsedData[18])
2947
+ let index = 18 + satelliteInfo + jammingState
2948
+
2949
+ let maxAcc = parsedData[index + 1] !== '' ? parsedData[index + 1] : null
2950
+ let avgAcc = parsedData[index + 2] !== '' ? parsedData[index + 2] : null
2951
+ let duration =
2952
+ parsedData[index + 3] !== '' ? parseFloat(parsedData[index + 3]) : null
2953
+
2954
+ data = Object.assign(data, {
2955
+ alarm: utils.getAlarm(
2956
+ command[1],
2957
+ [parsedData[5], parsedData[6]],
2958
+ [maxAcc, duration]
2959
+ ),
2960
+ loc: {
2961
+ type: 'Point',
2962
+ coordinates: [parseFloat(parsedData[11]), parseFloat(parsedData[12])]
2963
+ },
2964
+ speed: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
2965
+ gpsStatus: utils.checkGps(
2966
+ parseFloat(parsedData[11]),
2967
+ parseFloat(parsedData[12])
2968
+ ),
2969
+ hdop: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
2970
+ status: null,
2971
+ azimuth: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
2972
+ altitude: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
2973
+ datetime: parsedData[13] !== '' ? utils.parseDate(parsedData[13]) : null,
2974
+ voltage: {
2975
+ battery: null,
2976
+ inputCharge: null,
2977
+ ada: null,
2978
+ adb: null,
2979
+ adc: null
2980
+ },
2981
+ mcc:
2982
+ parsedData[14] !== ''
2983
+ ? utils.latamMcc[parseInt(parsedData[14], 10)]
2984
+ : null,
2985
+ mnc:
2986
+ parsedData[15] !== ''
2987
+ ? utils.getMNC(parsedData[14], parsedData[15])
2988
+ : null,
2989
+ lac: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
2990
+ cid: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
2991
+ satellites:
2992
+ satelliteInfo &&
2993
+ parsedData[index - (satelliteInfo + jammingState) + 1] !== ''
2994
+ ? parseInt(parsedData[index - (satelliteInfo + jammingState) + 1])
2995
+ : null,
2996
+ jammingState:
2997
+ jammingState && parsedData[index - satelliteInfo + 1] !== ''
2998
+ ? utils.jammingSateTypes[parsedData[index - satelliteInfo + 1]]
2999
+ : null,
3000
+ maxAcceleration: {
3001
+ // Acceleration in m/s2
3002
+ raw: maxAcc,
3003
+ x: maxAcc
3004
+ ? utils.getAccelerationMagnitude(maxAcc.substring(0, 4), 4)
3005
+ : null,
3006
+ y: maxAcc
3007
+ ? utils.getAccelerationMagnitude(maxAcc.substring(4, 8), 4)
3008
+ : null,
3009
+ z: maxAcc
3010
+ ? utils.getAccelerationMagnitude(maxAcc.substring(8, 12), 4)
3011
+ : null
3012
+ },
3013
+ avgAcceleration: {
3014
+ // Acceleration in m/s2
3015
+ raw: avgAcc,
3016
+ x: avgAcc
3017
+ ? utils.getAccelerationMagnitude(avgAcc.substring(0, 4), 4)
3018
+ : null,
3019
+ y: avgAcc
3020
+ ? utils.getAccelerationMagnitude(avgAcc.substring(4, 8), 4)
3021
+ : null,
3022
+ z: avgAcc
3023
+ ? utils.getAccelerationMagnitude(avgAcc.substring(8, 12), 4)
3024
+ : null
3025
+ },
3026
+ duration: duration,
3027
+ odometer:
3028
+ parsedData[index + 4] !== '' ? parseFloat(parsedData[index + 4]) : null,
3029
+ hourmeter: null
3030
+ })
3031
+ } else {
3032
+ // GTBAR report is not parsed because it only supports one device
3033
+ data = Object.assign(data, {
3034
+ alarm: utils.getAlarm(command[1], raw.toString())
3035
+ })
3036
+ }
3037
+ // Check gps data
3038
+ if (data.loc !== null && typeof data.loc !== 'undefined') {
3039
+ if (
3040
+ data.loc.coordinates[0] === 0 ||
3041
+ isNaN(data.loc.coordinates[0]) ||
3042
+ data.loc.coordinates[1] === 0 ||
3043
+ isNaN(data.loc.coordinates[1])
3044
+ ) {
3045
+ data.loc = null
3046
+ }
3047
+ }
3048
+ return data
3049
+ }
3050
+
3051
+ module.exports = {
3052
+ parse: parse
3053
+ }