queclink-parser 1.9.15 → 1.9.17

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,25 @@
1
+ #### 1.9.17 (2025-09-22)
2
+
3
+ ##### New Features
4
+
5
+ * **getAlarm:** add handling for SOS button press event ([b39d687d](https://github.com/jaayesta/queclink-parser/commit/b39d687df059e467fa71bae887ac195e3189c6aa))
6
+
7
+ #### 1.9.16 (2025-09-03)
8
+
9
+ ##### New Features
10
+
11
+ * **createDefaultOut:** se agrega función para componer GTOUT de forma eficiente. ([b65bcc61](https://github.com/jaayesta/queclink-parser/commit/b65bcc6188f78ab7156e67f00c636c9504296b4d))
12
+ * **dosReport:** se agrega soporte a reporte DOS en GTOUT. ([158d2e4b](https://github.com/jaayesta/queclink-parser/commit/158d2e4b79acdae6407fc214e48f95c12d57b657))
13
+ * **fw11:** se agrega soporte a FW 11 ([3b91541d](https://github.com/jaayesta/queclink-parser/commit/3b91541dbe53803eb91c1512e51250714e5cd109))
14
+
15
+ ##### Bug Fixes
16
+
17
+ * **can:** se corrige parseo de GTERI cuando <CANbus report mask> es 0. ([b817fa2f](https://github.com/jaayesta/queclink-parser/commit/b817fa2f533575e7b6b4bfa487cf0bd2c1e439b4))
18
+ * **logs:** se eliminan logs no requeridos. ([34cb15a7](https://github.com/jaayesta/queclink-parser/commit/34cb15a750fd99e2fbd62216cdf079f5de3b0e5e))
19
+ * **dis:** se agrega gv58lau en soporte para cambio de entradas digitales ([c0c43a99](https://github.com/jaayesta/queclink-parser/commit/c0c43a991c3817f7a25e22ae5c46d86d6a0cd4d1))
20
+ * **310lau:** cambios menores en comentarios y ejemplos ([aeacc58a](https://github.com/jaayesta/queclink-parser/commit/aeacc58aa6c58d98347b73c15cf78cfd1ab0fba0))
21
+ * **alarm:** se quita SOS de entrada análoga 2 ([f4cd28f3](https://github.com/jaayesta/queclink-parser/commit/f4cd28f3b4a735d66e34a8904518ef10da801c2f))
22
+
1
23
  #### 1.9.15 (2025-03-11)
2
24
 
3
25
  ##### New Features
package/example.js CHANGED
@@ -80,9 +80,13 @@ var test2 = '+RESP:GTERI,8020040802,866314061760094,,00000100,12217,10,1,0,0.0,1
80
80
  var test3 = '+RESP:GTERI,8020040802,866314061760094,,00000100,12217,10,1,0,0.0,114,89.4,-71.542946,-32.972462,20250117083107,0730,0003,EA6F,00070B34,01,0,12.0,0000100:49:34,,,,100,210100,,2,01,6,4,17C608B8,283F,,78054133CB9F,1,3443,22,60,22.32,100,00,13,0,00000000,4007,,78054143F00B,1,0,20250121174252,7B18$'
81
81
  var test4 = '+RESP:GTERI,6E0B00,868589060064048,,00000100,12141,10,1,1,0.0,0,2.5,-71.543408,-32.972433,20250121211122,0730,0001,13EE,0032A502,01,12,2.6,0000014:48:01,,,,100,210100,0,3,FE,3,4,000A,780541416165,3260,00,13,0,00000000,4006,78054143F00B,1,0,02,6,4,156A0A3E,283F,,78054133CB9F,1,3449,26,54,26.22,100,20250121211125,340A$'
82
82
  var juego = "+RESP:GTERI,6E0802,868589060659029,,00000006,14064,10,1,1,32.4,71,471.3,-70.748220,-33.494213,20250123150132,0730,0001,3344,003D0601,01,12,9150.7,0000381:44:02,,,,100,220100,2,1,28FFB007286384D2,1,FF4C,1,203FFFFF,,2,,1190.32,1626,32,90,,,,0,371.38,193.02,178.36,128.66,,FFFF,0010,,00,0.06,0.00,FFFFFF,,,,,,,,,576370,434493,1719,371.38,,1.42,23731,,,,,,0000,56,0,,20250123150133,FAD9$"
83
- var tpms = '+RESP:GTERI,6E1003,864696060004173,GV310LAU,00000100,,10,1,1,0.0,0,115.8,117.129356,31.839248,20230808061540,0460,0001,DF5C,05FE6667,03,15,4.0,0000102:34:33,0,15259,10680,100,210000,7,1,1,06,12,0,001A42A2,0617,TMPS,08351B00043C,1,26,65,20231030085704,20231030085704,0017$'
84
83
  var newdtt = '+RESP:GTDTT,6E0802,868589060722215,,,,0,264,�Q4���,OzJ(��(��(��(��(��(��(��(��(��(��(��(��� N�K�4����.�]�f�v(�)sFisFisFh�����f�њ3I�3Mi���ܹ��QEQEQEQEQEQEQEQEQEQEQEQEQE(<Q��u.�7��}/�K��]��Jo���F�]�n�u��u.�i7 Rn��I��Ԍ�6M%QEQEQEQEQEQEQEQEQEQEQEQEQEQEQE.h���q��h�h�)][yB,1,24.6,322,2730.3,-68.802404,-23.413967,20250210162544,0730,0002,00CA,09B38E71,01,11,,,,,20250210162545,A522$'
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
+ 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
+ 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$'
85
87
 
88
+ 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
+ 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$"
86
90
  var data = {
87
91
  "imei": 868589060039404,
88
92
  "instruction": "temp_alarm_off",
@@ -97,72 +101,77 @@ var data = {
97
101
  "maxTemp": 29 || null
98
102
  }
99
103
 
100
- // console.log(queclink.parseCommand(data))
101
- const raw = new Buffer.from(tpms)
104
+ // data = {
105
+ // "imei": 868589060064048,
106
+ // "instruction": "1_on",
107
+ // "datetime": "2025-03-06T20:12:00.000Z",
108
+ // "password": "gv57cg",
109
+ // "device_serie": "GV",
110
+ // "user": user
111
+ // }
112
+
113
+ action = {
114
+ "imei": 868589060708180,
115
+ "user": {
116
+ "email": "fvergara@drivetech.pro",
117
+ "ip": "10.10.2.48",
118
+ "device": "Web"
119
+ },
120
+ "datetime": "2025-05-16T20:34:14.591Z",
121
+ "instruction": "2_on",
122
+ "action": "Abrir",
123
+ "loc": {
124
+ "type": "Point",
125
+ "coordinates": [
126
+ -71.543499,
127
+ -32.97255
128
+ ]
129
+ },
130
+ "device": "queclink",
131
+ "password": "gv310lau",
132
+ "dosReport": 2,
133
+ "command": null,
134
+ "device_serie": "GV",
135
+ "previousOutput": null,
136
+ "previousToggle": {
137
+ "1": 0,
138
+ "2": 1,
139
+ "3": 0,
140
+ "4": 0,
141
+ "5": 0
142
+ },
143
+ "previousDuration": {
144
+ "1": 0,
145
+ "2": 1,
146
+ "3": 0,
147
+ "4": 0,
148
+ "5": 0
149
+ }
150
+ }
151
+
152
+
153
+ spd = {
154
+ "imei": 866314061767966,
155
+ "user": {
156
+ "email": "fvergara@drivetech.pro",
157
+ "ip": "10.10.2.175",
158
+ "device": "Web"
159
+ },
160
+ "datetime": "2025-07-22T19:15:00.902Z",
161
+ "instruction": "set_speed_onE",
162
+ "action": "Configurar velocidad máxima",
163
+ "loc": null,
164
+ "device": "queclink",
165
+ "password": "gv58lau",
166
+ "device_serie": "GV",
167
+ "speed": "85",
168
+ "times": "30"
169
+ }
170
+ // console.log(queclink.parseCommand(action))
171
+ const raw = new Buffer.from(test)
102
172
  console.log(JSON.stringify(queclink.parse(raw), null, 2))
103
173
  queclink.parse(raw)
104
174
 
105
- // if (data.can) {
106
- // const {
107
- // comunicationOk,
108
- // vin,
109
- // ignitionKey,
110
- // totalDistance,
111
- // totalDistanceUnit,
112
- // rpm,
113
- // speed,
114
- // engineCoolantTemp,
115
- // fuelConsumption,
116
- // fuelLevel,
117
- // fuelLevelUnit,
118
- // range,
119
- // acceleratorPressure,
120
- // engineHours,
121
- // drivingTime,
122
- // idleTime,
123
- // idleFuelUsed,
124
- // axleWeight,
125
- // tachograph,
126
- // indicators,
127
- // lights,
128
- // doors,
129
- // overSpeedTime,
130
- // overSpeedEngineTime
131
- // } = data.can
132
-
133
- // const canData = {
134
- // raw: data.raw,
135
- // imei: data.imei,
136
- // datetime: data.datetime,
137
- // point: data.point,
138
- // comunicationOk,
139
- // vin,
140
- // ignitionKey,
141
- // totalDistance,
142
- // totalDistanceUnit,
143
- // rpm,
144
- // speed,
145
- // engineCoolantTemp,
146
- // fuelConsumption,
147
- // fuelLevel,
148
- // fuelLevelUnit,
149
- // range,
150
- // acceleratorPressure,
151
- // engineHours,
152
- // drivingTime,
153
- // idleTime,
154
- // idleFuelUsed,
155
- // axleWeight,
156
- // tachograph,
157
- // indicators,
158
- // lights,
159
- // doors,
160
- // overSpeedTime,
161
- // overSpeedEngineTime,
162
- // ...data.can.canExpanded
163
- // }
164
175
 
165
- // canData.canReportExpansionMask = canData.canReportExpansionMask.raw
166
- // console.log(canData)
167
- // delete data.can
168
- // }
176
+ // AT+GTSPD=gv58lau,1,0,0,60,300,0,0,0,0,,,,,,,,,,,,0000$
177
+ // AT+GTSPD=gv58lau,4,0,85,30,300,0,0,0,0,,,,,,,,,,,,0000$
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "queclink-parser",
3
- "version": "1.9.15",
3
+ "version": "1.9.17",
4
4
  "description": "Parse raw data from Queclink devices",
5
5
  "main": "src",
6
6
  "scripts": {
package/src/gv310lau.js CHANGED
@@ -564,31 +564,40 @@ const parse = raw => {
564
564
  // })
565
565
  }
566
566
 
567
+ var isValidCanData = true
567
568
  if (canData) {
568
569
  let newIndex = digitFuelSensor && !AC100 ? index + 9 + 1 : !digitFuelSensor && AC100 ? index + 9 + 4 : digitFuelSensor && AC100 ? index + 9 + 5 : index + 9
569
570
  let canInfo = utils.getCanData(parsedData, newIndex)
570
- data = Object.assign(data, { can: canInfo })
571
- index = index + 49
571
+ if (Object.keys(canInfo).length > 0) {
572
+ data = Object.assign(data, { can: canInfo })
573
+ index = index + 49
572
574
 
573
- if (canInfo?.totalDistance) {
574
- data.gpsOdometer = data.odometer
575
- data.odometer = canInfo.totalDistance
576
- }
575
+ if (canInfo?.totalDistance) {
576
+ data.gpsOdometer = data.odometer
577
+ data.odometer = canInfo.totalDistance
578
+ }
577
579
 
578
- if (canInfo?.engineHours) {
579
- data.gpsHourmeter = data.hourmeter
580
- data.hourmeter = canInfo.engineHours
581
- }
580
+ if (canInfo?.engineHours) {
581
+ data.gpsHourmeter = data.hourmeter
582
+ data.hourmeter = canInfo.engineHours
583
+ }
582
584
 
583
- if (canInfo?.speed) {
584
- data.gpsSpeed = data.speed
585
- data.speed = canInfo.speed
585
+ if (canInfo?.speed) {
586
+ data.gpsSpeed = data.speed
587
+ data.speed = canInfo.speed
588
+ }
589
+ } else {
590
+ isValidCanData = false
586
591
  }
587
592
  }
588
593
 
589
594
  // Bluetooth Accessories
590
595
  if (bluetoothAccessory) {
591
596
  let btIndex = digitFuelSensor ? index + 10 : index + 9
597
+ if (canData) {
598
+ btIndex = isValidCanData? btIndex : btIndex + 2
599
+ }
600
+
592
601
  let btDevices = utils.getBleData(parsedData, btIndex)
593
602
  externalData = Object.assign(externalData, {
594
603
  btDevices: btDevices
@@ -822,7 +831,7 @@ const parse = raw => {
822
831
  hourmeter: null
823
832
  })
824
833
  } else if (command[1] === 'GTEPS' || command[1] === 'GTAIS') {
825
- // External low battery and Low voltage for analog input
834
+ // External low battery and voltage for analog input
826
835
  let number = parsedData[6] !== '' ? parseInt(parsedData[6], 10) : 1
827
836
  let index = 6 + 12 * number // position append mask
828
837
  let satelliteInfo = false
@@ -1659,14 +1668,11 @@ const parse = raw => {
1659
1668
  })
1660
1669
  } else {
1661
1670
  // Long format
1662
- let index = 20 // position append mask
1663
- let satelliteInfo = false
1664
-
1665
- // If get satellites is configured
1666
- if (utils.includeSatellites(parsedData[index])) {
1667
- index += 1
1668
- satelliteInfo = true
1669
- }
1671
+ // let index = 20 // position append mask
1672
+ let satelliteInfo = utils.includeSatellites(parsedData[20])
1673
+ let accuracyInfo = utils.includeGnnsAccuracy(parsedData[20]) ? 3 : 0
1674
+ let index = 20 + satelliteInfo + accuracyInfo
1675
+
1670
1676
 
1671
1677
  data = Object.assign(data, {
1672
1678
  alarm: utils.getAlarm(command[1], parsedData[8], parsedData[6]),
@@ -1697,10 +1703,25 @@ const parse = raw => {
1697
1703
  lac: parsedData[18] !== '' ? parseInt(parsedData[18], 16) : null,
1698
1704
  cid: parsedData[19] !== '' ? parseInt(parsedData[19], 16) : null,
1699
1705
  satellites:
1700
- satelliteInfo && parsedData[index] !== ''
1701
- ? parseInt(parsedData[index], 10)
1706
+ satelliteInfo && parsedData[index - (satelliteInfo + accuracyInfo) + 1] !== ''
1707
+ ? parseInt(parsedData[index - (satelliteInfo + accuracyInfo) + 1], 10)
1708
+ : null,
1709
+ Hdop:
1710
+ accuracyInfo && parsedData[index - accuracyInfo + 1] !== ''
1711
+ ? parseFloat(parsedData[index - accuracyInfo + 1])
1712
+ : null,
1713
+ Vdop:
1714
+ accuracyInfo && parsedData[index - accuracyInfo + 2] !== ''
1715
+ ? parseFloat(parsedData[index - accuracyInfo + 2])
1716
+ : null,
1717
+ Ddop:
1718
+ accuracyInfo && parsedData[index] !== ''
1719
+ ? parseFloat(parsedData[index])
1720
+ : null,
1721
+ odometer:
1722
+ parsedData[index + 1] !== ''
1723
+ ? parseFloat(parsedData[index + 1])
1702
1724
  : null,
1703
- odometer: null,
1704
1725
  hourmeter: null
1705
1726
  })
1706
1727
  }
package/src/index.js CHANGED
@@ -212,27 +212,10 @@ const parseCommand = data => {
212
212
  let _data = data.instruction.split('_')
213
213
  port = parseInt(_data[0], 10)
214
214
  state = _data[1]
215
- prevOutputs = data.previousOutput || {
216
- '1': false,
217
- '2': false,
218
- '3': false,
219
- '4': false,
220
- '5': false
221
- }
222
- prevDurations = data.previousDuration || {
223
- '1': 0,
224
- '2': 0,
225
- '3': 0,
226
- '4': 0,
227
- '5': 0
228
- }
229
- prevToggles = data.previousToggle || {
230
- '1': 0,
231
- '2': 0,
232
- '3': 0,
233
- '4': 0,
234
- '5': 0
235
- }
215
+ prevOutputs = data.previousOutput || utils.createDefaultOut(5, false)
216
+ prevDurations = data.previousDuration || utils.createDefaultOut(5, 0)
217
+ prevToggles = data.previousToggle || utils.createDefaultOut(5, 0)
218
+
236
219
  const outputs = Object.keys(prevOutputs).map(
237
220
  key => (prevOutputs[key] === true ? 1 : 0)
238
221
  )
@@ -248,14 +231,19 @@ const parseCommand = data => {
248
231
  const do3 = `${outputs[2]},${prevDurations['3']},${prevToggles['3']}`
249
232
  const do4 = `${outputs[3]},${prevDurations['4']},${prevToggles['4']}`
250
233
  const do5 = `${outputs[4]},${prevDurations['5']},${prevToggles['5']}`
251
- const longOperation = data.longOperation || false ? '1' : '0'
252
- const dosReport = data.dosReport || false ? '1' : '0'
234
+ const longOperation = data.longOperation || false ? '1' : ''
235
+ const dosReport = data.dosReport || false ? data.dosReport : 0
236
+ const dos = `${outputs[port - 1]},${prevDurations[_data[0]]},${prevToggles[_data[0]]}`.split(',')
237
+ // const wave5 = dosReport ?
253
238
  if (data.device_serie === 'GV' && password === 'gv57cg') {
254
239
  command = `AT+GTDOS=${password},,,1,${do1},,,${dosReport},0,5,,,,${serialId}$`
255
240
  } else if (data.device_serie === 'GV' && password === 'gv58lau') {
256
- command = `AT+GTDOS=${password},0,3,1,${do1},0,,2,${do2},0,,3,${do3},0,,0,,,0${dosReport},,,FFFF$`
257
- } else if (data.device_serie === 'GV') {
241
+ command = `AT+GTDOS=${password},0,3,1,${do1},0,,2,${do2},0,,3,${do3},0,,0,,,${dosReport},,,${serialId}$`
242
+ } else if (data.device.serie === 'GV' && password.includes('lau')) {
258
243
  command = `AT+GTOUT=${password},${do1},${do2},${do3},${do4},${longOperation},${dosReport},,,${serialId}$`
244
+ } else if (data.device_serie === 'GV') {
245
+ // command = `AT+GTOUT=${password},${do1},${do2},${do3},${do4},${longOperation},${dosReport},,,${serialId}$`
246
+ command = `AT+GTOUT=${password},${do1},${do2},${do3},,,,${longOperation},${dosReport},,,${serialId}$`
259
247
  } else if (data.device_serie === 'GMT') {
260
248
  command = `AT+GTOUT=${password},${do1},${do2},,,,,,,,${serialId}$`
261
249
  } else if (data.device_serie === 'GV800') {
@@ -157,6 +157,7 @@
157
157
  "1": "Dispositivo reiniciado por Actualización de Firmware",
158
158
  "2": "Dispositivo operando nuevamente",
159
159
  "3": "Dispositivo operando nuevamente",
160
+ "5": "Dispositivo reiniciado por protocolo watchdog",
160
161
  "6": "Reinicio por actualización de configuración"
161
162
  },
162
163
  "GTPFR": {
package/src/utils.js CHANGED
@@ -696,20 +696,27 @@ const parseCanData = (data, key) => {
696
696
  Get CANbus data
697
697
  */
698
698
  const getCanData = (parsedData, ix) => {
699
+ let canAppendMask = parsedData[ix + 1] !== ''
700
+ ? nHexDigit(hex2bin(parsedData[ix + 1]), 32)
701
+ : null
702
+ if (canAppendMask == 0) {
703
+ return {}
704
+ }
705
+
699
706
  let inicatorsBin =
700
- parsedData[ix + 19] !== ''
707
+ canAppendMask[14] && parsedData[ix + 19] !== ''
701
708
  ? nHexDigit(hex2bin(parsedData[ix + 19]), 16)
702
709
  : null
703
710
  let lights =
704
- parsedData[ix + 20] !== ''
711
+ canAppendMask[13] && parsedData[ix + 20] !== ''
705
712
  ? nHexDigit(hex2bin(parsedData[ix + 20]), 8)
706
713
  : null
707
714
  let doors =
708
- parsedData[ix + 21] !== ''
715
+ canAppendMask[12] && parsedData[ix + 21] !== ''
709
716
  ? nHexDigit(hex2bin(parsedData[ix + 21]), 8)
710
717
  : null
711
718
  let canExpansionMask =
712
- parsedData[ix + 24] !== ''
719
+ canAppendMask[2] && parsedData[ix + 24] !== ''
713
720
  ? nHexDigit(hex2bin(parsedData[ix + 24]), 32)
714
721
  .split('')
715
722
  .reverse()
@@ -723,7 +730,7 @@ const getCanData = (parsedData, ix) => {
723
730
  .join('')
724
731
  : null
725
732
  let tachographBin =
726
- parsedData[ix + 18] !== ''
733
+ canAppendMask[15] && parsedData[ix + 18] !== ''
727
734
  ? nHexDigit(hex2bin(parsedData[ix + 18]), 8)
728
735
  .split('')
729
736
  .reverse()
@@ -732,26 +739,26 @@ const getCanData = (parsedData, ix) => {
732
739
 
733
740
  return {
734
741
  comunicationOk: parsedData[ix] ? parsedData[ix] === '1' : null,
735
- vin: parsedData[ix + 2] ? parsedData[ix + 2] : null,
736
- ignitionKey: parsedData[ix + 3] ? parseCanData(parsedData[ix + 3], 'ignitionKey') : null,
737
- totalDistance: parsedData[ix + 4] ? parseCanData(parsedData[ix + 4], 'totalDistance') : null,
738
- totalDistanceUnit: parsedData[ix + 4] ? parsedData[ix + 4].slice(0, 1) === 'H' ? 'km' : 'I' : null,
739
- fuelUsed: parsedData[ix + 5] ? parseFloat(parsedData[ix + 5]) : null, // float
740
- rpm: parsedData[ix + 6] ? parseInt(parsedData[ix + 6], 10) : null, // int
741
- speed: parsedData[ix + 7] ? parseFloat(parsedData[ix + 7]) : 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,
742
749
  engineCoolantTemp:
743
- parsedData[ix + 8] ? parseInt(parsedData[ix + 8], 10) : null,
744
- fuelConsumption: parsedData[ix + 9] ? parseCanData(parsedData[ix + 9], 'fuelConsumption') : null,
745
- fuelLevel: parsedData[ix + 10] ? parseFloat(parsedData[ix + 10].slice(1)) : null,
746
- fuelLevelUnit: parsedData[ix + 10] ? parsedData[ix + 10].slice(0, 1) === 'P' ? '%' : 'L' : null,
747
- range: parsedData[ix + 11] ? parseCanData(parsedData[ix + 11], 'range') : null,
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,
748
755
  acceleratorPressure:
749
- parsedData[ix + 12] ? parseFloat(parsedData[ix + 12]) : null,
750
- engineHours: parsedData[ix + 13] ? parseFloat(parsedData[ix + 13]) : null,
751
- drivingTime: parsedData[ix + 14] ? parseFloat(parsedData[ix + 14]) : null,
752
- idleTime: parsedData[ix + 15] ? parseFloat(parsedData[ix + 15]) : null,
753
- idleFuelUsed: parsedData[ix + 16] ? parseFloat(parsedData[ix + 16]) : null,
754
- axleWeight: parsedData[ix + 17] ? parseFloat(parsedData[ix + 17]) : null,
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,
755
762
  tachograph: parsedData[ix + 18] ? {
756
763
  raw: parsedData[ix + 18] ? parsedData[ix + 18] : null,
757
764
  validDriverData: tachographBin ? tachographBin[7] === '1' : null,
@@ -799,8 +806,8 @@ const getCanData = (parsedData, ix) => {
799
806
  trunk: doors ? doors[4] === '1' : null,
800
807
  hood: doors ? doors[5] === '1' : null
801
808
  } : null,
802
- overSpeedTime: parsedData[ix + 22] ? parseFloat(parsedData[ix + 22]) : null,
803
- overSpeedEngineTime: parsedData[ix + 23] ? parseFloat(parsedData[ix + 23]) : 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,
804
811
  canExpanded: {
805
812
  canReportExpansionMask: {
806
813
  raw: parsedData[ix + 24] ? parsedData[ix + 24] : null,
@@ -1163,7 +1170,7 @@ const getAlarm = (command, report, extra = false) => {
1163
1170
  if (extra === true && reportID === 1) {
1164
1171
  reportID = 2
1165
1172
  } else if (
1166
- ['gv800w', 'gv600w', 'gv300w', 'gv310lau', 'gv75w', 'GMT100'].includes(
1173
+ ['gv800w', 'gv600w', 'gv300w', 'gv310lau', 'gv58lau', 'gv75w', 'GMT100'].includes(
1167
1174
  extra
1168
1175
  )
1169
1176
  ) {
@@ -1333,9 +1340,9 @@ const getAlarm = (command, report, extra = false) => {
1333
1340
  } else if (command === 'GTAIS' || command === 'GTMAI') {
1334
1341
  const reportID = parseInt(report[0], 10)
1335
1342
  const reportType = parseInt(report[1], 10)
1336
- if (reportID === 2) {
1337
- return { type: 'SOS_Button', message: messages[command][reportID] }
1338
- }
1343
+ // if (reportID === 2) {
1344
+ // return { type: 'SOS_Button', message: messages[command][reportID] }
1345
+ // }
1339
1346
  return { type: 'AI', number: reportID, status: reportType === '0' }
1340
1347
  } else if (command === 'GTANT') {
1341
1348
  return {
@@ -1409,7 +1416,7 @@ const getAlarm = (command, report, extra = false) => {
1409
1416
  }
1410
1417
  } else if (command === 'GTIDA') {
1411
1418
  const status =
1412
- report.split(',')[1] !== null ? parseInt(report.split(',')[1], 10) : null
1419
+ report.split(',')[1] ? parseInt(report.split(',')[1], 10) : null
1413
1420
  const driverID = report.split(',')[0] !== null ? report.split(',')[0] : null
1414
1421
  return {
1415
1422
  type: 'Driver_Identification',
@@ -1616,6 +1623,17 @@ const getAlarm = (command, report, extra = false) => {
1616
1623
  temperature: temperature,
1617
1624
  message: messages[command][report].replace('()', `(${temperature}°C)`)
1618
1625
  }
1626
+ } else if (report === '20') {
1627
+ // Button pressed
1628
+ const number = parseInt(extra[0])
1629
+ const mac = extra[1]
1630
+ return {
1631
+ type: 'SOS_Button',
1632
+ number: number,
1633
+ deviceID: mac,
1634
+ voltage: extra[2].voltage ? extra[2].voltage : null,
1635
+ message: messages[command][report]
1636
+ }
1619
1637
  } else if (['07', '08', '09'].includes(report)) {
1620
1638
  const number = parseInt(extra[0])
1621
1639
  const mac = extra[1]
@@ -1672,6 +1690,15 @@ const getAlarm = (command, report, extra = false) => {
1672
1690
  }
1673
1691
  }
1674
1692
 
1693
+ /*
1694
+ Creates default output
1695
+ */
1696
+ const createDefaultOut = (size, defaultValue) => {
1697
+ return Object.fromEntries(
1698
+ Array.from({ length: size }, (_, i) => [i + 1, defaultValue])
1699
+ );
1700
+ }
1701
+
1675
1702
  /*
1676
1703
  Converst num to base number
1677
1704
  */
@@ -1814,6 +1841,7 @@ module.exports = {
1814
1841
  getCanData: getCanData,
1815
1842
  getBleData: getBleData,
1816
1843
  getAlarm: getAlarm,
1844
+ createDefaultOut: createDefaultOut,
1817
1845
  bin2dec: bin2dec,
1818
1846
  bin2hex: bin2hex,
1819
1847
  dec2bin: dec2bin,