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