93 lines
3.0 KiB
JavaScript
93 lines
3.0 KiB
JavaScript
'use strict';
|
|
|
|
const assert = require('assert'),
|
|
bitUtil = require('bit-util');
|
|
|
|
const GPS_13 = 0x13;
|
|
|
|
/**
|
|
* RAPParser is responsible for parsing RAP binary records
|
|
*/
|
|
class RAPParser {
|
|
|
|
constructor() {
|
|
// Using these local vars to avoid GC for more memory efficency
|
|
this._hour = 0;
|
|
this._minute = 0;
|
|
this._second = 0;
|
|
this._year = 0;
|
|
this._month = 0;
|
|
this._day = 0;
|
|
this._byte = 0;
|
|
}
|
|
|
|
/**
|
|
* Parse RAP binary response package
|
|
* @param {*} rapPkg The binary package data in Buffer. Structure: <Cmd><Len><Data>, Cmd = 0x13
|
|
* @returns a GPS data object
|
|
*/
|
|
parse(rapPkg) {
|
|
let record;
|
|
if (rapPkg && rapPkg[0] >= GPS_13) {
|
|
assert.ok(Buffer.isBuffer(rapPkg), 'rapPkg argument must be an instance of Buffer'); // prettier-ignore
|
|
|
|
// Byte 19th, if bit 4 is set -> has GPS Fix
|
|
if (rapPkg[18] && bitUtil.isBitOn(rapPkg[18], 4)) {
|
|
record = {};
|
|
let offset = 2; // Add 2 to skip the data package header <Cmd><Len> to read the data
|
|
|
|
record.lat = rapPkg.readInt32LE(offset) * 1e-5; offset += 4;
|
|
record.lon = rapPkg.readInt32LE(offset) * 1e-5; offset += 4;
|
|
record.speed = rapPkg.readUInt8(offset); offset += 1;
|
|
// GPS Direction in 2 Degree Increasements
|
|
record.head = rapPkg.readUInt8(offset) << 1; offset += 1;
|
|
|
|
this._hour = rapPkg.readUInt8(offset); offset += 1;
|
|
this._minute = rapPkg.readUInt8(offset); offset += 1;
|
|
this._second = rapPkg.readUInt8(offset); offset += 1;
|
|
this._year = 2000 + rapPkg.readUInt8(offset); offset += 1;
|
|
this._month = rapPkg.readUInt8(offset); offset += 1;
|
|
this._day = rapPkg.readUInt8(offset); offset += 1;
|
|
|
|
// Month in JS 0 => 11
|
|
record.gdt = new Date(Date.UTC(this._year, this._month - 1, this._day, this._hour, this._minute, this._second));
|
|
|
|
record.inputs = 0;
|
|
|
|
// Cmd 0x13. Byte 19th
|
|
this._byte = rapPkg.readUInt8(offset); offset += 1;
|
|
|
|
// Cmd 0x13. Byte 19th. Bits 0-3: numbers of GPS setellites
|
|
record.sats = bitUtil.extractBits(this._byte, 4, 0);
|
|
|
|
// Cmd 0x13. Byte 20th
|
|
this._byte = rapPkg.readUInt8(offset);
|
|
|
|
// Cmd 0x13. Byte 20th. Bit 3: Inputs+
|
|
if (bitUtil.isBitOn(this._byte, 3)) {
|
|
|
|
// Cmd 0x13. Byte 20th. Bit 0: 1 => extra inputs (21-24)
|
|
offset += bitUtil.isBitOn(this._byte, 0) ? 4 : 1;
|
|
|
|
// Skip reading Odometer data
|
|
|
|
// Cmd 0x13. Byte 21th/25th
|
|
this._byte = rapPkg.readUInt8(offset); offset += 1;
|
|
|
|
if (bitUtil.isBitOn(this._byte, 0)) {
|
|
// Cmd 0x13. Byte 22th/25th: Whether Digital input state present
|
|
this._byte = rapPkg.readUInt8(offset); offset += 1;
|
|
|
|
// Digital inputs (Up to 5, use only input 1 for Spray on/off, 0: spray on and 1 is off)
|
|
// Check Input 1 (bit 0) for spray on/off
|
|
record.inputs = bitUtil.isBitOn(this._byte, 0) ? 0 : 1;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
return record;
|
|
}
|
|
}
|
|
|
|
module.exports = RAPParser; |