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