<commit_before>var MessagePosition = ('./Message');

TK104 = function() {
  // do something, define constants
  this.command = {
    /* Incoming commands */
    LOGIN			: 'A',
    HEARTBEAT			: 'HEARTBEAT',
    AUTOMATIC_EVENT_REPORT	: 'AUTOMATIC_EVENT_REPORT',  // The most common reply by tracker device
    
    /* Outgoing commands */
    REAL_TIME_LOCATION_QUERY	: 'B',
    
    SET_HEARTBEAT_INTERVAL	: null,
    SET_TRACK_BY_TIME_INTERVAL	: 'C',
    SET_TRACK_BY_DISTANCE	: null,
  };
  
  this.event = {
    ALARM_SOS			: 'help me',
    ALARM_LOW_BATTERY		: 'low battery',
    ALARM_LOW_BATTERY_EXTERNAL	: null,
    
    STATUS_GPS_SIGNAL_LOSE	: null,
    STATUS_GPS_SIGNAL_RECOVERY	: null,
    STATUS_ENTER_SLEEP		: null,
    STATUS_EXIT_SLEEP		: null,
    STATUS_POWER_ON		: 'STATUS_POWER_ON',
    
    REPORT_HEARTBEAT		: 'REPORT_HEARTBEAT',
    REPORT_DIRECTION_CHANGE	: null,
    REPORT_BY_DISTANCE		: null,
    REPORT_REAL_TIME_LOCATION_QUERY	: null,
    REPORT_BY_TIME_INTERVAL	: 'tracker'
  };
  
  this.EOL = ';';
}

TK104.prototype.getCommandByCode = function(code) {
  for (var key in this.command) {
		if (this.command[key] === code) {
			return key;
		}
	}
	return 'UNKNOWN_COMMAND';    
}
  
TK104.prototype.getEventByCode = function(code) {
  for (var key in this.event) {
		if (this.event[key] === code) {
			return key;
		}
	}
	return 'UNKNOWN_EVENT';
}

/**
 * parse Message
 * @param {string} message
 */
TK104.prototype.parseMessage = function( msg ) {
  
  /* Heartbeat message (only imei is send) */
  if (msg.indexOf(',') === -1) {
  	return new Message({
  		raw:	msg,
  		imei:	msg,
  		command: this.HEARTBEAT,
  		event: this.REPORT_HEARTBEAT,
  		data: null
  	});
  }
  
  var parts = msg.split(',');
  
  /* Logon message */
  if (parts && parts[0] && parts[0] === '##') {
  	return new Message({
  		raw:	msg,
  		imei:	(/imei\:([0-9]*)/).exec(msg)[1],
  		command: this.LOGIN,
  		event:	this.STATUS_POWER_ON,
  		data:	null
  	});
  }
  
  /* Parse message */
  if (parts && parts[0] && parts[1]) {
	return new Message({
		raw:	msg,
  		imei:	(/imei\:([0-9]*)/).exec(msg)[1],
  		command: this.AUTOMATIC_EVENT_REPORT,
  		event:	this.getEventByCode( parts[1] ),
  		data:	msg
	});  	
  }
}

/**
 * parse position from Message.data
 * @param {message.data} data
 */
TK104.prototype.parsePosition = funtion( data ) {
  
  return new Position();
}

TK104.prototype.prepare = function(imei, cmd, data) {
  
  return new Message();
}
module.exports = TK104;
<commit_msg>First release<commit_after>"use strict";

var Message  = require('./Message').Message,
    Position = require('./Message').Position;


function Protocol() {

  // do something, define constants
  this.COMMAND = {
    /* Incoming commands */
    REQ_LOGIN				: 'LOGIN_REQUEST',
    REQ_HEARTBEAT			: 'HEARTBEAT_REQUEST',
    AUTOMATIC_EVENT_REPORT	: 'AUTOMATIC_EVENT_REPORT',  // The most common reply by tracker device
    
    /* Outgoing commands */
    RES_LOGIN				: 'LOAD',
    RES_HEARTBEAT			: 'ON',
	
    REAL_TIME_LOCATION_QUERY	: 'B',		// **,imei:359586018966098,B
    
    SET_HEARTBEAT_INTERVAL		: null, 	// not available for TK104
    SET_TRACK_BY_TIME_INTERVAL	: 'C',		// **,imei:359586018966098,C,10[s|m|h]
	
	SET_SMS_MODE				: 'N'		// **,imei:359586018966098,N
  };
  
  this.EVENT = {
    ALARM_SOS					: 'help me',
    ALARM_LOW_BATTERY			: 'low battery',
    
    STATUS_GPS_SIGNAL_LOSE		: null,
    STATUS_GPS_SIGNAL_RECOVERY	: null,
    STATUS_ENTER_SLEEP			: null,
    STATUS_EXIT_SLEEP			: null,
    STATUS_POWER_ON				: 'STATUS_POWER_ON',
    
    REPORT_HEARTBEAT			: 'REPORT_HEARTBEAT',
    REPORT_DIRECTION_CHANGE		: null,
    REPORT_BY_DISTANCE			: null,
    REPORT_REAL_TIME_LOCATION_QUERY	: null,
    REPORT_BY_TIME_INTERVAL		: 'tracker'
  };
  
  this.EOL = ';';
}

Protocol.prototype.getCommandByCode = function(code) {
  for (var key in this.COMMAND) {
		if (this.COMMAND[key] === code) {
			return key;
		}
	}
	return 'UNKNOWN_COMMAND';    
}
  
Protocol.prototype.getEventByCode = function(code) {
  for (var key in this.EVENT) {
		if (this.EVENT[key] === code) {
			return key;
		}
	}
	return 'UNKNOWN_EVENT';
}

/**
 * parse Message
 * @param {string} message
 */
Protocol.prototype.parseMessage = function( msg ) {
  
  /* Heartbeat message only (only imei is send), imei should by > 5 (~15) */
  if (msg.indexOf(',') === -1 && (/([0-9]*)/).exec(msg)[1]) {
	return new Message({
  		raw:	msg,
  		imei:	(/([0-9]*)/).exec(msg)[1],
  		command: this.COMMAND.REQ_HEARTBEAT,
		commandText: this.getCommandByCode( this.COMMAND.REQ_HEARTBEAT ),
  		event: this.EVENT.REPORT_HEARTBEAT,
		eventText: this.getEventByCode( this.EVENT.REPORT_HEARTBEAT ),
  		data: null
  	});
  }
  
  var parts = msg.split(',');

  /* Logon message */
  if (parts && parts[0] && parts[0] === '##') {
  	
	return new Message({
  		raw:	msg,
  		imei:	(/imei\:([0-9]*)/).exec(msg)[1],
  		command: this.COMMAND.REQ_LOGIN,
		commandText: this.getCommandByCode( this.COMMAND.REQ_LOGIN ),
  		event:	this.EVENT.STATUS_POWER_ON,
		eventText:	this.getEventByCode( this.EVENT.STATUS_POWER_ON) ,
  		data:	null
  	});
  }
  
  /* Heartbeat message + other message  */
  /*	TODO handle one after the other */
  
  
  /* Parse message */
  if (parts && parts[0] && parts[1]) {
	return new Message({
		raw:	msg,
  		imei:	(/imei\:([0-9]*)/).exec(msg)[1],
  		command: this.COMMAND.AUTOMATIC_EVENT_REPORT,
		commandText: this.getCommandByCode( this.COMMAND.AUTOMATIC_EVENT_REPORT ),
		event:	parts[1].toString(),
  		eventText:	this.getEventByCode( parts[1].toString() ),
  		data:	msg
	});  	
  }
}

/**
 * parse position from Message.data
 * @param {message.data} data
 */
Protocol.prototype.parsePosition = function( data ) {

  var parts = data.split(",");
  
  return new Position({
	raw:	data,          				  // full GPS location message as received from GPS tracker
	lat:	fixGeo(parts[7], parts[8]),   // GPS latitude in Degree
	lng:	fixGeo(parts[9], parts[10]),  // GPS longitude in Degree
	date:	new Date(
			  parseInt("20" + parts[2].substr(0, 2), 10), 
              parseInt(parts[2].substr(2,2),10) - 1, 
              parseInt(parts[2].substr(4,2),10),
              parseInt(parts[2].substr(6,2),10),
              parseInt(parts[2].substr(8,2),10),
              parseInt(parts[2].substr(10,2),10)),   // GPS datetime
	fix:	(parts[4] == 'F') ? true : false,         // GPS fix valid or not
	speed:	{
            'knots': Math.round(parts[11] * 1000) / 1000,
            'kmh':   Math.round(parts[11] * 1.852 * 1000) / 1000,
            'mph':   Math.round(parts[11] * 1.151 * 1000) / 1000
			},
	imei:	parts[0].split(":")[1],           // GPS tracker IMEI
	eventText:	this.getEventByCode( parts[1].toString() )
	});
}

Protocol.prototype.prepare = function(imei, cmd, data) {
  
  if (cmd == this.COMMAND.RES_LOGIN) {
	// LOAD
	return new Message({
		raw: cmd,
		imei: imei,
		command: cmd,
		commandText: this.getCommandByCode( cmd ),
		event:	null,
		eventText: null,
		data:	data
		});
  }
  
  if (cmd == this.COMMAND.RES_HEARTBEAT) {
	// ON
	return new Message({
		raw: cmd,
		imei: imei,
		command: cmd,
		commandText: this.getCommandByCode( cmd ),
		event:	null,
		eventText: null,
		data:	data
		});
  }
  
  if (cmd == this.COMMAND.SET_HEARTBEAT_INTERVAL) {
	return null;
  }
  
  if (cmd == this.COMMAND.SET_TRACK_BY_TIME_INTERVAL) {
	// **,imei:359586018966098,C,10[s|m|h]
	return new Message({
		raw: '**,imei:' + imei + ',' + cmd + ',' + data.interval + 's',
		imei: imei,
		command: cmd,
		commandText: this.getCommandByCode( cmd ),
		event:	null,
		eventText: null,
		data:	data
		});
  }
  
  if (cmd == this.COMMAND.REAL_TIME_LOCATION_QUERY) {
	// **,imei:359586018966098,B
	return new Message({
		raw: '**,imei:' + imei + ',' + cmd,
		imei: imei,
		command: cmd,
		commandText: this.getCommandByCode( cmd ),
		event:	null,
		eventText: null,
		data:	data
		});
  }
  
  if (cmd == this.COMMAND.SET_GSM_MODE) {
	// **,imei:359586018966098,N
	return new Message({
		raw: '**,imei:' + imei + ',' + cmd,
		imei: imei,
		command: cmd,		
		commandText: this.getCommandByCode( cmd ),
		event:	null,
		eventText: null,
		data:	data
		});
  }

  return null;
}

Protocol.prototype.send = function(clientconn, msg) {
	clientconn.write( new Buffer(msg.raw) );
}

module.exports = Protocol;

/*
 * from tk10x format to decimal
 */
var fixGeo = function(number, letter) {
  var minutes = number.substr(-7, 7);
  var degrees = parseInt(number.replace (minutes, ''), 10);
  var number = degrees + (minutes / 60);
  var number = parseFloat((letter === 'S' || letter === 'W' ? '-' : '') + number);
  return Math.round(number * 1000000) / 1000000;
};

{'fraction_non_alphanumeric': 0.15692378646373803, 'fraction_numerical': 0.02940159114493255, 'mean_word_length': 2.977074736359468, 'pattern_counts': {'":': 1, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7019203', 'n_tokens_mistral': 3689, 'n_tokens_neox': 3452, 'n_words': 660}