update
This commit is contained in:
@ -1,5 +1,8 @@
|
||||
const LibHelper = require("./LibHelper");
|
||||
|
||||
// Menyimpan status per device untuk mendeteksi cache
|
||||
const deviceStates = {};
|
||||
|
||||
class LibDevice {
|
||||
/**
|
||||
*
|
||||
@ -21,198 +24,105 @@ class LibDevice {
|
||||
ori_string: data,
|
||||
};
|
||||
|
||||
// eelinkCustom
|
||||
if (opts.isEelinkCustom) {
|
||||
me.protocol_name = "eelinkCustom";
|
||||
|
||||
me.field0 = data.slice(0, 2); // system status flag
|
||||
me.field1 = data.slice(2, 18); // IMEI
|
||||
me.field2 = data.slice(18, 34); // IMSI
|
||||
me.field3 = data.slice(34, 42); // Time
|
||||
me.field4 = data.slice(42, 58); // Location
|
||||
me.field5 = data.slice(58, 62); // Altitude
|
||||
me.field6 = data.slice(62, 66); // Heading
|
||||
me.field7 = data.slice(66, 68); // Velocity
|
||||
me.field8 = data.slice(68, 70); // Power Input Voltage
|
||||
me.field9 = data.slice(70, 72); // GPIO Status
|
||||
me.field10 = data.slice(72, 74); // Time Seconds
|
||||
me.field11 = data.slice(74, 76); // RSSI
|
||||
me.field12 = data.slice(76, 78); // Sequence Counter
|
||||
me.field13 = data.slice(78, 80); // Vendor ID
|
||||
me.field14 = data.slice(80, 82); // GPS Satellites
|
||||
me.field15 = data.slice(82, 90); // Accumulators
|
||||
|
||||
me.field0 = data.slice(0, 2);
|
||||
me.field1 = data.slice(2, 18);
|
||||
me.field2 = data.slice(18, 34);
|
||||
me.field3 = data.slice(34, 42);
|
||||
me.field4 = data.slice(42, 58);
|
||||
me.field5 = data.slice(58, 62);
|
||||
me.field6 = data.slice(62, 66);
|
||||
me.field7 = data.slice(66, 68);
|
||||
me.field8 = data.slice(68, 70);
|
||||
me.field9 = data.slice(70, 72);
|
||||
me.field10 = data.slice(72, 74);
|
||||
me.field11 = data.slice(74, 76);
|
||||
me.field12 = data.slice(76, 78);
|
||||
me.field13 = data.slice(78, 80);
|
||||
me.field14 = data.slice(80, 82);
|
||||
me.field15 = data.slice(82, 90);
|
||||
me.ori_string = data;
|
||||
}
|
||||
// gt06
|
||||
else if (data.slice(0, 4) == "7878" || data.slice(0, 4) == "7979") {
|
||||
} else if (data.slice(0, 4) == "7878" || data.slice(0, 4) == "7979") {
|
||||
me.protocol_name = "gt06";
|
||||
|
||||
me.start = data.slice(0, 4);
|
||||
me.length = parseInt(data.slice(4, 6), 16);
|
||||
me.protocol_id = data.slice(6, 8);
|
||||
me.serial_number = data.slice(-12, -8);
|
||||
me.error_check = data.slice(-8, -4);
|
||||
me.finish = data.slice(-4); // data.substr(6 + me.length * 2, 4);
|
||||
|
||||
me.finish = data.slice(-4);
|
||||
if (me.finish != "0d0a") {
|
||||
throw "finish code incorrect!";
|
||||
}
|
||||
|
||||
me.ori_string = data;
|
||||
}
|
||||
// gt02a
|
||||
else if (data.slice(0, 4) == "6868") {
|
||||
} else if (data.slice(0, 4) == "6868") {
|
||||
me.protocol_name = "gt02a";
|
||||
}
|
||||
// tk103
|
||||
// else if (data.indexOf("B")) {
|
||||
// me.protocol_name = 'tk103';
|
||||
// }
|
||||
// eelink
|
||||
else if (data.slice(0, 4) == "6767") {
|
||||
} else if (data.slice(0, 4) == "6767") {
|
||||
me.protocol_name = "eelink";
|
||||
|
||||
me.start = data.slice(0, 4);
|
||||
me.pid = data.slice(4, 6);
|
||||
me.size = parseInt(data.slice(6, 10), 16);
|
||||
me.sequence = parseInt(data.slice(10, 4), 16);
|
||||
|
||||
me.ori_string = data;
|
||||
}
|
||||
// unknown
|
||||
else {
|
||||
} else {
|
||||
me.protocol_name = "unknown";
|
||||
}
|
||||
|
||||
return me;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Object} me
|
||||
* @param {String} device_id
|
||||
* @returns
|
||||
* must return at least => act.cmd,act.action_type,act.device_id
|
||||
*/
|
||||
static gt06Action(me, device_id = null) {
|
||||
const act = {};
|
||||
|
||||
// Login message
|
||||
if (me.protocol_id == "01") {
|
||||
act.action_type = "login";
|
||||
|
||||
act.cmd = "login_request";
|
||||
act.action = "login_request";
|
||||
act.device_id = me.ori_string.slice(8).slice(0, 16).padStart(16, "0");
|
||||
|
||||
act.buffer_resp = LibDevice.gt06AuthorizeResp(me);
|
||||
}
|
||||
// Location data
|
||||
else if (me.protocol_id == "12" || me.protocol_id == "a0") {
|
||||
} else if (me.protocol_id == "12" || me.protocol_id == "a0") {
|
||||
act.action_type = "location";
|
||||
|
||||
act.cmd = "ping";
|
||||
act.action = "ping";
|
||||
act.device_id = device_id; // because device_id only sent when login
|
||||
|
||||
// content data
|
||||
// me.ori_string.slice(8).slice(0, 52); // me.ori_string.substr(8, me.length * 2);
|
||||
|
||||
// gps information
|
||||
act.device_id = device_id;
|
||||
act.gps_string = me.ori_string.slice(8).slice(0, 36);
|
||||
act.gps_data = LibDevice.gt06ParseLocation(me, act.gps_string);
|
||||
// if (!act.gps_data) {
|
||||
// //Something bad happened
|
||||
// _this.do_log('GPS Data can\'t be parsed. Discarding packet...');
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// lbs information
|
||||
act.lbs_string = me.ori_string.slice(8).slice(36, 52);
|
||||
act.lbs_data = LibDevice.gt06ParseLbs(me, act.lbs_string);
|
||||
}
|
||||
// Status information
|
||||
else if (me.protocol_id == "13") {
|
||||
act.action_type = "heartbeat";
|
||||
|
||||
// ==== Tambahan Deteksi Data Cache ====
|
||||
try {
|
||||
const gpsTime = new Date(act.gps_data?.date || "");
|
||||
const now = new Date();
|
||||
const timeDiff = Math.abs(now.getTime() - gpsTime.getTime()) / 1000;
|
||||
const serialNum = parseInt(me.serial_number, 16);
|
||||
const lastState = deviceStates[device_id] || {};
|
||||
let isSerialBurst = false;
|
||||
if (lastState.last_serial != null && lastState.last_time != null) {
|
||||
const interval = (Date.now() - lastState.last_time) / 1000;
|
||||
isSerialBurst = serialNum === lastState.last_serial + 1 && interval < 2;
|
||||
}
|
||||
act.is_cached = timeDiff > 30 || isSerialBurst;
|
||||
deviceStates[device_id] = {
|
||||
last_serial: serialNum,
|
||||
last_time: Date.now(),
|
||||
};
|
||||
} catch (err) {
|
||||
act.is_cached = false;
|
||||
}
|
||||
} else if (me.protocol_id == "13") {
|
||||
act.action_type = "heartbeat";
|
||||
act.cmd = "heartbeat";
|
||||
act.action = "heartbeat";
|
||||
act.device_id = device_id; // because device_id only sent when login
|
||||
|
||||
// status information
|
||||
act.device_id = device_id;
|
||||
act.stts_string = me.ori_string.slice(8).slice(0, 10);
|
||||
act.stts_data = LibDevice.gt06ParseHeartbeat(me, act.stts_string);
|
||||
|
||||
act.buffer_resp = LibDevice.gt06HeartbeatResp(me);
|
||||
}
|
||||
// String information
|
||||
else if (me.protocol_id == "15") {
|
||||
// act.action_type = 'other'; // 'heartbeat';
|
||||
// act.cmd = 'other'; // 'heartbeat';
|
||||
// act.action = 'other'; // 'heartbeat';
|
||||
// act.device_id = ''; // device_id; // because device_id only sent when login
|
||||
|
||||
act.action_type = "heartbeat";
|
||||
|
||||
act.cmd = "heartbeat";
|
||||
act.action = "heartbeat";
|
||||
act.device_id = device_id; // because device_id only sent when login
|
||||
|
||||
// status information
|
||||
act.stts_string = me.ori_string.slice(8).slice(0, 10);
|
||||
act.stts_data = LibDevice.gt06ParseHeartbeat(me, act.stts_string);
|
||||
|
||||
act.buffer_resp = LibDevice.gt06HeartbeatResp(me);
|
||||
}
|
||||
// Alarm data
|
||||
else if (me.protocol_id == "16" || me.protocol_id == "18") {
|
||||
act.action_type = "alarm";
|
||||
|
||||
act.cmd = "alarm";
|
||||
act.action = "alarm";
|
||||
act.device_id = device_id; // because device_id only sent when login
|
||||
|
||||
// content data
|
||||
// me.ori_string.slice(8).slice(0, 64); // me.ori_string.substr(8, me.length * 2);
|
||||
|
||||
// gps information
|
||||
act.gps_string = me.ori_string.slice(8).slice(0, 36);
|
||||
act.gps_data = LibDevice.gt06ParseLocation(me, act.gps_string);
|
||||
|
||||
// lbs information
|
||||
act.lbs_string = me.ori_string.slice(8).slice(36, 54);
|
||||
act.lbs_data = LibDevice.gt06ParseLbs(me, act.lbs_string);
|
||||
|
||||
// status information
|
||||
act.stts_string = me.ori_string.slice(8).slice(54, 64);
|
||||
act.stts_data = LibDevice.gt06ParseStatusAlarm(me, act.stts_string);
|
||||
|
||||
act.buffer_resp = LibDevice.gt06AlarmResp(me);
|
||||
}
|
||||
// GPS, query address information by phone number
|
||||
else if (me.protocol_id == "1A") {
|
||||
act.action_type = "other";
|
||||
|
||||
act.cmd = "other";
|
||||
act.action = "other";
|
||||
act.device_id = "";
|
||||
}
|
||||
// Command information sent by the server to the terminal
|
||||
else if (me.protocol_id == "80") {
|
||||
act.action_type = "other";
|
||||
|
||||
act.cmd = "other";
|
||||
act.action = "other";
|
||||
act.device_id = "";
|
||||
} else {
|
||||
act.action_type = "other";
|
||||
|
||||
act.cmd = "other";
|
||||
act.action = "other";
|
||||
act.device_id = "";
|
||||
act.device_id = device_id || "";
|
||||
}
|
||||
|
||||
return act;
|
||||
}
|
||||
|
||||
@ -220,6 +130,10 @@ class LibDevice {
|
||||
return Buffer.from("787805010001d9dc0d0a", "hex");
|
||||
}
|
||||
|
||||
static gt06AuthorizeResp(me) {
|
||||
return Buffer.from("787805010001d9dc0d0a", "hex");
|
||||
}
|
||||
|
||||
static gt06ParseLocation(me, gps_string = null) {
|
||||
if (!gps_string) {
|
||||
gps_string = me.ori_string.slice(8).slice(0, 36);
|
||||
|
||||
Reference in New Issue
Block a user