queclink-parser 1.9.14 → 1.9.16

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,33 @@
1
+ #### 1.9.16 (2025-09-03)
2
+
3
+ ##### New Features
4
+
5
+ * **createDefaultOut:** se agrega función para componer GTOUT de forma eficiente. ([b65bcc61](https://github.com/jaayesta/queclink-parser/commit/b65bcc6188f78ab7156e67f00c636c9504296b4d))
6
+ * **dosReport:** se agrega soporte a reporte DOS en GTOUT. ([158d2e4b](https://github.com/jaayesta/queclink-parser/commit/158d2e4b79acdae6407fc214e48f95c12d57b657))
7
+ * **fw11:** se agrega soporte a FW 11 ([3b91541d](https://github.com/jaayesta/queclink-parser/commit/3b91541dbe53803eb91c1512e51250714e5cd109))
8
+
9
+ ##### Bug Fixes
10
+
11
+ * **can:** se corrige parseo de GTERI cuando <CANbus report mask> es 0. ([b817fa2f](https://github.com/jaayesta/queclink-parser/commit/b817fa2f533575e7b6b4bfa487cf0bd2c1e439b4))
12
+ * **logs:** se eliminan logs no requeridos. ([34cb15a7](https://github.com/jaayesta/queclink-parser/commit/34cb15a750fd99e2fbd62216cdf079f5de3b0e5e))
13
+ * **dis:** se agrega gv58lau en soporte para cambio de entradas digitales ([c0c43a99](https://github.com/jaayesta/queclink-parser/commit/c0c43a991c3817f7a25e22ae5c46d86d6a0cd4d1))
14
+ * **310lau:** cambios menores en comentarios y ejemplos ([aeacc58a](https://github.com/jaayesta/queclink-parser/commit/aeacc58aa6c58d98347b73c15cf78cfd1ab0fba0))
15
+ * **alarm:** se quita SOS de entrada análoga 2 ([f4cd28f3](https://github.com/jaayesta/queclink-parser/commit/f4cd28f3b4a735d66e34a8904518ef10da801c2f))
16
+
17
+ #### 1.9.15 (2025-03-11)
18
+
19
+ ##### New Features
20
+
21
+ * **tirepressure:** se incorpora presión de ntco en PSI e interpretación de rawData BLE ([a263d70f](https://github.com/jaayesta/queclink-parser/commit/a263d70f1b2a358ed2cdcd414ad445e5f158f16c))
22
+ * **rf433:** started support for RF433 devices ([2f4f5d9b](https://github.com/jaayesta/queclink-parser/commit/2f4f5d9bf680be49e52c7f931430bae80a905d74))
23
+
24
+ ##### Bug Fixes
25
+
26
+ * **messages:** se actualiza mensaje en ACK BTS ([1307d12f](https://github.com/jaayesta/queclink-parser/commit/1307d12f07922d1dfc4870b348126adaf92bb2d8))
27
+ * **tirepressure:**
28
+ * se quita linea de debug ([91794b17](https://github.com/jaayesta/queclink-parser/commit/91794b17672298ec754ff22ab7d78425aaf5a801))
29
+ * alarma de presión en PSI ([3f7262c1](https://github.com/jaayesta/queclink-parser/commit/3f7262c1b984b4899fb612b3d8c3498341191a95))
30
+
1
31
  #### 1.9.14 (2025-01-27)
2
32
 
3
33
  ##### New Features
package/example.js CHANGED
@@ -79,12 +79,18 @@ var test = '+RESP:GTERI,6E0B00,868589060064048,,00000100,12109,10,1,1,0.0,83,3.1
79
79
  var test2 = '+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,00,13,0,00000000,4007,,78054143F00B,1,0,01,6,4,17C608B8,283F,,78054133CB9F,1,3443,22,60,22.32,100,20250121174252,7B18$'
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
+ 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 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$'
82
87
 
83
-
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$"
84
90
  var data = {
85
91
  "imei": 868589060039404,
86
- "instruction": "temp_alarm_on",
87
- "sensor_type": 'WTH300',
92
+ "instruction": "temp_alarm_off",
93
+ "sensor_type": 'WTH301',
88
94
  "sensor_index": 1,
89
95
  "action": "Configurar alarma de temperatura",
90
96
  "device": "queclink",
@@ -95,72 +101,77 @@ var data = {
95
101
  "maxTemp": 29 || null
96
102
  }
97
103
 
98
- // console.log(queclink.parseCommand(data))
99
- const raw = new Buffer.from(test4)
100
- console.log(JSON.stringify(queclink.parse(raw), null, 2))
101
- // queclink.parse(raw)
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
+
102
152
 
103
- // if (data.can) {
104
- // const {
105
- // comunicationOk,
106
- // vin,
107
- // ignitionKey,
108
- // totalDistance,
109
- // totalDistanceUnit,
110
- // rpm,
111
- // speed,
112
- // engineCoolantTemp,
113
- // fuelConsumption,
114
- // fuelLevel,
115
- // fuelLevelUnit,
116
- // range,
117
- // acceleratorPressure,
118
- // engineHours,
119
- // drivingTime,
120
- // idleTime,
121
- // idleFuelUsed,
122
- // axleWeight,
123
- // tachograph,
124
- // indicators,
125
- // lights,
126
- // doors,
127
- // overSpeedTime,
128
- // overSpeedEngineTime
129
- // } = data.can
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)
172
+ console.log(JSON.stringify(queclink.parse(raw), null, 2))
173
+ queclink.parse(raw)
130
174
 
131
- // const canData = {
132
- // raw: data.raw,
133
- // imei: data.imei,
134
- // datetime: data.datetime,
135
- // point: data.point,
136
- // comunicationOk,
137
- // vin,
138
- // ignitionKey,
139
- // totalDistance,
140
- // totalDistanceUnit,
141
- // rpm,
142
- // speed,
143
- // engineCoolantTemp,
144
- // fuelConsumption,
145
- // fuelLevel,
146
- // fuelLevelUnit,
147
- // range,
148
- // acceleratorPressure,
149
- // engineHours,
150
- // drivingTime,
151
- // idleTime,
152
- // idleFuelUsed,
153
- // axleWeight,
154
- // tachograph,
155
- // indicators,
156
- // lights,
157
- // doors,
158
- // overSpeedTime,
159
- // overSpeedEngineTime,
160
- // ...data.can.canExpanded
161
- // }
162
175
 
163
- // canData.canReportExpansionMask = canData.canReportExpansionMask.raw
164
- // console.log(canData)
165
- // delete data.can
166
- // }
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.14",
3
+ "version": "1.9.16",
4
4
  "description": "Parse raw data from Queclink devices",
5
5
  "main": "src",
6
6
  "scripts": {
package/src/gv310lau.js CHANGED
@@ -27,7 +27,6 @@ const parse = raw => {
27
27
  sentTime: utils.parseDate(parsedData[parsedData.length - 2]),
28
28
  serialId: parseInt(parsedData[parsedData.length - 1], 16)
29
29
  }
30
-
31
30
  // Gps
32
31
  if (command[1] === 'GTFRI') {
33
32
  try {
@@ -395,6 +394,8 @@ const parse = raw => {
395
394
  AC100 && digitFuelSensor
396
395
  ? parseInt(parsedData[index + 10], 10)
397
396
  : AC100 && !digitFuelSensor ? parseInt(parsedData[index + 9], 10) : 0
397
+ // Review when RF433 devices are implemented
398
+ const rf433DevicesConnected = parsedData[index + 8] === '7' ? parseInt(parsedData[index + 9]) : 0
398
399
 
399
400
  let externalData = {
400
401
  eriMask: {
@@ -540,33 +541,63 @@ const parse = raw => {
540
541
  AC100Devices: ac100Devices
541
542
  })
542
543
  }
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
+ // })
543
565
  }
544
566
 
567
+ var isValidCanData = true
545
568
  if (canData) {
546
569
  let newIndex = digitFuelSensor && !AC100 ? index + 9 + 1 : !digitFuelSensor && AC100 ? index + 9 + 4 : digitFuelSensor && AC100 ? index + 9 + 5 : index + 9
547
570
  let canInfo = utils.getCanData(parsedData, newIndex)
548
- data = Object.assign(data, { can: canInfo })
549
- index = index + 49
571
+ if (Object.keys(canInfo).length > 0) {
572
+ data = Object.assign(data, { can: canInfo })
573
+ index = index + 49
550
574
 
551
- if (canInfo?.totalDistance) {
552
- data.gpsOdometer = data.odometer
553
- data.odometer = canInfo.totalDistance
554
- }
575
+ if (canInfo?.totalDistance) {
576
+ data.gpsOdometer = data.odometer
577
+ data.odometer = canInfo.totalDistance
578
+ }
555
579
 
556
- if (canInfo?.engineHours) {
557
- data.gpsHourmeter = data.hourmeter
558
- data.hourmeter = canInfo.engineHours
559
- }
580
+ if (canInfo?.engineHours) {
581
+ data.gpsHourmeter = data.hourmeter
582
+ data.hourmeter = canInfo.engineHours
583
+ }
560
584
 
561
- if (canInfo?.speed) {
562
- data.gpsSpeed = data.speed
563
- data.speed = canInfo.speed
585
+ if (canInfo?.speed) {
586
+ data.gpsSpeed = data.speed
587
+ data.speed = canInfo.speed
588
+ }
589
+ } else {
590
+ isValidCanData = false
564
591
  }
565
592
  }
566
593
 
567
594
  // Bluetooth Accessories
568
595
  if (bluetoothAccessory) {
569
596
  let btIndex = digitFuelSensor ? index + 10 : index + 9
597
+ if (canData) {
598
+ btIndex = isValidCanData? btIndex : btIndex + 2
599
+ }
600
+
570
601
  let btDevices = utils.getBleData(parsedData, btIndex)
571
602
  externalData = Object.assign(externalData, {
572
603
  btDevices: btDevices
@@ -800,7 +831,7 @@ const parse = raw => {
800
831
  hourmeter: null
801
832
  })
802
833
  } else if (command[1] === 'GTEPS' || command[1] === 'GTAIS') {
803
- // External low battery and Low voltage for analog input
834
+ // External low battery and voltage for analog input
804
835
  let number = parsedData[6] !== '' ? parseInt(parsedData[6], 10) : 1
805
836
  let index = 6 + 12 * number // position append mask
806
837
  let satelliteInfo = false
@@ -1637,14 +1668,11 @@ const parse = raw => {
1637
1668
  })
1638
1669
  } else {
1639
1670
  // Long format
1640
- let index = 20 // position append mask
1641
- let satelliteInfo = false
1642
-
1643
- // If get satellites is configured
1644
- if (utils.includeSatellites(parsedData[index])) {
1645
- index += 1
1646
- satelliteInfo = true
1647
- }
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
+
1648
1676
 
1649
1677
  data = Object.assign(data, {
1650
1678
  alarm: utils.getAlarm(command[1], parsedData[8], parsedData[6]),
@@ -1675,10 +1703,25 @@ const parse = raw => {
1675
1703
  lac: parsedData[18] !== '' ? parseInt(parsedData[18], 16) : null,
1676
1704
  cid: parsedData[19] !== '' ? parseInt(parsedData[19], 16) : null,
1677
1705
  satellites:
1678
- satelliteInfo && parsedData[index] !== ''
1679
- ? 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])
1680
1724
  : null,
1681
- odometer: null,
1682
1725
  hourmeter: null
1683
1726
  })
1684
1727
  }
@@ -2043,7 +2086,7 @@ const parse = raw => {
2043
2086
  : null,
2044
2087
  tirePresure:
2045
2088
  parsedData[pressIx] !== '' && appendMask[6] === '1'
2046
- ? parseInt(parsedData[pressIx])
2089
+ ? parseInt(parsedData[pressIx]) / 6.895
2047
2090
  : null,
2048
2091
  timestamp:
2049
2092
  parsedData[timeIx] !== '' && appendMask[5] === '1'
package/src/gv58lau.js CHANGED
@@ -1780,7 +1780,7 @@ const parse = raw => {
1780
1780
  : null,
1781
1781
  tirePresure:
1782
1782
  parsedData[pressIx] !== '' && appendMask[6] === '1'
1783
- ? parseInt(parsedData[pressIx])
1783
+ ? parseInt(parsedData[pressIx]) / 6.895
1784
1784
  : null,
1785
1785
  timestamp:
1786
1786
  parsedData[timeIx] !== '' && appendMask[5] === '1'
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": {
@@ -300,7 +301,7 @@
300
301
  "GTVVS": "Config: ignición virtual",
301
302
  "GTAVS": "Config: ignición por acelerómetro",
302
303
  "GTVMS": "Config: modo de ignición",
303
- "GTBTS": "Config: protocolo bluetooth",
304
+ "GTBTS": "Config: general bluetooth",
304
305
  "GTBAS": "Config: accesorio bluetooth",
305
306
  "GTBID": "Config: baliza bluetooth",
306
307
  "GTHMC": "Config: horómetro",
package/src/utils.js CHANGED
@@ -211,7 +211,7 @@ const bluetoothModels = {
211
211
  '0': 'MAG ELA (Door Sensor)'
212
212
  },
213
213
  '12': {
214
- '0': 'MLD BLE TPMS (ATP100/ATP102)'
214
+ '0': 'ATP100/ATP102'
215
215
  },
216
216
  '13': {
217
217
  '0': 'WRL300 (Bluetooth Relay)'
@@ -431,12 +431,46 @@ const getTempInCelciousDegrees = hexTemp => {
431
431
  }
432
432
 
433
433
  /*
434
- Gets the temperature and humidity from bluetooth device
434
+ Gets the temperature from BLE devices in celcious degrees
435
435
  */
436
- const getBtTempHumData = hexTemp => {
437
- var int = parseInt(hexTemp.substring(0, 2), 16)
438
- var dec = parseInt(hexTemp.substring(2, 4), 16)
439
- return int + dec / 256
436
+ const getBleTempInCelciousDegrees = (device, hexData) => {
437
+ if (device === 'WTH300') {
438
+ let intTemp = parseInt(hexData.substring(0, 2), 16)
439
+ let decTemp = parseInt(hexData.substring(2, 4), 16)
440
+ return intTemp + decTemp / 256
441
+ } else if (['WTH301', 'WMS301'].includes(device)) {
442
+ let intTemp = parseInt(hexData.substring(0, 2), 16)
443
+ let decTemp = parseInt(hexData.substring(2, 4), 16)
444
+ return intTemp + decTemp / 100
445
+ } else if (device === 'ATP100/ATP102') {
446
+ let temp = parseInt(hexData.substring(4, 6), 16)
447
+ return temp - 40
448
+ } else {
449
+ return null
450
+ }
451
+ }
452
+
453
+ /*
454
+ Gets the humidity from BLE devices in rh
455
+ */
456
+ const getBleHumidityInRH = (device, hexData) => {
457
+ let intHum = parseInt(hexData.substring(4, 6), 16)
458
+ let decHum = parseInt(hexData.substring(6, 8), 16)
459
+ if (device === 'WTH300') {
460
+ return intHum + decHum / 256
461
+ } else if (['WTH301', 'WMS301'].includes(device)) {
462
+ return intHum + decHum / 100
463
+ } else {
464
+ return null
465
+ }
466
+ }
467
+
468
+ /*
469
+ Gets the humidity from BLE devices in rh
470
+ */
471
+ const getTirePressureInPSI = hexData => {
472
+ let tirePress = parseInt(hexData.substring(2, 4), 16) * 2.5 // In kPa
473
+ return tirePress / 6.895 // In PSI
440
474
  }
441
475
 
442
476
  /*
@@ -662,20 +696,27 @@ const parseCanData = (data, key) => {
662
696
  Get CANbus data
663
697
  */
664
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
+
665
706
  let inicatorsBin =
666
- parsedData[ix + 19] !== ''
707
+ canAppendMask[14] && parsedData[ix + 19] !== ''
667
708
  ? nHexDigit(hex2bin(parsedData[ix + 19]), 16)
668
709
  : null
669
710
  let lights =
670
- parsedData[ix + 20] !== ''
711
+ canAppendMask[13] && parsedData[ix + 20] !== ''
671
712
  ? nHexDigit(hex2bin(parsedData[ix + 20]), 8)
672
713
  : null
673
714
  let doors =
674
- parsedData[ix + 21] !== ''
715
+ canAppendMask[12] && parsedData[ix + 21] !== ''
675
716
  ? nHexDigit(hex2bin(parsedData[ix + 21]), 8)
676
717
  : null
677
718
  let canExpansionMask =
678
- parsedData[ix + 24] !== ''
719
+ canAppendMask[2] && parsedData[ix + 24] !== ''
679
720
  ? nHexDigit(hex2bin(parsedData[ix + 24]), 32)
680
721
  .split('')
681
722
  .reverse()
@@ -689,7 +730,7 @@ const getCanData = (parsedData, ix) => {
689
730
  .join('')
690
731
  : null
691
732
  let tachographBin =
692
- parsedData[ix + 18] !== ''
733
+ canAppendMask[15] && parsedData[ix + 18] !== ''
693
734
  ? nHexDigit(hex2bin(parsedData[ix + 18]), 8)
694
735
  .split('')
695
736
  .reverse()
@@ -698,26 +739,26 @@ const getCanData = (parsedData, ix) => {
698
739
 
699
740
  return {
700
741
  comunicationOk: parsedData[ix] ? parsedData[ix] === '1' : null,
701
- vin: parsedData[ix + 2] ? parsedData[ix + 2] : null,
702
- ignitionKey: parsedData[ix + 3] ? parseCanData(parsedData[ix + 3], 'ignitionKey') : null,
703
- totalDistance: parsedData[ix + 4] ? parseCanData(parsedData[ix + 4], 'totalDistance') : null,
704
- totalDistanceUnit: parsedData[ix + 4] ? parsedData[ix + 4].slice(0, 1) === 'H' ? 'km' : 'I' : null,
705
- fuelUsed: parsedData[ix + 5] ? parseFloat(parsedData[ix + 5]) : null, // float
706
- rpm: parsedData[ix + 6] ? parseInt(parsedData[ix + 6], 10) : null, // int
707
- 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,
708
749
  engineCoolantTemp:
709
- parsedData[ix + 8] ? parseInt(parsedData[ix + 8], 10) : null,
710
- fuelConsumption: parsedData[ix + 9] ? parseCanData(parsedData[ix + 9], 'fuelConsumption') : null,
711
- fuelLevel: parsedData[ix + 10] ? parseFloat(parsedData[ix + 10].slice(1)) : null,
712
- fuelLevelUnit: parsedData[ix + 10] ? parsedData[ix + 10].slice(0, 1) === 'P' ? '%' : 'L' : null,
713
- 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,
714
755
  acceleratorPressure:
715
- parsedData[ix + 12] ? parseFloat(parsedData[ix + 12]) : null,
716
- engineHours: parsedData[ix + 13] ? parseFloat(parsedData[ix + 13]) : null,
717
- drivingTime: parsedData[ix + 14] ? parseFloat(parsedData[ix + 14]) : null,
718
- idleTime: parsedData[ix + 15] ? parseFloat(parsedData[ix + 15]) : null,
719
- idleFuelUsed: parsedData[ix + 16] ? parseFloat(parsedData[ix + 16]) : null,
720
- 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,
721
762
  tachograph: parsedData[ix + 18] ? {
722
763
  raw: parsedData[ix + 18] ? parsedData[ix + 18] : null,
723
764
  validDriverData: tachographBin ? tachographBin[7] === '1' : null,
@@ -765,8 +806,8 @@ const getCanData = (parsedData, ix) => {
765
806
  trunk: doors ? doors[4] === '1' : null,
766
807
  hood: doors ? doors[5] === '1' : null
767
808
  } : null,
768
- overSpeedTime: parsedData[ix + 22] ? parseFloat(parsedData[ix + 22]) : null,
769
- 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,
770
811
  canExpanded: {
771
812
  canReportExpansionMask: {
772
813
  raw: parsedData[ix + 24] ? parsedData[ix + 24] : null,
@@ -924,14 +965,17 @@ const getBleData = (parsedData, btIndex) => {
924
965
  ? magIx + 3 : magIx + parseInt(appendMask[2])
925
966
  let relIx = aBatpIx + parseInt(appendMask[1])
926
967
 
968
+ let bleType = bluetoothAccessories[parsedData[cnt + 1]]
969
+ let bleModel = parsedData[cnt + 2] !== ''
970
+ ? bluetoothModels[parsedData[cnt + 1]][parsedData[cnt + 2]]
971
+ : null
972
+ let rawAppendMask = parsedData[cnt + 4]
973
+
927
974
  btDevices.push({
928
975
  index: parsedData[cnt],
929
- type: bluetoothAccessories[parsedData[cnt + 1]],
930
- model:
931
- parsedData[cnt + 2] !== ''
932
- ? bluetoothModels[parsedData[cnt + 1]][parsedData[cnt + 2]]
933
- : null,
934
- appendMask: parsedData[cnt + 4],
976
+ type: bleType,
977
+ model: bleModel,
978
+ appendMask: rawAppendMask,
935
979
  name:
936
980
  parsedData[aNameIx] !== '' && appendMask[15] === '1'
937
981
  ? parsedData[aNameIx]
@@ -953,7 +997,15 @@ const getBleData = (parsedData, btIndex) => {
953
997
  ? parseFloat(parsedData[aBatpIx])
954
998
  : null,
955
999
  accessoryData: {
956
- rawData: parsedData[cnt + 3] !== '' ? parsedData[cnt + 3] : null,
1000
+ data: parsedData[cnt + 3] !== '' ? {
1001
+ raw: parsedData[cnt + 3],
1002
+ temperature: getBleTempInCelciousDegrees(bleModel, parsedData[cnt + 3]),
1003
+ humidity: getBleHumidityInRH(bleModel, parsedData[cnt + 3]),
1004
+ relayState: bleModel === 'WRL300' ? parseInt(parsedData[cnt + 3]) === 1 ? 'Connected' : 'Disconnected' : null,
1005
+ tirePresure: getTirePressureInPSI(parsedData[cnt + 3]),
1006
+ productModel: bleModel === 'ATP100/ATP102' ? parsedData[cnt + 3].substring(6, 7) : null,
1007
+ fwVersion: bleModel === 'ATP100/ATP102' ? parsedData[cnt + 3].substring(7, 8) : null,
1008
+ } : null,
957
1009
  temperature:
958
1010
  parsedData[aTmpIx] !== '' && appendMask[11] === '1'
959
1011
  ? parseInt(parsedData[aTmpIx])
@@ -980,7 +1032,7 @@ const getBleData = (parsedData, btIndex) => {
980
1032
  : null,
981
1033
  tirePresure:
982
1034
  parsedData[pressIx] !== '' && appendMask[6] === '1'
983
- ? parseInt(parsedData[pressIx])
1035
+ ? parseInt(parsedData[pressIx]) / 6.895
984
1036
  : null,
985
1037
  timestamp:
986
1038
  parsedData[timeIx] !== '' && appendMask[5] === '1'
@@ -1118,7 +1170,7 @@ const getAlarm = (command, report, extra = false) => {
1118
1170
  if (extra === true && reportID === 1) {
1119
1171
  reportID = 2
1120
1172
  } else if (
1121
- ['gv800w', 'gv600w', 'gv300w', 'gv310lau', 'gv75w', 'GMT100'].includes(
1173
+ ['gv800w', 'gv600w', 'gv300w', 'gv310lau', 'gv58lau', 'gv75w', 'GMT100'].includes(
1122
1174
  extra
1123
1175
  )
1124
1176
  ) {
@@ -1288,9 +1340,9 @@ const getAlarm = (command, report, extra = false) => {
1288
1340
  } else if (command === 'GTAIS' || command === 'GTMAI') {
1289
1341
  const reportID = parseInt(report[0], 10)
1290
1342
  const reportType = parseInt(report[1], 10)
1291
- if (reportID === 2) {
1292
- return { type: 'SOS_Button', message: messages[command][reportID] }
1293
- }
1343
+ // if (reportID === 2) {
1344
+ // return { type: 'SOS_Button', message: messages[command][reportID] }
1345
+ // }
1294
1346
  return { type: 'AI', number: reportID, status: reportType === '0' }
1295
1347
  } else if (command === 'GTANT') {
1296
1348
  return {
@@ -1364,7 +1416,7 @@ const getAlarm = (command, report, extra = false) => {
1364
1416
  }
1365
1417
  } else if (command === 'GTIDA') {
1366
1418
  const status =
1367
- report.split(',')[1] !== null ? parseInt(report.split(',')[1], 10) : null
1419
+ report.split(',')[1] ? parseInt(report.split(',')[1], 10) : null
1368
1420
  const driverID = report.split(',')[0] !== null ? report.split(',')[0] : null
1369
1421
  return {
1370
1422
  type: 'Driver_Identification',
@@ -1627,6 +1679,15 @@ const getAlarm = (command, report, extra = false) => {
1627
1679
  }
1628
1680
  }
1629
1681
 
1682
+ /*
1683
+ Creates default output
1684
+ */
1685
+ const createDefaultOut = (size, defaultValue) => {
1686
+ return Object.fromEntries(
1687
+ Array.from({ length: size }, (_, i) => [i + 1, defaultValue])
1688
+ );
1689
+ }
1690
+
1630
1691
  /*
1631
1692
  Converst num to base number
1632
1693
  */
@@ -1762,7 +1823,6 @@ module.exports = {
1762
1823
  includeGnnsAccuracy: includeGnnsAccuracy,
1763
1824
  getAccelerationMagnitude: getAccelerationMagnitude,
1764
1825
  getTempInCelciousDegrees: getTempInCelciousDegrees,
1765
- getBtTempHumData: getBtTempHumData,
1766
1826
  getFuelConsumption: getFuelConsumption,
1767
1827
  getHoursForHourmeter: getHoursForHourmeter,
1768
1828
  getSignalStrength: getSignalStrength,
@@ -1770,6 +1830,7 @@ module.exports = {
1770
1830
  getCanData: getCanData,
1771
1831
  getBleData: getBleData,
1772
1832
  getAlarm: getAlarm,
1833
+ createDefaultOut: createDefaultOut,
1773
1834
  bin2dec: bin2dec,
1774
1835
  bin2hex: bin2hex,
1775
1836
  dec2bin: dec2bin,