Skip to content

Commit 2c7f006

Browse files
committed
feat(parser): Add support to save incomplete data. Now response a promise in method parse.
1 parent d7c4890 commit 2c7f006

6 files changed

Lines changed: 274 additions & 200 deletions

File tree

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ npm i -S cellocator-parser
2323
const cellocator = require('cellocator-parser');
2424

2525
const raw = new Buffer('4d43475000bdda0b0000060ddf20041017002000e3c40000baeff3c6b6224502000000000000ea65000402090daec5f7cb302cff3357000038090000930a002a170c03e007c1', 'hex');
26-
const data = cellocator.parse(raw);
26+
cellocator.parse(raw).then(result => console.log(result));
2727
/*{
2828
raw: '4d43475000bdda0b0000060ddf20041017002000e3c40000baeff3c6b6224502000000000000ea65000402090daec5f7cb302cff3357000038090000930a002a170c03e007c1',
29+
unitId: 776893,
2930
imei: 0,
3031
device: 'CelloTrack',
3132
type: 'data',

example.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
const cellocator = require('cellocator-parser');
22

33
const raw = new Buffer('4d43475000bdda0b0000060ddf20041017002000e3c40000baeff3c6b6224502000000000000ea65000402090daec5f7cb302cff3357000038090000930a002a170c03e007c1', 'hex');
4-
const data = cellocator.parse(raw);
4+
const data = await cellocator.parse(raw);

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@
3434
"homepage": "https://github.com/lgaticaq/cellocator-parser#readme",
3535
"dependencies": {
3636
"convert-base": "^0.1.0",
37+
"hiredis": "^0.5.0",
3738
"moment": "^2.13.0",
38-
"pad": "^1.0.0"
39+
"pad": "^1.0.0",
40+
"redis": "^2.6.2"
3941
},
4042
"devDependencies": {
4143
"chai": "^3.5.0",

src/index.js

Lines changed: 44 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -2,112 +2,45 @@
22

33
const utils = require('./utils');
44
const inbound = require('./inbound');
5+
const redis = require('redis');
6+
const Promise = require('bluebird');
7+
8+
let _client;
59

610
const patterns = {
711
data: /(4d434750[A-F0-9]{132})/gi
812
};
913

10-
const getData = raw => {
11-
const bytes = raw.toString('hex').split(/([A-F0-9]{2})/i).filter(x => x !== '');
12-
const seconds = bytes[62];
13-
const messageType = utils.parseMessageType(bytes[4]);
14-
const unitId = utils.parseUnitsId(bytes.slice(5, 9).join(''));
15-
const communication = utils.parseCommunication(bytes.slice(9, 11).join(''));
16-
const messageNumerator = utils.parseMessageNumerator(bytes[11]);
17-
const version = utils.parseVersion(bytes[12], bytes[13]);
18-
const transmissionReason = utils.parseTransmissionReason(bytes[18]);
19-
const engine = utils.parseEngineStatus(bytes[19]);
20-
const io = utils.parseIO(bytes.slice(20, 24).join(''));
21-
const unitsStatusCurrentGsmOperator = utils.parseUnitsStatusCurrentGsmOperator(bytes[15]);
22-
const currentGsmOperator = utils.parseCurrentGsmOperator(bytes[16]);
23-
const plmn = utils.parsePlmn(bytes[24], unitsStatusCurrentGsmOperator.currentGsmOperator1stNibble, currentGsmOperator);
24-
const analog1 = utils.parseAnalogInput1(bytes[25]);
25-
const analog2 = utils.parseAnalogInput2(bytes[26]);
26-
const analog3 = utils.parseAnalogInput3(bytes[27]);
27-
const analog4 = utils.parseAnalogInput4(bytes[28]);
28-
const odometer = utils.parseMileageCounter(bytes.slice(29, 32).join(''));
29-
const imei = utils.multiPurposeField(bytes.slice(32, 38).join(''), bytes[40]);
30-
const gpsTime = utils.parseGpsTime(bytes.slice(38, 40).join(''), seconds);
31-
const locationStatus = utils.parseLocationStatus(bytes[40]);
32-
const mode1 = utils.parseMode1(bytes[41]);
33-
const mode2 = utils.parseMode2(bytes[42]);
34-
const satellites = utils.parseSatellites(bytes[43]);
35-
const loc = utils.parseLoc(bytes.slice(44, 48).join(''), bytes.slice(48, 52).join(''));
36-
const altitude = utils.parseAltitude(bytes.slice(52, 56).join(''));
37-
const speed = utils.parseSpeed(bytes.slice(56, 60).join(''));
38-
const direction = utils.parseDirection(bytes.slice(60, 62).join(''));
39-
const datetime = utils.parseDatetime(bytes.slice(67, 69).join(''), bytes[66], bytes[65], bytes[64], bytes[63], bytes[62]);
40-
const data = {
41-
raw: bytes.join(''),
42-
unitId: unitId,
43-
imei: imei,
44-
device: 'CelloTrack',
45-
type: 'data',
46-
loc: loc,
47-
speed: speed,
48-
datetime: datetime,
49-
gpsTime: gpsTime,
50-
direction: direction,
51-
satellites: satellites,
52-
voltage: {
53-
ada: analog1,
54-
adb: analog2,
55-
adc: analog3,
56-
add: analog4
57-
},
58-
altitude: altitude,
59-
status: {
60-
engine: engine === 1,
61-
unlockInactive: io.unlockInactive,
62-
panicInactive: io.panicInactive,
63-
drivingStatus: io.drivingStatus,
64-
shockInactive: io.shockInactive,
65-
doorInactive: io.doorInactive,
66-
ignitionPortStatus: io.ignitionPortStatus,
67-
accelerometerStatus: io.accelerometerStatus,
68-
lock: io.lock,
69-
noHibernation: communication.noHibernation,
70-
momentarySpeed: communication.momentarySpeed,
71-
privateMode: communication.privateMode,
72-
firmwareSubversion: communication.firmwareSubversion,
73-
canOriginatedOdometer: communication.canOriginatedOdometer,
74-
canOriginatedSpeed: communication.canOriginatedSpeed,
75-
dataType33_38: communication.dataType33_38,
76-
messageSource: communication.messageSource,
77-
garminConnected: communication.garminConnected,
78-
garminEnable: communication.garminEnable,
79-
messageInitiative: communication.messageInitiative,
80-
locationStatus: locationStatus,
81-
charge: io.charge,
82-
standardImmobilizer: io.standardImmobilizer,
83-
globalOutput: io.globalOutput,
84-
ledOut: io.ledOut,
85-
gpsPower: io.gpsPower,
86-
gradualStop: io.gradualStop,
87-
siren: io.siren
88-
},
89-
version: version,
90-
transmissionReason: transmissionReason,
91-
odometer: odometer,
92-
gpsModes: {
93-
'1': mode1,
94-
'2': mode2
95-
},
96-
plmn: plmn,
97-
sn: messageNumerator,
98-
messageType: messageType
99-
};
100-
return data;
101-
};
102-
10314
const parse = raw => {
104-
const rawString = raw.toString('hex');
105-
let result = {type: 'UNKNOWN', raw: rawString};
106-
if (patterns.data.test(rawString)) {
107-
result = rawString.split(patterns.data).filter(x => patterns.data.test(x)).map(getData);
108-
if (result.length === 1) result = result[0];
109-
}
110-
return result;
15+
return new Promise((resolve, reject) => {
16+
const rawString = raw.toString('hex');
17+
if (!patterns.data.test(rawString)) resolve({type: 'UNKNOWN', raw: rawString});
18+
const results = rawString.split(patterns.data).filter(x => patterns.data.test(x)).map(utils.getData);
19+
if (!_client) {
20+
if (results.length === 1) resolve(results[0]);
21+
resolve(results);
22+
}
23+
_client.getAsync(`incompleteData:${results[0].unitId}`).then(reply => {
24+
const incompleteData = rawString.split(patterns.data).filter(x => !patterns.data.test(x) && x !== '');
25+
if (incompleteData.length > 0) {
26+
if (reply) {
27+
let previousData = '';
28+
if (/^4d434750/.test(reply)) {
29+
previousData = new Buffer(`${reply}${incompleteData[0]}`, 'hex');
30+
} else if (/^4d434750/.test(incompleteData[0])) {
31+
previousData = new Buffer(`${incompleteData[0]}${reply}`, 'hex');
32+
}
33+
if (patterns.data.test(previousData.toString('hex'))) {
34+
results.unshift(utils.getData(previousData));
35+
}
36+
} else {
37+
_client.set(`incompleteData:${results[0].unitId}`, incompleteData[0]);
38+
}
39+
}
40+
if (results.length === 1) resolve(results[0]);
41+
resolve(results);
42+
}).catch(reject);
43+
});
11144
};
11245

11346
const isCello = raw => {
@@ -118,15 +51,21 @@ const isCello = raw => {
11851
return result;
11952
};
12053

121-
const getImei = raw => {
122-
const bytes = raw.toString('hex').split(/([A-F0-9]{2})/i).filter(x => x !== '');
123-
return utils.multiPurposeField(bytes.slice(32, 38).join(''), bytes[40]);
54+
const setClient = options => {
55+
options = options || {};
56+
if (options.client) {
57+
_client = options.client;
58+
} else {
59+
_client = redis.createClient(options);
60+
}
61+
Promise.promisifyAll(Object.getPrototypeOf(_client));
12462
};
12563

12664
module.exports = {
12765
parse: parse,
12866
patterns: patterns,
12967
isCello: isCello,
130-
getImei: getImei,
131-
ack: inbound.ack
68+
getImei: utils.getImei,
69+
ack: inbound.ack,
70+
setClient: setClient
13271
};

0 commit comments

Comments
 (0)