UNPKG

flaglib

Version:

Ignition event 15 added.

1,346 lines (1,083 loc) 42.8 kB
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; }