queclink-parser 1.9.16 → 1.9.18

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/CHANGELOG.md CHANGED
@@ -1,3 +1,20 @@
1
+ #### 1.9.18 (2025-10-13)
2
+
3
+ ##### Bug Fixes
4
+
5
+ * **can:**
6
+ * se corrige indexación para GTERI sin datos CANbus ([2f80889d](https://github.com/jaayesta/queclink-parser/commit/2f80889de3d2d0adf77989ad37d9f336eb72a316))
7
+ * se adapta parser de GTERI con CANbus para FW12 ([20c6deee](https://github.com/jaayesta/queclink-parser/commit/20c6deeea2a688d0d1902eea69d448eb17bb064c))
8
+ * se corrige parser para GTERI con CANbus. ([a4aa7e68](https://github.com/jaayesta/queclink-parser/commit/a4aa7e689a9a36cae14c327568387dcded7c9ed3))
9
+ * se corrige parser para GTCAN. ([d1c72161](https://github.com/jaayesta/queclink-parser/commit/d1c721615f313d5fab1aaaff3766a37ac334dde0))
10
+ * **canbus:** asignación de odometro, horometro y velocidad dependen de comunicationOk ([6749610b](https://github.com/jaayesta/queclink-parser/commit/6749610beda92e671629a5b7b2f909c0a3a980b7))
11
+
12
+ #### 1.9.17 (2025-09-22)
13
+
14
+ ##### New Features
15
+
16
+ * **getAlarm:** add handling for SOS button press event ([b39d687d](https://github.com/jaayesta/queclink-parser/commit/b39d687df059e467fa71bae887ac195e3189c6aa))
17
+
1
18
  #### 1.9.16 (2025-09-03)
2
19
 
3
20
  ##### New Features
package/example.js CHANGED
@@ -84,9 +84,13 @@ var newdtt = '+RESP:GTDTT,6E0802,868589060722215,,,,0,264,�Q4���,OzJ(�
84
84
  var tpms = '+RESP:GTERI,6E0802,868589060612317,,00000104,14134,10,1,1,0.0,160,536.2,-70.676717,-33.422117,20250331211305,0730,0001,3345,003B3901,01,12,5809.4,0000132:27:33,,,,98,110000,0,0,203FFFFF,,,,,,,,,,,,,,,,,,,,,,,FFFFFF,,,,,,,,,,,,,,,,,,,,,,,,,6,00,13,0,00000000,4007,,780541484188,1,0,02,6,5,0DAD092E,083F,,7805413E6D0D,1,3423,23,35,23.50,06,12,0,005E4EB3,0617,RF,08351B002230,1,38,235,20250331211239,07,12,0,005F50B3,0617,LF,08351B00234E,1,40,237,20250331211221,08,12,0,005F4CB3,0617,RR,08351B00222D,1,36,237,20250331211215,09,12,0,00624CB3,0617,LR,08351B002247,1,36,245,20250331211209,20250331211306,AD50$'
85
85
  var newdtt = '+RESP:GTDTT,6E1102,866775051622785,GV310LAU,,,0,9,1134122,0,0.0,173,72.7,117.129363,31.839142,20221201085356,0460,0000,550B,085BE2AA,01,6,,,,,20221201085357,2E9E$'
86
86
  var dis58 = '+RESP:GTDIS,8020040803,866314061861249,,,10,1,1,0.0,349,399.7,-70.770383,-33.474911,20250516154520,0730,0001,333F,003D0711,01,11,55.2,20250516154521,B08D$'
87
-
88
87
  var test = '+RESP:GTERI,6E0C03,868589060367102,,00000104,13621,10,1,1,0.0,5,190.7,-71.541291,-33.576625,20250829142314,0730,0001,16A9,00305D03,01,12,31513.0,0002500:06:38,,,,100,110000,0,0,0,1,00,13,0,,4007,,FFFFFFFFFFFF,0,,20250829142315,D3AF$'
89
88
  var test2 ="+RESP:GTERI,6E0C03,868589060839548,,00000104,27841,10,1,1,0.0,1,195.5,-71.541562,-33.576687,20250903005133,0730,0001,16A9,00305D03,01,12,21626.9,0000531:51:33,,,,100,210900,0,1,203A2B9F,,2,H7241302,243017.00,0,H4.5,P91.60,,37.09,10.33,0040,00,0.00,0.00,A2BAFF,62,,,,,,,,11910,37.09,1.50,2.20,,,0,, 1,00,13,0,00000000,4007,,78054143F0A5,1,0,20250903005134,C7A3$"
89
+ var cantest = "+RESP:GTCAN,6E0C03,868589061025071,,00,1,E03C1FEF,,2,H5098434,159048.47,1592,70,H4.6,P87.60,,57,160.81,124.42,,00,0.00,0.00,C1FFFF,72,,0,,,,,,94009,62330,1338,160.81,43.27,3.54,3340,,,1,,,,1,0.0,359,475.7,-70.770337,-33.475763,20251013162220,0730,0001,333F,003D0701,01,12,20251013162222,36E8$"
90
+ var cantest2 = "+RESP:GTERI,6E0902,868589060831545,,00000104,14065,10,1,1,89.5,264,144.0,-71.280091,-33.650247,20251013160701,0730,0001,3391,02574D03,01,12,434363.5,0000250:27:42,,,,100,220100,0,1,203D24BF,1FUBCYCSX9HAA9810,2,H4345338,132280.27,1571,90,,70,60.29,FFFF,,00,0.00,0.00,D24CFF,,,,,,,,,5421,159.71,,,0000,0,,1,00,13,0,00000000,4007,,7805414BB11A,1,0,20251013160703,19C3$"
91
+ var cantest3 = '+RESP:GTERI,6E0C03,868589061025071,,00000104,28534,10,1,1,14.3,157,474.3,-70.771113,-33.475845,20251013160929,0730,0001,333F,003D0701,01,12,1371.2,0000029:30:58,,,,100,220100,0,1,203C1FEF,,2,H5098433,159048.28,911,66,H1.3,P87.60,,0,160.75,124.40,,00,0.00,0.00,C1FFFF,72,,0,,,,,,93992,62309,1338,160.75,43.27,3.54,3339,,,1,,6,00,13,0,00000000,4007,,7805414BB20C,1,0,FE,3,4,000A,78054149496C,,FE,3,4,000A,780541494969,,FE,3,4,000A,7805414948E1,3090,FE,3,4,000A,780541416190,,FE,3,4,000A,780541494879,3060,20251013160931,36B6$'
92
+ var t = "+RESP:GTERI,6E0C03,868589061025071,,00000100,25711,10,1,1,0.0,234,471.5,-70.771257,-33.476015,20251013163817,0730,0001,333F,003D0701,01,12,1371.3,0000029:46:32,,,,100,210100,0,6,00,13,0,00000000,4007,,7805414BB20C,1,0,FE,3,4,000A,780541416190,3000,FE,3,4,000A,7805414948D7,3080,FE,3,4,000A,78054149496D,3130,FE,3,4,000A,780541494969,3100,FE,3,4,000A,780541494879,,20251013163820,373D$"
93
+
90
94
  var data = {
91
95
  "imei": 868589060039404,
92
96
  "instruction": "temp_alarm_off",
@@ -168,7 +172,7 @@ spd = {
168
172
  "times": "30"
169
173
  }
170
174
  // console.log(queclink.parseCommand(action))
171
- const raw = new Buffer.from(test)
175
+ const raw = new Buffer.from(t)
172
176
  console.log(JSON.stringify(queclink.parse(raw), null, 2))
173
177
  queclink.parse(raw)
174
178
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "queclink-parser",
3
- "version": "1.9.16",
3
+ "version": "1.9.18",
4
4
  "description": "Parse raw data from Queclink devices",
5
5
  "main": "src",
6
6
  "scripts": {
package/src/gv310lau.js CHANGED
@@ -251,7 +251,8 @@ const parse = raw => {
251
251
  // External Data
252
252
  const digitFuelSensor =
253
253
  utils.nHexDigit(utils.hex2bin(parsedData[4]), 11)[10] === '1'
254
- const AC100 = utils.nHexDigit(utils.hex2bin(parsedData[4]), 11)[9] === '1'
254
+ const AC100 =
255
+ utils.nHexDigit(utils.hex2bin(parsedData[4]), 11)[9] === '1'
255
256
  const canData =
256
257
  utils.nHexDigit(utils.hex2bin(parsedData[4]), 11)[8] === '1'
257
258
  const fuelLevelPercentage =
@@ -541,63 +542,61 @@ const parse = raw => {
541
542
  AC100Devices: ac100Devices
542
543
  })
543
544
  }
544
- // } else if (parsedData[index + 8] === '7') {
545
- // index += 1
546
- // // RF433 Devices
547
- // let rf433Devices = []
548
- // // Review when RF433 devices are implemented
549
- // let count = index + 9
550
- // for (var l = 0; l < rf433DevicesConnected; l++) {
551
- // rf433Devices.push({
552
- // // deviceNumber: parsedData[count],
553
- // // deviceType: parsedData[count + 1],
554
- // // deviceData: parsedData[count + 2]
555
- // // ? utils.getTempInCelciousDegrees(parsedData[count + 2])
556
- // // : null
557
- // deviceData: parsedData[count]
558
- // })
559
- // count += 1
560
- // // count += 3
561
- // }
562
- // externalData = Object.assign(externalData, {
563
- // rf433Devices: rf433Devices
564
- // })
545
+ // } else if (parsedData[index + 8] === '7') {
546
+ // index += 1
547
+ // // RF433 Devices
548
+ // let rf433Devices = []
549
+ // // Review when RF433 devices are implemented
550
+ // let count = index + 9
551
+ // for (var l = 0; l < rf433DevicesConnected; l++) {
552
+ // rf433Devices.push({
553
+ // // deviceNumber: parsedData[count],
554
+ // // deviceType: parsedData[count + 1],
555
+ // // deviceData: parsedData[count + 2]
556
+ // // ? utils.getTempInCelciousDegrees(parsedData[count + 2])
557
+ // // : null
558
+ // deviceData: parsedData[count]
559
+ // })
560
+ // count += 1
561
+ // // count += 3
562
+ // }
563
+ // externalData = Object.assign(externalData, {
564
+ // rf433Devices: rf433Devices
565
+ // })
565
566
  }
566
567
 
567
- var isValidCanData = true
568
568
  if (canData) {
569
569
  let newIndex = digitFuelSensor && !AC100 ? index + 9 + 1 : !digitFuelSensor && AC100 ? index + 9 + 4 : digitFuelSensor && AC100 ? index + 9 + 5 : index + 9
570
- let canInfo = utils.getCanData(parsedData, newIndex)
570
+ let parsedCanData = utils.getCanData(parsedData, newIndex, command[1])
571
+ let canInfo = parsedCanData[3]
572
+ index = parsedCanData[0]
571
573
  if (Object.keys(canInfo).length > 0) {
572
574
  data = Object.assign(data, { can: canInfo })
573
- index = index + 49
575
+ // index = parsedCanData[0]
574
576
 
575
- if (canInfo?.totalDistance) {
576
- data.gpsOdometer = data.odometer
577
- data.odometer = canInfo.totalDistance
578
- }
577
+ if (canInfo?.comunicationOk) {
578
+ if (typeof canInfo?.totalDistance === 'number') {
579
+ data.gpsOdometer = data.odometer
580
+ data.odometer = canInfo.totalDistance
581
+ }
579
582
 
580
- if (canInfo?.engineHours) {
581
- data.gpsHourmeter = data.hourmeter
582
- data.hourmeter = canInfo.engineHours
583
- }
583
+ if (typeof canInfo?.engineHours === 'number') {
584
+ data.gpsHourmeter = data.hourmeter
585
+ data.hourmeter = canInfo.engineHours
586
+ }
584
587
 
585
- if (canInfo?.speed) {
586
- data.gpsSpeed = data.speed
587
- data.speed = canInfo.speed
588
+ if (typeof canInfo?.speed === 'number') {
589
+ data.gpsSpeed = data.speed;
590
+ data.speed = canInfo.speed;
591
+ }
588
592
  }
589
- } else {
590
- isValidCanData = false
591
593
  }
592
594
  }
593
595
 
594
596
  // Bluetooth Accessories
595
597
  if (bluetoothAccessory) {
596
- let btIndex = digitFuelSensor ? index + 10 : index + 9
597
- if (canData) {
598
- btIndex = isValidCanData? btIndex : btIndex + 2
599
- }
600
-
598
+ // let btIndex = digitFuelSensor ? index + 1 : index
599
+ let btIndex = canData ? index : index + 9
601
600
  let btDevices = utils.getBleData(parsedData, btIndex)
602
601
  externalData = Object.assign(externalData, {
603
602
  btDevices: btDevices
@@ -1452,7 +1451,8 @@ const parse = raw => {
1452
1451
  hourmeter: null
1453
1452
  })
1454
1453
  } else if (command[1] === 'GTCAN') {
1455
- let index = 67 // position append mask
1454
+ let canData = utils.getCanData(parsedData, 5, command[1])
1455
+ let index = canData[0] // position append mask
1456
1456
  let satelliteInfo = false
1457
1457
 
1458
1458
  // If get satellites is configured
@@ -1463,20 +1463,7 @@ const parse = raw => {
1463
1463
 
1464
1464
  data = Object.assign(data, {
1465
1465
  alarm: utils.getAlarm(command[1], parsedData[4]),
1466
- loc: {
1467
- type: 'Point',
1468
- coordinates: [parseFloat(parsedData[60]), parseFloat(parsedData[61])]
1469
- },
1470
- speed: parsedData[57] !== '' ? parseFloat(parsedData[57]) : null,
1471
- gpsStatus: utils.checkGps(
1472
- parseFloat(parsedData[60]),
1473
- parseFloat(parsedData[61])
1474
- ),
1475
- hdop: parsedData[56] !== '' ? parseFloat(parsedData[56]) : null,
1476
1466
  status: null,
1477
- azimuth: parsedData[58] !== '' ? parseFloat(parsedData[58]) : null,
1478
- altitude: parsedData[59] !== '' ? parseFloat(parsedData[59]) : null,
1479
- datetime: parsedData[62] !== '' ? utils.parseDate(parsedData[62]) : null,
1480
1467
  voltage: {
1481
1468
  battery: null,
1482
1469
  inputCharge: null,
@@ -1484,19 +1471,20 @@ const parse = raw => {
1484
1471
  adb: null,
1485
1472
  adc: null
1486
1473
  },
1487
- mcc: parsedData[63] !== '' ? utils.latamMcc[parseInt(parsedData[63], 10)] : null,
1488
- mnc: parsedData[64] !== '' ? utils.getMNC(parsedData[63], parsedData[64]) : null,
1489
- lac: parsedData[65] !== '' ? parseInt(parsedData[65], 16) : null,
1490
- cid: parsedData[66] !== '' ? parseInt(parsedData[66], 16) : null,
1491
1474
  satellites:
1492
1475
  satelliteInfo && parsedData[index]
1493
1476
  ? parseInt(parsedData[index], 10)
1494
1477
  : null,
1495
1478
  odometer: null,
1496
1479
  hourmeter: null,
1497
- can: utils.getCanData(parsedData, 5)
1480
+ can: canData[3]
1481
+ })
1482
+
1483
+ data = {
1484
+ ...data,
1485
+ ...canData[1], // gnnsData
1486
+ ...canData[2] // gsmData
1498
1487
  }
1499
- )
1500
1488
  } else if (command[1] === 'GTDAT') {
1501
1489
  let dataIndex = 4
1502
1490
  // Short format
@@ -1672,7 +1660,7 @@ const parse = raw => {
1672
1660
  let satelliteInfo = utils.includeSatellites(parsedData[20])
1673
1661
  let accuracyInfo = utils.includeGnnsAccuracy(parsedData[20]) ? 3 : 0
1674
1662
  let index = 20 + satelliteInfo + accuracyInfo
1675
-
1663
+
1676
1664
 
1677
1665
  data = Object.assign(data, {
1678
1666
  alarm: utils.getAlarm(command[1], parsedData[8], parsedData[6]),
package/src/gv58lau.js CHANGED
@@ -310,7 +310,8 @@ const parse = raw => {
310
310
  // External Data
311
311
  const bluetoothAccessory =
312
312
  utils.nHexDigit(utils.hex2bin(parsedData[4]), 11)[2] === '1'
313
- const canData = utils.nHexDigit(utils.hex2bin(parsedData[4]), 11)[8] === '1'
313
+ const canData =
314
+ utils.nHexDigit(utils.hex2bin(parsedData[4]), 11)[8] === '1'
314
315
 
315
316
  let externalData = {
316
317
  eriMask: {
@@ -320,18 +321,36 @@ const parse = raw => {
320
321
  }
321
322
  }
322
323
 
323
- // Bluetooth Accessories
324
- if (bluetoothAccessory) {
325
- let btIndex
324
+ // CANBUS data
325
+ if (canData) {
326
+ let parsedCanData = utils.getCanData(parsedData, newIndex, command[1])
327
+ let canInfo = parsedCanData[3]
328
+ index = parsedCanData[0]
329
+ if (Object.keys(canInfo).length > 0) {
330
+ data = Object.assign(data, { can: canInfo })
331
+ if (canInfo?.comunicationOk) {
332
+ if (typeof canInfo?.totalDistance === 'number') {
333
+ data.gpsOdometer = data.odometer
334
+ data.odometer = canInfo.totalDistance
335
+ }
326
336
 
327
- if (canData) {
328
- btIndex = index + 58
329
- } else {
330
- btIndex = index + 9
337
+ if (typeof canInfo?.engineHours === 'number') {
338
+ data.gpsHourmeter = data.hourmeter
339
+ data.hourmeter = canInfo.engineHours
340
+ }
341
+
342
+ if (typeof canInfo?.speed === 'number') {
343
+ data.gpsSpeed = data.speed;
344
+ data.speed = canInfo.speed;
345
+ }
346
+ }
331
347
  }
348
+ }
332
349
 
350
+ // Bluetooth Accessories
351
+ if (bluetoothAccessory) {
352
+ let btIndex = canData ? index : index + 9
333
353
  let btDevices = utils.getBleData(parsedData, btIndex)
334
-
335
354
  externalData = Object.assign(externalData, {
336
355
  btDevices: btDevices
337
356
  })
@@ -1270,34 +1289,36 @@ const parse = raw => {
1270
1289
  hourmeter: null
1271
1290
  })
1272
1291
  } else if (command[1] === 'GTCAN') {
1273
- let satelliteInfo = utils.includeSatellites(parsedData[67])
1274
- let accuracyInfo = utils.includeGnnsAccuracy(parsedData[67]) ? 3 : 0
1275
- let index = 67 + (satelliteInfo + accuracyInfo)
1292
+ let canData = utils.getCanData(parsedData, 5, command[1])
1293
+ let index = canData[0] // position append mask
1294
+ let satelliteInfo = utils.includeSatellites(parsedData[index])
1295
+ let accuracyInfo = utils.includeGnnsAccuracy(parsedData[index]) ? 3 : 0
1296
+ index = index + (satelliteInfo + accuracyInfo)
1276
1297
 
1277
1298
  data = Object.assign(data, {
1278
1299
  alarm: utils.getAlarm(command[1], parsedData[4]),
1279
- loc: {
1280
- type: 'Point',
1281
- coordinates: [parseFloat(parsedData[60]), parseFloat(parsedData[61])]
1282
- },
1283
- speed: parsedData[57] !== '' ? parseFloat(parsedData[57]) : null,
1284
- gpsStatus: utils.checkGps(
1285
- parseFloat(parsedData[60]),
1286
- parseFloat(parsedData[61])
1287
- ),
1288
- hdop: parsedData[56] !== '' ? parseFloat(parsedData[56]) : null,
1289
- status: null,
1290
- azimuth: parsedData[58] !== '' ? parseFloat(parsedData[58]) : null,
1291
- altitude: parsedData[59] !== '' ? parseFloat(parsedData[59]) : null,
1292
- datetime: parsedData[62] !== '' ? utils.parseDate(parsedData[62]) : null,
1293
- voltage: {
1294
- battery: null,
1295
- inputCharge: null
1296
- },
1297
- mcc: parsedData[63] !== '' ? utils.latamMcc[parseInt(parsedData[63], 10)] || utils.latamMcc.default : null,
1298
- mnc: parsedData[64] !== '' ? utils.getMNC(parsedData[63], parsedData[64]) : null,
1299
- lac: parsedData[65] !== '' ? parseInt(parsedData[65], 16) : null,
1300
- cid: parsedData[66] !== '' ? parseInt(parsedData[66], 16) : null,
1300
+ // loc: {
1301
+ // type: 'Point',
1302
+ // coordinates: [parseFloat(parsedData[60]), parseFloat(parsedData[61])]
1303
+ // },
1304
+ // speed: parsedData[57] !== '' ? parseFloat(parsedData[57]) : null,
1305
+ // gpsStatus: utils.checkGps(
1306
+ // parseFloat(parsedData[60]),
1307
+ // parseFloat(parsedData[61])
1308
+ // ),
1309
+ // hdop: parsedData[56] !== '' ? parseFloat(parsedData[56]) : null,
1310
+ // status: null,
1311
+ // azimuth: parsedData[58] !== '' ? parseFloat(parsedData[58]) : null,
1312
+ // altitude: parsedData[59] !== '' ? parseFloat(parsedData[59]) : null,
1313
+ // datetime: parsedData[62] !== '' ? utils.parseDate(parsedData[62]) : null,
1314
+ // voltage: {
1315
+ // battery: null,
1316
+ // inputCharge: null
1317
+ // },
1318
+ // mcc: parsedData[63] !== '' ? utils.latamMcc[parseInt(parsedData[63], 10)] || utils.latamMcc.default : null,
1319
+ // mnc: parsedData[64] !== '' ? utils.getMNC(parsedData[63], parsedData[64]) : null,
1320
+ // lac: parsedData[65] !== '' ? parseInt(parsedData[65], 16) : null,
1321
+ // cid: parsedData[66] !== '' ? parseInt(parsedData[66], 16) : null,
1301
1322
  satellites:
1302
1323
  satelliteInfo && parsedData[index - (satelliteInfo + accuracyInfo) + 1] !== ''
1303
1324
  ? parseInt(parsedData[index - (satelliteInfo + accuracyInfo) + 1], 10)
@@ -1316,8 +1337,14 @@ const parse = raw => {
1316
1337
  : null,
1317
1338
  odometer: null,
1318
1339
  hourmeter: null,
1319
- can: utils.getCanData(parsedData, 5),
1340
+ can: canData[3],
1320
1341
  })
1342
+
1343
+ data = {
1344
+ ...data,
1345
+ ...canData[1], // gnnsData
1346
+ ...canData[2] // gsmData
1347
+ }
1321
1348
  } else if (command[1] === 'GTDAT') {
1322
1349
  let dataIndex = 4
1323
1350
  // Short format
package/src/utils.js CHANGED
@@ -388,7 +388,7 @@ const checkGps = (lng, lat) => {
388
388
  included in the report
389
389
  */
390
390
  const includeSatellites = positionAppendMask => {
391
- return nHexDigit(hex2bin(positionAppendMask), 4)[3] == '1'
391
+ return nHexDigit(hex2bin(positionAppendMask), 4)[3] === '1'
392
392
  }
393
393
 
394
394
  /*
@@ -396,7 +396,7 @@ const includeSatellites = positionAppendMask => {
396
396
  included in the report
397
397
  */
398
398
  const includeGnssTrigger = positionAppendMask => {
399
- return nHexDigit(hex2bin(positionAppendMask), 4)[2] == '1'
399
+ return nHexDigit(hex2bin(positionAppendMask), 4)[2] === '1'
400
400
  }
401
401
 
402
402
  /*
@@ -404,7 +404,7 @@ const includeGnssTrigger = positionAppendMask => {
404
404
  included in the report
405
405
  */
406
406
  const includeStatus = positionAppendMask => {
407
- return nHexDigit(hex2bin(positionAppendMask), 4)[1] == '1'
407
+ return nHexDigit(hex2bin(positionAppendMask), 4)[1] === '1'
408
408
  }
409
409
 
410
410
  /*
@@ -412,7 +412,7 @@ const includeStatus = positionAppendMask => {
412
412
  included in the report
413
413
  */
414
414
  const includeGnnsAccuracy = positionAppendMask => {
415
- return nHexDigit(hex2bin(positionAppendMask), 4)[0] == '1'
415
+ return nHexDigit(hex2bin(positionAppendMask), 4)[0] === '1'
416
416
  }
417
417
 
418
418
  /*
@@ -695,244 +695,337 @@ const parseCanData = (data, key) => {
695
695
  /*
696
696
  Get CANbus data
697
697
  */
698
- const getCanData = (parsedData, ix) => {
698
+ const getCanData = (parsedData, ix, type) => {
699
699
  let canAppendMask = parsedData[ix + 1] !== ''
700
- ? nHexDigit(hex2bin(parsedData[ix + 1]), 32)
701
- : null
702
- if (canAppendMask == 0) {
700
+ ? nHexDigit(hex2bin(parsedData[ix + 1]), 32)
701
+ : null
702
+ if (canAppendMask === 0) {
703
703
  return {}
704
704
  }
705
705
 
706
+ let spdIx
707
+ let rpmIx
708
+ let engcIx
709
+ let vinIx = ix + 1 + parseInt(canAppendMask[31])
710
+ let ignIx = vinIx + parseInt(canAppendMask[30])
711
+ let disIx = ignIx + parseInt(canAppendMask[29])
712
+ let fuelIx = disIx + parseInt(canAppendMask[28])
713
+ // if (type === 'GTCAN') {
714
+ spdIx = fuelIx + parseInt(canAppendMask[27])
715
+ rpmIx = spdIx + parseInt(canAppendMask[26])
716
+ engcIx = rpmIx + parseInt(canAppendMask[25])
717
+ // } else {
718
+ // rpmIx = fuelIx + parseInt(canAppendMask[27])
719
+ // spdIx = rpmIx + parseInt(canAppendMask[26])
720
+ // engcIx = spdIx + parseInt(canAppendMask[25])
721
+ // }
722
+ let fuelcIx = engcIx + parseInt(canAppendMask[24])
723
+ let fuellIx = fuelcIx + parseInt(canAppendMask[23])
724
+ let rngIx = fuellIx + parseInt(canAppendMask[22])
725
+ let accIx = rngIx + parseInt(canAppendMask[21])
726
+ let enghIx = accIx + parseInt(canAppendMask[20])
727
+ let drvIx = enghIx + parseInt(canAppendMask[19])
728
+ let idltIx = drvIx + parseInt(canAppendMask[18])
729
+ let idlfIx = idltIx + parseInt(canAppendMask[17])
730
+ let axlwIx = idlfIx + parseInt(canAppendMask[16])
731
+ let tacIx = axlwIx + parseInt(canAppendMask[15])
732
+ let indIx = tacIx + parseInt(canAppendMask[14])
733
+ let ligIx = indIx + parseInt(canAppendMask[13])
734
+ let doorIx = ligIx + parseInt(canAppendMask[12])
735
+ let osptIx = doorIx + parseInt(canAppendMask[11])
736
+ let ospeIx = osptIx + parseInt(canAppendMask[10])
737
+ // Values from 9 to 3 are reserved
738
+ let canxIx = ospeIx + parseInt(canAppendMask[2])
739
+
740
+ let canExpansionMask =
741
+ canAppendMask[2] === '1' && parsedData[canxIx] !== ''
742
+ ? nHexDigit(hex2bin(parsedData[canxIx]), 32)
743
+ .split('')
744
+ .reverse()
745
+ .join('')
746
+ : '00000000000000000000000000000000'
747
+
748
+ let repExpMask = canAppendMask[2] === '1' ? {
749
+ raw: parsedData[canxIx] ? parsedData[canxIx] : null,
750
+ adBlueLevel: canExpansionMask[0] === '1',
751
+ axleWeight1: canExpansionMask[1] === '1',
752
+ axleWeight3: canExpansionMask[2] === '1',
753
+ axleWeight4: canExpansionMask[3] === '1',
754
+ tachographOverspeedSignal: canExpansionMask[4] === '1',
755
+ tachographVehicleMotionSignal: canExpansionMask[5] === '1',
756
+ tachographDrivingDirection: canExpansionMask[6] === '1',
757
+ analogInputValue: canExpansionMask[7] === '1',
758
+ engineBrakingFactor: canExpansionMask[8] === '1',
759
+ pedalBrakingFactor: canExpansionMask[9] === '1',
760
+ totalAcceleratorKickDown: canExpansionMask[10] === '1',
761
+ totalEffectiveEngineSpeedTime: canExpansionMask[11] === '1',
762
+ totalCruiseControlTime: canExpansionMask[12] === '1',
763
+ totalAcceleratorKickDownTime: canExpansionMask[13] === '1',
764
+ totalBrakeApplications: canExpansionMask[14] === '1',
765
+ tachographDriver1Card: canExpansionMask[15] === '1',
766
+ tachographDriver2Card: canExpansionMask[16] === '1',
767
+ tachographDriver1Name: canExpansionMask[17] === '1',
768
+ tachographDriver2Name: canExpansionMask[18] === '1',
769
+ registrationNumber: canExpansionMask[19] === '1',
770
+ expansionInformation: canExpansionMask[20] === '1',
771
+ rapidBrakings: canExpansionMask[21] === '1',
772
+ rapidAccelerations: canExpansionMask[22] === '1',
773
+ engineTorque: canExpansionMask[23] === '1'
774
+ } : null
775
+
776
+ let adbIx = canxIx + parseInt(canExpansionMask[0])
777
+ let ax1Ix = adbIx + parseInt(canExpansionMask[1])
778
+ let ax3Ix = ax1Ix + parseInt(canExpansionMask[2])
779
+ let ax4Ix = ax3Ix + parseInt(canExpansionMask[3])
780
+ let tosIx = ax4Ix + parseInt(canExpansionMask[4])
781
+ let tvmIx = tosIx + parseInt(canExpansionMask[5])
782
+ let tddIx = tvmIx + parseInt(canExpansionMask[6])
783
+ let aivIx = tddIx + parseInt(canExpansionMask[7])
784
+ let ebrIx = aivIx + parseInt(canExpansionMask[8])
785
+ let pbrIx = ebrIx + parseInt(canExpansionMask[9])
786
+ let ackIx = pbrIx + parseInt(canExpansionMask[10])
787
+ let eesIx = ackIx + parseInt(canExpansionMask[11])
788
+ let crcIx = eesIx + parseInt(canExpansionMask[12])
789
+ let acktIx = crcIx + parseInt(canExpansionMask[13])
790
+ let braIx = acktIx + parseInt(canExpansionMask[14])
791
+ let tdc1Ix = braIx + parseInt(canExpansionMask[15])
792
+ let tdc2Ix = tdc1Ix + parseInt(canExpansionMask[16])
793
+ let tdn1Ix = tdc2Ix + parseInt(canExpansionMask[17])
794
+ let tdn2Ix = tdn1Ix + parseInt(canExpansionMask[18])
795
+ let regIx = tdn2Ix + parseInt(canExpansionMask[19])
796
+ let expbIx = regIx + parseInt(canExpansionMask[20])
797
+ let rbrIx = expbIx + parseInt(canExpansionMask[21])
798
+ let racIx = rbrIx + parseInt(canExpansionMask[22])
799
+ let etqIx = racIx + parseInt(canExpansionMask[23])
800
+
801
+ // Logic for CAN data
802
+ let gnnsIx = etqIx + 2 + parseInt(canAppendMask[1])
803
+ let gsmIx = canAppendMask[1] === '1' ? gnnsIx + parseInt(canAppendMask[0]) + 6 : gnnsIx + parseInt(canAppendMask[0])
804
+
805
+ let moreIx
806
+ let gnnsData = null
807
+ let gsmData = null
808
+ if (type === 'GTCAN') {
809
+ moreIx = canAppendMask[0] === '1' ? gsmIx + 4 : gsmIx
810
+ gnnsData = canAppendMask[1] === '1' ? {
811
+ hdop: parsedData[gnnsIx] ? parseFloat(parsedData[gnnsIx]) : null,
812
+ speed: parsedData[gnnsIx + 1] ? parseFloat(parsedData[gnnsIx + 1]) : null,
813
+ azimuth: parsedData[gnnsIx + 2] ? parseFloat(parsedData[gnnsIx + 2]) : null,
814
+ altitude: parsedData[gnnsIx + 3] ? parseFloat(parsedData[gnnsIx + 3]) : null,
815
+ loc: {
816
+ type: 'Point',
817
+ coordinates: [parseFloat(parsedData[gnnsIx + 4]), parseFloat(parsedData[gnnsIx + 5])]
818
+ },
819
+ gpsStatus: checkGps(
820
+ parseFloat(parsedData[gnnsIx + 4]),
821
+ parseFloat(parsedData[gnnsIx + 5])
822
+ ),
823
+ datetime: parsedData[gnnsIx + 6] ? parseDate(parsedData[gnnsIx + 6]) : null,
824
+ } : null
825
+
826
+ gsmData = canAppendMask[0] === '1' ? {
827
+ mcc: parsedData[gsmIx] !== '' ? latamMcc[parseInt(parsedData[gsmIx], 10)] : null,
828
+ mnc: parsedData[gsmIx + 1] !== '' ? getMNC(parsedData[gsmIx], parsedData[gsmIx + 1]) : null,
829
+ lac: parsedData[gsmIx + 2] !== '' ? parseInt(parsedData[gsmIx + 2], 16) : null,
830
+ cid: parsedData[gsmIx + 3] !== '' ? parseInt(parsedData[gsmIx + 3], 16) : null
831
+ } : null
832
+ } else {
833
+ moreIx = etqIx + 1
834
+ }
835
+
706
836
  let inicatorsBin =
707
- canAppendMask[14] && parsedData[ix + 19] !== ''
708
- ? nHexDigit(hex2bin(parsedData[ix + 19]), 16)
837
+ canAppendMask[14] === '1' && parsedData[indIx] !== ''
838
+ ? nHexDigit(hex2bin(parsedData[indIx]), 16)
709
839
  : null
710
840
  let lights =
711
- canAppendMask[13] && parsedData[ix + 20] !== ''
712
- ? nHexDigit(hex2bin(parsedData[ix + 20]), 8)
841
+ canAppendMask[13] === '1' && parsedData[ligIx] !== ''
842
+ ? nHexDigit(hex2bin(parsedData[ligIx]), 8)
713
843
  : null
714
844
  let doors =
715
- canAppendMask[12] && parsedData[ix + 21] !== ''
716
- ? nHexDigit(hex2bin(parsedData[ix + 21]), 8)
717
- : null
718
- let canExpansionMask =
719
- canAppendMask[2] && parsedData[ix + 24] !== ''
720
- ? nHexDigit(hex2bin(parsedData[ix + 24]), 32)
721
- .split('')
722
- .reverse()
723
- .join('')
845
+ canAppendMask[12] === '1' && parsedData[doorIx] !== ''
846
+ ? nHexDigit(hex2bin(parsedData[doorIx]), 8)
724
847
  : null
725
848
  let expansionBin =
726
- parsedData[ix + 45] !== ''
727
- ? nHexDigit(hex2bin(parsedData[ix + 45]), 16)
849
+ parsedData[expbIx] !== ''
850
+ ? nHexDigit(hex2bin(parsedData[expbIx]), 16)
728
851
  .split('')
729
852
  .reverse()
730
853
  .join('')
731
- : null
854
+ : '0000000000000000'
732
855
  let tachographBin =
733
- canAppendMask[15] && parsedData[ix + 18] !== ''
734
- ? nHexDigit(hex2bin(parsedData[ix + 18]), 8)
856
+ canAppendMask[15] === '1' && parsedData[tacIx] !== ''
857
+ ? nHexDigit(hex2bin(parsedData[tacIx]), 8)
735
858
  .split('')
736
859
  .reverse()
737
860
  .join('')
738
861
  : null
739
862
 
740
- return {
741
- comunicationOk: parsedData[ix] ? parsedData[ix] === '1' : null,
742
- vin: canAppendMask[31] && parsedData[ix + 2] ? parsedData[ix + 2] : null,
743
- ignitionKey: canAppendMask[30] && parsedData[ix + 3] ? parseCanData(parsedData[ix + 3], 'ignitionKey') : null,
744
- totalDistance: canAppendMask[29] && parsedData[ix + 4] ? parseCanData(parsedData[ix + 4], 'totalDistance') : null,
745
- totalDistanceUnit: canAppendMask[29] && parsedData[ix + 4] ? parsedData[ix + 4].slice(0, 1) === 'H' ? 'km' : 'I' : null,
746
- fuelUsed: canAppendMask[28] && parsedData[ix + 5] ? parseFloat(parsedData[ix + 5]) : null, // float
747
- rpm: canAppendMask[26] && parsedData[ix + 6] ? parseInt(parsedData[ix + 6], 10) : null, // int
748
- speed: canAppendMask[27] && parsedData[ix + 7] ? parseFloat(parsedData[ix + 7]) : null,
749
- engineCoolantTemp:
750
- canAppendMask[25] && parsedData[ix + 8] ? parseInt(parsedData[ix + 8], 10) : null,
751
- fuelConsumption: canAppendMask[24] && parsedData[ix + 9] ? parseCanData(parsedData[ix + 9], 'fuelConsumption') : null,
752
- fuelLevel: canAppendMask[23] && parsedData[ix + 10] ? parseFloat(parsedData[ix + 10].slice(1)) : null,
753
- fuelLevelUnit: canAppendMask[23] && parsedData[ix + 10] ? parsedData[ix + 10].slice(0, 1) === 'P' ? '%' : 'L' : null,
754
- range: canAppendMask[22] && parsedData[ix + 11] ? parseCanData(parsedData[ix + 11], 'range') : null,
755
- acceleratorPressure:
756
- canAppendMask[21] && parsedData[ix + 12] ? parseFloat(parsedData[ix + 12]) : null,
757
- engineHours: canAppendMask[20] && parsedData[ix + 13] ? parseFloat(parsedData[ix + 13]) : null,
758
- drivingTime: canAppendMask[19] && parsedData[ix + 14] ? parseFloat(parsedData[ix + 14]) : null,
759
- idleTime: canAppendMask[18] && parsedData[ix + 15] ? parseFloat(parsedData[ix + 15]) : null,
760
- idleFuelUsed: canAppendMask[17] && parsedData[ix + 16] ? parseFloat(parsedData[ix + 16]) : null,
761
- axleWeight: canAppendMask[16] && parsedData[ix + 17] ? parseFloat(parsedData[ix + 17]) : null,
762
- tachograph: parsedData[ix + 18] ? {
763
- raw: parsedData[ix + 18] ? parsedData[ix + 18] : null,
764
- validDriverData: tachographBin ? tachographBin[7] === '1' : null,
765
- insertedDriverCard: tachographBin ? tachographBin[5] === '1' : null,
766
- driverWorkingState: tachographBin
767
- ? dWorkingStates[parseInt(tachographBin.substring(3, 5), 2)]
768
- : null,
769
- drivingTimeState: tachographBin
770
- ? dTimeStates[parseInt(tachographBin.substring(5, 8), 2)]
771
- : null
772
- } : null,
773
- indicators: inicatorsBin ? {
774
- raw: inicatorsBin ? parsedData[ix + 19] : null,
775
- lowFuel: inicatorsBin ? inicatorsBin[0] === '1' : null,
776
- driverSeatbelt: inicatorsBin ? inicatorsBin[1] === '1' : null,
777
- airConditioning: inicatorsBin ? inicatorsBin[2] === '1' : null,
778
- cruiseControl: inicatorsBin ? inicatorsBin[3] === '1' : null,
779
- brakePedal: inicatorsBin ? inicatorsBin[4] === '1' : null,
780
- clutchPedal: inicatorsBin ? inicatorsBin[5] === '1' : null,
781
- handbrake: inicatorsBin ? inicatorsBin[6] === '1' : null,
782
- centralLock: inicatorsBin ? inicatorsBin[7] === '1' : null,
783
- reverseGear: inicatorsBin ? inicatorsBin[8] === '1' : null,
784
- runningLights: inicatorsBin ? inicatorsBin[9] === '1' : null,
785
- lowBeams: inicatorsBin ? inicatorsBin[10] === '1' : null,
786
- highBeams: inicatorsBin ? inicatorsBin[11] === '1' : null,
787
- rearFogLights: inicatorsBin ? inicatorsBin[12] === '1' : null,
788
- frontFogLights: inicatorsBin ? inicatorsBin[13] === '1' : null,
789
- doors: inicatorsBin ? inicatorsBin[14] === '1' : null,
790
- trunk: inicatorsBin ? inicatorsBin[15] === '1' : null
791
- } : null,
792
- lights: lights ? {
793
- raw: lights ? parsedData[ix + 20] : null,
794
- running: lights ? lights[0] === '1' : null,
795
- lowBeams: lights ? lights[1] === '1' : null,
796
- frontFog: lights ? lights[2] === '1' : null,
797
- rearFog: lights ? lights[3] === '1' : null,
798
- hazard: lights ? lights[4] === '1' : null
799
- } : null,
800
- doors: doors ? {
801
- raw: doors ? parsedData[ix + 21] : null,
802
- driver: doors ? doors[0] === '1' : null,
803
- passenger: doors ? doors[1] === '1' : null,
804
- rearLeft: doors ? doors[2] === '1' : null,
805
- rearRight: doors ? doors[3] === '1' : null,
806
- trunk: doors ? doors[4] === '1' : null,
807
- hood: doors ? doors[5] === '1' : null
808
- } : null,
809
- overSpeedTime: canAppendMask[11] && parsedData[ix + 22] ? parseFloat(parsedData[ix + 22]) : null,
810
- overSpeedEngineTime: canAppendMask[10] && parsedData[ix + 23] ? parseFloat(parsedData[ix + 23]) : null,
811
- canExpanded: {
812
- canReportExpansionMask: {
813
- raw: parsedData[ix + 24] ? parsedData[ix + 24] : null,
814
- engineTorque: canExpansionMask ? canExpansionMask[23] === '1' : null,
815
- rapidAccelerations: canExpansionMask
816
- ? canExpansionMask[22] === '1'
817
- : null,
818
- rapidBrakings: canExpansionMask ? canExpansionMask[21] === '1' : null,
819
- expansionInformation: canExpansionMask
820
- ? canExpansionMask[20] === '1'
821
- : null,
822
- registrationNumber: canExpansionMask
823
- ? canExpansionMask[19] === '1'
824
- : null,
825
- tachographDriver2Name: canExpansionMask
826
- ? canExpansionMask[18] === '1'
827
- : null,
828
- tachographDriver1Name: canExpansionMask
829
- ? canExpansionMask[17] === '1'
830
- : null,
831
- tachographDriver2Card: canExpansionMask
832
- ? canExpansionMask[16] === '1'
833
- : null,
834
- tachographDriver1Card: canExpansionMask
835
- ? canExpansionMask[15] === '1'
836
- : null,
837
- totalBrakeApplications: canExpansionMask
838
- ? canExpansionMask[14] === '1'
839
- : null,
840
- totalAcceleratorKickDownTime: canExpansionMask
841
- ? canExpansionMask[13] === '1'
842
- : null,
843
- totalCruiseControlTime: canExpansionMask
844
- ? canExpansionMask[12] === '1'
845
- : null,
846
- totalEffectiveEngineSpeedTime: canExpansionMask
847
- ? canExpansionMask[11] === '1'
848
- : null,
849
- totalAcceleratorKickDown: canExpansionMask
850
- ? canExpansionMask[10] === '1'
851
- : null,
852
- pedalBrakingFactor: canExpansionMask
853
- ? canExpansionMask[9] === '1'
854
- : null,
855
- engineBrakingFactor: canExpansionMask
856
- ? canExpansionMask[8] === '1'
857
- : null,
858
- analogInputValue: canExpansionMask
859
- ? canExpansionMask[7] === '1'
860
- : null,
861
- tachographDrivingDirection: canExpansionMask
862
- ? canExpansionMask[6] === '1'
863
- : null,
864
- tachographVehicleMotionSignal: canExpansionMask
865
- ? canExpansionMask[5] === '1'
866
- : null,
867
- tachographOverspeedSignal: canExpansionMask
868
- ? canExpansionMask[4] === '1'
869
- : null,
870
- AxleWeight4: canExpansionMask ? canExpansionMask[3] === '1' : null,
871
- AxleWeight3: canExpansionMask ? canExpansionMask[2] === '1' : null,
872
- AxleWeight1: canExpansionMask ? canExpansionMask[1] === '1' : null,
873
- adBlueLevel: canExpansionMask ? canExpansionMask[0] === '1' : null
863
+ return [
864
+ moreIx,
865
+ gnnsData,
866
+ gsmData,
867
+ {
868
+ comunicationOk: parsedData[ix] ? parsedData[ix] === '1' : null,
869
+ canAppendMask: {
870
+ hex: parsedData[ix + 1] !== '' ? parsedData[ix + 1] : null,
871
+ bin: canAppendMask,
872
+ vin: canAppendMask[31] === '1',
873
+ ignitionKey: canAppendMask[30] === '1',
874
+ totalDistance: canAppendMask[29] === '1',
875
+ totalFuelUsed: canAppendMask[28] === '1',
876
+ // speed: type === 'GTCAN' ? canAppendMask[27] === '1' : canAppendMask[26] === '1',
877
+ // rpm: type === 'GTCAN' ? canAppendMask[26] === '1' : canAppendMask[27] === '1',
878
+ speed: canAppendMask[27] === '1',
879
+ rpm: canAppendMask[26] === '1',
880
+ engineCoolantTemp: canAppendMask[25] === '1',
881
+ fuelConsumption: canAppendMask[24] === '1',
882
+ fuelLevel: canAppendMask[23] === '1',
883
+ range: canAppendMask[22] === '1',
884
+ acceleratorPressure: canAppendMask[21] === '1',
885
+ engineHours: canAppendMask[20] === '1',
886
+ drivingTime: canAppendMask[19] === '1',
887
+ idleTime: canAppendMask[18] === '1',
888
+ idleFuelUsed: canAppendMask[17] === '1',
889
+ axleWeight2: canAppendMask[16] === '1',
890
+ tachograph: canAppendMask[15] === '1',
891
+ indicators: canAppendMask[14] === '1',
892
+ lights: canAppendMask[13] === '1',
893
+ doors: canAppendMask[12] === '1',
894
+ overSpeedTime: canAppendMask[11] === '1',
895
+ overSpeedEngineTime: canAppendMask[10] === '1',
896
+ totalDistanceImpulses: canAppendMask[9] === '1',
897
+ canExpanded: canAppendMask[2] === '1',
898
+ gnssInformation: canAppendMask[1] === '1',
899
+ gsmInformation: canAppendMask[0] === '1'
874
900
  },
875
- adBlueLevel:
876
- parsedData[ix + 25] ? parseCanData(parsedData[ix + 25], 'adBlueLevel') : null,
877
- adBlueLevelUnit: parsedData[ix + 25] ? parsedData[ix + 25].slice(0, 1) === 'P' ? '%' : 'L' ? 'L' : '%' : null,
878
- axleWeight1: parsedData[ix + 26] ? parseInt(parsedData[ix + 26]) : null,
879
- axleWeight3: parsedData[ix + 27] ? parseInt(parsedData[ix + 27]) : null,
880
- axleWeight4: parsedData[ix + 28] ? parseInt(parsedData[ix + 28]) : null,
881
- tachographOverspeedSignal:
882
- parsedData[ix + 29] ? (parsedData[ix + 29] === '1') : null,
883
- tachographVehicleMotionSignal:
884
- parsedData[ix + 30] ? (parsedData[ix + 30] === '1') : null,
885
- tachographDrivingDirection:
886
- parsedData[ix + 31] ? parseCanData(parsedData[ix + 31], 'tachographDrivingDirection') : null,
887
- analogInputValue:
888
- parsedData[ix + 32] ? parseFloat(parsedData[ix + 32]) * 1000 : null,
889
- engineBrakingFactor:
890
- parsedData[ix + 33] ? parseInt(parsedData[ix + 33]) : null,
891
- pedalBrakingFactor:
892
- parsedData[ix + 34] ? parseInt(parsedData[ix + 34]) : null,
893
- totalAcceleratorKickDown:
894
- parsedData[ix + 35] ? parseInt(parsedData[ix + 35]) : null,
895
- totalEffectiveEngineSpeedTime:
896
- parsedData[ix + 36] ? parseFloat(parsedData[ix + 36]) : null,
897
- totalCruiseControlTime:
898
- parsedData[ix + 37] ? parseFloat(parsedData[ix + 37]) : null,
899
- totalAcceleratorKickDownTime:
900
- parsedData[ix + 38] ? parseFloat(parsedData[ix + 38]) : null,
901
- totalBrakeApplications:
902
- parsedData[ix + 39] ? parseInt(parsedData[ix + 39]) : null,
903
- tachographDriver1Card: parsedData[ix + 40] ? parsedData[ix + 40] : null,
904
- tachographDriver2Card: parsedData[ix + 41] ? parsedData[ix + 41] : null,
905
- tachographDriver1Name: parsedData[ix + 42] ? parsedData[ix + 42] : null,
906
- tachographDriver2Name: parsedData[ix + 43] ? parsedData[ix + 43] : null,
907
- registrationNumber: parsedData[ix + 44] ? parsedData[ix + 44] : null,
908
- expansionInformation: {
909
- raw: parsedData[ix + 45] ? parsedData[ix + 45] : null,
910
- webasto: expansionBin ? expansionBin[0] === '1' : null,
911
- brakeFluidLowIndicator: expansionBin
912
- ? expansionBin[1] === '1'
913
- : null,
914
- coolantLevelLowIndicator: expansionBin
915
- ? expansionBin[2] === '1'
916
- : null,
917
- batteryIndicator: expansionBin ? expansionBin[3] === '1' : null,
918
- brakeSystemFailureIndicator: expansionBin
919
- ? expansionBin[4] === '1'
901
+ vin: canAppendMask[31] === '1' && parsedData[vinIx] ? parsedData[vinIx] : null,
902
+ ignitionKey: canAppendMask[30] === '1' && parsedData[ignIx] ? parseCanData(parsedData[ignIx], 'ignitionKey') : null,
903
+ totalDistance: canAppendMask[29] === '1' && parsedData[disIx] ? parseCanData(parsedData[disIx], 'totalDistance') : null,
904
+ totalDistanceUnit: canAppendMask[29] === '1' && parsedData[disIx] ? parsedData[disIx].slice(0, 1) === 'H' ? 'km' : 'I' : null,
905
+ fuelUsed: canAppendMask[28] === '1' && parsedData[fuelIx] ? parseFloat(parsedData[fuelIx]) : null, // float
906
+ speed: canAppendMask[27] === '1' && parsedData[spdIx] ? parseFloat(parsedData[spdIx]) : null,
907
+ rpm: canAppendMask[26] === '1' && parsedData[rpmIx] ? parseInt(parsedData[rpmIx], 10) : null,
908
+ // speed: type === 'GTCAN' ? (canAppendMask[27] === '1' && parsedData[spdIx] ? parseFloat(parsedData[spdIx]) : null) :
909
+ // type === 'GTERI' ? (canAppendMask[26] === '1' && parsedData[spdIx] ? parseFloat(parsedData[spdIx]) : null) : null,
910
+ // rpm: type === 'GTCAN' ? (canAppendMask[26] === '1' && parsedData[rpmIx] ? parseInt(parsedData[rpmIx], 10) : null) :
911
+ // type === 'GTERI' ? (canAppendMask[27] === '1' && parsedData[rpmIx] ? parseInt(parsedData[rpmIx], 10) : null) : null,
912
+ engineCoolantTemp:
913
+ canAppendMask[25] === '1' && parsedData[engcIx] ? parseInt(parsedData[engcIx], 10) : null,
914
+ fuelConsumption: canAppendMask[24] === '1' && parsedData[fuelcIx] ? parseCanData(parsedData[fuelcIx], 'fuelConsumption') : null,
915
+ fuelLevel: canAppendMask[23] === '1' && parsedData[fuellIx] ? parseFloat(parsedData[fuellIx].slice(1)) : null,
916
+ fuelLevelUnit: canAppendMask[23] === '1' && parsedData[fuellIx] ? parsedData[fuellIx].slice(0, 1) === 'P' ? '%' : 'L' : null,
917
+ range: canAppendMask[22] === '1' && parsedData[rngIx] ? parseCanData(parsedData[rngIx], 'range') : null,
918
+ acceleratorPressure:
919
+ canAppendMask[21] === '1' && parsedData[accIx] ? parseFloat(parsedData[accIx]) : null,
920
+ engineHours: canAppendMask[20] === '1' && parsedData[enghIx] ? parseFloat(parsedData[enghIx]) : null,
921
+ drivingTime: canAppendMask[19] === '1' && parsedData[drvIx] ? parseFloat(parsedData[drvIx]) : null,
922
+ idleTime: canAppendMask[18] === '1' && parsedData[idltIx] ? parseFloat(parsedData[idltIx]) : null,
923
+ idleFuelUsed: canAppendMask[17] === '1' && parsedData[idlfIx] ? parseFloat(parsedData[idlfIx]) : null,
924
+ axleWeight2: canAppendMask[16] === '1' && parsedData[axlwIx] ? parseFloat(parsedData[axlwIx]) : null,
925
+ tachograph: canAppendMask[15] === '1' && parsedData[tacIx] ? {
926
+ raw: parsedData[tacIx] ? parsedData[tacIx] : null,
927
+ validDriverData: tachographBin ? tachographBin[7] === '1' : null,
928
+ insertedDriverCard: tachographBin ? tachographBin[5] === '1' : null,
929
+ driverWorkingState: tachographBin
930
+ ? dWorkingStates[parseInt(tachographBin.substring(3, 5), 2)]
920
931
  : null,
921
- oilPressureIndicator: expansionBin ? expansionBin[5] === '1' : null,
922
- engineHotIndicator: expansionBin ? expansionBin[6] === '1' : null,
923
- ABSFailureIndicator: expansionBin ? expansionBin[7] === '1' : null,
924
- checkEngineIndicator: expansionBin ? expansionBin[9] === '1' : null,
925
- airbagsIndicator: expansionBin ? expansionBin[10] === '1' : null,
926
- serviceCallIndicator: expansionBin
927
- ? expansionBin[11] === '1'
928
- : null,
929
- oilLevelLowIndicator: expansionBin ? expansionBin[12] === '1' : null
930
- },
931
- rapidBrakings: parsedData[ix + 46] ? parseInt(parsedData[ix + 46]) : null,
932
- rapidAccelerations: parsedData[ix + 47] ? parseInt(parsedData[ix + 47]) : null,
933
- engineTorque: parsedData[ix + 48] ? parseFloat(parsedData[ix + 48]) : null,
934
- }
935
- }
932
+ drivingTimeState: tachographBin
933
+ ? dTimeStates[parseInt(tachographBin.substring(5, 8), 2)]
934
+ : null
935
+ } : null,
936
+ indicators: canAppendMask[14] === '1' && inicatorsBin ? {
937
+ raw: inicatorsBin ? parsedData[indIx] : null,
938
+ lowFuel: inicatorsBin ? inicatorsBin[0] === '1' : null,
939
+ driverSeatbelt: inicatorsBin ? inicatorsBin[1] === '1' : null,
940
+ airConditioning: inicatorsBin ? inicatorsBin[2] === '1' : null,
941
+ cruiseControl: inicatorsBin ? inicatorsBin[3] === '1' : null,
942
+ brakePedal: inicatorsBin ? inicatorsBin[4] === '1' : null,
943
+ clutchPedal: inicatorsBin ? inicatorsBin[5] === '1' : null,
944
+ handbrake: inicatorsBin ? inicatorsBin[6] === '1' : null,
945
+ centralLock: inicatorsBin ? inicatorsBin[7] === '1' : null,
946
+ reverseGear: inicatorsBin ? inicatorsBin[8] === '1' : null,
947
+ runningLights: inicatorsBin ? inicatorsBin[9] === '1' : null,
948
+ lowBeams: inicatorsBin ? inicatorsBin[10] === '1' : null,
949
+ highBeams: inicatorsBin ? inicatorsBin[11] === '1' : null,
950
+ rearFogLights: inicatorsBin ? inicatorsBin[12] === '1' : null,
951
+ frontFogLights: inicatorsBin ? inicatorsBin[13] === '1' : null,
952
+ doors: inicatorsBin ? inicatorsBin[14] === '1' : null,
953
+ trunk: inicatorsBin ? inicatorsBin[15] === '1' : null
954
+ } : null,
955
+ lights: canAppendMask[13] === '1' && lights ? {
956
+ raw: lights ? parsedData[ligIx] : null,
957
+ running: lights ? lights[0] === '1' : null,
958
+ lowBeams: lights ? lights[1] === '1' : null,
959
+ frontFog: lights ? lights[2] === '1' : null,
960
+ rearFog: lights ? lights[3] === '1' : null,
961
+ hazard: lights ? lights[4] === '1' : null
962
+ } : null,
963
+ doors: canAppendMask[12] === '1' && doors ? {
964
+ raw: doors ? parsedData[doorIx] : null,
965
+ driver: doors ? doors[0] === '1' : null,
966
+ passenger: doors ? doors[1] === '1' : null,
967
+ rearLeft: doors ? doors[2] === '1' : null,
968
+ rearRight: doors ? doors[3] === '1' : null,
969
+ trunk: doors ? doors[4] === '1' : null,
970
+ hood: doors ? doors[5] === '1' : null
971
+ } : null,
972
+ overSpeedTime: canAppendMask[11] === '1' && parsedData[osptIx] ? parseFloat(parsedData[osptIx]) : null,
973
+ overSpeedEngineTime: canAppendMask[10] === '1' && parsedData[ospeIx] ? parseFloat(parsedData[ospeIx]) : null,
974
+ canExpanded: {
975
+ canReportExpansionMask: repExpMask,
976
+ adBlueLevel: repExpMask?.adBlueLevel &&
977
+ parsedData[adbIx] ? parseCanData(parsedData[adbIx], 'adBlueLevel') : null,
978
+ adBlueLevelUnit: repExpMask?.adBlueLevelUnit && parsedData[adbIx] ? parsedData[adbIx].slice(0, 1) === 'P' ? '%' : 'L' ? 'L' : '%' : null,
979
+ axleWeight1: repExpMask?.axleWeight1 && parsedData[ax1Ix] ? parseInt(parsedData[ax1Ix]) : null,
980
+ axleWeight3: repExpMask?.axleWeight3 && parsedData[ax3Ix] ? parseInt(parsedData[ax3Ix]) : null,
981
+ axleWeight4: repExpMask?.axleWeight4 && parsedData[ax4Ix] ? parseInt(parsedData[ax4Ix]) : null,
982
+ tachographOverspeedSignal: repExpMask?.tachographOverspeedSignal &&
983
+ parsedData[tosIx] ? (parsedData[tosIx] === '1') : null,
984
+ tachographVehicleMotionSignal: repExpMask?.tachographVehicleMotionSignal &&
985
+ parsedData[tvmIx] ? (parsedData[tvmIx] === '1') : null,
986
+ tachographDrivingDirection: repExpMask?.tachographDrivingDirection &&
987
+ parsedData[tddIx] ? parseCanData(parsedData[tddIx], 'tachographDrivingDirection') : null,
988
+ analogInputValue: repExpMask?.analogInputValue &&
989
+ parsedData[aivIx] ? parseFloat(parsedData[aivIx]) * 1000 : null,
990
+ engineBrakingFactor: repExpMask?.engineBrakingFactor &&
991
+ parsedData[ebrIx] ? parseInt(parsedData[ebrIx]) : null,
992
+ pedalBrakingFactor: repExpMask?.pedalBrakingFactor &&
993
+ parsedData[pbrIx] ? parseInt(parsedData[pbrIx]) : null,
994
+ totalAcceleratorKickDown: repExpMask?.totalAcceleratorKickDown &&
995
+ parsedData[ackIx] ? parseInt(parsedData[ackIx]) : null,
996
+ totalEffectiveEngineSpeedTime: repExpMask?.totalEffectiveEngineSpeedTime &&
997
+ parsedData[eesIx] ? parseFloat(parsedData[eesIx]) : null,
998
+ totalCruiseControlTime: repExpMask?.totalCruiseControlTime &&
999
+ parsedData[crcIx] ? parseFloat(parsedData[crcIx]) : null,
1000
+ totalAcceleratorKickDownTime: repExpMask?.totalAcceleratorKickDownTime &&
1001
+ parsedData[acktIx] ? parseFloat(parsedData[acktIx]) : null,
1002
+ totalBrakeApplications: repExpMask?.totalBrakeApplications &&
1003
+ parsedData[braIx] ? parseInt(parsedData[braIx]) : null,
1004
+ tachographDriver1Card: repExpMask?.tachographDriver1Card && parsedData[tdc1Ix] ? parsedData[tdc1Ix] : null,
1005
+ tachographDriver2Card: repExpMask?.tachographDriver2Card && parsedData[tdc2Ix] ? parsedData[tdc2Ix] : null,
1006
+ tachographDriver1Name: repExpMask?.tachographDriver1Name && parsedData[tdn1Ix] ? parsedData[tdn1Ix] : null,
1007
+ tachographDriver2Name: repExpMask?.tachographDriver2Name && parsedData[tdn2Ix] ? parsedData[tdn2Ix] : null,
1008
+ registrationNumber: repExpMask?.registrationNumber && parsedData[regIx] ? parsedData[regIx] : null,
1009
+ expansionInformation: repExpMask?.expansionInformation && expansionBin != '0000000000000000' ? {
1010
+ raw: parsedData[expbIx] ? parsedData[expbIx] : null,
1011
+ webasto: expansionBin[0] === '1',
1012
+ brakeFluidLowIndicator: expansionBin[1] === '1',
1013
+ coolantLevelLowIndicator: expansionBin[2] === '1',
1014
+ batteryIndicator: expansionBin[3] === '1',
1015
+ brakeSystemFailureIndicator: expansionBin[4] === '1',
1016
+ oilPressureIndicator: expansionBin[5] === '1',
1017
+ engineHotIndicator: expansionBin[6] === '1',
1018
+ ABSFailureIndicator: expansionBin[7] === '1',
1019
+ checkEngineIndicator: expansionBin[9] === '1',
1020
+ airbagsIndicator: expansionBin[10] === '1',
1021
+ serviceCallIndicator: expansionBin[11] === '1',
1022
+ oilLevelLowIndicator: expansionBin[12] === '1'
1023
+ } : null,
1024
+ rapidBrakings: repExpMask?.rapidBrakings && parsedData[rbrIx] ? parseInt(parsedData[rbrIx]) : null,
1025
+ rapidAccelerations: repExpMask?.rapidAccelerations && parsedData[racIx] ? parseInt(parsedData[racIx]) : null,
1026
+ engineTorque: repExpMask?.engineTorque && parsedData[etqIx] ? parseFloat(parsedData[etqIx]) : null,
1027
+ }
1028
+ }]
936
1029
  }
937
1030
 
938
1031
 
@@ -1623,6 +1716,17 @@ const getAlarm = (command, report, extra = false) => {
1623
1716
  temperature: temperature,
1624
1717
  message: messages[command][report].replace('()', `(${temperature}°C)`)
1625
1718
  }
1719
+ } else if (report === '20') {
1720
+ // Button pressed
1721
+ const number = parseInt(extra[0])
1722
+ const mac = extra[1]
1723
+ return {
1724
+ type: 'SOS_Button',
1725
+ number: number,
1726
+ deviceID: mac,
1727
+ voltage: extra[2].voltage ? extra[2].voltage : null,
1728
+ message: messages[command][report]
1729
+ }
1626
1730
  } else if (['07', '08', '09'].includes(report)) {
1627
1731
  const number = parseInt(extra[0])
1628
1732
  const mac = extra[1]