queclink-parser 1.3.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/gv55.js ADDED
@@ -0,0 +1,512 @@
1
+ 'use strict'
2
+ const utils = require('./utils.js')
3
+
4
+ /*
5
+ Parses messages data from GV55 devices
6
+ */
7
+ const parse = raw => {
8
+ raw = raw.substr(0, raw.length - 1)
9
+
10
+ const parsedData = raw.split(',')
11
+ const command = parsedData[0].split(':')
12
+
13
+ let history = false
14
+ if (utils.patterns.buffer.test(command[0])) {
15
+ history = true
16
+ }
17
+
18
+ let data = {
19
+ raw: `${raw.toString()}$`,
20
+ manufacturer: 'queclink',
21
+ device: 'Queclink-GV55',
22
+ type: 'data',
23
+ imei: parsedData[2],
24
+ protocolVersion: utils.getProtocolVersion(parsedData[1]),
25
+ temperature: null,
26
+ history: history,
27
+ sentTime: utils.parseDate(parsedData[parsedData.length - 2]),
28
+ serialId: parseInt(parsedData[parsedData.length - 1], 16)
29
+ }
30
+
31
+ // GPS
32
+ if (command[1] === 'GTFRI') {
33
+ if (typeof parsedData[24] !== 'undefined' && parsedData[24] !== null) {
34
+ data = Object.assign(data, {
35
+ alarm: utils.getAlarm(command[1], null),
36
+ loc: {
37
+ type: 'Point',
38
+ coordinates: [parseFloat(parsedData[11]), parseFloat(parsedData[12])]
39
+ },
40
+ speed: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
41
+ gpsStatus: utils.checkGps(
42
+ parseFloat(parsedData[11]),
43
+ parseFloat(parsedData[12])
44
+ ),
45
+ hdop: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
46
+ status: {
47
+ raw: parsedData[24],
48
+ sos:
49
+ utils.nHexDigit(
50
+ utils.hex2bin(parsedData[24].substring(2, 4)),
51
+ 2
52
+ )[0] === '1',
53
+ state: utils.states[parsedData[24].substring(0, 2)],
54
+ input: {
55
+ '1':
56
+ utils.nHexDigit(
57
+ utils.hex2bin(parsedData[24].substring(2, 4)),
58
+ 2
59
+ )[1] === '1',
60
+ '2':
61
+ utils.nHexDigit(
62
+ utils.hex2bin(parsedData[24].substring(2, 4)),
63
+ 2
64
+ )[0] === '1'
65
+ },
66
+ output: {
67
+ '1':
68
+ utils.nHexDigit(
69
+ utils.hex2bin(parsedData[24].substring(4, 6)),
70
+ 2
71
+ )[1] === '1',
72
+ '2':
73
+ utils.nHexDigit(
74
+ utils.hex2bin(parsedData[24].substring(4, 6)),
75
+ 2
76
+ )[0] === '1'
77
+ },
78
+ charge: parseFloat(parsedData[4]) > 5
79
+ },
80
+ azimuth: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
81
+ altitude: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
82
+ datetime:
83
+ parsedData[13] !== '' ? utils.parseDate(parsedData[13]) : null,
84
+ voltage: {
85
+ battery: parsedData[23] !== '' ? parseFloat(parsedData[23]) : null, // percentage
86
+ inputCharge:
87
+ parsedData[4] !== '' ? parseFloat(parsedData[4]) / 1000 : null
88
+ },
89
+ mcc: parsedData[14] !== '' ? parseInt(parsedData[14], 10) : null,
90
+ mnc: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null,
91
+ lac: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
92
+ cid: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
93
+ odometer: parsedData[19] !== '' ? parseFloat(parsedData[19]) : null,
94
+ hourmeter:
95
+ parsedData[20] !== ''
96
+ ? utils.getHoursForHourmeter(parsedData[20])
97
+ : null
98
+ })
99
+ }
100
+ } else if (command[1] === 'GTHBD') {
101
+ // Heartbeat. It must response an ACK command
102
+ data = Object.assign(data, {
103
+ alarm: utils.getAlarm(command[1], null)
104
+ })
105
+ } else if (command[1] === 'GTINF') {
106
+ // General Info Report
107
+ data = Object.assign(data, {
108
+ alarm: utils.getAlarm(command[1], null),
109
+ state: utils.states[parsedData[4]],
110
+ gsmInfo: {
111
+ SIM_ICC: parsedData[5],
112
+ RSSI_dBm: parsedData[6],
113
+ RSSI_quality:
114
+ parsedData[7] !== ''
115
+ ? 100 * parseInt(parseFloat(parsedData[7]) / 7, 10)
116
+ : null // Percentage
117
+ },
118
+ backupBattery: {
119
+ using: parsedData[10] === '1',
120
+ voltage: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
121
+ charging: parsedData[12] === '1'
122
+ },
123
+ externalGPSAntenna: parsedData[15] === '0',
124
+ status: {
125
+ // parsedData[24]
126
+ raw: parsedData[18] + parsedData[19],
127
+ sos: false,
128
+ input: {
129
+ '1': utils.nHexDigit(utils.hex2bin(parsedData[20]), 2)[1] === '1',
130
+ '2': utils.nHexDigit(utils.hex2bin(parsedData[20]), 2)[0] === '1'
131
+ },
132
+ output: {
133
+ '1': utils.nHexDigit(utils.hex2bin(parsedData[21]), 2)[1] === '1',
134
+ '2': utils.nHexDigit(utils.hex2bin(parsedData[21]), 2)[0] === '1'
135
+ },
136
+ charge: parsedData[8] === '1'
137
+ },
138
+ voltage: {
139
+ battery:
140
+ parsedData[11] !== ''
141
+ ? parseInt(100 * (parseFloat(parsedData[11]) / 5), 10)
142
+ : null, // percentage
143
+ inputCharge:
144
+ parsedData[9] !== '' ? parseFloat(parsedData[9]) / 1000 : null
145
+ },
146
+ lastFixUTCTime:
147
+ parsedData[16] !== '' ? utils.parseDate(parsedData[16]) : null,
148
+ timezoneOffset: parsedData[22]
149
+ })
150
+ } else if (
151
+ command[1] === 'GTTOW' ||
152
+ command[1] === 'GTDIS' ||
153
+ command[1] === 'GTIOB' ||
154
+ command[1] === 'GTSPD' ||
155
+ command[1] === 'GTSOS' ||
156
+ command[1] === 'GTRTL' ||
157
+ command[1] === 'GTDOG' ||
158
+ command[1] === 'GTIGL' ||
159
+ command[1] === 'GTHBM'
160
+ ) {
161
+ // Common Alarms
162
+ data = Object.assign(data, {
163
+ alarm: utils.getAlarm(command[1], parsedData[5], true),
164
+ loc: {
165
+ type: 'Point',
166
+ coordinates: [parseFloat(parsedData[11]), parseFloat(parsedData[12])]
167
+ },
168
+ speed: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
169
+ gpsStatus: utils.checkGps(
170
+ parseFloat(parsedData[11]),
171
+ parseFloat(parsedData[12])
172
+ ),
173
+ hdop: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
174
+ status: null,
175
+ azimuth: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
176
+ altitude: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
177
+ datetime: parsedData[13] !== '' ? utils.parseDate(parsedData[13]) : null,
178
+ voltage: {
179
+ battery: null,
180
+ inputCharge: null
181
+ },
182
+ mcc: parsedData[14] !== '' ? parseInt(parsedData[14], 10) : null,
183
+ mnc: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null,
184
+ lac: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
185
+ cid: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
186
+ odometer: parsedData[19] !== '' ? parseFloat(parsedData[19]) : null,
187
+ hourmeter: null
188
+ })
189
+ } else if (command[1] === 'GTEPS' || command[1] === 'GTAIS') {
190
+ // External low battery and Low voltage for analog input
191
+ data = Object.assign(data, {
192
+ alarm: utils.getAlarm(command[1], parsedData[5]),
193
+ loc: {
194
+ type: 'Point',
195
+ coordinates: [parseFloat(parsedData[11]), parseFloat(parsedData[12])]
196
+ },
197
+ speed: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
198
+ gpsStatus: utils.checkGps(
199
+ parseFloat(parsedData[11]),
200
+ parseFloat(parsedData[12])
201
+ ),
202
+ hdop: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
203
+ status: null,
204
+ azimuth: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
205
+ altitude: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
206
+ datetime: parsedData[13] !== '' ? utils.parseDate(parsedData[13]) : null,
207
+ voltage: {
208
+ battery: parsedData[23] !== '' ? parseFloat(parsedData[23]) : null, // percentage
209
+ inputCharge:
210
+ parsedData[4] !== '' ? parseFloat(parsedData[4]) / 1000 : null
211
+ },
212
+ mcc: parsedData[14] !== '' ? parseInt(parsedData[14], 10) : null,
213
+ mnc: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null,
214
+ lac: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
215
+ cid: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
216
+ odometer: parsedData[19] !== '' ? parseFloat(parsedData[19]) : null,
217
+ hourmeter:
218
+ parsedData[20] !== ''
219
+ ? utils.getHoursForHourmeter(parsedData[20])
220
+ : null
221
+ })
222
+ } else if (
223
+ command[1] === 'GTPNA' ||
224
+ command[1] === 'GTPFA' ||
225
+ command[1] === 'GTPDP'
226
+ ) {
227
+ // Event report (It uses the last GPS data and MCC info)
228
+ data = Object.assign(data, {
229
+ alarm: utils.getAlarm(command[1], null),
230
+ loc: null,
231
+ speed: null,
232
+ gpsStatus: null,
233
+ hdop: null,
234
+ status: null,
235
+ azimuth: null,
236
+ altitude: null,
237
+ datetime: parsedData[4] !== '' ? utils.parseDate(parsedData[4]) : null,
238
+ voltage: {
239
+ battery: null,
240
+ inputCharge: null
241
+ },
242
+ mcc: null,
243
+ mnc: null,
244
+ lac: null,
245
+ cid: null,
246
+ odometer: null,
247
+ hourmeter: null
248
+ })
249
+ } else if (
250
+ command[1] === 'GTMPN' ||
251
+ command[1] === 'GTMPF' ||
252
+ command[1] === 'GTCRA' ||
253
+ command[1] === 'GTJDR'
254
+ ) {
255
+ data = Object.assign(data, {
256
+ alarm: utils.getAlarm(command[1], null),
257
+ loc: {
258
+ type: 'Point',
259
+ coordinates: [parseFloat(parsedData[8]), parseFloat(parsedData[9])]
260
+ },
261
+ speed: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
262
+ gpsStatus: utils.checkGps(
263
+ parseFloat(parsedData[8]),
264
+ parseFloat(parsedData[9])
265
+ ),
266
+ hdop: parsedData[4] !== '' ? parseFloat(parsedData[4]) : null,
267
+ status: null,
268
+ azimuth: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
269
+ altitude: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
270
+ datetime: parsedData[10] !== '' ? utils.parseDate(parsedData[10]) : null,
271
+ voltage: {
272
+ battery: null,
273
+ inputCharge: null
274
+ },
275
+ mcc: parsedData[11] !== '' ? parseInt(parsedData[11], 10) : null,
276
+ mnc: parsedData[12] !== '' ? parseInt(parsedData[12], 10) : null,
277
+ lac: parsedData[13] !== '' ? parseInt(parsedData[13], 16) : null,
278
+ cid: parsedData[14] !== '' ? parseInt(parsedData[14], 16) : null,
279
+ odometer: null,
280
+ hourmeter: null
281
+ })
282
+ } else if (
283
+ command[1] === 'GTJDS' ||
284
+ command[1] === 'GTANT' ||
285
+ command[1] === 'GTRMD'
286
+ ) {
287
+ data = Object.assign(data, {
288
+ alarm: utils.getAlarm(command[1], parsedData[4]),
289
+ loc: {
290
+ type: 'Point',
291
+ coordinates: [parseFloat(parsedData[9]), parseFloat(parsedData[10])]
292
+ },
293
+ speed: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
294
+ gpsStatus: utils.checkGps(
295
+ parseFloat(parsedData[9]),
296
+ parseFloat(parsedData[10])
297
+ ),
298
+ hdop: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
299
+ status: null,
300
+ azimuth: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
301
+ altitude: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
302
+ datetime: parsedData[11] !== '' ? utils.parseDate(parsedData[11]) : null,
303
+ voltage: {
304
+ battery: null,
305
+ inputCharge: null
306
+ },
307
+ mcc: parsedData[12] !== '' ? parseInt(parsedData[12], 10) : null,
308
+ mnc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
309
+ lac: parsedData[14] !== '' ? parseInt(parsedData[14], 16) : null,
310
+ cid: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
311
+ odometer: null,
312
+ hourmeter: null
313
+ })
314
+ } else if (command[1] === 'GTBPL') {
315
+ data = Object.assign(data, {
316
+ alarm: utils.getAlarm(command[1], null),
317
+ loc: {
318
+ type: 'Point',
319
+ coordinates: [parseFloat(parsedData[9]), parseFloat(parsedData[10])]
320
+ },
321
+ speed: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
322
+ gpsStatus: utils.checkGps(
323
+ parseFloat(parsedData[9]),
324
+ parseFloat(parsedData[10])
325
+ ),
326
+ hdop: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
327
+ status: null,
328
+ azimuth: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
329
+ altitude: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
330
+ datetime: parsedData[11] !== '' ? utils.parseDate(parsedData[11]) : null,
331
+ voltage: {
332
+ battery: parsedData[4] !== '' ? parseFloat(parsedData[4]) : null,
333
+ inputCharge: null
334
+ },
335
+ mcc: parsedData[12] !== '' ? parseInt(parsedData[12], 10) : null,
336
+ mnc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
337
+ lac: parsedData[14] !== '' ? parseInt(parsedData[14], 16) : null,
338
+ cid: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
339
+ odometer: null,
340
+ hourmeter: null
341
+ })
342
+ } else if (command[1] === 'GTIGN' || command[1] === 'GTIGF') {
343
+ data = Object.assign(data, {
344
+ alarm: utils.getAlarm(command[1], parsedData[4]),
345
+ loc: {
346
+ type: 'Point',
347
+ coordinates: [parseFloat(parsedData[9]), parseFloat(parsedData[10])]
348
+ },
349
+ speed: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
350
+ gpsStatus: utils.checkGps(
351
+ parseFloat(parsedData[9]),
352
+ parseFloat(parsedData[10])
353
+ ),
354
+ hdop: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
355
+ status: null,
356
+ azimuth: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
357
+ altitude: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
358
+ datetime: parsedData[11] !== '' ? utils.parseDate(parsedData[11]) : null,
359
+ voltage: {
360
+ battery: null,
361
+ inputCharge: null
362
+ },
363
+ mcc: parsedData[12] !== '' ? parseInt(parsedData[12], 10) : null,
364
+ mnc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
365
+ lac: parsedData[14] !== '' ? parseInt(parsedData[14], 16) : null,
366
+ cid: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
367
+ odometer: parsedData[18] !== '' ? parseFloat(parsedData[18]) : null,
368
+ hourmeter:
369
+ parsedData[17] !== ''
370
+ ? utils.getHoursForHourmeter(parsedData[17])
371
+ : null
372
+ })
373
+ } else if (command[1] === 'GTIDN' || command[1] === 'GTIDF') {
374
+ data = Object.assign(data, {
375
+ alarm: utils.getAlarm(command[1], parsedData[5]),
376
+ loc: {
377
+ type: 'Point',
378
+ coordinates: [parseFloat(parsedData[10]), parseFloat(parsedData[11])]
379
+ },
380
+ speed: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
381
+ gpsStatus: utils.checkGps(
382
+ parseFloat(parsedData[10]),
383
+ parseFloat(parsedData[11])
384
+ ),
385
+ hdop: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
386
+ status: null,
387
+ azimuth: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
388
+ altitude: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
389
+ datetime: parsedData[12] !== '' ? utils.parseDate(parsedData[12]) : null,
390
+ voltage: {
391
+ battery: null,
392
+ inputCharge: null
393
+ },
394
+ mcc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
395
+ mnc: parsedData[14] !== '' ? parseInt(parsedData[14], 10) : null,
396
+ lac: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
397
+ cid: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
398
+ odometer: parsedData[18] !== '' ? parseFloat(parsedData[18]) : null,
399
+ hourmeter: null
400
+ })
401
+ } else if (
402
+ command[1] === 'GTSTR' ||
403
+ command[1] === 'GTSTP' ||
404
+ command[1] === 'GTLSP'
405
+ ) {
406
+ data = Object.assign(data, {
407
+ alarm: utils.getAlarm(command[1], null),
408
+ loc: {
409
+ type: 'Point',
410
+ coordinates: [parseFloat(parsedData[10]), parseFloat(parsedData[11])]
411
+ },
412
+ speed: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
413
+ gpsStatus: utils.checkGps(
414
+ parseFloat(parsedData[10]),
415
+ parseFloat(parsedData[11])
416
+ ),
417
+ hdop: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
418
+ status: null,
419
+ azimuth: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
420
+ altitude: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
421
+ datetime: parsedData[12] !== '' ? utils.parseDate(parsedData[12]) : null,
422
+ voltage: {
423
+ battery: null,
424
+ inputCharge: null
425
+ },
426
+ mcc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
427
+ mnc: parsedData[14] !== '' ? parseInt(parsedData[14], 10) : null,
428
+ lac: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
429
+ cid: parsedData[16] !== '' ? parseInt(parsedData[16], 16) : null,
430
+ odometer: parsedData[18] !== '' ? parseFloat(parsedData[18]) : null,
431
+ hourmeter: null
432
+ })
433
+ } else if (command[1] === 'GTSTT') {
434
+ // Motion State Changed
435
+ data = Object.assign(data, {
436
+ alarm: utils.getAlarm(command[1], null),
437
+ loc: {
438
+ type: 'Point',
439
+ coordinates: [parseFloat(parsedData[9]), parseFloat(parsedData[10])]
440
+ },
441
+ speed: parsedData[6] !== '' ? parseFloat(parsedData[6]) : null,
442
+ gpsStatus: utils.checkGps(
443
+ parseFloat(parsedData[9]),
444
+ parseFloat(parsedData[10])
445
+ ),
446
+ hdop: parsedData[5] !== '' ? parseFloat(parsedData[5]) : null,
447
+ status: null,
448
+ azimuth: parsedData[7] !== '' ? parseFloat(parsedData[7]) : null,
449
+ altitude: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
450
+ datetime: parsedData[11] !== '' ? utils.parseDate(parsedData[11]) : null,
451
+ voltage: {
452
+ battery: null,
453
+ inputCharge: null
454
+ },
455
+ mcc: parsedData[12] !== '' ? parseInt(parsedData[12], 10) : null,
456
+ mnc: parsedData[13] !== '' ? parseInt(parsedData[13], 10) : null,
457
+ lac: parsedData[14] !== '' ? parseInt(parsedData[14], 16) : null,
458
+ cid: parsedData[15] !== '' ? parseInt(parsedData[15], 16) : null,
459
+ odometer: null,
460
+ hourmeter: null
461
+ })
462
+ } else if (command[1] === 'GTGSS') {
463
+ // GPS Status
464
+ data = Object.assign(data, {
465
+ alarm: utils.getAlarm(command[1], parsedData[4]),
466
+ loc: {
467
+ type: 'Point',
468
+ coordinates: [parseFloat(parsedData[12]), parseFloat(parsedData[13])]
469
+ },
470
+ speed: parsedData[9] !== '' ? parseFloat(parsedData[9]) : null,
471
+ gpsStatus: utils.checkGps(
472
+ parseFloat(parsedData[12]),
473
+ parseFloat(parsedData[13])
474
+ ),
475
+ hdop: parsedData[8] !== '' ? parseFloat(parsedData[8]) : null,
476
+ status: null,
477
+ azimuth: parsedData[10] !== '' ? parseFloat(parsedData[10]) : null,
478
+ altitude: parsedData[11] !== '' ? parseFloat(parsedData[11]) : null,
479
+ datetime: parsedData[14] !== '' ? utils.parseDate(parsedData[14]) : null,
480
+ voltage: {
481
+ battery: null,
482
+ inputCharge: null
483
+ },
484
+ mcc: parsedData[15] !== '' ? parseInt(parsedData[15], 10) : null,
485
+ mnc: parsedData[16] !== '' ? parseInt(parsedData[16], 10) : null,
486
+ lac: parsedData[17] !== '' ? parseInt(parsedData[17], 16) : null,
487
+ cid: parsedData[18] !== '' ? parseInt(parsedData[18], 16) : null,
488
+ odometer: null,
489
+ hourmeter: null
490
+ })
491
+ } else {
492
+ data = Object.assign(data, {
493
+ alarm: utils.getAlarm(command[1], null)
494
+ })
495
+ }
496
+ // Check gps data
497
+ if (data.loc !== null && typeof data.loc !== 'undefined') {
498
+ if (
499
+ data.loc.coordinates[0] === 0 ||
500
+ isNaN(data.loc.coordinates[0]) ||
501
+ data.loc.coordinates[1] === 0 ||
502
+ isNaN(data.loc.coordinates[1])
503
+ ) {
504
+ data.loc = null
505
+ }
506
+ }
507
+ return data
508
+ }
509
+
510
+ module.exports = {
511
+ parse: parse
512
+ }