flaglib
Version:
Ignition event 15 added.
1,346 lines (1,083 loc) • 42.8 kB
JavaScript
var util = require('util');
var PickUpPoint = require('./pickuppoint.js');
var Util = require('./util.js');
var Flag = require('./flag.js');
var LatLon = require('./LatLon.js');
var ActiveGroupUser = require('./groupuser.js');
var FlagCategories = require('./flagcategories.js');
var FlagConstants = require('./flagconstants.js');
var UserCommands = require('./usercommands.js');
var IndividualDeviceLogger = require('./IndividualDeviceLogger');
var logger = require('./logger');
//var Helper = require("../tables/helper.js").Helper;
//var pushHandler = require('./push');
module.exports = ActiveGroup;
var PID = "0";
var GID = "1";
var PNAME = "2";
//var DRIVER = "4";
var PPOINTS = "3";
var PU_START_TIME = "4"; //PU = pickUP
var PU_STOP_TIME = "5";
var DP_START_TIME = "6"; //DP = Drop
var DP_STOP_TIME = "7";
var STYPE = "8";
var SID = "9";
var PPACKAGE = "10"; //profile package
var SPEED_CUTOFF = "11";
var SPEED_CUTOFF_ALERTED = "12";
var GROUP_NAME = "13";
var RFID = "14";
var LPOINT = "15"; //location lat, long
var LID = "16";
var DID = "17"; //device id
var SMS = "18";
var ANDROID = "19";
var IOS = "20";
var WAIT = "21";
var PRVDIST = "22";
var PRVTIME = "23";
var ORDER_UPDATED = "24";
var STATUS_UPDATED = "25"; // it is final status
var TRIP_STATUS = "26"; // record trip ended if the vehicle is reached the location, even session is not ended. ones updated, don;t update again and again.
var LOC_REACH_TIME = "27";
var PROFILE_STATUS = "28";
var VID = "29";
var LAST_POINT_INDEX = "30";
var PROFILE_TYPE = "31";
var PRVPOINT = "32"; //previous lat, long
var TOTALDIST = "33"; //previous lat, long
var PREV_UPDATE_TIME = "34"; //previous lat, long
var MIN_DIST_LOCATION = 0.300;//If the vehcile reached the location with minimum distance, it recoed as trip ended. otherwise it record 5 min before trip end time.
var MIN_TIME_GAP = 10*60; //10 minutes before end record, records trip ended.
var MIN_TIME_GAP_START = 300; //5 minutes after start record, trip started, 5 min before end, records trip ended.
var MIN_START_GAP_TO_END = 30*60;// 30 min
var MIN_START_DISTANCE_MOVE_TO_END = 500;// 500 m
var MIN_DIST_MOVE = 200; //200m
var TRIP_SCHEDULED = 0; // initial value
var TRIP_STARTED = 1;//after 5 min of trip start
var TRIP_ENDED = 2;//before 5 min of trip end
var TRIP_ONGOING = 3;//ONGOIING TO RECORD INTERMEDIATE STATUS
var PROFILE_ACTIVE = 1;
var PROFILE_INACTIVE = 0;
var SESSION_TYPE;
//var __me = this;
var utility = new Util();
/*
* This function is a constructor.
* input: profile id and group id.
*/
function ActiveGroup() {
this.profileId = null;
this.locationId = null;
this.groupId = null;
this.vehicleId = null;
this.profileName = null;
this.profile_pacakge = null;
this.PickUpPoints = [];
this.invalid = false;
//this.driver = null;
this.pickUpStartTime = 0;
this.pickUpStopTime = 0;
this.dropStartTime = 0;
this.dropStopTime = 0;
this.sessionType = -1;
this.sessionId = -1;
this.alertArray = []
this.cutoff_alerted = false;
this.groupName = "";
this.speed_cutoff = 500;//not to alert by default, solarge vale is fine.
//rfid = 0 means no RFID, =1 means RFID enabled.
this.rfid = 0;
this.lpoint = null;
this.deviceId = 0;
this.sms = 1; //default value = ALWAYS (send sms anyway)
this.android = "http://bit.ly/2gB1EWx"; //ELLII-TRACKER default android app link
this.ios = "http://bit.ly/2iZjfLa";//ELLII-TRACKER default ios app link
this.wait = 0;
this.prvDist = 0;
this.prvTime = "";
this.orderUpdated = false;
this.statusUpdated = false;
this.tripStatus = TRIP_SCHEDULED;
this.locationReachedTime = -1;
this.profileStatus = 0;
this.lastpointIndex = -1
this.profileType = 1; // BY defaulr consider as CORPORATE
this.prvPoint = null;
this.totalDistance = 0;
this.prvUpdateTime = 0;
//construct();
//logger.info("ActiveGroup const called: "+ this.profileId+ " "+this.groupId);
}
/*
* This function construct the active group by reading the appropriate tables.
*
*/
ActiveGroup.prototype.construct = function(sesionType1, req, groupData, allPickupPoints, callback) {
logger.info("ActiveGroup construct start profile id : "+groupData.profile_id+"group data: "+groupData.group_id);
this.sessionType = sesionType1;
this.vehicleId = groupData.vehicle_id;
this.groupId = groupData.group_id;
this.profileId = groupData.profile_id;
this.pickUpStartTime = groupData.pickup_start_time;
this.pickUpStopTime = groupData.pickup_stop_time;
this.dropStartTime = groupData.drop_start_time;
this.dropStopTime = groupData.drop_stop_time;
this.profileName = groupData.profile_name;
this.profile_pacakge = groupData.profile_package;
this.sms = groupData.sms;
this.android = groupData.android;
this.ios = groupData.ios;
this.PickUpPoints = null;
this.rfid = groupData.rfid;
this.tripStatus = TRIP_SCHEDULED;
this.profileStatus = groupData.profile_status;
this.profileType = groupData.profile_type;
logger.info("ActiveGroup construct this.pickUpStartTime : "+this.pickUpStartTime);
logger.info("ActiveGroup construct this.pickUpStopTime : "+this.pickUpStopTime);
this.speed_cutoff = groupData.speed_cutoff_limit;
this.groupName = "";
if ((allPickupPoints != null) && (allPickupPoints.length>0)){
this.groupName = allPickupPoints[0].group_name;
this.lpoint = new LatLon(allPickupPoints[0].llat,allPickupPoints[0].llon, this.profileName);
}
//this.profileName = "Vehicle";
this.buildGroup(allPickupPoints);
/**
groupData = {
group_id: 1
profile_id: 2
group_sesion_id: 3,
start_time
stop_time
session_type: pickup/drop
}
allPickupPoints = {
pickup_point_id
user_mobile_number
alert_before
userArn
platform
};
*/
if (callback!=null){
setTimeout(function(){ callback(); }, 5000);
}
};
ActiveGroup.prototype.getSessionType = function(){
return this.sessionType;
}
ActiveGroup.prototype.buildGroup = function(result){
var size = result.length;
logger.info("ActiveGroup construct buildGroup start: size: "+size);
if (this.PickUpPoints == null){
this.PickUpPoints = [];
}
for (var i = 0; i<size; i++){
this.locationId = result[i].location_id;
//check pickup
var index = this.getPickupPointIndex(result[i].pickup_point_id);
var pp = null;
if (index == -1){
pp = new PickUpPoint(result[i].pickup_point_id,result[i].porder,result[i].location_lat,result[i].location_long, result[i].pickup_point_title);
if (this.PickUpPoints == null){
this.PickUpPoints = [];
}
this.PickUpPoints.push(pp);
}else{
pp = this.PickUpPoints[index];
}
var temp = pp.hasUser(result[i].user_mobile_number);
var gp = null;
if (temp == null){
gp = new ActiveGroupUser();
}else{
gp = temp;
logger.info("user already exist: " +gp.getUserID());
}
if (gp == null){
continue;
}
/*
* Add condition to check, if the user has same packge if the uset is app installed user.
* If different package, ignore the user.
*/
if (result[i].package !=null){
if (result[i].package != result[i].profile_package){
//continue;
//make it uninstalled user rather completely stopping it.
result[i].userArn = null;
}
}
if (this.sessionType == "P"){
gp.updateUser(result[i].user_mobile_number,result[i].userArn,
result[i].alert_before, result[i].platform,result[i].alert_lat,result[i].alert_lon,
result[i].alert_on_return,result[i].alert_course,result[i].alert_adjust, result[i].student_name, result[i].rfid_card_number,result[i].swipe_rfid);
}else{
gp.updateUser(result[i].user_mobile_number,result[i].userArn,
result[i].alert_before, result[i].platform,result[i].drop_alert_lat,result[i].drop_alert_lon,
result[i].drop_alert_on_return,result[i].drop_alert_course,result[i].drop_alert_adjust,result[i].student_name, result[i].rfid_card_number,result[i].swipe_rfid);
}
pp.addUser(gp);
}
//__me.PickUpPoints = this.PickUpPoints;
logger.info("======== buildGroup last line Pickup points length ::", this.PickUpPoints.length);
}
/*
* Ones route is traversed, store the order of the points it is traversed.
* How to know, route is travelled?
* 1. if all are picked
* route is done
* 2. if time is < 10 min to end session end time
* route is done
*
*/
ActiveGroup.prototype.isAllPicked = function(ign_status,flagData){
var status = true;
var size = 0;
//if already updated, dont update again.
//if return true, it will update, so return false
if (this.orderUpdated){
return false;
}
if(this.PickUpPoints != null){
size = this.PickUpPoints.length;
}
logger.info("isAllPicked: checking length:"+size);
for (var i = 0; i<size; i++){
logger.info("isAllPicked: checking:"+this.PickUpPoints[i].getPicked() );
if (this.PickUpPoints[i].getPicked() == false){
status = false;
break;
}
}
if (!status){
var flag = new Flag(flagData);
var latlng = new LatLon(flag.getFlagValue(FlagConstants.FLAG_LATITUDE),flag.getFlagValue(FlagConstants.FLAG_LONGITUDE),"");
var dist = latlng.checkDistance(this.lpoint);
var timestamp = flag.getFlagValue(FlagConstants.FLAG_DEVICE_TIME_STAMP);
var time = convertStringToSeconds(timestamp);
var diffTime = 200;
console.log("is ALL Picked:time: "+time);
console.log("is ALL Picked:this.pickUpStopTime: "+this.pickUpStopTime);
console.log("is ALL Picked:this.dropStopTime: "+this.dropStopTime);
console.log("is ALL Picked:this.this.sessionType: "+this.sessionType);
if (this.sessionType == "P"){
diffTime = convertStringToSeconds_(this.pickUpStopTime)-time;
if (diffTime < 0){
diffTime = diffTime * -1;
}
}
if (this.sessionType == "D"){
console.log("is ALL Picked:this.this.sessionType: "+convertStringToSeconds_(this.dropStopTime));
diffTime = convertStringToSeconds_(this.dropStopTime)-time;
if (diffTime < 0){
diffTime = diffTime * -1;
}
}
console.log("is ALL Picked:this.diffTime: "+diffTime);
if ((dist <=0.150) && ( diffTime <=(15*60)) ){
logger.info("isAllPicked: returning true" );
//this.orderUpdated = true;
status = true;
}else{
status = false;
}
}//if (!status)
return status;
}
ActiveGroup.prototype.getLastPointIndex = function(){
if (this.lastpointIndex != -1){
return this.lastpointIndex;
}
var size = 0;
if(this.PickUpPoints != null){
size = this.PickUpPoints.length;
}
var index = -1;
var dist1 = 0;
for (var i = 0; i<size; i++){
var point = new LatLon(this.PickUpPoints[i].getLat(),this.PickUpPoints[i].getLon(), "");
var dist = point.checkDistance(this.lpoint);
if (dist>dist1){
index = i;
dist1 = dist;
}
}
this.lastpointIndex = index;
console.log("********************************this.lastpointIndex: "+this.lastpointIndex);
return index;
}
var convertStringToSeconds = function(date){
if( (date == undefined) || (date == "") ){
return 0;
}
var seconds = parseInt(date.substring(6, 8),10)*60*60+parseInt(date.substring(8, 10),10)*60+parseInt(date.substring(10, 12),10);
return seconds;
}
var convertStringToSeconds_ = function(time){
if( (time == undefined) || (time == "") ){
return 0;
}
var parts = time.split(":");
console.log("convertStringToSeconds_"+parts);
var seconds = parseInt(parts[0],10)*60*60+parseInt(parts[1],10)*60+parseInt(parts[2],10);
console.log("convertStringToSeconds_"+seconds);
return seconds;
}
var sortfunction = function (a, b){
//Compare "a" and "b" in some fashion, and return -1, 0, or 1
var v1 = convertStringToSeconds(a["time"]);
var v2 = convertStringToSeconds(b["time"]);
if (v1 > v2){
return 1;
}else if(v1 < v2){
return -1;
}else{
return 0;
}
}
ActiveGroup.prototype.getPPOrder = function(){
var ppOrder = [];
logger.info("getPPOrder: "+this.orderUpdated);
if (this.orderUpdated){
return ppOrder;
}
var size = 0;
var mainObj = {};
mainObj["gid"] = this.groupId;
if(this.PickUpPoints != null){
size = this.PickUpPoints.length;
}
for (var i = 0; i<size; i++){
ppOrder.push(this.PickUpPoints[i].getNearPoint());
}
ppOrder.sort(sortfunction);
mainObj["pp"] = ppOrder;
this.orderUpdated = true;
//moved to log final status
//this.orderUpdated = true;
logger.info("======== storing pickup point order for group id:: "+this.groupId+" ", ppOrder);
return mainObj;
}
ActiveGroup.prototype.logFinalStatus = function(req,device_id,updateTripStatus,onDelete,smsParams,pushParams){
if ((!onDelete) || (this.statusUpdated) || (device_id == null) || (device_id == undefined)){
return;
}
if (updateTripStatus!=null){
this.handleTripStatusRecord(null,null,updateTripStatus,req,smsParams,pushParams);
}
logger.info("======== logFinalStatus: "+this.statusUpdated+" time: " +new Date().getTime());
var size = 0;
if(this.PickUpPoints != null){
size = this.PickUpPoints.length;
}
var dl = new IndividualDeviceLogger();
var log = "";
for (var i = 0; i<size; i++){
var pp = this.PickUpPoints[i];
log = log+pp.getFinalStatus(device_id, this.profileId, this.groupId);
dl.writeGroupStatustLog(log);
}
this.statusUpdated= true;
return;
}
ActiveGroup.prototype.getPickupPointIndex = function(pid){
var size = 0;
if(this.PickUpPoints != null){
size = this.PickUpPoints.length;
}
logger.info("getPickupPointIndex pid : "+pid);
for (var i = 0; i<size; i++){
if (pid == this.PickUpPoints[i].getId()){
logger.info("getPickupPointIndex pickup_point_id : "+this.PickUpPoints[i].getId());
return i;
}
}
return -1;
}
/*
* This function is a destructor of the group.
*
*/
ActiveGroup.prototype.deleteGroup = function() {
logger.info("ActiveGroup deleteGroup start: ");
var length = users.length;
for (var i = 0; i<length; i++){
users[i] = null;
delete users[i];
}
users = null;
delete users;
logger.info("ActiveGroup deleteGroup end: ");
};
/*
*
*/
ActiveGroup.prototype.checkSpeedCutoffCrossed = function(flgData) {
var flag = new Flag(flgData);
if (this.cutoff_alerted){
return null;
}
if ( (this.speed_cutoff < flag.getFlagValue(FlagConstants.FLAG_SPEED)) ){
var data = {userMobile:flag.getFlagValue(FlagConstants.FLAG_SENDER),cutoff:this.speed_cutoff, speed:flag.getFlagValue(FlagConstants.FLAG_SPEED)};
this.cutoff_alerted = true;
return data;
}
return null;
}
ActiveGroup.prototype.isLocationReached = function(flag){
var status = false;
var latlng = new LatLon(flag.getFlagValue(FlagConstants.FLAG_LATITUDE),flag.getFlagValue(FlagConstants.FLAG_LONGITUDE),"");
var dist = latlng.checkDistance(this.lpoint);
//check vehicle distace to last point identified
var index = this.getLastPointIndex();
if ((index<0) || (index>=this.PickUpPoints.length)){
return status;
}
if (this.PickUpPoints[index] == undefined){
return status;
}
var latlng1 = new LatLon(this.PickUpPoints[index].getLat(),this.PickUpPoints[index].getLon(),"");
var dist1 = latlng1.checkDistance(latlng);
logger.info("isLocationReached: dist: "+dist+" this.sessionType : "+this.sessionType);
if( (this.sessionType == "P") && (dist<=MIN_DIST_LOCATION)){
this.locationReachedTime = flag.getFlagValue(FlagConstants.FLAG_DATE);
status = true;
} else if( (this.sessionType == "D") && (dist1<=MIN_DIST_LOCATION)){
this.locationReachedTime = flag.getFlagValue(FlagConstants.FLAG_DATE);
status = true;
}else{
logger.info("isLocationReached: condition failed");
}
return status;
}
/*
* This function send alert to parents when vehicle started and reached campus.
*
*/
ActiveGroup.prototype.sendTripStatusAlert = function(status,smsParams, pushParams){
var TAG = "sendStatusAlert";
if (this.profileType == 1){ //1= CORPORATE, 2 = SCHOOL, send now only for schools
return;
}
var name = "";
if((this.groupName != null) && (this.groupName != undefined)){
name = this.groupName;
}
if (status == TRIP_STARTED){
this.sendGroupAlert(name +" vehicle started.", null, smsParams, pushParams);
}else if (status == TRIP_ENDED){
if (this.sessionType == "P"){
this.sendGroupAlert(name + " vehicle reached campus.", null, smsParams, pushParams);
}
}
}
/*
* This function based on current status of trip handles trip status record
*/
ActiveGroup.prototype.handleTripStatusRecord = function(flgData,activeSession,updateTripStatus,req,smsParams, pushParams){
var TAG = "handleTripStatusRecord";
if (this.tripStatus == -1){ //in case if it is -1
this.tripStatus = TRIP_SCHEDULED;
}
logger.info(TAG,"handleTripStatusRecord**********$$$$$$$$$$ 1"+this.tripStatus+ " flgData:"+flgData+" activeSession: "+activeSession);
if ( (this.statusUpdated == true) || (this.tripStatus == TRIP_ENDED) || (updateTripStatus == null) || (updateTripStatus == undefined) ){
return;
}
var flag = new Flag(flgData);
var distance = flag.getFlagValue(FlagConstants.DISTANCE)
if (flgData == null && activeSession == null){
//both null means logging final status
if (this.tripStatus == TRIP_STARTED){
logger.info(TAG,"handleTripStatusRecord**********$$$$$$$$$$ logging final status");
var time = -1;
if (this.locationReachedTime == -1){
time = new Date().getTime();
}else{
time = this.locationReachedTime;
}
if (this.sessionType == "P"){
updateTripStatus(req,TRIP_ENDED,this.groupId,this.vehicleId,time, null,null,distance,this.pickUpStartTime,this.pickUpStopTime);
}else{
updateTripStatus(req,TRIP_ENDED,this.groupId,this.vehicleId,time, null,null,distance,this.dropStartTime,this.dropStopTime);
}
this.sendTripStatusAlert(TRIP_ENDED,smsParams, pushParams);
this.tripStatus = TRIP_ENDED;
this.statusUpdated = true;
}
return;
}
logger.info(TAG,"handleTripStatusRecord**********$$$$$$$$$$ 2"+this.tripStatus);
if (this.tripStatus == TRIP_SCHEDULED){
var timeDiff = activeSession.getTimeAfterTripStart(flag.getFlagValue(FlagConstants.FLAG_DEVICE_TIME_STAMP));
logger.info(TAG,"handleTripStatusRecord**********$$$$$$$$$$ timeDiff 5 : "+timeDiff);
if((timeDiff >= MIN_TIME_GAP_START)&&(this.totalDistance >= MIN_DIST_MOVE)){
if (this.sessionType == "P"){
logger.info("ActiveGroup tripcheck this.pickUpStartTime : "+this.pickUpStartTime);
logger.info("ActiveGroup tripcheck this.pickUpStopTime : "+this.pickUpStopTime);
updateTripStatus(req,TRIP_STARTED,this.groupId,this.vehicleId,flag.getFlagValue(FlagConstants.FLAG_DATE), flag.getFlagValue(FlagConstants.FLAG_LATITUDE),flag.getFlagValue(FlagConstants.FLAG_LONGITUDE),distance,this.pickUpStartTime,this.pickUpStopTime);
}else{
updateTripStatus(req,TRIP_STARTED,this.groupId,this.vehicleId,flag.getFlagValue(FlagConstants.FLAG_DATE), flag.getFlagValue(FlagConstants.FLAG_LATITUDE),flag.getFlagValue(FlagConstants.FLAG_LONGITUDE),distance,this.dropStartTime,this.dropStopTime);
}
this.sendTripStatusAlert(TRIP_STARTED,smsParams, pushParams);
this.tripStatus = TRIP_STARTED;
logger.info(TAG,"handleTripStatusRecord**********$$$$$$$$$$ this.tripStatus : "+"TRIP_STARTED");
}
} else if (this.tripStatus == TRIP_STARTED){
var timeDiff = activeSession.getTimeBeforeTripEnd(flag.getFlagValue(FlagConstants.FLAG_DEVICE_TIME_STAMP));
var timeDiffAfterTripStart = activeSession.getTimeAfterTripStart(flag.getFlagValue(FlagConstants.FLAG_DEVICE_TIME_STAMP));
//Is location reached, keep updates the location reach time. but will not update the trip end untill session ends.
//Is location reached is only applicable for pickup, not for drop.
// While session ending, if location reached has the valid time, it uses the time to upate the trip end status.
//check if location is reached while in pickup session
var location_reached = this.isLocationReached(flag);
logger.info(TAG,"handleTripStatusRecord*************************************$$$$$$$$$$ timeDiff 6 : "+timeDiff+" location_reached: "+location_reached);
var min_45 = 45*60;
/*
* Commented minimum 45 m duratin, bcz, sometimes the vehicle is reaching much before session end time.
*
*/
if (location_reached){ //&& (timeDiff < min_45) ){
location_reached = true;
}else{
location_reached = false;
}
/*
* 1. If vehicl reached location after 30 min of session start, then assume trip ended.
* Or
* 2. if trip ending in MIN_TIME_GAP, then also record as trip end.
*/
if ( ( (this.totalDistance>MIN_START_DISTANCE_MOVE_TO_END) && ( location_reached)) || (timeDiff <= MIN_TIME_GAP) ){
var time = -1;
if (this.locationReachedTime == -1){
time = flag.getFlagValue(FlagConstants.FLAG_DATE);
}else{
time = this.locationReachedTime;
}
if (this.sessionType == "P"){
updateTripStatus(req,TRIP_ENDED,this.groupId,this.vehicleId,time, flag.getFlagValue(FlagConstants.FLAG_LATITUDE),flag.getFlagValue(FlagConstants.FLAG_LONGITUDE),distance,this.pickUpStartTime,this.pickUpStopTime);
}else{
updateTripStatus(req,TRIP_ENDED,this.groupId,this.vehicleId,time, flag.getFlagValue(FlagConstants.FLAG_LATITUDE),flag.getFlagValue(FlagConstants.FLAG_LONGITUDE),distance,this.dropStartTime,this.dropStopTime);
}
this.sendTripStatusAlert(TRIP_ENDED,smsParams, pushParams);
this.tripStatus = TRIP_ENDED;
this.statusUpdated = true;
this.prevUpdateTime = flag.getFlagValue(FlagConstants.FLAG_DATE);
}else{
/*
* Update trip on going, so that in case of trip ended early and mobile app is off before session end, it will help to
* calculate trip untill record.
*/
if ( (this.prevUpdateTime == 0) || (this.prevUpdateTime == undefined)){
this.prevUpdateTime = flag.getFlagValue(FlagConstants.FLAG_DATE);
logger.info(TAG,"handleTripStatusRecord*************************************$$$$$$$$$$ prevUpdateTime this.prevUpdateTime:"+this.prevUpdateTime);
}else{
var prvtime = this.prevUpdateTime;
var curtime = flag.getFlagValue(FlagConstants.FLAG_DATE);
var diff = curtime - prvtime;
diff = diff/(1000*60);
logger.info(TAG,"handleTripStatusRecord*************************************$$$$$$$$$$ prevUpdateTime prvtime:"+prvtime+ " curtime:"+curtime+" diff : "+diff);
if (diff >= 10){
if (this.sessionType == "P"){
updateTripStatus(req,TRIP_ONGOING,this.groupId,this.vehicleId,curtime, flag.getFlagValue(FlagConstants.FLAG_LATITUDE),flag.getFlagValue(FlagConstants.FLAG_LONGITUDE),distance,this.pickUpStartTime,this.pickUpStopTime);
}else{
updateTripStatus(req,TRIP_ONGOING,this.groupId,this.vehicleId,curtime, flag.getFlagValue(FlagConstants.FLAG_LATITUDE),flag.getFlagValue(FlagConstants.FLAG_LONGITUDE),distance,this.dropStartTime,this.dropStopTime);
}
this.prevUpdateTime = curtime;
}
}
}
}
}
ActiveGroup.prototype.isStale = function(flgData){
var status = false;
var flag = new Flag(flgData);
var TWOHOURS = 2*60*60;
var t1 = this.convertStringToSeconds(flag.getFlagValue(FlagConstants.FLAG_DEVICE_TIME_STAMP));
console.log("isStale: t1: "+t1);
var t2 = this.convertStringToSeconds(""+this.prvTime);
console.log("isStale: t2: "+t2);
console.log("isStale: this.prvTime: "+this.prvTime);
var diff = t1 - t2;
//If it is stale from drop, then drop time is more than current time. So the below check.
if (diff < 0){
diff = (-1) * diff;
}
console.log("isStale: diff: "+diff);
if ((t1!=0) && (t2!=0) && (diff > TWOHOURS)){
status = true;
}
console.log("isStale: status: "+status);
return status;
}
/*
* This function check the nearby pickup point to send alert.
* input: current location, total time and total distance to calculate avg speed.
*
*/
ActiveGroup.prototype.checkUpdate = function(flgData, next, smsParams, pushParams, updateSwipeData,ignStatus,updateTripStatus,activeSession,req) {
if ((this.profileStatus == PROFILE_INACTIVE) || (this.statusUpdated) ){
logger.info("checkUpdate: ", "Profile "+this.profileName+ " is inactive."+" this.statusUpdated: "+this.statusUpdated);
return;
}
//If ignition is off, no more updates.
if (ignStatus == 0){
return;
}
var flag = new Flag(flgData);
if (this.prvPoint == null){
this.prvPoint = new LatLon(flag.getFlagValue(FlagConstants.FLAG_LATITUDE),flag.getFlagValue(FlagConstants.FLAG_LONGITUDE),"");
}else{
var currPoint = new LatLon(flag.getFlagValue(FlagConstants.FLAG_LATITUDE),flag.getFlagValue(FlagConstants.FLAG_LONGITUDE),"");
this.totalDistance = this.totalDistance + (currPoint.checkDistance(this.prvPoint) * 1000);
this.prvPoint = currPoint;
}
logger.info("checkUpdate this.totalDistance:"+this.totalDistance);
//parse flag
var flag = new Flag(flgData);
if (this.deviceId == 0){
this.deviceId = flag.getFlagValue(FlagConstants.FLAG_SENDER);
}
this.handleTripStatusRecord(flgData,activeSession,updateTripStatus,req,smsParams, pushParams);
//check if this pickup point is is scheduled time, if not don;t check update, return
//logger.info(' ==== ::', this.PickUpPoints);
//logger.info(' ++++ ::', __me.PickUpPoints);
//this.PickUpPoints = __me.PickUpPoints;
logger.info("checkUpdate for profile id:", this.profileId+" group id : "+this.groupId+" this.vehicleId: "+ this.vehicleId+" this.sessionType: "+this.sessionType);
/*
* [Madhu]: 17/11/17, This condition is negating the orderUpdate and updating again again. So commenting for now.
* This condition might have kept to handle some edge case, will uncomment if we discover the edge case.
*/
/*if ((ignStatus == 1) && (this.isAllPicked(ignStatus) == false)){
this.orderUpdated = false;
}*/
var data = utility.hex2a(flgData);
var flag1 = JSON.parse(data);
/*var date = new Date(flag1[FlagConstants.FLAG_DATE]);
var minutes = date.getHours()*60+date.getMinutes();
if ( (minutes<=this.pickUpStartTime) || (minutes >=this.pickUpStopTime) ){
//no nearby alert check if it falls out of session boundaries.
return;
}*/
var length = this.PickUpPoints ? this.PickUpPoints.length || 0 : 0;
//logger.info(length + " ::CheckUpdate:: ======== ::this.PickUpPoints.length: ", this.PickUpPoints);
//check if the flag category is swipe or track
if( flag.getFlagValue(FlagConstants.FLAG_CATEGORY) == FlagCategories.CTG_FLAG_RFID_SWIPE ){
this.checkSwipe(flag.getFlagValue(FlagConstants.FLAG_RFID_ID), next, smsParams, pushParams,updateSwipeData,flag.getFlagValue(FlagConstants.FLAG_LATITUDE),flag.getFlagValue(FlagConstants.FLAG_LONGITUDE),flag.getFlagValue(FlagConstants.FLAG_DATE));
return;
}
//check the flag type, if it is different than CTG_FLAG_TRACK
if( (flag.getFlagValue(FlagConstants.FLAG_CATEGORY) != FlagCategories.CTG_FLAG_TRACK) &&
(flag.getFlagValue(FlagConstants.FLAG_CATEGORY) != FlagCategories.CTG_FLAG_TRACK_DEVICE))
{
logger.info("checkupdate returning: ");
return;
}
var latlng = new LatLon(flag.getFlagValue(FlagConstants.FLAG_LATITUDE),flag.getFlagValue(FlagConstants.FLAG_LONGITUDE),"");
var totaltime = flag.getFlagValue(FlagConstants.FLAG_DATE) - flag.getFlagValue(FlagConstants.FLAG_TRACK_START_TIME);
var totaldist = flag.getFlagValue(FlagConstants.FLAG_TRACK_DISTANCE);
var speed = flag.getFlagValue(FlagConstants.FLAG_SPEED);
var indexArray = [];
/* If trip is not started, don't alert user */
if (this.tripStatus != TRIP_STARTED){
return;
}
/*
* Date: July 26, 2016.
* This is temporary fix added to consider order of pickup point for alerting.
* Since the current implementation is not allowed to insert pickup points to already added route, it might miss last points, though they are in middle of route.
* This fix is until automatic order of pickup points from shortest path algorithm.
*/
//var lastAlertIndex = -1;
/*
* Date: July 26, 2016.
* This is temporary fix added to consider order of pickup point for alerting.
* Since the current implementation is not allowed to insert pickup points to already added route, it might miss last points, though they are in middle of route.
* This fix is until automatic order of pickup points from shortest path algorithm.
* END
*/
if (ignStatus == 1){
this.prvTime = flag.getFlagValue(FlagConstants.FLAG_DEVICE_TIME_STAMP);
for (var i = 0; i<length; i++){
var point = this.PickUpPoints[i];
point.checkTimeToPointAndAlert(this.sessionType,this.groupId, flag.getFlagValue(FlagConstants.FLAG_SENDER), latlng, flag.getFlagValue(FlagConstants.FLAG_DEVICE_TIME_STAMP), speed, this.profileName, smsParams, pushParams, this.profile_pacakge,flag.getFlagValue(FlagConstants.FLAG_COMPASS),this.groupName,flag.getFlagValue(FlagConstants.FLAG_TRACK_DISTANCE),this.sms,this.android,this.ios);
}
/*
* Extra code to strengthen alert mechanism.
* Check, if vehicle in near point, and previous point is alerted, then alert.
*/
// 1. first check any point is near
var point = null;
var orderId = -1;
for (var i = 0; i<length; i++){
point = this.PickUpPoints[i];
orderId = point.isNearAlertDistance(this.sessionType,this.groupId, flag.getFlagValue(FlagConstants.FLAG_SENDER), latlng, flag.getFlagValue(FlagConstants.FLAG_DEVICE_TIME_STAMP), speed, this.profileName, smsParams, pushParams, this.profile_pacakge,flag.getFlagValue(FlagConstants.FLAG_COMPASS),this.groupName,flag.getFlagValue(FlagConstants.FLAG_TRACK_DISTANCE),this.sms,this.android,this.ios);
if (orderId != -1){
break;
}
}
if (orderId != -1){
// 2. if point order is 1, alert anyway
if ((point) && (orderId == 1)){
point.alertParentAnyway(this.sessionType,this.groupId, flag.getFlagValue(FlagConstants.FLAG_SENDER), latlng, flag.getFlagValue(FlagConstants.FLAG_DEVICE_TIME_STAMP), speed, this.profileName, smsParams, pushParams, this.profile_pacakge,flag.getFlagValue(FlagConstants.FLAG_COMPASS),this.groupName,flag.getFlagValue(FlagConstants.FLAG_TRACK_DISTANCE),this.sms,this.android,this.ios);
}
// 3. if order is not 1, check its previous point alerted or not.
point = null;
for (var i = 0; i<length; i++){
point = this.PickUpPoints[i];
var val = point.areYouAlerted(orderId);
if (val){
point.alertParentAnyway(this.sessionType,this.groupId, flag.getFlagValue(FlagConstants.FLAG_SENDER), latlng, flag.getFlagValue(FlagConstants.FLAG_DEVICE_TIME_STAMP), speed, this.profileName, smsParams, pushParams, this.profile_pacakge,flag.getFlagValue(FlagConstants.FLAG_COMPASS),this.groupName,flag.getFlagValue(FlagConstants.FLAG_TRACK_DISTANCE),this.sms,this.android,this.ios);
break;
}
}
}//if (orderId != -1){
}
if (this.prvDist != flag.getFlagValue(FlagConstants.FLAG_TRACK_DISTANCE)){
if (this.wait > 300){
//log wait point.
//check if the wait is near any pickup point, if it is not near, then it is unknown point.
var isNear = false;
for (var i = 0; i<length; i++){
var point = this.PickUpPoints[i];
isNear = point.isNear(latlng);
if (isNear){
break;
}
}
//if it is not near, log point
if (!isNear){
var dl = new IndividualDeviceLogger();
dl.writePointReachLog("[REACHPOINT-B],"+flag.getFlagValue(FlagConstants.FLAG_SENDER) + "," + "unknown point" +","+ this.prvTime+","+ flag.getFlagValue(FlagConstants.FLAG_DEVICE_TIME_STAMP)+","+ 0+","+flag.getFlagValue(FlagConstants.FLAG_LATITUDE)+","+flag.getFlagValue(FlagConstants.FLAG_LONGITUDE)+",[REACHPOINT-E]",flag.getFlagValue(FlagConstants.FLAG_SENDER));
}
}
this.prvDist = flag.getFlagValue(FlagConstants.FLAG_TRACK_DISTANCE);
this.prvTime = flag.getFlagValue(FlagConstants.FLAG_DEVICE_TIME_STAMP);
this.wait = 0;
}else{
var t1 = this.convertStringToSeconds(flag.getFlagValue(FlagConstants.FLAG_DEVICE_TIME_STAMP));
var t2 = this.convertStringToSeconds(""+this.prvTime);
this.wait = t1-t2;
console.log("wait time is: "+this.wait);
}
if (next!=null){
next();
}
//logger.info("ActiveGroup checkUpdate end: ");
};
ActiveGroup.prototype.convertStringToSeconds = function(date){
logger.info("date: "+date);
if (date == 0){
return 0;
}
date = ""+date;
var seconds = parseInt(date.substring(6, 8),10)*60*60+parseInt(date.substring(8, 10),10)*60+parseInt(date.substring(10, 12),10);
logger.info("time diff: "+seconds);
return seconds;
}
/*
* This function check the swipe value in all pickup point, which ever matches, it send the alert to parent.
* input: RFID value
*
*/
ActiveGroup.prototype.logReachPoints = function() {
var length = this.PickUpPoints ? this.PickUpPoints.length || 0 : 0;
if (length == 0){
return;
}
for (var i = 0; i<length; i++){
var point = this.PickUpPoints[i];
point.logReachPoint(this.deviceId);
}
}
/*
* This function check the swipe value in all pickup point, which ever matches, it send the alert to parent.
* input: RFID value
*
*/
ActiveGroup.prototype.checkSwipe = function(rfid, next, smsParams, pushParams,updateSwipeData, lat,lon, date) {
logger.info("checkSwipe for profile id:", this.profileId+" group id : "+this.groupId+" rfid: "+rfid + " this.sessionType: "+this.sessionType);
//if the group is RFID enable only, proceed otherwise simply return
if (this.rfid == 0){
return;
}
var length = this.PickUpPoints ? this.PickUpPoints.length || 0 : 0;
var status = false;
for (var i = 0; i<length; i++){
var point = this.PickUpPoints[i];
var status1 = point.checkSwipeAndAlert(this.profileId, this.locationId, rfid, this.sessionType,this.groupId, this.profileName, smsParams, pushParams, this.profile_pacakge,this.groupName, updateSwipeData,lat,lon,this.lpoint,date,this.sms,this.android,this.ios);
if (status1){
status = true;
//break;
}
}
logger.info("checkSwipe for updateSwipeData:", status+" i : "+i+ " date :"+date);
if ( (status == false) && (i == length) && (updateSwipeData) ){
logger.info("checkSwipe for updateSwipeData: i am getting in: "+date);
updateSwipeData(this.profileId, this.locationId, this.groupId,this.groupName, rfid,0,0,0,lat,lon, "",false);
}
if (next!=null){
next();
}
//logger.info("ActiveGroup checkUpdate end: ");
};
/*
* This function send alert to the whole group.
* input: alert message
*
*/
ActiveGroup.prototype.sendGroupAlert = function(alert, next, smsParams, pushParams) {
logger.info("ActiveGroup sendGroupAlert start: ");
var length = this.PickUpPoints.length;
for (var i = 0; i<length; i++){
var users = this.PickUpPoints[i].getUsers();
var count = users.length;
for (var j = 0; j<count; j++){
var user = users[j];
pushParams.platform = user.getUserPlatform();
var userCommands = new UserCommands(smsParams, pushParams);
var userid = [];
userid.push(user.getUserID());
var alertCommand = userCommands.getStatusAlert(this.profileName, this.profileId, alert, new Date().getTime());
/*
* Now only push, make it send SMS, if opted SMS in profile. [Madhu]: 12-3-18
*/
userCommands.sendAlert(userid,user.getUserArn(), null, alertCommand, this.groupType);
}
}
if (next!=null){
next();
}
};
/*
* This function send alert to the whole group.
* input: alert message
*
*/
ActiveGroup.prototype.sendStatusAlert = function(alert, next, smsParams, pushParams) {
logger.info("ActiveGroup sendStatusAlert start: ");
//ActiveGroup.prototype.sendGroupAlert = function(alert, next) {
var length = this.PickUpPoints.length;
var alertCommand = userCommands.getStatusAlert(this.profileName, this.profileId, alert, new Date().getTime())
for (var i = 0; i<length; i++){
var users = this.PickUpPoints[i].getUsers();
var count = users.length;
for (var j = 0; j<count; j++){
var user = users[j];
pushParams.platform = user.getUserPlatform();
var userCommands = new UserCommands(smsParams, pushParams);
userCommands.sendAlert(user.getUserID(),user.getUserArn(), alert, alertCommand, this.groupType);
}
}
if (next!=null){
next();
}
};
ActiveGroup.prototype.isInValid = function(){
return this.invalid;
}
/*
* Parse JSON obejct and create objects
*/
ActiveGroup.prototype.fromJSON = function(data){
if (data == null){
logger.info("fromJSON returning");
this.invalid = true;
return;
}
logger.info("fromJSON 1");
this.PickUpPoints = [];
var flagJson = null;
flagJson = JSON.parse(utility.hex2a(data));
this.profileId = flagJson[PID];
this.groupId = flagJson[GID];
this.vehicleId = flagJson[VID];
//this.groupType = flagJson[GTYPE];
this.profileName = flagJson[PNAME];
this.profile_pacakge = flagJson[PPACKAGE];
var dr = new ActiveGroupUser("");
//dr.fromJSON(flagJson[DRIVER]);
//this.driver = dr;
var pPointsArray = JSON.parse(flagJson[PPOINTS]);
if ((pPointsArray == undefined) || (pPointsArray == null)){
this.PickUpPoints = null;
return;
}
this.PickUpPoints = [];
for(var i=0;i<pPointsArray.length;i++){
var pp = new PickUpPoint(0,0,0,"");
pp.fromJSON(pPointsArray[i]);
this.PickUpPoints.push(pp);
}
this.pickUpStartTime = flagJson[PU_START_TIME];
this.pickUpStopTime = flagJson[PU_STOP_TIME];
this.dropStartTime = flagJson[DP_START_TIME];
this.dropStopTime = flagJson[DP_STOP_TIME];
this.sessionType = flagJson[STYPE];
this.sessionId = flagJson[SID];
this.speed_cutoff = flagJson[SPEED_CUTOFF];
this.cutoff_alerted = flagJson[SPEED_CUTOFF_ALERTED];
this.groupName = flagJson[GROUP_NAME];
this.rfid = flagJson[RFID];
this.lpoint = new LatLon(0,0,"");
this.locationId = flagJson[LID];
this.lpoint.fromJSON(flagJson[LPOINT]);
this.deviceId = flagJson[DID];
this.sms = flagJson[SMS];
this.android = flagJson[ANDROID];
this.ios = flagJson[IOS];
this.wait = flagJson[WAIT];
this.prvDist = flagJson[PRVDIST];
this.prvTime = flagJson[PRVTIME];
this.orderUpdated = flagJson[ORDER_UPDATED];
this.statusUpdated = flagJson[STATUS_UPDATED];
this.tripStatus = flagJson[TRIP_STATUS];
this.locationReachedTime = flagJson[LOC_REACH_TIME];
this.profileStatus = flagJson[PROFILE_STATUS];
this.lastpointIndex = flagJson[LAST_POINT_INDEX];
this.profileType = flagJson[PROFILE_TYPE];
this.prvPoint = new LatLon(0,0,"");
this.prvPoint.fromJSON(flagJson[PRVPOINT]);
this.totalDistance = flagJson[TOTALDIST];
this.prevUpdateTime = flagJson[PREV_UPDATE_TIME];
//__me.PickUpPoints = this.PickUpPoints;
logger.info('============= end fromJson Pickup points length :: =========', this.PickUpPoints.length);
}
/*
* Parse it to JSON to store
*/
ActiveGroup.prototype.toJSON = function(){
logger.info("toJSON 1");
var ppointsArry = [];
var mainObj = {};
mainObj[PID] = this.profileId;
mainObj[GID] = this.groupId;
mainObj[VID] = this.vehicleId;
//mainObj[GTYPE] = this.groupType;
mainObj[PNAME] = this.profileName;
mainObj[PPACKAGE] = this.profile_pacakge;
//mainObj[DRIVER] = this.driver.toJSON();
if (this.PickUpPoints != null){
for(var i=0;i<this.PickUpPoints.length;i++){
//logger.info("ActiveGroup.prototype.toJSON::::"+i);
ppointsArry.push(this.PickUpPoints[i].toJSON());
}
mainObj[PPOINTS] = JSON.stringify(ppointsArry);
}else{
mainObj[PPOINTS] = "";
}
mainObj[PU_START_TIME] = this.pickUpStartTime;
mainObj[PU_STOP_TIME] = this.pickUpStopTime;
mainObj[DP_START_TIME] = this.dropStartTime;
mainObj[DP_STOP_TIME] = this.dropStopTime;
mainObj[STYPE] = this.sessionType;
mainObj[SID] = this.sessionId;
mainObj[SPEED_CUTOFF] = this.speed_cutoff;
mainObj[SPEED_CUTOFF_ALERTED] = this.cutoff_alerted;
mainObj[GROUP_NAME] = this.groupName;
mainObj[RFID] = this.rfid;
if (this.lpoint){
mainObj[LPOINT] = this.lpoint.toJSON();
}else{
mainObj[LPOINT] = null;
}
mainObj[LID] = this.locationId;
mainObj[DID] = this.deviceId;
mainObj[SMS] = this.sms;
mainObj[ANDROID] = this.android;
mainObj[IOS] = this.ios;
mainObj[WAIT] = this.wait;
mainObj[PRVDIST] = this.prvDist;
mainObj[PRVTIME] = this.prvTime;
mainObj[ORDER_UPDATED] = this.orderUpdated;
mainObj[STATUS_UPDATED] = this.statusUpdated;
mainObj[TRIP_STATUS] = this.tripStatus;
mainObj[LOC_REACH_TIME] = this.locationReachedTime;
mainObj[PROFILE_STATUS] = this.profileStatus;
mainObj[LAST_POINT_INDEX] = this.lastpointIndex;
mainObj[PROFILE_TYPE] = this.profileType;
mainObj[PREV_UPDATE_TIME] = this.prevUpdateTime;
if (this.prvPoint){
mainObj[PRVPOINT] = this.prvPoint.toJSON();
}else{
mainObj[PRVPOINT] = null;
}
mainObj[TOTALDIST] = this.totalDistance;
return utility.convertFromAscii2Hexa(JSON.stringify(mainObj));
}
/*
* private function to inject data for automate test suite
*/
ActiveGroup.prototype.injectData = function injectData(profileId, groupId, profileName, PickUpPoints, startTime,stopTime, sessionType,sessionId){
this.profileId = profileId;
this.groupId = groupId;
this.profileName = profileName;
this.PickUpPoints = PickUpPoints;
this.invalid = false;
//this.driver = null;
this.pickUpStartTime = startTime;
this.pickUpStopTime = stopTime;
this.sessionType = sessionType;
this.sessionId = sessionId;
}
/*
* private function to inject data for automate test suite
*/
function sortfunction(a, b){
//Compare "a" and "b" in some fashion, and return -1, 0, or 1
var p1 = new LatLon(a.getLat(),a.getLon(), "");
var aDist = this.driverPoint.checkDistance(p1);
p1 = new LatLon(b.getLat(),b.getLon(), "");
var bDist = this.driverPoint.checkDistance(p1) ;
return aDist - bDist;
}
/*
* function to get number of users in each pickup point in array format.
* ex: if 3 pickup points and users are like 2, 1 3.
* output: [2,1,3]
*/
ActiveGroup.prototype.getUsersInPickUpPoints = function(){
var array = [];
var length = this.PickUpPoints.length;
var i = 1;
for (i; i<length;i++){
array.push(this.PickUpPoints[i].getUserCount());
}
return array;
}
/*
* function to get alerts count in each pickup point in array format.
* ex: if 3 pickup points and users are like 2, 1 3.
* output: [2,1,3]
*/
ActiveGroup.prototype.getAlertesInPickUpPoints = function(){
var array = [];
var length = this.PickUpPoints.length;
var i = 1;
for (i; i<length;i++){
array.push(this.PickUpPoints[i].getAlertCount());
}
return array;
}
ActiveGroup.prototype.getProfileId = function(){
return this.profileId;
}
ActiveGroup.prototype.getProfileName = function(){
return this.profileName;
}
ActiveGroup.prototype.getGroupId = function(){
return this.groupId;
}
ActiveGroup.prototype.getALLPPPoints = function(){
/* var points = [];
if (this.PickUpPoints != null){
logger.info("getALLPPPoints :"+this.PickUpPoints.length);
for(var i=0;i<this.PickUpPoints.length;i++){
points.push(new LatLon(this.PickUpPoints[i].getLat(),this.PickUpPoints[i].getLon(), ""));
}
return points;
}*/
return this.PickUpPoints;
}