From e064d603f4ac321bef6b52532b3853d64a355c87 Mon Sep 17 00:00:00 2001 From: Leonardo Gatica Date: Tue, 6 Sep 2016 20:48:39 +0000 Subject: [PATCH] feat(parser): Add messages to parse responses. Modularize all components. --- README.md | 30 +- src/avl05.js | 58 +++ src/avl08.js | 61 ++++ src/avl201.js | 52 +++ src/commands.js | 146 ++++++++ src/errors.js | 8 + src/firmware.js | 14 + src/index.js | 842 ++----------------------------------------- src/info.js | 22 ++ src/map.js | 14 + src/messages/es.json | 52 +++ src/patterns.js | 13 + src/pictures.js | 22 ++ src/responses.js | 541 +++++++++++++++++++++++++++ src/utils.js | 57 +++ test/responses.js | 737 +++++++++++++++++++++++++++++++++++++ test/test.js | 695 ++++++++++------------------------- 17 files changed, 2031 insertions(+), 1333 deletions(-) create mode 100644 src/avl05.js create mode 100644 src/avl08.js create mode 100644 src/avl201.js create mode 100644 src/commands.js create mode 100644 src/errors.js create mode 100644 src/firmware.js create mode 100644 src/info.js create mode 100644 src/map.js create mode 100644 src/messages/es.json create mode 100644 src/patterns.js create mode 100644 src/pictures.js create mode 100644 src/responses.js create mode 100644 src/utils.js create mode 100644 test/responses.js diff --git a/README.md b/README.md index 496689c..09ba228 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![dependency Status](https://img.shields.io/david/lgaticaq/tz-parser.svg?style=flat-square)](https://david-dm.org/lgaticaq/tz-parser#info=dependencies) [![devDependency Status](https://img.shields.io/david/dev/lgaticaq/tz-parser.svg?style=flat-square)](https://david-dm.org/lgaticaq/tz-parser#info=devDependencies) -> Parse raw data from TZ-AVL devices +> Parse raw data from TZ-AVL devices (AVL-05, AVL-08, AVL-201) ## Installation @@ -20,34 +20,38 @@ npm i -S tz-parser [Try on Tonic](https://tonicdev.com/npm/tz-parser) ```js -import tz from 'tz-parser' +const tz = require('tz-parser'); -const raw = new Buffer('$$B6869444005480041|91$GPRMC,194329.000,A,3321.6735,S,07030.7640,W,0.00,0.00,090216,,,A*6C|02.1|01.3|01.7|000000000000|20160209194326|13981188|00000000|32D3A03F|0000|0.6376|0100|7B20\r\n'); +const raw = new Buffer('$$B6869444005480041|AA$GPRMC,194329.000,A,3321.6735,S,07030.7640,W,0.00,0.00,090216,,,A*6C|02.1|01.3|01.7|000000000000|20160209194326|13981188|00000000|32D3A03F|0000|0.6376|0100|995F\r\n'); const data = tz.parse(raw); /*{ - raw: '$$B6869444005480041|91$GPRMC,194329.000,A,3321.6735,S,07030.7640,W,0.00,0.00,090216,,,A*6C|02.1|01.3|01.7|000000000000|20160209194326|13981188|00000000|32D3A03F|0000|0.6376|0100|7B20\r\n', - device: 'TZ-AVL05', + raw: '$$B6869444005480041|AA$GPRMC,194329.000,A,3321.6735,S,07030.7640,W,0.00,0.00,090216,,,A*6C|02.1|01.3|01.7|000000000000|20160209194326|13981188|00000000|32D3A03F|0000|0.6376|0100|995F\r\n', + device: 'tz', + model: 'TZ-AVL05', type: 'data', imei: '869444005480041', - alarm: { type: 'Sleep', status: true }, - loc: { type: 'Point', coordinates: [ -70.51273333, -33.361225 ] }, - gpsStatus: true, + alarm: {type: 'Gps'}, + loc: { + type: 'Point', + coordinates: [-70.51273333333333, -33.361225] + }, speed: 0, + gpsStatus: true, track: '0.00', magneticVariation: null, - gpsMode: 'Autonomous' + gpsMode: 'Autonomous', pdop: 2.1, hdop: 1.3, vdop: 1.7, status: { raw: '000000000000', sos: false, - input: { '1': false, '2': false, '3': false, '4': false, '5': false }, - output: { '1': false, '2': false }, + input: {'1': false, '2': false, '3': false, '4': false, '5': false}, + output: {'1': false, '2': false}, charge: true }, - datetime: Tue Feb 09 2016 19:43:26 GMT+0000 (UTC), - voltage: { battery: 3.98, inputCharge: 11.88, ada: 0, adb: 0 }, + datetime: 2016-02-09T19:43:26.000Z, + voltage: {battery: 3.98, inputCharge: 11.88, ada: 0, adb: 0}, lac: 13011, cid: 41023, temperature: 0, diff --git a/src/avl05.js b/src/avl05.js new file mode 100644 index 0000000..a515eb6 --- /dev/null +++ b/src/avl05.js @@ -0,0 +1,58 @@ +'use strict'; + +const moment = require('moment'); +const nmea = require('node-nmea'); +const patterns = require('./patterns'); +const utils = require('./utils'); + +module.exports = raw => { + const match = patterns.avl05.exec(raw.toString()); + const gprmcData = nmea.parse(match[4]); + const data = { + raw: match[0], + device: 'tz', + model: 'TZ-AVL05', + type: 'data', + imei: match[2], + alarm: utils.getAlarm(match[3]), + loc: gprmcData.loc ? gprmcData.loc.geojson : null, + speed: gprmcData.speed ? gprmcData.speed.kmh : null, + gpsStatus: gprmcData.gps, + track: gprmcData.track, + magneticVariation: gprmcData.magneticVariation, + gpsMode: gprmcData.mode, + pdop: parseFloat(match[17]), + hdop: parseFloat(match[18]), + vdop: parseFloat(match[19]), + status: { + raw: match.slice(20, 32).join(''), + sos: match[20] === '1', + input: { + '1': match[24] === '1', + '2': match[25] === '1', + '3': match[26] === '1', + '4': match[27] === '1', + '5': match[21] === '1' + }, + output: { + '1': match[28] === '1', + '2': match[29] === '1' + }, + charge: match[33] === '1' + }, + datetime: moment(`${match[32]}+00:00`, 'YYYYMMDDHHmmssZZ').toDate(), + voltage: { + battery: parseInt(match[34], 10) / 100, + inputCharge: parseInt(match[35], 10) / 100, + ada: parseInt(match[36], 10) / 100, + adb: parseInt(match[37], 10) / 100 + }, + lac: parseInt(match[38], 16), + cid: parseInt(match[39], 16), + temperature: parseFloat(match[40]) / 10, + odometer: parseFloat(match[41]), + serialId: parseInt(match[42], 10), + valid: utils.isValid(match[0], parseInt(match[1], 16), parseInt(match[43], 16)) + }; + return data; +}; diff --git a/src/avl08.js b/src/avl08.js new file mode 100644 index 0000000..0b50bff --- /dev/null +++ b/src/avl08.js @@ -0,0 +1,61 @@ +'use strict'; + +const moment = require('moment'); +const nmea = require('node-nmea'); +const patterns = require('./patterns'); +const utils = require('./utils'); + +module.exports = raw => { + const match = patterns.avl08.exec(raw.toString()); + const gprmcData = nmea.parse(match[4]); + const data = { + raw: match[0], + device: 'tz', + model: 'TZ-AVL08', + type: 'data', + imei: match[2], + alarm: utils.getAlarm(match[3]), + loc: gprmcData.loc ? gprmcData.loc.geojson : null, + speed: gprmcData.speed ? gprmcData.speed.kmh : null, + gpsStatus: gprmcData.gps, + track: gprmcData.track, + magneticVariation: gprmcData.magneticVariation, + gpsMode: gprmcData.mode, + pdop: parseFloat(match[17]), + hdop: parseFloat(match[18]), + vdop: parseFloat(match[19]), + status: { + raw: match.slice(20, 32).join(''), + sos: match[20] === '1', + input: { + '1': match[24] === '1', + '2': match[25] === '1', + '3': match[26] === '1', + '4': match[27] === '1', + '5': match[21] === '1' + }, + output: { + '1': match[28] === '1', + '2': match[29] === '1', + '3': match[30] === '1', + '4': match[31] === '1' + }, + charge: match[33] === '1' + }, + datetime: moment(`${match[32]}+00:00`, 'YYYYMMDDHHmmssZZ').toDate(), + voltage: { + battery: parseInt(match[34], 10) / 100, + inputCharge: parseInt(match[35], 10) / 100, + ada: parseInt(match[36], 10) / 100, + adb: parseInt(match[37], 10) / 100 + }, + lac: parseInt(match[38], 16), + cid: parseInt(match[39], 16), + temperature: parseFloat(match[40]) / 10, + odometer: parseFloat(match[41]), + serialId: parseInt(match[42], 10), + rfidNumber: match[43] || null, + valid: utils.isValid(match[0], parseInt(match[1], 16), parseInt(match[44], 16)) + }; + return data; +}; diff --git a/src/avl201.js b/src/avl201.js new file mode 100644 index 0000000..ba28867 --- /dev/null +++ b/src/avl201.js @@ -0,0 +1,52 @@ +'use strict'; + +const moment = require('moment'); +const nmea = require('node-nmea'); +const patterns = require('./patterns'); +const utils = require('./utils'); + +module.exports = raw => { + const match = patterns.avl201.exec(raw.toString()); + const gprmcData = nmea.parse(match[4]); + const data = { + raw: match[0], + device: 'tz', + model: 'TZ-AVL201', + type: 'data', + imei: match[2], + alarm: utils.getAlarm(match[3]), + loc: gprmcData.loc ? gprmcData.loc.geojson : null, + speed: gprmcData.speed ? gprmcData.speed.kmh : null, + gpsStatus: gprmcData.gps, + track: gprmcData.track, + magneticVariation: gprmcData.magneticVariation, + gpsMode: gprmcData.mode, + pdop: parseFloat(match[17]), + hdop: parseFloat(match[18]), + vdop: parseFloat(match[19]), + status: { + raw: match.slice(20, 32).join(''), + input: { + '1': match[22] === '1', + '2': match[23] === '1', + '3': match[20] === '1' + }, + output: { + '1': match[30] === '1' + }, + charge: match[33] === '1' + }, + datetime: moment(`${match[32]}+00:00`, 'YYYYMMDDHHmmssZZ').toDate(), + voltage: { + battery: parseInt(match[34], 10) / 100, + inputCharge: parseInt(match[35], 10) / 100 + }, + lac: parseInt(match[36], 16), + cid: parseInt(match[37], 16), + temperature: parseFloat(match[38]) / 10, + odometer: parseFloat(match[39]), + serialId: parseInt(match[40], 10), + valid: utils.isValid(match[0], parseInt(match[1], 16), parseInt(match[41], 16)) + }; + return data; +}; diff --git a/src/commands.js b/src/commands.js new file mode 100644 index 0000000..2d81ef0 --- /dev/null +++ b/src/commands.js @@ -0,0 +1,146 @@ +'use strict'; + +const parseSetUserPassword = data => { + return `*${data.password},001,${data.newPassword}#`; +}; + +const parseSetIoSwitch = data => { + const _data = data.instruction.split('_'); + const ports = {'1': 'A', '2': 'B', '3': 'C', '4': 'D'}; + return `*${data.password},025,${ports[_data[0]]},${_data[1] === 'on' ? 1 : 0}#`; +}; + +const parseSetSysSwitch = data => { + const state = data.instruction.split('_')[1]; + return `*${data.password},016,${state === 'on' ? 1 : 0}#`; +}; + +const parseClearbuf = data => { + return `*${data.password},500#`; +}; + +const parseSetGprsInterval = data => { + return `*${data.password},018,${data.interval},${data.times || 999}#`; +}; + +const parseSetPhoneSmsForSos = data => { + const state = data.instruction.split('_')[0]; + return `*${data.password},003,0,${state === 'set' ? 1 : 0},00569${data.number},00569${data.number}#`; +}; + +const parseSetOverSpeedAlarm = data => { + const speed = data.speed || 100; + const state = data.instruction.split('_')[2]; + const times = data.times || 10; + const interval = data.interval || 60; + const digit = /on(E)?/.test(state) ? 1 : 0; + return `*${data.password},005,${digit},${speed},${times},${interval}#`; +}; + +const parseSetpictureinterval = data => { + const interval = data.interval || 5; + const times = data.times || 1; + return `*${data.password},200,${interval},${times}#`; +}; + +const parseGetpicture = data => { + return `*${data.password},210#`; +}; + +const parseSetiopicture = data => { + const triggers = {on: 1, off: 2, both: 3}; + const trigger = triggers[data.trigger || 'both']; + const number = data.number || 1; + return `*${data.password},201,${data.port},${trigger},${number}#`; +}; + +const parseCustom = data => { + return data.command; +}; + +const parseSetdataflash = data => { + const state = data.instruction.split('_')[2]; + const digit = state === 'on' ? 1 : 0; + return `*${data.password},601,${digit}#`; +}; + +const parseSetTrembleSwitch = data => { + return `*${data.password},021,${data.sleep ? 1 : 0},${data.tremble ? 1 : 0}#`; +}; + +const parseSetTrembleToSleep = data => { + return `*${data.password},044,${data.time}#`; +}; + +const parseSetTrembleToWakeup = data => { + return `*${data.password},043,${data.time}#`; +}; + +const parseRboot = data => { + return `*${data.password},991#`; +}; + +const parseSetExtend2 = data => { + const a = data.a ? 1 : 0; + const b = data.b ? 1 : 0; + const c = data.c ? 1 : 0; + const d = data.d ? 1 : 0; + const e = data.e ? 1 : 0; + const f = data.f ? 1 : 0; + const g = data.g ? 1 : 0; + const h = data.h ? 1 : 0; + return `*${data.password},118,${a}${b}${c}${d}${e}${f}${g}${h}#`; +}; + +const parseSetHeartbeatSwitch = data => { + const state = data.instruction.split('_')[2]; + const digit = state === 'on' ? 1 : 0; + return `*${data.password},040,${digit}#`; +}; + +const parseSetHeartbeatInterval = data => { + return `*${data.password},041,${data.times}#`; +}; + +const parseSetidle = data => { + const state = data.instruction.split('_')[2]; + const digit = state === 'on' ? 1 : 0; + return `*${data.password},404,${digit},${data.times}#`; +}; + +const parseCommand = data => { + let command = null; + data.password = data.password || '000000'; + const parsers = [ + {pattern: /^set_password$/, parser: parseSetUserPassword}, + {pattern: /^[1-4]{1}_(on|off)$/, parser: parseSetIoSwitch}, + {pattern: /^gprs_(on|off)$/, parser: parseSetSysSwitch}, + {pattern: /^clear_mem$/, parser: parseClearbuf}, + {pattern: /^set_interval_gprs$/, parser: parseSetGprsInterval}, + {pattern: /^(set|setoff)_sos_number(E)?$/, parser: parseSetPhoneSmsForSos}, + {pattern: /^set_speed_(on|off)(E)?$/, parser: parseSetOverSpeedAlarm}, + {pattern: /^picture$/, parser: parseSetpictureinterval}, + {pattern: /^take_picture$/, parser: parseGetpicture}, + {pattern: /^configure_io_picture$/, parser: parseSetiopicture}, + {pattern: /^Custom$/, parser: parseCustom}, + {pattern: /^set_memory_(on|off)$/, parser: parseSetdataflash}, + {pattern: /^set_tremble$/, parser: parseSetTrembleSwitch}, + {pattern: /^set_into_sleep$/, parser: parseSetTrembleToSleep}, + {pattern: /^set_wake_up$/, parser: parseSetTrembleToWakeup}, + {pattern: /^reboot$/, parser: parseRboot}, + {pattern: /^set_extend$/, parser: parseSetExtend2}, + {pattern: /^set_heartbeat_(on|off)$/, parser: parseSetHeartbeatSwitch}, + {pattern: /^set_interval_heartbeat$/, parser: parseSetHeartbeatInterval}, + {pattern: /^set_idling_(on|off)$/, parser: parseSetidle} + ]; + const parser = parsers.find(x => x.pattern.test(data.instruction)); + if (parser) { + command = parser.parser(data); + } + + return command; +}; + +module.exports = { + parseCommand: parseCommand +}; diff --git a/src/errors.js b/src/errors.js new file mode 100644 index 0000000..fa5fa8e --- /dev/null +++ b/src/errors.js @@ -0,0 +1,8 @@ +'use strict'; + +const patterns = require('./patterns'); + +module.exports = data => { + const match = patterns.receiveErr.exec(data.toString()); + return {device: 'tz', type: 'error', command: match[0]}; +}; diff --git a/src/firmware.js b/src/firmware.js new file mode 100644 index 0000000..7ea7ace --- /dev/null +++ b/src/firmware.js @@ -0,0 +1,14 @@ +'use strict'; + +const patterns = require('./patterns'); + +module.exports = data => { + const match = patterns.firmware.exec(data.toString()); + return { + device: 'tz', + type: 'firmware', + imei: match[1], + firmware: match[2], + gsm: match[3] + }; +}; diff --git a/src/index.js b/src/index.js index 97cbcf5..be6ac2a 100644 --- a/src/index.js +++ b/src/index.js @@ -1,816 +1,51 @@ 'use strict'; -const crc = require('crc'); -const moment = require('moment'); -const nmea = require('node-nmea'); - -const patterns = { - avl05: /^\$\$([0-9A-F]{2})(\d{15})\|([0-9A]{2})(\$GPRMC\,(\d{6}\.\d{3})\,([AV])\,(\d{4}\.\d{4}\,[NS])\,(\d{5}\.\d{4}\,[WE])\,(\d{1,3}\.\d{1,3})?\,(\d{1,3}\.\d{1,3})?\,(\d{6})\,((\d{1,3}\.\d{1,3})?\,([WE])?)\,?([ADENS])?\*([0-9A-F]{2})|[0]{60})\|(\d{2}\.\d{1})\|(\d{2}\.\d{1})\|(\d{2}\.\d{1})\|([01])([01])([01])([01])([01])([01])([01])([01])([01])([01])([01])([01])\|(\d{14})\|([01])(\d{3})(\d{4})\|(\d{4})(\d{4})\|([0-9A-F]{4})([0-9A-F]{4})\|([01\-]\d{3})\|(\d{1,4}\.\d{1,12})\|(\d{4})\|([0-9A-F]{4})\r\n$/, - avl08: /^\$\$([0-9A-F]{2})(\d{15})\|([0-9A]{2})(\$GPRMC\,(\d{6}\.\d{3})\,([AV])\,(\d{4}\.\d{4}\,[NS])\,(\d{5}\.\d{4}\,[WE])\,(\d{1,3}\.\d{1,3})?\,(\d{1,3}\.\d{1,3})?\,(\d{6})\,((\d{1,3}\.\d{1,3})?\,([WE])?)\,?([ADENS])?\*([0-9A-F]{2})|[0]{60})\|(\d{2}\.\d{1})\|(\d{2}\.\d{1})\|(\d{2}\.\d{1})\|([01])([01])([01])([01])([01])([01])([01])([01])([01])([01])([01])([01])\|(\d{14})\|([01])(\d{3})(\d{4})\|(\d{4})(\d{4})\|([0-9A-F]{4})([0-9A-F]{4})\|([01\-]\d{3})\|(\d{1,4}\.\d{1,12})\|(\d{4})\|(\d{10})?\|([0-9A-F]{4})\r\n$/, - avl201: /^\$\$([0-9A-F]{2})(\d{15})\|([0-9A]{2})(\$GPRMC\,(\d{6}\.\d{3})\,([AV])\,(\d{4}\.\d{4}\,[NS])\,(\d{5}\.\d{4}\,[WE])\,(\d{1,3}\.\d{1,3})?\,(\d{1,3}\.\d{1,3})?\,(\d{6})\,((\d{1,3}\.\d{1,3})?\,([WE])?)\,?([ADENS])?\*([0-9A-F]{2})|[0]{60})\|(\d{2}\.\d{1})\|(\d{2}\.\d{1})\|(\d{2}\.\d{1})\|([01])([01])([01])([01])([01])([01])([01])([01])([01])([01])([01])([01])\|(\d{14})\|([01])(\d{3})(\d{4})\|([0-9A-F]{4})([0-9A-F]{4})\|([01\-]\d{3})\|(\d{1,4}\.\d{1,12})\|(\d{4})\|([0-9A-F]{4})\r\n$/, - receiveOk: /^Receive:'\d{3}'OK\r\n\*(\d{6})\,(\d{3})(\S*)?#$/, - receiveErr: /^Receive:Set Err\r\n(\S*)/, - picture: /^(\$U\d{15}\d{5}\d{3}\d{3}[0-9a-fA-F]{1,200}#)+(Receive:'210'OK\r\n\*\d{6}\,210#)?$/, - firmware: /^IMEI:(\d{15})\r\nVER:(\S*)\r\nGSMVER:(\S*)\r\n$/, - info: /^Lat:([+-]?\d{4}\.\d{4}[NS])\r\nLong:([+-]?\d{5}\.\d{4}[WE])\r\nSpd:(\d{3})km\/h\r\nFix:([AV])\r\nSat:(\d{2})\r\nHDOP:(\d{2}\.\d{1})\r\nGSM:(\d{2})\r\nBatt:(\d{2}\.\d{2})V\r\nMile:(\d{1,4}\.\d{1,12})\r\nTime:(\d{2}\/\d{2}\/\d{2}\ \d{2}:\d{2}:\d{2})\r\n$/, - map: /^http:\/\/maps.google.com\/maps\?f=q&hl=en&q=(-?\d+\.\d+),(-?\d+\.\d+)&ie=UTF8&z=16&iwloc=addr&om=1$/ -}; - -const getAlarm = alarm => { - const alarmTypes = { - '01': {type: 'SOS_Button'}, - '49': {type: 'DI', number: 5, status: false}, - '09': {type: 'Auto_Shutdown'}, - '10': {type: 'Low_Battery'}, - '11': {type: 'Over_Speed', status: true}, - '13': {type: 'Over_Speed', status: false}, - '14': {type: 'Aceleration', status: true}, - '15': {type: 'Aceleration', status: false}, - '30': {type: 'Parking'}, - '42': {type: 'Geo_Fence', status: true}, - '43': {type: 'Geo_Fence', status: false}, - '50': {type: 'DI', number: 1, status: false}, - '51': {type: 'DI', number: 1, status: true}, - '52': {type: 'DI', number: 2, status: false}, - '53': {type: 'DI', number: 2, status: true}, - '54': {type: 'DI', number: 3, status: false}, - '55': {type: 'DI', number: 3, status: true}, - '56': {type: 'DI', number: 4, status: false}, - '57': {type: 'DI', number: 4, status: true}, - '60': {type: 'Charge', status: true}, - '61': {type: 'Charge', status: false}, - '66': {type: 'Rfid'}, - '77': {type: 'Angle'}, - '88': {type: 'Heartbeat'}, - '91': {type: 'Sleep', status: true}, - '92': {type: 'Sleep', status: false}, - 'AA': {type: 'Gps'} - }; - return alarmTypes[alarm]; -}; - -const verifyCrc = (raw, checksum) => { - let crcData; - const idx = raw.lastIndexOf('|'); - if (idx > 0) { - const data = raw.slice(0, idx + 1); - crcData = crc.crc16modbus(data); - } - return crcData === checksum; -}; - -const verifyLen = (raw, len) => { - return raw.replace('\r\n', '').length === len; -}; - -const isValid = (raw, len, checksum) =>{ - return verifyCrc(raw, checksum) && verifyLen(raw, len); -}; - -const getAvl05 = raw => { - const match = patterns.avl05.exec(raw.toString()); - const gprmcData = nmea.parse(match[4]); - const data = { - raw: match[0], - device: 'TZ-AVL05', - type: 'data', - imei: match[2], - alarm: getAlarm(match[3]), - loc: gprmcData.loc ? gprmcData.loc.geojson : null, - speed: gprmcData.speed ? gprmcData.speed.kmh : null, - gpsStatus: gprmcData.gps, - track: gprmcData.track, - magneticVariation: gprmcData.magneticVariation, - gpsMode: gprmcData.mode, - pdop: parseFloat(match[17]), - hdop: parseFloat(match[18]), - vdop: parseFloat(match[19]), - status: { - raw: match.slice(20, 32).join(''), - sos: match[20] === '1', - input: { - '1': match[24] === '1', - '2': match[25] === '1', - '3': match[26] === '1', - '4': match[27] === '1', - '5': match[21] === '1' - }, - output: { - '1': match[28] === '1', - '2': match[29] === '1' - }, - charge: match[33] === '1' - }, - datetime: moment(`${match[32]}+00:00`, 'YYYYMMDDHHmmssZZ').toDate(), - voltage: { - battery: parseInt(match[34], 10) / 100, - inputCharge: parseInt(match[35], 10) / 100, - ada: parseInt(match[36], 10) / 100, - adb: parseInt(match[37], 10) / 100 - }, - lac: parseInt(match[38], 16), - cid: parseInt(match[39], 16), - temperature: parseFloat(match[40]) / 10, - odometer: parseFloat(match[41]), - serialId: parseInt(match[42], 10), - valid: isValid(match[0], parseInt(match[1], 16), parseInt(match[43], 16)) - }; - return data; -}; - -const getAvl08 = raw => { - const match = patterns.avl08.exec(raw.toString()); - const gprmcData = nmea.parse(match[4]); - const data = { - raw: match[0], - device: 'TZ-AVL08', - type: 'data', - imei: match[2], - alarm: getAlarm(match[3]), - loc: gprmcData.loc ? gprmcData.loc.geojson : null, - speed: gprmcData.speed ? gprmcData.speed.kmh : null, - gpsStatus: gprmcData.gps, - track: gprmcData.track, - magneticVariation: gprmcData.magneticVariation, - gpsMode: gprmcData.mode, - pdop: parseFloat(match[17]), - hdop: parseFloat(match[18]), - vdop: parseFloat(match[19]), - status: { - raw: match.slice(20, 32).join(''), - sos: match[20] === '1', - input: { - '5': match[21] === '1', - '1': match[24] === '1', - '2': match[25] === '1', - '3': match[26] === '1', - '4': match[27] === '1' - }, - output: { - '1': match[28] === '1', - '2': match[29] === '1', - '3': match[30] === '1', - '4': match[31] === '1' - }, - charge: match[33] === '1' - }, - datetime: moment(`${match[32]}+00:00`, 'YYYYMMDDHHmmssZZ').toDate(), - voltage: { - battery: parseInt(match[34], 10) / 100, - inputCharge: parseInt(match[35], 10) / 100, - ada: parseInt(match[36], 10) / 100, - adb: parseInt(match[37], 10) / 100 - }, - lac: parseInt(match[38], 16), - cid: parseInt(match[39], 16), - temperature: parseFloat(match[40]) / 10, - odometer: parseFloat(match[41]), - serialId: parseInt(match[42], 10), - rfidNumber: match[43] ? parseInt(match[43], 10) : null, - valid: isValid(match[0], parseInt(match[1], 16), parseInt(match[44], 16)) - }; - return data; -}; - -const getAvl201 = raw => { - const match = patterns.avl201.exec(raw.toString()); - const gprmcData = nmea.parse(match[4]); - const data = { - raw: match[0], - device: 'TZ-AVL201', - type: 'data', - imei: match[2], - alarm: getAlarm(match[3]), - loc: gprmcData.loc ? gprmcData.loc.geojson : null, - speed: gprmcData.speed ? gprmcData.speed.kmh : null, - gpsStatus: gprmcData.gps, - track: gprmcData.track, - magneticVariation: gprmcData.magneticVariation, - gpsMode: gprmcData.mode, - pdop: parseFloat(match[17]), - hdop: parseFloat(match[18]), - vdop: parseFloat(match[19]), - status: { - raw: match.slice(20, 32).join(''), - input: { - '3': match[20] === '1', - '1': match[22] === '1', - '2': match[23] === '1' - }, - output: { - '1': match[30] === '1' - }, - charge: match[33] === '1' - }, - datetime: moment(`${match[32]}+00:00`, 'YYYYMMDDHHmmssZZ').toDate(), - voltage: { - battery: parseInt(match[34], 10) / 100, - inputCharge: parseInt(match[35], 10) / 100 - }, - lac: parseInt(match[36], 16), - cid: parseInt(match[37], 16), - temperature: parseFloat(match[38]) / 10, - odometer: parseFloat(match[39]), - serialId: parseInt(match[40], 10), - valid: isValid(match[0], parseInt(match[1], 16), parseInt(match[41], 16)) - }; - return data; -}; - -const getCommand = raw => { - const match = patterns.receiveOk.exec(raw.toString()); - const password = match[1]; - const code = match[2]; - const extra = match[3] ? match[3].substr(1).split(',') : null; - let data = {device: 'TZ-COMMAND-OK', type: 'ok', password: password}; - if (code === '001') { - data.command = 'SetUserPassword'; - data.newPassword = extra[0]; - } else if (code === '002') { - let x = extra[0]; - let y = extra[1]; - data.command = 'SETINTERVALOFSMS'; - data.enable = x !== '0'; - data.interval = x; - data.limit = y; - } else if (code === '003') { - let x = extra[0]; - let f = extra[1]; - let callNumber = extra[2]; - let smsNumber = extra[3]; - data.command = 'SETPHONESMSFORSOS'; - data.enable = ((x === '0') && (f === '1')); - data.callNumber = callNumber; - data.smsNumber = smsNumber; - } else if (code === '004') { - let x = extra[0]; - let y = extra[1]; - data.command = 'SETLOWPOWERALARM'; - data.lowPower = parseFloat(x) / 100; - data.autoShutdown = parseFloat(y) / 100; - } else if (code === '005') { - let s = extra[0]; - let x = extra[1]; - let y = extra[2]; - let z = extra[3]; - data.command = 'SETOVERSPEEDALARM'; - data.enable = s === '1'; - data.speed = parseInt(x, 10); - data.times = parseInt(y, 10); - data.interval = parseInt(z, 10); - } else if (code === '006') { - let lat1 = extra[0]; - let lon1 = extra[1]; - let lat2 = extra[2]; - let lon2 = extra[3]; - let y = extra[5]; - const parseDir = (dir) => { - if (/^-/.test(dir)) { - if (dir.length === 4) { - return `${dir.substr(1)},S`; - } else { - return `${dir.substr(1)},W`; - } - } else { - if (dir.length === 4) { - return `${dir.substr(1)},N`; - } else { - return `${dir.substr(1)},E`; - } - } - }; - data.command = 'SETGEOFENCEALARM'; - if (y === '0') { - data.enable = false; - } else { - data.enable = true; - data.mode = y === '1' ? 'inside' : 'outside'; - data.geojson = { - type: 'Polygon', - coordinates: [[ - [nmea.degToDec(parseDir(lon2)), nmea.degToDec(parseDir(lat2))], - [nmea.degToDec(parseDir(lon2)), nmea.degToDec(parseDir(lat1))], - [nmea.degToDec(parseDir(lon1)), nmea.degToDec(parseDir(lat1))], - [nmea.degToDec(parseDir(lon1)), nmea.degToDec(parseDir(lat2))], - [nmea.degToDec(parseDir(lon2)), nmea.degToDec(parseDir(lat2))] - ]] - }; - } - } else if (code === '008') { - let _data = extra[0].split(''); - let a = _data[0]; - let b = _data[1]; - let c = _data[2]; - let d = _data[3]; - let e = _data[4]; - let f = _data[5]; - let g = _data[6]; - data.command = 'SETEXTEND'; - data.extend = { - a: a === '1', - b: b === '1', - c: c === '1', - d: d === '1', - e: e === '1', - f: f === '1', - g: g === '1' - }; - } else if (code === '009') { - data.command = 'SETGSMBAUD'; - if (extra[0] === '0') { - data.band = '900/1800'; - } else if (extra[0] === '1') { - data.band = '850/1900'; - } else { - data.band = 'auto'; - } - } else if (code === '011') { - let apn = extra[0]; - let username = extra[1]; - let pass = extra[2]; - data.command = 'SETAPN'; - data.apn = apn; - data.username = username; - data.pass = pass; - } else if (code === '014') { - let x = extra[0]; - let dns1 = extra[1]; - let dns2 = extra[2]; - data.command = 'SETDNS'; - data.enable = x === '1'; - data.dns1 = dns1; - data.dns2 = dns2; - } else if (code === '015') { - let host = extra[1]; - let port = extra[2]; - data.command = 'SETIPANDPORT'; - data.host = host; - data.port = parseInt(port, 10); - } else if (code === '018') { - let x = extra[0]; - let y = extra[1]; - data.command = 'SETGPRSINTERVAL'; - data.enable = x !== '0'; - data.interval = parseInt(x, 10); - data.limit = parseInt(y, 10); - } else if (code === '016') { - let x = extra[0]; - data.command = 'SETSYSSWITCH'; - data.enable = x === '1'; - } else if (code === '019') { - let x = extra[0]; - data.command = 'SETTCPSWITCH'; - data.mode = x === '1' ? 'tcp' : 'udp'; - } else if (code === '021') { - let x = extra[0]; - let y = extra[1]; - data.command = 'SETTREMBLESWITCH'; - data.sleep = x === '1'; - data.tremble = y === '1'; - } else if (code === '022') { - let x = extra[0]; - let y = extra[1]; - data.command = 'SETSLEEPSWITCH'; - data.closeGps = x === '0'; - data.closeGsm = y === '0'; - } else if (code === '025') { - const ports = {'A': 1, 'B': 2, 'C': 3, 'D': 4}; - let x = extra[0]; - let y = extra[1]; - data.command = 'SETIOSWITCH'; - data.enable = y === '1'; - data.port = ports[x]; - } else if (code === '040') { - let x = extra[0]; - data.command = 'SETHEARTBEATSWITCH'; - data.enable = x === '1'; - } else if (code === '041') { - let x = extra[0]; - data.command = 'SETHEARTBEATINTERVAL'; - data.enable = x !== '0'; - data.interval = x; - } else if (code === '042') { - data.command = 'SETHEARTBEATINIT'; - } else if (code === '044') { - let x = extra[0]; - data.command = 'SETTREMBLETOSLEEP'; - data.after = parseInt(x, 10); - } else if (code === '043') { - let x = extra[0]; - data.command = 'SETTREMBLETOWAKEUP'; - data.after = parseInt(x, 10); - } else if (code === '110') { - let x = extra[0]; - data.command = 'SETPARKINGALARM'; - data.enable = x === '1'; - } else if (code === '990') { - data.command = 'FACTORYRESET'; - } else if (code === '991') { - data.command = 'RBOOT'; - } else if (code === '113') { - let a = extra[0]; - let b = extra[1]; - data.command = 'SETOILSENSER'; - data.empty = parseInt(a, 10) / 100; - data.full = parseInt(b, 10) / 100; - } else if (code === '117') { - let a = extra[0]; - let b = extra[1]; - let c = extra[2]; - let d = extra[3]; - data.command = 'SETSHUTOIL'; - data.speed = parseInt(a, 10); - data.off = parseInt(b, 10); - data.restart = parseInt(c, 10); - data.repeat = parseInt(d, 10); - } else if (code === '116') { - let a = extra[0]; - data.command = 'SETSHUTOILSWITCH'; - data.enable = a === '1'; - } else if (code === '103') { - let s = extra[0]; - let number = extra[1]; - data.command = 'SETCALLA'; - data.mode = s === '0' ? 'gprs' : 'call'; - data.number = number; - } else if (code === '118') { - let _data = extra[0].split(''); - let a = _data[0]; - let b = _data[1]; - let c = _data[2]; - let d = _data[3]; - let e = _data[4]; - let f = _data[5]; - let g = _data[6]; - let h = _data[7]; - data.command = 'SETEXTEND2'; - data.extend = { - a: a === '1', - b: b === '1', - c: c === '1', - d: d === '1', - e: e === '1', - f: f === '1', - g: g === '1', - h: h === '1' - }; - } else if (code === '122') { - let s = extra[0]; - let pin = extra[1]; - data.command = 'SETPIN'; - data.enable = s === '1'; - data.pin = pin; - } else if (code === '300' || code === '400') { - let x = extra[0]; - let y = extra[1]; - data.command = 'SETANGLE'; - if (x === '0') { - data.enable = false; - } else if (x === '1') { - data.enable = true; - } else if (x === '2') { - data.enable = true; - data.port = 4; - } else if (x === '3') { - data.enable = true; - data.port = 3; - } - data.angle = parseInt(y, 10); - } else if (code === '600') { - let x = extra[0]; - let y = extra[1]; - data.command = 'SETREBOOT'; - data.enable = x === '1'; - data.interval = parseInt(y, 10); - } else if (code === '120') { - let a = extra[0]; - let b = extra[1]; - let c = extra[2]; - data.command = 'SETACCALARM'; - data.enable = a === '1'; - data.acceleration = parseInt(b, 10); - data.deceleration = parseInt(c, 10); - } else if (code === '121') { - let x = extra[0]; - let y = extra[1]; - let z = extra[2]; - data.command = 'SETROAMING'; - data.enable = x === '1'; - data.interval = parseInt(y, 10); - data.network = z; - } else if (code === '123') { - let x = extra[0]; - data.command = 'SETACKSTATE'; - data.enable = x === '1'; - } else if (code === '130') { - let x = extra[0]; - let y = extra[1]; - data.command = 'SETCALLFILTER'; - data.enable = x === '1'; - data.caller = y; - } else if (code === '119') { - let x = extra[0]; - data.command = 'SETSENDTYPE'; - data.mode = x === '0' ? 'gprs' : 'sms'; - } else if (code === '200') { - let x = extra[0]; - let y = extra[1]; - data.command = 'SETPICTUREINTERVAL'; - data.interval = parseInt(x, 10); - data.times = parseInt(y, 10); - } else if (code === '500') { - data.command = 'CLEARBUF'; - } else if (code === '210') { - data.command = 'GETPICTURE'; - } else if (code === '601') { - let x = extra[0]; - data.command = 'SETDATAFLASH'; - data.enable = x === '1'; - } else if (code === '156') { - let x = extra[0]; - let y = extra[1]; - let z = extra[2]; - data.command = 'SETTRACKINGINTERVAL'; - data.enable = x === '1'; - data.intervalOn = parseInt(y, 10); - data.intervalOff = parseInt(z, 10); - } else if (code === '151') { - let x = extra[0]; - let y = extra[1]; - data.command = 'SETSENDODOMETER'; - data.enable = x === '1'; - data.range = parseInt(y, 10); - } else if (code === '155') { - let x = extra[0]; - let y = extra[1]; - data.command = 'SETIMEI'; - data.enable = x === '1'; - data.newImei = y; - } else if (code === '404') { - let x = extra[0]; - let y = extra[1]; - data.command = 'SETIDLE'; - data.enable = x === '1'; - data.interval = parseInt(y, 10); - } else if (code === '023') { - let x = extra[0]; - let y = extra[1]; - data.command = 'SETINTERVALGPRSSTANDBY'; - data.enable = x === '1'; - data.interval = parseInt(y, 10); - } else if (code === '201') { - let x = extra[0]; - let y = extra[1]; - let z = extra[2]; - data.command = 'SETIOPICTURE'; - if (x === '0') { - data.enable = false; - } else if (x === '1') { - data.enable = true; - data.port = 4; - } else if (x === '2') { - data.enable = true; - data.port = 3; - } else if (x === '3') { - data.enable = true; - data.port = 2; - } else if (x === '4') { - data.enable = true; - data.port = 1; - } - if (y === '1') { - data.mode = 'open'; - } else if (y === '2') { - data.mode = 'close'; - } else { - data.mode = 'both'; - } - data.times = parseInt(z, 10); - } else if (code === '202') { - let x = extra[0]; - data.command = 'SETPICTUREPACKET'; - data.number = parseInt(x, 10); - } - return data; -}; - -const getPicture = raw => { - const results = raw.toString().match(/\$U\d{15}\d{5}\d{3}\d{3}[0-9a-fA-F]{1,200}#/g).map(x => { - const match = /\$U(\d{15})(\d{5})(\d{3})(\d{3})([0-9a-fA-F]{1,200})#/.exec(x); - return { - imei: match[1], - number: parseInt(match[2], 10), - total: parseInt(match[3], 10), - sequence: parseInt(match[4], 10), - data: match[5] - }; - }); - const imei = results[0].imei; - const number = results[0].number; - const total = results[0].total; - const data = results.map(x => { - return {sequence: x.sequence, data: x.data}; - }); - return { - device: 'TZ-IMAGE', - type: 'image', - imei: imei, - number: number, - total: total, - data: data - }; -}; - -const getCommandError = data => { - const match = patterns.receiveErr.exec(data.toString()); - return {device: 'TZ-ERROR', type: 'error', command: match[0]}; -}; - -const getCommandFirmware = data => { - const match = patterns.firmware.exec(data.toString()); - return { - device: 'TZ-FIRMWARE', - type: 'firmware', - imei: match[1], - firmware: match[2], - gsm: match[3] - }; -}; - -const getCommandInfo = data => { - const match = patterns.info.exec(data.toString()); - return { - device: 'TZ-INFO', - type: 'info', - latitude: match[1], - longitude: match[2], - speed: parseInt(match[3], 10), - fix: match[4], - sat: parseInt(match[5], 10), - hdop: parseFloat(match[6]), - gsm: parseInt(match[7], 10), - battery: parseFloat(match[8]), - odometer: parseFloat(match[9]), - datetime: moment(`${match[10]} +00:00`, 'DD/MM/YY HH:mm:ss ZZ').toDate() - }; -}; - -const getCommandMap = data => { - const match = patterns.map.exec(data.toString()); - return { - device: 'TZ-MAP', - type: 'map_link', - url: match[0], - latitude: parseFloat(match[1]), - longitude: parseFloat(match[2]) - }; -}; +const responses = require('./responses'); +const commands = require('./commands'); +const patterns = require('./patterns'); +const avl05 = require('./avl05'); +const avl08 = require('./avl08'); +const avl201 = require('./avl201'); +const pictures = require('./pictures'); +const errors = require('./errors'); +const firmware = require('./firmware'); +const info = require('./info'); +const map = require('./map'); const parse = raw => { let result = {type: 'UNKNOWN', raw: raw.toString()}; - if (patterns.avl05.test(raw.toString())) { - result = getAvl05(raw); - } else if (patterns.avl08.test(raw.toString())) { - result = getAvl08(raw); - } else if (patterns.avl201.test(raw.toString())) { - result = getAvl201(raw); - } else if (patterns.receiveOk.test(raw.toString())) { - result = getCommand(raw); - } else if (patterns.picture.test(raw.toString())) { - result = getPicture(raw); - } else if (patterns.receiveErr.test(raw.toString())) { - result = getCommandError(raw); - } else if (patterns.info.test(raw.toString())) { - result = getCommandInfo(raw); - } else if (patterns.firmware.test(raw.toString())) { - result = getCommandFirmware(raw); - } else if (patterns.map.test(raw.toString())) { - result = getCommandMap(raw); + const _patterns = [ + {pattern: patterns.avl05, parser: avl05}, + {pattern: patterns.avl08, parser: avl08}, + {pattern: patterns.avl201, parser: avl201}, + {pattern: patterns.receiveOk, parser: responses.getCommand}, + {pattern: patterns.picture, parser: pictures}, + {pattern: patterns.receiveErr, parser: errors}, + {pattern: patterns.info, parser: info}, + {pattern: patterns.firmware, parser: firmware}, + {pattern: patterns.map, parser: map} + ]; + const parser = _patterns.find(x => x.pattern.test(raw.toString())); + if (parser) { + result = parser.parser(raw); } return result; }; const isTz = raw => { - let result = false; - if (patterns.avl05.test(raw.toString())) { - result = true; - } else if (patterns.avl08.test(raw.toString())) { - result = true; - } else if (patterns.avl201.test(raw.toString())) { - result = true; - } else if (patterns.receiveOk.test(raw.toString())) { - result = true; - } else if (patterns.picture.test(raw.toString())) { - result = true; - } else if (patterns.receiveErr.test(raw.toString())) { - result = true; - } else if (patterns.info.test(raw.toString())) { - result = true; - } else if (patterns.firmware.test(raw.toString())) { - result = true; - } else if (patterns.map.test(raw.toString())) { - result = true; - } - return result; + const pattern = Object.keys(patterns).map(x => patterns[x]).find(x => x.test(raw.toString())); + return pattern !== 'undefined'; }; -const parseCommand = data => { - let command = ''; - const password = data.password || '000000'; - let state, digit, port, number, speed, interval, times, trigger, a, b, c, d, e, f, g, h; - if (/^set_password$/.test(data.instruction)) { - command = `*${password},001,${data.newPassword}#`; - } else if (/^[1-4]{1}_(on|off)$/.test(data.instruction)) { - let _data = data.instruction.split('_'); - port = _data[0]; - state = _data[1]; - const ports = {'1': 'A', '2': 'B', '3': 'C', '4': 'D'}; - digit = state === 'on' ? 1 : 0; - command = `*${password},025,${ports[port]},${digit}#`; - } else if (/^gprs_(on|off)$/.test(data.instruction)) { - state = data.instruction.split('_')[1]; - digit = state === 'on' ? 1 : 0; - command = `*${password},016,${digit}#`; - } else if (data.instruction === 'clear_mem') { - command = `*${password},500#`; - } else if (data.instruction === 'set_interval_gprs') { - times = data.times || 999; - command = `*${password},018,${data.interval},${times}#`; - } else if (/^(set|setoff)_sos_number(E)?$/.test(data.instruction)) { - number = data.number; - state = data.instruction.split('_')[0]; - digit = state === 'set' ? 1 : 0; - command = `*${password},003,0,${digit},00569${number},00569${number}#`; - } else if (/^set_speed_(on|off)(E)?$/.test(data.instruction)) { - speed = data.speed || 100; - state = data.instruction.split('_')[2]; - times = data.times || 10; - interval = data.interval || 60; - digit = /on(E)?/.test(state) ? 1 : 0; - command = `*${password},005,${digit},${speed},${times},${interval}#`; - } else if (data.instruction === 'picture') { - interval = data.interval || 5; - times = data.times || 1; - command = `*${password},200,${interval},${times}#`; - } else if (data.instruction === 'take_picture') { - command = `*${password},210#`; - } else if (data.instruction === 'configure_io_picture') { - const triggers = {on: 1, off: 2, both: 3}; - trigger = triggers[data.trigger || 'both']; - number = data.number || 1; - command = `*${password},201,${data.port},${trigger},${number}#`; - } else if(data.instruction === 'Custom'){ - command = data.command; - } else if (/^set_memory_(on|off)$/.test(data.instruction)) { - state = data.instruction.split('_')[2]; - digit = state === 'on' ? 1 : 0; - command = `*${password},601,${digit}#`; - } else if (/^set_tremble$/.test(data.instruction)) { - command = `*${password},021,${data.sleep ? 1 : 0},${data.tremble ? 1 : 0}#`; - } else if (/^set_into_sleep$/.test(data.instruction)) { - command = `*${password},044,${data.time}#`; - } else if (/^set_wake_up$/.test(data.instruction)) { - command = `*${password},043,${data.time}#`; - } else if (/^reboot$/.test(data.instruction)) { - command = `*${password},991#`; - } else if (/^set_extend$/.test(data.instruction)) { - a = data.a ? 1 : 0; - b = data.b ? 1 : 0; - c = data.c ? 1 : 0; - d = data.d ? 1 : 0; - e = data.e ? 1 : 0; - f = data.f ? 1 : 0; - g = data.g ? 1 : 0; - h = data.h ? 1 : 0; - command = `*${password},118,${a}${b}${c}${d}${e}${f}${g}${h}#`; - } else if (/^set_heartbeat_(on|off)$/.test(data.instruction)) { - state = data.instruction.split('_')[2]; - digit = state === 'on' ? 1 : 0; - command = `*${password},040,${digit}#`; - } else if (/^set_interval_heartbeat$/.test(data.instruction)) { - command = `*${password},041,${data.times}#`; - } else if (/^set_idling_(on|off)$/.test(data.instruction)) { - state = data.instruction.split('_')[2]; - digit = state === 'on' ? 1 : 0; - command = `*${password},404,${digit},${data.times}#`; - } - return command; -}; - -const getRebootCommand = password => { - password = password || '000000'; - return `*${password},991#`; -}; +const getRebootCommand = password => `*${password || '000000'},991#`; const getImei = raw => { let imei = null; const data = raw.toString(); - if (patterns.avl05.test(data)) { - imei = patterns.avl05.exec(data)[2]; - } else if (patterns.avl08.test(data)) { - imei = patterns.avl08.exec(data)[2]; - } else if (patterns.avl201.test(data)) { - imei = patterns.avl201.exec(data)[2]; + const _patterns = [patterns.avl05, patterns.avl08, patterns.avl201]; + const pattern = _patterns.find(x => x.test(data)); + if (pattern) { + imei = pattern.exec(data)[2]; } return imei; }; @@ -818,19 +53,8 @@ const getImei = raw => { module.exports = { parse: parse, patterns: patterns, - getAvl05: getAvl05, - getAvl08: getAvl08, - getAvl201: getAvl201, - getCommand: getCommand, - getPicture: getPicture, - getCommandError: getCommandError, - getCommandFirmware: getCommandFirmware, - getCommandInfo: getCommandInfo, - getCommandMap: getCommandMap, - verifyLen: verifyLen, - verifyCrc: verifyCrc, + parseCommand: commands.parseCommand, isTz: isTz, - parseCommand: parseCommand, getRebootCommand: getRebootCommand, getImei: getImei }; diff --git a/src/info.js b/src/info.js new file mode 100644 index 0000000..29c86d9 --- /dev/null +++ b/src/info.js @@ -0,0 +1,22 @@ +'use strict'; + +const moment = require('moment'); +const patterns = require('./patterns'); + +module.exports = data => { + const match = patterns.info.exec(data.toString()); + return { + device: 'tz', + type: 'info', + latitude: match[1], + longitude: match[2], + speed: parseInt(match[3], 10), + fix: match[4], + sat: parseInt(match[5], 10), + hdop: parseFloat(match[6]), + gsm: parseInt(match[7], 10), + battery: parseFloat(match[8]), + odometer: parseFloat(match[9]), + datetime: moment(`${match[10]} +00:00`, 'DD/MM/YY HH:mm:ss ZZ').toDate() + }; +}; diff --git a/src/map.js b/src/map.js new file mode 100644 index 0000000..39afd54 --- /dev/null +++ b/src/map.js @@ -0,0 +1,14 @@ +'use strict'; + +const patterns = require('./patterns'); + +module.exports = data => { + const match = patterns.map.exec(data.toString()); + return { + device: 'tz', + type: 'map_link', + url: match[0], + latitude: parseFloat(match[1]), + longitude: parseFloat(match[2]) + }; +}; diff --git a/src/messages/es.json b/src/messages/es.json new file mode 100644 index 0000000..ae03d85 --- /dev/null +++ b/src/messages/es.json @@ -0,0 +1,52 @@ +{ + "SetUserPassword": "Cambio de contraseña del dispositivo", + "SETINTERVALOFSMS": "Ajuste de intervalos de sms", + "SETPHONESMSFORSOS": "Ajuste de teléfono y sms para SOS", + "SETLOWPOWERALARM": "Ajuste de la alarma de energía baja", + "SETOVERSPEEDALARM": "Ajuste de la alarma de exceso de velocidad", + "SETGEOFENCEALARM": "Ajuste de la alarma de geocerca", + "SETEXTEND": "Ajuste de configuración extendida", + "SETGSMBAUD": "Ajuste de banda GSM", + "SETAPN": "Ajuste de APN", + "SETDNS": "Ajuste de DNS", + "SETIPANDPORT": "Ajuste de ip y puerto del servidor", + "SETGPRSINTERVAL": "Ajuste de intervalo GPRS", + "SETSYSSWITCH": "Ajuste de GPRS", + "SETTCPSWITCH": "Ajuste de modo GPRS", + "SETTREMBLESWITCH": "Ajuste de sensor de movimiento", + "SETSLEEPSWITCH": "Ajuste de Sleep", + "SETIOSWITCH": "Cambio de estado en las salidas digitales", + "SETHEARTBEATSWITCH": "Ajuste de Heartbeat", + "SETHEARTBEATINTERVAL": "Ajuste de intervalo de Heartbeat", + "SETHEARTBEATINIT": "Ajuste de inicialización de Heartbeat", + "SETTREMBLETOSLEEP": "Ajuste de activación de modo Sleep", + "SETTREMBLETOWAKEUP": "Ajuste de activación de modo Wake Up", + "SETPARKINGALARM": "Ajuste de la alarma de estacionamiento", + "FACTORYRESET": "Restablecimiento de fabrica", + "RBOOT": "Dispositivo reiniciado", + "SETOILSENSER": "Ajuste del sensor de combustible", + "SETSHUTOIL": "Ajuste del corte de combustible", + "SETSHUTOILSWITCH": "Activación del corte de combustible", + "SETCALLA": "Ajuste de la alarma de SOS", + "SETEXTEND2": "Ajuste de configuración extendida 2", + "SETPIN": "Ajuste del código pin de la tarjeta sim", + "SETANGLE": "Ajuste de la alarma de angulo", + "SETREBOOT": "Ajuste del intervalo de reiniciación", + "SETACCALARM": "Ajuste de la alarma de aceleración", + "SETROAMING": "Ajuste de roaming", + "SETACKSTATE": "Ajuste de ACK", + "SETCALLFILTER": "Ajuste de filtrado de llamadas", + "SETSENDTYPE": "Ajuste del tipo de envío de datos", + "SETPICTUREINTERVAL": "Ajuste de intervalo de captura de imágenes", + "CLEARBUF": "Memoria interna vaciada", + "GETPICTURE": "Nueva captura de imagen", + "SETDATAFLASH": "Activación de vaciado de memoria interna", + "SETTRACKINGINTERVAL": "Ajuste del intervalo de envío de datos", + "SETSENDODOMETER": "Activación de alarma de odometro", + "SETIMEI": "Ajuste de IMEI", + "SETIDLE": "Ajuste de la alarma de ralenti", + "SETINTERVALGPRSSTANDBY": "Ajuste del intervalo de envío de datos en modo standby", + "SETIOPICTURE": "Ajuste de captura de imágenes por activación de salidas digitales", + "SETPICTUREPACKET": "Ajuste de cantidad de paquetes enviados por imagen", + "default": "Última acción" +} diff --git a/src/patterns.js b/src/patterns.js new file mode 100644 index 0000000..d74ab2d --- /dev/null +++ b/src/patterns.js @@ -0,0 +1,13 @@ +'use strict'; + +module.exports = { + avl05: /^\$\$([0-9A-F]{2})(\d{15})\|([0-9A]{2})(\$GPRMC\,(\d{6}\.\d{3})\,([AV])\,(\d{4}\.\d{4}\,[NS])\,(\d{5}\.\d{4}\,[WE])\,(\d{1,3}\.\d{1,3})?\,(\d{1,3}\.\d{1,3})?\,(\d{6})\,((\d{1,3}\.\d{1,3})?\,([WE])?)\,?([ADENS])?\*([0-9A-F]{2})|[0]{60})\|(\d{2}\.\d{1})\|(\d{2}\.\d{1})\|(\d{2}\.\d{1})\|([01])([01])([01])([01])([01])([01])([01])([01])([01])([01])([01])([01])\|(\d{14})\|([01])(\d{3})(\d{4})\|(\d{4})(\d{4})\|([0-9A-F]{4})([0-9A-F]{4})\|([01\-]\d{3})\|(\d{1,4}\.\d{1,12})\|(\d{4})\|([0-9A-F]{4})\r\n$/, + avl08: /^\$\$([0-9A-F]{2})(\d{15})\|([0-9A]{2})(\$GPRMC\,(\d{6}\.\d{3})\,([AV])\,(\d{4}\.\d{4}\,[NS])\,(\d{5}\.\d{4}\,[WE])\,(\d{1,3}\.\d{1,3})?\,(\d{1,3}\.\d{1,3})?\,(\d{6})\,((\d{1,3}\.\d{1,3})?\,([WE])?)\,?([ADENS])?\*([0-9A-F]{2})|[0]{60})\|(\d{2}\.\d{1})\|(\d{2}\.\d{1})\|(\d{2}\.\d{1})\|([01])([01])([01])([01])([01])([01])([01])([01])([01])([01])([01])([01])\|(\d{14})\|([01])(\d{3})(\d{4})\|(\d{4})(\d{4})\|([0-9A-F]{4})([0-9A-F]{4})\|([01\-]\d{3})\|(\d{1,4}\.\d{1,12})\|(\d{4})\|(\d{10})?\|([0-9A-F]{4})\r\n$/, + avl201: /^\$\$([0-9A-F]{2})(\d{15})\|([0-9A]{2})(\$GPRMC\,(\d{6}\.\d{3})\,([AV])\,(\d{4}\.\d{4}\,[NS])\,(\d{5}\.\d{4}\,[WE])\,(\d{1,3}\.\d{1,3})?\,(\d{1,3}\.\d{1,3})?\,(\d{6})\,((\d{1,3}\.\d{1,3})?\,([WE])?)\,?([ADENS])?\*([0-9A-F]{2})|[0]{60})\|(\d{2}\.\d{1})\|(\d{2}\.\d{1})\|(\d{2}\.\d{1})\|([01])([01])([01])([01])([01])([01])([01])([01])([01])([01])([01])([01])\|(\d{14})\|([01])(\d{3})(\d{4})\|([0-9A-F]{4})([0-9A-F]{4})\|([01\-]\d{3})\|(\d{1,4}\.\d{1,12})\|(\d{4})\|([0-9A-F]{4})\r\n$/, + receiveOk: /^Receive:'\d{3}'OK\r\n\*(\d{6})\,(\d{3})(\S*)?#$/, + receiveErr: /^Receive:Set Err\r\n(\S*)/, + picture: /^(\$U\d{15}\d{5}\d{3}\d{3}[0-9a-fA-F]{1,200}#)+(Receive:'210'OK\r\n\*\d{6}\,210#)?$/, + firmware: /^IMEI:(\d{15})\r\nVER:(\S*)\r\nGSMVER:(\S*)\r\n$/, + info: /^Lat:([+-]?\d{4}\.\d{4}[NS])\r\nLong:([+-]?\d{5}\.\d{4}[WE])\r\nSpd:(\d{3})km\/h\r\nFix:([AV])\r\nSat:(\d{2})\r\nHDOP:(\d{2}\.\d{1})\r\nGSM:(\d{2})\r\nBatt:(\d{2}\.\d{2})V\r\nMile:(\d{1,4}\.\d{1,12})\r\nTime:(\d{2}\/\d{2}\/\d{2}\ \d{2}:\d{2}:\d{2})\r\n$/, + map: /^http:\/\/maps.google.com\/maps\?f=q&hl=en&q=(-?\d+\.\d+),(-?\d+\.\d+)&ie=UTF8&z=16&iwloc=addr&om=1$/ +}; diff --git a/src/pictures.js b/src/pictures.js new file mode 100644 index 0000000..a695eaf --- /dev/null +++ b/src/pictures.js @@ -0,0 +1,22 @@ +'use strict'; + +module.exports = raw => { + const results = raw.toString().match(/\$U\d{15}\d{5}\d{3}\d{3}[0-9a-fA-F]{1,200}#/g).map(x => { + const match = /\$U(\d{15})(\d{5})(\d{3})(\d{3})([0-9a-fA-F]{1,200})#/.exec(x); + return { + imei: match[1], + number: parseInt(match[2], 10), + total: parseInt(match[3], 10), + sequence: parseInt(match[4], 10), + data: match[5] + }; + }); + return { + device: 'tz', + type: 'image', + imei: results[0].imei, + number: results[0].number, + total: results[0].total, + data: results.map(x => ({sequence: x.sequence, data: x.data})) + }; +}; diff --git a/src/responses.js b/src/responses.js new file mode 100644 index 0000000..cb9e0fa --- /dev/null +++ b/src/responses.js @@ -0,0 +1,541 @@ +'use strict'; + +const nmea = require('node-nmea'); +const patterns = require('./patterns'); + +const langs = ['es']; + +const parseSetUserPassword = extra => { + return { + command: 'SetUserPassword', + newPassword: extra[0] + }; +}; + +const parseSetIntervalOfSms = extra => { + const x = extra[0]; + return { + command: 'SETINTERVALOFSMS', + enable: x !== '0', + interval: x, + limit: extra[1] + }; +}; + +const parseSetPhoneSmsForSos = extra => { + return { + command: 'SETPHONESMSFORSOS', + enable: ((extra[0] === '0') && (extra[1] === '1')), + callNumber: extra[2], + smsNumber: extra[3] + }; +}; + +const parseSetLowPowerAlarm = extra => { + return { + command: 'SETLOWPOWERALARM', + lowPower: parseFloat(extra[0]) / 100, + autoShutdown: parseFloat(extra[1]) / 100 + }; +}; + +const parseSetOverSpeedAlarm = extra => { + return { + command: 'SETOVERSPEEDALARM', + enable: extra[0] === '1', + speed: parseInt(extra[1], 10), + times: parseInt(extra[2], 10), + interval: parseInt(extra[3], 10) + }; +}; + +const parseDir = dir => { + let raw; + if (/^-/.test(dir)) { + if (dir.split('.')[0].length === 5) { + raw = `${dir.substr(1)},S`; + } else { + raw = `${dir.substr(1)},W`; + } + } else { + if (dir.split('.')[0].length === 5) { + raw = `${dir.substr(1)},N`; + } else { + raw = `${dir.substr(1)},E`; + } + } + return raw; +}; + +const parseSetGeofenceAlarm = extra => { + const lat1 = extra[0]; + const lon1 = extra[1]; + const lat2 = extra[2]; + const lon2 = extra[3]; + const y = extra[5]; + const data = {command: 'SETGEOFENCEALARM'}; + if (y === '0') { + data.enable = false; + } else { + data.enable = true; + data.mode = y === '1' ? 'inside' : 'outside'; + data.geojson = { + type: 'Polygon', + coordinates: [[ + [nmea.degToDec(parseDir(lon2)), nmea.degToDec(parseDir(lat2))], + [nmea.degToDec(parseDir(lon2)), nmea.degToDec(parseDir(lat1))], + [nmea.degToDec(parseDir(lon1)), nmea.degToDec(parseDir(lat1))], + [nmea.degToDec(parseDir(lon1)), nmea.degToDec(parseDir(lat2))], + [nmea.degToDec(parseDir(lon2)), nmea.degToDec(parseDir(lat2))] + ]] + }; + } + return data; +}; + +const parseSetExtend = extra => { + const data = extra[0].split(''); + return { + command: 'SETEXTEND', + extend: { + a: data[0] === '1', + b: data[1] === '1', + c: data[2] === '1', + d: data[3] === '1', + e: data[4] === '1', + f: data[5] === '1', + g: data[6] === '1' + } + }; +}; + +const parseSetGsmBaud = extra => { + const data = {command: 'SETGSMBAUD'}; + if (extra[0] === '0') { + data.band = '900/1800'; + } else if (extra[0] === '1') { + data.band = '850/1900'; + } else { + data.band = 'auto'; + } + return data; +}; + +const parseSetApn = extra => { + return { + command: 'SETAPN', + apn: extra[0], + username: extra[1], + pass: extra[2] + }; +}; + +const parseSetDns = extra => { + return { + command: 'SETDNS', + enable: extra[0] === '1', + dns1: extra[1], + dns2: extra[2] + }; +}; + +const parseSetIpAndPort = extra => { + return { + command: 'SETIPANDPORT', + host: extra[1], + port: parseInt(extra[2], 10) + }; +}; + +const parseSetGprsInterval = extra => { + const x = extra[0]; + return { + command: 'SETGPRSINTERVAL', + enable: x !== '0', + interval: parseInt(x, 10), + limit: parseInt(extra[1], 10) + }; +}; + +const parseSetSysSwitch = extra => { + return { + command: 'SETSYSSWITCH', + enable: extra[0] === '1' + }; +}; + +const parseSetTcpSwitch = extra => { + return { + command: 'SETTCPSWITCH', + mode: extra[0] === '1' ? 'tcp' : 'udp' + }; +}; + +const parseSetTrembleSwitch = extra => { + return { + command: 'SETTREMBLESWITCH', + sleep: extra[0] === '1', + tremble: extra[1] === '1' + }; +}; + +const parseSetSleepSwitch = extra => { + return { + command: 'SETSLEEPSWITCH', + closeGps: extra[0] === '0', + closeGsm: extra[1] === '0' + }; +}; + +const parseSetIoSwitch = extra => { + const ports = {'A': 1, 'B': 2, 'C': 3, 'D': 4}; + return { + command: 'SETIOSWITCH', + enable: extra[1] === '1', + port: ports[extra[0]] + }; +}; + +const parseSetHeartbeatSwitch = extra => { + return { + command: 'SETHEARTBEATSWITCH', + enable: extra[0] === '1' + }; +}; + +const parseSetHeartbeatInterval = extra => { + const x = extra[0]; + return { + command: 'SETHEARTBEATINTERVAL', + enable: x !== '0', + interval: x + }; +}; + +const parseSetHeartbeatIntit = () => { + return {command: 'SETHEARTBEATINIT'}; +}; + +const parseSetTrembleToSleep = extra => { + return { + command: 'SETTREMBLETOSLEEP', + after: parseInt(extra[0], 10) + }; +}; + +const parseSetTrembleToWakeup = extra => { + return { + command: 'SETTREMBLETOWAKEUP', + after: parseInt(extra[0], 10) + }; +}; + +const parseSetParkingAlarm = extra => { + return { + command: 'SETPARKINGALARM', + enable: extra[0] === '1' + }; +}; + +const parseFactoryReset = () => { + return {command: 'FACTORYRESET'}; +}; + +const parseRboot = () => { + return {command: 'RBOOT'}; +}; + +const parseSetOilSenser = extra => { + return { + command: 'SETOILSENSER', + empty: parseInt(extra[0], 10) / 100, + full: parseInt(extra[1], 10) / 100 + }; +}; + +const parseSetShutOil = extra => { + return { + command: 'SETSHUTOIL', + speed: parseInt(extra[0], 10), + off: parseInt(extra[1], 10), + restart: parseInt(extra[2], 10), + repeat: parseInt(extra[3], 10) + }; +}; + +const parseSetShutOilSwitch = extra => { + return { + command: 'SETSHUTOILSWITCH', + enable: extra[0] === '1' + }; +}; + +const parseSetCallA = extra => { + return { + command: 'SETCALLA', + mode: extra[0] === '0' ? 'gprs' : 'call', + number: extra[1] + }; +}; + +const parseSetExtend2 = extra => { + const data = extra[0].split(''); + return { + command: 'SETEXTEND2', + extend: { + a: data[0] === '1', + b: data[1] === '1', + c: data[2] === '1', + d: data[3] === '1', + e: data[4] === '1', + f: data[5] === '1', + g: data[6] === '1', + h: data[7] === '1' + } + }; +}; + +const parseSetPin = extra => { + return { + command: 'SETPIN', + enable: extra[0] === '1', + pin: extra[1] + }; +}; + +const parseSetAngle = extra => { + const x = extra[0]; + const data = {command: 'SETANGLE'}; + if (x === '0') { + data.enable = false; + } else if (x === '1') { + data.enable = true; + } else if (x === '2') { + data.enable = true; + data.port = 4; + } else { + data.enable = true; + data.port = 3; + } + data.angle = parseInt(extra[1], 10); + return data; +}; + +const parseReboot = extra => { + return { + command: 'SETREBOOT', + enable: extra[0] === '1', + interval: parseInt(extra[1], 10) + }; +}; + +const parseSetAccAlarm = extra => { + return { + command: 'SETACCALARM', + enable: extra[0] === '1', + acceleration: parseInt(extra[1], 10), + deceleration: parseInt(extra[2], 10) + }; +}; + +const parseSetRoaming = extra => { + return { + command: 'SETROAMING', + enable: extra[0] === '1', + interval: parseInt(extra[1], 10), + network: extra[2] + }; +}; + +const parseSetackstate = extra => { + return { + command: 'SETACKSTATE', + enable: extra[0] === '1' + }; +}; + +const parseSetcallfilter = extra => { + return { + command: 'SETCALLFILTER', + enable: extra[0] === '1', + caller: extra[1] + }; +}; + +const parseSetsendtype = extra => { + return { + command: 'SETSENDTYPE', + mode: extra[0] === '0' ? 'gprs' : 'sms' + }; +}; + +const parseSetpictureinterval = extra => { + return { + command: 'SETPICTUREINTERVAL', + interval: parseInt(extra[0], 10), + times: parseInt(extra[1], 10) + }; +}; + +const parseClearbuf = () => { + return {command: 'CLEARBUF'}; +}; + +const parseGetpicture = () => { + return {command: 'GETPICTURE'}; +}; + +const parseSetdataflash = extra => { + return { + command: 'SETDATAFLASH', + enable: extra[0] === '1' + }; +}; + +const parseSettrackinginterval = extra => { + return { + command: 'SETTRACKINGINTERVAL', + enable: extra[0] === '1', + intervalOn: parseInt(extra[1], 10), + intervalOff: parseInt(extra[2], 10) + }; +}; + +const parseSetsendodometer = extra => { + return { + command: 'SETSENDODOMETER', + enable: extra[0] === '1', + range: parseInt(extra[1], 10) + }; +}; + +const parseSetimei = extra => { + return { + command: 'SETIMEI', + enable: extra[0] === '1', + newImei: extra[1] + }; +}; + +const parseSetidle = extra => { + return { + command: 'SETIDLE', + enable: extra[0] === '1', + interval: parseInt(extra[1], 10) + }; +}; + +const parseSetintervalgprsstandby = extra => { + return { + command: 'SETINTERVALGPRSSTANDBY', + enable: extra[0] === '1', + interval: parseInt(extra[1], 10) + }; +}; + +const parseSetiopicture = extra => { + const x = extra[0]; + const y = extra[1]; + const data = {command: 'SETIOPICTURE'}; + if (x === '0') { + data.enable = false; + } else if (x === '1') { + data.enable = true; + data.port = 4; + } else if (x === '2') { + data.enable = true; + data.port = 3; + } else if (x === '3') { + data.enable = true; + data.port = 2; + } else { + data.enable = true; + data.port = 1; + } + if (y === '1') { + data.mode = 'open'; + } else if (y === '2') { + data.mode = 'close'; + } else { + data.mode = 'both'; + } + data.times = parseInt(extra[2], 10); + return data; +}; + +const parseSetpicturepacket = extra => { + return { + command: 'SETPICTUREPACKET', + number: parseInt(extra[0], 10) + }; +}; + +const getCommand = (raw, lang) => { + lang = langs[lang] || 'es'; + const messages = require(`./messages/${lang}.json`); + const match = patterns.receiveOk.exec(raw.toString()); + const password = match[1]; + const code = match[2]; + const extra = match[3] ? match[3].substr(1).split(',') : null; + let defaultData = {device: 'tz', type: 'ok', password: password}; + const parsers = { + '001': parseSetUserPassword, + '002': parseSetIntervalOfSms, + '003': parseSetPhoneSmsForSos, + '004': parseSetLowPowerAlarm, + '005': parseSetOverSpeedAlarm, + '006': parseSetGeofenceAlarm, + '008': parseSetExtend, + '009': parseSetGsmBaud, + '011': parseSetApn, + '014': parseSetDns, + '015': parseSetIpAndPort, + '016': parseSetSysSwitch, + '018': parseSetGprsInterval, + '019': parseSetTcpSwitch, + '021': parseSetTrembleSwitch, + '022': parseSetSleepSwitch, + '023': parseSetintervalgprsstandby, + '025': parseSetIoSwitch, + '040': parseSetHeartbeatSwitch, + '041': parseSetHeartbeatInterval, + '042': parseSetHeartbeatIntit, + '043': parseSetTrembleToWakeup, + '044': parseSetTrembleToSleep, + '103': parseSetCallA, + '110': parseSetParkingAlarm, + '113': parseSetOilSenser, + '116': parseSetShutOilSwitch, + '117': parseSetShutOil, + '118': parseSetExtend2, + '119': parseSetsendtype, + '120': parseSetAccAlarm, + '121': parseSetRoaming, + '122': parseSetPin, + '123': parseSetackstate, + '130': parseSetcallfilter, + '151': parseSetsendodometer, + '155': parseSetimei, + '156': parseSettrackinginterval, + '200': parseSetpictureinterval, + '201': parseSetiopicture, + '202': parseSetpicturepacket, + '210': parseGetpicture, + '300': parseSetAngle, + '400': parseSetAngle, + '404': parseSetidle, + '500': parseClearbuf, + '600': parseReboot, + '601': parseSetdataflash, + '990': parseFactoryReset, + '991': parseRboot + }; + const parser = parsers[code]; + const data = Object.assign(parser ? parser(extra) : {}, defaultData); + data.message = messages[data.command] || messages.default; + return data; +}; + +module.exports = { + getCommand: getCommand +}; diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 0000000..95661f2 --- /dev/null +++ b/src/utils.js @@ -0,0 +1,57 @@ +'use strict'; + +const crc = require('crc'); + +const verifyCrc = (raw, checksum) => { + let crcData; + const idx = raw.lastIndexOf('|'); + const data = raw.slice(0, idx + 1); + crcData = crc.crc16modbus(data); + return crcData === checksum; +}; + +const verifyLen = (raw, len) => { + return raw.replace('\r\n', '').length === len; +}; + +const isValid = (raw, len, checksum) =>{ + return verifyCrc(raw, checksum) && verifyLen(raw, len); +}; + +const getAlarm = alarm => { + const alarmTypes = { + '01': {type: 'SOS_Button'}, + '49': {type: 'DI', number: 5, status: false}, + '09': {type: 'Auto_Shutdown'}, + '10': {type: 'Low_Battery'}, + '11': {type: 'Over_Speed', status: true}, + '13': {type: 'Over_Speed', status: false}, + '14': {type: 'Aceleration', status: true}, + '15': {type: 'Aceleration', status: false}, + '30': {type: 'Parking'}, + '42': {type: 'Geo_Fence', status: true}, + '43': {type: 'Geo_Fence', status: false}, + '50': {type: 'DI', number: 1, status: false}, + '51': {type: 'DI', number: 1, status: true}, + '52': {type: 'DI', number: 2, status: false}, + '53': {type: 'DI', number: 2, status: true}, + '54': {type: 'DI', number: 3, status: false}, + '55': {type: 'DI', number: 3, status: true}, + '56': {type: 'DI', number: 4, status: false}, + '57': {type: 'DI', number: 4, status: true}, + '60': {type: 'Charge', status: true}, + '61': {type: 'Charge', status: false}, + '66': {type: 'Rfid'}, + '77': {type: 'Angle'}, + '88': {type: 'Heartbeat'}, + '91': {type: 'Sleep', status: true}, + '92': {type: 'Sleep', status: false}, + 'AA': {type: 'Gps'} + }; + return alarmTypes[alarm]; +}; + +module.exports = { + isValid: isValid, + getAlarm: getAlarm +}; diff --git a/test/responses.js b/test/responses.js new file mode 100644 index 0000000..4dbf226 --- /dev/null +++ b/test/responses.js @@ -0,0 +1,737 @@ +'use strict'; + +const tz = require('../src'); +const expect = require('chai').expect; + +describe('responses', () => { + it('should return SetUserPassword data parsed', () => { + const raw = new Buffer('Receive:\'001\'OK\r\n*000000,001,111111#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SetUserPassword'); + expect(data.message).to.eql('Cambio de contraseña del dispositivo'); + expect(data.newPassword).to.eql('111111'); + }); + + it('should return SETINTERVALOFSMS data parsed', () => { + const raw = new Buffer('Receive:\'002\'OK\r\n*000000,002,1,999#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETINTERVALOFSMS'); + expect(data.message).to.eql('Ajuste de intervalos de sms'); + expect(data.enable).to.be.true; + expect(data.interval).to.eql('1'); + expect(data.limit).to.eql('999'); + }); + + it('should return SETPHONESMSFORSOS data parsed', () => { + const raw = new Buffer('Receive:\'003\'OK\r\n*000000,003,0,1,005695487459,005695487459#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETPHONESMSFORSOS'); + expect(data.message).to.eql('Ajuste de teléfono y sms para SOS'); + expect(data.enable).to.be.true; + expect(data.callNumber).to.eql('005695487459'); + expect(data.smsNumber).to.eql('005695487459'); + }); + + it('should return SETLOWPOWERALARM data parsed', () => { + const raw = new Buffer('Receive:\'004\'OK\r\n*000000,004,380,350#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETLOWPOWERALARM'); + expect(data.message).to.eql('Ajuste de la alarma de energía baja'); + expect(data.lowPower).to.eql(3.8); + expect(data.autoShutdown).to.eql(3.5); + }); + + it('should return SETOVERSPEEDALARM data parsed', () => { + const raw = new Buffer('Receive:\'005\'OK\r\n*000000,005,1,100,10,360#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETOVERSPEEDALARM'); + expect(data.message).to.eql('Ajuste de la alarma de exceso de velocidad'); + expect(data.enable).to.be.true; + expect(data.speed).to.eql(100); + expect(data.times).to.eql(10); + expect(data.interval).to.eql(360); + }); + + it('should return SETGEOFENCEALARM data parsed', () => { + const raw = new Buffer('Receive:\'006\'OK\r\n*000000,006,+3321.6805,+07030.9513,+3321.6095,+07030.8714,1,1#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETGEOFENCEALARM'); + expect(data.message).to.eql('Ajuste de la alarma de geocerca'); + expect(data.enable).to.be.true; + expect(data.mode).to.eql('inside'); + expect(data.geojson.type).to.eql('Polygon'); + expect(data.geojson.coordinates).to.eql([[ + [70.51452333333333, 33.36015833333333], + [70.51452333333333, 33.36134166666667], + [70.515855, 33.36134166666667], + [70.515855, 33.36015833333333], + [70.51452333333333, 33.36015833333333] + ]]); + }); + + it('should return SETGEOFENCEALARM data parsed', () => { + const raw = new Buffer('Receive:\'006\'OK\r\n*000000,006,-3321.6805,-07030.9513,-3321.6095,-07030.8714,1,2#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETGEOFENCEALARM'); + expect(data.message).to.eql('Ajuste de la alarma de geocerca'); + expect(data.enable).to.be.true; + expect(data.mode).to.eql('outside'); + expect(data.geojson.type).to.eql('Polygon'); + expect(data.geojson.coordinates).to.eql([[ + [-70.51452333333333, -33.36015833333333], + [-70.51452333333333, -33.36134166666667], + [-70.515855, -33.36134166666667], + [-70.515855, -33.36015833333333], + [-70.51452333333333, -33.36015833333333] + ]]); + }); + + it('should return SETGEOFENCEALARM data parsed', () => { + const raw = new Buffer('Receive:\'006\'OK\r\n*000000,006,-3321.6805,-07030.9513,-3321.6095,-07030.8714,1,0#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETGEOFENCEALARM'); + expect(data.message).to.eql('Ajuste de la alarma de geocerca'); + expect(data.enable).to.be.false; + }); + + it('should return SETEXTEND data parsed', () => { + const raw = new Buffer('Receive:\'008\'OK\r\n*000000,008,1000001#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETEXTEND'); + expect(data.message).to.eql('Ajuste de configuración extendida'); + expect(data.extend).to.eql({a: true, b: false, c: false, d: false, e: false, f: false, g: true}); + }); + + it('should return SETGSMBAUD data parsed', () => { + const raw = new Buffer('Receive:\'009\'OK\r\n*000000,009,0#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETGSMBAUD'); + expect(data.message).to.eql('Ajuste de banda GSM'); + expect(data.band).to.eql('900/1800'); + }); + + it('should return SETGSMBAUD data parsed', () => { + const raw = new Buffer('Receive:\'009\'OK\r\n*000000,009,1#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETGSMBAUD'); + expect(data.message).to.eql('Ajuste de banda GSM'); + expect(data.band).to.eql('850/1900'); + }); + + it('should return SETGSMBAUD data parsed', () => { + const raw = new Buffer('Receive:\'009\'OK\r\n*000000,009,2#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETGSMBAUD'); + expect(data.message).to.eql('Ajuste de banda GSM'); + expect(data.band).to.eql('auto'); + }); + + it('should return SETAPN data parsed', () => { + const raw = new Buffer('Receive:\'011\'OK\r\n*000000,011,imovil.entelpcs.cl,entelpcs,entelpcs#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETAPN'); + expect(data.message).to.eql('Ajuste de APN'); + expect(data.apn).to.eql('imovil.entelpcs.cl'); + expect(data.username).to.eql('entelpcs'); + expect(data.pass).to.eql('entelpcs'); + }); + + it('should return SETDNS data parsed', () => { + const raw = new Buffer('Receive:\'014\'OK\r\n*000000,014,1,8.8.8.8,8.8.4.4#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETDNS'); + expect(data.message).to.eql('Ajuste de DNS'); + expect(data.enable).to.be.true; + expect(data.dns1).to.eql('8.8.8.8'); + expect(data.dns2).to.eql('8.8.4.4'); + }); + + it('should return SETIPANDPORT data parsed', () => { + const raw = new Buffer('Receive:\'015\'OK\r\n*000000,015,1,server.com,1331#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETIPANDPORT'); + expect(data.message).to.eql('Ajuste de ip y puerto del servidor'); + expect(data.host).to.eql('server.com'); + expect(data.port).to.eql(1331); + }); + + it('should return SETGPRSINTERVAL data parsed', () => { + const raw = new Buffer('Receive:\'018\'OK\r\n*000000,018,10,999#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETGPRSINTERVAL'); + expect(data.message).to.eql('Ajuste de intervalo GPRS'); + expect(data.enable).to.be.true; + expect(data.interval).to.eql(10); + expect(data.limit).to.eql(999); + }); + + it('should return SETSYSSWITCH data parsed', () => { + const raw = new Buffer('Receive:\'016\'OK\r\n*000000,016,1#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETSYSSWITCH'); + expect(data.message).to.eql('Ajuste de GPRS'); + expect(data.enable).to.be.true; + }); + + it('should return SETTCPSWITCH data parsed', () => { + const raw = new Buffer('Receive:\'019\'OK\r\n*000000,019,1#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETTCPSWITCH'); + expect(data.message).to.eql('Ajuste de modo GPRS'); + expect(data.mode).to.eql('tcp'); + }); + + it('should return SETTCPSWITCH data parsed', () => { + const raw = new Buffer('Receive:\'019\'OK\r\n*000000,019,0#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETTCPSWITCH'); + expect(data.message).to.eql('Ajuste de modo GPRS'); + expect(data.mode).to.eql('udp'); + }); + + it('should return SETTREMBLESWITCH data parsed', () => { + const raw = new Buffer('Receive:\'021\'OK\r\n*000000,021,1,1#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETTREMBLESWITCH'); + expect(data.message).to.eql('Ajuste de sensor de movimiento'); + expect(data.sleep).to.be.true; + expect(data.tremble).to.be.true; + }); + + it('should return SETSLEEPSWITCH data parsed', () => { + const raw = new Buffer('Receive:\'022\'OK\r\n*000000,022,0,0#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETSLEEPSWITCH'); + expect(data.message).to.eql('Ajuste de Sleep'); + expect(data.closeGps).to.be.true; + expect(data.closeGsm).to.be.true; + }); + + it('should return SETIOSWITCH data parsed', () => { + const raw = new Buffer('Receive:\'025\'OK\r\n*000000,025,A,1#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETIOSWITCH'); + expect(data.message).to.eql('Cambio de estado en las salidas digitales'); + expect(data.enable).to.be.true; + expect(data.port).to.eql(1); + }); + + it('should return SETIOSWITCH data parsed', () => { + const raw = new Buffer('Receive:\'025\'OK\r\n*000000,025,A,1#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETIOSWITCH'); + expect(data.message).to.eql('Cambio de estado en las salidas digitales'); + expect(data.enable).to.be.true; + expect(data.port).to.eql(1); + }); + + it('should return SETHEARTBEATSWITCH data parsed', () => { + const raw = new Buffer('Receive:\'040\'OK\r\n*000000,040,0#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETHEARTBEATSWITCH'); + expect(data.message).to.eql('Ajuste de Heartbeat'); + expect(data.enable).to.be.false; + }); + + it('should return SETHEARTBEATINTERVAL data parsed', () => { + const raw = new Buffer('Receive:\'041\'OK\r\n*000000,041,0#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETHEARTBEATINTERVAL'); + expect(data.message).to.eql('Ajuste de intervalo de Heartbeat'); + expect(data.enable).to.be.false; + }); + + it('should return SETHEARTBEATINIT data parsed', () => { + const raw = new Buffer('Receive:\'042\'OK\r\n*000000,042#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETHEARTBEATINIT'); + expect(data.message).to.eql('Ajuste de inicialización de Heartbeat'); + }); + + it('should return SETTREMBLETOSLEEP data parsed', () => { + const raw = new Buffer('Receive:\'044\'OK\r\n*000000,044,30#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETTREMBLETOSLEEP'); + expect(data.message).to.eql('Ajuste de activación de modo Sleep'); + expect(data.after).to.eql(30); + }); + + it('should return SETTREMBLETOWAKEUP data parsed', () => { + const raw = new Buffer('Receive:\'043\'OK\r\n*000000,043,10#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETTREMBLETOWAKEUP'); + expect(data.message).to.eql('Ajuste de activación de modo Wake Up'); + expect(data.after).to.eql(10); + }); + + it('should return SETPARKINGALARM data parsed', () => { + const raw = new Buffer('Receive:\'110\'OK\r\n*000000,110,0#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETPARKINGALARM'); + expect(data.message).to.eql('Ajuste de la alarma de estacionamiento'); + expect(data.enable).to.be.false; + }); + + it('should return FACTORYRESET data parsed', () => { + const raw = new Buffer('Receive:\'990\'OK\r\n*000000,990#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('FACTORYRESET'); + expect(data.message).to.eql('Restablecimiento de fabrica'); + }); + + it('should return RBOOT data parsed', () => { + const raw = new Buffer('Receive:\'991\'OK\r\n*000000,991#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('RBOOT'); + expect(data.message).to.eql('Dispositivo reiniciado'); + }); + + it('should return SETOILSENSER data parsed', () => { + const raw = new Buffer('Receive:\'113\'OK\r\n*000000,113,100,500#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETOILSENSER'); + expect(data.message).to.eql('Ajuste del sensor de combustible'); + expect(data.empty).to.eql(1); + expect(data.full).to.eql(5); + }); + + it('should return SETSHUTOIL data parsed', () => { + const raw = new Buffer('Receive:\'117\'OK\r\n*000000,117,60,500,3000,5#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETSHUTOIL'); + expect(data.message).to.eql('Ajuste del corte de combustible'); + expect(data.speed).to.eql(60); + expect(data.off).to.eql(500); + expect(data.restart).to.eql(3000); + expect(data.repeat).to.eql(5); + }); + + it('should return SETSHUTOILSWITCH data parsed', () => { + const raw = new Buffer('Receive:\'116\'OK\r\n*000000,116,0#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETSHUTOILSWITCH'); + expect(data.message).to.eql('Activación del corte de combustible'); + expect(data.enable).to.be.false; + }); + + it('should return SETCALLA data parsed', () => { + const raw = new Buffer('Receive:\'103\'OK\r\n*000000,103,0,005695487459#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETCALLA'); + expect(data.message).to.eql('Ajuste de la alarma de SOS'); + expect(data.mode).to.eql('gprs'); + expect(data.number).to.eql('005695487459'); + }); + + it('should return SETCALLA data parsed', () => { + const raw = new Buffer('Receive:\'103\'OK\r\n*000000,103,1,005695487459#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETCALLA'); + expect(data.message).to.eql('Ajuste de la alarma de SOS'); + expect(data.mode).to.eql('call'); + expect(data.number).to.eql('005695487459'); + }); + + it('should return SETEXTEND2 data parsed', () => { + const raw = new Buffer('Receive:\'118\'OK\r\n*000000,118,10000001#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETEXTEND2'); + expect(data.message).to.eql('Ajuste de configuración extendida 2'); + expect(data.extend).to.eql({a: true, b: false, c: false, d: false, e: false, f: false, g: false, h: true}); + }); + + it('should return SETPIN data parsed', () => { + const raw = new Buffer('Receive:\'122\'OK\r\n*000000,122,0,1234#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETPIN'); + expect(data.message).to.eql('Ajuste del código pin de la tarjeta sim'); + expect(data.enable).to.be.false; + expect(data.pin).to.eql('1234'); + }); + + it('should return SETANGLE data parsed', () => { + const raw = new Buffer('Receive:\'300\'OK\r\n*000000,300,0,360#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETANGLE'); + expect(data.message).to.eql('Ajuste de la alarma de angulo'); + expect(data.enable).to.be.false; + expect(data.angle).to.eql(360); + }); + + it('should return SETANGLE data parsed', () => { + const raw = new Buffer('Receive:\'400\'OK\r\n*000000,400,0,360#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETANGLE'); + expect(data.message).to.eql('Ajuste de la alarma de angulo'); + expect(data.enable).to.be.false; + expect(data.angle).to.eql(360); + }); + + it('should return SETANGLE data parsed', () => { + const raw = new Buffer('Receive:\'400\'OK\r\n*000000,400,1,360#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETANGLE'); + expect(data.message).to.eql('Ajuste de la alarma de angulo'); + expect(data.enable).to.be.true; + expect(data.angle).to.eql(360); + }); + + it('should return SETANGLE data parsed', () => { + const raw = new Buffer('Receive:\'400\'OK\r\n*000000,400,2,360#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETANGLE'); + expect(data.message).to.eql('Ajuste de la alarma de angulo'); + expect(data.enable).to.be.true; + expect(data.port).to.eql(4); + expect(data.angle).to.eql(360); + }); + + it('should return SETANGLE data parsed', () => { + const raw = new Buffer('Receive:\'400\'OK\r\n*000000,400,3,360#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETANGLE'); + expect(data.message).to.eql('Ajuste de la alarma de angulo'); + expect(data.enable).to.be.true; + expect(data.port).to.eql(3); + expect(data.angle).to.eql(360); + }); + + it('should return SETREBOOT data parsed', () => { + const raw = new Buffer('Receive:\'600\'OK\r\n*000000,600,0,30#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETREBOOT'); + expect(data.message).to.eql('Ajuste del intervalo de reiniciación'); + expect(data.enable).to.be.false; + expect(data.interval).to.eql(30); + }); + + it('should return SETACCALARM data parsed', () => { + const raw = new Buffer('Receive:\'120\'OK\r\n*000000,120,0,30,30#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETACCALARM'); + expect(data.message).to.eql('Ajuste de la alarma de aceleración'); + expect(data.enable).to.be.false; + expect(data.acceleration).to.eql(30); + expect(data.deceleration).to.eql(30); + }); + + it('should return SETROAMING data parsed', () => { + const raw = new Buffer('Receive:\'121\'OK\r\n*000000,121,0,30,210#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETROAMING'); + expect(data.message).to.eql('Ajuste de roaming'); + expect(data.enable).to.be.false; + expect(data.interval).to.eql(30); + expect(data.network).to.eql('210'); + }); + + it('should return SETACKSTATE data parsed', () => { + const raw = new Buffer('Receive:\'123\'OK\r\n*000000,123,0#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETACKSTATE'); + expect(data.message).to.eql('Ajuste de ACK'); + expect(data.enable).to.be.false; + }); + + it('should return SETCALLFILTER data parsed', () => { + const raw = new Buffer('Receive:\'130\'OK\r\n*000000,130,0,0#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETCALLFILTER'); + expect(data.message).to.eql('Ajuste de filtrado de llamadas'); + expect(data.enable).to.be.false; + expect(data.caller).to.eql('0'); + }); + + it('should return SETSENDTYPE data parsed', () => { + const raw = new Buffer('Receive:\'119\'OK\r\n*000000,119,0#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETSENDTYPE'); + expect(data.message).to.eql('Ajuste del tipo de envío de datos'); + expect(data.mode).to.eql('gprs'); + }); + + it('should return SETSENDTYPE data parsed', () => { + const raw = new Buffer('Receive:\'119\'OK\r\n*000000,119,1#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETSENDTYPE'); + expect(data.message).to.eql('Ajuste del tipo de envío de datos'); + expect(data.mode).to.eql('sms'); + }); + + it('should return SETPICTUREINTERVAL data parsed', () => { + const raw = new Buffer('Receive:\'200\'OK\r\n*000000,200,10,999#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETPICTUREINTERVAL'); + expect(data.message).to.eql('Ajuste de intervalo de captura de imágenes'); + expect(data.interval).to.eql(10); + expect(data.times).to.eql(999); + }); + + it('should return CLEARBUF data parsed', () => { + const raw = new Buffer('Receive:\'500\'OK\r\n*000000,500#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('CLEARBUF'); + expect(data.message).to.eql('Memoria interna vaciada'); + }); + + it('should return GETPICTURE data parsed', () => { + const raw = new Buffer('Receive:\'210\'OK\r\n*000000,210#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('GETPICTURE'); + expect(data.message).to.eql('Nueva captura de imagen'); + }); + + it('should return SETDATAFLASH data parsed', () => { + const raw = new Buffer('Receive:\'601\'OK\r\n*000000,601,1#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETDATAFLASH'); + expect(data.message).to.eql('Activación de vaciado de memoria interna'); + expect(data.enable).to.be.true; + }); + + it('should return SETTRACKINGINTERVAL data parsed', () => { + const raw = new Buffer('Receive:\'156\'OK\r\n*000000,156,0,30,30#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETTRACKINGINTERVAL'); + expect(data.message).to.eql('Ajuste del intervalo de envío de datos'); + expect(data.enable).to.be.false; + expect(data.intervalOn).to.eql(30); + expect(data.intervalOff).to.eql(30); + }); + + it('should return SETSENDODOMETER data parsed', () => { + const raw = new Buffer('Receive:\'151\'OK\r\n*000000,151,0,100#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETSENDODOMETER'); + expect(data.message).to.eql('Activación de alarma de odometro'); + expect(data.enable).to.be.false; + expect(data.range).to.eql(100); + }); + + it('should return SETIMEI data parsed', () => { + const raw = new Buffer('Receive:\'155\'OK\r\n*000000,155,0,000000000000000#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETIMEI'); + expect(data.message).to.eql('Ajuste de IMEI'); + expect(data.enable).to.be.false; + expect(data.newImei).to.eql('000000000000000'); + }); + + it('should return SETIDLE data parsed', () => { + const raw = new Buffer('Receive:\'404\'OK\r\n*000000,404,0,30#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETIDLE'); + expect(data.message).to.eql('Ajuste de la alarma de ralenti'); + expect(data.enable).to.be.false; + expect(data.interval).to.eql(30); + }); + + it('should return SETINTERVALGPRSSTANDBY data parsed', () => { + const raw = new Buffer('Receive:\'023\'OK\r\n*000000,023,0,30#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETINTERVALGPRSSTANDBY'); + expect(data.message).to.eql('Ajuste del intervalo de envío de datos en modo standby'); + expect(data.enable).to.be.false; + expect(data.interval).to.eql(30); + }); + + it('should return SETIOPICTURE data parsed', () => { + const raw = new Buffer('Receive:\'201\'OK\r\n*000000,201,0,3,5#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETIOPICTURE'); + expect(data.message).to.eql('Ajuste de captura de imágenes por activación de salidas digitales'); + expect(data.enable).to.be.false; + expect(data.mode).to.eql('both'); + expect(data.times).to.eql(5); + }); + + it('should return SETIOPICTURE data parsed', () => { + const raw = new Buffer('Receive:\'201\'OK\r\n*000000,201,1,1,5#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETIOPICTURE'); + expect(data.message).to.eql('Ajuste de captura de imágenes por activación de salidas digitales'); + expect(data.enable).to.be.true; + expect(data.port).to.eql(4); + expect(data.mode).to.eql('open'); + expect(data.times).to.eql(5); + }); + + it('should return SETIOPICTURE data parsed', () => { + const raw = new Buffer('Receive:\'201\'OK\r\n*000000,201,2,2,5#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETIOPICTURE'); + expect(data.message).to.eql('Ajuste de captura de imágenes por activación de salidas digitales'); + expect(data.enable).to.be.true; + expect(data.port).to.eql(3); + expect(data.mode).to.eql('close'); + expect(data.times).to.eql(5); + }); + + it('should return SETIOPICTURE data parsed', () => { + const raw = new Buffer('Receive:\'201\'OK\r\n*000000,201,3,3,5#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETIOPICTURE'); + expect(data.message).to.eql('Ajuste de captura de imágenes por activación de salidas digitales'); + expect(data.enable).to.be.true; + expect(data.port).to.eql(2); + expect(data.mode).to.eql('both'); + expect(data.times).to.eql(5); + }); + + it('should return SETIOPICTURE data parsed', () => { + const raw = new Buffer('Receive:\'201\'OK\r\n*000000,201,4,3,5#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETIOPICTURE'); + expect(data.message).to.eql('Ajuste de captura de imágenes por activación de salidas digitales'); + expect(data.enable).to.be.true; + expect(data.port).to.eql(1); + expect(data.mode).to.eql('both'); + expect(data.times).to.eql(5); + }); + + it('should return SETPICTUREPACKET data parsed', () => { + const raw = new Buffer('Receive:\'202\'OK\r\n*000000,202,6#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.command).to.eql('SETPICTUREPACKET'); + expect(data.message).to.eql('Ajuste de cantidad de paquetes enviados por imagen'); + expect(data.number).to.eql(6); + }); + + it('should return undefined response', () => { + const raw = new Buffer('Receive:\'999\'OK\r\n*000000,999#'); + const data = tz.parse(raw); + expect(data.password).to.eql('000000'); + expect(data.device).to.eql('tz'); + expect(data.message).to.eql('Última acción'); + }); +}); diff --git a/test/test.js b/test/test.js index 41757dc..c825cfa 100644 --- a/test/test.js +++ b/test/test.js @@ -4,11 +4,61 @@ const tz = require('../src'); const expect = require('chai').expect; describe('tz-parzer', () => { + it('should return UNKNOWN data parsed', () => { + const raw = new Buffer('+RESP:GTFRI,350302,867844003012625,,12372,10,1,0,0.0,0,820.8,-70.514872,-33.361021,20160811154617,0730,0002,7410,C789,00,0.0,00000:15:30,2788,705,164,0D,00,,,20160811154651,061D$'); + const data = tz.parse(raw); + expect(data.raw).to.eql(raw.toString()); + expect(data.type).to.eql('UNKNOWN'); + }); + + it('should return TZ-AVL05 data parsed with invalid checksum', () => { + const raw = new Buffer('$$B6869444005480041|AA$GPRMC,194329.000,A,3321.6735,S,07030.7640,W,0.00,0.00,090216,,,A*6C|02.1|01.3|01.7|000000000000|20160209194326|13981188|00000000|32D3A03F|0000|0.6376|0100|995A\r\n'); + const data = tz.parse(raw); + expect(data.raw).to.eql(raw.toString()); + expect(data.device).to.eql('tz'); + expect(data.model).to.eql('TZ-AVL05'); + expect(data.type).to.eql('data'); + expect(data.imei).to.eql('869444005480041'); + expect(data.alarm.type).to.eql('Gps'); + expect(data.loc.type).to.eql('Point'); + expect(data.loc.coordinates).to.eql([-70.51273333333333, -33.361225]); + expect(data.speed).to.eql(0); + expect(data.gpsStatus).to.be.a.true; + expect(data.track).to.eql('0.00'); + expect(data.magneticVariation).to.be.null; + expect(data.gpsMode).to.eql('Autonomous'); + expect(data.pdop).to.eql(2.1); + expect(data.hdop).to.eql(1.3); + expect(data.vdop).to.eql(1.7); + expect(data.status.raw).to.eql('000000000000'); + expect(data.status.sos).to.be.false; + expect(data.status.input[1]).to.be.false; + expect(data.status.input[2]).to.be.false; + expect(data.status.input[3]).to.be.false; + expect(data.status.input[4]).to.be.false; + expect(data.status.input[5]).to.be.false; + expect(data.status.output[1]).to.be.false; + expect(data.status.output[2]).to.be.false; + expect(data.status.charge).to.be.true; + expect(data.datetime).to.eql(new Date('2016-02-09T19:43:26.000Z')); + expect(data.voltage.battery).to.eql(3.98); + expect(data.voltage.inputCharge).to.eql(11.88); + expect(data.voltage.ada).to.eql(0); + expect(data.voltage.adb).to.eql(0); + expect(data.lac).to.eql(13011); + expect(data.cid).to.eql(41023); + expect(data.temperature).to.eql(0); + expect(data.odometer).to.eql(0.6376); + expect(data.serialId).to.eql(100); + expect(data.valid).to.be.false; + }); + it('should return TZ-AVL05 data parsed', () => { const raw = new Buffer('$$B6869444005480041|AA$GPRMC,194329.000,A,3321.6735,S,07030.7640,W,0.00,0.00,090216,,,A*6C|02.1|01.3|01.7|000000000000|20160209194326|13981188|00000000|32D3A03F|0000|0.6376|0100|995F\r\n'); const data = tz.parse(raw); expect(data.raw).to.eql(raw.toString()); - expect(data.device).to.eql('TZ-AVL05'); + expect(data.device).to.eql('tz'); + expect(data.model).to.eql('TZ-AVL05'); expect(data.type).to.eql('data'); expect(data.imei).to.eql('869444005480041'); expect(data.alarm.type).to.eql('Gps'); @@ -49,7 +99,8 @@ describe('tz-parzer', () => { const raw = new Buffer('$$AE869444005480041|AA000000000000000000000000000000000000000000000000000000000000|02.1|01.3|01.7|000000000000|20160209194326|13981188|00000000|32D3A03F|0000|0.6376|0100|6CCB\r\n'); const data = tz.parse(raw); expect(data.raw).to.eql(raw.toString()); - expect(data.device).to.eql('TZ-AVL05'); + expect(data.device).to.eql('tz'); + expect(data.model).to.eql('TZ-AVL05'); expect(data.type).to.eql('data'); expect(data.imei).to.eql('869444005480041'); expect(data.alarm.type).to.eql('Gps'); @@ -80,10 +131,11 @@ describe('tz-parzer', () => { }); it('should return TZ-AVL08 data parsed', () => { - const raw = new Buffer('$$B7869444005480041|AA$GPRMC,194329.000,A,3321.6735,S,07030.7640,W,0.00,0.00,090216,,,A*6C|02.1|01.3|01.7|000000000000|20160209194326|13981188|00000000|32D3A03F|0000|0.6376|0100||56E2\r\n'); + const raw = new Buffer('$$C1869444005480041|AA$GPRMC,194329.000,A,3321.6735,S,07030.7640,W,0.00,0.00,090216,,,A*6C|02.1|01.3|01.7|000000000000|20160209194326|13981188|00000000|32D3A03F|0000|0.6376|0100|0123456789|688C\r\n'); const data = tz.parse(raw); expect(data.raw).to.eql(raw.toString()); - expect(data.device).to.eql('TZ-AVL08'); + expect(data.device).to.eql('tz'); + expect(data.model).to.eql('TZ-AVL08'); expect(data.type).to.eql('data'); expect(data.imei).to.eql('869444005480041'); expect(data.alarm.type).to.eql('Gps'); @@ -120,14 +172,15 @@ describe('tz-parzer', () => { expect(data.odometer).to.eql(0.6376); expect(data.serialId).to.eql(100); expect(data.valid).to.be.true; - expect(data.rfidNumber).to.be.null; + expect(data.rfidNumber).to.eql('0123456789'); }); it('should return TZ-AVL08 data with empty GPRMC parsed', () => { const raw = new Buffer('$$AF869444005480041|AA000000000000000000000000000000000000000000000000000000000000|02.1|01.3|01.7|000000000000|20160209194326|13981188|00000000|32D3A03F|0000|0.6376|0100||8195\r\n'); const data = tz.parse(raw); expect(data.raw).to.eql(raw.toString()); - expect(data.device).to.eql('TZ-AVL08'); + expect(data.device).to.eql('tz'); + expect(data.model).to.eql('TZ-AVL08'); expect(data.type).to.eql('data'); expect(data.imei).to.eql('869444005480041'); expect(data.alarm.type).to.eql('Gps'); @@ -161,7 +214,8 @@ describe('tz-parzer', () => { const raw = new Buffer('$$AD869444005480041|AA$GPRMC,194329.000,A,3321.6735,S,07030.7640,W,0.00,0.00,090216,,,A*6C|02.1|01.3|01.7|000000000000|20160209194326|13981188|32D3A03F|0000|0.6376|0100|5BEB\r\n'); const data = tz.parse(raw); expect(data.raw).to.eql(raw.toString()); - expect(data.device).to.eql('TZ-AVL201'); + expect(data.device).to.eql('tz'); + expect(data.model).to.eql('TZ-AVL201'); expect(data.type).to.eql('data'); expect(data.imei).to.eql('869444005480041'); expect(data.alarm.type).to.eql('Gps'); @@ -196,7 +250,8 @@ describe('tz-parzer', () => { const raw = new Buffer('$$A5869444005480041|AA000000000000000000000000000000000000000000000000000000000000|02.1|01.3|01.7|000000000000|20160209194326|13981188|32D3A03F|0000|0.6376|0100|A683\r\n'); const data = tz.parse(raw); expect(data.raw).to.eql(raw.toString()); - expect(data.device).to.eql('TZ-AVL201'); + expect(data.device).to.eql('tz'); + expect(data.model).to.eql('TZ-AVL201'); expect(data.type).to.eql('data'); expect(data.imei).to.eql('869444005480041'); expect(data.alarm.type).to.eql('Gps'); @@ -223,7 +278,7 @@ describe('tz-parzer', () => { it('should return TZ-INFO data parsed', () => { const raw = new Buffer('Lat:-3321.6664S\r\nLong:-07030.8921W\r\nSpd:000km/h\r\nFix:A\r\nSat:04\r\nHDOP:02.2\r\nGSM:29\r\nBatt:04.01V\r\nMile:0.1527\r\nTime:19/02/16 15:00:17\r\n'); const data = tz.parse(raw); - expect(data.device).to.eql('TZ-INFO'); + expect(data.device).to.eql('tz'); expect(data.type).to.eql('info'); expect(data.latitude).to.eql('-3321.6664S'); expect(data.longitude).to.eql('-07030.8921W'); @@ -237,506 +292,10 @@ describe('tz-parzer', () => { expect(data.datetime).to.eql(new Date('2016-02-19T15:00:17.000Z')); }); - it('should return TZ-COMMAND-OK SetUserPassword data parsed', () => { - const raw = new Buffer('Receive:\'001\'OK\r\n*000000,001,111111#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SetUserPassword'); - expect(data.newPassword).to.eql('111111'); - }); - - it('should return TZ-COMMAND-OK SETINTERVALOFSMS data parsed', () => { - const raw = new Buffer('Receive:\'002\'OK\r\n*000000,002,1,999#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETINTERVALOFSMS'); - expect(data.enable).to.be.true; - expect(data.interval).to.eql('1'); - expect(data.limit).to.eql('999'); - }); - - it('should return TZ-COMMAND-OK SETPHONESMSFORSOS data parsed', () => { - const raw = new Buffer('Receive:\'003\'OK\r\n*000000,003,0,1,005695487459,005695487459#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETPHONESMSFORSOS'); - expect(data.enable).to.be.true; - expect(data.callNumber).to.eql('005695487459'); - expect(data.smsNumber).to.eql('005695487459'); - }); - - it('should return TZ-COMMAND-OK SETLOWPOWERALARM data parsed', () => { - const raw = new Buffer('Receive:\'004\'OK\r\n*000000,004,380,350#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETLOWPOWERALARM'); - expect(data.lowPower).to.eql(3.8); - expect(data.autoShutdown).to.eql(3.5); - }); - - it('should return TZ-COMMAND-OK SETOVERSPEEDALARM data parsed', () => { - const raw = new Buffer('Receive:\'005\'OK\r\n*000000,005,1,100,10,360#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETOVERSPEEDALARM'); - expect(data.enable).to.be.true; - expect(data.speed).to.eql(100); - expect(data.times).to.eql(10); - expect(data.interval).to.eql(360); - }); - - it('should return TZ-COMMAND-OK SETGEOFENCEALARM data parsed', () => { - const raw = new Buffer('Receive:\'006\'OK\r\n*000000,006,-3321.6805,-07030.9513,-3321.6095,-07030.8714,1,1#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETGEOFENCEALARM'); - expect(data.enable).to.be.true; - expect(data.mode).to.eql('inside'); - expect(data.geojson.type).to.eql('Polygon'); - expect(data.geojson.coordinates).to.eql([[ - [-70.51452333333333, -33.36015833333333], - [-70.51452333333333, -33.36134166666667], - [-70.515855, -33.36134166666667], - [-70.515855, -33.36015833333333], - [-70.51452333333333, -33.36015833333333] - ]]); - }); - - it('should return TZ-COMMAND-OK SETEXTEND data parsed', () => { - const raw = new Buffer('Receive:\'008\'OK\r\n*000000,008,1000001#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETEXTEND'); - expect(data.extend).to.eql({a: true, b: false, c: false, d: false, e: false, f: false, g: true}); - }); - - it('should return TZ-COMMAND-OK SETGSMBAUD data parsed', () => { - const raw = new Buffer('Receive:\'009\'OK\r\n*000000,009,2#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETGSMBAUD'); - expect(data.band).to.eql('auto'); - }); - - it('should return TZ-COMMAND-OK SETAPN data parsed', () => { - const raw = new Buffer('Receive:\'011\'OK\r\n*000000,011,imovil.entelpcs.cl,entelpcs,entelpcs#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETAPN'); - expect(data.apn).to.eql('imovil.entelpcs.cl'); - expect(data.username).to.eql('entelpcs'); - expect(data.pass).to.eql('entelpcs'); - }); - - it('should return TZ-COMMAND-OK SETDNS data parsed', () => { - const raw = new Buffer('Receive:\'014\'OK\r\n*000000,014,1,8.8.8.8,8.8.4.4#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETDNS'); - expect(data.enable).to.be.true; - expect(data.dns1).to.eql('8.8.8.8'); - expect(data.dns2).to.eql('8.8.4.4'); - }); - - it('should return TZ-COMMAND-OK SETIPANDPORT data parsed', () => { - const raw = new Buffer('Receive:\'015\'OK\r\n*000000,015,1,server.com,1331#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETIPANDPORT'); - expect(data.host).to.eql('server.com'); - expect(data.port).to.eql(1331); - }); - - it('should return TZ-COMMAND-OK SETGPRSINTERVAL data parsed', () => { - const raw = new Buffer('Receive:\'018\'OK\r\n*000000,018,10,999#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETGPRSINTERVAL'); - expect(data.enable).to.be.true; - expect(data.interval).to.eql(10); - expect(data.limit).to.eql(999); - }); - - it('should return TZ-COMMAND-OK SETSYSSWITCH data parsed', () => { - const raw = new Buffer('Receive:\'016\'OK\r\n*000000,016,1#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETSYSSWITCH'); - expect(data.enable).to.be.true; - }); - - it('should return TZ-COMMAND-OK SETTCPSWITCH data parsed', () => { - const raw = new Buffer('Receive:\'019\'OK\r\n*000000,019,1#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETTCPSWITCH'); - expect(data.mode).to.eql('tcp'); - }); - - it('should return TZ-COMMAND-OK SETTREMBLESWITCH data parsed', () => { - const raw = new Buffer('Receive:\'021\'OK\r\n*000000,021,1,1#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETTREMBLESWITCH'); - expect(data.sleep).to.be.true; - expect(data.tremble).to.be.true; - }); - - it('should return TZ-COMMAND-OK SETSLEEPSWITCH data parsed', () => { - const raw = new Buffer('Receive:\'022\'OK\r\n*000000,022,0,0#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETSLEEPSWITCH'); - expect(data.closeGps).to.be.true; - expect(data.closeGsm).to.be.true; - }); - - it('should return TZ-COMMAND-OK SETIOSWITCH data parsed', () => { - const raw = new Buffer('Receive:\'025\'OK\r\n*000000,025,A,1#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETIOSWITCH'); - expect(data.enable).to.be.true; - expect(data.port).to.eql(1); - }); - - it('should return TZ-COMMAND-OK SETHEARTBEATSWITCH data parsed', () => { - const raw = new Buffer('Receive:\'040\'OK\r\n*000000,040,0#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETHEARTBEATSWITCH'); - expect(data.enable).to.be.false; - }); - - it('should return TZ-COMMAND-OK SETHEARTBEATINTERVAL data parsed', () => { - const raw = new Buffer('Receive:\'041\'OK\r\n*000000,041,0#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETHEARTBEATINTERVAL'); - expect(data.enable).to.be.false; - }); - - it('should return TZ-COMMAND-OK SETHEARTBEATINIT data parsed', () => { - const raw = new Buffer('Receive:\'042\'OK\r\n*000000,042#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETHEARTBEATINIT'); - }); - - it('should return TZ-COMMAND-OK SETTREMBLETOSLEEP data parsed', () => { - const raw = new Buffer('Receive:\'044\'OK\r\n*000000,044,30#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETTREMBLETOSLEEP'); - expect(data.after).to.eql(30); - }); - - it('should return TZ-COMMAND-OK SETTREMBLETOWAKEUP data parsed', () => { - const raw = new Buffer('Receive:\'043\'OK\r\n*000000,043,10#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETTREMBLETOWAKEUP'); - expect(data.after).to.eql(10); - }); - - it('should return TZ-COMMAND-OK SETPARKINGALARM data parsed', () => { - const raw = new Buffer('Receive:\'110\'OK\r\n*000000,110,0#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETPARKINGALARM'); - expect(data.enable).to.be.false; - }); - - it('should return TZ-COMMAND-OK FACTORYRESET data parsed', () => { - const raw = new Buffer('Receive:\'990\'OK\r\n*000000,990#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('FACTORYRESET'); - }); - - it('should return TZ-COMMAND-OK RBOOT data parsed', () => { - const raw = new Buffer('Receive:\'991\'OK\r\n*000000,991#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('RBOOT'); - }); - - it('should return TZ-COMMAND-OK SETOILSENSER data parsed', () => { - const raw = new Buffer('Receive:\'113\'OK\r\n*000000,113,100,500#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETOILSENSER'); - expect(data.empty).to.eql(1); - expect(data.full).to.eql(5); - }); - - it('should return TZ-COMMAND-OK SETSHUTOIL data parsed', () => { - const raw = new Buffer('Receive:\'117\'OK\r\n*000000,117,60,500,3000,5#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETSHUTOIL'); - expect(data.speed).to.eql(60); - expect(data.off).to.eql(500); - expect(data.restart).to.eql(3000); - expect(data.repeat).to.eql(5); - }); - - it('should return TZ-COMMAND-OK SETSHUTOILSWITCH data parsed', () => { - const raw = new Buffer('Receive:\'116\'OK\r\n*000000,116,0#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETSHUTOILSWITCH'); - expect(data.enable).to.be.false; - }); - - it('should return TZ-COMMAND-OK SETCALLA data parsed', () => { - const raw = new Buffer('Receive:\'103\'OK\r\n*000000,103,0,005695487459#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETCALLA'); - expect(data.mode).to.eql('gprs'); - expect(data.number).to.eql('005695487459'); - }); - - it('should return TZ-COMMAND-OK SETEXTEND2 data parsed', () => { - const raw = new Buffer('Receive:\'118\'OK\r\n*000000,118,10000001#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETEXTEND2'); - expect(data.extend).to.eql({a: true, b: false, c: false, d: false, e: false, f: false, g: false, h: true}); - }); - - it('should return TZ-COMMAND-OK SETPIN data parsed', () => { - const raw = new Buffer('Receive:\'122\'OK\r\n*000000,122,0,1234#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETPIN'); - expect(data.enable).to.be.false; - expect(data.pin).to.eql('1234'); - }); - - it('should return TZ-COMMAND-OK SETANGLE data parsed', () => { - const raw = new Buffer('Receive:\'300\'OK\r\n*000000,300,0,360#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETANGLE'); - expect(data.enable).to.be.false; - expect(data.angle).to.eql(360); - }); - - it('should return TZ-COMMAND-OK SETANGLE data parsed', () => { - const raw = new Buffer('Receive:\'400\'OK\r\n*000000,400,0,360#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETANGLE'); - expect(data.enable).to.be.false; - expect(data.angle).to.eql(360); - }); - - it('should return TZ-COMMAND-OK SETREBOOT data parsed', () => { - const raw = new Buffer('Receive:\'600\'OK\r\n*000000,600,0,30#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETREBOOT'); - expect(data.enable).to.be.false; - expect(data.interval).to.eql(30); - }); - - it('should return TZ-COMMAND-OK SETACCALARM data parsed', () => { - const raw = new Buffer('Receive:\'120\'OK\r\n*000000,120,0,30,30#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETACCALARM'); - expect(data.enable).to.be.false; - expect(data.acceleration).to.eql(30); - expect(data.deceleration).to.eql(30); - }); - - it('should return TZ-COMMAND-OK SETROAMING data parsed', () => { - const raw = new Buffer('Receive:\'121\'OK\r\n*000000,121,0,30,210#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETROAMING'); - expect(data.enable).to.be.false; - expect(data.interval).to.eql(30); - expect(data.network).to.eql('210'); - }); - - it('should return TZ-COMMAND-OK SETACKSTATE data parsed', () => { - const raw = new Buffer('Receive:\'123\'OK\r\n*000000,123,0#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETACKSTATE'); - expect(data.enable).to.be.false; - }); - - it('should return TZ-COMMAND-OK SETCALLFILTER data parsed', () => { - const raw = new Buffer('Receive:\'130\'OK\r\n*000000,130,0,0#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETCALLFILTER'); - expect(data.enable).to.be.false; - expect(data.caller).to.eql('0'); - }); - - it('should return TZ-COMMAND-OK SETSENDTYPE data parsed', () => { - const raw = new Buffer('Receive:\'119\'OK\r\n*000000,119,0#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETSENDTYPE'); - expect(data.mode).to.eql('gprs'); - }); - - it('should return TZ-COMMAND-OK SETPICTUREINTERVAL data parsed', () => { - const raw = new Buffer('Receive:\'200\'OK\r\n*000000,200,10,999#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETPICTUREINTERVAL'); - expect(data.interval).to.eql(10); - expect(data.times).to.eql(999); - }); - - it('should return TZ-COMMAND-OK CLEARBUF data parsed', () => { - const raw = new Buffer('Receive:\'500\'OK\r\n*000000,500#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('CLEARBUF'); - }); - - it('should return TZ-COMMAND-OK GETPICTURE data parsed', () => { - const raw = new Buffer('Receive:\'210\'OK\r\n*000000,210#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('GETPICTURE'); - }); - - it('should return TZ-COMMAND-OK SETDATAFLASH data parsed', () => { - const raw = new Buffer('Receive:\'601\'OK\r\n*000000,601,1#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETDATAFLASH'); - expect(data.enable).to.be.true; - }); - - it('should return TZ-COMMAND-OK SETTRACKINGINTERVAL data parsed', () => { - const raw = new Buffer('Receive:\'156\'OK\r\n*000000,156,0,30,30#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETTRACKINGINTERVAL'); - expect(data.enable).to.be.false; - expect(data.intervalOn).to.eql(30); - expect(data.intervalOff).to.eql(30); - }); - - it('should return TZ-COMMAND-OK SETSENDODOMETER data parsed', () => { - const raw = new Buffer('Receive:\'151\'OK\r\n*000000,151,0,100#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETSENDODOMETER'); - expect(data.enable).to.be.false; - expect(data.range).to.eql(100); - }); - - it('should return TZ-COMMAND-OK SETIMEI data parsed', () => { - const raw = new Buffer('Receive:\'155\'OK\r\n*000000,155,0,000000000000000#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETIMEI'); - expect(data.enable).to.be.false; - expect(data.newImei).to.eql('000000000000000'); - }); - - it('should return TZ-COMMAND-OK SETIDLE data parsed', () => { - const raw = new Buffer('Receive:\'404\'OK\r\n*000000,404,0,30#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETIDLE'); - expect(data.enable).to.be.false; - expect(data.interval).to.eql(30); - }); - - it('should return TZ-COMMAND-OK SETINTERVALGPRSSTANDBY data parsed', () => { - const raw = new Buffer('Receive:\'023\'OK\r\n*000000,023,0,30#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETINTERVALGPRSSTANDBY'); - expect(data.enable).to.be.false; - expect(data.interval).to.eql(30); - }); - - it('should return TZ-COMMAND-OK SETIOPICTURE data parsed', () => { - const raw = new Buffer('Receive:\'201\'OK\r\n*000000,201,3,3,5#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETIOPICTURE'); - expect(data.enable).to.be.true; - expect(data.port).to.eql(2); - expect(data.mode).to.eql('both'); - expect(data.times).to.eql(5); - }); - - it('should return TZ-COMMAND-OK SETPICTUREPACKET data parsed', () => { - const raw = new Buffer('Receive:\'202\'OK\r\n*000000,202,6#'); - const data = tz.parse(raw); - expect(data.password).to.eql('000000'); - expect(data.device).to.eql('TZ-COMMAND-OK'); - expect(data.command).to.eql('SETPICTUREPACKET'); - expect(data.number).to.eql(6); - }); - it('should return TZ-FIRMWARE data parsed', () => { const raw = new Buffer('IMEI:869444005480041\r\nVER:TC_AVL05vSST_JOSE10.12\r\nGSMVER:1116B02SIM840WL_MXIC\r\n'); const data = tz.parse(raw); - expect(data.device).to.eql('TZ-FIRMWARE'); + expect(data.device).to.eql('tz'); expect(data.type).to.eql('firmware'); expect(data.imei).to.eql('869444005480041'); expect(data.firmware).to.eql('TC_AVL05vSST_JOSE10.12'); @@ -746,7 +305,7 @@ describe('tz-parzer', () => { it('should return TZ-MAP data parsed', () => { const raw = new Buffer('http://maps.google.com/maps?f=q&hl=en&q=-33.361106,-070.514868&ie=UTF8&z=16&iwloc=addr&om=1'); const data = tz.parse(raw); - expect(data.device).to.eql('TZ-MAP'); + expect(data.device).to.eql('tz'); expect(data.type).to.eql('map_link'); expect(data.url).to.eql('http://maps.google.com/maps?f=q&hl=en&q=-33.361106,-070.514868&ie=UTF8&z=16&iwloc=addr&om=1'); expect(data.latitude).to.eql(-33.361106); @@ -756,7 +315,7 @@ describe('tz-parzer', () => { it('should return TZ-ERROR data parsed', () => { const raw = new Buffer('Receive:Set Err\r\n*000000,999,9999#'); const data = tz.parse(raw); - expect(data.device).to.eql('TZ-ERROR'); + expect(data.device).to.eql('tz'); expect(data.type).to.eql('error'); expect(data.command).to.eql('Receive:Set Err\r\n*000000,999,9999#'); }); @@ -764,7 +323,7 @@ describe('tz-parzer', () => { it('should return TZ-IMAGE data parsed', () => { const raw = new Buffer('$U35977203928389100001071001FFD8FFDB008400100B0C0E0C0A100E0D0E1211101318281A181616183123251D283A333D3C3933383740485C4E404457453738506D51575F626768673E4D71797064785C656763011112121815182F1A1A2F634238426363636363636363636363636363#'); const data = tz.parse(raw); - expect(data.device).to.eql('TZ-IMAGE'); + expect(data.device).to.eql('tz'); expect(data.type).to.eql('image'); expect(data.imei).to.eql('359772039283891'); expect(data.number).to.eql(1); @@ -798,6 +357,14 @@ describe('tz-parzer', () => { expect(raw).to.eql('*000000,025,A,1#'); }); + it('should return raw command di 1 off', () => { + const data = { + instruction: '1_off' + }; + const raw = tz.parseCommand(data); + expect(raw).to.eql('*000000,025,A,0#'); + }); + it('should return raw command gprs on', () => { const data = { instruction: 'gprs_on' @@ -806,6 +373,14 @@ describe('tz-parzer', () => { expect(raw).to.eql('*000000,016,1#'); }); + it('should return raw command gprs off', () => { + const data = { + instruction: 'gprs_off' + }; + const raw = tz.parseCommand(data); + expect(raw).to.eql('*000000,016,0#'); + }); + it('should return raw command clear internal memory', () => { const data = { instruction: 'clear_mem' @@ -832,6 +407,15 @@ describe('tz-parzer', () => { expect(raw).to.eql('*000000,003,0,0,0056992052518,0056992052518#'); }); + it('should return raw command set on sos number', () => { + const data = { + instruction: 'set_sos_number', + number: 92052518 + }; + const raw = tz.parseCommand(data); + expect(raw).to.eql('*000000,003,0,1,0056992052518,0056992052518#'); + }); + it('should return raw command set on speed', () => { const data = { instruction: 'set_speed_on', @@ -841,6 +425,22 @@ describe('tz-parzer', () => { expect(raw).to.eql('*000000,005,1,120,10,60#'); }); + it('should return raw command set on speed', () => { + const data = { + instruction: 'set_speed_on' + }; + const raw = tz.parseCommand(data); + expect(raw).to.eql('*000000,005,1,100,10,60#'); + }); + + it('should return raw command set off speed', () => { + const data = { + instruction: 'set_speed_off' + }; + const raw = tz.parseCommand(data); + expect(raw).to.eql('*000000,005,0,100,10,60#'); + }); + it('should return raw command set time taking pictures', () => { const data = { instruction: 'picture' @@ -875,6 +475,14 @@ describe('tz-parzer', () => { expect(raw).to.eql('*000000,601,1#'); }); + it('should return raw command set memory on', () => { + const data = { + instruction: 'set_memory_off' + }; + const raw = tz.parseCommand(data); + expect(raw).to.eql('*000000,601,0#'); + }); + it('should return raw command set sleep and tremble', () => { const data = { instruction: 'set_tremble', @@ -885,6 +493,16 @@ describe('tz-parzer', () => { expect(raw).to.eql('*000000,021,1,1#'); }); + it('should return raw command set sleep and tremble', () => { + const data = { + instruction: 'set_tremble', + sleep: false, + tremble: false + }; + const raw = tz.parseCommand(data); + expect(raw).to.eql('*000000,021,0,0#'); + }); + it('should return raw command set into sleep', () => { const data = { instruction: 'set_into_sleep', @@ -914,10 +532,33 @@ describe('tz-parzer', () => { it('should return raw command extend', () => { const data = { instruction: 'set_extend', - a: true + a: true, + b: true, + c: true, + d: true, + e: true, + f: true, + g: true, + h: true + }; + const raw = tz.parseCommand(data); + expect(raw).to.eql('*000000,118,11111111#'); + }); + + it('should return raw command extend', () => { + const data = { + instruction: 'set_extend', + a: false, + b: false, + c: false, + d: false, + e: false, + f: false, + g: false, + h: false }; const raw = tz.parseCommand(data); - expect(raw).to.eql('*000000,118,10000000#'); + expect(raw).to.eql('*000000,118,00000000#'); }); it('should return raw command set heartbeat on', () => { @@ -928,6 +569,14 @@ describe('tz-parzer', () => { expect(raw).to.eql('*000000,040,1#'); }); + it('should return raw command set heartbeat off', () => { + const data = { + instruction: 'set_heartbeat_off' + }; + const raw = tz.parseCommand(data); + expect(raw).to.eql('*000000,040,0#'); + }); + it('should return raw command set interval heartbeat', () => { const data = { instruction: 'set_interval_heartbeat', @@ -946,6 +595,30 @@ describe('tz-parzer', () => { expect(raw).to.eql('*000000,404,1,300#'); }); + it('should return raw command set off idling alarm', () => { + const data = { + instruction: 'set_idling_off', + times: 300 + }; + const raw = tz.parseCommand(data); + expect(raw).to.eql('*000000,404,0,300#'); + }); + + it('should return raw custom command', () => { + const data = { + instruction: 'Custom', + command: '*000000,991#' + }; + const raw = tz.parseCommand(data); + expect(raw).to.eql('*000000,991#'); + }); + + it('should return raw null command', () => { + const data = {instruction: 'asdf'}; + const raw = tz.parseCommand(data); + expect(raw).to.be.null; + }); + it('should return raw command reboot', () => { const raw = tz.getRebootCommand(); expect(raw).to.eql('*000000,991#');