queclink-parser 1.3.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/gv75w.js ADDED
@@ -0,0 +1,1294 @@
1
+ 'use strict'
2
+ const utils = require('./utils.js')
3
+
4
+ /*
5
+ Parses messages data from GV75W 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-GV75W',
22
+ type: 'data',
23
+ imei: parsedData[2],
24
+ protocolVersion: utils.getProtocolVersion(parsedData[1]),
25
+ temperature: null,
26
+ history: history,
27
+ sentTime: utils.parseDate(parsedData[parsedData.length - 2]),
28
+ serialId: parseInt(parsedData[parsedData.length - 1], 16)
29
+ }
30
+
31
+ // Gps
32
+ if (command[1] === 'GTFRI') {
33
+ try {
34
+ let number = parsedData[6] !== '' ? parseInt(parsedData[6], 10) : 1
35
+ let index = 6 + 12 * number // odometer
36
+
37
+ data = Object.assign(data, {
38
+ alarm: utils.getAlarm(command[1], null),
39
+ loc: {
40
+ type: 'Point',
41
+ coordinates: [parseFloat(parsedData[11]), parseFloat(parsedData[12])]
42
+ },
43
+ speed: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
44
+ gpsStatus: utils.checkGps(
45
+ parseFloat(parsedData[11]),
46
+ parseFloat(parsedData[12])
47
+ ),
48
+ hdop: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
49
+ status: {
50
+ // parsedData[24]
51
+ raw: parsedData[index + 6],
52
+ sos: false,
53
+ input: {
54
+ '1':
55
+ utils.nHexDigit(
56
+ utils.hex2bin(
57
+ utils.nHexDigit(parsedData[index + 6], 10).substring(6, 8)
58
+ ),
59
+ 4
60
+ )[3] === '1',
61
+ '2':
62
+ utils.nHexDigit(
63
+ utils.hex2bin(
64
+ utils.nHexDigit(parsedData[index + 6], 10).substring(6, 8)
65
+ ),
66
+ 4
67
+ )[2] === '1',
68
+ '3':
69
+ utils.nHexDigit(
70
+ utils.hex2bin(
71
+ utils.nHexDigit(parsedData[index + 6], 10).substring(6, 8)
72
+ ),
73
+ 4
74
+ )[1] === '1',
75
+ '4':
76
+ utils.nHexDigit(
77
+ utils.hex2bin(
78
+ utils.nHexDigit(parsedData[index + 6], 10).substring(6, 8)
79
+ ),
80
+ 4
81
+ )[0] === '1'
82
+ },
83
+ output: {
84
+ '1':
85
+ utils.nHexDigit(
86
+ utils.hex2bin(
87
+ utils.nHexDigit(parsedData[index + 6], 10).substring(8, 10)
88
+ ),
89
+ 3
90
+ )[2] === '1',
91
+ '2':
92
+ utils.nHexDigit(
93
+ utils.hex2bin(
94
+ utils.nHexDigit(parsedData[index + 6], 10).substring(8, 10)
95
+ ),
96
+ 3
97
+ )[1] === '1',
98
+ '3':
99
+ utils.nHexDigit(
100
+ utils.hex2bin(
101
+ utils.nHexDigit(parsedData[index + 6], 10).substring(8, 10)
102
+ ),
103
+ 3
104
+ )[0] === '1'
105
+ },
106
+ charge: parseFloat(parsedData[4]) > 5,
107
+ state:
108
+ utils.nHexDigit(parsedData[index + 6], 10).substring(4, 6) !== ''
109
+ ? utils.states[ // eslint-disable-line
110
+ utils.nHexDigit(parsedData[index + 6], 10).substring(4, 6)
111
+ ]
112
+ : null
113
+ },
114
+ azimuth: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
115
+ altitude: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
116
+ datetime:
117
+ parsedData[13] !== '' ? utils.parseDate(parsedData[13]) : null,
118
+ voltage: {
119
+ battery:
120
+ parsedData[index + 5] !== ''
121
+ ? parseFloat(parsedData[index + 5])
122
+ : null, // percentage
123
+ inputCharge:
124
+ parsedData[4] !== '' ? parseFloat(parsedData[4]) / 1000 : null,
125
+ ada: null,
126
+ adb: null
127
+ },
128
+ mcc: parsedData[14] !== '' ? parseInt(parsedData[14], 10) : null,
129
+ mnc: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null,
130
+ lac: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
131
+ cid: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
132
+ odometer:
133
+ parsedData[index + 1] !== ''
134
+ ? parseFloat(parsedData[index + 1])
135
+ : null,
136
+ hourmeter:
137
+ parsedData[index + 2] !== ''
138
+ ? utils.getHoursForHourmeter(parsedData[index + 2])
139
+ : null
140
+ })
141
+ } catch (err) {
142
+ return { type: 'UNKNOWN', raw: data.raw.toString() }
143
+ }
144
+ } else if (command[1] === 'GTERI') {
145
+ // GPS with AC100 Devices Connected
146
+ let number = parsedData[7] !== '' ? parseInt(parsedData[7], 10) : 1
147
+ let index = 7 + 12 * number // odometer
148
+ data = Object.assign(data, {
149
+ alarm: utils.getAlarm(command[1], null),
150
+ loc: {
151
+ type: 'Point',
152
+ coordinates: [parseFloat(parsedData[12]), parseFloat(parsedData[13])]
153
+ },
154
+ speed: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
155
+ gpsStatus: utils.checkGps(
156
+ parseFloat(parsedData[12]),
157
+ parseFloat(parsedData[13])
158
+ ),
159
+ hdop: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
160
+ status: {
161
+ // parsedData[index + 6]
162
+ raw: parsedData[index + 6],
163
+ sos: false,
164
+ input: {
165
+ '1':
166
+ utils.nHexDigit(
167
+ utils.hex2bin(
168
+ utils.nHexDigit(parsedData[index + 6], 10).substring(6, 8)
169
+ ),
170
+ 4
171
+ )[3] === '1',
172
+ '2':
173
+ utils.nHexDigit(
174
+ utils.hex2bin(
175
+ utils.nHexDigit(parsedData[index + 6], 10).substring(6, 8)
176
+ ),
177
+ 4
178
+ )[2] === '1',
179
+ '3':
180
+ utils.nHexDigit(
181
+ utils.hex2bin(
182
+ utils.nHexDigit(parsedData[index + 6], 10).substring(6, 8)
183
+ ),
184
+ 4
185
+ )[1] === '1',
186
+ '4':
187
+ utils.nHexDigit(
188
+ utils.hex2bin(
189
+ utils.nHexDigit(parsedData[index + 6], 10).substring(6, 8)
190
+ ),
191
+ 4
192
+ )[0] === '1'
193
+ },
194
+ output: {
195
+ '1':
196
+ utils.nHexDigit(
197
+ utils.hex2bin(
198
+ utils.nHexDigit(parsedData[index + 6], 10).substring(8, 10)
199
+ ),
200
+ 3
201
+ )[2] === '1',
202
+ '2':
203
+ utils.nHexDigit(
204
+ utils.hex2bin(
205
+ utils.nHexDigit(parsedData[index + 6], 10).substring(8, 10)
206
+ ),
207
+ 3
208
+ )[1] === '1',
209
+ '3':
210
+ utils.nHexDigit(
211
+ utils.hex2bin(
212
+ utils.nHexDigit(parsedData[index + 6], 10).substring(8, 10)
213
+ ),
214
+ 3
215
+ )[0] === '1'
216
+ },
217
+ charge: parseFloat(parsedData[5]) > 5,
218
+ state:
219
+ utils.nHexDigit(parsedData[index + 6], 10).substring(4, 6) !== ''
220
+ ? utils.states[ // eslint-disable-line
221
+ utils.nHexDigit(parsedData[index + 6], 10).substring(4, 6)
222
+ ]
223
+ : null
224
+ },
225
+ azimuth: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
226
+ altitude: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
227
+ datetime: parsedData[14] !== '' ? utils.parseDate(parsedData[14]) : null,
228
+ voltage: {
229
+ battery:
230
+ parsedData[index + 5] !== ''
231
+ ? parseFloat(parsedData[index + 5])
232
+ : null, // percentage
233
+ inputCharge:
234
+ parsedData[5] !== '' ? parseFloat(parsedData[5]) / 1000 : null,
235
+ ada: null,
236
+ adb: null
237
+ },
238
+ mcc: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null,
239
+ mnc: parsedData[16] !== '' ? parseInt(parsedData[16], 10) : null,
240
+ lac: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
241
+ cid: parsedData[18] !== '' ? parseInt(parsedData[18], 16) : null,
242
+ odometer:
243
+ parsedData[index + 1] !== '' ? parseFloat(parsedData[index + 1]) : null,
244
+ hourmeter:
245
+ parsedData[index + 2] !== ''
246
+ ? utils.getHoursForHourmeter(parsedData[index + 2])
247
+ : null
248
+ })
249
+ // External Data
250
+ const digitFuelSensor =
251
+ utils.nHexDigit(utils.hex2bin(parsedData[4]), 5)[4] === '1'
252
+ const AC100 = utils.nHexDigit(utils.hex2bin(parsedData[4]), 5)[3] === '1'
253
+ const reserved = utils.nHexDigit(utils.hex2bin(parsedData[4]), 5)[2] === '1'
254
+ const fuelLevelPercentage =
255
+ utils.nHexDigit(utils.hex2bin(parsedData[4]), 5)[1] === '1'
256
+ const fuelVolume =
257
+ utils.nHexDigit(utils.hex2bin(parsedData[4]), 5)[0] === '1'
258
+ const fuelSensorData = digitFuelSensor ? parsedData[index + 9] : null
259
+ const ac100DevicesConnected =
260
+ AC100 && digitFuelSensor
261
+ ? parseInt(parsedData[index + 9], 10)
262
+ : AC100 && !digitFuelSensor ? parseInt(parsedData[index + 8], 10) : 0
263
+
264
+ let externalData = {
265
+ eriMask: {
266
+ raw: parsedData[4],
267
+ digitFuelSensor: digitFuelSensor,
268
+ AC100: AC100,
269
+ reserved: reserved,
270
+ fuelLevelPercentage: fuelLevelPercentage,
271
+ fuelVolume: fuelVolume
272
+ },
273
+ uartDeviceType: utils.uartDeviceTypes[parsedData[index + 7]]
274
+ }
275
+ // Fuel Sensor
276
+ if (parsedData[index + 7] === '1') {
277
+ if (digitFuelSensor && !AC100) {
278
+ externalData = Object.assign(externalData, {
279
+ fuelSensorData: {
280
+ data: fuelSensorData,
281
+ sensorType: parsedData[index + 10],
282
+ percentage:
283
+ fuelLevelPercentage && parsedData[index + 11] !== ''
284
+ ? parseInt(parsedData[index + 11], 10)
285
+ : null,
286
+ volume:
287
+ fuelVolume && fuelLevelPercentage && parsedData[index + 12] !== ''
288
+ ? parseInt(parsedData[index + 12], 10)
289
+ : fuelVolume &&
290
+ !fuelLevelPercentage &&
291
+ parsedData[index + 11] !== ''
292
+ ? parseInt(parsedData[index + 11], 10)
293
+ : null
294
+ },
295
+ AC100Devices: null
296
+ })
297
+ } else if (!digitFuelSensor && AC100) {
298
+ let ac100Devices = []
299
+ let count = index + 10
300
+ for (var i = 0; i < ac100DevicesConnected; i++) {
301
+ ac100Devices.push({
302
+ deviceNumber: parsedData[count],
303
+ deviceType: parsedData[count + 1],
304
+ deviceData: parsedData[count + 2]
305
+ ? utils.getTempInCelciousDegrees(parsedData[count + 2])
306
+ : null
307
+ })
308
+ count += 3
309
+ }
310
+ externalData = Object.assign(externalData, {
311
+ fuelSensorData: null,
312
+ AC100Devices: ac100Devices
313
+ })
314
+ } else if (digitFuelSensor && AC100) {
315
+ let ac100Devices = []
316
+ let count =
317
+ fuelVolume && fuelLevelPercentage
318
+ ? 33
319
+ : fuelVolume && !fuelLevelPercentage ? index + 13 : index + 12
320
+ for (var j = 0; j < ac100DevicesConnected; j++) {
321
+ ac100Devices.push({
322
+ deviceNumber: parsedData[count],
323
+ deviceType: parsedData[count + 1],
324
+ deviceData: parsedData[count + 2]
325
+ ? utils.getTempInCelciousDegrees(parsedData[count + 2])
326
+ : null
327
+ })
328
+ count += 3
329
+ }
330
+ externalData = Object.assign(externalData, {
331
+ fuelSensorData: {
332
+ data: fuelSensorData,
333
+ sensorType: parsedData[index + 11],
334
+ percentage:
335
+ fuelLevelPercentage && parsedData[index + 12] !== ''
336
+ ? parseInt(parsedData[index + 12], 10)
337
+ : null,
338
+ volume:
339
+ fuelVolume && fuelLevelPercentage && parsedData[index + 13] !== ''
340
+ ? parseInt(parsedData[index + 13], 10)
341
+ : fuelVolume &&
342
+ !fuelLevelPercentage &&
343
+ parsedData[index + 12] !== ''
344
+ ? parseInt(parsedData[index + 12], 10)
345
+ : null
346
+ },
347
+ AC100Devices: ac100Devices
348
+ })
349
+ }
350
+ } else if (parsedData[index + 7] === '2') {
351
+ // AC100 1 Wire Bus
352
+ if (!digitFuelSensor && AC100) {
353
+ let ac100Devices = []
354
+ let count = index + 9
355
+ for (var k = 0; k < ac100DevicesConnected; k++) {
356
+ ac100Devices.push({
357
+ deviceNumber: parsedData[count],
358
+ deviceType: parsedData[count + 1],
359
+ deviceData: parsedData[count + 2]
360
+ ? utils.getTempInCelciousDegrees(parsedData[count + 2])
361
+ : null
362
+ })
363
+ count += 3
364
+ }
365
+ externalData = Object.assign(externalData, {
366
+ fuelSensorData: null,
367
+ AC100Devices: ac100Devices
368
+ })
369
+ } else if (digitFuelSensor && !AC100) {
370
+ externalData = Object.assign(externalData, {
371
+ fuelSensorData: {
372
+ data: fuelSensorData,
373
+ sensorType: null,
374
+ percentage: null,
375
+ volume: null
376
+ },
377
+ AC100Devices: null
378
+ })
379
+ } else if (digitFuelSensor && AC100) {
380
+ let ac100Devices = []
381
+ let count = index + 10
382
+ for (var l = 0; l < ac100DevicesConnected; l++) {
383
+ ac100Devices.push({
384
+ deviceNumber: parsedData[count],
385
+ deviceType: parsedData[count + 1],
386
+ deviceData: parsedData[count + 2]
387
+ ? utils.getTempInCelciousDegrees(parsedData[count + 2])
388
+ : null
389
+ })
390
+ count += 3
391
+ }
392
+ externalData = Object.assign(externalData, {
393
+ fuelSensorData: {
394
+ data: fuelSensorData,
395
+ sensorType: null,
396
+ percentage: null,
397
+ volume: null
398
+ },
399
+ AC100Devices: ac100Devices
400
+ })
401
+ }
402
+ }
403
+ data = Object.assign(data, {
404
+ externalData: externalData
405
+ })
406
+ } else if (command[1] === 'GTHBD') {
407
+ // Heartbeat. It must response an ACK command
408
+ data = Object.assign(data, {
409
+ alarm: utils.getAlarm(command[1], null)
410
+ })
411
+ } else if (command[1] === 'GTINF') {
412
+ // General Info Report
413
+ data = Object.assign(data, {
414
+ alarm: utils.getAlarm(command[1], null),
415
+ state: utils.states[parsedData[4]],
416
+ gsmInfo: {
417
+ SIM_ICC: parsedData[5],
418
+ RSSI_dBm: parsedData[6],
419
+ RSSI_quality:
420
+ parsedData[7] !== ''
421
+ ? 100 * parseInt(parseFloat(parsedData[7]) / 7, 10)
422
+ : null // Percentage
423
+ },
424
+ backupBattery: {
425
+ using: parsedData[10] === '1',
426
+ voltage: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
427
+ charging: parsedData[12] === '1'
428
+ },
429
+ externalGPSAntenna: parsedData[15] === '0',
430
+ status: {
431
+ // parsedData[24]
432
+ raw: parsedData[18] + parsedData[19],
433
+ sos: false,
434
+ input: {
435
+ '4': utils.nHexDigit(utils.hex2bin(parsedData[20][1]), 4)[0] === '1',
436
+ '3': utils.nHexDigit(utils.hex2bin(parsedData[20][1]), 4)[1] === '1',
437
+ '2': utils.nHexDigit(utils.hex2bin(parsedData[20][1]), 4)[2] === '1',
438
+ '1': utils.nHexDigit(utils.hex2bin(parsedData[20][1]), 4)[3] === '1'
439
+ },
440
+ output: {
441
+ '4': utils.nHexDigit(utils.hex2bin(parsedData[19][1]), 4)[0] === '1',
442
+ '3': utils.nHexDigit(utils.hex2bin(parsedData[19][1]), 4)[1] === '1',
443
+ '2': utils.nHexDigit(utils.hex2bin(parsedData[19][1]), 4)[2] === '1',
444
+ '1': utils.nHexDigit(utils.hex2bin(parsedData[19][1]), 4)[3] === '1'
445
+ },
446
+ charge: parsedData[8] === '1'
447
+ },
448
+ voltage: {
449
+ battery:
450
+ parsedData[11] !== ''
451
+ ? parseInt(100 * (parseFloat(parsedData[11]) / 5), 10)
452
+ : null, // percentage
453
+ inputCharge:
454
+ parsedData[9] !== '' ? parseFloat(parsedData[9]) / 1000 : null,
455
+ ada: null,
456
+ adb: null
457
+ },
458
+ lastFixUTCTime:
459
+ parsedData[16] !== '' ? utils.parseDate(parsedData[16]) : null,
460
+ timezoneOffset: parsedData[20]
461
+ })
462
+ } else if (
463
+ command[1] === 'GTTOW' ||
464
+ command[1] === 'GTDIS' ||
465
+ command[1] === 'GTIOB' ||
466
+ command[1] === 'GTSPD' ||
467
+ command[1] === 'GTSOS' ||
468
+ command[1] === 'GTRTL' ||
469
+ command[1] === 'GTDOG' ||
470
+ command[1] === 'GTIGL' ||
471
+ command[1] === 'GTHBM'
472
+ ) {
473
+ // Common Alarms
474
+ data = Object.assign(data, {
475
+ alarm: utils.getAlarm(command[1], parsedData[5], 'gv75w'),
476
+ loc: {
477
+ type: 'Point',
478
+ coordinates: [parseFloat(parsedData[11]), parseFloat(parsedData[12])]
479
+ },
480
+ speed: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
481
+ gpsStatus: utils.checkGps(
482
+ parseFloat(parsedData[11]),
483
+ parseFloat(parsedData[12])
484
+ ),
485
+ hdop: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
486
+ status: null,
487
+ azimuth: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
488
+ altitude: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
489
+ datetime: parsedData[13] !== '' ? utils.parseDate(parsedData[13]) : null,
490
+ voltage: {
491
+ battery: null,
492
+ inputCharge: null,
493
+ ada: null,
494
+ adb: null
495
+ },
496
+ mcc: parsedData[14] !== '' ? parseInt(parsedData[14], 10) : null,
497
+ mnc: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null,
498
+ lac: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
499
+ cid: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
500
+ odometer: parsedData[19] !== '' ? parseFloat(parsedData[19]) : null,
501
+ hourmeter: null
502
+ })
503
+ } else if (command[1] === 'GTTMP') {
504
+ // Temperature Alarm
505
+ let number = parsedData[7] !== '' ? parseInt(parsedData[7], 10) : 1
506
+ let index = 8 + 12 * number // odometer
507
+ data = Object.assign(data, {
508
+ alarm: utils.getAlarm(command[1], parsedData[6], [
509
+ parsedData[index + 9],
510
+ parsedData[index + 11]
511
+ ]),
512
+ loc: {
513
+ type: 'Point',
514
+ coordinates: [parseFloat(parsedData[12]), parseFloat(parsedData[13])]
515
+ },
516
+ speed: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
517
+ gpsStatus: utils.checkGps(
518
+ parseFloat(parsedData[12]),
519
+ parseFloat(parsedData[13])
520
+ ),
521
+ hdop: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
522
+ status: {
523
+ // parsedData[24]
524
+ raw: `${parsedData[index + 4]}${parsedData[index + 5]}`,
525
+ sos: false,
526
+ input: {
527
+ '3':
528
+ utils.nHexDigit(utils.hex2bin(parsedData[index + 4][1]), 4)[1] ===
529
+ '1',
530
+ '2':
531
+ utils.nHexDigit(utils.hex2bin(parsedData[index + 4][1]), 4)[2] ===
532
+ '1',
533
+ '1':
534
+ utils.nHexDigit(utils.hex2bin(parsedData[index + 4][1]), 4)[3] ===
535
+ '1'
536
+ },
537
+ output: {
538
+ '2':
539
+ utils.nHexDigit(utils.hex2bin(parsedData[index + 5][1]), 4)[2] ===
540
+ '1',
541
+ '1':
542
+ utils.nHexDigit(utils.hex2bin(parsedData[index + 5][1]), 4)[3] ===
543
+ '1'
544
+ },
545
+ charge: parseFloat(parsedData[5]) > 5,
546
+ state: null
547
+ },
548
+ azimuth: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
549
+ altitude: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
550
+ datetime: parsedData[14] !== '' ? utils.parseDate(parsedData[14]) : null,
551
+ voltage: {
552
+ battery: null, // percentage
553
+ inputCharge:
554
+ parsedData[5] !== '' ? parseFloat(parsedData[5]) / 1000 : null,
555
+ ada:
556
+ parsedData[index + 2] !== ''
557
+ ? parseFloat(parsedData[index + 2]) / 1000
558
+ : null,
559
+ adb:
560
+ parsedData[index + 3] !== ''
561
+ ? parseFloat(parsedData[index + 3]) / 1000
562
+ : null
563
+ },
564
+ mcc: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null,
565
+ mnc: parsedData[16] !== '' ? parseInt(parsedData[16], 10) : null,
566
+ lac: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
567
+ cid: parsedData[18] !== '' ? parseInt(parsedData[18], 16) : null,
568
+ odometer: parsedData[index] !== '' ? parseFloat(parsedData[index]) : null,
569
+ hourmeter:
570
+ parsedData[index + 1] !== ''
571
+ ? utils.getHoursForHourmeter(parsedData[index + 1])
572
+ : null
573
+ })
574
+ } else if (command[1] === 'GTEPS' || command[1] === 'GTAIS') {
575
+ // External low battery and Low voltage for analog input
576
+ data = Object.assign(data, {
577
+ alarm: utils.getAlarm(command[1], parsedData[5]),
578
+ loc: {
579
+ type: 'Point',
580
+ coordinates: [parseFloat(parsedData[11]), parseFloat(parsedData[12])]
581
+ },
582
+ speed: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
583
+ gpsStatus: utils.checkGps(
584
+ parseFloat(parsedData[11]),
585
+ parseFloat(parsedData[12])
586
+ ),
587
+ hdop: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
588
+ status: null,
589
+ azimuth: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
590
+ altitude: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
591
+ datetime: parsedData[13] !== '' ? utils.parseDate(parsedData[13]) : null,
592
+ voltage: {
593
+ battery: parsedData[23] !== '' ? parseFloat(parsedData[23]) : null, // percentage
594
+ inputCharge:
595
+ parsedData[4] !== '' ? parseFloat(parsedData[4]) / 1000 : null,
596
+ ada: null,
597
+ adb: null
598
+ },
599
+ mcc: parsedData[14] !== '' ? parseInt(parsedData[14], 10) : null,
600
+ mnc: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null,
601
+ lac: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
602
+ cid: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
603
+ odometer: parsedData[19] !== '' ? parseFloat(parsedData[19]) : null,
604
+ hourmeter:
605
+ parsedData[20] !== ''
606
+ ? utils.getHoursForHourmeter(parsedData[20])
607
+ : null
608
+ })
609
+ } else if (
610
+ command[1] === 'GTPNA' ||
611
+ command[1] === 'GTPFA' ||
612
+ command[1] === 'GTPDP'
613
+ ) {
614
+ // Event report (It uses the last GPS data and MCC info)
615
+ data = Object.assign(data, {
616
+ alarm: utils.getAlarm(command[1], null),
617
+ loc: null,
618
+ speed: null,
619
+ gpsStatus: null,
620
+ hdop: null,
621
+ status: null,
622
+ azimuth: null,
623
+ altitude: null,
624
+ datetime: parsedData[4] !== '' ? utils.parseDate(parsedData[4]) : null,
625
+ voltage: {
626
+ battery: null,
627
+ inputCharge: null,
628
+ ada: null,
629
+ adb: null
630
+ },
631
+ mcc: null,
632
+ mnc: null,
633
+ lac: null,
634
+ cid: null,
635
+ odometer: null,
636
+ hourmeter: null
637
+ })
638
+ } else if (
639
+ command[1] === 'GTMPN' ||
640
+ command[1] === 'GTMPF' ||
641
+ command[1] === 'GTJDR'
642
+ ) {
643
+ data = Object.assign(data, {
644
+ alarm: utils.getAlarm(command[1], null),
645
+ loc: {
646
+ type: 'Point',
647
+ coordinates: [parseFloat(parsedData[8]), parseFloat(parsedData[9])]
648
+ },
649
+ speed: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
650
+ gpsStatus: utils.checkGps(
651
+ parseFloat(parsedData[8]),
652
+ parseFloat(parsedData[9])
653
+ ),
654
+ hdop: parsedData[4] !== '' ? parseFloat(parsedData[4]) : null,
655
+ status: null,
656
+ azimuth: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
657
+ altitude: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
658
+ datetime: parsedData[10] !== '' ? utils.parseDate(parsedData[10]) : null,
659
+ voltage: {
660
+ battery: null,
661
+ inputCharge: null,
662
+ ada: null,
663
+ adb: null
664
+ },
665
+ mcc: parsedData[11] !== '' ? parseInt(parsedData[11], 10) : null,
666
+ mnc: parsedData[12] !== '' ? parseInt(parsedData[12], 10) : null,
667
+ lac: parsedData[13] !== '' ? parseInt(parsedData[13], 16) : null,
668
+ cid: parsedData[14] !== '' ? parseInt(parsedData[14], 16) : null,
669
+ odometer: null,
670
+ hourmeter: null
671
+ })
672
+ } else if (command[1] === 'GTCRA') {
673
+ data = Object.assign(data, {
674
+ alarm: utils.getAlarm(command[1], parsedData[4]),
675
+ loc: {
676
+ type: 'Point',
677
+ coordinates: [parseFloat(parsedData[9]), parseFloat(parsedData[10])]
678
+ },
679
+ speed: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
680
+ gpsStatus: utils.checkGps(
681
+ parseFloat(parsedData[9]),
682
+ parseFloat(parsedData[10])
683
+ ),
684
+ hdop: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
685
+ status: null,
686
+ azimuth: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
687
+ altitude: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
688
+ datetime: parsedData[11] !== '' ? utils.parseDate(parsedData[11]) : null,
689
+ voltage: {
690
+ battery: null,
691
+ inputCharge: null,
692
+ ada: null,
693
+ adb: null
694
+ },
695
+ mcc: parsedData[12] !== '' ? parseInt(parsedData[12], 10) : null,
696
+ mnc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
697
+ lac: parsedData[14] !== '' ? parseInt(parsedData[14], 16) : null,
698
+ cid: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
699
+ odometer: null,
700
+ hourmeter: null
701
+ })
702
+ } else if (
703
+ command[1] === 'GTJDS' ||
704
+ command[1] === 'GTANT' ||
705
+ command[1] === 'GTRMD'
706
+ ) {
707
+ data = Object.assign(data, {
708
+ alarm: utils.getAlarm(command[1], parsedData[4]),
709
+ loc: {
710
+ type: 'Point',
711
+ coordinates: [parseFloat(parsedData[9]), parseFloat(parsedData[10])]
712
+ },
713
+ speed: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
714
+ gpsStatus: utils.checkGps(
715
+ parseFloat(parsedData[9]),
716
+ parseFloat(parsedData[10])
717
+ ),
718
+ hdop: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
719
+ status: null,
720
+ azimuth: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
721
+ altitude: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
722
+ datetime: parsedData[11] !== '' ? utils.parseDate(parsedData[11]) : null,
723
+ voltage: {
724
+ battery: null,
725
+ inputCharge: null,
726
+ ada: null,
727
+ adb: null
728
+ },
729
+ mcc: parsedData[12] !== '' ? parseInt(parsedData[12], 10) : null,
730
+ mnc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
731
+ lac: parsedData[14] !== '' ? parseInt(parsedData[14], 16) : null,
732
+ cid: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
733
+ odometer: null,
734
+ hourmeter: null
735
+ })
736
+ } else if (command[1] === 'GTBPL') {
737
+ data = Object.assign(data, {
738
+ alarm: utils.getAlarm(command[1], null),
739
+ loc: {
740
+ type: 'Point',
741
+ coordinates: [parseFloat(parsedData[9]), parseFloat(parsedData[10])]
742
+ },
743
+ speed: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
744
+ gpsStatus: utils.checkGps(
745
+ parseFloat(parsedData[9]),
746
+ parseFloat(parsedData[10])
747
+ ),
748
+ hdop: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
749
+ status: null,
750
+ azimuth: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
751
+ altitude: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
752
+ datetime: parsedData[11] !== '' ? utils.parseDate(parsedData[11]) : null,
753
+ voltage: {
754
+ battery: parsedData[4] !== '' ? parseFloat(parsedData[4]) : null,
755
+ inputCharge: null,
756
+ ada: null,
757
+ adb: null
758
+ },
759
+ mcc: parsedData[12] !== '' ? parseInt(parsedData[12], 10) : null,
760
+ mnc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
761
+ lac: parsedData[14] !== '' ? parseInt(parsedData[14], 16) : null,
762
+ cid: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
763
+ odometer: null,
764
+ hourmeter: null
765
+ })
766
+ } else if (command[1] === 'GTIGN' || command[1] === 'GTIGF') {
767
+ data = Object.assign(data, {
768
+ alarm: utils.getAlarm(command[1], parsedData[4]),
769
+ loc: {
770
+ type: 'Point',
771
+ coordinates: [parseFloat(parsedData[9]), parseFloat(parsedData[10])]
772
+ },
773
+ speed: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
774
+ gpsStatus: utils.checkGps(
775
+ parseFloat(parsedData[9]),
776
+ parseFloat(parsedData[10])
777
+ ),
778
+ hdop: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
779
+ status: null,
780
+ azimuth: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
781
+ altitude: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
782
+ datetime: parsedData[11] !== '' ? utils.parseDate(parsedData[11]) : null,
783
+ voltage: {
784
+ battery: null,
785
+ inputCharge: null,
786
+ ada: null,
787
+ adb: null
788
+ },
789
+ mcc: parsedData[12] !== '' ? parseInt(parsedData[12], 10) : null,
790
+ mnc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
791
+ lac: parsedData[14] !== '' ? parseInt(parsedData[14], 16) : null,
792
+ cid: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
793
+ odometer: parsedData[18] !== '' ? parseFloat(parsedData[18]) : null,
794
+ hourmeter:
795
+ parsedData[17] !== ''
796
+ ? utils.getHoursForHourmeter(parsedData[17])
797
+ : null
798
+ })
799
+ } else if (command[1] === 'GTIDN' || command[1] === 'GTIDF') {
800
+ data = Object.assign(data, {
801
+ alarm: utils.getAlarm(command[1], parsedData[5]),
802
+ loc: {
803
+ type: 'Point',
804
+ coordinates: [parseFloat(parsedData[10]), parseFloat(parsedData[11])]
805
+ },
806
+ speed: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
807
+ gpsStatus: utils.checkGps(
808
+ parseFloat(parsedData[10]),
809
+ parseFloat(parsedData[11])
810
+ ),
811
+ hdop: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
812
+ status: null,
813
+ azimuth: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
814
+ altitude: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
815
+ datetime: parsedData[12] !== '' ? utils.parseDate(parsedData[12]) : null,
816
+ voltage: {
817
+ battery: null,
818
+ inputCharge: null,
819
+ ada: null,
820
+ adb: null
821
+ },
822
+ mcc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
823
+ mnc: parsedData[14] !== '' ? parseInt(parsedData[14], 10) : null,
824
+ lac: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
825
+ cid: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
826
+ odometer: parsedData[18] !== '' ? parseFloat(parsedData[18]) : null,
827
+ hourmeter: null
828
+ })
829
+ } else if (
830
+ command[1] === 'GTSTR' ||
831
+ command[1] === 'GTSTP' ||
832
+ command[1] === 'GTLSP'
833
+ ) {
834
+ data = Object.assign(data, {
835
+ alarm: utils.getAlarm(command[1], null),
836
+ loc: {
837
+ type: 'Point',
838
+ coordinates: [parseFloat(parsedData[10]), parseFloat(parsedData[11])]
839
+ },
840
+ speed: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
841
+ gpsStatus: utils.checkGps(
842
+ parseFloat(parsedData[10]),
843
+ parseFloat(parsedData[11])
844
+ ),
845
+ hdop: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
846
+ status: null,
847
+ azimuth: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
848
+ altitude: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
849
+ datetime: parsedData[12] !== '' ? utils.parseDate(parsedData[12]) : null,
850
+ voltage: {
851
+ battery: null,
852
+ inputCharge: null,
853
+ ada: null,
854
+ adb: null
855
+ },
856
+ mcc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
857
+ mnc: parsedData[14] !== '' ? parseInt(parsedData[14], 10) : null,
858
+ lac: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
859
+ cid: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
860
+ odometer: parsedData[18] !== '' ? parseFloat(parsedData[18]) : null,
861
+ hourmeter: null
862
+ })
863
+ } else if (command[1] === 'GTSTT') {
864
+ // Motion State Changed
865
+ data = Object.assign(data, {
866
+ alarm: utils.getAlarm(command[1], null),
867
+ loc: {
868
+ type: 'Point',
869
+ coordinates: [parseFloat(parsedData[9]), parseFloat(parsedData[10])]
870
+ },
871
+ speed: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
872
+ gpsStatus: utils.checkGps(
873
+ parseFloat(parsedData[9]),
874
+ parseFloat(parsedData[10])
875
+ ),
876
+ hdop: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
877
+ status: null,
878
+ azimuth: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
879
+ altitude: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
880
+ datetime: parsedData[11] !== '' ? utils.parseDate(parsedData[11]) : null,
881
+ voltage: {
882
+ battery: null,
883
+ inputCharge: null,
884
+ ada: null,
885
+ adb: null
886
+ },
887
+ mcc: parsedData[12] !== '' ? parseInt(parsedData[12], 10) : null,
888
+ mnc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
889
+ lac: parsedData[14] !== '' ? parseInt(parsedData[14], 16) : null,
890
+ cid: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
891
+ odometer: null,
892
+ hourmeter: null
893
+ })
894
+ } else if (command[1] === 'GTGSS') {
895
+ // GPS Status
896
+ data = Object.assign(data, {
897
+ alarm: utils.getAlarm(command[1], parsedData[4]),
898
+ loc: {
899
+ type: 'Point',
900
+ coordinates: [parseFloat(parsedData[12]), parseFloat(parsedData[13])]
901
+ },
902
+ speed: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
903
+ gpsStatus: utils.checkGps(
904
+ parseFloat(parsedData[12]),
905
+ parseFloat(parsedData[13])
906
+ ),
907
+ hdop: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
908
+ status: null,
909
+ azimuth: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
910
+ altitude: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
911
+ datetime: parsedData[14] !== '' ? utils.parseDate(parsedData[14]) : null,
912
+ voltage: {
913
+ battery: null,
914
+ inputCharge: null,
915
+ ada: null,
916
+ adb: null
917
+ },
918
+ mcc: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null,
919
+ mnc: parsedData[16] !== '' ? parseInt(parsedData[16], 10) : null,
920
+ lac: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
921
+ cid: parsedData[18] !== '' ? parseInt(parsedData[18], 16) : null,
922
+ odometer: null,
923
+ hourmeter: null
924
+ })
925
+ } else if (command[1] === 'GTIDA') {
926
+ // iButton
927
+ data = Object.assign(data, {
928
+ alarm: utils.getAlarm(command[1], `${parsedData[5]},${parsedData[6]}`),
929
+ loc: {
930
+ type: 'Point',
931
+ coordinates: [parseFloat(parsedData[12]), parseFloat(parsedData[13])]
932
+ },
933
+ speed: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
934
+ gpsStatus: utils.checkGps(
935
+ parseFloat(parsedData[12]),
936
+ parseFloat(parsedData[13])
937
+ ),
938
+ hdop: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
939
+ status: null,
940
+ azimuth: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
941
+ altitude: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
942
+ datetime: parsedData[14] !== '' ? utils.parseDate(parsedData[14]) : null,
943
+ voltage: {
944
+ battery: null,
945
+ inputCharge: null,
946
+ ada: null,
947
+ adb: null
948
+ },
949
+ mcc: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null,
950
+ mnc: parsedData[16] !== '' ? parseInt(parsedData[16], 10) : null,
951
+ lac: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
952
+ cid: parsedData[18] !== '' ? parseInt(parsedData[18], 16) : null,
953
+ odometer: parsedData[20] !== '' ? parseFloat(parsedData[20]) : null,
954
+ hourmeter: null
955
+ })
956
+ } else if (command[1] === 'GTCAN') {
957
+ let inicatorsBin =
958
+ parsedData[24] !== ''
959
+ ? utils.nHexDigit(utils.hex2bin(parsedData[24]), 16)
960
+ : null
961
+ let lights =
962
+ parsedData[25] !== ''
963
+ ? utils.nHexDigit(utils.hex2bin(parsedData[25]), 8)
964
+ : null
965
+ let doors =
966
+ parsedData[26] !== ''
967
+ ? utils.nHexDigit(utils.hex2bin(parsedData[26]), 8)
968
+ : null
969
+ data = Object.assign(data, {
970
+ alarm: utils.getAlarm(command[1], parsedData[4]),
971
+ loc: {
972
+ type: 'Point',
973
+ coordinates: [parseFloat(parsedData[59]), parseFloat(parsedData[60])]
974
+ },
975
+ speed: parsedData[56] !== '' ? parseFloat(parsedData[56]) : null,
976
+ gpsStatus: utils.checkGps(
977
+ parseFloat(parsedData[59]),
978
+ parseFloat(parsedData[60])
979
+ ),
980
+ hdop: parsedData[55] !== '' ? parseFloat(parsedData[55]) : null,
981
+ status: null,
982
+ azimuth: parsedData[57] !== '' ? parseFloat(parsedData[57]) : null,
983
+ altitude: parsedData[58] !== '' ? parseFloat(parsedData[58]) : null,
984
+ datetime: parsedData[61] !== '' ? utils.parseDate(parsedData[61]) : null,
985
+ voltage: {
986
+ battery: null,
987
+ inputCharge: null,
988
+ ada: null,
989
+ adb: null
990
+ },
991
+ mcc: parsedData[62] !== '' ? parseInt(parsedData[62], 10) : null,
992
+ mnc: parsedData[63] !== '' ? parseInt(parsedData[63], 10) : null,
993
+ lac: parsedData[64] !== '' ? parseInt(parsedData[64], 16) : null,
994
+ cid: parsedData[65] !== '' ? parseInt(parsedData[65], 16) : null,
995
+ odometer: null,
996
+ hourmeter: null,
997
+ can: {
998
+ comunicationOk: parsedData[5] === '1',
999
+ vin: parsedData[7] !== '' ? parsedData[7] : null,
1000
+ ignitionKey: parsedData[8] !== '' ? parseInt(parsedData[8], 10) : null,
1001
+ distance: parsedData[9] !== '' ? parsedData[9] : null,
1002
+ fuelUsed: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null, // float
1003
+ rpm: parsedData[11] !== '' ? parseInt(parsedData[11], 10) : null, // int
1004
+ speed: parsedData[12] !== '' ? parseFloat(parsedData[12]) : null,
1005
+ coolantTemp:
1006
+ parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
1007
+ fuelConsumption: parsedData[14] !== '' ? parsedData[14] : null,
1008
+ fuelLevel: parsedData[15] !== '' ? parsedData[15] : null,
1009
+ range: parsedData[16] !== '' ? parsedData[16] : null,
1010
+ acceleratorPressure:
1011
+ parsedData[17] !== '' ? parseFloat(parsedData[17]) : null, // %
1012
+ engineHours: parsedData[18] !== '' ? parseFloat(parsedData[18]) : null,
1013
+ drivingTime: parsedData[19] !== '' ? parseFloat(parsedData[19]) : null,
1014
+ idleTime: parsedData[20] !== '' ? parseFloat(parsedData[20]) : null,
1015
+ idleFuelUsed: parsedData[21] !== '' ? parseFloat(parsedData[21]) : null,
1016
+ axleWight: parsedData[22] !== '' ? parsedData[22] : null,
1017
+ tachograph: parsedData[23] !== '' ? parsedData[23] : null,
1018
+ indicators: {
1019
+ raw: parsedData[24] !== '' ? parsedData[24] : null,
1020
+ lowFuel: inicatorsBin ? inicatorsBin[0] === '1' : null,
1021
+ driverSeatbelt: inicatorsBin ? inicatorsBin[1] === '1' : null,
1022
+ airConditioning: inicatorsBin ? inicatorsBin[2] === '1' : null,
1023
+ cruiseControl: inicatorsBin ? inicatorsBin[3] === '1' : null,
1024
+ brakePedal: inicatorsBin ? inicatorsBin[4] === '1' : null,
1025
+ clutchPedal: inicatorsBin ? inicatorsBin[5] === '1' : null,
1026
+ handbrake: inicatorsBin ? inicatorsBin[6] === '1' : null,
1027
+ centralLock: inicatorsBin ? inicatorsBin[7] === '1' : null,
1028
+ reverseGear: inicatorsBin ? inicatorsBin[8] === '1' : null,
1029
+ runningLights: inicatorsBin ? inicatorsBin[9] === '1' : null,
1030
+ lowBeams: inicatorsBin ? inicatorsBin[10] === '1' : null,
1031
+ highBeams: inicatorsBin ? inicatorsBin[11] === '1' : null,
1032
+ rearFogLights: inicatorsBin ? inicatorsBin[12] === '1' : null,
1033
+ frontFogLights: inicatorsBin ? inicatorsBin[13] === '1' : null,
1034
+ doors: inicatorsBin ? inicatorsBin[14] === '1' : null,
1035
+ trunk: inicatorsBin ? inicatorsBin[15] === '1' : null
1036
+ },
1037
+ lights: {
1038
+ raw: parsedData[25] !== '' ? parsedData[25] : null,
1039
+ running: lights ? lights[0] === '1' : null,
1040
+ lowBeams: lights ? lights[1] === '1' : null,
1041
+ frontFog: lights ? lights[2] === '1' : null,
1042
+ rearFog: lights ? lights[3] === '1' : null,
1043
+ hazard: lights ? lights[4] === '1' : null
1044
+ },
1045
+ doors: {
1046
+ raw: parsedData[26] !== '' ? parsedData[26] : null,
1047
+ driver: doors ? doors[0] === '1' : null,
1048
+ passenger: doors ? doors[1] === '1' : null,
1049
+ rearLeft: doors ? doors[2] === '1' : null,
1050
+ rearRight: doors ? doors[3] === '1' : null,
1051
+ trunk: doors ? doors[4] === '1' : null,
1052
+ hood: doors ? doors[5] === '1' : null
1053
+ },
1054
+ overSpeedTime: parsedData[27] !== '' ? parsedData[27] : null,
1055
+ overSpeedEngineTime: parsedData[28] !== '' ? parsedData[28] : null,
1056
+ adblueLevel: parsedData[30] !== '' ? parsedData[30] : null
1057
+ }
1058
+ })
1059
+ } else if (command[1] === 'GTDAT') {
1060
+ let dataIndex = 4
1061
+ // Short format
1062
+ if (parsedData.length === 7) {
1063
+ data = Object.assign(data, {
1064
+ loc: null,
1065
+ speed: null,
1066
+ gpsStatus: null,
1067
+ hdop: null,
1068
+ status: null,
1069
+ azimuth: null,
1070
+ altitude: null,
1071
+ datetime: null,
1072
+ voltage: {
1073
+ battery: null,
1074
+ inputCharge: null,
1075
+ ada: null,
1076
+ adb: null
1077
+ },
1078
+ mcc: null,
1079
+ mnc: null,
1080
+ lac: null,
1081
+ cid: null,
1082
+ odometer: null,
1083
+ hourmeter: null
1084
+ })
1085
+ } else {
1086
+ dataIndex = 7
1087
+ data = Object.assign(data, {
1088
+ loc: {
1089
+ type: 'Point',
1090
+ coordinates: [parseFloat(parsedData[12]), parseFloat(parsedData[13])]
1091
+ },
1092
+ speed: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
1093
+ gpsStatus: utils.checkGps(
1094
+ parseFloat(parsedData[12]),
1095
+ parseFloat(parsedData[13])
1096
+ ),
1097
+ hdop: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
1098
+ status: null,
1099
+ azimuth: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
1100
+ altitude: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
1101
+ datetime:
1102
+ parsedData[14] !== '' ? utils.parseDate(parsedData[14]) : null,
1103
+ voltage: {
1104
+ battery: null,
1105
+ inputCharge: null,
1106
+ ada: null,
1107
+ adb: null
1108
+ },
1109
+ mcc: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null,
1110
+ mnc: parsedData[16] !== '' ? parseInt(parsedData[16], 10) : null,
1111
+ lac: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
1112
+ cid: parsedData[18] !== '' ? parseInt(parsedData[18], 16) : null,
1113
+ odometer: null,
1114
+ hourmeter: null
1115
+ })
1116
+ }
1117
+
1118
+ // Checks if its a temperature GTDAT -> DT
1119
+ if (/^>DT/.test(parsedData[7])) {
1120
+ const parsedSerialData =
1121
+ parsedData[7] !== '' ? parsedData[7].split('|') : ''
1122
+ let externalData = {
1123
+ eriMask: {
1124
+ raw: '00000000',
1125
+ digitFuelSensor: false,
1126
+ AC100: false,
1127
+ reserved: false,
1128
+ fuelLevelPercentage: false,
1129
+ fuelVolume: false
1130
+ },
1131
+ uartDeviceType: 'Camaleon',
1132
+ fuelSensorData: null
1133
+ }
1134
+ let AC100Devices = [
1135
+ {
1136
+ deviceNumber: `${parsedData[2]}|1`,
1137
+ deviceType: '1',
1138
+ deviceData:
1139
+ parsedSerialData[3] !== '' ? parseFloat(parsedSerialData[3]) : null
1140
+ }
1141
+ ]
1142
+ if (parsedSerialData[4] !== '') {
1143
+ AC100Devices.push({
1144
+ deviceNumber: `${parsedData[2]}|2`,
1145
+ deviceType: '1',
1146
+ deviceData:
1147
+ parsedSerialData[4] !== '' ? parseFloat(parsedSerialData[4]) : null
1148
+ })
1149
+ }
1150
+ externalData = Object.assign(externalData, {
1151
+ AC100Devices: AC100Devices
1152
+ })
1153
+ data = Object.assign(data, {
1154
+ alarm: utils.getAlarm('GTERI', null),
1155
+ externalData: externalData
1156
+ })
1157
+ } else if (/^>ET/.test(parsedData[7])) {
1158
+ // Temp Alarms
1159
+ // GTTMP
1160
+ const parsedSerialData =
1161
+ parsedData[7] !== '' ? parsedData[7].split('|') : ''
1162
+ const alarm = utils.getAlarm('GTTMP', `${parsedSerialData[2]}0`, [
1163
+ `${parsedData[2]}|${parsedSerialData[2]}`,
1164
+ parsedSerialData[4]
1165
+ ])
1166
+ data = Object.assign(data, {
1167
+ alarm: alarm
1168
+ })
1169
+ } else if (/^>ID/.test(parsedData[7])) {
1170
+ // Checks if its a iButton GTDAT -> DT
1171
+ const parsedSerialData =
1172
+ parsedData[7] !== '' ? parsedData[7].split('|') : ''
1173
+ const driverID = parsedSerialData[2] ? parsedSerialData[2] : ''
1174
+ const alarm = utils.getAlarm('GTIDA', `${driverID},1`)
1175
+ data = Object.assign(data, {
1176
+ alarm: alarm
1177
+ })
1178
+ } else {
1179
+ // Normal GTDAT
1180
+ data = Object.assign(data, {
1181
+ alarm: utils.getAlarm(command[1], parsedData[dataIndex])
1182
+ })
1183
+ }
1184
+ } else if (command[1] === 'GTDTT') {
1185
+ // short format
1186
+ if (parsedData.length === 11) {
1187
+ data = Object.assign(data, {
1188
+ alarm: utils.getAlarm(command[1], parsedData[8], parsedData[6]),
1189
+ loc: null,
1190
+ speed: null,
1191
+ gpsStatus: null,
1192
+ hdop: null,
1193
+ status: null,
1194
+ azimuth: null,
1195
+ altitude: null,
1196
+ datetime: null,
1197
+ voltage: {
1198
+ battery: null,
1199
+ inputCharge: null,
1200
+ ada: null,
1201
+ adb: null
1202
+ },
1203
+ mcc: null,
1204
+ mnc: null,
1205
+ lac: null,
1206
+ cid: null,
1207
+ odometer: null,
1208
+ hourmeter: null
1209
+ })
1210
+ } else {
1211
+ // Long format
1212
+ data = Object.assign(data, {
1213
+ alarm: utils.getAlarm(command[1], parsedData[8], parsedData[6]),
1214
+ loc: {
1215
+ type: 'Point',
1216
+ coordinates: [parseFloat(parsedData[13]), parseFloat(parsedData[14])]
1217
+ },
1218
+ speed: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
1219
+ gpsStatus: utils.checkGps(
1220
+ parseFloat(parsedData[13]),
1221
+ parseFloat(parsedData[14])
1222
+ ),
1223
+ hdop: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
1224
+ status: null,
1225
+ azimuth: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
1226
+ altitude: parsedData[12] !== '' ? parseFloat(parsedData[12]) : null,
1227
+ datetime:
1228
+ parsedData[15] !== '' ? utils.parseDate(parsedData[15]) : null,
1229
+ voltage: {
1230
+ battery: null,
1231
+ inputCharge: null,
1232
+ ada: null,
1233
+ adb: null
1234
+ },
1235
+ mcc: parsedData[16] !== '' ? parseInt(parsedData[16], 10) : null,
1236
+ mnc: parsedData[17] !== '' ? parseInt(parsedData[17], 10) : null,
1237
+ lac: parsedData[18] !== '' ? parseInt(parsedData[18], 16) : null,
1238
+ cid: parsedData[19] !== '' ? parseInt(parsedData[19], 16) : null,
1239
+ odometer: null,
1240
+ hourmeter: null
1241
+ })
1242
+ }
1243
+ } else if (command[1] === 'GTDOS') {
1244
+ data = Object.assign(data, {
1245
+ alarm: utils.getAlarm(command[1], `${parsedData[4]},${parsedData[5]}`),
1246
+ loc: {
1247
+ type: 'Point',
1248
+ coordinates: [parseFloat(parsedData[10]), parseFloat(parsedData[11])]
1249
+ },
1250
+ speed: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
1251
+ gpsStatus: utils.checkGps(
1252
+ parseFloat(parsedData[10]),
1253
+ parseFloat(parsedData[11])
1254
+ ),
1255
+ hdop: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
1256
+ status: null,
1257
+ azimuth: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
1258
+ altitude: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
1259
+ datetime: parsedData[12] !== '' ? utils.parseDate(parsedData[12]) : null,
1260
+ voltage: {
1261
+ battery: null,
1262
+ inputCharge: null,
1263
+ ada: null,
1264
+ adb: null
1265
+ },
1266
+ mcc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
1267
+ mnc: parsedData[14] !== '' ? parseInt(parsedData[14], 10) : null,
1268
+ lac: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
1269
+ cid: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
1270
+ odometer: null,
1271
+ hourmeter: null
1272
+ })
1273
+ } else {
1274
+ data = Object.assign(data, {
1275
+ alarm: utils.getAlarm(command[1], null)
1276
+ })
1277
+ }
1278
+ // Check gps data
1279
+ if (data.loc !== null && typeof data.loc !== 'undefined') {
1280
+ if (
1281
+ data.loc.coordinates[0] === 0 ||
1282
+ isNaN(data.loc.coordinates[0]) ||
1283
+ data.loc.coordinates[1] === 0 ||
1284
+ isNaN(data.loc.coordinates[1])
1285
+ ) {
1286
+ data.loc = null
1287
+ }
1288
+ }
1289
+ return data
1290
+ }
1291
+
1292
+ module.exports = {
1293
+ parse: parse
1294
+ }