Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
Lodash cloneDeep vs JSON Clone 7545236934650044
(version: 0)
Comparing performance of:
Lodash cloneDeep vs Json clone
Created:
5 years ago
by:
Guest
Jump to the latest result
HTML Preparation code:
<script src='https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js'></script>
Script Preparation code:
var MyObject = { "_id" : "kid_bkFYnCzzzb", "appId" : "bdc63fc4e71d4a6db08ae95b04269b7c", "environmentName" : "Production", "appsecret" : "9226605b7b09477ab7ffbe5dbab5e181", "mastersecret" : "e731f9a285834900a35c2813dd1762c2", "API_version" : 3, "creator" : "e9e87e6e44a840fdab2d176cb8f74b09", "creation_time" : "2016-05-04T01:53:03.192Z", "devUserIDs" : [ "e9e87e6e44a840fdab2d176cb8f74b09", "5e74042dfead4d6dab106746ad276e62", "9e5331f5765349d29866452cbd70c277" ], "collaborators" : [ "d31ddbd3be76450f9ce6dce52e7cb818", "b3bdf429002749edbeb04ca4447d6817", "379a07326d864031aa802bfd084c34e4", "97d398c5e48c457793e4a0a11e11f68a", "333555f5a843412fb6a3edaca658906d", "5c6ac833169b4d1ea51e804a36355a86", "4bf5209cadf14946b207cd4137907f05", "834124069ba24656aee5eae697822ee4", "ee07cbafc3764bf1a3866f1072503bc7" ], "blobService" : { "gcsContainerName" : "449962836b6c4ea5b59b03abd32fbedb", "useGCS" : true }, "acl" : { "EventCodeDetails" : "append-read", "Events" : "append-only", "EventType" : "append-only", "Farmer" : "append-read", "HectaresTilledCalculator" : "write", "MaintenanceTypes" : "append-read", "ResponseFromOperator" : "append-read", "Revenue" : "append-read", "RevenueTypes" : "append-read", "SmsGatewayInfo" : "append-read", "StoreCurrentStatus" : "append-read", "TelerivetFarmerInfo" : "append-read", "TractorDetail" : { "create" : [ { "roleId" : "all-users", "type" : "always" } ], "read" : [ { "roleId" : "all-users", "type" : "grant" } ], "update" : [ { "roleId" : "all-users", "type" : "grant" } ], "delete" : [ { "roleId" : "all-users", "type" : "entity" } ] }, "TractorInfo" : "append-read", "TractorOperator" : "append-read", "TractorOwner" : "write", "TractorToOperator" : "append-only", "_customEndpoints" : { "EventCodeDetails" : "master-or-user", "FarmerMessageExpiryCheck" : "master-or-user", "GetTractorStatus" : "master-or-user", "NotificationGeoFence" : "master-or-user", "TelerivetFarmerInfo" : "master-or-user", "forgotPassword" : "master-or-user", "getActivity" : "master-or-user", "getTractors" : "master-or-user", "responseFromOperator" : "master-or-user", "ActionStatusMaintenanceLog" : "master-or-user", "AlertTwoTrackEventNotifications" : "master-or-user", "AlertStatusMaintenanceLog" : "master-or-user", "TractorCurrentLocation" : "master-or-user", "MaintenanceCalculate" : "master-or-user", "RunMaintenanceRepairNotification" : "master-or-user", "TotalHectareForTractor" : "master-or-user", "TractorActivity" : "master-or-user", "AutoRunMaintenance" : "master-or-user", "demo-endpoint" : "master-or-user", "push-demo" : "master-or-user", "SyncCollections" : "master-or-user", "MarkNotificationAsRead" : "master-or-user", "FilterDailyTractorActivities" : "master-or-user", "DisableGeofenceNotifications" : "master-or-user", "ResetMaintenanceCounter" : "master-or-user", "CopyMaintenanceActivities" : "master-or-user", "CreateMaintenanceActivities" : "master-or-user", "UpdateRevenue" : "master-or-user", "GetHeatMapData" : "master-or-user", "remove-read-notifications" : "master-or-user", "process-hectares-daily-data" : "master-or-user", "process-timezones" : "master-or-user", "process-tractor-activities" : "master-or-user", "process-maintenance" : "master-or-user", "process-real-time-daily-data" : "master-or-user", "UpdateDailyTractorActivityHectaresAndRevenue" : "master-or-user", "test-tractor-activities" : "master-or-user", "b_UpdateTractorOwners" : "master-or-user", "unassign-tractor-on-delete" : "master-or-user", "test" : "master-or-user", "process-update-tractors-status" : "master-or-user", "fetch-store-tractor-activities-three" : "master-or-user", "fetch-store-tractor-activities-two" : "master-or-user", "temp-daily-tractor-activity-clone" : "master-or-user", "fetch-update-daily-tractor-activity" : "master-or-user", "update-tractor-geofence" : "master-or-user", "b_UpdateBookingAgents" : "master-or-user", "UpdateTractorOwnersOnBackend" : "master-or-user", "UpdateBookingAgentsOnBackend" : "master-or-user", "b_UpdateDailyTractorActivities" : "master-or-user", "deleteDuplicateFarmMeasures" : "master-or-user", "DeleteDuplicateFarmMeasure" : "master-or-user", "UpdateBookingsWeather" : "master-or-user", "Update2TrackTractorActiveTimeToday" : "master-or-user", "Update_bookings_Sync_Status_to_1" : "master-or-user", "ResetTractorDetailActiveTimeToday" : "master-or-user", "UpdateBookingsWeatherDetails" : "master-or-user", "ManuallyTriggerNotification" : "master-or-user", "DeleteBookingWeatherValue" : "master-or-user", "deleteUserPushToken" : "master-or-user", "UpdateLatestBookingsWeatherInformation" : "master-or-user", "getTractorReports" : "master-or-user", "_CreatorUpdater" : "master-or-user", "TractorsNearby" : "master-or-user", "BookingsNearbySometimeAgo" : "master-or-user", "UpdateAerisTractorEngineHours" : "master-or-user", "Update2TrackTractorEngineHours" : "master-or-user", "FetchBookingAgentsBetweenDateRange" : "master-or-user", "removeDuplicateBookingAgents" : "master-or-user", "deleteBookingAgents" : "master-or-user", "updateBookingsOrgID" : "master-or-user", "_generateBookingAgentsBookingsReport" : "master-or-user", "getBookingAgentFarmersDetails" : "master-or-user", "_duplicateCreatorRemover" : "master-or-user", "exportUsersEmail" : "master-or-user", "PushEmail" : "master-or-user", "SendMaintenanceAlert" : "master-or-user", "fetch_tractors_activities" : "master-or-user", "PushDailyReports" : "master-or-user", "_test" : "master-or-user", "EngineHoursDistanceDiscoveredWeeklyAlert" : "master-or-user", "getTractotsLatLng" : "master-or-user", "exportRegisteredBookingAgentsForDateRange" : "master-or-user", "geocoderService" : "master-or-user", "aeris_geofence_notification" : "master-or-user", "removeDuplicateBookings" : "master-or-user", "getOperatorIDByTractorID" : "master-or-user", "getBookingsLatLng" : "master-or-user", "count2TrackTractors" : "master-or-user", "UpdateTwoTrackTractorActivityOnPOSTFromAWSBackend" : "master-or-user", "UpdateAerisTractorsActivityOnPostFromAWSBackend" : "master-or-user", "UpdateAerisTractorsOnPOSTFromAWSBACKEND" : "master-or-user", "UpdateTwoTrackTractorsStatusOnPOSTFromAWSBACKEND" : "master-or-user", "UpdateAllTractorsDetailAddressOnPOSTFromAWSBACKEND" : "master-or-user", "deprecated_getTractorLatLngSummaryForDateRange" : "master-or-user", "deprecated_update-daily-real-time-tractor-activity" : "master-or-user", "deprecated_aeris-tractors-location" : "master-or-user", "deprecated_temp-update-daily-activities-from-web-app" : "master-or-user", "deprecated_UpdateAerisTractorActiveTimeToday" : "master-or-user", "deprecated_UpdateTractorDetailAddress" : "master-or-user", "deprecated_fetch-store-tractor-activities-one" : "master-or-user", "deprecated_update-2track-token" : "master-or-user", "PushNotificationWhenTractorNearby" : "master-or-user", "getTractorServiceTypes" : "master-or-user", "SyncTractorsFromAWSBackend" : "master-or-user", "updateTractorIDsToNewIDUsingOldID" : "master-or-user", "generateAndStoreSubscriptionCode" : "master-or-user", "attemptLogin" : "master-or-user", "HandleTractorsAlertsEventFromAWSBACKEND" : "master-or-user", "generateMultipleSubCodes" : "master-or-user", "UpdateOrgIdOfTestAccounts" : "master-or-user", "PostDataToAwsBackend" : "master-or-user", "syncUserProfileImageUrl" : "master-or-user", "PostBookingsDataToBackend" : "master-or-user", "HandleTractorFuelDataPostedFromAWSBackend" : "master-or-user", "ComputeTempFuelVolumes" : "master-or-user", "PopulateFuelHistoryAndSendAlert" : "master-or-user", "FireMaintenanceAlert" : "master-or-user", "ExportTractorOperatorIDAndTractorID" : "master-or-user", "updateTractorCreator" : "master-or-user", "PostTractorOperatorIDToAWS" : "master-or-user", "CreateUserApi" : "master-or-user", "AutomateReportsGeneration" : "master-or-user", "TractorWorkingOvertimeAlert" : "master-or-user", "_UpdateTractorOwnerOrgId" : "master-or-user", "_ProperlyFormatOrgIDsInUserCollection" : "master-or-user", "_UpdateStatusOfTractorsForThoseAssignedOperators" : "master-or-user", "UpdateTractorGeofenceV2" : "master-or-user", "_UploadMaintenanceCSVSheet" : "master-or-user", "updateTractorDetailOnUpdateFromQueue" : "master-or-user", "TestConsumer" : "master-or-user", "PushRecentBookings" : "master-or-user", "PushAdNotificationToCustomer" : "master-or-user", "updateUserOrgIdByEmail" : "master-or-user", "UpdateTractorsRealTimeLocation" : "master-or-user", "getFuelDataByTractorId" : "master-or-user", "TriggerPushNotification" : "master-or-user", "PopulateDemoData" : "master-or-user", "PopulateDemoBookings" : "master-or-user", "ComputeDailyFuelConsumed" : "master-or-user", "_ComputeDailyFuelConsumedInit" : "master-or-user", "__updateTractorLocationOnPostFromLocationService" : "master-or-user", "playground" : "master-or-user", "genericUpdate" : "master-or-user", "_FixTractorDetailGeofence" : "master-or-user", "__updateTractorActiveTimeToday" : "master-or-user", "__updateTractorDetailProps" : "master-or-user", "_MigrateTractorOwnerData" : "master-or-user", "__handlePushedAlertsMessages" : "master-or-user", "__activeTractorsPerMonthFinder" : "master-or-user", "__upload_mechanisation_service_as_bookings" : "master-or-user", "getPastMaintenanceForTractor" : "master-or-user", "NearbyTractorTechnician" : "master-or-user", "__pulled_trips_active_time_updater" : "master-or-user", "FetchBookingWeatherData" : "master-or-user" }, "NotificationGeoFenceMaintenance" : "append-only", "TractorCurrentLocation" : "append-read", "Maintenance" : "append-read", "TractorActivity" : "write", "TractorActivityData" : "write", "CumulativeTractorActivityData" : "append-read", "AgroDealersHeatMapData" : "append-read", "TrackerIds" : "write", "ServiceBookingHistory" : "append-read", "Notification" : "append-read", "TestTractorActivities" : "append-read", "UserFeedback" : "append-read", "user" : "append-read", "TestDailyTractorActivity" : "append-read", "OldDailyTractorActivity" : "append-read", "DailyTractorActivity" : "append-read", "BookingAgents" : { "create" : [ { "roleId" : "all-users", "type" : "always" } ], "read" : [ { "roleId" : "all-users", "type" : "always" } ], "update" : [ { "roleId" : "all-users", "type" : "always" } ], "delete" : [ { "roleId" : "all-users", "type" : "always" } ] }, "TwoTrackApiToken" : "append-read", "ServiceBookings" : { "create" : [ { "roleId" : "all-users", "type" : "always" } ], "read" : [ { "roleId" : "all-users", "type" : "grant" } ], "update" : [ { "roleId" : "all-users", "type" : "grant" } ], "delete" : [ { "roleId" : "all-users", "type" : "entity" } ] }, "TractorTips" : "append-read", "TractorAds" : "append-read", "FarmMeasure" : "append-read", "FarmMeasures" : "append-read", "AppVersionHistory" : "append-read", "Logger" : "append-read", "_blob" : { "create" : [ { "roleId" : "all-users", "type" : "always" } ], "read" : [ { "roleId" : "all-users", "type" : "always" } ], "update" : [ { "roleId" : "all-users", "type" : "always" } ], "delete" : [ { "roleId" : "all-users", "type" : "entity" } ] }, "FuelHistory" : "append-read", "UserAccounts" : "append-read", "OperatorReview" : "append-read", "Emails" : "append-read", "APIKeys" : "append-read", "MaintenanceRepo" : "append-read", "FailedPosts" : "append-read", "Logs" : "append-read", "DailyFuelConsumed" : "append-read", "FuelCalibrationResults" : "append-read", "MaintenanceHistory" : "append-read", "TractorTechnician" : "append-read" }, "bl" : { "Events" : { "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPreFetch 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\nfunction onPreFetch(request, response, modules) {\n \tvar currentUser = modules.requestContext.getAuthenticatedUserId();\n var logger = modules.logger;\n var obj = {\"creator\":currentUser,\"gr\":false,\"gw\":false};\n\n var token = \"\";\n\n collectionAccess.collection('TwoTrackApiToken').findOneAsync({id: 9228383772})\n .then(function(accessToken) {\n token = accessToken;\n \n },\n function(err) {\n \n return response.error(err);\n });\n \n \n var collectionName = request.collectionName;\n if (!currentUser || !collectionName) {\n\t return response.error(\"Invalid user\");\n\t} else{\n \tmodules.collectionAccess.collection('TractorDetail').find({\"Status\": 1, \"_acl\": obj}, function (err, docs) {\n \t logger.info(\"length of list \"+docs.length);\n if (err) {\n logger.error('Query failed: '+ err);\n } else {\n logger.info(\"Object.keys(docs).length=\"+Object.keys(docs).length);\n if(Object.keys(docs).length>0){\n docs.forEach(function(doc){\n logger.info(\"doc=\"+doc.TractorID);\n var requestData={\n \"token\": \"\"+token.token+\"\",\n \"trackerId\":doc.TractorID,\n \"startActivityId\":0,\n \"rowCount\":1,\n \"startUTCTime\":\"\",\n \"endUTCTime\":\"\"\n }\n var requestOptions = {\n 'url': 'https://hellotractor.2-track.com:8080/api/activity',\n headers: {\n \"Version\" : \"v1\",\n \"Content-Type\" : \"application/json\",\n // \"Accept\" :\"application/vnd.twotrack.v1+json\"\n },\n json:requestData\n }\n logger.info(\"reached here\");\n modules.request.post(requestOptions, function(error, resp, body){\n //logger.info(\"body=\"+body);\n //logger.info(\"error=\"+error);\n if (error){\n logger.info(\"error=\"+error);\n response.body = {error: error.message};\n response.complete(400);\n }else{\n // response.continue();\n var respData=resp.body.data;\n logger.info(\"respData=\"+respData);\n if(respData !==null && respData!== \"\"){\n respData.forEach(function(data,a){\n logger.info(\"data.activityId = \"+data.activityId);\n modules.collectionAccess.collection('Events').find({\"ActivityID\": data.activityId}, function (err, docs) {\n // response.continue();\n logger.info(\"docs.length = \"+docs.length);\n if(docs.length === 0){\n // response.continue();\n if (doc.OperatorID !== null){\n var entity = modules.kinvey.entity();\n entity.OperatorID=doc.OperatorID;\n logger.info(\"OperatorID id :\"+doc.OperatorID);\n entity.TractorID=doc.TractorID;\n entity.ActivityID=data.activityId; \n entity.EventCode=data.eventCode;\n entity.EventName=data.eventName;\n entity.Speed=data.speed;\n entity.Odometer=data.odometer;\n entity.Idle=data.idle;\n entity.IsGPSValid=data.isGPSValid;\n entity.LatLng=data.lat+\",\"+data.lon;\n entity.DirectionEW=data.directionEW;\n entity.DirectionNS=data.directionNS;\n entity.WindSpeed=data.windSpeed;\n entity.Altitude=data.altitude;\n entity.IgnitionStatus=data.ignitionStatus;\n logger.info(\"$$$$\" + entity.IgnitionStatus);\n entity.BatteryVoltage=data.batteryVoltage;\n entity.SatelliteNumber=data.satelliteNumber; \n entity.Street=data.street; \n entity.Town=data.town;\n entity.County=data.county; \n entity.Country=data.country; \n entity.ActivityUTCDate=data.activityUTCDate; \n entity._acl.setGloballyReadable(false);\n entity._acl.addReader(currentUser);\n entity._acl.addWriter(currentUser);\n modules.collectionAccess.collection(\"Events\").save(entity, function(err) {\n if (err !== null){\n logger.error('Query failed: '+ err);\n return response.error(err);\n } else{\n // response.continue();\n logger.info(\"saved\");\n }\n \n });//events collection end\n // response.continue();\n }\n // response.continue();\n }\n //response.continue();\n });\n // response.continue();\n });//resp foreach\n \n // response.continue();\n }//else if end\n \n }\n // response.continue();\n });// request end\n });//doc for each end\n }// doc null chk\n }\n // response.continue();\n });\n }\n response.continue();\n}\n\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n", "hasOnPreFetch" : true }, "EventType" : { "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPreSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\nfunction onPreSave(request, response, modules) {\n var currentUser = modules.requestContext.getAuthenticatedUserId();\n\tif (!currentUser) {\n\t return response.error(\"Invalid user\");\n\t}\n\tresponse.continue();\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n", "hasOnPreSave" : true }, "Farmer" : { "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\nvar isSendToAWSDone = false;\nvar isSendToBlockchainDone = false;\n\nfunction onPostSave(request, response, modules) {\n var async = modules.async;\n var httpRequest = modules.request;\n var logger = modules.logger;\n \n async.parallel({\n sendToAWSBackend: async.apply(\n sendToAWSBackend,\n httpRequest,\n logger,\n response\n ),\n sendToBlockchain: async.apply(\n sendToBlockchain,\n logger,\n response,\n httpRequest\n )\n });\n}\n\n//!important - Called when all functions have been executed\nfunction callback(response) {\n if (isSendToBlockchainDone && isSendToAWSDone) {\n response.continue();\n }\n}\n\nfunction sendToBlockchain(logger, response, httpRequest) {\n var msg = buildBlockchainMessage(response);\n var baseUrl = getBookingManagerBaseUrl();\n var url = baseUrl+\"/api/v1/users/add-farmer\";\n logger.info(url);\n var authorization = getBookingManagerToken();\n \thttpRequest.post(blockchainRequestOptions(response, msg, url, authorization), function(\n blockErr,\n blockRes,\n blockBody\n ) {\n logger.info(\n \"Blockchain Response: \" +\n JSON.stringify(blockErr) +\n \", \" +\n JSON.stringify(blockRes) +\n \", \" +\n JSON.stringify(blockBody)\n );\n if(blockRes.status != 200){\n \n var doc = {\n \turl: url, \n msg: msg, \n httpStatus: blockRes.status, \n no_tries: 0\n };\n var collectionName = getFailedTransactionsCollection();\n var failedPosts = modules.collectionAccess.collection(collectionName);\n \n failedPosts.save(doc, function(err, docs){\n if(err){\n logger.info(err);\n }\n\n //Done\n isSendToBlockchainDone = true;\n callback(response);\n }); \n \n } else {\n isSendToBlockchainDone = true;\n callback(response);\n }\n });\n}\n\nfunction buildBlockchainMessage(response) {\n var msg = {\n id: response.body._id,\n farmSize: response.body.FarmSize,\n farmerId: response.body.FarmerName,\n latLon: response.body.LatLong,\n location: response.body.Location,\n activityType: response.body.ActivityType,\n serialNum: response.body.SerialNum,\n };\n\n return msg;\n}\n\nfunction blockchainRequestOptions(response, msg, url, authorization) {\n //Send to IBM Swagger (REST API) \n var requestOptions = {\n uri: url,\n headers: {\n Authorization: authorization\n },\n json: msg\n };\n\n return requestOptions;\n}\n\n/**\n * *******************************************************************************************\n * Makes a copy of the farmer on the AWS Backend\n * @param httpRequest An object of the HTTP {@link modules.request} from the modules package\n * @param logger An object of the {@link modules.logger} library from the modules package\n * @param response The response to the client request\n * ********************************************************************************************\n */\n\nfunction sendToAWSBackend(httpRequest, logger, response) {\n var requestOptions = awsRequestOptions(response);\n httpRequest.post(requestOptions, function(awsErr, awsResp, awsBody) {\n logger.info(\"Results: \" + awsErr + \", \" + JSON.stringify(awsResp) + \", \" + awsBody);\n\n //Done\n isSendToAWSDone = true;\n callback(response);\n });\n}\n\nfunction awsRequestOptions(response) {\n var url = AWS_BACKEND_HOST+'/kinvey/api/farmers';\n\n var msg = {\n op: 'create',\n data: response.body\n };\n\n var requestOptions = {\n uri: url,\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n Version: \"v1\"\n },\n json: msg\n };\n\n return requestOptions;\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPreSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\nfunction onPreSave(request, response, modules) {\n var currentUser = modules.requestContext.getAuthenticatedUserId();\n var logger = modules.logger;\n var collectionName = request.collectionName;\n if (!currentUser || !collectionName) {\n\t return response.error(\"Invalid user\");\n\t} else if (currentUser && !request.body._id) {\n\t modules.collectionAccess.collection(collectionName).count({}, function (err, docs) {\n if (err) {\n logger.error('Query failed: '+ err);\n return response.error(err);\n } else {\n request.body.FarmerID = 300001 + docs;\n response.continue();\n }\n });\n\t} else {\n\t response.continue();\n\t}\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostDelete 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\nfunction onPostDelete(request, response, modules) {\n \n var req = modules.request;\n\tvar operation = 'delete';\n\t\n\tvar logger = modules.logger;\n\t\n\t//logger.info(response);\n\t//logger.info(request);\n \n var msg = {\n op: operation,\n data: request\n };\n \n req.post({\n uri : 'https://cloud.hellotractor.com/kinvey/api/farmers',\n json : msg\n }, function(error, res, body) {\n response.continue();\n });\n\t\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n", "hasOnPreSave" : true, "hasOnPostSave" : true, "hasOnPostDelete" : true }, "HectaresTilledCalculator" : { "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPreSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\nfunction onPreSave(request, response, modules) {\n\tvar logger = modules.logger;\n\tvar totalHectares = 0;\n\tvar tractorID = request.body.TractorId;\n var operatorID = request.body.OperatorId;\n var statusOfTractor = request.body.Status;\n var tractorName = request.body.TractorName;\n var currency = request.body.Currency;\n var rate = request.body.Rate;\n \n\tvar token = \"\";\n\n collectionAccess.collection('TwoTrackApiToken').findOneAsync({id: 9228383772})\n .then(function(accessToken) {\n token = accessToken;\n \n },\n function(err) {\n \n return response.error(err);\n });\n\t\n modules.collectionAccess.collection('TractorActivity').find({\"TractorId\": tractorID}, function (err, docs) {\n //logger.info(\"dosc from table : \"+ docs.length);\n if(docs.length > 0){\n docs.forEach(function(doc, a){\n //logger.info(\"doc :: \"+doc[0]);\n var hectServFloat = doc.HectaresServiced;\n \n totalHectares = totalHectares + hectServFloat;\n \n });\n }\n });\n var requestData={\n \"token\": \"\"+token.token+\"\",\n \"trackers\":[{\"trackerId\": tractorID}]\n };\n var requestOptions = {\n 'url': 'https://hellotractor.2-track.com:8080/api/status',\n headers: {\n \"Version\" : \"v1\",\n \"Content-Type\" : \"application/json\",\n // \"Accept\" :\"application/vnd.twotrack.v1+json\"\n },\n json:requestData,\n };\n modules.request.post(requestOptions, function(error, resp, body){\n \n if (error){\n logger.info(\"error=\"+error);\n response.body = {error: error.message};\n response.complete(400);\n }else{\n // response.continue();\n var respData=resp.body.data;\n logger.info(\"respData=\"+Object.keys(respData).length);\n if(Object.keys(respData).length > 0){\n respData.forEach(function(data,a){\n \n var odometerReading = totalHectares;\n var latitude = data.lat;\n var longitude = data.lon;\n var utcDate = data.lastReportUTCDate;\n var street = data.street;\n var town = data.town;\n modules.collectionAccess.collection('HectaresTilledCalculator').find({\"TractorId\": tractorID, \"OperatorId\": operatorID ,\"Status\": 1}, function (err, docs) {\n \n if (docs.length === 0) {\n var entity = modules.kinvey.entity();\n entity.TractorId = tractorID;\n entity.OperatorId = operatorID;\n entity.Status = 1;\n entity.HectaresTilledStartPT = totalHectares;\n entity.HectaresTilledStopPT = totalHectares;\n \n entity.Latitude = data.lat;\n entity.Longitude = data.lon;\n entity.Street = data.street;\n entity.Town = data.town;\n entity.Currency = \"RAND\";\n entity.Rate = 200;\n entity.TractorName = tractorName;\n entity.UtcDate = data.lastReportUTCDate;\n modules.collectionAccess.collection('HectaresTilledCalculator').save(entity, function (err) {\n logger.info(\"saved as new\");\n // response.continue();\n });\n } else {\n // response.continue();\n docs.forEach(function(doc, a) {\n var id = doc._id;\n doc.HectaresTilledStopPT = totalHectares;\n doc.Latitude = latitude;\n doc.Longitude = longitude;\n doc.UtcDate = utcDate;\n doc.Street = street;\n doc.Town = town;\n logger.info(\"Status = \"+statusOfTractor);\n doc.Status = statusOfTractor;\n doc.Currency = currency;\n doc.Rate = rate;\n // doc.TractorName = tractorName;\n logger.info(\"saved before\");\n modules.collectionAccess.collection('HectaresTilledCalculator').updateAsync({\"_id\": id}, doc, function (err, docs) {\n logger.info(\"updated\");\n // response.continue();\n });\n // response.continue();\n });\n }\n // response.continue();\n });\n });\n } else {\n modules.collectionAccess.collection('HectaresTilledCalculator').find({\"TractorId\": tractorID, \"OperatorId\": operatorID ,\"Status\": 1}, function (err, docs) {\n logger.info(\"no of docs present :: \"+docs.length);\n if (docs.length === 0) {\n var entity = modules.kinvey.entity();\n entity.TractorId = tractorID;\n entity.OperatorId = operatorID;\n logger.info(\"status inside=\"+statusOfTractor);\n entity.Status = statusOfTractor;\n entity.HectaresTilledStartPT = totalHectares;\n entity.HectaresTilledStopPT = totalHectares;\n logger.info(\"HectaresTilledStartPT :: \"+entity.HectaresTilledStartPT);\n entity.Latitude = 0.0;\n entity.Longitude = 0.0;\n entity.Street = \"\";\n entity.Town = \"\";\n entity.Currency = \"Nigerian Naira\";\n entity.Rate = 200;\n entity.UtcDate = \"\";\n modules.collectionAccess.collection('HectaresTilledCalculator').save(entity, function (err) {\n logger.info(\"saved as new\");\n // response.continue();\n });\n }else{\n docs.forEach(function(doc, a) {\n var id = doc._id;\n doc.HectaresTilledStopPT = totalHectares;\n doc.Latitude = 0.0;\n doc.Longitude = 0.0;\n doc.UtcDate = \"\";\n doc.Street = \"\";\n doc.Town = \"\";\n doc.Status = statusOfTractor;\n // doc.Currency = \"RAND\";\n // doc.Rate = 200;\n // doc.TractorName = tractorName;;\n modules.collectionAccess.collection('HectaresTilledCalculator').updateAsync({\"_id\": id}, doc, function (err, docs) {\n logger.info(\"updated\");\n // response.continue();\n });\n // response.continue();\n });\n }\n // response.continue();\n });\n // response.continue();\n }\n }\n response.complete();\n });\n \n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n", "hasOnPreSave" : true }, "Revenue" : { "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPreSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\nfunction onPreSave(request, response, modules) {\n /*var logger=modules.logger;\n\tvar tractorInfo = request.body.TractorId;\n\tlogger.info(tractorInfo);\n\tmodules.collectionAccess.collection('Events').find({\"TractorID\": tractorInfo}, function (err, docs) {\n\t var a = docs.length - 1;\n logger.info(\"docsss fetched \"+docs[a].Odometer);\n if (err) {\n logger.error('Query failed: '+ err);\n } else {\n var odometer=docs[a].Odometer;\n logger.info(\"@@@@@\"+ tractorInfo);\n modules.collectionAccess.collection('Revenue').find({\"TractorId\": tractorInfo}, function(err, docs) {\n logger.info(\"rev length\"+ docs.length);\n \n //logger.info(\"id\"+ id);\n if (err) {\n logger.error('Query failed: '+ err);\n } else {\n docs.forEach(function(doc){\n var id = doc._id;\n logger.info(\"odometer\"+odometer);\n doc.HectaresTilled = odometer;\n logger.info(\"#####\" + doc.HectaresTilled);\n modules.collectionAccess.collection('Revenue').updateAsync({\"_id\": id}, doc, function(err) {\n logger.info(\"saved\");\n });\n });\n response.continue();\n }\n });\n response.complete();\n }\n\t});*/\n\tresponse.continue();\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n", "hasOnPreSave" : true }, "TractorDetail" : { "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n// after tractor creation we create mandatory maintenance,\n// create or remove revenues if some of attachments were changed,\n// send revenue push\nvar isSendToBlockchainDone = false;\nvar isSendToAWSDone = false;\n\nfunction onPostSave(request, response, modules) {\n modules.logger.info('i got called');\n var async = modules.async;\n var httpRequest = modules.request;\n var logger = modules.logger;\nmodules.logger.info( request.body );\n async.parallel({\n sendToAWSBackend: async.apply(\n sendToAWSBackend,\n httpRequest,\n logger,\n response\n ),\n sendToBlockchain: async.apply(\n sendToBlockchain,\n logger,\n response,\n httpRequest\n )\n });\n}\n\n//!important - Called when all functions have been executed\nfunction callback(response) {\n if (isSendToBlockchainDone && isSendToAWSDone) {\n response.continue();\n }\n}\n\nfunction sendToBlockchain(logger, response, httpRequest) {\n var msg = buildBlockchainMessage(response);\n logger.info(msg);\n var baseUrl = getBookingManagerBaseUrl();\n var url = baseUrl+\"/api/v1/tractors\"; \n logger.info(url);\n var authorization = getBookingManagerToken();\n httpRequest.post(blockchainRequestOptions(msg, url, authorization), function(\n blockErr,\n blockRes,\n blockBody\n ) {\n logger.info(\n \"Blockchain Response: \" +\n JSON.stringify(blockErr) +\n \", \" +\n JSON.stringify(blockRes) +\n \", \" +\n JSON.stringify(blockBody)\n );\n if(blockRes.status != 200){\n \n var doc = {\n \turl: url, \n msg: msg, \n httpStatus: blockRes.status, \n no_tries: 0\n };\n var collectionName = getFailedTransactionsCollection();\n var failedPosts = modules.collectionAccess.collection(collectionName);\n \n \tfailedPosts.save(doc, function(err, docs){\n if(err){\n logger.info(err);\n }\n\n //Done\n isSendToBlockchainDone = true;\n callback(response);\n });\n \n } else {\n isSendToBlockchainDone = true;\n callback(response);\n }\n });\n}\n\nfunction buildBlockchainMessage(response) {\n modules.logger.info(\"About to build request message to Blockchain\");\n\tvar msg = { \n id:response.body._id,\n activeTimeToday:\tresponse.body.ActiveTimeToday,\n bookingRequests:\tresponse.body.BookingRequests,\n characteristic:\tresponse.body.Characteristic,\n country:\tresponse.body.Country,\n dailyTractorUpdates:\tresponse.body.DailyTractorUpdates,\n engineHours:\tresponse.body.EngineHours,\n lastActiveTime:\tresponse.body.LastActiveTime,\n lastActivityId:\tresponse.body.LastActivityId,\n lastGeofenceNotificationTime:\tresponse.body.LastGeofenceNotificationTime,\n latitude:\tresponse.body.Latitude,\n licensePlateNumber:\tresponse.body.license_plate_number,\n longitude:\tresponse.body.Longitude,\n needToSendGeofenceOutNotification:\tresponse.body.NeedToSendGeofenceOutNotification,\n operatorId:\tresponse.body.OperatorID,\n positionLatitude:\tresponse.body.PositionLatitude,\n positionLongitude:\tresponse.body.PositionLongitude,\n speed:\tresponse.body.Speed,\n status:\tresponse.body.Status,\n street:\tresponse.body.Street,\n totalDistanceCovered:\tresponse.body.TotalDistanceCovered,\n totalHectaresTilled:\tresponse.body.TotalHectaresTilled,\n town:\tresponse.body.Town,\n tractorID:\tresponse.body.TractorID,\n tractorName:\tresponse.body.TractorName,\n updated_at:\tmodules.moment(response.body.UpdatedAt).toISOString(),\n created_at:\tmodules.moment(response.body._kmd.lmt).toISOString(),\n wasInArea:\tresponse.body.WasInArea,\n acl: response.body._acl.creator,\n tractorModelId: response.body.TractorModelID\n\t};\n return msg;\n\n}\n\nfunction blockchainRequestOptions(msg, url, authorization) {\n //Send to IBM Swagger (REST API)\n var requestOptions = {\n uri: url,\n headers: {\n Authorization: authorization\n },\n json: msg\n };\n\n return requestOptions;\n}\n\n\n\n\n/**\n * *******************************************************************************************\n * Makes a copy of the tractor on the AWS Backend\n * @param httpRequest An object of the HTTP {@link modules.request} from the modules package\n * @param logger An object of the {@link modules.logger} library from the modules package\n * @param response The response to the client request\n * ********************************************************************************************\n */\n\nfunction sendToAWSBackend(httpRequest, logger, response) {\n logger.info('posting to aws backend');\n var requestOptions = awsRequestOptions(response);\n httpRequest.post(requestOptions, function(awsErr, awsResp, awsBody) {\n logger.info(\"Results: \" + awsErr + \", \" + JSON.stringify(awsResp) + \", \" + awsBody);\n\n //Done\n isSendToAWSDone = true;\n callback(response);\n });\n}\n\nfunction awsRequestOptions(response){\n var url = AWS_BACKEND_HOST+'/kinvey/api/tractors'; \n modules.logger.info(url);\n var msg = {\n op: \"create\",\n data: response.body\n };\n\n var requestOptions = {\n uri: url,\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n Version: \"v1\"\n },\n \n json: msg\n };\n\n return requestOptions;\n}\n\n\n\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPreSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\nfunction onPreSave(request, response, modules) {\n var collectionAccess = modules.collectionAccess,\n async = modules.async,\n logger = modules.logger,\n moment = modules.moment,\n tempObjectStore = modules.utils.tempObjectStore;\n \n \n var currentUser = modules.requestContext.getAuthenticatedUserId(),\n obj = {\"creator\": \"kid_bkFYnCzzzb\", \"gr\": false, \"r\": [currentUser], \"w\": [currentUser]},\n tractorId = request.body.TractorID;\n\n if(!currentUser) {\n logger.info(\"invalid user!\");\n return response.error(\"Invalid user\");\n } else {\n request.body.UpdatedAt = modules.moment().format('YYYY-MM-DD HH:mm:ss');\n \n if(request.method == 'PUT') {\n \n logger.info(request.body.Latitude);\n \t\t\t//logger.info(request.body.Longitude);\n \n collectionAccess.collection('TractorDetail').findOneAsync({TractorID: tractorId})\n .then(function(tractor) {\n var geofenceLatitude = request.body.Latitude,\n geofenceLongitude = request.body.Longitude;\n\n request.body.Street = tractor.Street;\n request.body.Town = tractor.Town;\n request.body.Country = tractor.Country;\n tempObjectStore.set('oldCharacteristic', tractor.Characteristic ? tractor.Characteristic : \"\");\n if(tractor && (tractor.Latitude != geofenceLatitude || tractor.Longitude != geofenceLongitude)) {\n request.body.NeedToSendGeofenceOutNotification = true;\n request.body.LastGeofenceNotificationTime = '';\n request.body.WasInArea = true;\n c_sendGeoFenceNotification(tractor, 'geofenceCreated', function(err) {\n if(err){\n return response.error(err);\n }\n return response.continue();\n });\n } else {\n return response.continue();\n }\n },\n function(err) {\n logger.info('error ' + JSON.stringify(err));\n return response.error(err);\n });\n } else {\n request.body.NeedToSendGeofenceOutNotification = true;\n request.body.LastGeofenceNotificationTime = '';\n request.body.WasInArea = true;\n request.body.Currency = null;\n\n collectionAccess.collection('TractorDetail').countAsync({TractorID: tractorId})\n .then(function(count) {\n if(count > 0) {\n return response.error('Tractor with the same Tractor ID already exists');\n } else {\n return response.continue();\n }\n }, function(err) {\n return response.error(err);\n });\n }\n }\n\n \n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostDelete 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\nfunction onPostDelete(request, response, modules) {\n \n var req = modules.request;\n\tvar operation = 'delete';\n\t\n\tvar logger = modules.logger;\n\t\n\t//logger.info(response);\n\t//logger.info(request);\n \n var msg = {\n op: operation,\n data: request\n };\n \n req.post({\n uri : 'http://cloud.hellotractor.com/kinvey/api/tractors',\n json : msg\n }, function(error, res, body) {\n response.continue();\n });\n\t\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n", "hasOnPreSave" : true, "hasOnPostSave" : true, "hasOnPostDelete" : true }, "TractorInfo" : { "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPreSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\nfunction onPreSave(request, response, modules) {\n\n\tvar req = modules.request;\n\tvar trackers=[];\n\tvar logger = modules.logger;\n\t\n\tvar token = \"\";\n\n collectionAccess.collection('TwoTrackApiToken').findOneAsync({id: 9228383772})\n .then(function(accessToken) {\n token = accessToken;\n \n },\n function(err) {\n \n return response.error(err);\n });\n\t\n\t\n\t modules.collectionAccess.collection('TractorDetail').find({}, function (err, docs) {\n if (err) {\n logger.error('Query failed: '+ err);\n } else {\n \n if(docs!==null && docs!==\"\"){\n docs.forEach(function(doc){\n \n var tacker={\n \"trackerId\":doc.TractorID\n };\n trackers.push(tacker);\n \n });\n trackers.push(tacker);\n }\n \n }\n\t \n\tvar requestData={\n \"token\": \"\"+token.token+\"\",\n \"trackers\" :trackers\n\t};\n\tlogger.info(requestData);\n\tvar requestOptions = {\n 'url': 'https://hellotractor.2-track.com:8080/api/tracker',\n headers: {\n \"Version\" : \"v1\",\n \"Content-Type\" : \"application/json\",\n \"Accept\" :\"application/vnd.twotrack.v1+json\"\n },\n json:requestData,\n };\n\treq.post(requestOptions, function(error, resp, body){\n\t \n if (error){\n response.body = {error: error.message};\n response.complete(400);\n return;\n }\n \n // saving data to db\n // response.continue();\n var respData=resp.body.data;\n \n if(respData !==null && respData!== \"\"){\n respData.forEach(function(data,a){\n \n var entity = modules.kinvey.entity();\n entity.TrackerId=data.trackerId;\n \n entity.TrackerName=data.trackerName;\n entity.VehicleNo=data.vehicleNo;\n entity.InstalledUTCDate=data.installedUTCDate;\n \n //calling db save function\n \n \n modules.collectionAccess.collection(\"TractorInfo\").save(entity, function(err) {\n if (err !== null){\n logger.error('Query failed: '+ err);\n return response.error(err);\n } else{\n // logger.info(entity);\n response.continue();\n }\n });\n \n });\n }\n \n response.complete(resp.status);\n});\n});\n}\n\n\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n//Flags indicating when each function has been executed regardless of an error\nvar isSendToBlockchainDone = false;\n\nfunction onPostSave(request, response, modules) {\n var async = modules.async;\n var httpRequest = modules.request;\n var logger = modules.logger;\n\n async.parallel({\n sendToBlockchain: async.apply(\n sendToBlockchain,\n logger,\n response,\n httpRequest\n )\n });\n}\n\n//!important - Called when all functions have been executed\nfunction callback(response) {\n if (isSendToBlockchainDone) {\n response.continue();\n }\n}\n\nfunction sendToBlockchain(logger, response, httpRequest) {\n var msg = buildBlockchainMessage(response);\n logger.info(msg);\n var baseUrl = getBookingManagerBaseUrl();\n var url = baseUrl+\"/api/v1/tractors/\"+response.body.VehicleNo+\"tractor-info\";\n logger.info(url);\n var authorization = getBookingManagerToken();\n httpRequest.post(blockchainRequestOptions(msg, url, authorization), function(\n blockErr,\n blockRes,\n blockBody\n ) {\n logger.info(\n \"Blockchain Response: \" +\n JSON.stringify(blockErr) +\n \", \" +\n JSON.stringify(blockRes) +\n \", \" +\n JSON.stringify(blockBody)\n );\n if(blockRes.status != 200){\n \n var doc = {\n \turl: url, \n msg: msg, \n httpStatus: blockRes.status, \n no_tries: 0\n };\n var collectionName = getFailedTransactionsCollection();\n var failedPosts = modules.collectionAccess.collection(collectionName);\n \n \tfailedPosts.save(doc, function(err, docs){\n if(err){\n logger.info(err);\n }\n\n //Done\n isSendToBlockchainDone = true;\n callback(response);\n });\n \n } else {\n isSendToBlockchainDone = true;\n callback(response);\n }\n });\n}\n\nfunction buildBlockchainMessage(response) {\n var msg = {\n _id: response.body._id,\n TrackerId: response.body.TrackerId,\n TrackerName: response.body.TrackerName,\n \tVehicleNo: response.body.VehicleNo,\n InstalledUTCDate: response.body.InstalledUTCDate,\n };\n\n return msg;\n}\n\nfunction blockchainRequestOptions(msg, url, authorization) {\n //Send to IBM Swagger (REST API)\n var requestOptions = {\n uri: url,\n headers: {\n Authorization: authorization\n },\n json: msg\n };\n\n return requestOptions;\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n", "hasOnPreSave" : true, "hasOnPostSave" : true }, "TractorOperator" : { "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n//Flags indicating when each function has been executed regardless of an error\nvar isSendToAWSDone = false;\nvar isSendToBlockchainDone = false;\n\nfunction onPostSave(request, response, modules) {\n var async = modules.async;\n var httpRequest = modules.request;\n var logger = modules.logger;\n var lodash = modules.lodash;\n var moment = modules.moment;\n\n async.parallel({\n sendToAWSBackend: async.apply(\n sendToAWSBackend,\n httpRequest,\n logger,\n response\n ),\n sendToBlockchain: async.apply(\n sendToBlockchain,\n logger,\n response,\n httpRequest,\n lodash,\n \tmoment\n )\n });\n}\n\n//!important - Called when all functions have been executed\nfunction callback(response) {\n if (isSendToAWSDone && isSendToBlockchainDone) {\n response.continue();\n }\n}\n\n\n/**\n * **********************************************************************************\n * Sends the tractor operator to IBM Swagger REST API\n * @param logger An object of the {@link modules.logger} class\n * @param response The response to the client request\n * @param httpRequest An object of the {@link modules.request} class\n * **********************************************************************************\n */\nfunction sendToBlockchain(logger, response, httpRequest, lodash, moment) {\n var baseUrl = getBookingManagerBaseUrl();\n var url = baseUrl+\"/api/v1/users/add-tractor-operator\";\n var authorization = getBookingManagerToken();\n var msg = buildBlockchainMessage(logger,response,lodash, moment);\n httpRequest.post(blockchainRequestOptions(logger, msg, url, authorization), function(\n blockErr,\n blockRes,\n blockBody\n ) {\n logger.info(\n \"Blockchain Response: \" +\n JSON.stringify(blockErr) +\n \", \" +\n JSON.stringify(blockRes) +\n \", \" +\n JSON.stringify(blockBody)\n );\n if(blockRes.status != 200){\n \n var doc = {\n \turl: url, \n msg: msg, \n httpStatus: blockRes.status, \n no_tries: 0\n };\n var collectionName = getFailedTransactionsCollection();\n var failedPosts = modules.collectionAccess.collection(collectionName);\n \n \tfailedPosts.save(doc, function(err, docs){\n if(err){\n logger.info(err);\n }\n\n //Done\n isSendToBlockchainDone = true;\n callback(response);\n });\n \n } else {\n isSendToBlockchainDone = true;\n callback(response);\n }\n });\n}\n\n function buildBlockchainMessage(logger,response,lodash, moment){\n \n logger.info(response.body);\n \n var pick = lodash.pick(response.body,['_id','LatLng','Location','OperatorID', 'OperatorRating', 'CreatedAt', 'UpdatedAt'])\n\n pick['_Id']=pick['_id'];\n pick['latLon']=pick['LatLng'];\n pick['location']=pick['Location'];\n pick['operatorId']=pick['OperatorID'];\n pick['operatorRating']=pick['OperatorRating'];\n// pick['created_at']=pick['CreatedAt'];\n// pick['updated_at']=pick['UpdatedAt'];\n \n pick['created_at'] = moment(lodash.get(response.body,'CreatedAt')).toISOString();\n pick['updated_at'] = moment(lodash.get(response.body,'UpdatedAt')).toISOString();\n \n pick['acl'] = response.body._acl.creator;\n delete pick['_id'];\n delete pick['LatLng'];\n delete pick['Location'];\n delete pick['OperatorID'];\n delete pick['OperatorRating'];\n delete pick['CreatedAt'];\n delete pick['UpdatedAt'];\n\n logger.info(\"picking items - Operator\");\n\n logger.info(pick);\n \n return pick; \n\n}\n\nfunction blockchainRequestOptions(logger, msg, url, authorization) {\n //Send to IBM Swagger (REST API)\n var requestOptions = {\n uri: url,\n headers: {\n Authorization: authorization\n },\n json: msg\n };\n\n return requestOptions;\n}\n\n\n/**\n * *******************************************************************************************\n * Makes a copy of the operator on the AWS Backend\n * @param httpRequest An object of the HTTP {@link modules.request} from the modules package\n * @param logger An object of the {@link modules.logger} library from the modules package\n * @param response The response to the client request\n * ********************************************************************************************\n */\n\nfunction sendToAWSBackend(httpRequest, logger, response) {\n var requestOptions = awsRequestOptions(response);\n httpRequest.post(requestOptions, function(awsErr, awsResp, awsBody) {\n logger.info(\"Results: \" + awsErr + \", \" + JSON.stringify(awsResp) + \", \" + awsBody);\n\n //Done\n isSendToAWSDone = true;\n callback(response);\n });\n}\n\nfunction awsRequestOptions(response){\n var url = AWS_BACKEND_HOST+'kinvey/api/operators'; \n modules.logger.info(url);\n var msg = {\n op: \"create\",\n data: response.body\n };\n\n var requestOptions = {\n uri: url,\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n Version: \"v1\"\n },\n json: msg\n };\n\n return requestOptions;\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPreSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\nfunction onPreSave(request, response, modules) {\n var currentUser = modules.requestContext.getAuthenticatedUserId();\n var logger = modules.logger;\n logger.info(\"request : \" + JSON.stringify(request.body));\n var collectionName = request.collectionName;\n if (!currentUser || !collectionName) {\n\t return response.error(\"Invalid user\");\n\t} else if (currentUser && !request.body.OperatorID) {\n\t modules.collectionAccess.collection(collectionName).count({}, function (err, docs) {\n if (err) {\n logger.error('Query failed: '+ err);\n return response.error(err);\n } else {\n \n //request.body.OperatorID = generate();\n response.continue();\n }\n });\n\t} else {\n\t response.continue();\n\t}\n\n\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostDelete 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\nfunction onPostDelete(request, response, modules) {\n \n var req = modules.request;\n\tvar operation = 'delete';\n\t\n\tvar logger = modules.logger;\n\t\n\t//logger.info(response);\n\t//logger.info(request);\n \n var msg = {\n op: operation,\n data: request\n };\n \n req.post({\n uri : 'http://cloud.hellotractor.com/kinvey/api/operators',\n json : msg\n }, function(error, res, body) {\n response.continue();\n });\n\t\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n", "hasOnPreSave" : true, "hasOnPostSave" : true, "hasOnPostDelete" : true }, "TractorOwner" : { "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n//Flags indicating when each function has been executed regardless of an error\nvar isSendToAWSDone = false;\nvar isSendToBlockchainDone = false;\n\nfunction onPostSave(request, response, modules) {\n var async = modules.async;\n var httpRequest = modules.request;\n var logger = modules.logger;\n var lodash = modules.lodash;\n var moment = modules.moment;\n\n async.parallel({\n sendToAWSBackend: async.apply(\n sendToAWSBackend,\n httpRequest,\n logger,\n response\n ),\n sendToBlockchain: async.apply(\n sendToBlockchain,\n logger,\n response,\n httpRequest,\n lodash,\n moment\n )\n });\n}\n\n//!important - Called when all functions have been executed\nfunction callback(response) {\n if (isSendToAWSDone && isSendToBlockchainDone) {\n response.continue();\n }\n}\n\n\n/**\n * **********************************************************************************\n * Sends the booking request to IBM Swagger REST API\n * @param logger An object of the {@link modules.logger} class\n * @param response The response to the client request\n * @param httpRequest An object of the {@link modules.request} class\n * **********************************************************************************\n */\nfunction sendToBlockchain(logger, response, httpRequest, lodash, moment) {\n var baseUrl = getBookingManagerBaseUrl();\n var url = baseUrl+\"/api/v1/users/add-tractor-owner\";\n var authorization = getBookingManagerToken();\n var msg = buildBlockchainMessage(logger, response, lodash, moment);\n \n httpRequest.post(blockchainRequestOptions(logger, msg, url, authorization), function(\n blockErr,\n blockRes,\n blockBody\n ) {\n logger.info(\n \"Blockchain Response: \" +\n JSON.stringify(blockErr) +\n \", \" +\n JSON.stringify(blockRes) +\n \", \" +\n JSON.stringify(blockBody)\n );\n\n if(blockRes.status != 200){\n \n var doc = {\n \turl: url, \n msg: msg, \n httpStatus: blockRes.status, \n no_tries: 0\n };\n var collectionName = getFailedTransactionsCollection();\n var failedPosts = modules.collectionAccess.collection(collectionName);\n \n \tfailedPosts.save(doc, function(err, docs){\n if(err){\n logger.info(err);\n }\n\n //Done\n isSendToBlockchainDone = true;\n callback(response);\n });\n \n } else {\n isSendToBlockchainDone = true;\n callback(response);\n }\n });\n}\n\n function buildBlockchainMessage(logger,response,lodash, moment){\n logger.info(response.body);\n var pick = lodash.pick(response.body,['_id','country','enableRevenue','maintenanceNotification', 'mpesaPaybillAccountId','systemNotifications','timezone','userLevel'])\n \n pick['acl'] = response.body._acl.creator;\n pick['created_at'] = moment(lodash.get(response.body,'_kmd.ect')).toISOString();\n pick['updated_at'] = moment(lodash.get(response.body,'_kmd.lmt')).toISOString();\n pick['orgId'] = response.body.orgID\n \n logger.info(\"picking items\");\n logger.info(pick);\n \n return pick;\n}\n\nfunction blockchainRequestOptions(logger, msg, url, authorization) {\n //Send to IBM Swagger (REST API)\n logger.info(\"here\");\n\n var requestOptions = {\n uri: url,\n headers: {\n Authorization: authorization\n },\n json: msg\n };\n\n return requestOptions;\n}\n\n\n\n/**\n * *******************************************************************************************\n * Makes a copy of the operator on the AWS Backend\n * @param httpRequest An object of the HTTP {@link modules.request} from the modules package\n * @param logger An object of the {@link modules.logger} library from the modules package\n * @param response The response to the client request\n * ********************************************************************************************\n */\n\nfunction sendToAWSBackend(httpRequest, logger, response) {\n var requestOptions = awsRequestOptions(response);\n httpRequest.post(requestOptions, function(awsErr, awsResp, awsBody) {\n logger.info(\"Results: \" + awsErr + \", \" + JSON.stringify(awsResp) + \", \" + awsBody);\n\n //Done\n isSendToAWSDone = true;\n callback(response);\n });\n}\n\nfunction awsRequestOptions(response){\n var url = AWS_BACKEND_HOST+'/kinvey/api/users'; \n modules.logger.info(url);\n var msg = {\n op: \"create\",\n data: response.body\n };\n\n var requestOptions = {\n uri: url,\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n Version: \"v1\"\n },\n json: msg\n };\n\n return requestOptions;\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n", "hasOnPostSave" : true }, "TractorToOperator" : { "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPreSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\nfunction onPreSave(request, response, modules) {\n var currentUser = modules.requestContext.getAuthenticatedUserId();\n var logger = modules.logger;\n logger.info(request.body);\n\tif (!currentUser) {\n\t return response.error(\"Invalid user\");\n\t}\n\tresponse.continue();\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n//Flags indicating when each function has been executed regardless of an error\nvar isSendToBlockchainDone = false;\n\nfunction onPostSave(request, response, modules) {\n var async = modules.async;\n var httpRequest = modules.request;\n var logger = modules.logger;\n\n async.parallel({\n sendToBlockchain: async.apply(\n sendToBlockchain,\n logger,\n response,\n httpRequest\n )\n });\n}\n\n\n//!important - Called when all functions have been executed\nfunction callback(response) {\n if (isSendToBlockchainDone) {\n response.continue();\n }\n}\n\n/**\n * **********************************************************************************\n * Sends the booking request to IBM Swagger REST API\n * @param logger An object of the {@link modules.logger} class\n * @param response The response to the client request\n * @param httpRequest An object of the {@link modules.request} class\n * **********************************************************************************\n */\nfunction sendToBlockchain(logger, response, httpRequest) {\n modules.collectionAccess.collection(response.body.TractorId._collection).\n findOne({\"_id\": modules.collectionAccess.objectID(response.body.TractorId._id)}, \n function(error, tractor){ \n \t\t\t\tif(error){ \n \tlogger.info(error);\n } else {\n if(tractor){\n logger.info(JSON.stringify(tractor)); \n modules.collectionAccess.collection(response.body.OperatorId._collection).\n findOne({\"_id\": modules.collectionAccess.objectID(response.body.OperatorId._id)},\n function(error, operator){\n if(error){\n logger.info(error);\n }else{\n if(operator != null){\n logger.info(JSON.stringify(operator));\n logger.info(\"Found operator\");\n var baseUrl = getBookingManagerBaseUrl();\n var url = baseUrl+\"/api/v1/tractors/tractor-to-operator/\";\n logger.info(url);\n var msg = {\n _id: response.body._id,\n tractorId : tractor.TractorID,\n operatorId : operator.OperatorID\n }\n logger.info(msg);\n var authorization = getBookingManagerToken();\n logger.info(authorization);\n \n httpRequest.post(blockchainRequestOptions(logger, msg, url, authorization),\n function(blockErr, blockRes, blockBody) {\n logger.info(\n \"Blockchain Response: \" +\n JSON.stringify(blockErr) +\n \", \" +\n JSON.stringify(blockRes) +\n \", \" +\n JSON.stringify(blockBody)\n );\n if(blockRes.status != 200){\n\n var doc = {\n url: url, \n msg: msg, \n httpStatus: blockRes.status, \n no_tries: 0\n };\n var collectionName = getFailedTransactionsCollection();\n var failedPosts = modules.collectionAccess.collection(collectionName);\n\n failedPosts.save(doc, function(err, docs){\n if(err){\n logger.info(err);\n }\n });\n\n }\n isSendToBlockchainDone = true;\n callback(response);\n });\n }\n }\n });\n }\n }});\n}\n\nfunction blockchainRequestOptions(msg, url, authorization) {\n //Send to IBM Swagger (REST API)\n var requestOptions = {\n uri: url,\n headers: {\n Authorization: authorization\n },\n json:{}\n };\n\n return requestOptions;\n}\n\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n", "hasOnPreSave" : true, "hasOnPostSave" : true }, "user" : { "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\nfunction onPostSave(request, response, modules) {\n var logger = modules.logger,\n collectionAccess = modules.collectionAccess;\n logger.info(request.body);\n\n var name = request.body.first_name,\n lastName = request.body.last_name,\n email = request.body.email,\n phone = request.body.phone,\n address = request.body.address,\n username = request.body.email,\n bookingAgentID = request.body.bookingAgentID,\n latitude = request.body.latitude,\n longitude = request.body.longitude,\n profileImage = request.body.profileImage,\n profileImageURL = request.body.profileImageURL,\n todaysDate = modules.moment.utc().format('YYYY-MM-DD HH:mm:ss'),\n _id = response.body._id,\n \t_kmd = response.body._kmd;\n \n \n var orgId = \"\";\n if(request.body.orgIDs){\n orgId = request.body.orgIDs;\n }\n \n var timeZone = \"\";\n if (request.body.timeZone){\n timeZone = request.body.timeZone;\n }\n \n var userId = response.body._id;\n \n logger.info(response.body);\n \n //Check if user type is booking agent. BA user type is 2\n if(request.body.user_type === 2){\n collectionAccess.collection('BookingAgents')\n .findOneAsync({bookingAgentID: bookingAgentID})\n .then(function(bookingAgent) {\n if(bookingAgent) {\n \n bookingAgent.name = name;\n bookingAgent.email = email;\n bookingAgent.phone = phone;\n bookingAgent.address = address;\n bookingAgent.username = phone;\n bookingAgent.latitude = latitude;\n bookingAgent.longitude = longitude;\n bookingAgent.bookingAgentID = bookingAgentID;\n bookingAgent.profileImage = profileImage; \n bookingAgent.profileImageURL = profileImageURL;\n bookingAgent.orgID = orgId;\n bookingAgent.userId = userId;\n \tbookingAgent.updatedAt = todaysDate;\n \n collectionAccess.collection('BookingAgents').update(\n {bookingAgentID : bookingAgentID}, \n bookingAgent, \n {upsert: true}, \n function(updateErr, updatedBookingAgent){\n if (updateErr){\n logger.error('Query failed for updating booking agent: ' + err);\n return response.error(err);\n }\n\n return response.complete(200);\n });\n \n } else {\n bookingAgent = {\n name: name,\n email: email,\n phone: phone,\n address: address,\n username: phone,\n latitude: latitude,\n longitude: longitude,\n profileImage: profileImage, \n profileImageURL: profileImageURL, \n bookingAgentID: bookingAgentID,\n orgID: orgId,\n createdAt: todaysDate,\n updatedAt: todaysDate,\n userId: userId\n };\n\n// var entity = modules.kinvey.entity(bookingAgent);\n bookingAgent._acl = response.body._acl;\n bookingAgent._id = response.body._id;\n bookingAgent._kmd = {\"lmt\":response.body._kmd.lmt,\"ect\":response.body._kmd.ect}; \n\n collectionAccess.collection('BookingAgents').save(bookingAgent, function(err) {\n if(err) {\n logger.error('Query failed for creating booking agent: ' + err);\n return response.error(err);\n }\n return response.complete(200);\n });\n }\n },\n function(err) {\n return response.error(err);\n });\n }\n else{\n \n collectionAccess.collection('TractorOwner')\n .findOneAsync({username: email})\n .then(function(tractorOwner) {\n if(tractorOwner) {\n return response.complete(200);\n } else {\n tractorOwner = {\n first_name: name,\n last_name: lastName,\n email: email,\n phone: phone,\n address: address,\n username: email,\n smsNotifications: false,\n emailNotifications: false,\n enableRevenue: true,\n\t\t\t\t\t\t\t\torgID: orgId,\n timeZone: timeZone\n };\n\n var entity = modules.kinvey.entity(tractorOwner);\n entity._acl = {creator: response.body._id};\n\n collectionAccess.collection('TractorOwner').save(entity, function(err) {\n if(err) {\n logger.error('Query failed for creating tractor owner: ' + err);\n return response.error(err);\n }\n return response.complete(200);\n });\n }\n },\n function(err) {\n return response.error(err);\n });\n \n }\n \n //}\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n", "hasOnPostSave" : true }, "_custom" : { "EventCodeDetails" : { "code" : "function onRequest(request, response, modules) {\r\n var logger = modules.logger;\r\n var req = modules.request;\r\n var token = \"\";\r\n\r\n collectionAccess.collection('TwoTrackApiToken').findOneAsync({id: 9228383772})\r\n .then(function(accessToken) {\r\n token = accessToken;\r\n \r\n },\r\n function(err) {\r\n \r\n return response.error(err);\r\n });\r\n //data to send in request body\r\n var requestData={\r\n \"token\": \"\"+token.token+\"\",\r\n };\r\n var requestOptions = {\r\n 'url': 'https://hellotractor.2-track.com:8080/api/event',\r\n headers: {\r\n \"Version\" : \"v1\",\r\n \"Content-Type\": \"application/json\",\r\n // \"Accept\" :\"application/vnd.hellotractor+json\",\r\n \"Accept\" :\"application/vnd.twotrack.v1+json\"\r\n },\r\n json:requestData,\r\n };\r\n req.post(requestOptions, function(error, resp, body){\r\n \r\n if (error){\r\n response.body = {error: error.message};\r\n return response.complete(400);\r\n }else{\r\n var respData=resp.body.data;\r\n if(respData !==null && respData!== undefined){\r\n respData.forEach(function(data,a){\r\n var entity = modules.kinvey.entity();\r\n entity.eventCode=data.eventCode;\r\n entity.eventName=data.eventName; \r\n modules.collectionAccess.collection(\"EventCodeDetails\").save(entity, function(err) {\r\n if (err !== null){\r\n logger.error('Query failed: '+ err);\r\n return response.error(err);\r\n } else{\r\n logger.info(\"saved\");\r\n }\r\n \r\n });\r\n });//resp foreach\r\n }\r\n }\r\n return response.complete();\r\n });\r\n \r\n}" }, "FarmerMessageExpiryCheck" : { "code" : "function onRequest(request, response, modules) {\n\t\tvar logger = modules.logger;\n modules.collectionAccess.collection('TelerivetFarmerInfo').find({\"Status\": 1}, function (err, docs) {\n if (err) {\n logger.error('Query failed: '+ err);\n } else {\n docs.forEach(function(doc, a) {\n var entity = modules.kinvey.entity();\n var endDateFromDatabase = doc.EndDate;\n var currentDate = new Date();\n var theMoment = modules.moment(currentDate);\n var currentDateFormat = theMoment.toString();\n var startDate = modules.moment(endDateFromDatabase, 'YYYY-M-DD HH:mm:ss');\n var endDate = modules.moment(currentDateFormat, 'YYYY-M-DD HH:mm:ss');\n var secondsDiff = startDate.diff(endDate, 'seconds');\n if(secondsDiff < 0){\n doc.Status = 0;\n modules.collectionAccess.collection(\"TelerivetFarmerInfo\").saveAsync(doc , function(err) {\n if (err !== null){\n logger.error('Query failed: '+ err);\n return response.error(err);\n } else{\n return response.complete(400);\n }\n });\n }\n });\n }\n return response.complete();\n });\n\n}" }, "GetTractorStatus" : { "code" : "function onRequest(request, response, modules) {\n var currentUser = modules.requestContext.getAuthenticatedUserId();\n\tvar logger = modules.logger;\n\tvar identifier=null;\n \n var token = \"\";\n\n collectionAccess.collection('TwoTrackApiToken').findOneAsync({id: 9228383772})\n .then(function(accessToken) {\n token = accessToken;\n \n },\n function(err) {\n \n return response.error(err);\n });\n \n \n\tmodules.collectionAccess.collection('HectaresTilledCalculator').find({\"Status\":1}, function (err, docs) {\n if (err) {\n logger.error('Query failed: '+ err);\n } else {\n docs.forEach(function(doc, a) {\n var tractorId = doc.TractorId;\n var operatorId = doc.OperatorId;\n var requestData={\n \"token\": \"\"+token.token+\"\",\n \"trackerId\":tractorId,\n \"startActivityId\":0,\n \"rowCount\":5,\n \"startUTCTime\":\"\",\n \"endUTCTime\":\"\"\n };\n var requestOptions = {\n 'url': 'https://hellotractor.2-track.com:8080/api/activity',\n headers: {\n \"Version\" : \"v1\",\n \"Content-Type\" : \"application/json\",\n // \"Accept\" :\"application/vnd.twotrack.v1+json\"\n },\n json:requestData,\n };\n modules.request.post(requestOptions, function(error, resp, body){\n \n if (error){\n response.body = {error: error.message};\n response.complete(400);\n }else{\n var respData=resp.body.data;\n if(respData !==null && respData!== \"\"){\n for(var i = respData.length-1 ; i >= 0; i-- ){\n var data = respData[i];\n if(data.eventCode === \"11\"){\n identifier = data.activityId + \"_\" + data.activityUTCDate;\n data.journeyIdentifier = identifier;\n }else{\n if(null !== identifier){\n data.journeyIdentifier = identifier;\n }else{\n modules.collectionAccess.collection('ActivityHectar').find({\"TractorId\":tractorId, \"OperatorId\":operatorId, \"JourneyEndTime\": \"\"}, function (err, docs) {\n \n if (docs.length === 0){\n response.complete();\n }else{\n identifier = doc[0].JourneyIdentifier;\n data.journeyIdentifier = identifier;\n }\n });\n }\n }\n }\n respData.forEach(function(data,a){\n if(data.eventCode === \"11\"){\n modules.collectionAccess.collection('ActivityHectar').find({\"ActivityId\":data.activityId}, function (err, docs) {\n \n if(docs.length === 0){\n var entity = modules.kinvey.entity();\n entity.TractorId = tractorId;\n entity.OperatorId = operatorId;\n entity.HectarTilledStartPT = data.odometer;\n entity.HectarTilledStopPT = data.odometer;\n entity.ActivityId = data.activityId;\n entity.JourneyStartTime = data.activityUTCDate;\n entity.JourneyEndTime = \"\";\n entity.Latitude = data.lat;\n entity.JourneyIdentifier = data.journeyIdentifier;\n entity.Longitude = data.lon;\n entity.IgnitionStatus = data.ignitionStatus;\n entity.Street = data.street;\n entity.Town = data.town;\n entity.County = data.county;\n entity.Country = data.country;\n modules.collectionAccess.collection('TractorOperator').find({\"OperatorID\":operatorId}, function (err, docs) {\n \n entity.OperatorName = docs[0].OperatorName;\n modules.collectionAccess.collection(\"ActivityHectar\").save(entity, function(err) {\n \n });\n response.continue();\n });\n }\n response.continue();\n });\n }\n else if (data.eventCode === \"12\"){\n modules.collectionAccess.collection('ActivityHectar').find({\"TractorId\":tractorId, \"OperatorId\":operatorId, \"JourneyEndTime\": \"\", \"JourneyIdentifier\": data.journeyIdentifier}, function (err, docs) {\n \n if (docs.length === 0){\n \n }else{\n docs.forEach(function(doc, a) {\n var id = doc._id;\n doc.JourneyEndTime = data.activityUTCDate;\n doc.HectarTilledStopPT = data.odometer;\n doc.Latitude = data.lat;\n doc.Longitude = data.lon;\n doc.IgnitionStatus = data.ignitionStatus;\n doc.Street = data.street;\n doc.Town = data.town;\n doc.County = data.county;\n doc.Country = data.country;\n modules.collectionAccess.collection('ActivityHectar').updateAsync({\"_id\": id}, doc, function (err, docs) {\n logger.info(\"update\");\n });\n });\n }\n });\n }\n else{\n \n modules.collectionAccess.collection('ActivityHectar').find({\"TractorId\":tractorId, \"OperatorId\":operatorId, \"JourneyEndTime\": \"\", \"JourneyIdentifier\": data.journeyIdentifier}, function (err, docs) {\n logger.info(\"docs ## ::\"+docs.length);\n if (docs.length === 0){\n response.complete();\n }else{\n docs.forEach(function(doc, a) {\n var id = doc._id;\n doc.HectarTilledStopPT = data.odometer;\n doc.Latitude = data.lat;\n doc.Longitude = data.lon;\n doc.IgnitionStatus = data.ignitionStatus;\n entity.JourneyIdentifier = data.journeyIdentifier;\n doc.Street = data.street;\n doc.Town = data.town;\n doc.County = data.county;\n doc.Country = data.country;\n modules.collectionAccess.collection('ActivityHectar').updateAsync({\"_id\": id}, doc, function (err, docs) {\n //logger.info(\"update again\");\n });\n });\n }\n });\n }\n });\n } \n }\n });\n });\n }\n\t});\n\t//response.complete(200);\n}" }, "NotificationGeoFence" : { "code" : "function onRequest(request, response, modules) {\n\tvar logger = modules.logger;\n\tvar token = \"\";\n\t\n\tcollectionAccess.collection('TwoTrackApiToken').findOneAsync({id: 9228383772})\n\t.then(function(accessToken) {\n\t\ttoken = accessToken;\n\t\t\n\t},\n\tfunction(err) {\n\t\t\n\t\treturn response.error(err);\n\t});\n\t\n\tmodules.collectionAccess.collection('TractorDetail').find({\"Status\":1}, function (err, docs) {\n\t logger.info(\"docs Length\" + docs.length);\n if (err) {\n logger.error('Query failed: '+ err);\n } else {\n docs.forEach(function(doc, a) {\n //logger.info(doc);\n if (doc.Latitude !== undefined || doc.Longitude !== undefined){\n var tractorId = doc.TractorID;\n var latitudeList = doc.Latitude;\n var longitudeList = doc.Longitude;\n var requestData={\n \"token\": \"\"+token.token+\"\",\n \"trackers\": [{\"trackerId\": tractorId}]\n };\n var requestOptions = {\n 'url': 'https://hellotractor.2-track.com:8080/api/status',\n headers: {\n \"Version\" : \"v1\",\n \"Content-Type\" : \"application/json\"\n },\n json:requestData,\n };\n modules.request.post(requestOptions, function(error, resp, body){\n if (error){\n logger.info(\"error=\"+error);\n response.body = {error: error.message};\n response.complete(400);\n }else{\n var respData=resp.body.data;\n if(respData !==null && respData!== \"\"){\n respData.forEach(function(data,a){\n var latitude = data.lat;\n var longitude = data.lon;\n \n var answer = checkcheck(latitude, longitude, latitudeList, longitudeList);\n logger.info(\"answer --- \"+answer);\n function checkcheck (xLat, yLng, latList, lngList) {\n var i, j=latList.length-1 ;\n var oddNodes=false;\n var polyLat = latList;\n var polyLng = lngList;\n for (i=0; i<latList.length; i++) {\n if((polyLng[i]< yLng && polyLng[j]>=yLng || polyLng[j]< yLng && polyLng[i]>=yLng) && (polyLat[i]<=xLat || polyLat[j]<=xLat)) {\n oddNodes^=(polyLat[i]+(yLng-polyLng[i])/(polyLng[j]-polyLng[i])*(polyLat[j]-polyLat[i])<xLat); \n }\n j=i;\n }\n logger.info(\"******\" + oddNodes);\n if(oddNodes === 0){\n modules.collectionAccess.collection('NotificationGeoFence').find({\"TractorId\":tractorId}, function (err, docs) {\n logger.info(\"docs.length : \" + docs.length);\n if (docs.length === 0) {\n var entity = modules.kinvey.entity();\n var date = new Date();\n entity.NotificationType = \"Alert\";\n entity.CurrentDate = date;\n entity.TractorId = tractorId;\n entity.Message = \"The tractor with tractor Id \"+ tractorId + \" is out of geofence area\";\n entity.ReadStatus = 0;\n entity._acl.setGloballyReadable(false);\n entity._acl.addReader(currentUser); \n entity._acl.addWriter(currentUser);\n logger.info(\"save\" + entity.TractorId);\n modules.collectionAccess.collection(\"NotificationGeoFenceMaintenance\").save(entity, function(err) {\n });\n }\n });\n }\n else if (oddNodes === 1){\n modules.collectionAccess.collection('NotificationGeoFenceMaintenance').findAndRemove({\"TractorId\":tractorId}, function (err, docs) {\n });\n }\n return oddNodes;\n }\n });\n }else{\n }\n response.complete();\n }\n });\n }\n });\n }\n\t});\n\t//response.complete(200);\n}" }, "TelerivetFarmerInfo" : { "code" : "function onRequest(request, response, modules) {\n var logger = modules.logger;\n var a;\n var smsContentToSent;\n var fromNumber;\n var mainObj = [];\n var tractorInformation = [];\n var farmerLatLngSplit = {};\n var tractorIds = [];\n var entity = modules.kinvey.entity();\n var saveForLoopValue;\n var lengthForCheck;\n var tractorLengthCheck;\n var saveTractorDetail = {TractorID : \"\" , OperatorID : \"\", Latitude: \"\", Longitude : \"\", OperatorPhoneNo : \"\", OperatorName : \"\", Radius : \"\"};\n modules.collectionAccess.collection('TelerivetFarmerInfo').find({}, function (err, docs) {\n var farmerLength = (docs.length)-1;\n if(docs.length>0){\n a = docs[farmerLength].SmsId;\n url = 'http://54.218.5.173/request/data?key=gaiSq3O2p7frojorudre&last_id=' + a;\n }else{\n url = 'http://54.218.5.173/request/data?key=gaiSq3O2p7frojorudre&last_id=146';\n }\n var requestOptions = {\n 'url': url,\n headers: {}\n };\n modules.request.post(requestOptions, function(error, resp, body){\n if (error){\n response.body = {error: error.message};\n // //response.complete(400);\n return;\n }\n response.body = JSON.parse(body);\n var temp=response[\"body\"].data;\n if (temp[0] === undefined){\n // //response.complete();\n }\n var smsId = temp[0].id;\n var smsFromNo = temp[0].from_number;\n fromNumber = smsFromNo;\n var smsToNo = temp[0].to_number;\n var smsType = temp[0].message_type;\n var smsContent = temp[0].content;\n var smsCont = smsContent.trim();\n if(smsCont.indexOf('10') !== 0){\n var entity = modules.kinvey.entity();\n entity.SmsId = temp[0].id;\n \n modules.collectionAccess.collection(\"TelerivetFarmerInfo\").save(entity, function(err) {\n response.complete();\n });\n } else{\n \n var smsDirection = temp[0].direction;\n var smsCreateTime = temp[0].created_at;\n modules.collectionAccess.collection('TelerivetFarmerInfo').find({\"FromNumber\": smsFromNo, \"Status\" : 1}, function (err, docs) {\n if(Object.keys(docs).length > 0){\n var i = 0;\n docs.forEach(function(doc, a) {\n var startDateFromDatabase = doc.StartDate;\n var theMomentStartDate = modules.moment(startDateFromDatabase);\n theMomentStartDate.add('hours', 6);\n var estimatedEndDate = theMomentStartDate.toString();\n var currentDate = new Date();\n var startDate = modules.moment(currentDate, 'YYYY-M-DD HH:mm:ss');\n var endDate = modules.moment(estimatedEndDate, 'YYYY-M-DD HH:mm:ss');\n var secondsDiff = startDate.diff(endDate, 'seconds');\n \n if(secondsDiff < 0){\n //Send message back to farmer\n }else{\n i++;\n if(i===1){\n farmerDetailsUpdate(temp);\n }\n }\n });\n } else {\n farmerDetailsUpdate(temp);\n }\n });\n }\n });\n ////response.complete();\n });\n \n function farmerDetailsUpdate(temp){\n //var tractorInformation = [];\n \n entity.SmsId = temp[0].id;\n var toUseLater = entity.SmsId;\n entity.FromNumber = temp[0].from_number;\n entity.ToNumber = temp[0].to_number;\n entity.SmsType = temp[0].message_type;\n logger.info(\"smsContent :: \"+temp[0].content);\n if(temp[0].content === \"101\"){\n entity.Content = \"tilling\"; \n } else if(temp[0].content === \"102\"){\n entity.Content = \"ploughing\";\n } else if(temp[0].content === \"103\"){\n entity.Content = \"ridging\";\n } else if(temp[0].content === \"104\"){\n entity.Content = \"planting\";\n } else if(temp[0].content === \"105\"){\n entity.Content = \"irrigating\";\n } else if(temp[0].content === \"106\"){\n entity.Content = \"reaping\";\n } else{\n entity.Content = \"hauling\";\n }\n smsContentToSent = entity.Content;\n \n entity.Direction = temp[0].direction;\n entity.CreationTime = temp[0].created_at;\n var smsFromNo = temp[0].from_number;\n var date = new Date();\n entity.StartDate = date;\n var theMoment = modules.moment(date);\n theMoment.add('hours', 6);\n var endDate = theMoment.toString();\n entity.EndDate = endDate;\n entity.Status = 1;\n modules.collectionAccess.collection(\"Farmer\").find({\"MobileNumber\": smsFromNo}, function (err, docs) {\n \n if (err) {\n \n response.complete(400)\n } else {\n \n docs.forEach(function(doc, a) {\n if(doc.length === 0){\n //response.complete();\n }\n farmerName = doc.FarmerName;\n var farmerLocation = doc.Location;\n var positionLatLng = doc.LatLong;\n farmerLatLngSplit = positionLatLng.split(\",\");\n });\n }\n //call list of tractor ids matching the feature\n modules.collectionAccess.collection(\"TractorDetail\").find({\"Status\": 1}, function (err, docs) {\n \n tractorLengthCheck = docs.length;\n \n if(docs.length > 0){\n var r = 0;\n var p = 0;\n docs.forEach(function(doc, a) {\n r++;\n var features = doc.Characteristic;\n if(features.indexOf(temp[0].content) > -1){\n var tractorDetail = {TractorID : \"\",OperatorID : \"\"};\n \n tractorDetail.TractorID = doc.TractorID;\n tractorDetail.OperatorID = doc.OperatorID;\n tractorIds.push(tractorDetail);\n logger.info(\"tractor Ids Array = \"+tractorIds[p]);\n p++;\n }\n \n if(tractorLengthCheck === r){\n lengthForCheck = tractorIds.length;\n var z = 0;\n for(var w = 0; w< tractorIds.length; w++){\n z++;\n saveForLoopValue = w;\n saveTractor(z,lengthForCheck,saveForLoopValue);\n }\n }\n });\n \n }\n });\n });\n }\n \n function saveTractor(z,lengthForCheck,saveForLoopValue){\n logger.info(\"tractor id=\"+tractorIds[saveForLoopValue].TractorID);\n modules.collectionAccess.collection(\"TractorCurrentLocation\").find({\"TractorId\": tractorIds[saveForLoopValue].TractorID}, function (err, docs) {\n if(docs.length > 0){\n \n saveTractorDetail.Latitude = docs[0].Latitude;\n saveTractorDetail.Longitude = docs[0].Longitude;\n \n modules.collectionAccess.collection(\"TractorOperator\").find({\"OperatorID\": tractorIds[saveForLoopValue].OperatorID}, function (err, docs) {\n saveTractorDetail.TractorID = tractorIds[saveForLoopValue].TractorID;\n saveTractorDetail.OperatorID = tractorIds[saveForLoopValue].OperatorID;\n saveTractorDetail.OperatorPhoneNo = docs[0].MobileNumber;\n saveTractorDetail.OperatorName = docs[0].OperatorName;\n saveTractorDetail.Radius = docs[0].Radius;\n tractorInformation.push(saveTractorDetail);\n if(lengthForCheck === z){\n sendMessage();\n }\n });\n }else{\n saveTractorDetail.TractorID = tractorIds[saveForLoopValue].TractorID;\n saveTractorDetail.OperatorID = tractorIds[saveForLoopValue].OperatorID;\n modules.collectionAccess.collection(\"TractorOperator\").find({\"OperatorID\": tractorIds[saveForLoopValue].OperatorID}, function (err, docs) {\n saveTractorDetail.OperatorPhoneNo = docs[0].MobileNumber;\n saveTractorDetail.OperatorName = docs[0].OpertorName;\n saveTractorDetail.Radius = docs[0].Radius;\n tractorInformation.push(saveTractorDetail); \n if(lengthForCheck === z){\n sendMessage();\n }\n });\n }\n });\n }\n \n \n function sendMessage(){\n \n for(var i = 0; i < tractorInformation.length; i++){\n if(tractorInformation[i].Latitude !== \"\"){\n var distance = calculateDistance(farmerLatLngSplit[0], farmerLatLngSplit[1], tractorInformation[i].Latitude, tractorInformation[i].Longitude);\n\n if(tractorInformation[i].Radius !== \"\"){\n if(distance <= parseInt(tractorInformation[i].Radius)/0.62137){\n var objItem={\"opertorId\": tractorInformation[i].OperatorID, \"distance\": distance, \"operatorName\": tractorInformation[i].OperatorName, \"operatorPhoneNo\": tractorInformation[i].OperatorPhoneNo};\n mainObj.push(objItem);\n }\n }\n }\n }\n if(mainObj.length > 1){\n var listOfDistances = mainObj.sort(compare);\n //logger.info(\"listOfDistances = \"+listOfDistances[0]);\n sendMessageToOperator(listOfDistances[0].operatorName,farmerName,fromNumber,smsContentToSent,listOfDistances[0].operatorPhoneNo);\n entity.FarmerName = farmerName;\n entity.ListOfDistances = listOfDistances;\n modules.collectionAccess.collection(\"TelerivetFarmerInfo\").save(entity, function(err) {\n if (err !== null){\n return response.error(err);\n } else{\n }\n });\n }else{\n response.complete();\n }\n }\n \n //function to do compare list of distances\n function compare(a,b) {\n\n if (a.distance < b.distance)\n return -1;\n else if (a.distance > b.distance)\n return 1;\n else \n return 0;\n }\n //calculate the distances from farmer to list of tractors\n function calculateDistance(lat1, long1, lat2, long2){ \n //radians\n lat1 = (lat1 * 2.0 * Math.PI) / 60.0 / 360.0; \n long1 = (long1 * 2.0 * Math.PI) / 60.0 / 360.0; \n lat2 = (lat2 * 2.0 * Math.PI) / 60.0 / 360.0; \n long2 = (long2 * 2.0 * Math.PI) / 60.0 / 360.0; \n var a = 6378137.0; // Earth Major Axis (WGS84) \n var b = 6356752.3142; // Minor Axis \n var f = (a-b) / a; // \"Flattening\" \n var e = 2.0*f - f*f; // \"Eccentricity\" \n var beta = (a / Math.sqrt( 1.0 - e * Math.sin( lat1 ) * Math.sin( lat1 ))); \n var cos = Math.cos( lat1 ); \n var x = beta * cos * Math.cos( long1 ); \n var y = beta * cos * Math.sin( long1 ); \n var z = beta * ( 1 - e ) * Math.sin( lat1 ); \n beta = ( a / Math.sqrt( 1.0 - e * Math.sin( lat2 ) * Math.sin( lat2 ))); \n cos = Math.cos( lat2 ); \n x -= (beta * cos * Math.cos( long2 )); \n y -= (beta * cos * Math.sin( long2 )); \n z -= (beta * (1 - e) * Math.sin( lat2 )); \n return (Math.sqrt( (x*x) + (y*y) + (z*z) )/1000); \n }\n //send sms to nearest tractor, but sms will go to the operator phone number \n function sendMessageToOperator(operatorName,farmerName,smsFromNo,smsContent,phoneNumber){\n //logger.info(\"@ phoneNumber : \"+phoneNumber);\n //logger.info(\"@ operatorName : \"+operatorName);\n //logger.info(\"@ farmerName : \"+farmerName);\n //logger.info(\"@ smsFromNo : \"+smsFromNo);\n //logger.info(\"@ smsContent : \"+smsContent);\n var headers = {\n \"Content-Type\": \"application/json\"\n };\n var opti = {\n url: 'https://api.telerivet.com/v1/projects/PJ2743212d87e98295/messages/send',\n headers: headers,\n json: {\n \"api_key\":\"yZZA48CDp07DkzGgKyVyTDKX0KODJHOF\",\n \"content\": \"Hello \" + operatorName +\", farmer \" + farmerName +\", with phone number: \" + smsFromNo +\" has requested \" + smsContent +\" services. Please reply yes or no to 2348176017561 to accept or decline this request within 6 hours\", \"to_number\": phoneNumber}\n };\n //logger.info(\"phonenumber1 : \"+phoneNumber);\n modules.request.post(opti, function (error, resp, body) {\n //logger.info(\"#####\");\n //logger.info(\"@@@@@@\");\n response.complete();\n });\n }\n}" }, "forgotPassword" : { "code" : "function onRequest(request, response, modules) {\n\tresponse.complete(500);\n}" }, "getActivity" : { "code" : "function onRequest(request, response, modules) {\n var collectionAccess = modules.collectionAccess\n , logger = modules.logger\n , body = request.body\n , resultA = null, resultB = null, callback;\n callback = function(){\n if (resultA){\n // Got both responses\n response.body = {Events: resultA};\n return response.complete(200);\n } else {\n // Still waiting for the other response.\n return response.complete(500);\n }\n };\n collectionAccess.collection('Events')\n .find({name: body.thing}, function (err, docs)\n {\n if (err) {\n logger.error('Query failed: '+ err);\n response.body.debug = err;\n return response.complete(500);\n } else {\n resultA = docs;\n callback();\n }\n });\n // response.complete(200);\n}" }, "getTractors" : { "code" : "function onRequest(request, response, modules) {\n var collectionAccess = modules.collectionAccess\n , logger = modules.logger\n , body = request.body\n , resultA = null, resultB = null, callback;\n logger.info(modules.requestContext);\n callback = function(){\n if (resultA){\n // Got both responses\n response.body = {Events: resultA};\n return response.complete(200);\n } else {\n // Still waiting for the other response.\n return response.complete(500);\n }\n };\n collectionAccess.collection('Events').find({name: body.thing}, function (err, docs) {\n if (err) {\n logger.error('Query failed: '+ err);\n response.body.debug = err;\n return response.complete(500);\n } else {\n resultA = docs;\n callback();\n }\n });\n}" }, "responseFromOperator" : { "code" : "function onRequest(request, response, modules) {\n\tvar req = modules.request;\n\tvar logger = modules.logger;\n\tvar farmerName;\n\tvar smsFromNum;\n\t var url;\n modules.collectionAccess.collection('ResponseFromOperator').find({}, function (err, docs) {\n var farmerLength = (docs.length)-1;\n if(docs.length>0){\n var a = docs[farmerLength].SmsId;\n url = 'http://54.218.5.173/request/data?key=gaiSq3O2p7frojorudre&last_id=' + a;\n }else{\n url = 'http://54.218.5.173/request/data?key=gaiSq3O2p7frojorudre&last_id=146';\n }\n\tvar requestOptions = {\n 'url': url,\n headers: {}\n }\n req.post(requestOptions, function(error, resp, body){\n if (error){\n response.body = {error: error.message};\n response.complete(400);\n return;\n }\n response.body = JSON.parse(body);\n var temp=response[\"body\"].data;\n if (temp[0] === undefined){\n response.complete();\n }\n var smsId = temp[0].id;\n var entity = modules.kinvey.entity();\n entity.SmsId = temp[0].id;\n modules.collectionAccess.collection(\"ResponseFromOperator\").save(entity, function(err) {\n logger.info(\"i m just saving sms id in db\");\n });\n var operatorNo = temp[0].from_number;\n var smsContent = temp[0].content;\n var smsContentTrimed = smsContent.trim();\n var splitStrng = smsContentTrimed.split(\" \");\n if(splitStrng.length < 6){\n response.complete();\n }\n logger.info(\"split \"+splitStrng[0]);\n logger.info(\"split 1 \"+splitStrng[1].trim());\n if((smsContent.search('yes') <= 5) || (smsContent.search('YES') <= 5)){\n modules.collectionAccess.collection(\"Farmer\").find({\"MobileNumber\": splitStrng[1].trim()}, function (err, docs) {\n logger.info(\"farmer length=\"+docs.length);\n if (err) {\n logger.error('Query failed: '+ err);\n return response.error(err);\n } else {\n docs.forEach(function(doc, a) {\n var id = doc._id;\n doc.OperatorNumber = operatorNo;\n farmerName=doc.FarmerName;\n smsFromNum = doc.MobileNumber;\n logger.info(\"farmerName\"+farmerName);\n logger.info(\"smsFromNum\"+smsFromNum);\n modules.collectionAccess.collection(\"Farmer\").updateAsync ({_id: id}, doc, function(err) {\n if (err !== null){\n logger.error('Query failed: '+ err);\n return response.error(err);\n } else{\n response.continue();\n }\n });\n });\n }\n return response.complete();\n });\n } else if((smsContent.search('no') <= 5) || (smsContent.search('NO') <= 5)){\n modules.collectionAccess.collection('TelerivetFarmerInfo').find({\"FromNumber\": splitStrng[1]}, function (err, docs) {\n if (err) {\n logger.error('Query failed: '+ err);\n return response.error(err);\n } else {\n docs.forEach(function(doc, a) {\n var id = doc._id;\n logger.info(\"doc\" + doc);\n doc.ListOfDistances.splice(0,1);\n modules.collectionAccess.collection('TelerivetFarmerInfo').updateAsync ({_id: id}, doc, function(err) {\n });\n var nextOperatorNo = doc.ListOfDistances[0].operatorPhoneNo;\n var nextOperatorName = doc.ListOfDistances[0].opertorName;\n smsFromNum = doc.FromNumber;\n farmerName = doc.FarmerName;\n var smsContent = doc.Content;\n sendMessageToOperator(nextOperatorNo,farmerName,smsFromNum,nextOperatorName,smsContent);\n });\n }\n });\n } else {\n return response.complete();\n }\n \n });\n });\n function sendMessageToOperator(phoneNumber,farmerName,smsFromNo,operatorName,smsContent){\n var headers = {\n \"Content-Type\": \"application/json\"\n };\n var opti = {\n url: 'https://api.telerivet.com/v1/projects/PJ2743212d87e98295/messages/send',\n headers: headers,\n json: {\n \"api_key\":\"yZZA48CDp07DkzGgKyVyTDKX0KODJHOF\",\n \"content\": \"Hello \" + operatorName +\", farmer \" + farmerName +\", with phone number: \" + smsFromNo +\" has requested \" + smsContent +\" services. Please reply yes or no to 2348176017561 to accept or decline this request within 6 hours\", \"to_number\": phoneNumber}\n };\n modules.request.post(opti, function (error, resp, body) {\n\n return response.complete();\n });\n }\n}" }, "ActionStatusMaintenanceLog" : { "code" : "function onRequest(request, response, modules) {\n var currentUser = modules.requestContext.getAuthenticatedUserId();\n\tvar logger = modules.logger;\n\tmodules.collectionAccess.collection('Maintenance').find({\"Status\": 0}, function (err, docs) {\n if (err) {\n logger.error('Query failed: '+ err);\n } else {\n docs.forEach(function(doc, a) {\n var id = doc._id;\n var date = new Date();\n\t var dateProper = date.toString();\n\t var currentDateTime = dateProper.slice(4,18);\n\t // logger.info(\"from newdate :\" + currentDateTime);\n\t var dateDb = doc.RepairDate;\n\t var properRepairDateTime = dateDb.slice(4,18);\n\t // logger.info(\"from DB :\"+properRepairDateTime);\n\t if (properRepairDateTime === currentDateTime){\n\t // logger.info(\"status will change\");\n\t doc.Status = 1;\n\t modules.collectionAccess.collection('Maintenance').updateAsync({\"_id\": id}, doc, function (err, docs) {\n\n\t });\n\t }\n });\n }\n \n\t});\n\tmodules.collectionAccess.collection('Maintenance').find({\"Status\": 1}, function (err, docs) {\n\t logger.info(\"******** \" + docs.length);\n\t docs.forEach(function(doc, a) {\n\t var aclId = doc._acl;\n \t var entity = modules.kinvey.entity();\n var date = new Date();\n entity.NotificationType = \"Action\";\n entity.CurrentDate = date;\n entity.TractorId = doc.TractorId;\n var tractId = entity.TractorId;\n entity.Message = \"Have you checked and adjusted the \"+ doc.Description + \" on tractor \" + doc.TractorId + \"? If you have done so click here to reset the counter\";\n entity.ReadStatus = 0;\n modules.collectionAccess.collection('NotificationGeoFenceMaintenance').find({\"TractorId\": tractId, \"NotificationType\": \"Action\"}, function (err, docs) {\n \n if(docs.length > 0){\n docs.forEach(function(doc, a) {\n if(doc.Message !== entity.Message){\n // entity._acl.setGloballyReadable(false);\n // entity._acl.addReader(aclId); \n // entity._acl.addWriter(aclId);\n entity._acl = aclId;\n modules.collectionAccess.collection(\"NotificationGeoFenceMaintenance\").save(entity, function(err) {\n });\n }\n });\n \n }else{\n // entity._acl.setGloballyReadable(false);\n // entity._acl.addReader(aclId); \n // entity._acl.addWriter(aclId);\n //logger.info(\"save\" + aclId);\n entity._acl = aclId;\n modules.collectionAccess.collection(\"NotificationGeoFenceMaintenance\").save(entity, function(err) {\n return response.complete();\n });\n }\n \n });\n\t });\n return response.complete();\n });\n\t\n}" }, "AlertTwoTrackEventNotifications" : { "code" : "function onRequest(request, response, modules) {\n\tvar currentUser = modules.requestContext.getAuthenticatedUserId();\n\tvar logger = modules.logger;\n\t\n\tvar token = \"\";\n\n collectionAccess.collection('TwoTrackApiToken').findOneAsync({id: 9228383772})\n .then(function(accessToken) {\n token = accessToken;\n \n },\n function(err) {\n \n return response.error(err);\n });\n\t\n\tmodules.collectionAccess.collection('TractorDetail').find({\"Status\":1}, function (err, docs) {\n if (err) {\n logger.error('Query failed: '+ err);\n } else {\n docs.forEach(function(doc, a) {\n var tractorId = doc.TractorID;\n var aclId = doc._acl;\n var requestData={\n \"token\": \"\"+token.token+\"\",\n \"trackerId\":tractorId,\n \"startActivityId\":0,\n \"rowCount\":10,\n \"startUTCTime\":\"\",\n \"endUTCTime\":\"\"\n };\n var requestOptions = {\n 'url': 'https://hellotractor.2-track.com:8080/api/activity',\n headers: {\n \"Version\" : \"v1\",\n \"Content-Type\" : \"application/json\",\n // \"Accept\" :\"application/vnd.twotrack.v1+json\"\n },\n json:requestData,\n };\n modules.request.post(requestOptions, function(error, resp, body){\n logger.info(\"resp\"+resp);\n if (error){\n logger.info(\"error=\"+error);\n response.body = {error: error.message};\n return response.complete(400);\n }else{\n var respData=resp.body.data;\n if(respData !==null && respData!== \"\"){\n for(var i = respData.length-1 ; i >= 0; i-- ){\n var data = respData[i];\n if (data.eventCode === \"90\" || data.eventCode === \"91\"){\n var entity = modules.kinvey.entity();\n var date = new Date();\n entity.NotificationType = \"Alert\";\n entity.CurrentDate = date;\n entity.TractorId = tractorId;\n var tractId = entity.TractorId;\n entity.Message = \"Battery is running low on tractor \"+ tractorId + \". Consider replacing the battery\";\n entity.ReadStatus = 0;\n modules.collectionAccess.collection('NotificationGeoFenceMaintenance').find({\"TractorId\": tractId, \"NotificationType\": \"Alert\"}, function (err, docs) {\n \n if(docs.length > 0){\n docs.forEach(function(doc, a) {\n \n if(doc.Message !== entity.Message){\n entity._acl = aclId;\n modules.collectionAccess.collection(\"NotificationGeoFenceMaintenance\").save(entity, function(err) {\n return response.complete();\n });\n }\n });\n }else{\n entity._acl = aclId;\n modules.collectionAccess.collection(\"NotificationGeoFenceMaintenance\").save(entity, function(err) {\n return response.complete();\n });\n }\n });\n }\n \n }\n }\n }\n \n });\n });\n }\n\t});\n}" }, "AlertStatusMaintenanceLog" : { "code" : "function onRequest(request, response, modules) {\n var currentUser = modules.requestContext.getAuthenticatedUserId();\n\tvar logger = modules.logger;\n\tmodules.collectionAccess.collection('Maintenance').find({\"Status\": 0}, function (err, docs) {\n\t logger.info(\"Maintenance row :: \" + docs.length);\n if (err) {\n logger.error('Query failed: '+ err);\n } else {\n docs.forEach(function(doc, a) {\n var id = doc._id;\n var date = new Date();\n\t var dateProper = date.toString();\n\t var currentDateTime = dateProper.slice(4,18);\n\t //logger.info(\"from newdate :\" + currentDateTime);\n\t var dateDb = doc.RepairDate;\n\t var properRepairDateTime = dateDb.slice(4,18);\n\t //logger.info(\"from DB :\"+properRepairDateTime);\n\t if (properRepairDateTime === currentDateTime){\n\t //logger.info(\"status will change\");\n\t doc.Status = 1;\n\t modules.collectionAccess.collection('Maintenance').updateAsync({\"_id\": id}, doc, function (err, docs) {\n\t //logger.info(\"updated\");\n \n\t });\n\t }\n });\n }\n\t});\n\tmodules.collectionAccess.collection('Maintenance').find({\"Status\": 1}, function (err, docs) {\n\t docs.forEach(function(doc, a) {\n\t var aclId = doc._acl;\n //logger.info(\"aclId : \" + aclId);\n \t var entity = modules.kinvey.entity();\n var date = new Date();\n entity.NotificationType = \"Alert\";\n entity.CurrentDate = date;\n entity.TractorId = doc.TractorId;\n var tractId = entity.TractorId;\n entity.Message = \"It is time to \"+ doc.Description + \" on tractor \" + doc.TractorId;\n entity.ReadStatus = 0;\n modules.collectionAccess.collection('NotificationGeoFenceMaintenance').find({\"TractorId\": tractId, \"NotificationType\": \"Alert\"}, function (err, docs) {\n \n logger.info(\"length in notif table : \" + docs.length);\n if(docs.length > 0){\n docs.forEach(function(doc, a) {\n if(doc.Message !== entity.Message){\n // entity._acl.setGloballyReadable(false);\n // entity._acl.addReader(aclId); \n // entity._acl.addWriter(aclId);\n \n entity._acl = aclId;\n modules.collectionAccess.collection(\"NotificationGeoFenceMaintenance\").save(entity, function(err) {\n \n });\n \n }\n \n });\n \n }else{\n // entity._acl.setGloballyReadable(false);\n // entity._acl.addReader(aclId); \n // entity._acl.addWriter(aclId);\n //logger.info(\"save2\" + aclId);\n entity._acl = aclId;\n modules.collectionAccess.collection(\"NotificationGeoFenceMaintenance\").save(entity, function(err) {\n \n });\n }\n });\n\t });\n //logger.info(\"docs with status 1 \"+docs.length);\n return response.complete();\n });\n}" }, "TractorCurrentLocation" : { "code" : "function onRequest(request, response, modules) {\n\tvar logger = modules.logger,\n\ttoken = \"\";\n\t\n\tmodules.collectionAccess.collection('TwoTrackApiToken').findOneAsync({id: 9228383772})\n\t.then(function(accessToken) {\n\t\ttoken = accessToken;\n\t\t\n\t},\n\tfunction(err) {\n\t\t\n\t\treturn response.error(err);\n\t});\n\t\n\tmodules.collectionAccess.collection('TractorDetail').find({\"Status\": 1}, function (err, docs) {\n\t \n\t docs.forEach(function(doc, a){\n\t var tractorId = doc.TractorID;\n\t var requestData={\n \"token\": \"\"+token.token+\"\",\n \"trackers\":[{\"trackerId\": tractorId}]\n };\n var requestOptions = {\n 'url': 'https://hellotractor.2-track.com:8080/api/status',\n headers: {\n \"Version\" : \"v1\",\n \"Content-Type\" : \"application/json\",\n // \"Accept\" :\"application/vnd.twotrack.v1+json\"\n },\n json:requestData,\n };\n modules.request.post(requestOptions, function(error, resp, body){\n logger.info(\"response=\"+resp);\n if (error){\n response.body = {error: error.message};\n return response.complete(400);\n }else{\n var respData=resp.body.data;\n if(respData !==null && respData!== \"\"){\n respData.forEach(function(data,a){\n var entity = modules.kinvey.entity();\n entity.TractorId = tractorId;\n \n entity.Latitude = data.lat;\n \n entity.Longitude = data.lon;\n \n modules.collectionAccess.collection('TractorCurrentLocation').find({\"TractorId\": tractorId}, function (err, docs) {\n \n if(docs.length === 0){\n \n modules.collectionAccess.collection('TractorCurrentLocation').saveAsync(entity, function (err) {\n logger.info(\"saved as new\");\n //response.continue();\n });\n }else{\n docs.forEach(function(doc, a){\n var id = doc._id;\n doc.TractorId = tractorId;\n doc.Latitude = data.lat;\n doc.Longitude = data.lon;\n modules.collectionAccess.collection('TractorCurrentLocation').updateAsync({\"_id\": id}, doc, function (err, docs) {\n \n });\n });\n }\n });\n });\n } else{\n return response.complete();\n }\n }\n });\n\t });\n\t return response.complete();\n\t});\n}" }, "MaintenanceCalculate" : { "code" : "function onRequest(request, response, modules) {\n\tvar logger = modules.logger;\n\tvar timeAdd;\n var lengthForCheck;\n var TotalTimeTaken = 0;\n var MaintananceObject;\n var id;\n\tmodules.collectionAccess.collection('TractorDetail').find({}, function (err, docs) {\n\t //logger.info(\"docs.length : \" + docs.length);\n\t docs.forEach(function(doc, a) {\n\t //logger.info(\"tractId TractorDetail : \" + doc.TractorID);\n\t modules.collectionAccess.collection('Maintenance').find({\"TractorId\": doc.TractorID}, function (err, docs) {\n\t //logger.info(\"docs.length Maintenance : \" + docs.length);\n\t id = 0;\n\t docs.forEach(function(doc, a) {\n\t MaintananceObject = doc;\n\t id = doc._id;\n\t var maintenanceDate = doc.Date;\n\t var maintTractId = doc.TractorId;\n\t //logger.info(\"maintTractId : \" + maintTractId);\n\t //logger.info(\"maintenanceDate : \" + new Date(maintenanceDate));\n\t checkTractorActivity(MaintananceObject,id, maintTractId,maintenanceDate);\n\t });\n\t });\n\t });\n\t response.complete();\n\t});\n\t\n\tfunction checkTractorActivity(MaintananceObject,id,tractorId,maintenanceDate){\n\t modules.collectionAccess.collection('TractorActivity').find({\"TractorId\": tractorId}, function (err, docs) {\n lengthForCheck = docs.length;\n var z = 0;\n timeAdd = 0;\n docs.forEach(function(doc, a) {\n z++;\n var tractorActivityDate = doc.StartTimeStamp;\n if(new Date(tractorActivityDate) >= new Date(maintenanceDate)){\n timeAdd = timeAdd + parseFloat(doc.TotalTimeServiced);\n TotalTimeTaken = timeAdd; \n }\n //logger.info(\"lengthForCheck = \"+lengthForCheck);\n //logger.info(\"lengthForCheck z = \"+z);\n if(lengthForCheck === z){\n //logger.info(\"lengthForCheck equal =\"+TotalTimeTaken + \" id :\" + id);\n if(TotalTimeTaken !== 0){\n updateMaintanence(TotalTimeTaken, MaintananceObject, id);\n TotalTimeTaken = 0;\n }\n }\n });\n });\n\t}\n\t\n\tfunction updateMaintanence(timeTakenValue, doc, id){\n\t //logger.info(\"doc value = \"+doc);\n\t //logger.info(\"timeTakenValue = \"+timeTakenValue);\n\t //logger.info(\"id id = \"+id);\n\t doc.TimeTaken = timeTakenValue;\n \tmodules.collectionAccess.collection(\"Maintenance\").updateAsync({_id: id}, doc, function(err) {\n \t});\n\t}\n\t//response.complete(200);\n}" }, "RunMaintenanceRepairNotification" : { "code" : "function onRequest(request, response, modules) {\n var logger = modules.logger;\n var currentUser = modules.requestContext.getAuthenticatedUserId();\n modules.collectionAccess.collection('Maintenance').find({}, function (err, docs) {\n if (err) {\n logger.error('Query failed: '+ err);\n } else {\n docs.forEach(function(doc, a) {\n var beforeDuration = doc.Duration - 4;\n if(doc.TimeTaken > beforeDuration){\n var id = doc._id;\n doc.Status = 1;\n\t modules.collectionAccess.collection('Maintenance').updateAsync({\"_id\": id}, doc, function (err, docs) {\n \t logger.info(\"updated\");\n \n \t });\n var entity = modules.kinvey.entity();\n var date = new Date();\n entity.NotificationType = \"Action\";\n entity.CurrentDate = date;\n entity.TractorId = doc.TractorId;\n entity.Message = \"Have you checked and adjusted the \"+ doc.Description + \" on tractor \" + doc.TractorId + \"? If you have done so click here to reset the counter\";\n entity.ReadStatus = 0;\n // entity._acl.setGloballyReadable(false);\n // entity._acl.addReader(currentUser); \n // entity._acl.addWriter(currentUser);\n modules.collectionAccess.collection(\"NotificationGeoFenceMaintenance\").save(entity, function(err) {\n response.complete();\n });\n }\n });\n }\n });\n\t//response.complete();\n}" }, "TotalHectareForTractor" : { "code" : "function onRequest(request, response, modules) {\n\tvar logger = modules.logger;\n\tvar totalHectaresCalculate = 0.0;\n\tmodules.collectionAccess.collection('TractorDetail').find({}, function (err, docs) {\n\t //logger.info(\"docs : \" + docs.length);\n\t if(docs.length > 0){\n\t docs.forEach(function(doc, a){\n\t \n\t var tractorId = doc.TractorID;\n\t modules.collectionAccess.collection('HectaresTilledCalculator').find({\"TractorId\": tractorId}, function (err, docs) {\n\t \n\t if(docs.length > 0){\n\t var totalHectaresCalculate = docs[docs.length-1].HectaresTilledStopPT;\n\t \n\t modules.collectionAccess.collection('TractorDetail').find({\"TractorID\": tractorId}, function (err, docs) {\n\t \n\t if(docs.length > 0){\n\t docs.forEach(function(doc, a){\n\t var id = doc._id;\n\t doc.TotalHectaresTilled = totalHectaresCalculate;\n\t \n modules.collectionAccess.collection('TractorDetail').updateAsync({\"_id\": id}, doc, function (err, docs) {\n \n });\n\t });\n\t }\n\t });\n\t } else if(docs.length === 0){\n\t totalHectaresCalculate = 0.0;\n\t modules.collectionAccess.collection('TractorActivity').find({\"TractorId\": tractorId}, function (err, docs) {\n \n if(docs.length > 0){\n docs.forEach(function(doc, a){\n //logger.info(\"doc :: \"+doc[0]);\n var hectServFloat = doc.HectaresServiced;\n \n totalHectaresCalculate = totalHectaresCalculate + hectServFloat;\n //logger.info(\"totalHectaresCalculate :: \"+totalHectaresCalculate);\n });\n var id = doc._id;\n doc.TotalHectaresTilled = parseFloat(totalHectaresCalculate);\n \n modules.collectionAccess.collection('TractorDetail').updateAsync({\"_id\": id}, doc, function (err, docs) {\n \n });\n \n //response.complete(200);\n }\n });\n\t }\n\t });\n\t });\n\t \n\t }\n\t});\n\tresponse.complete();\n}" }, "TractorActivity" : { "code" : "function onRequest(request, response, modules) {\n var logger = modules.logger;\n var a;\n\tmodules.collectionAccess.collection('TractorActivity').find({}, function (err, docs) {\n logger.info(\"rowLength = \"+docs.length);\n var rowLength = (docs.length)-1;\n if(docs.length>0){\n a = docs[rowLength].Id;\n logger.info(\"a\" + a);\n url = 'http://54.218.5.173/tractors/hectares?key=7f8Q72tXhh&last_id=' + a;\n }else{\n url = 'http://54.218.5.173/tractors/hectares?key=7f8Q72tXhh&last_id=0';\n }\n var requestOptions = {\n 'url': url,\n headers: {}\n };\n modules.request.get(requestOptions, function(error, resp, body){\n logger.info(\"resp \" + resp);\n logger.info(\"body \" + body);\n if (error){\n response.body = {error: error.message};\n response.complete(400);\n return;\n }\n response.body = JSON.parse(body);\n var temps=response[\"body\"].data;\n temps.forEach(function(temp, a) {\n logger.info(\"temp \" + temp);\n if (temp === undefined){\n response.complete();\n }\n var id = temp.id;\n var tractorId = temp.tractor_id;\n logger.info(\"tractorId : \" + tractorId);\n var hectaresServiced = temp.hectares_serviced;\n var totalTimeServiced = temp.total_time_serviced;\n var startTimeStamp = temp.start_time_stamp;\n var endTimeStamp = temp.end_time_stamp;\n var entity = modules.kinvey.entity();\n entity.Id = id;\n logger.info(\"is to be stored \" + entity.Id);\n entity.TractorId = parseInt(tractorId);\n entity.HectaresServiced = parseFloat(hectaresServiced);\n entity.TotalTimeServiced = totalTimeServiced;\n entity.StartTimeStamp = startTimeStamp;\n entity.EndTimeStamp = endTimeStamp;\n modules.collectionAccess.collection(\"TractorActivity\").save(entity, function(err) {\n response.complete();\n });\n \n });\n });\n\t});\n\tresponse.complete();\n}" }, "AutoRunMaintenance" : { "code" : "function onRequest(request, response, modules) {\n var logger = modules.logger;\n modules.collectionAccess.collection('Maintenance').find({}, function (err, docs) {\n logger.info(\"docs.length : \" + docs.length);\n if (err) {\n logger.error('Query failed: '+ err);\n return response.complete(400);\n } else {\n docs.forEach(function(doc, a) {\n var id = doc._id;\n var dur = doc.Duration;\n var startDate = doc.Date;\n var theMoment = modules.moment(startDate);\n theMoment.add('hours', doc.Duration);\n var latestRepairDate = theMoment.toString();\n doc.RepairDate = latestRepairDate;\n //doc.Duration = 600;\n modules.collectionAccess.collection(\"Maintenance\").updateAsync({_id: id}, doc, function(err) {\n return response.complete();\n });\n });\n return response.complete();\n }\n });\n}" }, "demo-endpoint" : { "code" : "function onRequest(request, response, modules) {\n\tresponse.body = {name : \"Edward Pie\", email : \"hackstockpie@gmail.com\"};\n\tresponse.complete(200)\n}" }, "push-demo" : { "code" : "//Used to test push notifications.\n//You can set 'type' in request body to receive\n//different pushes\n\nfunction onRequest(request, response, modules) {\n var collectionAccess = modules.collectionAccess,\n logger = modules.logger,\n moment = modules.moment,\n type = request.body.type;\n\n var username = 'admin@hellotractor.com';\n\n collectionAccess.collection('user').findOneAsync({username: username})\n .then(function(user) {\n if(!user) {\n return response.error('user with username ' + username + ' was not found');\n }\n var notifications;\n if(type == 'geofence') {\n notifications = [\n //{\n // message: 'Geofence in',\n // userId: user._id.toString(),\n // type: 'alert',\n // action: 'none',\n // read: false,\n // tractorId: 100007,\n // operatorId: 200008\n //},\n {\n message: 'Test Geofence notification',\n userId: user._id.toString(),\n type: 'action',\n action: 'geofence_out',\n read: false,\n tractorId: 100007,\n operatorId: 200008\n }];\n }else if(type =='maintenancePartial') {\n notifications = [\n {\n message: 'Maintenance 80% Alert!',\n userId: user._id.toString(),\n type: 'action',\n action: 'maintenance_partial',\n read: false,\n tractorId: 100007,\n operatorId: 200008\n }];\n }else if (type == 'maintenance'){\n notifications = [\n {\n message: 'Maintenance full Alert!',\n userId: user._id.toString(),\n type: 'action',\n action: 'maintenance',\n read: false,\n tractorId: 100007,\n operatorId: 200008\n }];\n }else if(type == 'revenue'){\n notifications = [\n {\n message: 'Please set some revenue',\n userId: user._id.toString(),\n type: 'action',\n action: 'revenue',\n read: false,\n tractorId: 100007,\n operatorId: 200008\n }];\n } else {\n notifications = [\n {\n message: 'Action-based test notification ' + moment().toISOString(),\n userId: user._id.toString(),\n type: 'action',\n action: 'maintance',\n read: false\n },\n {\n message: 'Alert-based test notification ' + moment().toISOString(),\n userId: user._id.toString(),\n type: 'alert',\n action: 'none',\n read: false\n }];\n }\n\n logger.info('notifications ' + JSON.stringify(notifications));\n c_sendNotifications(notifications, function(err) {\n if(err) {\n return response.error(err);\n }\n\n return response.complete(200);\n });\n\n }, function(err) {\n return response.error(err);\n });\n //response.complete(200);\n}\n" }, "SyncCollections" : { "code" : "//Used to sync Operators, Farmers, Tractors on client side in local db\n//for better searching performance\n\nfunction onRequest(request, response, modules) {\n var collectionAccess = modules.collectionAccess,\n logger = modules.logger,\n async = modules.async,\n lastSyncDate = request.body.lastSyncDate,\n query = lastSyncDate ? {'_kmd.lmt': {$gt: lastSyncDate}} : {};\n\n async.parallel({\n operators: async.apply(fetchData, query, 'TractorOperator'),\n tractors: async.apply(fetchData, query, 'TractorDetail'),\n farmers: async.apply(fetchData, query, 'Farmer')\n }, function(err, data) {\n if(err) {\n return response.error(err);\n }\n response.body = data;\n return response.complete(200);\n });\n\n\n function fetchData(query, collectionName, cb) {\n collectionAccess.collection(collectionName).find(query, {}, cb);\n }\n}\n" }, "MarkNotificationAsRead" : { "code" : "//Used to mark notification as read\n\nfunction onRequest(request, response, modules) {\n var collectionAccess = modules.collectionAccess,\n logger = modules.logger,\n async = modules.async,\n moment = modules.moment;\n\n var userId = request.body.userId;\n if(userId){\n logger.info(\"userId posted so about to delete all notifications for user \"+ userId);\n \n //then let's handle deleting for all\n collectionAccess.collection('Notification')\n .remove({\n userId: userId\n },function(err){\n if(err){\n logger.info(\"error: \"+ err);\n return response.error(err);\n }\n return response.complete(200);\n });\n }\n else{\n var notificationId = request.body.notificationId;\n if(!notificationId) {\n return response.error('notificationId parameter is required');\n }\n\n collectionAccess.collection('Notification')\n .update({_id: collectionAccess.objectID(notificationId)}, {\n $set: {\n read: true,\n readTime: moment().toISOString()\n }\n }, function(err) {\n if(err) {\n return response.error(err);\n }\n return response.complete(200);\n });\n }\n\n \n //response.complete(200);\n}\n" }, "FilterDailyTractorActivities" : { "code" : "function onRequest(request, response, modules) {\n var collectionAccess = modules.collectionAccess,\n async = modules.async,\n logger = modules.logger,\n moment = modules.moment;\n\n var start = request.body.start,\n end = request.body.end,\n tractorId = request.body.TractorID;\n\n if(!start || !end || !tractorId) {\n return response.error('start, end and TractorID parameters are required');\n }\n\n start = moment(start).format('YYYY-MM-DD');\n end = moment(end).format('YYYY-MM-DD');\n\n collectionAccess.collection('DailyTractorActivity').findAsync({\n TractorID: tractorId,\n day: {\n $gte: start,\n $lte: end\n }\n }, {sort: {day: 1}})\n .then(function(tractorActivities) {\n var startActivity = tractorActivities[0],\n endActivity = tractorActivities[tractorActivities.length - 1],\n totalSpeed = 0,\n totalSpeedCounter = 0,\n result = {\n Hectares: 0,\n Revenue: 0,\n DistanceTravelled: 0,\n TotalTimeActive: 0,\n TotalTimeIdle: 0,\n Route: [],\n Country: endActivity.Country,\n Town: endActivity.Town,\n Street: endActivity.Street,\n IgnitionStatus: endActivity.IgnitionStatus,\n StartActiveData: startActivity.StartActiveData,\n LastActiveData: endActivity.LastActiveData,\n OperatorID: endActivity.OperatorID,\n TractorID: tractorId,\n StartTown: startActivity.StartTown,\n StartCountry: startActivity.StartCountry,\n StartStreet: startActivity.StartStreet\n };\n tractorActivities.forEach(function(tractorActivity) {\n result.Hectares += tractorActivity.Hectares ? tractorActivity.Hectares : 0;\n result.Revenue += tractorActivity.Revenue ? tractorActivity.Revenue : 0;\n totalSpeed += tractorActivity.TotalSpeed ? tractorActivity.TotalSpeed : 0;\n totalSpeedCounter += tractorActivity.TotalSpeedCounter ? tractorActivity.TotalSpeedCounter : 0;\n result.DistanceTravelled += tractorActivity.DistanceTravelled ? tractorActivity.DistanceTravelled : 0;\n result.TotalTimeActive += tractorActivity.TotalTimeActive ? tractorActivity.TotalTimeActive : 0;\n result.TotalTimeIdle += tractorActivity.TotalTimeIdle ? tractorActivity.TotalTimeIdle : 0;\n result.Route = result.Route.concat(tractorActivity.Route);\n });\n result.AverageSpeed = totalSpeedCounter > 0 ? (totalSpeed / totalSpeedCounter).toFixed(1) : totalSpeed;\n\n collectionAccess.collection('TractorOperator').findOneAsync({OperatorID: result.OperatorID})\n .then(function(operator) {\n result.operator = operator;\n response.body = result;\n return response.complete(200);\n }, function(err) {\n return response.error(err);\n });\n }, function(err) {\n return response.error(err);\n });\n}\n" }, "DisableGeofenceNotifications" : { "code" : "function onRequest(request, response, modules) {\n var collectionAccess = modules.collectionAccess,\n logger = modules.logger,\n moment = modules.moment,\n async = modules.async;\n\n var tractorId = request.body.tractorId;\n if(!tractorId) {\n return response.error('tractorId parameter is required');\n }\n\n collectionAccess.collection('TractorDetail').update({TractorID: tractorId}, {\n $set: {\n NeedToSendGeofenceOutNotification: false\n }\n }, function(err) {\n if(err) {\n return response.error(err);\n }\n response.body = {};\n return response.complete(200);\n });\n \n}" }, "ResetMaintenanceCounter" : { "code" : "function onRequest(request, response, modules) {\n var collectionAccess = modules.collectionAccess,\n logger = modules.logger,\n async = modules.async,\n moment = modules.moment,\n requestContext = modules.requestContext;\n\n var maintenanceId = request.body.maintenanceId;\n if(!maintenanceId) {\n return response.error('maintenanceId parameter is required');\n }\n\n collectionAccess.collection('MaintenanceActivity').update({_id: collectionAccess.objectID(maintenanceId)},\n {\n $set: {\n Counter: 0,\n Status: 1\n }\n }, function(err) {\n if(err) {\n return response.error(err);\n }\n response.body = {};\n return response.complete(200);\n });\n //response.complete(200);\n}" }, "CopyMaintenanceActivities" : { "code" : "function onRequest(request, response, modules) {\n var collectionAccess = modules.collectionAccess,\n logger = modules.logger,\n async = modules.async,\n moment = modules.moment,\n requestContext = modules.requestContext;\n\n var fromTractorId = request.body.fromTractorId,\n toTractorId = request.body.toTractorId,\n currentUserId = requestContext.getAuthenticatedUserId();\n\n async.parallel({\n fromTractorMaintenance: async.apply(getMaintenanceByTractorId, fromTractorId),\n toTractorMaintenance: async.apply(getMaintenanceByTractorId, toTractorId)\n }, function(err, results) {\n if(err) {\n return response.error(err);\n }\n var fromTractorMaintenance = results.fromTractorMaintenance,\n toTractorMaintenance = results.toTractorMaintenance;\n\n async.parallel({\n copyPredefinedMaintenance: async.apply(copyPredefinedMaintenance, fromTractorMaintenance, toTractorMaintenance),\n copyCustomMaintenance: async.apply(copyCustomMaintenance, fromTractorMaintenance, toTractorMaintenance)\n }, function(err) {\n if(err) {\n return response.error(err);\n }\n response.body = {};\n return response.complete();\n });\n });\n\n function copyPredefinedMaintenance(fromTractorMaintenance, toTractorMaintenance, cb) {\n var fromTractorPredefinedMaintenance = fromTractorMaintenance.filter(function(maintenance) {\n return maintenance.Type == 1;\n }),\n toTractorPredefinedMaintenance = toTractorMaintenance.filter(function(maintenance) {\n return maintenance.Type == 1;\n }),\n newTractorPredefinedMaintenance;\n\n var fromPredefinedMaintenanceIds = fromTractorPredefinedMaintenance.map(function(maintenance) {\n return maintenance.PredefinedMaintenanceActivityId;\n }),\n toPredefinedMaintenanceIds = toTractorPredefinedMaintenance.map(function(maintenance) {\n return maintenance.PredefinedMaintenanceActivityId;\n }),\n newPredefinedMaintenanceIds = [];\n\n fromPredefinedMaintenanceIds.forEach(function(fromPredefinedMaintenanceId) {\n if(toPredefinedMaintenanceIds.indexOf(fromPredefinedMaintenanceId) == -1) {\n newPredefinedMaintenanceIds.push(fromPredefinedMaintenanceId);\n }\n });\n\n newTractorPredefinedMaintenance = fromTractorPredefinedMaintenance.filter(function(maintenence) {\n return newPredefinedMaintenanceIds.indexOf(maintenence.PredefinedMaintenanceActivityId) != -1;\n });\n\n logger.info('new maintenance predefined ' + JSON.stringify(newTractorPredefinedMaintenance));\n\n async.each(newTractorPredefinedMaintenance, handlePredefinedMaintenance, cb);\n\n function handlePredefinedMaintenance(predefinedMaintenance, cb) {\n var maintenanceActivity = {\n TractorID: toTractorId,\n Duration: predefinedMaintenance.Duration,\n Description: predefinedMaintenance.Description,\n PredefinedMaintenanceActivityId: predefinedMaintenance.PredefinedMaintenanceActivityId,\n CurrentUserId: currentUserId\n };\n c_createNewMaintenanceActivity(maintenanceActivity, cb);\n }\n\n }\n\n function copyCustomMaintenance(fromTractorMaintenance, toTractorMaintenance, cb){\n var fromTractorCustomMaintenance = fromTractorMaintenance.filter(function(maintenance) {\n return maintenance.Type == 2;\n }),\n toTractorCustomMaintenance = toTractorMaintenance.filter(function(maintenance) {\n return maintenance.Type == 2;\n }),\n newTractorCustomMaintenance;\n\n var fromCustomMaintenanceDescriptions = fromTractorCustomMaintenance.map(function(maintenance) {\n return maintenance.Description;\n }),\n toCustomMaintenanceDescriptions = toTractorCustomMaintenance.map(function(maintenance) {\n return maintenance.Description;\n }),\n newCustomMaintenanceDescriptions = [];\n\n fromCustomMaintenanceDescriptions.forEach(function(fromCustomMaintenanceDescription) {\n if(toCustomMaintenanceDescriptions.indexOf(fromCustomMaintenanceDescription) == -1) {\n newCustomMaintenanceDescriptions.push(fromCustomMaintenanceDescription);\n }\n });\n\n newTractorCustomMaintenance= fromTractorCustomMaintenance.filter(function(maintenence) {\n return newCustomMaintenanceDescriptions.indexOf(maintenence.Description) != -1;\n });\n\n logger.info('new maintenance custom ' + JSON.stringify(newTractorCustomMaintenance));\n\n async.each(newTractorCustomMaintenance, handleCustomMaintenance, cb);\n\n function handleCustomMaintenance(customMaintenance, cb) {\n var maintenance = {\n TractorID: toTractorId,\n Duration: customMaintenance.Duration,\n Description: customMaintenance.Description,\n Type: 2,\n CurrentUserId: currentUserId\n };\n c_createNewMaintenanceActivity(maintenance, cb);\n }\n }\n\n function getMaintenanceByTractorId(tractorId, cb) {\n collectionAccess.collection('MaintenanceActivity').find({TractorID: tractorId}, {}, cb);\n }\n \n}\n" }, "CreateMaintenanceActivities" : { "code" : "function onRequest(request, response, modules) {\n var collectionAccess = modules.collectionAccess,\n logger = modules.logger,\n async = modules.async,\n moment = modules.moment,\n requestContext = modules.requestContext;\n\n var newMaintenanceActivities = request.body.predefinedMaintenance,\n tractorId = request.body.tractorId,\n currentUserId = requestContext.getAuthenticatedUserId();\n\n collectionAccess.collection('MaintenanceActivity').findAsync({TractorID: tractorId, Type: 1})\n .then(function(maintenanceActivities) {\n var existedMaintenanceActivities = maintenanceActivities.map(function(maintenanceActivity) {\n return maintenanceActivity.PredefinedMaintenanceActivityId;\n });\n\n var maintenanceIdsForDelete = [],\n maintenanceIdsForCreate = [];\n\n existedMaintenanceActivities.forEach(function(existedMaintenanceActivity) {\n if(newMaintenanceActivities.indexOf(existedMaintenanceActivity) == -1) {\n maintenanceIdsForDelete.push(existedMaintenanceActivity);\n }\n });\n\n newMaintenanceActivities.forEach(function(newMaintenanceActivity) {\n if(existedMaintenanceActivities.indexOf(newMaintenanceActivity) == -1) {\n maintenanceIdsForCreate.push(newMaintenanceActivity);\n }\n });\n\n logger.info('create ' + JSON.stringify(maintenanceIdsForCreate));\n logger.info('delete ' + JSON.stringify(maintenanceIdsForDelete));\n\n async.parallel({\n createActivities: async.apply(createActivities, maintenanceIdsForCreate),\n deleteActivities: async.apply(deleteActivities, maintenanceIdsForDelete)\n }, function(err) {\n if(err) {\n return response.error(err);\n }\n response.body = {};\n return response.complete(200);\n })\n\n }, function(err) {\n return response.error(err);\n });\n\n function createActivities(maintenanceIdsForCreate, cb) {\n maintenanceIdsForCreate = maintenanceIdsForCreate.map(function(activity) {\n return collectionAccess.objectID(activity);\n });\n\n collectionAccess.collection('PredefinedMaintenanceActivity').findAsync({_id: {$in: maintenanceIdsForCreate}})\n .then(function(predefinedMaintenanceActivities) {\n async.each(predefinedMaintenanceActivities, handlePredefinedMaintenanceActivity, cb);\n\n function handlePredefinedMaintenanceActivity(predefinedMaintenanceActivity, cb) {\n var maintenance = {\n TractorID: tractorId,\n Duration: predefinedMaintenanceActivity.Duration,\n Description: predefinedMaintenanceActivity.Description,\n PredefinedMaintenanceActivityId: predefinedMaintenanceActivity._id.toString(),\n CurrentUserId: currentUserId\n };\n c_createNewMaintenanceActivity(maintenance, cb);\n }\n }, cb);\n }\n\n function deleteActivities(maintenanceIdsForDelete, cb) {\n collectionAccess.collection('MaintenanceActivity').remove({\n PredefinedMaintenanceActivityId: {$in: maintenanceIdsForDelete},\n TractorID: tractorId\n }, cb);\n }\n \n}" }, "UpdateRevenue" : { "code" : "//Used for setting Default property of Revenue and update Currency of the TractorDetail\n\nfunction onRequest(request, response, modules) {\n var collectionAccess = modules.collectionAccess,\n logger = modules.logger,\n moment = modules.moment,\n async = modules.async;\n\n var tractorId = request.body.tractorId,\n defaultRevenueType = request.body.defaultRevenueType,\n currency = request.body.currency;\n\n async.parallel([\n changeDefaultRevenue,\n changeTractorCurrency\n ],function(err){\n if(err){\n return response.error(err);\n }\n return response.complete(200);\n });\n\n //find previous Default Revenue and set Default to false,\n //after it set Default to true for Revenue with type that was sent as param\n function changeDefaultRevenue(cb){\n collectionAccess.collection('Revenue').findOne({\n TractorId: tractorId,\n Type: defaultRevenueType\n }, {}, function(err, revenue) {\n if(err){\n return cb(err);\n }\n if(!revenue) {\n return cb('Revenue with this type does not exist');\n } else {\n collectionAccess.collection('Revenue').update({TractorId: tractorId, Default: true}, {$set: {Default: false}},\n function(err) {\n if(err) {\n return cb(err);\n }\n collectionAccess.collection('Revenue').update({TractorId: tractorId, Type: defaultRevenueType}, {$set: {Default: true}}, cb);\n });\n }\n });\n }\n\n function changeTractorCurrency(cb){\n collectionAccess.collection('TractorDetail').update({TractorID: tractorId},{$set:{Currency: currency}},cb);\n }\n}\n" }, "GetHeatMapData" : { "code" : "function onRequest(request, response, modules) {\n var collectionAccess = modules.collectionAccess,\n async = modules.async,\n logger = modules.logger,\n moment = modules.moment;\n\n collectionAccess.collection('Farmer').findAsync({})\n .then(function(farmers) {\n var results = {\n points: []\n };\n\n async.each(farmers, handleFarmer, function(err) {\n if(err) {\n return response.error(err);\n }\n response.body = results;\n return response.complete(200);\n });\n\n function handleFarmer(farmer, cb) {\n if(farmer.LatLong) {\n var points = farmer.LatLong.split(',');\n results.points.push({\n lat: points[0],\n lng: points[1]\n });\n return cb();\n } else {\n return cb();\n }\n }\n }, function(err) {\n return response.error(err);\n });\n //response.complete(200);\n}\n" }, "remove-read-notifications" : { "code" : "//Scheduled endpoint\n//Interval - 5-minutes\n//Start time - 2016/11/29 11:00\n\n//Remove notifications that were read more than 1 day ago\n\nfunction onRequest(request, response, modules){\n var collectionAccess = modules.collectionAccess,\n logger = modules.logger,\n async = modules.async,\n moment = modules.moment;\n\n collectionAccess.collection('Notification')\n .remove({\n read:true,\n readTime:{\n $lte: moment().subtract({hours:1}).toISOString()\n }\n },function(err){\n if(err){\n return response.error(err);\n }\n return response.complete(200);\n });\n\n //response.complete(200);\n}\n" }, "process-hectares-daily-data" : { "code" : "//Scheduled endpoint\n//Interval - daily\n//Start time - 2016/11/29 00:10\n\n//Used to calculate Revenue Generated per data based on TractorActivity collection,\n//sending daily sms updates\n\nfunction onRequest(request, response, modules) {\n var collectionAccess = modules.collectionAccess,\n async = modules.async,\n logger = modules.logger,\n moment = modules.moment;\n\n //commented data was used for testing\n //var start = moment.utc().startOf('day').format('YYYY-MM-DD HH:mm:ss.0');\n //var end = moment.utc().endOf('day').format('YYYY-MM-DD HH:mm:ss.0');\n //logger.info('start ' + start);\n //logger.info('end ' + end);\n //logger.info('moment ' + moment().format('YYYY-MM-DD HH:mm:ss.0'));\n //var fromDate = '2016-10-30 10:30:00.0',\n // tillDate = '2016-10-30 11:00:00.0';\n //var fromDate = '2016-10-30 10:00:00.0',\n // tillDate = '2016-10-30 10:30:00.0';\n //var fromDate = '2016-10-31 00:00:00.0',\n // tillDate = '2016-10-31 23:59:40.0';\n //var day = '2016-10-31';\n var fromDate = moment.utc().subtract({hours: 10}).startOf('day').format('YYYY-MM-DD HH:mm:ss.0'),\n tillDate = moment.utc().subtract({hours: 10}).endOf('day').format('YYYY-MM-DD HH:mm:ss.0');\n var day = moment.utc().subtract({hours: 10}).format('YYYY-MM-DD');\n\n\n collectionAccess.collection('TractorDetail').findAsync({})\n .then(function(tractors) {\n async.each(tractors, handleTractor, function(err) {\n if(err) {\n return response.error(err);\n }\n return response.complete(200);\n });\n\n function handleTractor(tractor, cb) {\n if(tractor.TractorID.toString().length != 6) {\n return cb();\n } else {\n collectionAccess.collection('DailyTractorActivity').findOneAsync({\n day: day,\n TractorID: tractor.TractorID\n })\n .then(function(dailyTractorActivity) {\n if(!dailyTractorActivity) {\n return cb();\n } else {\n getDailyData(tractor, function(err, results) {\n if(err) {\n return cb(err);\n }\n results['_kmd.lmt'] = moment().toISOString();\n dailyTractorActivity.TotalTimeActive = dailyTractorActivity.TotalTimeActive < 86400 ? dailyTractorActivity.TotalTimeActive : 86400;\n results.TotalTimeIdle = 86400 - dailyTractorActivity.TotalTimeActive;\n collectionAccess.collection('DailyTractorActivity').update({_id: collectionAccess.objectID(dailyTractorActivity._id)}, {$set: results}, function(err){\n if(err){\n return cb(err);\n }\n sendDailyUpdateSms(dailyTractorActivity._id, tractor, cb);\n });\n });\n }\n }, cb);\n }\n\n //get fields based on hectares data\n //calculate fields HectaresServiced, Revenue, RevenueType, RevenueCurrency\n function getDailyData(tractor, cb) {\n async.parallel({\n tractorActivities: async.apply(getHectaresTractorActivities, tractor),\n revenue: async.apply(getRevenue, tractor)\n }, function(err, results) {\n if(err) {\n return cb(err);\n }\n var tractorActivities = results.tractorActivities,\n revenue = results.revenue,\n totalHectaresServiced = 0;\n tractorActivities.forEach(function(tractorActivity) {\n totalHectaresServiced += tractorActivity.HectaresServiced;\n });\n\n var revenueType = revenue && revenue.Type ? revenue.Type: 101,\n revenueGenerated = revenue && revenue.Rate ? totalHectaresServiced * revenue.Rate: null;\n\n return cb(null, {HectaresServiced: totalHectaresServiced, Revenue: revenueGenerated, RevenueType: revenueType, RevenueCurrency: tractor.Currency});\n });\n\n function getHectaresTractorActivities(tractor, cb) {\n collectionAccess.collection('TractorActivity').find({\n TractorId: tractor.TractorID,\n StartTimeStamp: {\n $gt: fromDate\n },\n EndTimeStamp: {\n $lt: tillDate\n }\n }, {}, cb);\n }\n\n function getRevenue(tractor, cb) {\n collectionAccess.collection('Revenue').findOne({\n TractorId: tractor.TractorID,\n Default:true\n }, cb)\n }\n }\n\n function sendDailyUpdateSms(dailyActivityId, tractor, cb) {\n\n async.parallel({\n dailyActivity: getDailyActivity,\n tractorOwner: getTractorOwner,\n operator:getOperator\n },function(err, results){\n var dailyActivity = results.dailyActivity,\n tractorOwner = results.tractorOwner,\n operator = results.operator;\n\n if(dailyActivity && tractorOwner && tractor.DailyTractorUpdates && tractorOwner.phone) {\n var startTime = moment(dailyActivity.StartActiveData).format('h:mm A'),\n endTime = moment(dailyActivity.LastActiveData).format('h:mm A');\n if(tractor.UtcOffset) {\n if(tractor.UtcOffset > 0) {\n startTime = moment(dailyActivity.StartActiveData).add({minutes: tractor.UtcOffset}).format('h:mm A');\n endTime = moment(dailyActivity.LastActiveData).add({minutes: tractor.UtcOffset}).format('h:mm A');\n } else {\n startTime = moment(dailyActivity.StartActiveData).subtract({minutes: tractor.UtcOffset}).format('h:mm A');\n endTime = moment(dailyActivity.LastActiveData).subtract({minutes: tractor.UtcOffset}).format('h:mm A');\n }\n }\n\n var message = 'Hello ' + tractorOwner.first_name + ', your tractor ' + tractor.TractorName + ' did ' + dailyActivity.HectaresServiced +\n ' hectares from ' + startTime + ' to ' + endTime +\n ' on ' + moment(dailyActivity.day).format('MMMM Do') + ', and earned ' + dailyActivity.Revenue + ' ' + dailyActivity.RevenueCurrency +\n '. Tractor was active for ' + moment(dailyActivity.LastActiveData).diff(moment(dailyActivity.StartActiveData), 'hours') + ' hours ' +\n 'and was operated by ' + operator.OperatorName;\n logger.info('message ' + message);\n c_sendSms(message, tractorOwner.phone, tractor.Country, cb);\n } else {\n return cb();\n }\n });\n\n function getDailyActivity(cb) {\n collectionAccess.collection('DailyTractorActivity').findOne({_id: collectionAccess.objectID(dailyActivityId)}, {}, cb);\n }\n\n function getTractorOwner(cb) {\n collectionAccess.collection('user').findOneAsync({_id: collectionAccess.objectID(tractor._acl.creator)})\n .then(function(user) {\n if(!user) {\n return cb();\n }\n collectionAccess.collection('TractorOwner').findOne({username: user.email}, {}, cb);\n }, cb);\n }\n\n function getOperator(cb){\n collectionAccess.collection('TractorOperator').findOne({OperatorID: tractor.OperatorID},cb);\n }\n }\n }\n },\n function(error) {\n if(error) {\n response.error(error);\n }\n });\n //response.complete(200);\n}\n" }, "process-timezones" : { "code" : "//Scheduled endpoint\n//Interval - daily\n//Start time - 2016/11/29 00:30\n\n//Update UtcOffset field in TractorDetail collection on Kinvey\n//using Google Maps timezone API\n//Need to do it in case when tractor will change timezone\n\nfunction onRequest(request, response, modules) {\n var collectionAccess = modules.collectionAccess,\n logger = modules.logger,\n async = modules.async,\n moment = modules.moment;\n \n collectionAccess.collection('TractorDetail').findAsync({})\n .then(function(tractors) {\n async.each(tractors, processTractorTimezone, function(err) {\n if(err) {\n return response.error(err);\n } else {\n return response.complete(200);\n }\n });\n\n function processTractorTimezone(tractor, cb) {\n if(tractor.PositionLatitude && tractor.PositionLongitude) {\n getUtcOffset(tractor.PositionLongitude, tractor.PositionLongitude, function(err, offset) {\n logger.info(offset);\n if(err) {\n return cb(err);\n }\n collectionAccess.collection('TractorDetail').update({_id: collectionAccess.objectID(tractor._id)},\n {$set: {UtcOffset: offset}}, cb);\n });\n } else {\n collectionAccess.collection('TractorDetail').update({_id: collectionAccess.objectID(tractor._id)},\n {$set: {UtcOffset: 0}}, cb);\n }\n\n function getUtcOffset(latitude, longitude, cb) {\n var GoogleTimezoneApiKey = 'AIzaSyCENGAB8-qFOFeHB0_T379DSdxJbaptIMY',\n requestOptions = {\n url: 'https://maps.googleapis.com/maps/api/timezone/json?location=' + latitude + ',' + longitude + '×tamp=1331161200&key=' + GoogleTimezoneApiKey,\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json'\n },\n json: true\n };\n\n modules.request.request(requestOptions, function(err, resp, body) {\n var utcOffsetInSeconds = body && body.rawOffset ? body.rawOffset/60 : 0;\n cb(null, utcOffsetInSeconds);\n });\n }\n }\n }, function(err) {\n return response.error(err);\n });\n //response.complete(200);\n}" }, "process-tractor-activities" : { "code" : "// //Scheduled endpoint\n// //Interval - 5-minutes\n// //Start time - 2016/11/29 02:47\n\n// //Fetching tractor activities from 2-track server and store them in TractorActivityData collection on Kinvey,\n// //updating coordinates and address of tractor(TractorDetail) based on last activity,\n// //sending geofence notification(tractor left or returned back in the area),\n// //sending maintenance alert-based push notifications based on EventCode field from 2-track\n\n// function onRequest(request, response, modules) {\n\n// var collectionAccess = modules.collectionAccess,\n// logger = modules.logger,\n// async = modules.async,\n// moment = modules.moment;\n \n// var token = \"\";\n\n// collectionAccess.collection('TwoTrackApiToken').findOneAsync({id: 9228383772})\n// .then(function(accessToken) {\n// token = accessToken;\n \n// },\n// function(err) {\n \n// return response.error(err);\n// });\n \n// //Get tractors and loop through the tractors\n// modules.collectionAccess.collection('TractorDetail').find({}, function (err, tractors) {\n\n// tractors.forEach(function(tractor, a){\n\n// if(tractor.TractorID.toString().length === 6){\n// //logger.info(tractor.TractorID);\n// //Make request to 2track and store data in collection\n\n// var startActivityId = tractor.LastActivityId ? tractor.LastActivityId : 0,\n// payloadOptions = {\n// token: \"\"+token.token+\"\",\n// trackerId: tractor.TractorID,\n// startActivityId: startActivityId,\n// rowCount: 10,\n// startUTCTime: \"\",\n// endUTCTime: \"\"\n// },\n// requestOptions = {\n// url: 'https://hellotractor.2-track.com:8080/api/activity',\n// method: 'POST',\n// headers: {\n// 'Content-Type': 'application/json',\n// 'Accept': 'application/json',\n// 'Version': 'v1'\n// },\n// json: true,\n// body: payloadOptions\n// };\n \n// modules.request.request(requestOptions, function(err, resp, body) {\n// if(err) {\n// return cb(err);\n// } else {\n// if(!body.data) {\n// return cb();\n// } else {\n// logger.info(\"Successfully placed http request for tractor updates for: \" + tractor.TractorID);\n// async.parallel({\n// saveTractorActivities: async.apply(saveTractorActivities, body.data, tractor.TractorID),\n// updateTractorDetail: async.apply(updateTractorDetail, body.data, tractor.TractorID, tractor)\n// });\n// }\n// }\n\n// //response.complete(200);\n// });\n// }\n// });\n// //response.complete(200);\n// });\n\n// function saveTractorActivities(activities, cb) {\n// //logger.info(\"about to start saving tractor activities and data is: \"+ activities);\n// var tractorID = cb;\n// activities.forEach(function(data, a) {\n\n// //Save data in the collection\n\n// var entity = modules.kinvey.entity();\n// entity.TractorID = tractorID;\n// entity.ActivityID = data.activityId;\n// entity.EventCode = data.eventCode;\n// entity.EventName = data.eventName;\n// entity.Speed = data.speed;\n// entity.Odometer = data.odometer;\n// entity.Idle = data.idle;\n// entity.IsGPSValid = data.isGPSValid;\n// entity.Lat = data.lat;\n// entity.Lng = data.lon;\n// entity.DirectionEW = data.directionEW;\n// entity.DirectionNS = data.directionNS;\n// entity.Altitude = data.altitude;\n// entity.IgnitionStatus = data.ignitionStatus;\n// entity.BatteryVoltage = data.batteryVoltage;\n// entity.SatelliteNumber = data.satelliteNumber;\n// entity.Street = data.street;\n// entity.Town = data.town;\n// entity.County = data.county;\n// entity.Country = data.country;\n// entity.ActivityUTCDate = data.activityUTCDate;\n\n\n// collectionAccess.collection('TractorActivityData').save(entity, function(err) {\n// //logger.info(\"saving activities\");\n// //return response.complete();\n// });\n// });\n\n// }\n\n\n// //update coordinates and address of tractor, send geofence push notifications\n// function updateTractorDetail(activities, cb, tractor) {\n// //logger.info(\"Begining process for updating tractor and tractor data is:\" + tractor.TractorID);\n\n// if(activities.length === 0) {\n// logger.info(\"No activities data for tractor \" + tractor.TractorID);\n// return;\n// //return cb();\n// }\n// var lastActivity = activities.reduce(function(prev, curr) {\n// return prev.activityUTCDate > curr.activityUTCDate ? prev : curr;\n// });\n\n// var setObject = {\n// LastActiveTime: lastActivity.activityUTCDate\n// };\n\n// if(lastActivity.lat && lastActivity.lon) {\n\n// setObject.PositionLatitude = lastActivity.lat;\n// setObject.PositionLongitude = lastActivity.lon;\n// setObject.LastActivityId = lastActivity.activityId;\n\n// if(lastActivity.country){\n// setObject.Street = lastActivity.street;\n// setObject.Town = lastActivity.town;\n// setObject.Country = lastActivity.country;\n// }\n// setObject['_kmd.lmt'] = moment().toISOString();\n\n// //logger.info('last activity utcdate for tractor is: ' + setObject.LastActiveTime);\n// //logger.info('tractor ' + JSON.stringify(tractor));\n\n// //TODO: add - code of c_sendGeofenceNotificationIfNecessary is placed in common/geofence.js\n// c_sendGeofenceNotificationIfNecessary(lastActivity, tractor, function(err, result){\n// if(err){\n// return cb(err);\n// }\n// if(result.wasSent) {\n// setObject.LastGeofenceNotificationTime = !result.WasInArea && tractor.NeedToSendGeofenceOutNotification ? moment().toISOString() : '';\n// setObject.WasInArea = result.WasInArea;\n// setObject.NeedToSendGeofenceOutNotification = true;\n// }\n// //logger.info('set Object ' + JSON.stringify(setObject));\n// collectionAccess.collection('TractorDetail').update({TractorID: cb}, {\n// $set: setObject\n// }, cb);\n// });\n\n// collectionAccess.collection('TractorDetail').update({TractorID: cb},\n// {\n// $set: setObject\n\n// }, function(err) {\n// if(err) {\n// return response.error(err);\n// }\n\n// //return response.complete(200);\n// });\n\n// }\n// else{\n// response.complete(400);\n// //return cb();\n// }\n// }\n\n// //response.complete(200);\n\n// }\n" }, "process-maintenance" : { "code" : "//Scheduled endpoint\n//Interval - 30-minutes\n//Start time - 2016/11/29 00:01\n\n//Used to check Counter value and send maintenance push notifications\n\nfunction onRequest(request, response, modules) {\n var collectionAccess = modules.collectionAccess,\n async = modules.async,\n logger = modules.logger,\n moment = modules.moment;\n\n collectionAccess.collection('TractorDetail').findAsync({})\n .then(function(tractors) {\n async.each(tractors, handleTractor, function(err) {\n if(err) {\n return response.error(err);\n }\n response.body = {};\n return response.complete(200);\n });\n\n function handleTractor(tractor, cb) {\n collectionAccess.collection('MaintenanceActivity').findAsync({\n TractorID: tractor.TractorID\n })\n .then(function(maintenanceActivities) {\n async.each(maintenanceActivities, handleMaintenanceActivity, cb);\n\n //info about Status of MaintenanceActivity you can find in the doc file about Maintenance\n function handleMaintenanceActivity(maintenanceActivity, cb) {\n var durationInSeconds = maintenanceActivity.Duration * 60 * 60,\n partialDurationInSeconds = durationInSeconds * 0.8,\n counter = maintenanceActivity.Counter,\n status = maintenanceActivity.Status;\n if(counter < partialDurationInSeconds) {\n return cb();\n } else {\n if(counter < durationInSeconds) {\n var needToSendPartialPush = (status != 2) || (status == 2 && moment().diff(moment(maintenanceActivity.LastNotificationTime), 'days') >= 1);\n if(!needToSendPartialPush) {\n return cb();\n } else {\n //code of c_sendMaintenanceNotification is placed in common/maintenance.js\n c_sendMaintenanceNotification(maintenanceActivity, tractor.OperatorID, 'maintenancePartial', function(err) {\n if(err) {\n return cb(err);\n }\n collectionAccess.collection('MaintenanceActivity').update({_id: collectionAccess.objectID(maintenanceActivity._id)}, {\n $set: {\n Status: 2,\n LastNotificationTime: moment().toISOString()\n }\n }, cb);\n });\n }\n } else {\n var needToSendPush = (status != 3) || (status == 3 && moment().diff(moment(maintenanceActivity.LastNotificationTime), 'days') >= 1);\n if(!needToSendPush) {\n return cb();\n } else {\n //code of c_sendMaintenanceNotification is placed in common/maintenance.js\n c_sendMaintenanceNotification(maintenanceActivity, tractor.OperatorID, 'maintenance', function(err) {\n if(err) {\n return cb(err);\n }\n collectionAccess.collection('MaintenanceActivity').update({_id: collectionAccess.objectID(maintenanceActivity._id)}, {\n $set: {\n Status: 3,\n LastNotificationTime: moment().toISOString()\n }\n }, cb);\n })\n }\n }\n }\n }\n }, cb);\n }\n }, function(err) {\n return response.error(err);\n })\n //response.complete(200);\n}" }, "process-real-time-daily-data" : { "code" : "//Scheduled endpoint\n//Interval - 30-minutes\n//Start time - 2016/11/28 23:58\n\n//Used to calculate DailyTractorActivity fields based on TractorActivityData collection,\n//updating Counter field for MaintenanceActivity entities\n\n\nfunction onRequest(request, response, modules) {\n var collectionAccess = modules.collectionAccess,\n async = modules.async,\n logger = modules.logger,\n moment = modules.moment;\n\n //var start = moment.utc().startOf('day').format('YYYY-MM-DD HH:mm:ss.0');\n //var end = moment.utc().endOf('day').format('YYYY-MM-DD HH:mm:ss.0');\n //logger.info('start ' + start);\n //logger.info('end ' + end);\n //logger.info('moment ' + moment().format('YYYY-MM-DD HH:mm:ss.0'));\n //var fromDate = '2016-10-30 10:30:00.0',\n // tillDate = '2016-10-30 11:00:00.0';\n //var fromDate = '2016-10-30 10:00:00.0',\n // tillDate = '2016-10-30 10:30:00.0';\n //var fromDate = '2016-11-06 00:00:00.0',\n // tillDate = '2016-11-06 23:59:40.0';\n //var day = '2016-11-06',\n // dayStart = moment('2016-11-06 00:00:00.0');\n \n //logger.info('start time ' + moment().utc().toISOString());\n\n var tillDate = moment.utc().format('YYYY-MM-DD HH:mm:ss.0'),\n fromDate = moment(tillDate).subtract({minutes: 30}).format('YYYY-MM-DD HH:mm:ss.0');\n\n collectionAccess.collection('TractorDetail').findAsync({})\n .then(function(tractors) {\n async.each(tractors, handleTractor, function(err) {\n //logger.info('end time ' + moment().utc().toISOString());\n if(err) {\n logger.info(\"There was error processing activities : \"+ err);\n response.error(err);\n }\n return response.complete(200);\n });\n\n function handleTractor(tractor, cb) {\n if(tractor.TractorID.toString().length != 6) {\n return cb();\n } else {\n var day;\n if(tractor.UtcOffset) {\n if(tractor.UtcOffset > 0) {\n day = moment.utc().add({minutes: tractor.UtcOffset}).format('YYYY-MM-DD');\n } else {\n day = moment.utc().subtract({minutes: tractor.UtcOffset}).format('YYYY-MM-DD');\n }\n } else {\n day = moment.utc().format('YYYY-MM-DD');\n }\n collectionAccess.collection('DailyTractorActivity').findAsync({\n day: day,\n TractorID: tractor.TractorID\n })\n .then(function(dailyTractorActivities) {\n var dailyTractorActivity = dailyTractorActivities[0];\n getRealTimeData(tractor, dailyTractorActivity, function(err, results) {\n\n if(err) {\n return cb(err);\n }\n if(!results) {\n return cb();\n }\n results.OperatorID = tractor.OperatorID;\n results.TractorID = tractor.TractorID;\n results.day = day;\n\n collectionAccess.collection('Revenue').findOneAsync({\n TractorId: tractor.TractorID,\n Default: true\n })\n .then(function(revenue) {\n results.RevenueType = revenue && revenue.Type ? revenue.Type : 101;\n results.RevenueCurrency = tractor && tractor.Currency ? tractor.Currency : null;\n results.Revenue = revenue && revenue.Rate ? 0 : null;\n\n if(dailyTractorActivity) {\n results['_kmd.lmt'] = moment().toISOString();\n collectionAccess.collection('DailyTractorActivity').update({_id: collectionAccess.objectID(dailyTractorActivity._id)}, {$set: results}, cb);\n } else {\n var entity = modules.kinvey.entity(results);\n entity.HectaresServiced = 0;\n collectionAccess.collection('DailyTractorActivity').save(entity, cb);\n }\n }, cb);\n });\n }, cb);\n }\n\n //get fields based on real time data\n //calculate fields AverageSpeed, LastActiveData,Country, Town, Street, IgnitionStatus, DistanceTravelled,\n //TotalTimeActive, TotalTimeIdle, Route\n function getRealTimeData(tractor, dailyTractorActivity, cb) {\n collectionAccess.collection('TractorActivityData').findAsync({\n ActivityUTCDate: {$gt: fromDate, $lt: tillDate},\n TractorID: tractor.TractorID\n }, {\n sort: {\n ActivityUTCDate: 1\n }\n })\n .then(function(tractorsActivities) {\n if(tractorsActivities.length === 0) {\n return cb();\n } else {\n async.parallel({\n totalTime: async.apply(calculateTotalTimeActiveAndIdle, tractorsActivities, dailyTractorActivity),\n averageData: async.apply(calculateAverageData, tractorsActivities, dailyTractorActivity),\n route: async.apply(getRoute, tractorsActivities, dailyTractorActivity)\n }, function(err, results) {\n if(err) {\n return cb(err);\n }\n results = c_mergeObjects([results.totalTime, results.averageData, results.route]);\n return cb(null, results);\n });\n }\n\n function calculateTotalTimeActiveAndIdle(tractorsActivities, dailyTractorActivity, cb) {\n var totalTimeActive = dailyTractorActivity && dailyTractorActivity.TotalTimeActive ? dailyTractorActivity.TotalTimeActive : 0,\n totalTimeActiveStartValue = totalTimeActive,\n lastActivity = tractorsActivities[tractorsActivities.length - 1],\n totalTimeIdle,\n tractorTillDate,\n dayStart,\n dayEnd;\n\n if(tractor.UtcOffset) {\n if(tractor.UtcOffset > 0) {\n tractorTillDate = moment(tillDate).add({minutes: tractor.UtcOffset}).format('YYYY-MM-DD HH:mm:ss.0');\n dayStart = moment.utc().add({minutes: tractor.UtcOffset}).startOf('day').format('YYYY-MM-DD HH:mm:ss.0');\n dayEnd = moment.utc().add({minutes: tractor.UtcOffset}).endOf('day').format('YYYY-MM-DD HH:mm:ss.0');\n } else {\n tractorTillDate = moment(tillDate).subtract({minutes: tractor.UtcOffset}).format('YYYY-MM-DD HH:mm:ss.0');\n dayStart = moment.utc().subtract({minutes: tractor.UtcOffset}).startOf('day').format('YYYY-MM-DD HH:mm:ss.0');\n dayEnd = moment.utc().subtract({minutes: tractor.UtcOffset}).endOf('day').format('YYYY-MM-DD HH:mm:ss.0');\n }\n } else {\n dayStart = moment.utc().startOf('day').format('YYYY-MM-DD HH:mm:ss.0');\n dayEnd = moment.utc().endOf('day').format('YYYY-MM-DD HH:mm:ss.0');\n tractorTillDate = tillDate;\n }\n\n\n var lastJourneyStartTime = dailyTractorActivity && dailyTractorActivity.LastJourneyStartTime ? dailyTractorActivity.LastJourneyStartTime : dayStart;\n\n tractorsActivities.forEach(function(tractorActivity) {\n if(tractorActivity.EventName == 'Journey Start') {\n lastJourneyStartTime = tractorActivity.ActivityUTCDate;\n } else if(tractorActivity.EventName == 'Journey End') {\n //logger.info('journey start ' + lastJourneyStartTime + ' journey end ' + tractorActivity.ActivityUTCDate);\n var start = moment(lastJourneyStartTime),\n end = moment(tractorActivity.ActivityUTCDate);\n var diff = end.diff(start, 'seconds');\n diff = diff > 0 ? diff : 0;\n totalTimeActive += diff;\n }\n });\n\n if(moment(dayEnd).diff(moment(tractorTillDate), 'minutes') < 5 && lastActivity.EventName != 'Journey End') {\n var diff = moment(dayEnd).diff(moment(lastJourneyStartTime), 'seconds');\n diff = diff > 0 ? diff : 0;\n totalTimeActive += diff;\n }\n\n totalTimeIdle = moment(tractorTillDate).diff(moment(dayStart), 'seconds') - totalTimeActive;\n //logger.info('Total time active ' + totalTimeActive + ' ' + dayStart + ' ' + tractorTillDate);\n\n var totalTimeActiveDiff = totalTimeActive - totalTimeActiveStartValue;\n\n updateMaintenanceActivities(tractor, totalTimeActiveDiff, function(err){\n return cb(err, {TotalTimeActive: totalTimeActive, TotalTimeIdle: totalTimeIdle, LastJourneyStartTime: lastJourneyStartTime});\n });\n\n function updateMaintenanceActivities(tractor, totalTimeActiveDiff, cb) {\n if(totalTimeActiveDiff <= 0) {\n return cb();\n } else {\n //get Maintenance activities of specific tractor with types predefined and custom\n collectionAccess.collection('MaintenanceActivity').findAsync({\n TractorID: tractor.TractorID,\n Type: {$in: [1, 2]}\n })\n .then(function(maintenanceActivities) {\n async.each(maintenanceActivities, handleMaintenanceActivity,cb);\n\n function handleMaintenanceActivity(maintenanceActivity, cb) {\n totalTimeActiveDiff = totalTimeActiveDiff && totalTimeActiveDiff > 0 ? totalTimeActiveDiff : 0;\n var counter = maintenanceActivity.Counter + totalTimeActiveDiff;\n counter = counter ? counter : 0;\n collectionAccess.collection('MaintenanceActivity').update({_id: collectionAccess.objectID(maintenanceActivity._id)}, {$set: {Counter: counter}}, cb);\n }\n }, cb);\n }\n\n }\n }\n\n function calculateAverageData(tractorsActivities, dailyTractorActivity, cb) {\n var startActivity = tractorsActivities[0],\n endActivity = tractorsActivities[tractorsActivities.length - 1],\n totalSpeed = dailyTractorActivity && dailyTractorActivity.TotalSpeed ? dailyTractorActivity.TotalSpeed : 0,\n totalSpeedCounter = dailyTractorActivity && dailyTractorActivity.TotalSpeedCounter ? dailyTractorActivity.TotalSpeedCounter : 0;\n\n tractorsActivities.forEach(function(tractorActivity) {\n totalSpeed += tractorActivity.Speed;\n totalSpeedCounter = tractorActivity.Speed && tractorActivity.Speed > 0 ? totalSpeedCounter + 1 : totalSpeedCounter;\n });\n\n var averageSpeed = totalSpeedCounter > 0 ? (totalSpeed / totalSpeedCounter).toFixed(1) : totalSpeed;\n\n var distanceTravelled = dailyTractorActivity && dailyTractorActivity.DistanceTravelled ? dailyTractorActivity.DistanceTravelled : 0,\n additionalDistance = dailyTractorActivity && dailyTractorActivity.LastOdometerValue ? endActivity.Odometer - dailyTractorActivity.LastOdometerValue :\n endActivity.Odometer - startActivity.Odometer;\n distanceTravelled += additionalDistance;\n\n var startCountry = dailyTractorActivity && dailyTractorActivity.StartCountry ? dailyTractorActivity.StartCountry : startActivity.Country;\n startCountry = startCountry ? startCountry : \"\";\n\n var startTown = dailyTractorActivity && dailyTractorActivity.StartTown ? dailyTractorActivity.StartTown : startActivity.Town;\n startTown = startTown ? startTown : \"\";\n\n var startStreet = dailyTractorActivity && dailyTractorActivity.StartStreet ? dailyTractorActivity.StartStreet : startActivity.Street;\n startStreet = startStreet ? startStreet : \"\";\n\n var startActiveData = dailyTractorActivity && dailyTractorActivity.StartActiveData ? dailyTractorActivity.StartActiveData : startActivity.ActivityUTCDate;\n\n return cb(null, {\n TotalSpeed: totalSpeed,\n TotalSpeedCounter: totalSpeedCounter,\n AverageSpeed: averageSpeed.toString(),\n StartActiveData: startActiveData,\n LastActiveData: endActivity.ActivityUTCDate,\n Country: endActivity.Country,\n Town: endActivity.Town,\n Street: endActivity.Street,\n IgnitionStatus: endActivity.IgnitionStatus,\n DistanceTravelled: distanceTravelled,\n LastOdometerValue: endActivity.Odometer,\n StartCountry: startCountry,\n StartTown: startTown,\n StartStreet: startStreet\n });\n }\n\n function getRoute(tractorActivities, dailyTractorActivity, cb) {\n var route = tractorActivities.map(function(tractorActivity) {\n return {\n Lat: tractorActivity.Lat,\n Lng: tractorActivity.Lng,\n Time: moment.utc().format('HH:mm:ss.0')\n };\n });\n route = dailyTractorActivity && dailyTractorActivity.Route ? dailyTractorActivity.Route.concat(route) : route;\n\n return cb(null, {\n Route: route\n });\n }\n }, cb);\n }\n }\n },\n function(error) {\n response.error(error);\n });\n}\n" }, "UpdateDailyTractorActivityHectaresAndRevenue" : { "code" : "function onRequest(request, response, modules) {\n var logger = modules.logger;\n var message= \"Hello, World!\";\n logger.info(message);\n response.complete(200);\n}" }, "test-tractor-activities" : { "code" : "function onRequest(request, response, modules) {\n \n var collectionAccess = modules.collectionAccess,\n logger = modules.logger,\n async = modules.async,\n moment = modules.moment;\n \n var startActivityId = '664074';\n \n var token = \"\";\n\n collectionAccess.collection('TwoTrackApiToken').findOneAsync({id: 9228383772})\n .then(function(accessToken) {\n token = accessToken;\n \n },\n function(err) {\n \n return response.error(err);\n });\n \n //fetch data for static tractor and store in the collection\n var payloadOptions = {\n token: \"\"+token.token+\"\",\n trackerId: 100009,\n startActivityId: startActivityId,\n rowCount: 30,\n startUTCTime: \"\",\n endUTCTime: \"\"\n };\n \n var requestOptions = {\n url: 'https://hellotractor.2-track.com:8080/api/activity',\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Version': 'v1'\n },\n json: true,\n body: payloadOptions\n };\n \n modules.request.get(requestOptions, function(error, resp, body){\n logger.info(\"resp \" + resp);\n logger.info(\"body \" + body);\n // if (error){\n // response.body = {error: error.message};\n // return response.complete(400);\n // }\n \n //var r = JSON.parse(body);\n var data=body;\n //return response.complete(data);\n \n data.forEach(function(temp, a) {\n \n logger.info(\"temp \" + temp);\n\n var entity = modules.kinvey.entity();\n entity.TractorID = temp.tracker_id;\n entity.ActivityID = temp.activity_id;\n modules.collectionAccess.collection(\"TestTractorActivities\").save(entity, function(err) {\n return response.complete();\n });\n \n });\n });\n}" }, "b_UpdateTractorOwners" : { "code" : "function onRequest(request, response, modules) {\n \n var collectionAccess = modules.collectionAccess,\n logger = modules.logger,\n async = modules.async,\n moment = modules.moment;\n\n //loop through the tractor owners and post the data of each row to the aws backend.\n modules.collectionAccess.collection('TractorOwner').find({}, function (err, tractorOwners) {\n \n tractorOwners.forEach(function(tractorOwner, a){\n \n //logger.info(\"syncing to server for: \"+ tractorOwner.first_name);\n \n var payloadOptions = {\n op: 'create',\n data: tractorOwner\n },\n requestOptions = {\n url: 'https://cloud.hellotractor.com/kinvey/api/users',\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Version': 'v1'\n },\n json: true,\n body: payloadOptions\n };\n\n modules.request.request(requestOptions, function(err, resp, body) {\n if(err) {\n //return cb(err);\n } else {\n \n //logger.info(\"Successfully placed http request\");\n //response.complete(200);\n }\n\n \n });\n\n });\n });\n \n //response.complete(200);\n}" }, "unassign-tractor-on-delete" : { "code" : "function onRequest(request, response, modules){\n \n \tvar logger = modules.logger;\n \tvar collectionAccess = modules.collectionAccess;\n \t//logger.info(\"body1: \"+ JSON.stringify(request));\n \tvar operatorId = request.body.operatorId;\n \tlogger.info(\"ID posted: \"+ operatorId);\n\n \tif(!operatorId){\n \t\tlogger.error(\"Invalid operator ID posted: \"+ operatorId);\n \t\treturn response.complete(400);\n \t}\n\n \tlogger.info(\"operator ID posted: \"+ operatorId);\n\n \tcollectionAccess.collection('TractorDetail').update({OperatorID: operatorId}, {\n\t $set: {\n\t OperatorID: 0,\n\t Status: 0\n\t }\n\t }, function(err) {\n if(err) {\n return response.error(err);\n }\n return response.complete(200);\n });\n \n //return response.complete(200);\n}" }, "test" : { "code" : "function onRequest(request, response, modules) {\n// var logger = modules.logger;\n// logger.info(\"Hey test\");\n// response.complete();\n \n \n// var fuelHistoryCol = modules.collectionAccess.collection(\"FuelHistory\");\n// fuelHistoryCol.find({}, function(fuelErr, fuelHistoryList){\n// var count = fuelHistoryList.length;\n// modules.logger.info(\"Count: \"+count);\n// fuelHistoryList.forEach(function(fuelHistory){\n// var operator = {OperatorID: fuelHistory.OperatorID? Number(fuelHistory.OperatorID): null};\n// fuelHistoryCol.update({\"_id\":fuelHistory._id}, {$set: operator}, {upsert: false}, function(updateErr, updatedRes){\n// count--;\n// if (count <= 0){\n// response.complete();\n// }\n// })\n// });\n// }); \n \n \n// logger.info(\"Hello external API\");\n // response.complete();\n// var options = {limit:1};\n// var count = 0;\n// var hectares = 0;\n \n\n// modules.collectionAccess.collection(\"ServiceBookings\").distinct(\"bookingID\", {\"bookingStatus\":0}, function (err, docs) {\n// if (err) {\n// logger.error('Query failed: '+ err);\n// response.error();\n// } else {\n// modules.logger.info(docs.length);\n// for (var i = 0; i < docs.length; i++){\n// if (docs[i].hectaresServiced && docs[i]._acl.creator != \"5af40bd426860c399aba621b\" && docs[i]._acl.creator != \"598ad681bac152c62bcfd9ef\"){\n// hectares += Number(docs[i].hectaresServiced);\n// }\n// count += 1;\n// if (count >= docs.length){\n// modules.logger.info(\"Hectares: \"+hectares+\", Count: \"+count);\n// response.complete();\n// } \n// }\n// }\n// }); \n \n \n// var country = \"Kenya\";\n// var date = \"2019-02-15\";\n// var query = {\"LastActiveTime\": {$gte: date}, \"Country\":country};\n// var query = {\"LastActiveTime\": {$gte: date}};\n// var sort = {sort: {\"Country\":1}};\n \n \n \n// modules.collectionAccess.collection(\"TractorDetail\").find(query, function (err, docs) {\n// if (err) {\n// logger.error('Query failed: '+ err);\n// response.error();\n// } else {\n// modules.logger.info(country+\" tractors: \"+docs.length);\n// response.complete();\n// }\n// }); \n \n \n \n //Total number of engine hours\n// modules.collectionAccess.collection(\"TractorDetail\").find(query, function (err, docs) {\n// if (err) {\n// logger.error('Query failed: '+ err);\n// response.error();\n// } else {\n// var engineHours = 0;\n// var distance = 0;\n// for (var i = 0; i < docs.length; i++){\n// engineHours += Number(docs[i].EngineHours);\n// distance += Number(docs[i].TotalDistanceCovered);\n// }\n// modules.logger.info(\"Total Tractors: \"+docs.length);\n// modules.logger.info(\"Total Eninge Hours: \"+engineHours);\n// modules.logger.info(\"Total Distance Covered: \"+distance);\n// response.complete();\n// }\n// }); \n \n \n \n// modules.collectionAccess.collection('ServiceBookings').update({orgID:\"165\"}, {$set: {\"BookingArchived\":\"\"}}, {upsert: false, multi: true}, function(err){\n// logger.info(\"Done\");\n// });\n \n \n \n \n// Compute total number of bookings after a certain date\n// var bookingStatusQuery = {\"bookingStatus\":0};\n// var createdAtQuery = {\"createdAt\": {$gte:\"2019-02-22\", $lt:\"2019-02-23\"}};\n// modules.collectionAccess.collection(\"ServiceBookings\").distinct(\"bookingID\", createdAtQuery, function (err, docs) {\n// if (err) {\n// logger.error('Query failed: '+ err);\n// response.error();\n// } else {\n// modules.logger.info(\"Bookings Number: \"+docs.length);\n// modules.logger.info(docs);\n \n// for (var i = 0; i < docs.length; i++){\n// if (docs[i].hectaresServiced && docs[i]._acl.creator != \"5af40bd426860c399aba621b\" && docs[i]._acl.creator != \"598ad681bac152c62bcfd9ef\"){\n// hectares += Number(docs[i].hectaresServiced);\n// }\n// count += 1;\n// if (count >= docs.length){\n// modules.logger.info(\"Hectares: \"+hectares+\", Count: \"+count);\n// response.complete();\n// } \n// }\n// }\n// }); \n \n \n// }\n\n\n// function onRequest(request, response, modules) {\n// var logger = modules.logger;\n// logger.info(\"Hey test\");\n// response.complete();\n \n// var fuelHistoryCol = modules.collectionAccess.collection(\"FuelHistory\");\n// fuelHistoryCol.find({}, function(fuelErr, fuelHistoryList){\n// var count = fuelHistoryList.length;\n// modules.logger.info(\"Count: \"+count);\n// fuelHistoryList.forEach(function(fuelHistory){\n// var operator = {OperatorID: fuelHistory.OperatorID? Number(fuelHistory.OperatorID): null};\n// fuelHistoryCol.update({\"_id\":fuelHistory._id}, {$set: operator}, {upsert: false}, function(updateErr, updatedRes){\n// count--;\n// if (count <= 0){\n// response.complete();\n// }\n// })\n// });\n// });\n \n// var usersCol = modules.collectionAccess.collection(\"user\");\n// var orgId = \"165\";\n// var tractorOwners = usersCol.find({orgIDs: orgId, user_type: {$ne: 2}}, function(userErr, users){\n// modules.logger.info(users.length);\n// response.complete();\n// });\n \n// var trackerIdsCol = modules.collectionAccess.collection(\"TrackerIds\");\n// var count = 0;\n \n// var baseId = 910000\n// for(var i = 0; i < 100; i++){\n// var trackerId = {tracker_id: (baseId+i)}\n// var trackerIdA = modules.kinvey.entity(trackerId);\n// trackerIdsCol.save(trackerIdA, function(saveIdErr, savedTrackerId){\n// if (i >= 99){\n// response.complete();\n// }\n// });\n// }\n \n \n \n// logger.info(\"Hello external API\");\n // response.complete();\n// var options = {limit:1};\n// var count = 0;\n// var hectares = 0;\n \n\n// modules.collectionAccess.collection(\"ServiceBookings\").distinct(\"bookingID\", {\"bookingStatus\":0}, function (err, docs) {\n// if (err) {\n// logger.error('Query failed: '+ err);\n// response.error();\n// } else {\n// modules.logger.info(docs.length);\n// for (var i = 0; i < docs.length; i++){\n// if (docs[i].hectaresServiced && docs[i]._acl.creator != \"5af40bd426860c399aba621b\" && docs[i]._acl.creator != \"598ad681bac152c62bcfd9ef\"){\n// hectares += Number(docs[i].hectaresServiced);\n// }\n// count += 1;\n// if (count >= docs.length){\n// modules.logger.info(\"Hectares: \"+hectares+\", Count: \"+count);\n// response.complete();\n// } \n// }\n// }\n// }); \n \n \n// var country = \"Kenya\";\n// var date = \"2019-02-15\";\n// var query = {\"LastActiveTime\": {$gte: date}, \"Country\":country};\n// var query = {\"LastActiveTime\": {$gte: date}};\n// var sort = {sort: {\"Country\":1}};\n \n \n \n// modules.collectionAccess.collection(\"TractorDetail\").find(query, function (err, docs) {\n// if (err) {\n// logger.error('Query failed: '+ err);\n// response.error();\n// } else {\n// modules.logger.info(country+\" tractors: \"+docs.length);\n// response.complete();\n// }\n// }); \n \n \n \n //Total number of engine hours\n// modules.collectionAccess.collection(\"TractorDetail\").find(query, function (err, docs) {\n// if (err) {\n// logger.error('Query failed: '+ err);\n// response.error();\n// } else {\n// var engineHours = 0;\n// var distance = 0;\n// for (var i = 0; i < docs.length; i++){\n// engineHours += Number(docs[i].EngineHours);\n// distance += Number(docs[i].TotalDistanceCovered);\n// }\n// modules.logger.info(\"Total Tractors: \"+docs.length);\n// modules.logger.info(\"Total Eninge Hours: \"+engineHours);\n// modules.logger.info(\"Total Distance Covered: \"+distance);\n// response.complete();\n// }\n// }); \n \n \n \n// modules.collectionAccess.collection('ServiceBookings').update({orgID:\"165\"}, {$set: {\"BookingArchived\":\"\"}}, {upsert: false, multi: true}, function(err){\n// logger.info(\"Done\");\n// });\n \n \n \n \n// Compute total number of bookings after a certain date\n// var bookingStatusQuery = {\"bookingStatus\":0};\n// var createdAtQuery = {\"createdAt\": {$gte:\"2019-02-22\", $lt:\"2019-02-23\"}};\n// modules.collectionAccess.collection(\"ServiceBookings\").distinct(\"bookingID\", createdAtQuery, function (err, docs) {\n// if (err) {\n// logger.error('Query failed: '+ err);\n// response.error();\n// } else {\n// modules.logger.info(\"Bookings Number: \"+docs.length);\n// modules.logger.info(docs);\n \n// for (var i = 0; i < docs.length; i++){\n// if (docs[i].hectaresServiced && docs[i]._acl.creator != \"5af40bd426860c399aba621b\" && docs[i]._acl.creator != \"598ad681bac152c62bcfd9ef\"){\n// hectares += Number(docs[i].hectaresServiced);\n// }\n// count += 1;\n// if (count >= docs.length){\n// modules.logger.info(\"Hectares: \"+hectares+\", Count: \"+count);\n// response.complete();\n// } \n// }\n// }\n// }); \n \n \n \n// Generates dummy tractors for test@hellotractor.com\n// var fuelHistoryCol = modules.collectionAccess.collection(\"FuelHistory\");\n// var tractorIds = [100119];\n// var testAcl = {\"creator\":\"5a8831637ab19c0d42abd747\"};\n// var log = modules.logger;\n// var countTractors = 0;\n// var countTractorsSaved = 0;\n// fuelHistoryCol.find({TractorID: {$in: tractorIds}}, function(fuelHistoryErr, fuelHistoryList){\n// countTractors = fuelHistoryList.length;\n// log.info(\"Count tractors: \"+countTractors);\n// fuelHistoryList.forEach(function(fuelHistory){\n// delete fuelHistory._id;\n// fuelHistory._acl = testAcl;\n// fuelHistory.TractorID = 500196\n// fuelHistoryCol.save(fuelHistory, function(fuelHistorySaveErr, fuelHistorySaved){\n// countTractors--;\n// countTractorsSaved++;\n// finish();\n// });\n// });\n// });\n\n// var finish = function(){\n// if (countTractors <= 0){\n// log.info(\"Done: \"+countTractorsSaved);\n// response.complete();\n// }\n// }\n \n \n// var serviceBookingsCol = modules.collectionAccess.collection(\"ServiceBookings\");\n// var log = modules.logger;\n// var newOrgID = \"300\";\n// var lastThreeMonths = modules.moment.utc().subtract(3, \"months\").format(\"YYYY-MM-DD\");\n// log.info(\"Last three months: \"+lastThreeMonths);\n// var countBookings = 0;\n// var bookingsSaved = 0;\n// var query = {\n// $and: [\n// {orgID: \"305\"},\n// {bookingStatus: 0},\n// {createdAt: {$gt: lastThreeMonths}}\n// ]\n// };\n\n// serviceBookingsCol.find(query, {limit: 20, sort: {clusterID: -1}}, function(serviceBookingErr, serviceBookingList){\n// if (serviceBookingList && serviceBookingList.length > 0){\n// log.info(\"Service bookings length: \"+serviceBookingList.length);\n// countBookings = serviceBookingList.length;\n// serviceBookingList.forEach(function(booking){\n// booking.orgID = newOrgID;\n// booking.farmerName = booking.farmerName+\" Test\";\n// serviceBookingsCol.save(booking, function(serviceBookingSavedErr, serviceBookingSaved){\n// countBookings--;\n// bookingsSaved++;\n// finish();\n// });\n// });\n// } else {\n// log.info(\"Finished: No booking found\");\n// finish();\n// }\n// });\n\n// var finish = function(){\n// if (countBookings <= 0){\n// log.info(\"Done: \"+bookingsSaved);\n// response.complete();\n// }\n// }\n \n \n \n //Generates dummy fuel history for select tractors\n// var fuelHistoryCol = modules.collectionAccess.collection(\"FuelHistory\");\n// var tractorIds = [500196];\n// var testAcl = {\"creator\":\"59c8d84f8c59558e131dd898\"};\n// var log = modules.logger;\n// var countTractors = 0;\n// var countTractorsSaved = 0;\n// fuelHistoryCol.find({TractorID: {$in: tractorIds}}, function(fuelHistoryErr, fuelHistoryList){\n// countTractors = fuelHistoryList.length;\n// log.info(\"Count tractors: \"+countTractors);\n// fuelHistoryList.forEach(function(fuelHistory){\n// fuelHistory._acl = testAcl;\n// fuelHistory.TractorID = 100119\n// fuelHistoryCol.save(fuelHistory, function(fuelHistorySaveErr, fuelHistorySaved){\n// countTractors--;\n// countTractorsSaved++;\n// finish();\n// });\n// });\n// });\n\n// var finish = function(){\n// if (countTractors <= 0){\n// log.info(\"Done: \"+countTractorsSaved);\n// response.complete();\n// }\n// }\n \n// var usersCol = modules.collectionAccess.collection(\"user\");\n// usersCol.find({\"orgIDs\": \"6018\"}, function(necasAgentsErr, necasUsers){\n// // var usersNameAndPhone = necasUsers.map(function(user){\n// // return user.first_name +\", \"+user.username;\n// // })\n \n// modules.logger.info(JSON.stringify(necasUsers));\n// modules.logger.info(\"Here\");\n// response.complete();\n// });\n \n var notificationCol = modules.collectionAccess.collection(\"Notification\");\n notificationCol.find({_kmd: {$exists: false}}, function(notificationErr, notificationList){\n modules.logger.info(\"Count empty kmd notificaitions: \"+notificationList.length);\n \n notificationCol.update({_kmd: {$exists: false}}, {$set: {_kmd: {\"lmt\":\"2020-04-22T09:06:04.938Z\", \"ect\":\"2020-04-22T09:06:04.938Z\"}}}, {multi: true, upsert: false}, function(updateNotificationErr, updateNotificationList){\n modules.logger.info(\"Notifications updated successfully\");\n \tresponse.complete(); \n })\n });\n \n}" }, "process-update-tractors-status" : { "code" : "// function onRequest(request, response, modules){\n \n// /*\n// This endpoint gets the status of each tractor from 2track and updates it with the latest reading from the monitoring device\n// */\n \n// var collectionAccess = modules.collectionAccess,\n// async = modules.async,\n// logger = modules.logger,\n// moment = modules.moment,\n// token = \"\";\n \n// //Get 2track access token\n// collectionAccess.collection('TwoTrackApiToken').findOneAsync({id: 9228383772})\n// .then(function(accessToken) {\n// token = accessToken;\n \n// },\n// function(err) {\n \n// return response.error(err);\n// });\n \n// //Get tractors and loop through the tractors\n// modules.collectionAccess.collection('TractorDetail').find({}, function (err, tractors) {\n\n// tractors.forEach(function(tractor, a){\n\n// if(tractor.TractorID.toString().length === 6){\n// //logger.info(\"tractor ServiceProvider: \"+ tractor.ServiceProvider);\n \n// //Make a request to 2track for the tractor's status and update the tractor detail collection\n// var payloadOptions = {\n// \"token\": \"\"+token.token+\"\",\n// \"trackers\":[{\"trackerId\": tractor.TractorID}]\n// },\n// requestOptions = {\n// url: 'https://hellotractor.2-track.com:8080/api/status',\n// method: 'POST',\n// headers: {\n// 'Content-Type': 'application/json',\n// 'Accept': 'application/json',\n// 'Version': 'v1'\n// },\n// json: true,\n// body: payloadOptions\n// };\n \n// modules.request.request(requestOptions, function(err, resp, body) {\n// //logger.info(\"Data returned is:\" + JSON.stringify(body.data));\n// if(err) {\n// return cb(err);\n// } else {\n// if(!body.data) {\n// logger.info(\"There was no data in body for tractor: \"+ tractor.TractorID);\n// return;\n// } else {\n// //logger.info(\"Successfully placed http request for tractor status for: \" + tractor.TractorID);\n// async.parallel({\n// updateTractorDetail: async.apply(updateTractorDetail, resp.body.data, tractor.TractorID, tractor)\n// });\n// }\n// }\n\n// //response.complete(200);\n// });\n// }\n \n// }); //end forEach tractors\n// });//end collectionAccess get all tractors\n \n \n// function updateTractorDetail(data, cb, tractor) {\n\n// if(data.length === 0) {\n// logger.info(\"No status for tractor \" + tractor.TractorID);\n// return;\n// }\n \n// /*\n// [{\"trackerId\":\"100021\",\"speed\":0,\"odometer\":2603967,\"isGPSValid\":true,\"lat\":0.0711,\"lon\":37.1458,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":322,\"altitude\":200893,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"Laikipia County\",\"country\":\"Kenya\",\"lastReportUTCDate\":\"2017-05-10 05:15:13.0\"}]\n// */\n \n// var setObject = {\n// LastActiveTime: data[0].lastReportUTCDate,\n// PositionLatitude: data[0].lat,\n// PositionLongitude: data[0].lon,\n// Speed: data[0].speed,\n// UpdatedAt: modules.moment().format('YYYY-MM-DD HH:mm:ss')\n// };\n \n// // Street: data[0].street,\n// // Town: data[0].town,\n// // Country: data[0].country,\n \n// setObject['_kmd.lmt'] = moment().toISOString();\n// //logger.info(\"LastActiveTime is: \"+ setObject.LastActiveTime);\n \n// var tractorId = tractor.TractorID;\n \n// collectionAccess.collection('TractorDetail').update({TractorID: tractor.TractorID},\n// {\n// $set: setObject\n\n// }, function(err) {\n// if(err) {\n// return response.error(err);\n// }\n\n// //return response.complete(200);\n// }); \n \n// logger.info(\"Finished updating tractor: \" + tractor.TractorID);\n// }\n \n// }\n" }, "fetch-store-tractor-activities-three" : { "code" : "function onRequest(request, response, modules){\n \n var collectionAccess = modules.collectionAccess,\n logger = modules.logger,\n async = modules.async,\n moment = modules.moment;\n \n var token = \"\";\n\t\n\tcollectionAccess.collection('TwoTrackApiToken').findOneAsync({id: 9228383772})\n\t.then(function(accessToken) {\n\t\ttoken = accessToken;\n\t\t\n\t},\n\tfunction(err) {\n\t\t\n\t\treturn response.error(err);\n\t});\n\n modules.collectionAccess.collection('TractorDetail').find({\n TractorID: {\n $gte: 100099,\n $lte: 100150\n }\n }, function (err, tractors) {\n\n tractors.forEach(function(tractor, a){\n if(tractor.TractorID.toString().length === 6){\n\n //Make request to 2track and store data in collection\n var startActivityId = tractor.LastActivityId ? tractor.LastActivityId : 0,\n payloadOptions = {\n token: \"\"+token.token+\"\",\n trackerId: tractor.TractorID,\n startActivityId: startActivityId,\n rowCount: 100,\n startUTCTime: \"\",\n endUTCTime: \"\"\n },\n requestOptions = {\n url: 'https://hellotractor.2-track.com:8080/api/activity',\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Version': 'v1'\n },\n json: true,\n body: payloadOptions\n };\n\n modules.request.request(requestOptions, function(err, resp, body) {\n if(err) {\n logger.error(\"Error placing request to 2track\");\n return;\n } else {\n if(!body.data) {\n logger.error(\"Error: No data available for tractor\");\n return;\n } else {\n //logger.info(\"Successfully placed http request for tractor updates for: \" + tractor.TractorID);\n async.parallel({\n saveTractorActivities: async.apply(saveTractorActivities, body.data, tractor.TractorID),\n updateTractorDetail: async.apply(updateTractorDetail, body.data, tractor.TractorID, tractor)\n });\n }\n }\n //response.complete(200);\n });\n }\n });\n });\n \n function saveTractorActivities(tractorActivities, tractorId){\n //logger.info(\"in function saveTractorActivities and tractor activityId is: \"+tractor.activityId);\n \n tractorActivities.forEach(function(tractor, a) {\n \n var entity = modules.kinvey.entity();\n entity.TractorID = tractorId;\n entity.ActivityID = tractor.activityId;\n entity.EventCode = tractor.eventCode;\n entity.EventName = tractor.eventName;\n entity.Speed = tractor.speed;\n entity.Odometer = tractor.odometer;\n entity.Idle = tractor.idle;\n entity.IsGPSValid = tractor.isGPSValid;\n entity.Lat = tractor.lat;\n entity.Lng = tractor.lon;\n entity.DirectionEW = tractor.directionEW;\n entity.DirectionNS = tractor.directionNS;\n entity.Altitude = tractor.altitude;\n entity.IgnitionStatus = tractor.ignitionStatus;\n entity.BatteryVoltage = tractor.batteryVoltage;\n entity.SatelliteNumber = tractor.satelliteNumber;\n entity.Street = tractor.street;\n entity.Town = tractor.town;\n entity.County = tractor.county;\n entity.Country = tractor.country;\n entity.ActivityUTCDate = tractor.activityUTCDate;\n\n collectionAccess.collection('TractorActivityData').save(entity, function(err) {\n logger.info(\"Successfully saved data for tractor with ID: \" + tractorId);\n });\n });\n \n //response.complete();\n }\n \n //update coordinates and address of tractor, send geofence push notifications\n function updateTractorDetail(activities, cb, tractor) {\n //logger.info(\"Begining process for updating tractor and tractor data is:\" + tractor.TractorID);\n\n if(activities.length === 0) {\n logger.info(\"No activities data for tractor \" + tractor.TractorID);\n return;\n //return cb();\n }\n var lastActivity = activities.reduce(function(prev, curr) {\n return prev.activityUTCDate > curr.activityUTCDate ? prev : curr;\n });\n\n var setObject = {\n LastActiveTime: lastActivity.activityUTCDate\n };\n\n if(lastActivity.lat && lastActivity.lon) {\n\n setObject.PositionLatitude = lastActivity.lat;\n setObject.PositionLongitude = lastActivity.lon;\n setObject.LastActivityId = lastActivity.activityId;\n\n// if(lastActivity.country){\n// setObject.Street = lastActivity.street;\n// setObject.Town = lastActivity.town;\n// setObject.Country = lastActivity.country;\n// }\n setObject['_kmd.lmt'] = moment().toISOString();\n\n collectionAccess.collection('TractorDetail').update({TractorID: cb},\n {\n $set: setObject\n\n }, function(err) {\n if(err) {\n return response.error(err);\n }\n\n //return response.complete(200);\n });\n\n }\n else{\n response.complete(400);\n //return cb();\n }\n }\n //response.complete();\n}" }, "fetch-store-tractor-activities-two" : { "code" : "// function onRequest(request, response, modules){\n \n// var collectionAccess = modules.collectionAccess,\n// logger = modules.logger,\n// async = modules.async,\n// moment = modules.moment;\n \n// var token = \"\";\n\n// collectionAccess.collection('TwoTrackApiToken').findOneAsync({id: 9228383772})\n// .then(function(accessToken) {\n// token = accessToken;\n \n// },\n// function(err) {\n \n// return response.error(err);\n// }); \n \n// modules.collectionAccess.collection('TractorDetail').find({\n// TractorID: {\n// $gte: 100049,\n// $lte: 100100\n// }\n// }, function (err, tractors) {\n\n// tractors.forEach(function(tractor, a){\n// if(tractor.TractorID.toString().length === 6){\n\n// //Make request to 2track and store data in collection\n// var startActivityId = tractor.LastActivityId ? tractor.LastActivityId : 0,\n// payloadOptions = {\n// token: \"\"+token.token+\"\",\n// trackerId: tractor.TractorID,\n// startActivityId: startActivityId,\n// rowCount: 100,\n// startUTCTime: \"\",\n// endUTCTime: \"\"\n// },\n// requestOptions = {\n// url: 'https://hellotractor.2-track.com:8080/api/activity',\n// method: 'POST',\n// headers: {\n// 'Content-Type': 'application/json',\n// 'Accept': 'application/json',\n// 'Version': 'v1'\n// },\n// json: true,\n// body: payloadOptions\n// };\n\n// modules.request.request(requestOptions, function(err, resp, body) {\n// if(err) {\n// logger.error(\"Error placing request to 2track\");\n// return;\n// } else {\n// if(!body.data) {\n// logger.error(\"Error: No data available for tractor\");\n// return;\n// } else {\n// //logger.info(\"Successfully placed http request for tractor updates for: \" + tractor.TractorID);\n// async.parallel({\n// saveTractorActivities: async.apply(saveTractorActivities, body.data, tractor.TractorID),\n// updateTractorDetail: async.apply(updateTractorDetail, body.data, tractor.TractorID, tractor)\n// });\n// }\n// }\n// //response.complete(200);\n// });\n// }\n// });\n// });\n \n// function saveTractorActivities(tractorActivities, tractorId){\n// //logger.info(\"in function saveTractorActivities and tractor activityId is: \"+tractor.activityId);\n \n// tractorActivities.forEach(function(tractor, a) {\n \n// var entity = modules.kinvey.entity();\n// entity.TractorID = tractorId;\n// entity.ActivityID = tractor.activityId;\n// entity.EventCode = tractor.eventCode;\n// entity.EventName = tractor.eventName;\n// entity.Speed = tractor.speed;\n// entity.Odometer = tractor.odometer;\n// entity.Idle = tractor.idle;\n// entity.IsGPSValid = tractor.isGPSValid;\n// entity.Lat = tractor.lat;\n// entity.Lng = tractor.lon;\n// entity.DirectionEW = tractor.directionEW;\n// entity.DirectionNS = tractor.directionNS;\n// entity.Altitude = tractor.altitude;\n// entity.IgnitionStatus = tractor.ignitionStatus;\n// entity.BatteryVoltage = tractor.batteryVoltage;\n// entity.SatelliteNumber = tractor.satelliteNumber;\n// entity.Street = tractor.street;\n// entity.Town = tractor.town;\n// entity.County = tractor.county;\n// entity.Country = tractor.country;\n// entity.ActivityUTCDate = tractor.activityUTCDate;\n\n// collectionAccess.collection('TractorActivityData').save(entity, function(err) {\n// logger.info(\"Successfully saved data for tractor with ID: \" + tractorId);\n// });\n// });\n \n// //response.complete();\n// }\n \n// //update coordinates and address of tractor, send geofence push notifications\n// function updateTractorDetail(activities, cb, tractor) {\n// //logger.info(\"Begining process for updating tractor and tractor data is:\" + tractor.TractorID);\n\n// if(activities.length === 0) {\n// logger.info(\"No activities data for tractor \" + tractor.TractorID);\n// return;\n// //return cb();\n// }\n// var lastActivity = activities.reduce(function(prev, curr) {\n// return prev.activityUTCDate > curr.activityUTCDate ? prev : curr;\n// });\n\n// var setObject = {\n// LastActiveTime: lastActivity.activityUTCDate\n// };\n\n// if(lastActivity.lat && lastActivity.lon) {\n\n// setObject.PositionLatitude = lastActivity.lat;\n// setObject.PositionLongitude = lastActivity.lon;\n// setObject.LastActivityId = lastActivity.activityId;\n\n// // if(lastActivity.country){\n// // setObject.Street = lastActivity.street;\n// // setObject.Town = lastActivity.town;\n// // setObject.Country = lastActivity.country;\n// // }\n// setObject['_kmd.lmt'] = moment().toISOString();\n\n// collectionAccess.collection('TractorDetail').update({TractorID: cb},\n// {\n// $set: setObject\n\n// }, function(err) {\n// if(err) {\n// return response.error(err);\n// }\n\n// //return response.complete(200);\n// });\n\n// }\n// else{\n// response.complete(400);\n// //return cb();\n// }\n// }\n// //response.complete();\n// }" }, "temp-daily-tractor-activity-clone" : { "code" : "// function onRequest(request, response, modules){\n \n// var collectionAccess = modules.collectionAccess,\n// logger = modules.logger,\n// async = modules.async,\n// moment = modules.moment,\n// requestContext = modules.requestContext;\n \n// modules.collectionAccess.collection('DailyTractorActivity').find({day: \"2017-06-21\"}, function (err, activities) {\n\n// activities.forEach(function(activity, a){\n// //copy the data over to the new collection\n// async.parallel({\n// saveClone: async.apply(saveClone, activity)\n// });\n// }\n \n// );\n// \t});\n \n// function saveClone(activity){\n \n// var entity = modules.kinvey.entity();\n// entity.TotalTimeActive = activity.TotalTimeActive;\n// entity.TotalTimeIdle = activity.TotalTimeIdle; \n// entity.DistanceTravelled = activity.DistanceTravelled;\n// entity.TractorID = activity.TractorID;\n// entity.day = activity.day;\n// entity.PositionLongitude = activity.PositionLongitude;\n// entity.LastActivityId = activity.LastActivityId;\n// entity.LastJourneyStartTime = activity.LastJourneyStartTime;\n// entity.TotalSpeed = activity.TotalSpeed;\n// entity.TotalSpeedCounter = activity.TotalSpeedCounter;\n// entity.AverageSpeed = activity.AverageSpeed;\n// entity.StartActiveData = activity.StartActiveData;\n// entity.LastActiveData = activity.LastActiveData;\n// entity.LastOdometerValue = activity.LastOdometerValue;\n// entity.BatteryVoltage = activity.batteryVoltage;\n// entity.SatelliteNumber = activity.satelliteNumber;\n// entity.Revenue = activity.Revenue;\n// entity.Town = activity.Town;\n// entity.Street = activity.Street;\n// entity.Country = activity.Country;\n// entity.StartCountry = activity.StartCountry;\n// entity.StartTown = activity.StartTown;\n// entity.StartStreet = activity.StartStreet;\n// entity.Route = activity.Route;\n// entity.OperatorID = activity.OperatorID;\n// entity.RevenueType = activity.RevenueType;\n// entity.RevenueCurrency = activity.RevenueCurrency;\n// entity.HectaresServiced = activity.HectaresServiced;\n// entity.IgnitionStatus = activity.IgnitionStatus;\n// entity.Hectares = activity.Hectares;\n// entity._kmd = activity._kmd;\n// entity._id = activity._id;\n\n// collectionAccess.collection('DailyTractorActivityClone').save(entity, function(err) {\n// logger.info(\"Successfully saved data for activity on day: \"+ activity.day);\n// });\n \n// }\n \n// //response.complete();\n \n// }" }, "fetch-update-daily-tractor-activity" : { "code" : "// function onRequest(request, response, modules){\n \n// var collectionAccess = modules.collectionAccess,\n// logger = modules.logger,\n// async = modules.async,\n// moment = modules.moment;\n \n// var token = \"\";\n \t\n// \tcollectionAccess.collection('TwoTrackApiToken').findOneAsync({id: 9228383772})\n// \t.then(function(accessToken) {\n// \t\ttoken = accessToken;\n \t\t\n// \t},\n// \tfunction(err) {\n \t\t\n// \t\treturn response.error(err);\n// \t});\n \n// modules.collectionAccess.collection('TractorDetail').find({}, function (err, tractors) {\n\n// tractors.forEach(function(tractor, a){\n \n// if(tractor.TractorID.toString().length === 6){\n\n// //Make request to 2track and store data in collection\n// var payloadOptions = {\n// token: \"\"+token.token+\"\",\n// trackerId: tractor.TractorID,\n// startActivityId: startActivityId,\n// rowCount: 101,\n// startUTCTime: \"\",\n// endUTCTime: \"\"\n// },\n// requestOptions = {\n// url: 'https://hellotractor.2-track.com:8080/api/activity',\n// method: 'POST',\n// headers: {\n// 'Content-Type': 'application/json',\n// 'Accept': 'application/json',\n// 'Version': 'v1'\n// },\n// json: true,\n// body: payloadOptions\n// };\n\n// modules.request.request(requestOptions, function(err, resp, body) {\n// if(err) {\n// logger.error(\"Error placing request to 2track\");\n// return;\n// } else {\n// if(!body.data) {\n// logger.error(\"Error: No data available for tractor\");\n// return;\n// } else {\n// //logger.info(\"Successfully placed http request for tractor updates for: \" + tractor.TractorID);\n// async.parallel({\n// updateDailyTractorActivity: async.apply(updateDailyTractorActivity, body.data, tractor.TractorID, tractor)\n// });\n// }\n// }\n// //response.complete(200);\n// });\n// }\n// });\n// });\n \n// //update coordinates and address of tractor, send geofence push notifications\n// function updateDailyTractorActivity(activities, cb, tractor) {\n// //logger.info(\"Begining process for updating tractor and tractor data is:\" + tractor.TractorID);\n\n// if(activities.length === 0) {\n// logger.info(\"No activities data for tractor \" + tractor.TractorID);\n// return;\n// //return cb();\n// }\n \n// //check if this tractor has been created. If not, then create a new row\n// modules.collectionAccess.collection('TractorDetail').find({}, function (err, tractors) {\n \n// };\n// else{\n// var entity = modules.kinvey.entity(results);\n// entity.HectaresServiced = 0;\n// collectionAccess.collection('DailyTractorActivity').save(entity, cb);\n// }\n\n// var setObject = {\n// LastActiveTime: lastActivity.activityUTCDate\n// };\n\n// if(lastActivity.lat && lastActivity.lon) {\n\n// setObject.day = lastActivity.lat;\n// setObject.PositionLongitude = lastActivity.lon;\n// setObject.LastActivityId = lastActivity.activityId;\n// setObject.TotalTimeActive = lastActivity.lat;\n// setObject.TotalTimeIdle = lastActivity.lat;\n// setObject.LastJourneyStartTime = lastActivity.lat;\n// setObject.TotalSpeed = lastActivity.lat;\n// setObject.TotalSpeedCounter = lastActivity.lat;\n// setObject.AverageSpeed = lastActivity.lat;\n// setObject.StartActiveData = lastActivity.lat;\n// setObject.LastActiveData = lastActivity.lat;\n// setObject.Country = lastActivity.lat;\n// setObject.Town = lastActivity.lat;\n// setObject.Street = lastActivity.lat;\n// setObject.DistanceTravelled = lastActivity.lat;\n// setObject.LastOdometerValue = lastActivity.lat;\n// setObject.Revenue = lastActivity.lat;\n// setObject.StartCountry = lastActivity.lat;\n// setObject.StartTown = lastActivity.lat;\n// setObject.StartStreet = lastActivity.lat;\n// setObject.Route = lastActivity.lat;\n// setObject.OperatorID = lastActivity.lat;\n// setObject.RevenueType = lastActivity.lat;\n// setObject.RevenueCurrency = lastActivity.lat;\n// setObject.HectaresServiced = lastActivity.lat;\n// setObject.IgnitionStatus = lastActivity.lat;\n\n// setObject['_kmd.lmt'] = moment().toISOString();\n\n// collectionAccess.collection('TestDailyTractorActivity').update({TractorID: cb, day: },\n// {\n// $set: setObject\n\n// }, function(err) {\n// if(err) {\n// return response.error(err);\n// }\n\n// //return response.complete(200);\n// });\n\n// }\n// else{\n// response.complete(400);\n// //return cb();\n// }\n// }\n// }" }, "update-tractor-geofence" : { "code" : "function onRequest(request, response, modules) {\n \n var logger = modules.logger;\n var collectionAccess = modules.collectionAccess;\n \n var tractorId = request.body.tractorId;\n logger.info(\"ID posted: \"+ tractorId);\n\n var tractors = []; \n var count = 0;\n \n if(!tractorId){\n logger.error(\"Invalid Tractor posted: \"+ tractorId);\n return response.complete(400);\n }\n\n logger.info(\"tractorId posted: \"+ JSON.stringify(request.body)); \n \n if (Array.isArray(tractorId)){\n logger.info(\"isArray checked\");\n for (var i=0; i<tractorId.length; i++){\n collectionAccess.collection('TractorDetail').update({TractorID: tractorId[i]}, {\n $set: {\n Latitude: request.body.Latitude,\n Longitude: request.body.Longitude,\n NeedToSendGeofenceOutNotification: true,\n WasInArea: true,\n LastGeofenceNotificationTime: ''\n }\n }, function(err, tractorUpdated) {\n collectionAccess.collection(\"TractorDetail\").find({TractorID: tractorId[i]}, {}, function(err, tractor){\n if (err){\n logger.info('error ' + JSON.stringify(err));\n return response.error(err); \n } else {\n logger.info(\"no error: \"+i);\n var geofenceLatitude = request.body.Latitude,\n geofenceLongitude = request.body.Longitude;\n\n tractors.push(tractorUpdated);\n if(tractors.length == tractorId.length) {\n c_sendGeoFenceNotification(tractor, 'geofenceCreated', function(err2) {\n if(err2){\n return response.error(err2);\n }\n return response.complete();\n });\n response.complete();\n } else {\n response.complete();\n } \n \n }\n }); \n });\n } \n } else {\n logger.info(\"isNotArray\");\n collectionAccess.collection('TractorDetail').update({TractorID: tractorId}, {\n $set: {\n Latitude: request.body.Latitude,\n Longitude: request.body.Longitude,\n NeedToSendGeofenceOutNotification: true,\n WasInArea: true,\n LastGeofenceNotificationTime: ''\n }\n }, function(err) {\n if(err) {\n return response.error(err);\n }\n\n collectionAccess.collection('TractorDetail').findOneAsync({TractorID: tractorId})\n .then(function(tractor) {\n var geofenceLatitude = request.body.Latitude,\n geofenceLongitude = request.body.Longitude;\n\n if(tractor) {\n c_sendGeoFenceNotification(tractor, 'geofenceCreated', function(err) {\n if(err){\n return response.error(err);\n }\n return response.continue();\n });\n } else {\n return response.continue();\n }\n },\n function(err) {\n logger.info('error ' + JSON.stringify(err));\n return response.error(err);\n });\n\n return response.complete(200);\n }); \n }\n}" }, "b_UpdateBookingAgents" : { "code" : "function onRequest(request, response, modules) {\n \n var collectionAccess = modules.collectionAccess,\n logger = modules.logger,\n async = modules.async,\n moment = modules.moment;\n\n //loop through the tractor owners and post the data of each row to the aws backend.\n modules.collectionAccess.collection('BookingAgents').find({}, function (err, bookingAgents) {\n \n bookingAgents.forEach(function(bookingAgent, a){\n \n logger.info(\"syncing to server for: \"+ bookingAgent.username);\n \n var payloadOptions = {\n op: 'create',\n data: bookingAgent\n },\n requestOptions = {\n url: 'https://cloud.hellotractor.com/kinvey/api/bookingagents',\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Version': 'v1'\n },\n json: true,\n body: payloadOptions\n };\n\n modules.request.request(requestOptions, function(err, resp, body) {\n if(err) {\n //return cb(err);\n } else {\n \n //response.complete(200);\n }\n \n });\n\n });\n });\n \n //response.complete(200);\n}" }, "UpdateTractorOwnersOnBackend" : { "code" : "function onRequest(request, response, modules) {\n \n var collectionAccess = modules.collectionAccess,\n logger = modules.logger,\n async = modules.async,\n moment = modules.moment;\n\n //loop through the tractor owners and post the data of each row to the aws backend.\n modules.collectionAccess.collection('TractorOwner').find({}, function (err, tractorOwners) {\n \n tractorOwners.forEach(function(tractorOwner, a){\n \n //logger.info(\"syncing to server for: \"+ tractorOwner.first_name);\n \n var payloadOptions = {\n op: 'create',\n data: tractorOwner\n },\n requestOptions = {\n url: 'https://cloud.hellotractor.com/kinvey/api/users',\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Version': 'v1'\n },\n json: true,\n body: payloadOptions\n };\n\n modules.request.request(requestOptions, function(err, resp, body) {\n if(err) {\n //return cb(err);\n } else {\n \n //logger.info(\"Successfully placed http request\");\n //response.complete(200);\n }\n\n \n });\n\n });\n });\n \n //response.complete(200);\n}" }, "UpdateBookingAgentsOnBackend" : { "code" : "function onRequest(request, response, modules) {\n \n var collectionAccess = modules.collectionAccess,\n logger = modules.logger,\n async = modules.async,\n moment = modules.moment;\n\n //loop through the tractor owners and post the data of each row to the aws backend.\n modules.collectionAccess.collection('BookingAgents').find({}, function (err, bookingAgents) {\n \n bookingAgents.forEach(function(bookingAgent, a){\n \n logger.info(\"syncing to server for: \"+ bookingAgent.username);\n \n var payloadOptions = {\n op: 'create',\n data: bookingAgent\n },\n requestOptions = {\n url: 'https://cloud.hellotractor.com/kinvey/api/bookingagents',\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Version': 'v1'\n },\n json: true,\n body: payloadOptions\n };\n\n modules.request.request(requestOptions, function(err, resp, body) {\n if(err) {\n //return cb(err);\n } else {\n \n //response.complete(200);\n }\n \n });\n\n });\n });\n \n //response.complete(200);\n}" }, "b_UpdateDailyTractorActivities" : { "code" : "function onRequest(request, response, modules){\n \n var collectionAccess = modules.collectionAccess,\n logger = modules.logger,\n async = modules.async,\n moment = modules.moment;\n\n //loop through the tractor owners and post the data of each row to the aws backend.\n modules.collectionAccess.collection('DailyTractorActivity').find({\n day: {\n $gte: moment.utc().format('YYYY-MM-DD'),\n $lte: moment.utc().format('YYYY-MM-DD')\n }\n }, function (err, dailytractoractivities) {\n \n dailytractoractivities.forEach(function(dailytractoractivity, a){\n \n logger.info(\"Syncing daily tractor activities to server\");\n \n var payloadOptions = {\n data: dailytractoractivity\n },\n requestOptions = {\n url: 'https://cloud.hellotractor.com/kinvey/api/dailytractoractivities',\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Version': 'v1'\n },\n json: true,\n body: payloadOptions\n };\n\n modules.request.request(requestOptions, function(err, resp, body) {\n if(err) {\n //return cb(err);\n } else {\n \n //response.complete(200);\n }\n \n });\n\n });\n });\n \n}" }, "deleteDuplicateFarmMeasures" : { "code" : "function onRequest(request, response, modules) {\n response.complete();\n}" }, "DeleteDuplicateFarmMeasure" : { "code" : "function onRequest(request, response, modules) {\n var FarmMeasureCollection = modules.collectionAccess.collection(\"FarmMeasure\"); \n var myLodash = modules.lodash;\n var farmMeasureData = FarmMeasureCollection.findAsync({syncStatus: 1});\n farmMeasureData.then(\n function(docs){\n var result = [];\n myLodash.forEach(docs, function(item){\n if (result.indexOf(item.farmMeasureID) < 0){\n result.push(item.farmMeasureID);\n } else {\n FarmMeasureCollection.remove({_id : item._id}, function(err){\n if (err){\n \tmodules.logger.info(err);\n }\n });\n }\n }); \n }, function(err){\n modules.logger.info(err);\n response.error(400);\n }); \n}" }, "UpdateBookingsWeather" : { "code" : "function onRequest(request, response, modules) {\n// response.complete();\nfor (var a = 0; a < 1000000; a++){\n modules.logger.info(a);\n}\n}" }, "Update2TrackTractorActiveTimeToday" : { "code" : "//Runs every three minutes to retrieve the active time for all 2track tractors \n//from DailyTractorActivity collection today\n//Created by Abdulmajid on 19/06/2018\n\nfunction onRequest(request, response, modules) {\n var tractorDetailCollection = modules.collectionAccess.collection(\"TractorDetail\");\n var dailyTractorActivityCollection = modules.collectionAccess.collection(\"DailyTractorActivity\"); \n var log = modules.logger;\n var loggerCollection= modules.collectionAccess.collection(\"Logger\");\n var LOG_ID = 106;\n var count = 0;\n var size = 0;\n var startTime = modules.moment().valueOf();\n var todaysDate = modules.moment.utc().format('YYYY-MM-DD'); \n \n\n tractorDetailCollection.find({TractorID: {$lt:500000}, LastActiveTime: {$gte: todaysDate}}, {}, function(err2, docs){\n\n //Group TractorIDs into an array\n var tractorIDs = [];\n for (var j = 0; j < docs.length; j++){\n tractorIDs.push(docs[j].TractorID);\n } //end for group tractor IDs\n\n findDailyActivityForTractorsAndUpdate(tractorIDs);\n\n });\n \n var findDailyActivityForTractorsAndUpdate = function(tractorIDs){\n// var todaysDate = \"2017-05-19\"; for testing\n \n loggerCollection.find({logID:LOG_ID}, {}, function(err1, logs){ \n \n dailyTractorActivityCollection.find({TractorID: {$in: tractorIDs}, day: todaysDate}, {\"sort\":{\"_id\":1}}, function(err, dailyActivities){\n log.info(\"No of daily activities: \"+dailyActivities.length);\n\n var startFrom = 0;\n if (logs[0].Message < dailyActivities.length){\n startFrom = logs[0].Message;\n }\n\n size = dailyActivities.length;\n count = startFrom;\n log.info(\"Size: \"+size+\", Start From: \"+startFrom); \n\n for (var i = startFrom; i < dailyActivities.length; i++){\n updateTractorDetailCollection(dailyActivities[i]);\n } \n\n }); \n\n }); \n }\n \n var updateTractorDetailCollection = function(dailyActivity){\n tractorDetailCollection.update({TractorID: dailyActivity.TractorID}, \n {$set: {\n \"ActiveTimeToday\":dailyActivity.TotalTimeActive,\n \"UpdatedAt\":modules.moment().format('YYYY-MM-DD HH:mm:ss')\n }}, \n {upsert: false}, \n function(tractorErr, tractorDetailDoc){\n count++;\n// log.info(\"No: \"+count+\", \"+JSON.stringify(dailyActivity));\n shouldCompleteRequest();\n }); //End update tractor detail with active time today \n }\n \n var shouldCompleteRequest = function(){\n var duration = modules.moment().valueOf() - startTime;\n if (count >= size || duration >= 19000){\n log.info(\"Total: \"+count);\n\n //Update logger and finish task\n loggerCollection.update({logID:LOG_ID}, {$set: {Message:count}}, {upsert: false}, function(logErr, logDoc){\n response.complete(); \n }); //End update logger collection with last count \n }//end if \n } \n \n} //end onRequest function\n \n\n" }, "Update_bookings_Sync_Status_to_1" : { "code" : "function onRequest(request, response, modules) {\n \n var Bookings = modules.collectionAccess.collection('ServiceBookings');\n Bookings.update({}, {$set: {\"syncStatus\": 1} }, {\"multi\":true } , function(err, updatedDocs){\n if(err) { modules.logger.info('There was an error:' + err) }\n else { modules.logger.info('docs updated')}\n \n response.complete();\n });\n \n}" }, "ResetTractorDetailActiveTimeToday" : { "code" : "//Resets the active time today field for all tractors to 0 at 11:59pm daily\n//Created by Abdulmajid on 21/06/2018\n\nfunction onRequest(request, response, modules) {\n var tractorDetailCollection = modules.collectionAccess.collection(\"TractorDetail\");\n tractorDetailCollection.update({}, {$set: {\n \"ActiveTimeToday\":0, \n \"UpdatedAt\":modules.moment().format('YYYY-MM-DD HH:mm:ss')\n }}, {upsert: false, multi: true}, function(err, doc){\n modules.logger.info(\"Reset Complete\");\n response.complete();\n });\n}" }, "UpdateBookingsWeatherDetails" : { "code" : "//Updates weather information for bookings every three (3) minutes where the service date is two weeks later than today\n//Created by Paul on 28/06/2018 \n//@update 01/11/2018 ( changed ready to fetch info to cater for bookings whose service date are in the future and storing only service date weather information of 9am only)\n\nfunction onRequest(request, response, modules) {\n var LOG_ID = 108, //log id to know count for the next batch\n collectionAccess = modules.collectionAccess,\n Logger = modules.collectionAccess.collection('Logger'),\n Booking = modules.collectionAccess.collection(\"ServiceBookings\"),\n APPID = \"&APPID=36b45f00efffeeb4d17f8509fe86d167\",\n Request = modules.request,\n count = 0,\n now = modules.moment(),\n startFrom = 0,\n now = modules.moment(),\n updateLimit = 60;\n\n //fetch weather information for bookings one week to the service date\n var canFetchBookingWeatherInfo = function (serviceDate) {\n var serviceDateTimestamp = modules.moment(serviceDate),\n oneWeekMinusServiceDate = modules.moment(serviceDateTimestamp).subtract(7, \"days\").format(\"YYYY-MM-DD\");\n return (now.format(\"YYYY-MM-DD\") >= oneWeekMinusServiceDate) && (now.format(\"YYYY-MM-DD\") <= serviceDate )\n }\n\n //fetch the booking weather condition\n var getWeatherConditionForBooking = function (booking) {\n /** make a request to the open weather API **/\n var lat = booking.latitude,\n lng = booking.longitude,\n isSetLatLng = lat && lng ? true : false;\n\n var readyToFetchWeatherInfo = canFetchBookingWeatherInfo(booking.serviceDate);\n\n if (isSetLatLng && readyToFetchWeatherInfo){\n\n var weatherURL = \"https://api.openweathermap.org/data/2.5/forecast?units=metric&lat=\" + lat + \"&lon=\" + lng + APPID;\n requestOptions = {\n url: weatherURL,\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json'\n },\n json: true\n };\n Request.request(requestOptions, function (err, resp, body) {\n if (!err) {\n if (body.cod == 200) {\n updateSingleBookingWeatherCondition(body, booking);\n } else {\n count++;\n checkToUpdateOrResetLogCount();\n }\n } else {\n count++;\n checkToUpdateOrResetLogCount();\n modules.logger.info(err);\n }\n });\n } else {\n count++;\n checkToUpdateOrResetLogCount();\n }\n }\n\n var getUpdatedAtForBooking = function () {\n return now.format('YYYY-MM-DD HH:mm:ss');\n\n }\n\n var updateSingleBookingWeatherCondition = function (condition, booking) {\n \n var bookingServiceDate = booking.serviceDate;\n var BookingServiceDateWeatherInfo = getBookingServiceDateWeatherInfo(condition, bookingServiceDate);\n modules.logger.info(\" BookingServiceDateWeatherInfo is \" + BookingServiceDateWeatherInfo);\n \n\t\tif( BookingServiceDateWeatherInfo ){ \n Booking.update({\n \"bookingID\": booking.bookingID\n }, {\n $set: {\n \"WeatherCondition\": BookingServiceDateWeatherInfo,\n \"updatedAt\": getUpdatedAtForBooking()\n }\n }, function (err, updatedBooking) {\n if (!err) {\n modules.logger.info(\"Updated the weather condition of booking with ID: \" + booking.bookingID);\n } else {\n modules.logger.info(\"not updating booking with ID: \" + booking_id);\n }\n count++;\n //update log count here\n checkToUpdateOrResetLogCount();\n\n })\n \n }\n else {\n\t\t\t\t\n count++;\n checkToUpdateOrResetLogCount();\n\n }\n\n }\n\n var checkToUpdateOrResetLogCount = function () {\n if (count == updateLimit) {\n //update or reset the log count\n UpdateOrResetLogCount();\n }\n }\n\n\n var UpdateOrResetLogCount = function () {\n var newCount = count + startFrom;\n modules.logger.info(\"new log count is \" + newCount);\n Booking.count({\n \"bookingStatus\": 0\n }, function (err, bookingCount) {\n\n modules.logger.info(\"total booking count is \" + bookingCount);\n if (newCount >= bookingCount) {\n Logger.update({\n \"logID\": LOG_ID\n }, {\n $set: {\n \"Message\": 0\n }\n }, function (err, countUpdated) {\n if (!err) {\n modules.logger.info(\"Log count reset successfull\");\n response.complete();\n } else {\n response.complete();\n }\n })\n\n } else if (newCount < bookingCount) {\n Logger.update({\n \"logID\": LOG_ID\n }, {\n $set: {\n \"Message\": newCount\n }\n }, function (err, updatedLogCount) {\n if (!err) {\n modules.logger.info(\"Log Count successfully updated to: \" + newCount);\n } else {\n modules.logger.info(\"There was an error updating log count\");\n }\n\n })\n }\n\n response.complete();\n\n })\n }\n\n //find the last log count\n Logger.find({\n \"logID\": LOG_ID\n }, function (err, lastCount) {\n startFrom = lastCount[0].Message; //0\n\n Booking.find({\n \"bookingStatus\": 0\n }, {\n \"limit\": updateLimit,\n \"skip\": startFrom\n }, function (err, bookings) {\n if (bookings && bookings.length > 0) {\n updateLimit = bookings.length;\n //modules.logger.info( bookings.length );\n bookings.forEach(function (booking) {\n getWeatherConditionForBooking(booking);\n })\n } else {\n modules.logger.info(\"no bookings found\");\n response.complete();\n }\n })\n });\n}\n\n\n" }, "ManuallyTriggerNotification" : { "code" : "function onRequest(request, response, modules) {\n var Push = modules.push,\n username = 'test@hellotractor.com',\n User = modules.collectionAccess.collection('user'),\n triggerData = {\n id: response.body._id,\n TractorDetail:\"\", \n type: \"action\", \n action: \"trigger\", \n kind: 12, \n trigger:907, \n entity: {\n \n } \n \n };\n \n var sendRefreshTrigger = function(user, data){\n return Push.send(user, JSON.stringify(data));\n }\n \n User.find({\"username\":username}, function(err, user){\n \n //push the trigger via notification \n \tif( sendRefreshTrigger( user, triggerData) )\n {\n \tmodules.logger.info(\"app refresh trigger sent to : \" + username );\n return response.complete();\n }\n \telse {\n modules.logger.info(\"push notification not sent to : \" + username );\n return response.complete();\n \t\t\t}\n });\n\n \n}" }, "DeleteBookingWeatherValue" : { "code" : "function onRequest(request, response, modules) {\nvar Booking = modules.collectionAccess.collection('ServiceBookings');\n \nvar updateQuery = { $set: { WeatherCondition: '' } };\n \n Booking.update({},updateQuery, {multi: true}, function(err, done){\n if(!err){\n modules.logger.info('updated all bookings Weather Condition to empty');\n response.complete();\n }\n else {\n modules.logger.info('failed updating all bookings Weather condition');\n modules.logger.error(err);\n response.complete();\n }\n } )\n}" }, "deleteUserPushToken" : { "code" : "function onRequest(request, response, modules) {\n\tvar updateValue = {\"pushTokens\": [] };\n modules.collectionAccess.collection('user').update({}, { $set:{_messaging:updateValue }}, {multi:true}, \t\t function(err, done){\n if(!err){\n modules.logger.info('updated all push tokens');\n response.complete();\n }\n else {\n modules.logger.info('there was an error');\n response.complete();\n }\n } )\n}" }, "UpdateLatestBookingsWeatherInformation" : { "code" : "\n//fetch new bookings that was posted 30 minutes ago\n//@update 01/11/2018 ( added checks to store service date weather info of 9am only and cater for fetching weather information of bookings whose service date are in future , greater than now )\nfunction onRequest(request, response, modules) {\n \tvar Booking = modules.collectionAccess.collection(\"ServiceBookings\"),\n \t\tAPPID = \"&APPID=36b45f00efffeeb4d17f8509fe86d167\",\n \t\tRequest = modules.request,\n \t\tnow = modules.moment(),\n newBookings,\n count = 0;\n\n //fetch weather information for bookings one week to the service date\n var canFetchBookingWeatherInfo = function (serviceDate) {\n var serviceDateTimestamp = modules.moment(serviceDate),\n oneWeekMinusServiceDate = modules.moment(serviceDateTimestamp).subtract(7, \"days\").format(\"YYYY-MM-DD\");\n \treturn ( now.format(\"YYYY-MM-DD\") >= oneWeekMinusServiceDate) && ( now.format(\"YYYY-MM-DD\") <= serviceDate );\n }\n\n //fetch the booking weather condition\n var getWeatherConditionForBooking = function (booking) {\n /** make a request to the open weather API **/\n var lat = booking.latitude,\n lng = booking.longitude,\n isSetLatLng = lat && lng ? true : false;\n\n var readyToFetchWeatherInfo = canFetchBookingWeatherInfo(booking.serviceDate);\n\n if (isSetLatLng && readyToFetchWeatherInfo) {\n \t\t\tvar weatherURL = \"https://api.openweathermap.org/data/2.5/forecast?units=metric&lat=\" + lat + \"&lon=\" + lng + APPID;\n requestOptions = {\n url: weatherURL,\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json'\n },\n json: true\n };\n Request.request(requestOptions, function (err, resp, body){\n modules.logger.info(JSON.stringify(body));\n if(body.cod == 200){\n //update the booking with weather information if the response is a good one\n \tupdateSingleBookingWeatherCondition(body,booking);\n }\n }); //request function ends \n }\n else { \n modules.logger.info(\"lat lng not set and not ready to fetch\");\n count++;\n if( count == newBookings.length) { response.complete() };\n\n }\n }\n\n var getUpdatedAtForBooking = function () {\n return now.format('YYYY-MM-DD HH:mm:ss');\n\n }\n\n var updateSingleBookingWeatherCondition = function (condition, booking) {\n \n var bookingServiceDate = booking.serviceDate;\n var BookingServiceDateWeatherInfo = getBookingServiceDateWeatherInfo(condition, bookingServiceDate);\n modules.logger.info(\" BookingServiceDateWeatherInfo is \" + BookingServiceDateWeatherInfo);\n \n\t\tif( BookingServiceDateWeatherInfo ){\n \n Booking.update({\n \"bookingID\": booking.bookingID\n }, {\n $set: {\n \"WeatherCondition\": BookingServiceDateWeatherInfo,\n \"updatedAt\": getUpdatedAtForBooking()\n }\n }, function (err, updatedBooking) {\n if (!err) {\n count++\n modules.logger.info(\"Updated the weather condition of booking with ID: \" + booking.bookingID);\n } else {\n modules.logger.info(\"not updating booking with ID: \" + booking.bookingID);\n count++\n }\n if( count == newBookings.length) { response.complete() };\n })\n \n }\n \n else {\n count++;\n if( count == newBookings.length) { response.complete() };\n\n }\n\t \n\n }\n \n //filter those records that were posted 30 minutes ago \n \n var getNewBookings = function(bookings){ \n return bookings.filter( function(booking){\n \n /* diff below is in milliseconds, divide by 1000 to get seconds\n Math.abs is used to the absolute difference so that new Date('2018-08-02 12:00') and new Date('2018-08-02 \t\t00:00') gives the same result \n */ \n var diff = Math.abs(new Date() - new Date(booking.updatedAt)); \n\tvar minutes = Math.floor((diff/1000)/60); //in seconds , divide by 60 to get the minutes \n\treturn true //minutes <= 30;\n \n });\n }\n \n\n Booking.find({\n \"bookingStatus\": 0,\n }, function (err, bookings) {\n if (bookings && bookings.length > 0) {\n newBookings = getNewBookings(bookings)\n if( newBookings.length > 0){\n newBookings.forEach(function (booking) {\n getWeatherConditionForBooking(booking)\n modules.logger.info('new booking count is ' +newBookings.length);\n });\n }\n \telse {\n modules.logger.info('no new bookings found');\n response.complete();\n }\n \n } else {\n modules.logger.info(\"no bookings found\");\n response.complete();\n }\n });\n\n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" }, "getTractorReports" : { "code" : "function onRequest(request, response, modules) {\n \n var TractorOwner = modules.collectionAccess.collection('TractorOwner'),\n TractorDetail = modules.collectionAccess.collection('TractorDetail'),\n Http = modules.request,\n count = 0;\n \n var getTractorIds = function(tractorDetails){\n return tractorDetails.map(function(tractorDetail){\n return tractorDetail.TractorID;\n })\n }\n \n var sendTractorReportsRequest = function(tractorIds, customerName,customerEmail, tractorOwners){\n var startDate = \"2017-08-01\";\n var endDate = \"2017-08-31\";\n var date_range = startDate+'|'+endDate;\n var tractorIDs = tractorIds.join(',');\n var request_url = \"https://cloud.hellotractor.com/report/log/csv?tractor_ids=\"+tractorIDs+\"&dates=\"+ date_range+\"&customer_name=\"+customerName+\"&customer_email=\"+customerEmail;\n\tmodules.logger.info( request_url );\n var requestOptions = {\n url:request_url,\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json'\n },\n json: true\n };\n \n Http.request(requestOptions, function(err, resp, body){\n if(!err){\n modules.logger.info(JSON.stringify(resp));\n count++\n }\n else {\n count++\n }\n if( count == tractorOwners.length ) { response.complete() } ;\n })\n }\n\n \n TractorOwner.find({\"username\": \"tohfan08@yahoo.com\"}, function(err, tractorOwners){\n tractorOwners.forEach( function(tractorOwner){\n var tractorOwnerName = tractorOwner.first_name,\n \t\ttractorOwnerEmail = tractorOwner.email; \n TractorDetail.find({\"_acl.creator\": tractorOwner._acl.creator}, function(err, tractorDetails){\n\t\t\t\t\tvar tractorIds = getTractorIds(tractorDetails);\n \t\n \t//send request only if the tractor owner has tractors \n \tif(tractorIds.length > 0){ \n modules.logger.info(\"The acl \" + tractorOwner._acl.creator + \" has \" + tractorIds ); \n \t\tsendTractorReportsRequest(tractorIds,tractorOwnerName,tractorOwnerEmail,tractorOwners );\n }\n else {\n count++;\n }\n \t\t\t\t\t\t\n }) \n }) \n })\n \n}" }, "_CreatorUpdater" : { "code" : "function onRequest(request, response, modules) {\n\tvar TractorDetail = modules.collectionAccess.collection('TractorDetail');\n TractorDetail.find({\"_acl.gr\": {$exists:true}, \"_acl.gw\": {$exists:true}},function(err, tractorDetails){\n if(!err){\n var count =0;\n \n \ttractorDetails.forEach( function(tractorDetail){\n \n var creator = {\"creator\": tractorDetail._acl.creator };\n \n \t\t\tTractorDetail.update({_id: tractorDetail._id}, {$set:{_acl: creator}},\n function(err, done){\n count++\n if( tractorDetails.length == count){\n modules.logger.info('all updated');\n response.complete();\n }\n })\n }) \n }\n else {\n modules.logger.error( \"There was an error\" );\n response.complete();\n }\n })\n}" }, "TractorsNearby" : { "code" : "/**\n * Used to retrieve the nearest tractors within a close proximity to the location passed\n * Requires - lat, long, and maxDistance parameters passed in the body of the request\n * Last updated: 4th June 2020, 9th June 2020\n * @param request \n * @param response \n * @param modules \n */\n\nfunction onRequest(request, response, modules) {\n var currLat = request.body.lat,\n currLong = request.body.long,\n maxDistance = request.body.maxDistance, //kilometers\n apiKey = \"AIzaSyCOpj5ds5nIRt7RxyogDNfybL67Z4d9xfk\", //Google API Key for displaying routes from farm location to tractor\n threshold = 10,\n logger = modules.logger;\n \n var tractorDetailCol = modules.collectionAccess.collection(\"TractorDetail\");\n var tractorOperatorCol = modules.collectionAccess.collection(\"TractorOperator\");\n var appUserCol = modules.collectionAccess.collection(\"user\");\n var pricePerHectareCol = modules.collectionAccess.collection(\"PricePerHectare\");\n \n var R = 6371 * Math.pow(10, 3); //earth radius in meters\n var PI = Math.PI;\n var radius = maxDistance * Math.pow(10, 3) //In meters\n \n var minLat = currLat - radius / R * 180 / PI;\n var maxLat = currLat + radius / R * 180 / PI;\n var minLong = currLong - (radius / R * 180 / PI) / Math.cos(currLat * PI / 180);\n var maxLong = currLong + (radius / R * 180 / PI) / Math.cos(currLat * PI / 180);\n \n var tractorQuery = {\n $and: [\n { \"PositionLatitude\": { $gte: minLat } },\n { \"PositionLatitude\": { $lte: maxLat } },\n { \"PositionLongitude\": { $gte: minLong } },\n { \"PositionLongitude\": { $lte: maxLong } },\n { \"BookingRequests\": true}\n ]\n };\n \n /**\n * Retrives tractors from tractor detail collection that satisfy tractor query criteri\n * @param tractorQuery An object of the query criteria\n */\n var fetchTractors = function(){\n tractorDetailCol.find(tractorQuery, function (tractorsErr, tractorList) {\n if (tractorsErr || !tractorList) {\n logger.info(\"Query failed: \" + tractorsErr);\n response.error(\"Unable to find nearby tractors\");\n } else {\n logger.info(\"Building nearby tractor list, bounding square tractors: \"+tractorList.length);\n buildNearbyTractors(tractorList);\n }\n });\n }\n \n /**\n * Creates an array of creator id and operator id and filters the tractor list to extract those within the radius\n * @param tractorList The list of tractors that satisfy the rectangular bounding box queried\n */\n var buildNearbyTractors = function(tractorList){\n var creatorIdArr = [];\n var operatorIdArr = [];\n var tractorsWithinCircle = [];\n var countTractors = 0;\n var unit = \"K\"; //Killometers\n \n var totalTractorCount = tractorList.length;\n for (var i = 0; i < totalTractorCount; i++){\n var tractor = tractorList[i];\n var lat = tractor.PositionLatitude;\n var long = tractor.PositionLongitude;\n var distanceFromPosition = distance(\n currLat,\n currLong,\n lat,\n long,\n unit\n );\n \n if (distanceFromPosition <= maxDistance) {\n tractorsWithinCircle.push(tractor);\n creatorIdArr.push(tractor._acl.creator);\n if (tractor.OperatorID) {\n operatorIdArr.push(tractor.OperatorID);\n }\n countTractors++;\n }\n \n if (countTractors > threshold){\n break;\n }\n }\n \n logger.info(\"Number of tractors within bounding circle: \" + tractorsWithinCircle.length);\n \n //Find tractor owners to retrieve org id of the creator\n fetchTractorOwnerUsers(creatorIdArr, operatorIdArr, tractorsWithinCircle);\n }\n \n \n var fetchTractorOwnerUsers = function(creatorIdArr, operatorIdArr, tractorsWithinCircle){\n appUserCol.find({\"_acl.creator\": {$in: creatorIdArr}}, function(usersErr, userList){\n var userIdToUserMap = buildUserIdToUserMap(userList? userList: []);\n //find operators to retrieve operator information of tractors assigned\n fetchOperators(creatorIdArr, operatorIdArr, userIdToUserMap, tractorsWithinCircle);\n });\n }\n \n var buildUserIdToUserMap = function(userList){\n var userIdToUserMap = userList.reduce(function(acc, user, index){\n acc[user._acl.creator] = user;\n return acc;\n }, {});\n \n return userIdToUserMap;\n }\n \n var buildOperatorIdOperatorMap = function(operators){\n var operatorIdOperatorMap = operators.reduce(function(acc, operator, index){\n acc[operator.OperatorID] = operator;\n return acc;\n }, {});\n \n return operatorIdOperatorMap;\n }\n \n var fetchOperators = function (creatorIdArr, operatorIdArr, userIdToUserMap, tractorsWithinCircle){\n tractorOperatorCol.find({\"OperatorID\": {$in: operatorIdArr}}, function(operatorsErr, operatorList){\n var operatorIdOperatorMap = buildOperatorIdOperatorMap(operatorList);\n fetchPricePerHectare(creatorIdArr, userIdToUserMap, tractorsWithinCircle, operatorIdOperatorMap);\n });\n }\n\n var buildResponse = function(userIdToUserMap, tractorsWithinCircle, operatorIdOperatorMap, creatorIdAttachmentCodeToPricePerHectareMap){\n var tractorListToReturn = [];\n tractorsWithinCircle.forEach(function(tractor){\n var tractorOwner = userIdToUserMap[tractor._acl.creator];\n var operator = operatorIdOperatorMap[tractor.OperatorID];\n\n var attachmentsPricePerHectareMap = creatorIdAttachmentCodeToPricePerHectareMap[tractor._acl.creator];\n var tractorAttachmentPrices = {};\n\n if (attachmentsPricePerHectareMap){\n var tractorAttachmentCodes = tractor.Characteristic.split(\",\");\n tractorAttachmentCodes.forEach(function(attachmentCode){\n var pricePerHectare = attachmentsPricePerHectareMap[attachmentCode];\n if (pricePerHectare){\n tractorAttachmentPrices[pricePerHectare.serviceType] = pricePerHectare;\n }\n });\n }\n\n if (tractorOwner && operator){\n var lat = tractor.PositionLatitude;\n var lng = tractor.PositionLongitude;\n var orgID = tractorOwner.orgIDs;\n var tractorResponse = constructResponse(lat, lng, tractor, operator, apiKey, orgID, tractorAttachmentPrices);\n tractorListToReturn.push(tractorResponse);\n }\n });\n\n finish(tractorListToReturn); \n }\n\n var fetchPricePerHectare = function(creatorIdArr, userIdToUserMap, tractorsWithinCircle, operatorIdOperatorMap){\n pricePerHectareCol.find({\"_acl.creator\": {$in: creatorIdArr}}, function(pricerPerHectareErr, pricePerHectareList){\n var creatorIdAttachmentCodeToPricePerHectareMap = {};\n if (pricePerHectareList && pricePerHectareList.length > 0)\n creatorIdAttachmentCodeToPricePerHectareMap = buildCreatorIdAttachmentCodeToPricePerHectareMap(pricePerHectareList);\n buildResponse(userIdToUserMap, tractorsWithinCircle, operatorIdOperatorMap, creatorIdAttachmentCodeToPricePerHectareMap);\n });\n }\n\n /**\n * {\"ajhdiksdhna1112\": {\"100\": {\"PricePerHectare\": 12500}, \"101\": {\"PricePerHecatre\": 25000}}, \n * \"bheu1313132\": {\"100\": {\"PricePerHectare\": 15500}, \"101\": {\"PricePerHecatre\": 25000}}}\n * @param pricePerHectareList\n */\n\n var buildCreatorIdAttachmentCodeToPricePerHectareMap = function(pricePerHectareList){\n var attachmentCodeToPricePerHectareMap = pricePerHectareList.reduce(function(acc, pricePerHectare, index){\n if (!acc[pricePerHectare._acl.creator]) acc[pricePerHectare._acl.creator] = {};\n acc[pricePerHectare._acl.creator][pricePerHectare.serviceType] = pricePerHectare;\n return acc;\n }, {});\n \n return attachmentCodeToPricePerHectareMap;\n }\n \n var finish = function(tractorListToReturn){\n modules.logger.info(\"Number of tractors nearby: \" + tractorListToReturn.length);\n modules.logger.info(\"Response: \" + JSON.stringify(tractorListToReturn));\n response.body = tractorListToReturn;\n response.complete();\n }\n \n //Entry point, fetch tractors that satisfy query criteria\n fetchTractors(tractorQuery); \n }\n \n function distance(lat1, lon1, lat2, lon2, unit) {\n var radlat1 = (Math.PI * lat1) / 180;\n var radlat2 = (Math.PI * lat2) / 180;\n var theta = lon1 - lon2;\n var radtheta = (Math.PI * theta) / 180;\n var dist =\n Math.sin(radlat1) * Math.sin(radlat2) +\n Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);\n if (dist > 1) {\n dist = 1;\n }\n dist = Math.acos(dist);\n dist = (dist * 180) / Math.PI;\n dist = dist * 60 * 1.1515;\n if (unit == \"K\") {\n dist = dist * 1.609344;\n }\n if (unit == \"N\") {\n dist = dist * 0.8684;\n }\n return dist;\n }\n \n function constructResponse(lat, lng, doc, operatorAssigned, apiKey, orgID, tractorAttachmentPrices) {\n var strippedDoc = {\n _id: doc._id,\n _kmd: doc._kmd,\n _acl: doc._acl,\n PositionLatitude: lat,\n PositionLongitude: lng,\n EngineHours: doc.EngineHours,\n Characteristic: doc.Characteristic,\n TractorName: doc.TractorName,\n ImplementsAttached: doc.ImplementsAttached,\n license_plate_number: doc.license_plate_number,\n Country: doc.Country,\n Town: doc.Town,\n Street: doc.Street,\n TractorID: doc.TractorID,\n Heading: doc.Heading,\n TractorModelID: doc.TractorModelID,\n OperatorID: doc.OperatorID,\n ImplementAttached: doc.ImplementAttached,\n TractorOperator: operatorAssigned,\n OrgID: orgID,\n AttachmentPricePerHectare: tractorAttachmentPrices,\n APIKey: apiKey\n };\n \n return strippedDoc;\n }" }, "BookingsNearbySometimeAgo" : { "code" : "function onRequest(request, response, modules) {\n var currLat = request.body.lat, \n currLong = request.body.long, \n count = 0, \n count2 = 0, \n maxDistance = request.body.maxDistance, //kilometers\n filteredBookings = [], \n startDate = request.body.startDate, \n endDate = request.body.endDate; \n \n var query = {serviceDate: { $gte: startDate, $lte: endDate }};\n \n var serviceBookings = modules.collectionAccess.collection('ServiceBookings');\n serviceBookings.find(query, function (err, docs) {\n if (err) {\n logger.error('Query failed: '+ err);\n response.error(\"Unable to find nearby bookings\");\n } else {\n if (docs.length > 0){\n docs.forEach(function(doc){\n var lat = doc.latitude;\n var long = doc.longitude;\n var unit = \"K\"; //Killometers\n \n if (lat && long){\n \n var distanceFromPosition = distance(currLat, currLong, lat, long, unit);\n if (distanceFromPosition <= maxDistance){\n count++;\n var strippedDoc = {\n latitude:doc.latitude,\n longitude:doc.longitude,\n serviceDate:doc.serviceDate,\n hectaresServiced:doc.hectaresServiced,\n distanceToDestination:doc.distanceToDestination,\n serviceType:doc.serviceType\n };\n filteredBookings.push(strippedDoc);\n }\n }\n \n count2++;\n if (count2 == docs.length){\n modules.logger.info(\"Number of bookings nearby: \"+count);\n modules.logger.info(\"Total Number of Bookings: \"+count2); \t\t\t\t\t\t\n modules.logger.info(\"Later: \"+modules.moment.utc());\n\t\t\t\t\t\tresponse.body = filteredBookings;\n response.complete();\n }\n\n });\n } else {\n response.complete();\n }\n }\n\t});\n}\n\nfunction distance (lat1, lon1, lat2, lon2, unit) {\n\tvar radlat1 = Math.PI * lat1/180;\n\tvar radlat2 = Math.PI * lat2/180;\n\tvar theta = lon1-lon2;\n\tvar radtheta = Math.PI * theta/180;\n\tvar dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);\n\tif (dist > 1) {\n\t\tdist = 1;\n\t}\n\tdist = Math.acos(dist);\n\tdist = dist * 180/Math.PI;\n\tdist = dist * 60 * 1.1515;\n\tif (unit==\"K\") {\n dist = dist * 1.609344\n }\n\tif (unit==\"N\") { \n dist = dist * 0.8684 \n }\n\treturn dist;\n} " }, "UpdateAerisTractorEngineHours" : { "code" : "//Runs every three minutes to retrieve the total engine hours\n//for all aeris tractors on cloud.hellotractor.com\n//Created by Abdulmajid on 22/08/2018\n\nfunction onRequest(request, response, modules) {\n var tractorDetailCollection = modules.collectionAccess.collection(\"TractorDetail\");\n var log = modules.logger;\n var loggerCollection= modules.collectionAccess.collection(\"Logger\");\n var LOG_ID = 109;\n var count = 0;\n var size = 0;\n var startTime = modules.moment().valueOf();\n var todaysDate = modules.moment.utc().format('YYYY-MM-DD');\n var timeout = 19990; //milliseoncs\n// var query = {TractorID: {$gte:500000}, LastActiveTime: {$gte:todaysDate}};\n var query = {TractorID: {$gte:500000}}; \n \n loggerCollection.find({logID:LOG_ID}, {}, function(err1, logs){ \n tractorDetailCollection.find(query, {}, function(err, docs){\n if (err){\n response.complete();\n } else if (docs.length > 0){\n var startFrom = 0;\n if (logs[0].Message < docs.length){\n startFrom = logs[0].Message;\n }\n\n size = docs.length;\n count = startFrom;\n log.info(\"Size: \"+size+\", Start From: \"+startFrom);\n\n //Iterate through all tractors to request weather data via geonames api\n for (var i = startFrom; i < docs.length; i++){\n var tractorDetail = docs[i];\n\n if (tractorDetail.TractorID){\n // modules.logger.info(JSON.stringify(booking));\n makeRequest(tractorDetail);\n\n } else {\n count++;\n shouldCompleteRequest(); \n } //End if booking is not 0\n\n } //end for loop\n \t\t} else {\n response.complete();\n }\n });\n });\n \n var makeRequest = function (tractorDetail){\n \tmodules.request.request(getRequestOptions(tractorDetail), function(err2, resp, body) {\n if(err2) {\n count++;\n\t\t\t\t\t\tshouldCompleteRequest();\n } else {\n if(!body) {\n modules.logger.info(\"There was no data in body for booking: \"+ url);\n count++;\n\t\t\t\t\t\t\tshouldCompleteRequest(); \n } else {\n updateTractorDetailCollection(tractorDetail, body);\n }\n }\n }); //end request \n} \n \nvar updateTractorDetailCollection = function (tractorDetail, body){\n var engineHoursDistanceCoveredArr = computeEngineHours(body);\n tractorDetailCollection.update({_id:tractorDetail._id}, \n {$set: {\n \"EngineHours\":engineHoursDistanceCoveredArr[0],\n \"TotalDistanceCovered\":engineHoursDistanceCoveredArr[1] \n }}, \n {upsert: false, _id:1}, \n function(tractorErr, tractorDetailDoc){\n \t\t\tcount++;\n shouldCompleteRequest();\n }); //End update tractor detail with active time today \n// modules.logger.info(\"Count: \"+count);\n } //end updateTractorDetailCollection function \n\n\n var shouldCompleteRequest = function(){\n var duration = modules.moment().valueOf() - startTime;\n if (count >= size || duration >= timeout){\n log.info(\"Total: \"+count);\n\n //Update logger and finish task\n loggerCollection.update({logID:LOG_ID}, {$set: {Message:count}}, {upsert: false}, function(logErr, logDoc){\n response.complete(); \n }); //End update logger collection with last count \n }//end if \n }\n} //end onRequest function\n\n\nfunction computeEngineHours(body){\n var engineHoursDistanceCoveredArr = []; \n try {\n if (body){\n var totalEngineHours = 0;\n var totalDistanceCovered = 0;\n for (var i = 0; i < body.length; i++){\n totalEngineHours += Number(body[i].total_active_time) + Number(body[i].total_inactive_time);\n totalDistanceCovered += Number(body[i].total_distance);\n }\n engineHoursDistanceCoveredArr.push(Math.round(totalEngineHours/3600));\nengineHoursDistanceCoveredArr.push(Math.round(totalDistanceCovered)); \n return engineHoursDistanceCoveredArr;\n }\n } catch(err){\n } \n \n return engineHoursDistanceCoveredArr;\n}\n\nfunction getRequestOptions(tractorDetail){\n\tvar url = \"https://cloud.hellotractor.com/api/v1/tractors/daily/activities/summary?tractor_id=\"+tractorDetail.TractorID;\n var requestOptions = {url:url, method: 'GET', \n\t\t\t\theaders: {\n \t'Content-Type': 'application/json',\n \t'Accept': 'application/json'\n \t},\n json: true\n }; \n return requestOptions;\n}" }, "Update2TrackTractorEngineHours" : { "code" : "//Runs every three minutes to compute the total engine hours\n//and total distance covered (killometers) for all 2track tractors on //cloud.hellotractor.com\n\n\nfunction onRequest(request, response, modules) {\n var tractorDetailCollection = modules.collectionAccess.collection(\"TractorDetail\");\n var dailyTractorActivityCollection = modules.collectionAccess.collection(\"DailyTractorActivity\");\n var log = modules.logger;\n var loggerCollection= modules.collectionAccess.collection(\"Logger\");\n var LOG_ID = 110;\n var count = 0;\n var size = 0;\n var startTime = modules.moment().valueOf();\n var todaysDate = modules.moment.utc().format('YYYY-MM-DD');\n var timeout = 19990; //milliseoncs\n// var query = {TractorID: {$gte:500000}, LastActiveTime: {$gte:todaysDate}};\n var query = {TractorID: {$lt:500000}}; \n \n loggerCollection.find({logID:LOG_ID}, {}, function(err1, logs){ \n tractorDetailCollection.find(query, {}, function(err, docs){\n if (err){\n response.complete();\n } else if (docs.length > 0){\n var startFrom = 0;\n if (logs[0].Message < docs.length){\n startFrom = logs[0].Message;\n }\n\n size = docs.length;\n count = startFrom;\n log.info(\"Size: \"+size+\", Start From: \"+startFrom);\n\n //Iterate through all tractors to request weather data via geonames api\n for (var i = startFrom; i < docs.length; i++){\n var tractorDetail = docs[i];\n\n if (tractorDetail.TractorID){\n // modules.logger.info(JSON.stringify(booking));\n makeRequest(tractorDetail);\n\n } else {\n count++;\n shouldCompleteRequest(); \n } //End if booking is not 0\n\n } //end for loop\n \t\t} else {\n response.complete();\n }\n });\n });\n \n var makeRequest = function (tractorDetail){\n var query = {TractorID:tractorDetail.TractorID};\n \n dailyTractorActivityCollection.find(query, function(err, docs){\n// modules.logger.info(\"After fetching daily tractor activities.\"); \n if (err){\n count++;\n\t\t\t\t\t\tshouldCompleteRequest();\n } else {\n updateTractorDetailCollection(tractorDetail, docs);\n }\n }); \n} \n \nvar updateTractorDetailCollection = function (tractorDetail, body){\n var engineHoursDistanceCoveredArr = computeEngineHours(body);\n tractorDetailCollection.update({_id:tractorDetail._id}, \n {$set: {\n \"EngineHours\":engineHoursDistanceCoveredArr[0],\n \"TotalDistanceCovered\":engineHoursDistanceCoveredArr[1] \n }}, \n {upsert: false, _id:1}, \n function(tractorErr, tractorDetailDoc){\n \t\t\tcount++;\n shouldCompleteRequest();\n }); //End update tractor detail with active time today \n// modules.logger.info(\"Count: \"+count);\n } //end updateTractorDetailCollection function \n\n\n var shouldCompleteRequest = function(){\n var duration = modules.moment().valueOf() - startTime;\n if (count >= size || duration >= timeout){\n log.info(\"Total: \"+count);\n\n //Update logger and finish task\n loggerCollection.update({logID:LOG_ID}, {$set: {Message:count}}, {upsert: false}, function(logErr, logDoc){\n response.complete(); \n }); //End update logger collection with last count \n }//end if \n }\n} //end onRequest function\n\n\nfunction computeEngineHours(body){\n var engineHoursDistanceCoveredArr = []; \n try {\n if (body){\n var totalEngineHours = 0;\n var totalDistanceCovered = 0;\n for (var i = 0; i < body.length; i++){\n totalEngineHours += Number(body[i].TotalTimeActive);\n totalDistanceCovered += Number(body[i].DistanceTravelled);\n }\n engineHoursDistanceCoveredArr.push(Math.round(totalEngineHours/3600));\nengineHoursDistanceCoveredArr.push(Math.round(totalDistanceCovered/1000)); \n return engineHoursDistanceCoveredArr;\n }\n } catch(err){\n } \n \n return engineHoursDistanceCoveredArr;\n}" }, "FetchBookingAgentsBetweenDateRange" : { "code" : " function onRequest(request, response, modules) {\n var BookingAgent = modules.collectionAccess.collection('BookingAgents');\n \n //fecth from july to august\n var from = \"2018-08-30\";\n var to= \"2018-09-06\";\n var agentsArr = [];\n BookingAgent.find(/*{\"createdAt\":{$gte:from, $lte:to}}*/{}, {\"name\":\"1\", \"phone\":\"1\", \"address\":\"1\"}, function(err, agents){\n var count = 0;\n \tif(!err){\n\t\t\t\tagents.forEach(function(agent){\n agentsArr.push({FullName:agent.name, PhoneNumber: agent.phone, AgentAddress: agent.address ? agent.address: \"\", registrationDate: agent.createdAt ? agent.createdAt.split(\" \")[0] : \"\"});\n \n count++;\n \n if( count == agents.length ){\n modules.logger.info(JSON.stringify(agentsArr));\n response.complete();\n }\n }) \n }\n else {\n modules.logger.info(\"There was an error \" + err); \n response.complete();\n }\n }); \n}\n\n" }, "removeDuplicateBookingAgents" : { "code" : "function onRequest(request, response, modules) {\n \n var BookingAgents = modules.collectionAccess.collection('ServiceBookings');\n BookingAgents.find({}, function(err, bookingAgents){\n \tvar bookingAgentsHash = {};\n \tvar count = 0;\n \tbookingAgents.forEach( function(bookingAgent){\n \n\t\t\tif( ! bookingAgentsHash[bookingAgent.bookingAgentID] ){\n bookingAgentsHash[bookingAgent.bookingAgentID] = [];\n }\n \n bookingAgentsHash[bookingAgent.bookingAgentID].push( bookingAgent );\n count++;\n \n if( count === bookingAgents.length){\n \n for( bookingAgentID in bookingAgentsHash ){\n \n var agentsDuplicateCount = bookingAgentsHash[bookingAgentID].length;\n var bookingAgentID = bookingAgentsHash[bookingAgentID][0].bookingAgentID;\n var singleAgentRecord = bookingAgentsHash[bookingAgentID][0];\n if( agentsDuplicateCount > 1 ){\n \t\t\t\t\tBookingAgents.remove({bookingAgentID: bookingAgentID }, function(err){});\n BookingAgents.save(singleAgentRecord, function(err, saved){}); \n } \n }\n \n modules.logger.info(\"The data are here! \" + JSON.stringify(bookingAgentsHash));\n \tresponse.complete();\n }\n \t\n \t})\n \n })\n}" }, "deleteBookingAgents" : { "code" : "function onRequest(request, response, modules) {\n \n var Booking = modules.collectionAccess.collection('TractorDetail');\n \n// var BookingAgents = modules.collectionAccess.collection('BookingAgents');\n \n// BookingAgents.remove({}, {multi:true}, function(err, done){\n// if( ! err ){\n// modules.logger.info('all deleted');\n// response.complete();\n\n// }\n// else {\n// modules.logger.info(\" there was an error \" + err);\n// response.complete();\n\n// }\n// })\n \n Booking.remove({}, function(err, bookings){\n// modules.logger.info(\"The bookings with orgID of 305 is \" + bookings.length );\n response.complete();\n })\n \n \n}" }, "updateBookingsOrgID" : { "code" : "function onRequest(request, response, modules) {\nvar now = modules.moment.utc();\nvar today = now.format(\"YYYY-MM-DD HH:MM:SS\");\nvar Booking = modules.collectionAccess.collection('ServiceBookings');\nvar dateRangeQuery = {\"_kmd.ect\": { $lte: \"2018-06-30\"} , orgID:\"305\"}; \n \n Booking.update(dateRangeQuery, {$set: { orgID: \"110\", updatedAt:now }}, {\"multi\":true},function(err){\n if(!err){\n modules.logger.info(\"all updated\");\n response.complete();\n }\n });\n}" }, "_generateBookingAgentsBookingsReport" : { "code" : "function onRequest(request, response, modules) {\n\n var Booking = modules.collectionAccess.collection(\"ServiceBookings\");\n var BookingAgent = modules.collectionAccess.collection(\"BookingAgents\");\n\tvar bookingsHash = {};\n var bookingAgentsHash = {};\n var bookingAgentsArr = [];\n \n //Find all bookings and form hash of bookingAgentId to bookings array \n Booking.find({},{name:1, bookingAgentID:1, phone:1}, function(err,_bookings){\n _bookings.forEach(function(_booking){\n bookingsHash[_booking.bookingAgentID] = bookingsHash[_booking.bookingAgentID] || [];\n bookingsHash[_booking.bookingAgentID].push(_booking);\n })\n //Find all booking agents and form a hash of the bookingAgentID to the agent details\n BookingAgent.find({}, function(err, _bookingAgents){\n\n _bookingAgents.forEach( function(_bookingAgent){\n if( bookingsHash[_bookingAgent.bookingAgentID] !== undefined){\n \n bookingAgentsArr.push( {fullName:_bookingAgent.name , Phone:_bookingAgent.phone, totalBookings:bookingsHash[_bookingAgent.bookingAgentID].length })\n \n }\n })\n\n modules.logger.info(\"The agent bookings are \" + JSON.stringify( bookingAgentsArr ));\n response.complete();\n\n})\n \n })\n \n}" }, "getBookingAgentFarmersDetails" : { "code" : "function onRequest(request, response, modules) {\n\nvar Booking = modules.collectionAccess.collection('ServiceBookings');\n \nvar bookingAgentID = \"1521828670\";\nvar boookingAgentBookings = [];\n \n Booking.find({bookingAgentID:bookingAgentID }, function(err, _agentBookings ){\n \n _agentBookings.forEach( function(_booking){\n boookingAgentBookings.push( {\n farmerName: _booking.farmerName,\n farmerPhone: _booking.farmerPhone\n });\n })\n \n modules.logger.info(\"The agent bookings are \" + JSON.stringify(boookingAgentBookings));\n response.complete(200);\n \n })\n\n}" }, "_duplicateCreatorRemover" : { "code" : "function onRequest(request, response, modules) {\n \n var BookingAgent = modules.collectionAccess.collection('BookingAgents')\n \n BookingAgent.find({}, function(err, _agents){\n var count = 0;\n _agents.map(function(_agent){\n var dupCreator = _agent._acl.creator.creator;\n modules.logger.info( \"the dup creator is \" + dupCreator );\n \n if(dupCreator === undefined ){\n\t\t\t\t\tcount++;\n }\n else{\n \tvar newCreatorFormat = {\"creator\":dupCreator};\n BookingAgent.update({_id: _agent._id}, {$set:{_acl:newCreatorFormat}}, function(err){\n count++;\n })\n }\n \n if( count === _agents.length){\n modules.logger.info(\"all updated\");\n response.complete();\n }\n \n })\n })\n \n \n}" }, "exportUsersEmail" : { "code" : "/** find users whose email address is not empty and export all the email addresses **/\n\nfunction onRequest(request, response, modules) {\n var userEmailsArray = [];\n var User = modules.collectionAccess.collection('user');\n \tvar count = 0;\n \tUser.find({}, function(err,_users){\n modules.logger.info(JSON.stringify(_users));\n var usersCount = _users.length;\n _users.map( function(_user){\n if(_user.email === undefined || _user.email ===\"\" ){\n count++;\n }\n else{\n userEmailsArray.push({email: _user.email})\n count++; \n }\n\n if( count === usersCount ) {\n modules.logger.info(JSON.stringify(userEmailsArray));\n response.complete();\n \t}\n\n })\n \n })\n \n}" }, "PushEmail" : { "code" : "function onRequest(request, response, modules) {\n var message = request.body.message,\n subject = request.body.subject,\n from = request.body.from,\n to = request.body.to,\n cc = \"apps2@hellotractor.com\",\n bcc = \"abdulmajid@hellotractor.com\",\n replyTo = \"Hello Tractor Support <support@hellotractor.com>\",\n emailType = request.body.emailType,\n userType = request.body.userType;\n \n var email = modules.email;\n email.send(from, //from\n to, //to\n subject, //subject\n message, //text_body \n replyTo, //reply_to\n null, //html_body\n cc, //cc\n bcc, //bcc\n function(err, result) {\n \n var mail = {\n \"_acl\": modules.kinvey.entity()._acl,\n \"_kmd\": modules.kinvey.entity()._kmd,\n \"from\": from,\n \"message\": message,\n \"to\": to,\n \"cc\": cc,\n \"bcc\": bcc,\n \"emailType\": emailType,\n \"userType\": userType,\n \"reply_to\": replyTo\n };\n \n modules.collectionAccess.collection(\"Emails\").save(mail, function(err2) {\n response.body = mail;\n return response.complete();\n });\n });\n}" }, "SendMaintenanceAlert" : { "code" : "function onRequest(request, response, modules) {\n var Maintenance = modules.collectionAccess.collection('MaintenanceRepo')\n var Push = modules.push;\n var Notification = modules.collectionAccess.collection(\"Notification\");\n var User = modules.collectionAccess.collection(\"user\");\n var TractorDetail = modules.collectionAccess.collection(\"TractorDetail\");\n var AlltractorDetails;\n\n try {\n TractorDetail.find({ maintenanceNotification: true }, function(\n err,\n tractorDetails\n ) {\n if (err) {\n modules.logger.info(\"There was an error \" + err);\n response.complete();\n } else {\n //populate the AllEngineHoursTractorArr array\n getTractorDetailByEngineHours(tractorDetails);\n\n var workCount = 0;\n\n modules.logger.info(\n \"all the tractor details are \" +\n JSON.stringify(AllEngineHoursTractorArr)\n );\n\n AllEngineHoursTractorArr.forEach(function(tractorsByEngineHourArr) {\n //filter the tractor details to make sure tractorModellD is greater than zero\n var ValidTractorDetails = getValidTractorDetails(\n tractorsByEngineHourArr\n );\n\n var tractorsModelHash = {};\n\n ValidTractorDetails.forEach(function(tractorDetail) {\n // Form a hashMap format of the tractorModellD to the tractorDetail\n tractorsModelHash[tractorDetail.TractorModelID] = tractorDetail;\n });\n\n var checksHash = {};\n // Find all maintenance and transform it to a hash of tractorModelId To the array of checks\n Maintenance.find({}, function(err, checks) {\n var allTractorOwners = getTractorsCreator(tractorDetails);\n\n // Find all the user by the creators array : allTractorOwner\n User.find({ \"_acl.creator\": { $in: allTractorOwners } }, function(\n err,\n tractorOwners\n ) {\n if (err) {\n modules.logger.info(\"There was an error \" + err);\n response.complete();\n } else {\n var tractorOwnerHash = {};\n\n // Convert the tractorOwners array to hashMap format of creator : tractorOwner\n tractorOwners.map(function(tractorOwner) {\n tractorOwnerHash[tractorOwner._acl.creator] = tractorOwner;\n });\n\n // Loop over the tractor details to send notificat ion for each tractor maintenance\n tractorsByEngineHourArr.forEach(function(tractorDetail) {\n var tractorOwner =\n tractorOwnerHash[tractorDetail._acl.creator];\n var tractorEngineHours = tractorDetail.EngineHours;\n var tractorModellD = tractorDetail.TractorModelID;\n\n modules.logger.info(\"engine hours \" + tractorEngineHours);\n\n //Filter the maintenance to get the ones that match the tractor detail engine hour and model Id\n var _tractorChecks = checks.filter(function(check) {\n return (\n check.tractorModelId === tractorModellD &&\n check.engineHours === tractorEngineHours\n );\n });\n\n // Send notification alert only if there is a tractor owner and maintenance alert for the tractot\n if (tractorOwner !== undefined && _tractorChecks.length > 0) {\n var formattedMaintenanceChecks = getFormatedChecksMessage(\n _tractorChecks\n );\n\n var notificationMessage =\n \"Hi \" +\n tractorOwner.first_name +\n \",\" +\n formattedMaintenanceChecks +\n \" recommended for the tractor: \" +\n tractorDetail.TractorName;\n\n var tractorID = tractorDetail.TractorID;\n\n //Set the push notification message\n var maintenanceAlertMessage = JSON.stringify({\n message: notificationMessage,\n type: \"action\",\n action: \"maintenance\",\n data: _tractorChecks,\n tractorID: tractorID,\n id: tractorDetail._id,\n tractorModelID: tractorDetail.TractorModelID,\n engineHours: tractorDetail.EngineHours,\n _acl: tractorOwner._acl,\n _kmd: response._kmd\n });\n\n // Check if the notification has not been sent\n var notification_action =\n \"maintenance_alert_for_\" + tractorDetail.EngineHours;\n modules.logger.info(\n \"notification_action is \" + notification_action\n );\n\n Notification.find(\n {\n tractorId: tractorDetail.TractorID,\n action: notification_action\n },\n function(err, alerts) {\n modules.logger.info(\n \"alerts length is \" + alerts.length\n );\n\n //Send alerts only if it has not been sent before.\n if (alerts.length == 0) {\n if (\n Push.send(tractorOwner, maintenanceAlertMessage)\n ) {\n modules.logger.info(\n \"mainatenance checks alert sent to \" +\n tractorOwner.username\n );\n\n //Set the notification details\n var notification = {\n message: notificationMessage,\n type: \"action\",\n read: false,\n tractorId: tractorID,\n userId: tractorDetail._id,\n action: notification_action\n };\n\n //Save the notification to the collection\n Notification.save(notification, function(\n err,\n saved\n ) {\n if (!err) {\n modules.logger.info(\n \"notification saved \" + JSON.stringify(saved)\n );\n workCount++;\n if (\n workCount === AllEngineHoursTractorArr.length\n ) {\n response.complete();\n }\n } else {\n modules.logger.info(\"There was an error\");\n }\n });\n }\n } else {\n workCount++;\n if (workCount === AllEngineHoursTractorArr.length) {\n response.complete();\n }\n }\n }\n );\n }\n });\n }\n });\n });\n });\n }\n });\n } catch (err) {\n modules.logger.info(\"There was an error \" + err);\n response.complete(err);\n }\n}\n" }, "fetch_tractors_activities" : { "code" : "/**\n* This endpoint returns daily tractor activities for tractor ids in the posted request \n*\n*/\n\nfunction onRequest(request, response, modules) {\n\tvar startTime = new Date();\n var count=0;\n modules.logger.info(request);\n modules.logger.info(request.body);\n \n// return response.error(JSON.stringify(request.body));\n \n var requestBody = request.body.tractor_ids.split(','),\n \t\tfrom_date = request.body.from_date,\n to_date = request.body.to_date,\n operator_ids = [],\n \t\tdate_filter_obj = {},\n DailyTractorActivity = modules.collectionAccess.collection('DailyTractorActivity'),\n TractorDetail = modules.collectionAccess.collection('TractorDetail'),\n TractorOperator = modules.collectionAccess.collection('TractorOperator'),\n tractor_activities,\n tractor_operators,\n tractor_details;\n \n\t//convert each needle in the tractorIds haystack to typeof Number to pass the schema type of TractorID. \n for(var i=0; i< requestBody.length; i++){\n requestBody[i] = Number( requestBody[i]);\n }\n \n \n date_filter_obj = from_date && to_date ? { $gte:from_date , $lte:to_date } :date_filter_obj = from_date;\n \n TractorDetail.find({'TractorID': {$in: requestBody }}, function(err, tractorDetails ){\n if(tractorDetails.length > 0){\n tractor_details = tractorDetails;\n cb(TractorOperator, operator_ids,tractor_activities, tractor_details, startTime )\n }\n \n });\n \n \n /** request for daily tractors activities */\n DailyTractorActivity.find( { \"TractorID\": {$in: requestBody }, \"day\":date_filter_obj },function(err,docs){\n tractor_activities = docs;\n if(docs.length > 0){\n tractor_activities = docs ;\n docs.forEach( function(doc){\n if(doc.OperatorID){\n operator_ids.push(doc.OperatorID);\n }\n count++;\n if (count == docs.length){\n\t\t\t\t\t\t\tcb(TractorOperator, operator_ids, tractor_activities, tractor_details, startTime );\n }\n }); \n }\n response.complete();\n });\n \n}\n\nfunction cb(TractorOperator, operator_ids,tractor_activities, tractor_details, start ){\n if( tractor_activities && tractor_details ){\n \tmodules.logger.info(operator_ids );\n \n /** Tractor Details HashTable **/\n var tractorDetailsObj = {};\n tractor_details.forEach( function(tractor_detail){\n tractorDetailsObj[tractor_detail.TractorID] = tractor_detail\n });\n \n /** operators hashTable **/\n var operatorDetailsObj = {};\n TractorOperator.find({'OperatorID': {$in: operator_ids }}, function(err, Operators ){\n Operators.forEach( function(operator){\n operatorDetailsObj[operator.OperatorID] = operator\n });\n \n if(tractor_activities.length > 0){\n for(var i=0; i<tractor_activities.length;i++ ){\n if( tractor_activities[i].OperatorID ){\n \t\t\ttractor_activities[i].OperatorName = operatorDetailsObj[tractor_activities[i].OperatorID] ? operatorDetailsObj[tractor_activities[i].OperatorID].OperatorName : null; \n }\n tractor_activities[i].TractorName = tractorDetailsObj[tractor_activities[i].TractorID].TractorName;\n }\n response.body = tractor_activities;\n// var end = new Date() - start ;\n// modules.logger.info(\"Execution time was :\" + end +\"ms\");\n }\n });\n\t\n}\n \n}" }, "PushDailyReports" : { "code" : "\n//Sends a CSV report of service bookings sent daily at 12am\n//Created on 17/01/2019 by Abdulmajid\nfunction onRequest(request, response, modules) {\n var january = \"2019-01-01\";\n var oneDayAgo = modules.moment.utc().subtract(24, \"hours\").format(\"YYYY-MM-DD\");\n var oneDayAgo = january;\n var email = modules.email;\n var kinvey = modules.kinvey;\n var cServiceBookings = modules.collectionAccess.collection(\"ServiceBookings\");\n var cEmails = modules.collectionAccess.collection(\"Emails\");\n\n //Constants\n const from = \"Hello Tractor Support <support@hellotractor.com>\";\n const to = \"apps2@hellotractor.com\";\n const cc = \"abubakar@hellotractor.com\";\n const bcc = \"deborah@hellotractor.com\";\n const replyTo = \"Hello Tractor App <apps2@hellotractor.com>\";\n const subject = \"Booking Report Since: \" + oneDayAgo;\n// const subject = \"Booking Report for Today: \" + oneDayAgo;\n const emailType = \"HTBookingCSVReport\";\n const userType = \"0\"; //Hello Tractor Admin\n\n cServiceBookings.find({ createdAt: { $gte: oneDayAgo } }, function(\n err,\n serviceBookings\n ) {\n if (err || serviceBookings.length < 1) {\n response.complete();\n } else {\n var report = buildBookingsReport(serviceBookings);\n pushCSVBookingsReport(\n response,\n email,\n cEmails,\n kinvey,\n from,\n to,\n subject,\n report,\n replyTo,\n cc,\n bcc,\n emailType,\n userType\n );\n }\n });\n}\n\nfunction buildBookingsReport(serviceBookings) {\n //Extract headers\n var report = \"\";\n var comma = \",\";\n var headers = \"_id,creator,ect,Service Date,Booking Id,BookingAgentID,Tractor Paired To,\"+\n \"Operator ID,Booking Status,Cluster Id,Created At,Updated At,Distance To Destination,\"+\n \"Farm Location,Farmer Name,Farmer Phone,Gender,Hectares Serviced,Latitude,Longitude,Org Id,Primary Crop,Secondary Crop, BAName, BAPhone, Service Type\"+\"\\n\";\n\n \n\n report += headers;\n\n serviceBookings.forEach(function(booking){\n var bookingAgent = booking.bookingAgentData? JSON.parse(booking.bookingAgentData):\"\";\n var row = \n toString(booking._id) + comma + \n toString(booking._acl.creator) + comma +\n toString(booking._kmd.ect) + comma +\n toString(booking.serviceDate) + comma +\n toString(booking.bookingID) + comma +\n toString(booking.bookingAgentID) + comma + \n toString(booking.tractorPairedTo) + comma +\n toString(booking.OperatorID) + comma +\n bookingStatus(booking.bookingStatus) + comma +\n toString(booking.clusterID) + comma +\n toString(booking.createdAt) + comma +\n toString(booking.updatedAt) + comma +\n toString(booking.distanceToDestination) + comma +\n toString(booking.farmLocation) + comma +\n toString(booking.farmerName) + comma +\n toString(booking.farmerPhone) + comma +\n toString(booking.gender) + comma +\n toString(booking.hectaresServiced) + comma +\n toString(booking.latitude) + comma +\n toString(booking.longitude) + comma +\n toString(booking.orgID) + comma +\n toString(booking.primaryCrop) + comma +\n toString(booking.secondaryCrop) + comma +\n toString(bookingAgent?bookingAgent.name:\"\") + comma +\n toString(bookingAgent?bookingAgent.phone:\"\") + comma +\n getServiceName(booking.serviceType) + \"\\n\";\n report += row; \n });\n \n return report;\n}\n\nfunction toString(text){\n return JSON.stringify(text);\n}\n\n\n\n\n\nfunction getServiceName (serviceCode) {\n var service_name;\n switch (serviceCode) {\n case \"109\":\n service_name = 'Harrowing'\n break;\n case \"104\":\n service_name = 'Planting/Seeding'\n break;\n case \"105\":\n service_name = 'Irrigating'\n break;\n case \"102\":\n service_name = 'Ploughing'\n break;\n case \"101\":\n service_name = 'Tilling'\n break;\n case \"103\":\n service_name = 'Ridging'\n break;\n case \"107\":\n service_name = 'Trailing'\n break;\n case \"108\":\n service_name = 'Harvesting'\n break;\n case \"106\":\n service_name = 'Harvesting'\n break;\n case \"110\":\n service_name = 'Spreading'\n break;\n case \"112\":\n service_name = 'Sprayer'\n break;\n case \"113\":\n service_name = 'Bioagtive'\n break;\n case \"114\":\n service_name = 'Dozer'\n break;\n case \"115\":\n service_name = 'Mower'\n break;\n default:\n service_name = \"Service Code: \"+serviceCode;\n break;\n }\n return service_name;\n }\n\n\n\n\n\n\n\n//Sends the provided report to the user's email\nfunction pushCSVBookingsReport(\n response,\n email,\n cEmails,\n kinvey,\n from,\n to,\n subject,\n report,\n replyTo,\n cc,\n bcc,\n emailType,\n userType\n) {\n email.send(\n from, //from\n to, //to\n subject, //subject\n report, //text_body\n replyTo, //reply_to\n null, //html_body\n cc, //cc\n bcc, //bcc\n function(err, result) {\n if (err) {\n response.complete();\n } else {\n var mail = {\n _acl: kinvey.entity()._acl,\n _kmd: kinvey.entity()._kmd,\n from: from,\n message: report,\n to: to,\n cc: cc,\n bcc: bcc,\n emailType: emailType,\n userType: userType,\n reply_to: replyTo\n };\n\n cEmails.save(mail, function(err2) {\n// response.body = mail;\n response.complete();\n });\n }\n }\n );\n}\n\nfunction bookingStatus(status){\n if (status == 0){\n return \"New\";\n } else if (status == 1 || status == 2){\n return \"Paired\";\n } else if (status == 3){\n return \"Completed\"\n } else {\n return \"Unknown Status\";\n }\n}" }, "_test" : { "code" : "function onRequest(request, response, modules) {\n var userCol = modules.collectionAccess.collection(\"user\");\n var tractorOwnerCol = modules.collectionAccess.collection(\"TractorOwner\"); \n var tractorDetailCol = modules.collectionAccess.collection(\"TractorDetail\"); \n var fuelHistoryCol = modules.collectionAccess.collection(\"FuelHistory\"); \n var serviceBookingsCol = modules.collectionAccess.collection(\"ServiceBookings\"); \n var tractorOperatorCol = modules.collectionAccess.collection(\"TractorOperator\"); \n // bookingAgentCol.findOne({\"_acl.creator\": \"5d15fa675c95ad2e46e53b9c\"}, function(err, user){\n // modules.logger.info(\"User: \"+JSON.stringify(user));\n // \tresponse.complete(); \n // });\n // userCol.findOne({\"_acl.creator\": \"5dc53d5e1ffe08372c5cf20c\"}, function(userErr, user){\n // \tvar tractorOwner = {\n // first_name: user.first_name,\n // last_name: user.last_name,\n // phone: user.phone,\n // email: user.email,\n // phone: user.phone,\n // username: user.username, \n // orgID: user.orgIDs,\n // createdAt: modules.moment.utc().format('YYYY-MM-DD HH:mm:ss'),\n // updatedAt: modules.moment.utc().format('YYYY-MM-DD HH:mm:ss')\n // };\n \n // // var entity = modules.kinvey.entity(bookingAgent);\n // tractorOwner._acl = user._acl;\n // tractorOwner._kmd = user._kmd; \n \n // tractorOwnerCol.save(tractorOwner, function(err) {\n // if(err) {\n // modules.logger.error('Query failed for creating tractor owner: ' + err);\n // return response.error(err);\n // } else {\n // return response.complete(200);\n // }\n // }); \n \n \n \n // });\n \n // response.complete();\n \n // var oneDayAgo = modules.moment.utc().subtract(5, \"minutes\"); //.format(\"YYYY-MM-DD\");\n // \t\tmodules.logger.info(oneDayAgo);\n // var i = {id: 100};\n // modules.logger.info(i);\n // response.complete();\n \n \n // var count = 0;\n // var tractorIds = [];\n // var acl = {\"creator\":\"5e26e75b443e190015fd0bee\"};\n // tractorDetailCol.find({\"_acl.creator\": \"5e26e75b443e190015fd0bee\"}, function (err, tractors){\n // tractors.forEach(function(tractor){\n // tractorIds.push(tractor.TractorID);\n // });\n \n // var tractorIdToCopy = 502145;\n // fuelHistoryCol.find({\"TractorID\": tractorIdToCopy}, function(err, fuelHistoryList){\n // fuelHistoryList.forEach(function(fuelHistory){\n // tractorIds.forEach(function(tractorId){\n // delete fuelHistory._id;\n // fuelHistory._acl = acl;\n // fuelHistory.TractorID = tractorId;\n // fuelHistory.OperatorID = 1565008416787;\n // fuelHistoryCol.save(fuelHistory, function(saveFuelErr, fuelSaved){\n // count++;\n // finish(fuelHistoryList.length);\n // })\n // });\n // })\n // })\n \n // modules.logger.info(JSON.stringify(tractorIds));\n // response.complete();\n // });\n \n // var finish = function (fuelCount){\n // if (count >= (fuelCount * tractorIds.length)){\n // modules.logger.info(\"Count saved: \"+(fuelCount * tractorIds.length));\n // response.complete();\n // }\n // }\n \n // var kmd = {_kmd: {\"lmt\":\"2020-01-22T13:33:33.862Z\",\"ect\":\"2020-01-22T13:33:20.374Z\"}};\n // var toSDate = {TOServiceDate: \"2020-02-19\"};\n // var date = {createdAt: \"2020-01-21 12:58:14\", updatedAt: \"2020-01-21 12:58:14\"};\n \n \n \n // serviceBookingsCol.update({\"_acl.creator\":\"5e26f2b46706a300167614a3\"}, {$set: date}, {multi: true}, function(updateErr, updatedData){\n // modules.logger.info(\"Booking agent bookings updated successfully: \"+JSON.stringify(updatedData));\n // response.complete();\n // }) \n \n // var count = 0;\n // serviceBookingsCol.find({\"_acl.creator\":\"5e26f2b46706a300167614a3\"}, function(findErr, bookingList){\n // // modules.logger.info(\"Booking agent bookings updated successfully: \"+JSON.stringify(updatedData));\n // count = bookingList.length;\n // modules.logger.info(\"Bookings to update: \"+count);\n // bookingList.forEach(function(booking){\n // // booking.clusterID = clusterId.toString();\n // // booking.bookingID = bookingId.toString();\n // var docs = {$set: {serviceType: 101}};\n \n // serviceBookingsCol.update({_id: booking._id}, docs, {multi: true}, function(serviceBookingErr, serviceBokingUpdated){\n // count--;\n // finish();\n // });\n // });\n // }) \n \n\n var count = 0;\n var tractorIds = [];\n var operatorIds = [];\n var acl = {\"creator\":\"5e26e75b443e190015fd0bee\"};\n tractorDetailCol.find({\"_acl.creator\": \"5e26e75b443e190015fd0bee\"}, function (err, tractors){\n // tractors.forEach(function(tractor){\n // tractorIds.push(tractor.TractorID);\n // });\n modules.logger.info(\"Tractors found: \"+tractors.length);\n count = tractors.length;\n tractors.forEach(function(tractor){\n tractorOperatorCol.findOne({\"OperatorID\": tractor.OperatorID}, function(err, operator){\n var doc = {$set: {OperatorImageURL: operator.ImageLocation}}\n fuelHistoryCol.update({\"TractorID\":tractor.TractorID}, doc, {multi: true}, function(fuelErr, fuelUpdated){\n count--;\n finish();\n })\n })\n })\n });\n \n var finish = function (){\n if (count <= 0){\n modules.logger.info(\"Bookings updated: \"+count);\n response.complete();\n }\n } \n }" }, "EngineHoursDistanceDiscoveredWeeklyAlert" : { "code" : "function onRequest(request, response, modules) {\n //Use tractor details, Daily tractor activity and users collection\n //1) find tractors\n //2) loop through tractors to get engine hours and distance\n //3) sort by acl to get tractors with same owner\n //4) calcualate total distance and engine hours covered by all tractors for each user\n //5) store the values in an array using acl as key\n //6) loop through the users table and send engine hour and distance notification using acl.\n\n var Tractors = modules.collectionAccess.collection(\"TractorDetail\");\n Tractors.find({}, { sort: { _acl: 1 } }, function(err, allTractors) {\n if (err) {\n modules.logger.info(\"error found\" + err);\n response.error(300);\n } else {\n modules.logger.info(\"Total tractors: \" + allTractors.length);\n handleMergeAcl(allTractors);\n }\n });\n}\n\nfunction handleMergeAcl(tractors) {\n var current_acl = \"\";\n var count = 0;\n var counter = 0;\n var tractorDetail = [];\n var engineHours = 0;\n var distanceCovered = 0;\n\n for (var i = 0; i < tractors.length; i++) {\n if (current_acl == tractors[i]._acl.creator) {\n if (tractors[i].EngineHours) {\n engineHours = engineHours + Number(tractors[i].EngineHours);\n }\n if (tractors[i].TotalDistanceCovered) {\n distanceCovered =\n distanceCovered + Number(tractors[i].TotalDistanceCovered);\n }\n } else {\n current_acl = tractors[i]._acl.creator;\n if (tractors[i].EngineHours) {\n engineHours = Number(tractors[i].EngineHours);\n }\n if (tractors[i].TotalDistanceCovered) {\n distanceCovered = Number(tractors[i].TotalDistanceCovered);\n }\n count = count + 1;\n }\n\n tractorDetail[count - 1] = {\n _id: count - 1,\n _acl: {creator: current_acl},\n EngineHours: engineHours,\n TotalDistanceCovered: distanceCovered\n };\n\n counter += 1;\n \n if (counter >= tractors.length){\n verifyUser(modules, response, tractorDetail); //datatype is an array\n }\n \n } //end for loop\n\n // modules.logger.info(\"Merged: \" + tractorDetail.length);\n //modules.logger.info(\"Merged Details: \" + JSON.stringify(tractorDetail));\n \n}\n\nfunction verifyUser(modules, response, answer) {\n var users = modules.collectionAccess.collection(\"user\");\n var count = 0;\n var render = modules.utils.renderTemplate;\n// modules.logger.info(\"in verify user method: \" + JSON.stringify(answer));\n modules.logger.info(\"Answer Length: \" + answer.length);\n var notificationsSent = 0;\n \n answer.forEach(function(userTractorData){\n users.find({ \"_acl.creator\": userTractorData._acl.creator }, function(err, user) {\n if (err) {\n modules.logger.info(\"Failed to find user: \" + userTractorData._acl);\n } else {\n if (user[0]) {\n var mess = \"Hello \"+user[0].first_name+\", your tractors have been turned on for a total of \"+userTractorData.EngineHours+\" engine hours and covered a total distance of \"+userTractorData.TotalDistanceCovered+\"km\";\n \n notificationsSent++;\n// modules.logger.info(JSON.stringify(user[0]._acl.creator) + \" :\" + count);\n modules.logger.info(\"User Name: \"+user[0].first_name +\", message: \"+mess);\n } else {\n// modules.logger.info(JSON.stringify(user));\n }\n }\n count++;\n \n if (count >= answer.length){\n modules.logger.info(\"Notifications Sent: \"+notificationsSent);\n response.complete();\n }\n });\n });\n\n\n}" }, "getTractotsLatLng" : { "code" : "function onRequest(request, response, modules) {\n //expose all tractors lat and lng only \n var DailyTractorActivity = modules.collectionAccess.collection('DailyTractorActivity');\n \n // fetch tractor daily activities witin last year , from: 2018-01-01 , to: 2018-11-16; \n var tractorActivityQuery = {day: {\"$gte\" : \"2018-01-01\", \"$lte\": \"2018-11-16\"} }\n \t\n DailyTractorActivity.find( tractorActivityQuery,function(err, _activities){\n if( err ) return response.error(err);\n\t\t\n var stateActivitiesCountHash = {};\n \n var _activities_lat_lng = _activities.map( function(_activity){\n if( _activity.Route && _activity.Route[0][\"Lat\"] && _activity.Route[0][\"Lng\"] ) {\n \n if( _activity[\"Town\"] ){\n var townName = _activity.Town;\n \t stateActivitiesCountHash[townName] = stateActivitiesCountHash[townName] + 1 || 0;\n }\n \n return { lat : _activity.Route[0][\"Lat\"], lng: _activity.Route[0][\"Lng\"] }\n }\n });\n \n // Send the array of tractors lat , lng object as response \n response.body = _activities_lat_lng;\n// modules.logger.info( \"total activities is \" + _activities.length + \" and valid activities by lat and lng criteria is \" + _activities_lat_lng.length );\n \n modules.logger.info( stateActivitiesCountHash );\n\n response.complete(200);\n })\n \n}" }, "exportRegisteredBookingAgentsForDateRange" : { "code" : "// function onRequest(request, response, modules) {\n \n// const BookingAgent = modules.collectionAccess.collection('BookingAgents');\n// const agents_query = {\"_kmd.lmt\":{ \"$gte\": \"2017-01-01\", \"$lte\": \"2019-02-28\"} }\n// BookingAgent.find(agents_query, function(_err, _booking_agents){\n// if( _err ) {\n// modules.logger.info(\"There was an error \" + new Error(_err).message );\n// response.complete();\n// }\n \n// var agents_array = [];\n// var count = 0;\n// for( var i=0; i<_booking_agents.length; i++){\n// agents_array.push({\n// \"S/N\": count+=1,\n// Name: _booking_agents[i].name,\n// Email: _booking_agents[i].email ? _booking_agents[i].email : \"NA\" , \n// Phone: _booking_agents[i].phone,\n// BookingAgentID: _booking_agents[i].bookingAgentID,\n// ORGID: _booking_agents[i].orgID ? _booking_agents[i].orgID : \"NA\" ,\n// RegistrationDate: _booking_agents[i].createdAt ? _booking_agents[i].createdAt.split(' ')[0]: \"NA\"\n// })\n// }\n \n// \tresponse.body = agents_array;\n// response.complete(200);\n\n// })\n// }\n\n\n\nfunction onRequest(request, response, modules) {\n var http = modules.request;\n \n var hasLocation = function(bookingAgent){\n if ( bookingAgent.latitude && bookingAgent.longitude ) {\n return {\n lat: bookingAgent.latitude,\n lng: bookingAgent.longitude\n }\n }\n \n return null;\n }\n \n const BookingAgent = modules.collectionAccess.collection('BookingAgents');\n const agents_query = {\"_kmd.lmt\":{ \"$gte\": \"2017-01-01\", \"$lte\": \"2019-02-28\"} }\n BookingAgent.find(agents_query,{\"limit\":510}, function(_err, _booking_agents){\n if( _err ) {\n modules.logger.info(\"There was an error \" + new Error(_err).message );\n response.complete();\n }\n \n var agents_hash = {};\n var count = 0;\n for( var i=0; i<_booking_agents.length; i++){\n agents_hash[_booking_agents[i].bookingAgentID] = {\n \"S/N\": count+=1,\n Name: _booking_agents[i].name,\n Email: _booking_agents[i].email ? _booking_agents[i].email : \"NA\" , \n Phone: _booking_agents[i].phone,\n BookingAgentID: _booking_agents[i].bookingAgentID,\n ORGID: _booking_agents[i].orgID ? _booking_agents[i].orgID : \"NA\" ,\n RegistrationDate: _booking_agents[i].createdAt ? _booking_agents[i].createdAt.split(' ')[0]: \"NA\",\n latitude: _booking_agents[i].latitude ? _booking_agents[i].latitude : 0, \n longitude: _booking_agents[i].longitude ? _booking_agents[i].longitude : 0\n }\n }\n \n // Reverse goecode the latitude and longitude \n var tmpCount = 0;\n var noLoc = 0;\n var url = \"https://baas.kinvey.com/rpc/kid_bkFYnCzzzb/custom/geocoderService\";\n \n for( var key in agents_hash ){\n var agent = agents_hash[key];\n// modules.logger.info( \"the agent latitude and longitude is \" + agent.latitude + \" , \" + agent.longitude );\n var _agentLocation = hasLocation(agent)\n \n if( _agentLocation ){\n modules.logger.info(\" The agent location is \" + JSON.stringify(_agentLocation) + \" and the booking agent ID is \" + agent.BookingAgentID );\n var requestOptions = {\n uri: url,\n body: JSON.stringify({\n lat: _agentLocation.lat,\n lng: _agentLocation.lng\n }),\n headers:{\n \"Content-Type\":\"application/json\",\n \"Authorization\": \"Basic a2lkX2JrRlluQ3p6emI6ZTczMWY5YTI4NTgzNDkwMGEzNWMyODEzZGQxNzYyYzI=\",\n \"X-Kinvey-API-Version\":3\n }\n \n }\n\n http.post(requestOptions, function(error, resp, body){\n if( error ) {\n modules.logger.info(\"There was an error \" + error );\n tmpCount++;\n }\telse {\n modules.logger.info( body );\n \tagents_hash[key].location = body.body\n \ttmpCount++;\n }\n \n })\n }\n else {\n noLoc++;\n// modules.logger.info(\"booking agent has no location\");\n tmpCount++;\n }\n \n if( tmpCount === Object.keys(agents_hash).length){\n modules.logger.info( \"The tempCount is \" + tmpCount );\n modules.logger.info( \"The hash count is \" + Object.keys(agents_hash).length );\n modules.logger.info( \"The no location agent count is \" + noLoc);\n response.body = agents_hash;\n response.complete(200);\n }\n\t}\n \n })\n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" }, "geocoderService" : { "code" : "function onRequest(request, response, modules) {\n \n var handleGeocodeServiceResponse = function(error, resp, body){\n var resObj = {};\n if( error ){\n // Whoops, error error!!\n modules.logger.info(\"Error getting reverse geocode values\");\n \t\tresObj = {\n success: false,\n error: new Error(error).message\n }\n \n }\n \t\n // All went on fine ):\n var location = JSON.parse(body).geonames[0];\n \tresObj = {\n success: true,\n body:location.name + ', ' + location.adminName1 + ', ' + location.countryName\n }\n \n// \tmodules.logger.info(\"We got data \" + body);\n \n // Set the response body\n response.body = resObj;\n \treturn response.complete();\n }\n \n var http = modules.request;\n var lat = request.body.lat;\n var lng = request.body.lng;\n var requestOptions = {\n qs: {\n lat: lat,\n lng: lng,\n username:'hellofuture'\n },\n uri:'http://api.geonames.org/findNearbyPlaceNameJSON'\n }\n \n http.get(requestOptions, handleGeocodeServiceResponse)\n \n}" }, "aeris_geofence_notification" : { "code" : "//Sends a push notification to the tractor owner when the tractor is not within the boundary defined in latitude and longitude \n//Scheduled endpoint\n//Interval - 1-minute\n//Start time - 2019/03/06 03:06\n//Created by Abdulmajid\n\nfunction onRequest(request, response, modules) {\n var collectionAccess = modules.collectionAccess,\n moment = modules.moment,\n logger = modules.logger,\n count = 0,\n dateTime30MinsAgo = modules.moment.utc().subtract(30, \"minutes\").format(\"YYYY-MM-DD HH:mm:ss\"),\n countTractorsUpdated = 0;\n \n var tractorQuery = {\n $and: [\n {TractorID: {$gte: 500000}},\n {LastActiveTime: {$gte: dateTime30MinsAgo}}\n ]\n }; //Filter only aeris tractors \n \n //Get tractors and loop through the tractors\n modules.collectionAccess\n .collection(\"TractorDetail\")\n .find(tractorQuery, function(err, tractors) {\n logger.info(\"Tractors found: \"+tractors.length);\n //Tractors found\n if (err){\n logger.info(\"Could not find tractors: \"+err);\n response.complete();\n } else {\n logger.info(\"Tractors found 2: \"+tractors.length);\n tractors.forEach(function(tractor) {\n if (tractor.TractorID && tractor.TractorID.toString().length === 6 && tractor.PositionLatitude && tractor.PositionLongitude) {\n //named lastActivity, but its simply the lon and lat that is required\n var lastActivity = {\n lat: tractor.PositionLatitude,\n lon: tractor.PositionLongitude\n };\n\n modules.logger.info(\"About to initiate c_sendGeofenceNotificationIfNecessary\");\n \n //code of c_sendGeofenceNotificationIfNecessary is placed in common/geofence.js\n c_sendGeofenceNotificationIfNecessary(lastActivity, tractor, function(geoErr, result) {\n if (geoErr) {\n logger.info(\"Failed to send geofence notification for: \"+tractor.TractorID+\", \"+geoErr);\n shouldCompleteRequest(tractors);\n } else {\n var tractorGeofenceUpdate = {};\n if (result && result.wasSent) {\n tractorGeofenceUpdate.LastGeofenceNotificationTime = !result.WasInArea && tractor.NeedToSendGeofenceOutNotification? moment().toISOString():\"\";\n tractorGeofenceUpdate.WasInArea = result.WasInArea;\n tractorGeofenceUpdate.NeedToSendGeofenceOutNotification = true;\n logger.info(\"Notification was sent for \"+tractor.TractorID);\n } else {\n logger.info(\"Notification was not sent: \"+tractor.TractorID);\n }\n\n //logger.info('set Object ' + JSON.stringify(setObject));\n collectionAccess.collection(\"TractorDetail\").update({TractorID: tractor.TractorID}, {$set: tractorGeofenceUpdate},\n function (updateErr, updateResult) {\n \tcountTractorsUpdated++;\n shouldCompleteRequest(tractors);\n });\n }\n });\n } else {\n logger.info(tractor.TractorID + \" is invalid\");\n shouldCompleteRequest(tractors);\n }\n });\n } //end if err\n });\n \n var shouldCompleteRequest = function (tractors){\n count++;\n if (count == tractors.length){\n \tlogger.info(\"Count tractors updated: \"+countTractorsUpdated);\n logger.info(\"Done\");\n response.complete();\n }\n }\n }\n " }, "removeDuplicateBookings" : { "code" : "function onRequest(request, response, modules) {\n \n var Booking = modules.collectionAccess.collection('ServiceBookings');\n \n Booking.find({}, function(err, bookings){\n \tvar bookingsHash = {};\n \tvar count = 0;\n \tbookings.forEach( function(booking){\n \n\t\t\tif( ! bookingsHash[booking.bookingID] ){\n bookingsHash[booking.bookingID] = [];\n }\n \n bookingsHash[booking.bookingID].push( booking );\n count++;\n \n if( count === bookings.length){\n \n for( var bookingID in bookingsHash ){\n \n var bookingsDuplicateCount = bookingsHash[bookingID].length;\n var bookingID = bookingsHash[bookingID][0].bookingID;\n var singleBookingRecord = bookingsHash[bookingID][0];\n if( bookingsDuplicateCount > 1 ){\n \t\t\t\t\tBooking.remove({bookingID: bookingID }, function(err){});\n Booking.save(singleBookingRecord, function(err, saved){}); \n } \n }\n \n modules.logger.info(\"The data are here! \" + JSON.stringify(bookingsHash));\n \tresponse.complete();\n }\n \t\n \t})\n \n })\n}\n \n " }, "getOperatorIDByTractorID" : { "code" : "function onRequest(request, response, modules){\n var Tractor = modules.collectionAccess.collection('TractorDetail');\n var tractor_id = Number(request.body.tractor_id);\n modules.logger.info(\"called with tractor_id \" + tractor_id );\n\n if( !tractor_id ){\n response.body = {success: false, errors: [{\n tractor_id: 'please provide tractor_id to get the operator_id'\n }]};\n \n response.complete();\n }\n \n Tractor.find({TractorID: tractor_id}, function(err, tractor){ \n // Exit if error;\n if( err ){\n response.body = {success:false, errors: new Error(err).message};\n return response.complete();\n }\n \n // Exit if no tractor was found using the supplied tractor id \n if( tractor.length === 0 ){\n response.body = {success:false, errors: [{\n tractor_id: 'Tractor with the tractorID ' + tractor_id + ' was not found, please supply a valid id'\n }]};\n return response.complete();\n }\n \n // We found the tractor and it has data , lets send the ID \n \n var operator_id;\n \n if( ! tractor[0].OperatorID ) {\n operator_id = null;\n }\n else {\n operator_id = tractor[0].OperatorID\n }\n \n response.body = {success:true, operator_id:operator_id };\n return response.complete();\n \n })\n \n}" }, "getBookingsLatLng" : { "code" : "function onRequest(request, response, modules) {\n //expose all tractors lat and lng only \n var Booking = modules.collectionAccess.collection('ServiceBookings');\n\n // Fetch booking for a date range \n var bookingsQuery = {createdAt: {\"$gte\" : \"2019-01-02\", \"$lte\": \"2019-04-05\"} }\n Booking.find( bookingsQuery, function(err, _bookings){\n\n if( err ) return response.error(err);\n \t\t\n var _bookings_lat_lng = _bookings.map( function(_booking){\n if( _booking.latitude && _booking.longitude ) {\n return { lat : Number(_booking.latitude), lng: Number(_booking.latitude) }\n }\n });\n \n // Send the array of bookings lat , lng object as response \n response.body = _bookings_lat_lng;\n response.complete(200);\n })\n \n}" }, "count2TrackTractors" : { "code" : "function onRequest(request, response, modules) {\n \n var Tractor = modules.collectionAccess.collection('TractorDetail');\n \n Tractor.find({}, function(err, _tractors){\n var tractorsCount =0;\n var count = 0\n var twotrack_tractors = []\n for(var i=0; i < _tractors.length; i++){\n if( _tractors[i][\"TractorID\"].toString().charAt(0) === \"1\" ){\n twotrack_tractors.push(_tractors[i][\"TractorID\"]) \n tractorsCount+=1;\n count++;\n }\n else {\n count++;\n }\n \n if( count === _tractors.length ){\n response.body = JSON.stringify(twotrack_tractors);\n response.complete();\n }\n }\n \n })\n}" }, "UpdateTwoTrackTractorActivityOnPOSTFromAWSBackend" : { "code" : "function onRequest(request, response, modules) {\n modules.logger.info('data posted');\n modules.logger.info( JSON.stringify(request.body.data) )\n var getFormattedRoute = function(activityArr){\n var route = [];\n for(var i=0; i < activityArr.length; i++){\n route.push({\"Lat\":activityArr[i].lat, \"Lng\": activityArr[i].lon, \"Time\": activityArr[i].activityUTCDate })\n }\n return route;\n }\n \n \tvar getTotalTimeIdle = function(activity){\n try {\n var today = modules.moment.utc().format('YYYY-MM-DD');\n var data = activity;\n var startDate = new Date(''+today+' 00:00:00');\n var endDate = new Date();\n var seconds = (endDate - startDate) / 1000;\n var inactiveTime = parseInt( (seconds - (activity.operateTime)).toFixed() );\n \n return inactiveTime;\n }\n catch(e){\n modules.logger.info(new Error(e).message)\n }\n }\n \n var Tractor = modules.collectionAccess.collection('DailyTractorActivity');\n \n // Get today date formatted as Y-m-d\n\tvar today = new Date().toISOString().split('T')[0]; \n \n //an array of activity objects\n var tractorDataArr = request.body.data; \n var queueCount = 0;\n \n if( tractorDataArr.length ){\n // To be able to find the tractor activity, its TractorID need be an int type but it's been posted as type string\n var tractor_id = + tractorDataArr[0].tractor_id;\n\n modules.logger.info(tractor_id );\n \n for( var i = 0; i < tractorDataArr.length; i++){\n \n var tractorData = tractorDataArr[i];\n \n var activityData = {};\n \n activityData.day = today;\n activityData.Latitude = tractorData.lat;\n activityData.Longitude = tractorData.lon;\n activityData.Speed = tractorData.speed;\n activityData.Town = tractorData.town;\n activityData.Street = tractorData.street;\n activityData.Country = tractorData.country;\n activityData.StartTown = tractorData.town;\n activityData.StartCountry = tractorData.country;\n activityData.StartStreet = tractorData.street;\n activityData.ignitionStatus = tractorData.ignitionStatus;\n activityData.LastOdometerValue = tractorDataArr[tractorDataArr.length-1].odometer;\n activityData.Route = getFormattedRoute(tractorDataArr);\n activityData.TractorID = tractor_id;\n activityData.HectaresServiced = 0;\n activityData.TotalTimeActive = tractorData.operateTime || 0;\n activityData.DistanceTravelled = tractorData.distance || 0;\n activityData.TotalTimeIdle = getTotalTimeIdle(tractorData);\n activityData.RevenuType = 101;\n activityData.Hectares = 0;\n activityData.Revenue = 0;\n activityData.RevenueType = 108;\n activityData.RevenueCurrency = ''\n activityData.LastJourneyStartTime = tractorData.activityUTCDate;\n activityData.BatteryVoltage = tractorData.batteryVoltage;\n activityData.SatelliteNumber = tractorData.satelliteNumber; \n activityData.LastActivityId = tractorData.activityId;\n activityData.StartActiveData = tractorDataArr[0].activityUTCDate;\n activityData.LastActiveData = tractorDataArr[tractorDataArr.length-1].activityUTCDate;\n \n // Attach nescessary kinvey metadata\n var KinveyMetaData = modules.kinvey.entity();\n activityData._acl = KinveyMetaData._acl;\n activityData._kmd = KinveyMetaData._kmd;\n \n \n \n Tractor.update({\"TractorID\":tractor_id, \"day\": today}, {$set: activityData}, {\"upsert\":true}, function(err, updated){\n if( !err){\n queueCount++;\n if( queueCount === tractorDataArr.length ){\n modules.logger.info('successfully updated all two track tractor activity for ' + tractor_id);\n response.complete();\n }\n }\n else {\n modules.logger.info(err);\n \n queueCount++;\n if( queueCount === tractorDataArr.length ){\n modules.logger.info('done processing with errors');\n response.complete();\n }\n }\n });\n \n \t} \n }\n}\n \n\n/*\nSample data posted \n\n\"returnCode\":\"200\",\"isSuccess\":true,\"data\":[{\"activityId\":121317998,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":12,\"odometer\":10075828,\"idle\":0,\"isGPSValid\":true,\"lat\":7.8573,\"lon\":10.9687,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":108,\"altitude\":20690,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"Palace Takum-Bali Rd\",\"town\":\"Bali\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 05:45:06.0\",\"tractor_id\":\"100120\"},{\"activityId\":121318014,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10075891,\"idle\":0,\"isGPSValid\":true,\"lat\":7.8574,\"lon\":10.9692,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":56,\"altitude\":21102,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"Palace Takum-Bali Rd\",\"town\":\"Bali\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 05:45:22.0\"},{\"activityId\":121318026,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":31,\"odometer\":10076002,\"idle\":0,\"isGPSValid\":true,\"lat\":7.858,\"lon\":10.97,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":39,\"altitude\":20360,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"Takum-Bali Rd\",\"town\":\"Bali\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 05:45:39.0\"},{\"activityId\":121318038,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":25,\"odometer\":10076136,\"idle\":0,\"isGPSValid\":true,\"lat\":7.859,\"lon\":10.9706,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":55,\"altitude\":19967,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":8,\"street\":\"Takum-Bali Rd\",\"town\":\"Bali\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 05:45:55.0\"},{\"activityId\":121318089,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10076184,\"idle\":33,\"isGPSValid\":true,\"lat\":7.859,\"lon\":10.971,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":109,\"altitude\":19920,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Takum-Bali Rd\",\"town\":\"Bali\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 05:46:41.0\"},{\"activityId\":121318197,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":30,\"odometer\":10076250,\"idle\":0,\"isGPSValid\":true,\"lat\":7.8587,\"lon\":10.9716,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":125,\"altitude\":20580,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Takum-Bali Rd\",\"town\":\"Bali\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 05:48:52.0\"},{\"activityId\":121318220,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":31,\"odometer\":10076420,\"idle\":0,\"isGPSValid\":true,\"lat\":7.8577,\"lon\":10.9727,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":141,\"altitude\":19859,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Mambila Plateau Rd\",\"town\":\"Bali\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 05:49:11.0\"},{\"activityId\":121318238,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10076698,\"idle\":0,\"isGPSValid\":true,\"lat\":7.8558,\"lon\":10.9743,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":124,\"altitude\":19841,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Mambila Plateau Rd\",\"town\":\"Bali\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 05:49:46.0\"},{\"activityId\":121318320,\"eventCode\":\"12\",\"eventName\":\"Journey End\",\"speed\":0,\"odometer\":10076710,\"idle\":0,\"isGPSValid\":true,\"lat\":7.8558,\"lon\":10.9744,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":113,\"altitude\":19836,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Mambila Plateau Rd\",\"town\":\"Bali\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 05:51:18.0\"},{\"activityId\":121318782,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":0,\"odometer\":10076710,\"idle\":1555394304,\"isGPSValid\":false,\"lat\":7.8558,\"lon\":10.9744,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":113,\"altitude\":0,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":0,\"street\":\"Mambila Plateau Rd\",\"town\":\"Bali\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 05:56:41.0\"},{\"activityId\":121318795,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":0,\"odometer\":10076710,\"idle\":1555394304,\"isGPSValid\":false,\"lat\":7.8558,\"lon\":10.9744,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":113,\"altitude\":0,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":0,\"street\":\"Mambila Plateau Rd\",\"town\":\"Bali\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 05:56:41.0\"},{\"activityId\":121318787,\"eventCode\":\"31\",\"eventName\":\"Sensor\",\"speed\":0,\"odometer\":10076710,\"idle\":1555394304,\"isGPSValid\":false,\"lat\":7.8558,\"lon\":10.9744,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":113,\"altitude\":0,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":0,\"street\":\"Mambila Plateau Rd\",\"town\":\"Bali\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 05:56:41.0\"},{\"activityId\":121318792,\"eventCode\":\"98\",\"eventName\":\"Power Connect\",\"speed\":0,\"odometer\":10076710,\"idle\":1555394304,\"isGPSValid\":false,\"lat\":7.8558,\"lon\":10.9744,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":113,\"altitude\":0,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":0,\"street\":\"Mambila Plateau Rd\",\"town\":\"Bali\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 05:56:41.0\"},{\"activityId\":121319075,\"eventCode\":\"12\",\"eventName\":\"Journey End\",\"speed\":0,\"odometer\":10076710,\"idle\":0,\"isGPSValid\":true,\"lat\":7.8558,\"lon\":10.9744,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":134,\"altitude\":19737,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Mambila Plateau Rd\",\"town\":\"Bali\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:00:54.0\"},{\"activityId\":121319712,\"eventCode\":\"11\",\"eventName\":\"Journey Start\",\"speed\":0,\"odometer\":10076710,\"idle\":0,\"isGPSValid\":true,\"lat\":7.8557,\"lon\":10.9745,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":136,\"altitude\":20044,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"Mambila Plateau Rd\",\"town\":\"Bali\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:05:29.0\"},{\"activityId\":121320914,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10076712,\"idle\":0,\"isGPSValid\":true,\"lat\":7.8557,\"lon\":10.9745,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":255,\"altitude\":19958,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Mambila Plateau Rd\",\"town\":\"Bali\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:06:07.0\"},{\"activityId\":121320917,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":32,\"odometer\":10082548,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9046,\"lon\":10.9894,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":1,\"altitude\":22907,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"Bali - Jalingo Rd\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:17:46.0\"},{\"activityId\":121320949,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":32,\"odometer\":10082847,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9074,\"lon\":10.9895,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":1,\"altitude\":23799,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"Bali - Jalingo Rd\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:18:25.0\"},{\"activityId\":121320999,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":32,\"odometer\":10083144,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9102,\"lon\":10.9896,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":1,\"altitude\":23928,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":8,\"street\":\"Bali - Jalingo Rd\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:18:58.0\"},{\"activityId\":121321041,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":33,\"odometer\":10083440,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9129,\"lon\":10.9896,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":1,\"altitude\":23813,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"Bali - Jalingo Rd\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:19:31.0\"},{\"activityId\":121321111,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":33,\"odometer\":10083737,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9157,\"lon\":10.9897,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":0,\"altitude\":22627,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":8,\"street\":\"Bali - Jalingo Rd\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:20:04.0\"},{\"activityId\":121321126,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":32,\"odometer\":10084034,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9184,\"lon\":10.9897,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":1,\"altitude\":22017,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"Bali - Jalingo Rd\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:20:37.0\"},{\"activityId\":121321315,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10084264,\"idle\":192,\"isGPSValid\":true,\"lat\":7.9205,\"lon\":10.9899,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":91,\"altitude\":22231,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 06:24:19.0\"},{\"activityId\":121321402,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10084386,\"idle\":3,\"isGPSValid\":true,\"lat\":7.9205,\"lon\":10.991,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":72,\"altitude\":22217,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Bali - Jalingo Rd\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:25:15.0\"},{\"activityId\":121321407,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10084431,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9206,\"lon\":10.9914,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":94,\"altitude\":22447,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Bali - Jalingo Rd\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:25:31.0\"},{\"activityId\":121321449,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10084478,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9205,\"lon\":10.9918,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":75,\"altitude\":22619,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Bali - Jalingo Rd\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:25:50.0\"},{\"activityId\":121321502,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10084542,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9206,\"lon\":10.9924,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":92,\"altitude\":22642,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"Bali - Jalingo Rd\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:26:21.0\"},{\"activityId\":121321538,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10084613,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9207,\"lon\":10.9932,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":72,\"altitude\":22588,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:26:48.0\"},{\"activityId\":121321557,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":17,\"odometer\":10084675,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9207,\"lon\":10.9937,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":89,\"altitude\":22518,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:27:05.0\"},{\"activityId\":121321588,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":14,\"odometer\":10084763,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9207,\"lon\":10.9946,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":105,\"altitude\":23004,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 06:27:29.0\"},{\"activityId\":121321628,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10084850,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9205,\"lon\":10.9953,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":84,\"altitude\":23179,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:27:57.0\"},{\"activityId\":121321654,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10084899,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9205,\"lon\":10.9958,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":114,\"altitude\":23225,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:28:13.0\"},{\"activityId\":121321668,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":16,\"odometer\":10084953,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9205,\"lon\":10.9963,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":94,\"altitude\":23193,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:28:29.0\"},{\"activityId\":121321701,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":12,\"odometer\":10085014,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9206,\"lon\":10.9968,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":78,\"altitude\":23224,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:28:47.0\"},{\"activityId\":121321738,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10085111,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9206,\"lon\":10.9977,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":98,\"altitude\":23252,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:29:15.0\"},{\"activityId\":121321762,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10085160,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9206,\"lon\":10.9982,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":62,\"altitude\":23186,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:29:31.0\"},{\"activityId\":121321776,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10085213,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9207,\"lon\":10.9986,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":79,\"altitude\":22976,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 06:29:48.0\"},{\"activityId\":121321796,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":13,\"odometer\":10085262,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9209,\"lon\":10.999,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":60,\"altitude\":22692,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 06:30:04.0\"},{\"activityId\":121321829,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":14,\"odometer\":10085312,\"idle\":0,\"isGPSValid\":true,\"lat\":7.921,\"lon\":10.9995,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":79,\"altitude\":22504,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:30:20.0\"},{\"activityId\":121321860,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":14,\"odometer\":10085391,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9213,\"lon\":11.0002,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":59,\"altitude\":22446,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:30:42.0\"},{\"activityId\":121321910,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":14,\"odometer\":10085455,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9215,\"lon\":11.0007,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":83,\"altitude\":22417,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 06:31:00.0\"},{\"activityId\":121321912,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10085513,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9215,\"lon\":11.0012,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":134,\"altitude\":22470,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 06:31:16.0\"},{\"activityId\":121321918,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":15,\"odometer\":10085574,\"idle\":0,\"isGPSValid\":true,\"lat\":7.921,\"lon\":11.0016,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":154,\"altitude\":22282,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:31:33.0\"},{\"activityId\":121321959,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10085610,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9208,\"lon\":11.0018,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":136,\"altitude\":22224,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 06:31:50.0\"},{\"activityId\":121321992,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":12,\"odometer\":10085778,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9197,\"lon\":11.0029,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":118,\"altitude\":22025,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 06:32:45.0\"},{\"activityId\":121322033,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":15,\"odometer\":10085906,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9192,\"lon\":11.0039,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":98,\"altitude\":22350,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 06:33:17.0\"},{\"activityId\":121322066,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":12,\"odometer\":10085990,\"idle\":0,\"isGPSValid\":true,\"lat\":7.919,\"lon\":11.0047,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":79,\"altitude\":22594,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:33:38.0\"},{\"activityId\":121322075,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10086015,\"idle\":6,\"isGPSValid\":true,\"lat\":7.919,\"lon\":11.0049,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":103,\"altitude\":22750,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 06:33:54.0\"},{\"activityId\":121322129,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":14,\"odometer\":10086087,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9188,\"lon\":11.0055,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":124,\"altitude\":22898,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:34:15.0\"},{\"activityId\":121322132,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10086146,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9185,\"lon\":11.006,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":95,\"altitude\":22810,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 06:34:31.0\"},{\"activityId\":121322171,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10086198,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9184,\"lon\":11.0065,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":113,\"altitude\":22939,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:34:54.0\"},{\"activityId\":121322190,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10086228,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9183,\"lon\":11.0068,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":90,\"altitude\":22949,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:35:10.0\"},{\"activityId\":121322245,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":4,\"odometer\":10086270,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9183,\"lon\":11.0073,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":70,\"altitude\":23131,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:35:30.0\"},{\"activityId\":121322323,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10086417,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9187,\"lon\":11.0087,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":86,\"altitude\":22802,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 06:36:12.0\"},{\"activityId\":121322347,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10086484,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9189,\"lon\":11.0093,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":69,\"altitude\":22714,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:36:31.0\"},{\"activityId\":121322699,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10086637,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9194,\"lon\":11.0106,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":53,\"altitude\":22405,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:37:19.0\"},{\"activityId\":121322702,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":24,\"odometer\":10086704,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9197,\"lon\":11.0111,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":72,\"altitude\":22302,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:37:35.0\"},{\"activityId\":121322705,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":12,\"odometer\":10086781,\"idle\":0,\"isGPSValid\":true,\"lat\":7.92,\"lon\":11.0118,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":53,\"altitude\":22270,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 06:37:57.0\"},{\"activityId\":121322788,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":12,\"odometer\":10086838,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9203,\"lon\":11.0122,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":75,\"altitude\":22298,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 06:38:13.0\"},{\"activityId\":121322794,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":16,\"odometer\":10086917,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9205,\"lon\":11.0129,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":57,\"altitude\":22221,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:38:36.0\"},{\"activityId\":121322799,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10087261,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9221,\"lon\":11.0156,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":70,\"altitude\":22326,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:40:00.0\"},{\"activityId\":121322804,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":18,\"odometer\":10087431,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9226,\"lon\":11.0171,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":86,\"altitude\":22383,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:40:45.0\"},{\"activityId\":121322806,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":14,\"odometer\":10087618,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9226,\"lon\":11.0188,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":70,\"altitude\":22241,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:41:27.0\"},{\"activityId\":121322823,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10087763,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9229,\"lon\":11.0201,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":86,\"altitude\":22238,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:42:19.0\"},{\"activityId\":121323088,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10087833,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9231,\"lon\":11.0207,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":69,\"altitude\":22035,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:42:45.0\"},{\"activityId\":121323091,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":4,\"odometer\":10088071,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9238,\"lon\":11.0228,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":52,\"altitude\":22373,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:43:53.0\"},{\"activityId\":121323096,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10088133,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9241,\"lon\":11.0234,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":70,\"altitude\":22589,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 06:44:15.0\"},{\"activityId\":121323099,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":18,\"odometer\":10088243,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9243,\"lon\":11.0244,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":87,\"altitude\":22800,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:44:45.0\"},{\"activityId\":121323102,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10088310,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9244,\"lon\":11.025,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":71,\"altitude\":22729,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 06:45:01.0\"},{\"activityId\":121323162,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10088416,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9246,\"lon\":11.0259,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":89,\"altitude\":22850,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:45:47.0\"},{\"activityId\":121323208,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":15,\"odometer\":10088486,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9248,\"lon\":11.0266,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":64,\"altitude\":22772,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 06:46:03.0\"},{\"activityId\":121323250,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":20,\"odometer\":10088579,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9252,\"lon\":11.0274,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":41,\"altitude\":22535,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:46:19.0\"},{\"activityId\":121323338,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":19,\"odometer\":10088746,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9263,\"lon\":11.0284,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":25,\"altitude\":22751,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:47:02.0\"},{\"activityId\":121323399,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":21,\"odometer\":10088821,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9268,\"lon\":11.0289,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":46,\"altitude\":22740,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:47:18.0\"},{\"activityId\":121323403,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":15,\"odometer\":10088919,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9273,\"lon\":11.0297,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":62,\"altitude\":22767,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:47:36.0\"},{\"activityId\":121323547,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10089191,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9284,\"lon\":11.0319,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":78,\"altitude\":23086,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 06:48:38.0\"},{\"activityId\":121323858,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":21,\"odometer\":10089500,\"idle\":0,\"isGPSValid\":true,\"lat\":7.929,\"lon\":11.0346,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":76,\"altitude\":23217,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:49:38.0\"},{\"activityId\":121323863,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":14,\"odometer\":10089565,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9293,\"lon\":11.0351,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":39,\"altitude\":23226,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:49:54.0\"},{\"activityId\":121323871,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10089631,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9297,\"lon\":11.0354,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":12,\"altitude\":23367,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:50:10.0\"},{\"activityId\":121323935,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10089673,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9301,\"lon\":11.0354,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":354,\"altitude\":23648,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:50:27.0\"},{\"activityId\":121323939,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":12,\"odometer\":10089729,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9306,\"lon\":11.0356,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":33,\"altitude\":23741,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:50:43.0\"},{\"activityId\":121323943,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10089823,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9313,\"lon\":11.0361,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":53,\"altitude\":24263,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:51:10.0\"},{\"activityId\":121323984,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10089900,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9318,\"lon\":11.0366,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":32,\"altitude\":24673,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 06:51:34.0\"},{\"activityId\":121323998,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10089943,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9321,\"lon\":11.0369,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":49,\"altitude\":24914,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 06:51:50.0\"},{\"activityId\":121324120,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10090100,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9332,\"lon\":11.0378,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":30,\"altitude\":25352,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:52:40.0\"},{\"activityId\":121324150,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10090158,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9336,\"lon\":11.0381,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":52,\"altitude\":25271,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:53:02.0\"},{\"activityId\":121324223,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10090266,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9344,\"lon\":11.0387,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":36,\"altitude\":25631,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:53:42.0\"},{\"activityId\":121324345,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":19,\"odometer\":10090519,\"idle\":0,\"isGPSValid\":true,\"lat\":7.936,\"lon\":11.0403,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":54,\"altitude\":25805,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:54:45.0\"},{\"activityId\":121324462,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":18,\"odometer\":10090627,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9367,\"lon\":11.041,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":38,\"altitude\":25769,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:55:07.0\"},{\"activityId\":121324470,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10090682,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9371,\"lon\":11.0413,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":62,\"altitude\":25677,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:55:23.0\"},{\"activityId\":121324493,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":13,\"odometer\":10090739,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9374,\"lon\":11.0417,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":46,\"altitude\":25753,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:55:41.0\"},{\"activityId\":121324551,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10090812,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9379,\"lon\":11.0422,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":27,\"altitude\":25767,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:56:05.0\"},{\"activityId\":121324593,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10090857,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9382,\"lon\":11.0425,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":53,\"altitude\":25828,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:56:21.0\"},{\"activityId\":121324693,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10090955,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9388,\"lon\":11.0431,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":36,\"altitude\":25610,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:56:53.0\"},{\"activityId\":121324781,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":16,\"odometer\":10091065,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9395,\"lon\":11.0437,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":59,\"altitude\":25426,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:57:26.0\"},{\"activityId\":121324786,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":16,\"odometer\":10091137,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9396,\"lon\":11.0443,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":106,\"altitude\":25283,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:57:42.0\"},{\"activityId\":121324834,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10091197,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9396,\"lon\":11.0449,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":84,\"altitude\":25290,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:58:00.0\"},{\"activityId\":121325194,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":19,\"odometer\":10091392,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9399,\"lon\":11.0466,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":67,\"altitude\":25263,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:58:56.0\"},{\"activityId\":121325211,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10091443,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9402,\"lon\":11.047,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":50,\"altitude\":25265,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 06:59:12.0\"},{\"activityId\":121325246,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10091698,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9416,\"lon\":11.0489,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":67,\"altitude\":24618,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:00:44.0\"},{\"activityId\":121325266,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10091774,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9419,\"lon\":11.0495,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":42,\"altitude\":24357,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:01:09.0\"},{\"activityId\":121325332,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":17,\"odometer\":10091874,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9424,\"lon\":11.0502,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":60,\"altitude\":24275,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:01:35.0\"},{\"activityId\":121325365,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":12,\"odometer\":10091919,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9427,\"lon\":11.0505,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":22,\"altitude\":24217,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:01:51.0\"},{\"activityId\":121325377,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10091966,\"idle\":0,\"isGPSValid\":true,\"lat\":7.943,\"lon\":11.0507,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":40,\"altitude\":24080,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:02:07.0\"},{\"activityId\":121325433,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10092007,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9433,\"lon\":11.0509,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":21,\"altitude\":24135,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:02:23.0\"},{\"activityId\":121325464,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10092065,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9439,\"lon\":11.051,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":5,\"altitude\":23880,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:02:40.0\"},{\"activityId\":121325512,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10092127,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9444,\"lon\":11.0511,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":28,\"altitude\":23831,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:03:05.0\"},{\"activityId\":121325570,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10092165,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9446,\"lon\":11.0514,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":49,\"altitude\":23961,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:03:22.0\"},{\"activityId\":121325646,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10092178,\"idle\":47,\"isGPSValid\":true,\"lat\":7.9447,\"lon\":11.0515,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":70,\"altitude\":23827,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:04:16.0\"},{\"activityId\":121325675,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10092223,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9449,\"lon\":11.0519,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":53,\"altitude\":23842,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:04:32.0\"},{\"activityId\":121325704,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10092267,\"idle\":0,\"isGPSValid\":true,\"lat\":7.945,\"lon\":11.0522,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":84,\"altitude\":23963,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:04:48.0\"},{\"activityId\":121325713,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10092305,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9452,\"lon\":11.0524,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":37,\"altitude\":24166,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:05:04.0\"},{\"activityId\":121325741,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10092337,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9455,\"lon\":11.0526,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":6,\"altitude\":23971,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:05:20.0\"},{\"activityId\":121325790,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":5,\"odometer\":10092399,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9461,\"lon\":11.0526,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":348,\"altitude\":23688,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:05:49.0\"},{\"activityId\":121325854,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10092449,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9465,\"lon\":11.0525,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":328,\"altitude\":23489,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:06:14.0\"},{\"activityId\":121325894,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10092481,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9467,\"lon\":11.0525,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":34,\"altitude\":23321,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Bali B\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:06:30.0\"},{\"activityId\":121325955,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10092545,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9471,\"lon\":11.0528,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":51,\"altitude\":23336,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:06:53.0\"},{\"activityId\":121326030,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10092623,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9476,\"lon\":11.0534,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":35,\"altitude\":23400,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:07:26.0\"},{\"activityId\":121326106,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":5,\"odometer\":10092687,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9481,\"lon\":11.0538,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":51,\"altitude\":23293,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:07:58.0\"},{\"activityId\":121326145,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10092717,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9481,\"lon\":11.054,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":92,\"altitude\":23365,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:08:14.0\"},{\"activityId\":121326370,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10092749,\"idle\":84,\"isGPSValid\":true,\"lat\":7.9482,\"lon\":11.0542,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":15,\"altitude\":23634,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:09:49.0\"},{\"activityId\":121326463,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10092865,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9492,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":359,\"altitude\":23052,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:10:29.0\"},{\"activityId\":121326520,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10092914,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9497,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":18,\"altitude\":22814,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:10:49.0\"},{\"activityId\":121326580,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10092987,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9503,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":0,\"altitude\":22753,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:11:21.0\"},{\"activityId\":121326761,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10093022,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9506,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":42,\"altitude\":22678,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:11:37.0\"},{\"activityId\":121326764,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10093034,\"idle\":17,\"isGPSValid\":true,\"lat\":7.9506,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":162,\"altitude\":22592,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 07:11:58.0\"},{\"activityId\":121326769,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":4,\"odometer\":10093064,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9503,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":219,\"altitude\":22699,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 07:12:14.0\"},{\"activityId\":121326775,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10093096,\"idle\":0,\"isGPSValid\":true,\"lat\":7.95,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":185,\"altitude\":22778,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:12:30.0\"},{\"activityId\":121326801,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10093166,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9494,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":203,\"altitude\":22897,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:12:59.0\"},{\"activityId\":121326845,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10093245,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9487,\"lon\":11.0543,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":184,\"altitude\":23026,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:13:28.0\"},{\"activityId\":121326881,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10093284,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9484,\"lon\":11.0542,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":208,\"altitude\":23102,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":13,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:13:44.0\"},{\"activityId\":121326910,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10093314,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9481,\"lon\":11.0542,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":191,\"altitude\":23307,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":13,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:14:00.0\"},{\"activityId\":121326954,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10093338,\"idle\":15,\"isGPSValid\":true,\"lat\":7.9481,\"lon\":11.0542,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":18,\"altitude\":23240,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":13,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:14:23.0\"},{\"activityId\":121327084,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10093538,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9499,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":1,\"altitude\":22771,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":13,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:15:40.0\"},{\"activityId\":121327120,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10093594,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9504,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":20,\"altitude\":22675,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":13,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:16:03.0\"},{\"activityId\":121327147,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":4,\"odometer\":10093626,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9506,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":103,\"altitude\":22665,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":13,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 07:16:19.0\"},{\"activityId\":121327175,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10093642,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9506,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":186,\"altitude\":22679,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 07:16:35.0\"},{\"activityId\":121327280,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10093758,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9495,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":204,\"altitude\":22759,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":13,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:17:22.0\"},{\"activityId\":121327282,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10093801,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9491,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":184,\"altitude\":22860,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:17:38.0\"},{\"activityId\":121327285,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10093852,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9487,\"lon\":11.0544,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":204,\"altitude\":23041,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:17:55.0\"},{\"activityId\":121327338,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10093893,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9484,\"lon\":11.0543,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":186,\"altitude\":23132,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:18:24.0\"},{\"activityId\":121327375,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":4,\"odometer\":10093935,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9481,\"lon\":11.0541,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":206,\"altitude\":23439,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:18:46.0\"},{\"activityId\":121328010,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":0,\"odometer\":10093944,\"idle\":297,\"isGPSValid\":true,\"lat\":7.9481,\"lon\":11.0542,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":12,\"altitude\":23675,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":13,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:23:46.0\"},{\"activityId\":121328051,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10093968,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9483,\"lon\":11.0542,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":12,\"altitude\":23592,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:24:06.0\"},{\"activityId\":121328275,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10094239,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9507,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":40,\"altitude\":22813,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:25:39.0\"},{\"activityId\":121328314,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10094279,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9503,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":186,\"altitude\":22973,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 07:25:55.0\"},{\"activityId\":121328403,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10094370,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9496,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":202,\"altitude\":22873,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":13,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:26:31.0\"},{\"activityId\":121328458,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10094414,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9492,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":182,\"altitude\":23007,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:26:47.0\"},{\"activityId\":121328480,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10094462,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9488,\"lon\":11.0544,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":199,\"altitude\":23110,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:27:03.0\"},{\"activityId\":121328538,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10094506,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9484,\"lon\":11.0542,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":215,\"altitude\":23157,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:27:22.0\"},{\"activityId\":121328614,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10094542,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9481,\"lon\":11.0541,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":237,\"altitude\":23425,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:27:40.0\"},{\"activityId\":121328664,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10094558,\"idle\":12,\"isGPSValid\":true,\"lat\":7.9481,\"lon\":11.0541,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":20,\"altitude\":23516,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:27:58.0\"},{\"activityId\":121328759,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":12,\"odometer\":10094689,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9492,\"lon\":11.0544,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":4,\"altitude\":23285,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":13,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:28:42.0\"},{\"activityId\":121328870,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10094796,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9502,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":20,\"altitude\":22925,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":13,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:29:18.0\"},{\"activityId\":121328907,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10094836,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9506,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":3,\"altitude\":22861,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 07:29:34.0\"},{\"activityId\":121328929,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10094868,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9505,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":184,\"altitude\":22840,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":13,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:29:50.0\"},{\"activityId\":121328969,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10094903,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9501,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":200,\"altitude\":22900,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:30:07.0\"},{\"activityId\":121329004,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10094945,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9498,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":176,\"altitude\":22904,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":13,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:30:23.0\"},{\"activityId\":121329052,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10094985,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9495,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":205,\"altitude\":23000,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:30:39.0\"},{\"activityId\":121329131,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10095037,\"idle\":0,\"isGPSValid\":true,\"lat\":7.949,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":185,\"altitude\":23025,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:30:57.0\"},{\"activityId\":121329186,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10095087,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9486,\"lon\":11.0543,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":206,\"altitude\":23223,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:31:13.0\"},{\"activityId\":121329211,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10095128,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9482,\"lon\":11.0542,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":190,\"altitude\":23352,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:31:30.0\"},{\"activityId\":121329263,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10095157,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9482,\"lon\":11.0541,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":21,\"altitude\":23444,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:31:45.0\"},{\"activityId\":121329357,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10095256,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9491,\"lon\":11.0544,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":2,\"altitude\":23219,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:32:20.0\"},{\"activityId\":121329379,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10095303,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9495,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":20,\"altitude\":23071,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 07:32:36.0\"},{\"activityId\":121329495,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10095419,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9505,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":3,\"altitude\":22782,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:33:21.0\"},{\"activityId\":121329557,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10095455,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9505,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":186,\"altitude\":22825,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 07:33:37.0\"},{\"activityId\":121329704,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10095569,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9496,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":202,\"altitude\":23011,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 07:34:46.0\"},{\"activityId\":121329758,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":12,\"odometer\":10095614,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9492,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":184,\"altitude\":23075,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:35:03.0\"},{\"activityId\":121329792,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10095680,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9486,\"lon\":11.0544,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":207,\"altitude\":23309,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:35:23.0\"},{\"activityId\":121329843,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":5,\"odometer\":10095719,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9483,\"lon\":11.0542,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":269,\"altitude\":23521,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:35:39.0\"},{\"activityId\":121329890,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10095758,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9486,\"lon\":11.0543,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":13,\"altitude\":23369,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:35:55.0\"},{\"activityId\":121330104,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10095989,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9506,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":41,\"altitude\":22893,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 07:37:24.0\"},{\"activityId\":121330137,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10096022,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9504,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":193,\"altitude\":22895,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:37:40.0\"},{\"activityId\":121330168,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10096065,\"idle\":0,\"isGPSValid\":true,\"lat\":7.95,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":176,\"altitude\":22999,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:37:57.0\"},{\"activityId\":121330224,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10096107,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9497,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":192,\"altitude\":22993,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 07:38:13.0\"},{\"activityId\":121330320,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10096232,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9485,\"lon\":11.0544,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":210,\"altitude\":23358,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:38:59.0\"},{\"activityId\":121330334,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":5,\"odometer\":10096267,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9483,\"lon\":11.0542,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":263,\"altitude\":23430,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:39:15.0\"},{\"activityId\":121330368,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10096277,\"idle\":13,\"isGPSValid\":true,\"lat\":7.9484,\"lon\":11.0542,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":9,\"altitude\":23567,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:39:32.0\"},{\"activityId\":121330460,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":5,\"odometer\":10096364,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9491,\"lon\":11.0544,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":31,\"altitude\":23249,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:40:10.0\"},{\"activityId\":121330485,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10096396,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9489,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":184,\"altitude\":23315,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:40:26.0\"},{\"activityId\":121330503,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10096428,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9486,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":212,\"altitude\":23416,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:40:42.0\"},{\"activityId\":121330538,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10096461,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9486,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":15,\"altitude\":23401,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:40:58.0\"},{\"activityId\":121330755,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10096717,\"idle\":23,\"isGPSValid\":true,\"lat\":7.9506,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":188,\"altitude\":22751,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:42:59.0\"},{\"activityId\":121330891,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10096892,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9491,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":205,\"altitude\":23238,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:44:13.0\"},{\"activityId\":121330922,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10096937,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9487,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":184,\"altitude\":23390,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:44:30.0\"},{\"activityId\":121330953,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":0,\"odometer\":10096967,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9485,\"lon\":11.0544,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":349,\"altitude\":23479,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:44:46.0\"},{\"activityId\":121330967,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10096982,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9486,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":16,\"altitude\":23517,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:45:02.0\"},{\"activityId\":121331188,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10097209,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9506,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":359,\"altitude\":22832,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 07:46:40.0\"},{\"activityId\":121331247,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10097229,\"idle\":8,\"isGPSValid\":true,\"lat\":7.9507,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":157,\"altitude\":22739,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:46:57.0\"},{\"activityId\":121331325,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10097262,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9504,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":192,\"altitude\":22759,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:47:13.0\"},{\"activityId\":121331434,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10097369,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9495,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":176,\"altitude\":23131,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:47:57.0\"},{\"activityId\":121331486,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10097406,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9491,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":208,\"altitude\":23277,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:48:13.0\"},{\"activityId\":121331554,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10097451,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9487,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":191,\"altitude\":23253,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:48:32.0\"},{\"activityId\":121331590,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10097489,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9486,\"lon\":11.0544,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":12,\"altitude\":23364,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:48:48.0\"},{\"activityId\":121331855,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10097730,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9507,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":33,\"altitude\":22862,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 07:50:24.0\"},{\"activityId\":121331885,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10097766,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9504,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":198,\"altitude\":22791,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 07:50:40.0\"},{\"activityId\":121331932,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10097809,\"idle\":0,\"isGPSValid\":true,\"lat\":7.95,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":177,\"altitude\":22866,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:50:57.0\"},{\"activityId\":121331994,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10097850,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9497,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":201,\"altitude\":23009,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:51:14.0\"},{\"activityId\":121332030,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":4,\"odometer\":10097873,\"idle\":7,\"isGPSValid\":true,\"lat\":7.9496,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":14,\"altitude\":23001,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:51:31.0\"},{\"activityId\":121332097,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10097889,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9495,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":189,\"altitude\":23222,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 07:51:47.0\"},{\"activityId\":121332137,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":12,\"odometer\":10097956,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9488,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":207,\"altitude\":23320,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:52:16.0\"},{\"activityId\":121332171,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10097990,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9486,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":230,\"altitude\":23323,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:52:33.0\"},{\"activityId\":121332239,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10098025,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9487,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":21,\"altitude\":23388,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:52:49.0\"},{\"activityId\":121332278,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10098080,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9492,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":3,\"altitude\":23258,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:53:10.0\"},{\"activityId\":121332466,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10098251,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9507,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":23,\"altitude\":22782,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 07:54:18.0\"},{\"activityId\":121332493,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10098285,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9504,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":196,\"altitude\":22817,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 07:54:34.0\"},{\"activityId\":121332544,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10098340,\"idle\":3,\"isGPSValid\":true,\"lat\":7.95,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":170,\"altitude\":23042,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 07:54:57.0\"},{\"activityId\":121332579,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10098379,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9496,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":191,\"altitude\":23031,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:55:13.0\"},{\"activityId\":121332654,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10098452,\"idle\":0,\"isGPSValid\":true,\"lat\":7.949,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":214,\"altitude\":23117,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:55:42.0\"},{\"activityId\":121332683,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10098467,\"idle\":15,\"isGPSValid\":true,\"lat\":7.9489,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":177,\"altitude\":23126,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:56:02.0\"},{\"activityId\":121332722,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10098508,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9486,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":226,\"altitude\":23167,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:56:18.0\"},{\"activityId\":121332758,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10098542,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9486,\"lon\":11.0544,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":30,\"altitude\":23152,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:56:34.0\"},{\"activityId\":121332808,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10098587,\"idle\":0,\"isGPSValid\":true,\"lat\":7.949,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":9,\"altitude\":23104,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:56:50.0\"},{\"activityId\":121332841,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10098613,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9492,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":8,\"altitude\":23106,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:57:01.0\"},{\"activityId\":121333066,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10098779,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9507,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":30,\"altitude\":22701,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 07:58:06.0\"},{\"activityId\":121333113,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10098815,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9505,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":183,\"altitude\":22907,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:58:22.0\"},{\"activityId\":121333177,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":5,\"odometer\":10098880,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9499,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":205,\"altitude\":22958,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:58:50.0\"},{\"activityId\":121333247,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":4,\"odometer\":10098916,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9496,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":186,\"altitude\":22902,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 07:59:08.0\"},{\"activityId\":121333299,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10098994,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9489,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":216,\"altitude\":23365,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 07:59:41.0\"},{\"activityId\":121333415,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10099030,\"idle\":18,\"isGPSValid\":true,\"lat\":7.9486,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":238,\"altitude\":23289,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:00:13.0\"},{\"activityId\":121333450,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10099061,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9486,\"lon\":11.0544,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":24,\"altitude\":23386,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:00:29.0\"},{\"activityId\":121333486,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10099103,\"idle\":0,\"isGPSValid\":true,\"lat\":7.949,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":1,\"altitude\":23176,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:00:47.0\"},{\"activityId\":121333535,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10099163,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9495,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":17,\"altitude\":23017,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:01:12.0\"},{\"activityId\":121333633,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10099288,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9506,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":353,\"altitude\":22777,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:02:02.0\"},{\"activityId\":121333679,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10099321,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9506,\"lon\":11.055,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":189,\"altitude\":22847,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:02:18.0\"},{\"activityId\":121333733,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10099399,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9498,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":207,\"altitude\":23108,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:02:50.0\"},{\"activityId\":121333760,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10099442,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9495,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":191,\"altitude\":23333,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:03:07.0\"},{\"activityId\":121333790,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10099489,\"idle\":0,\"isGPSValid\":true,\"lat\":7.949,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":170,\"altitude\":23257,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:03:28.0\"},{\"activityId\":121333834,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10099536,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9486,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":191,\"altitude\":23400,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":8,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:03:45.0\"},{\"activityId\":121333861,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10099558,\"idle\":18,\"isGPSValid\":true,\"lat\":7.9485,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":259,\"altitude\":23494,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:04:13.0\"},{\"activityId\":121333897,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10099592,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9487,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":15,\"altitude\":23348,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:04:29.0\"},{\"activityId\":121333930,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10099640,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9492,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":358,\"altitude\":23125,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:04:47.0\"},{\"activityId\":121333962,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10099675,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9495,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":20,\"altitude\":22902,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:05:04.0\"},{\"activityId\":121333989,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10099723,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9499,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":2,\"altitude\":22822,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:05:23.0\"},{\"activityId\":121334030,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10099780,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9504,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":18,\"altitude\":22632,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:05:44.0\"},{\"activityId\":121334086,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10099815,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9507,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":111,\"altitude\":22576,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:06:00.0\"},{\"activityId\":121334136,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10099855,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9503,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":191,\"altitude\":22733,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:06:16.0\"},{\"activityId\":121334196,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10099932,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9497,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":207,\"altitude\":23073,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:06:47.0\"},{\"activityId\":121334223,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10099971,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9494,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":186,\"altitude\":23146,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":8,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:07:03.0\"},{\"activityId\":121334283,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10100030,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9488,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":209,\"altitude\":23352,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":8,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:07:29.0\"},{\"activityId\":121334300,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10100065,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9486,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":243,\"altitude\":23660,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:07:45.0\"},{\"activityId\":121334333,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10100101,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9487,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":16,\"altitude\":23479,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:08:01.0\"},{\"activityId\":121334384,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10100171,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9494,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":357,\"altitude\":23173,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:08:28.0\"},{\"activityId\":121334396,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10100209,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9497,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":21,\"altitude\":23019,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:08:44.0\"},{\"activityId\":121334428,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10100250,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9501,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":4,\"altitude\":22928,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:09:00.0\"},{\"activityId\":121334468,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10100319,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9507,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":33,\"altitude\":22699,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:09:32.0\"},{\"activityId\":121334489,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10100355,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9505,\"lon\":11.055,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":189,\"altitude\":22709,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:09:48.0\"},{\"activityId\":121334557,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10100452,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9497,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":207,\"altitude\":23084,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:10:24.0\"},{\"activityId\":121334589,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10100492,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9494,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":185,\"altitude\":23083,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:10:40.0\"},{\"activityId\":121334634,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10100560,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9488,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":201,\"altitude\":23149,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:11:08.0\"},{\"activityId\":121334662,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10100592,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9486,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":297,\"altitude\":23404,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:11:24.0\"},{\"activityId\":121334693,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10100628,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9488,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":19,\"altitude\":23299,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:11:40.0\"},{\"activityId\":121334827,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10100695,\"idle\":38,\"isGPSValid\":true,\"lat\":7.9494,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":354,\"altitude\":23177,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:12:43.0\"},{\"activityId\":121334886,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":4,\"odometer\":10100720,\"idle\":10,\"isGPSValid\":true,\"lat\":7.9495,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":269,\"altitude\":22961,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:13:04.0\"},{\"activityId\":121334915,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10100742,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9493,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":178,\"altitude\":23020,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:13:20.0\"},{\"activityId\":121334970,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10100790,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9489,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":197,\"altitude\":23010,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:13:41.0\"},{\"activityId\":121335026,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10100811,\"idle\":16,\"isGPSValid\":true,\"lat\":7.9489,\"lon\":11.0545,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":358,\"altitude\":23251,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:14:05.0\"},{\"activityId\":121335071,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10100859,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9493,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":14,\"altitude\":22953,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:14:28.0\"},{\"activityId\":121335090,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":5,\"odometer\":10100881,\"idle\":9,\"isGPSValid\":true,\"lat\":7.9494,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":175,\"altitude\":22966,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:14:46.0\"},{\"activityId\":121335126,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10100900,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9493,\"lon\":11.0546,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":21,\"altitude\":22933,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:15:01.0\"},{\"activityId\":121335219,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10100987,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9501,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":4,\"altitude\":22782,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:15:47.0\"},{\"activityId\":121335268,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10101028,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9505,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":24,\"altitude\":22555,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:16:04.0\"},{\"activityId\":121335300,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10101060,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9507,\"lon\":11.055,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":146,\"altitude\":22521,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:16:20.0\"},{\"activityId\":121335338,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10101102,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9503,\"lon\":11.055,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":185,\"altitude\":22654,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:16:36.0\"},{\"activityId\":121335448,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10101185,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9496,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":202,\"altitude\":23165,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:17:10.0\"},{\"activityId\":121335557,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10101240,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9491,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":186,\"altitude\":23416,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:17:32.0\"},{\"activityId\":121335560,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10101293,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9487,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":203,\"altitude\":23546,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:17:54.0\"},{\"activityId\":121335652,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10101314,\"idle\":42,\"isGPSValid\":true,\"lat\":7.9487,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":8,\"altitude\":23502,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:18:41.0\"},{\"activityId\":121335768,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10101541,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9507,\"lon\":11.055,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":29,\"altitude\":22595,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:20:19.0\"},{\"activityId\":121335795,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10101555,\"idle\":17,\"isGPSValid\":true,\"lat\":7.9506,\"lon\":11.0551,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":176,\"altitude\":22550,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:20:41.0\"},{\"activityId\":121335815,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10101598,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9503,\"lon\":11.055,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":192,\"altitude\":22639,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:20:59.0\"},{\"activityId\":121335925,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10101770,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9488,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":208,\"altitude\":23237,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":7,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:22:08.0\"},{\"activityId\":121335940,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":5,\"odometer\":10101803,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9487,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":24,\"altitude\":23395,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:22:24.0\"},{\"activityId\":121335979,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10101835,\"idle\":15,\"isGPSValid\":true,\"lat\":7.949,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":0,\"altitude\":23104,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":8,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:22:52.0\"},{\"activityId\":121336026,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10101892,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9495,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":18,\"altitude\":22939,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:23:18.0\"},{\"activityId\":121336057,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10101946,\"idle\":0,\"isGPSValid\":true,\"lat\":7.95,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":353,\"altitude\":22733,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:23:41.0\"},{\"activityId\":121336069,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10101989,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9503,\"lon\":11.055,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":19,\"altitude\":22673,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:23:57.0\"},{\"activityId\":121336089,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10102029,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9507,\"lon\":11.055,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":46,\"altitude\":22685,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:24:14.0\"},{\"activityId\":121336106,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10102065,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9504,\"lon\":11.055,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":204,\"altitude\":23013,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:24:30.0\"},{\"activityId\":121336124,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10102098,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9501,\"lon\":11.055,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":182,\"altitude\":23054,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:24:46.0\"},{\"activityId\":121336156,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10102150,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9497,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":203,\"altitude\":23287,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:25:08.0\"},{\"activityId\":121336174,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10102190,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9493,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":186,\"altitude\":23519,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:25:26.0\"},{\"activityId\":121336203,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10102257,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9487,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":214,\"altitude\":23739,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:25:53.0\"},{\"activityId\":121336289,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10102279,\"idle\":13,\"isGPSValid\":true,\"lat\":7.9487,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":10,\"altitude\":23901,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:26:15.0\"},{\"activityId\":121336335,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10102384,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9496,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":26,\"altitude\":23077,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:27:04.0\"},{\"activityId\":121336379,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10102433,\"idle\":13,\"isGPSValid\":true,\"lat\":7.9499,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":9,\"altitude\":22646,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:27:33.0\"},{\"activityId\":121336435,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10102517,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9507,\"lon\":11.055,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":39,\"altitude\":22392,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:28:04.0\"},{\"activityId\":121336461,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10102556,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9504,\"lon\":11.055,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":189,\"altitude\":22653,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:28:20.0\"},{\"activityId\":121336554,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10102668,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9494,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":205,\"altitude\":23554,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:29:08.0\"},{\"activityId\":121336576,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":4,\"odometer\":10102703,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9491,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":189,\"altitude\":23875,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:29:24.0\"},{\"activityId\":121336609,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10102745,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9487,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":205,\"altitude\":23903,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:29:41.0\"},{\"activityId\":121336636,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10102778,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9489,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":17,\"altitude\":23700,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:29:57.0\"},{\"activityId\":121336670,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10102838,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9494,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":358,\"altitude\":23082,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:30:24.0\"},{\"activityId\":121336705,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10102871,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9497,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":20,\"altitude\":23059,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:30:40.0\"},{\"activityId\":121336761,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10102926,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9502,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":4,\"altitude\":22533,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:31:06.0\"},{\"activityId\":121336807,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10102975,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9507,\"lon\":11.055,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":27,\"altitude\":22400,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:31:29.0\"},{\"activityId\":121336847,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10102991,\"idle\":21,\"isGPSValid\":true,\"lat\":7.9506,\"lon\":11.055,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":182,\"altitude\":22560,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:31:55.0\"},{\"activityId\":121336898,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10103060,\"idle\":0,\"isGPSValid\":true,\"lat\":7.95,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":199,\"altitude\":23129,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:32:26.0\"},{\"activityId\":121336935,\"eventCode\":\"12\",\"eventName\":\"Journey End\",\"speed\":0,\"odometer\":10103085,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9498,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":190,\"altitude\":23304,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:32:47.0\"},{\"activityId\":121336964,\"eventCode\":\"11\",\"eventName\":\"Journey Start\",\"speed\":0,\"odometer\":10103085,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9498,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":190,\"altitude\":23479,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:32:57.0\"},{\"activityId\":121336998,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10103129,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9494,\"lon\":11.0548,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":175,\"altitude\":23347,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:33:23.0\"},{\"activityId\":121337011,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10103165,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9491,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":192,\"altitude\":23380,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:33:39.0\"},{\"activityId\":121337046,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":5,\"odometer\":10103185,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9491,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":11,\"altitude\":23501,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":9,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:33:55.0\"},{\"activityId\":121337064,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10103203,\"idle\":8,\"isGPSValid\":true,\"lat\":7.9491,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":189,\"altitude\":23575,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:34:11.0\"},{\"activityId\":121337104,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10103244,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9488,\"lon\":11.0547,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":159,\"altitude\":23776,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:34:30.0\"},{\"activityId\":121337122,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10103282,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9489,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":8,\"altitude\":23592,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:34:46.0\"},{\"activityId\":121337261,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":12,\"odometer\":10103500,\"idle\":23,\"isGPSValid\":true,\"lat\":7.9506,\"lon\":11.0551,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":188,\"altitude\":22759,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:36:31.0\"},{\"activityId\":121337326,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":5,\"odometer\":10103593,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9498,\"lon\":11.055,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":204,\"altitude\":23238,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:37:06.0\"},{\"activityId\":121337364,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10103653,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9493,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":188,\"altitude\":23493,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:37:27.0\"},{\"activityId\":121337393,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10103710,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9488,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":208,\"altitude\":23892,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":12,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:37:50.0\"},{\"activityId\":121337829,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":6,\"odometer\":10103909,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9507,\"lon\":11.0551,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":50,\"altitude\":22472,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:42:10.0\"},{\"activityId\":121337849,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10103953,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9503,\"lon\":11.0551,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":200,\"altitude\":22721,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:42:26.0\"},{\"activityId\":121337881,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":11,\"odometer\":10104004,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9499,\"lon\":11.0551,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":180,\"altitude\":22959,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:42:43.0\"},{\"activityId\":121337916,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10104053,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9494,\"lon\":11.055,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":198,\"altitude\":23264,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:43:00.0\"},{\"activityId\":121337965,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":5,\"odometer\":10104088,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9491,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":177,\"altitude\":23492,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:43:17.0\"},{\"activityId\":121337982,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":9,\"odometer\":10104123,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9488,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":201,\"altitude\":23555,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"\",\"town\":\"Maihula\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:43:33.0\"},{\"activityId\":121338009,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":7,\"odometer\":10104161,\"idle\":0,\"isGPSValid\":true,\"lat\":7.949,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":23,\"altitude\":23315,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:43:49.0\"},{\"activityId\":121338047,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":8,\"odometer\":10104212,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9495,\"lon\":11.0549,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":1,\"altitude\":23007,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":11,\"street\":\"Unnamed Road\",\"town\":\"\",\"county\":\"TR\",\"country\":\"Nigeria\",\"activityUTCDate\":\"2019-04-16 08:44:10.0\"},{\"activityId\":121338143,\"eventCode\":\"00\",\"eventName\":\"Normal\",\"speed\":10,\"odometer\":10104341,\"idle\":0,\"isGPSValid\":true,\"lat\":7.9506,\"lon\":11.0551,\"directionEW\":\"E\",\"directionNS\":\"N\",\"headingDegree\":19,\"altitude\":22543,\"ignitionStatus\":\"On\",\"batteryVoltage\":0,\"satelliteNumber\":10,\"street\":\"\",\"town\":\"\",\"county\":\"\",\"country\":\"\",\"activityUTCDate\":\"2019-04-16 08:44:58.0\"}],\"message\":\"\"} \n\n*/\n\n\n" }, "UpdateAerisTractorsActivityOnPostFromAWSBackend" : { "code" : "function onRequest(request, response, modules) {\n var tractorId = request.body.tractor_id;\n var DailyTractorActivity = modules.collectionAccess.collection('DailyTractorActivity');\n var Tractor = modules.collectionAccess.collection('TractorDetail');\n if( tractorId ) {\n var postedTractorActivity= request.body;\n\n var tractorActivityData = {};\n tractorActivityData.day = postedTractorActivity.day;\n tractorActivityData.TotalTimeActive = postedTractorActivity.total_active_time;\n tractorActivityData.TotalTimeIdle = postedTractorActivity.total_inactive_time;\n tractorActivityData.LastJourneyStartTime = postedTractorActivity.last_journey_start_time;\n tractorActivityData.TotalSpeed = postedTractorActivity.total_speed;\n tractorActivityData.TotalSpeedCounter = postedTractorActivity.total_speed_counter;\n tractorActivityData.AverageSpeed = postedTractorActivity.average_speed;\n tractorActivityData.StartActiveData = postedTractorActivity.start_active_date;\n tractorActivityData.LastActiveData = postedTractorActivity.last_active_date;\n tractorActivityData.Country = postedTractorActivity.country;\n tractorActivityData.Town = postedTractorActivity.town;\n tractorActivityData.Street = postedTractorActivity.street;\n tractorActivityData.StartCountry = postedTractorActivity.start_country;\n tractorActivityData.StartTown = postedTractorActivity.start_town;\n tractorActivityData.StartStreet = postedTractorActivity.start_street;\n tractorActivityData.Route = postedTractorActivity.route;\n tractorActivityData.OperatorID = postedTractorActivity.operator_id;\n tractorActivityData.IgnitionStatus = postedTractorActivity.ignition_status;\n tractorActivityData.Latitude = postedTractorActivity.latitude ? postedTractorActivity.latitude : 0;\n tractorActivityData.Longitude = postedTractorActivity.longitude ? postedTractorActivity.longitude : 0;\n tractorActivityData.RevenueType = postedTractorActivity.revenue_type;\n tractorActivityData.RevenueCurrency = postedTractorActivity.revenue_currency;\n tractorActivityData.HectaresServiced = postedTractorActivity.hectares;\n tractorActivityData.DistanceCovered = postedTractorActivity.total_distance;\n\n var tractorUpdateData = {};\n tractorUpdateData.ActiveTimeToday = postedTractorActivity.total_active_time + postedTractorActivity.total_inactive_time;\n\n\t\t\tvar kinveyMetaData = modules.kinvey.entity();\n tractorActivityData._acl = kinveyMetaData._acl;\n tractorActivityData._kmd = kinveyMetaData._kmd;\n \n DailyTractorActivity.update(\n {\"TractorID\": tractorId, \"day\":postedTractorActivity.day},\n {$set:tractorActivityData}, {\"upsert\":true},\n function(err, updated) {\n if( ! err ){\n modules.logger.info('updated tractor activity for tractor with id of ' + tractorId);\n// \t\t\tmodules.logger.info( \"total active time is \" + tractorUpdateData.ActiveTimeToday );\n\n Tractor.update({\"TractorID\": +tractorId}, {$set: tractorUpdateData }, function(err, updatedTractor){\n if( ! err ){\n modules.logger.info('updated tractor detail for tractor with id of ' + tractorId);\n response.body = {service:'aeris tractor activity service'};\n response.complete();\n }\n else {\n modules.logger.info(\"there was an error updating tractor details \" + tractorId );\n response.body = {service:'aeris tractor activity service'};\n response.complete();\n }\n });\n }\n else {\n \tmodules.logger.info(\"there was an error updating tractor activity detail\" + tractorId );\n response.body = {service:'aeris tractor activity service failed to update'};\n response.complete();\n }\n });\n }\n \n \telse {\n modules.logger.info('no tractor id sent');\n response.complete();\n }\n\n\n // Posted data sample\n\n /*{\"id\":157,\"k_id\":null,\"tractor_id\":\"500507\",\"day\":\"2019-04-14\",\"total_active_time\":2806,\"total_moving_time\":2806,\n \"total_inactive_time\":7259,\"total_distance\":6.47,\"last_journey_start_time\":\"2019-04-14T13:55:27.000Z\",\"total_speed\":0,\n \"total_speed_counter\":0,\"average_speed\":0,\"start_active_date\":\"2019-04-14T13:36:22.000Z\",\"last_active_date\":\"2019-04-14 16:43:12\",\n \"country\":\"\",\"town\":\"\",\"street\":\"\",\"start_country\":\"\",\"start_town\":\"\",\"start_street\":\"\",\n \"route\":null,\"operator_id\":null,\"revenue_type\":\"\",\"revenue_currency\":\"\",\"hectares\":0,\"ignition_status\":null,\n \"trips\":null,\"trip_start_end_datetime\":null,\"created_at\":\"2019-04-14 14:46:31\",\"updated_at\":\"2019-04-14 14:57:23\"}\n */\n\n}\n" }, "UpdateAerisTractorsOnPOSTFromAWSBACKEND" : { "code" : "function onRequest(request, response, modules) {\n var TractorDetail = modules.collectionAccess.collection('TractorDetail');\n var tractor_id = Number(request.body.tracker_id);\n var updateData = request.body;\n var tractorUpdateData = {};\n \n if( tractor_id ){\n \n var statusData = JSON.parse(updateData.status_from_2track);\n \n if( updateData.latitude && updateData.longitude ){\n tractorUpdateData.PositionLatitude = updateData.latitude;\n \t\t tractorUpdateData.PositionLongitude = updateData.longitude;\n }\n \n tractorUpdateData.LastActiveTime = updateData.last_reported_time;\n tractorUpdateData.FuelRawValue = statusData.fuelRawValue;\n tractorUpdateData.IgnitionStatus = statusData.ignitionStatus;\n tractorUpdateData.AssetState = statusData.assetState;\n// tractorUpdateData.Status = statusData.ignitionStatus === \"On\" ? 1 : 0;\n tractorUpdateData.Speed = statusData.speed;\n tractorUpdateData.Heading = statusData.heading;\n tractorUpdateData.FuelLevelVoltage = statusData.fuelLevelVoltage;\n tractorUpdateData.EngineHours = updateData.total_engine_hours ? Math.ceil((updateData.total_engine_hours)/3600) : 0;\n// tractorUpdateData.FixedOdometerReading = updateData.total_distance_covered ? updateData.total_distance_covered: 0;\n tractorUpdateData.TotalDistanceCovered = updateData.total_distance_covered ? updateData.total_distance_covered: 0;\n\n// tractorUpdateData.OperatorID = statusData.operator_id;\n tractorUpdateData.TotalHectaresTilled+= updateData.hectares;\n tractorUpdateData.UpdatedAt = updateData.updated_at; //modules.moment.utc().format('YYYY-MM-DD HH:mm:ss');\n tractorUpdateData._acl.lmt = new Date();\n \n // update the tractor detail\n TractorDetail.update({\"TractorID\":tractor_id}, {$set:tractorUpdateData},{\"multi\":true}, function(err, updatedTractor){\n if( !err ){\n \tmodules.logger.info('updated tractor detail having TractorID of ' + tractor_id );\n response.body = {service: 'aeris tractor detail service'}\n \t\t\tresponse.complete();\n }\n else {\n modules.logger.info('errors updating ' + err );\n response.body = {service: 'aeris tractor detail service'}\n response.complete();\n\n }\n \t\t\t })\n\n }\n else { \n modules.logger.info('exiting , data posted without tractor id ' + JSON.stringify(updateData));\n response.complete();\n }\n\n \n //Sample posted data \n\n //[2019-04-14 16:13:03] local.INFO: {\"id\":7,\"kinvey_creator_id\":null,\"tractor_owner_id\":null,\"tracker_id\":\"500502\",\"name\":\"TRAXI MH6005(RSH 579 ZA)\",\"attachments\":null,\"latitude\":9.897339,\"longitude\":10.983771,\"operator_id\":null,\"status\":null,\"speed\":0.08,\"total_hectares_serviced\":null,\"data\":null,\"is_deleted\":null,\"k_id\":null,\"receive_daily_updates\":null,\"receive_sms_booking_pairing\":null,\"user_id\":null,\"kinvey_operator_id\":null,\"status_from_2track\":\"{\\\"assetUid\\\":\\\"95e1c2a6-e202-44c8-8a4b-037801801194\\\",\\\"creationTime\\\":1515104866638,\\\"lastModifiedTime\\\":1515179131685,\\\"name\\\":\\\"TRAXI MH6005(RSH 579 ZA)\\\",\\\"vin\\\":\\\"500502\\\",\\\"assetId\\\":\\\"500502\\\",\\\"deviceId\\\":\\\"1333111468\\\",\\\"licensePlate\\\":\\\"RSH 579 ZA\\\",\\\"sequenceNumber\\\":1106,\\\"updateTime\\\":1554699641,\\\"timeOfFix\\\":1554699641,\\\"latitude\\\":9.897339,\\\"longitude\\\":10.983771,\\\"altitude\\\":39560,\\\"speed\\\":0.08,\\\"heading\\\":0,\\\"satellites\\\":6,\\\"fixStatus\\\":0,\\\"hdop\\\":22,\\\"carrier\\\":0,\\\"rssi\\\":-89,\\\"inputs\\\":0,\\\"eventType\\\":15,\\\"devicePowerVoltage\\\":null,\\\"assetState\\\":\\\"Off\\\",\\\"altitude_NEW\\\":3956,\\\"correlationId\\\":\\\"1106\\\",\\\"deviceBatteryVoltage\\\":4170,\\\"fuelLevelVoltage\\\":0,\\\"fuelRawValue\\\":267387135,\\\"gpsSpeed\\\":2880,\\\"heading_NEW\\\":0,\\\"ignitionStatus\\\":0,\\\"latitude_NEW\\\":9897339,\\\"locationTimestamp\\\":1554699641000,\\\"locationValidity\\\":0,\\\"longitude_NEW\\\":10983771,\\\"mobileIdentificationNumber\\\":\\\"1333111468\\\",\\\"timestamp\\\":1554699641000,\\\"vehicleBatteryVoltage\\\":0,\\\"vehicleStatusReason\\\":15,\\\"accountId\\\":\\\"100041\\\",\\\"accountName\\\":\\\"HelloTractorTestFleet\\\",\\\"deviceId2\\\":null,\\\"placeId\\\":null,\\\"tagIds\\\":[],\\\"makeModelId\\\":null,\\\"make\\\":null,\\\"model\\\":null,\\\"year\\\":null,\\\"initialDistance\\\":0,\\\"distanceUnit\\\":null,\\\"initialOperationalTime\\\":null,\\\"operationalTimeUnit\\\":null,\\\"dateOfBirth\\\":null,\\\"assetType\\\":null,\\\"customAttributes\\\":[],\\\"placeUid\\\":null,\\\"dataHex\\\":\\\"830513331114680101010204525caad5795caad57905e636ce068bfd9400009a8b00000008000006000014ffa72f1630003e0f1000003267910000000000000000000000000ff000ff0ff000ff0000000000000000000000000000000000000000000100020000000000000000000000000000104a\\\"}\",\"tractor_model_id\":null,\"last_reported_time\":\"2019-04-08 05:00:41\",\"group_id\":null,\"address\":null,\"created_at\":\"2019-04-10 12:18:25\",\"updated_at\":\"2019-04-14 16:13:03\"} \n\n}" }, "UpdateTwoTrackTractorsStatusOnPOSTFromAWSBACKEND" : { "code" : "function onRequest(request, response, modules) {\n var TractorDetail = modules.collectionAccess.collection('TractorDetail');\n var updateDataArr = request.body.data;\n modules.logger.info(\"Tractors status posted \" + JSON.stringify(updateDataArr));\n\n var tractorStatusData = {};\n var queueCount = 0; \n if( updateDataArr.length ){\n var trackerId;\n \tfor(var i=0; i<updateDataArr.length; i++){\n \n var updateData = updateDataArr[i];\n trackerId = +updateData.trackerId;\n \n tractorStatusData.LastActiveTime = updateData.lastReportUTCDate;\n \ttractorStatusData.Speed = updateData.speed;\n \ttractorStatusData.LastOdometerValue = updateData.odometer;\n \ttractorStatusData.PositionLatitude = updateData.lat;\n tractorStatusData.PositionLongitude = updateData.lon;\n \ttractorStatusData.Street = updateData.street;\n tractorStatusData.Country = updateData.country;\n tractorStatusData.Town = updateData.town;\n tractorStatusData.UpdatedAt = modules.moment().format(\"YYYY-MM-DD HH:mm:ss\");\n\t\t\ttractorStatusData.IgnitionStatus = updateData.ignitionStatus;\n \ttractorStatusData.Status = updateData.ignitionStatus == \"On\" ? 1 : 0;\n tractorStatusData.TrackerID = trackerId;\n tractorStatusData.ServiceProvider = \"2TRACK\";\n\n // Run the update \n TractorDetail.update({\"TractorID\":trackerId}, {$set:tractorStatusData}, function(err, updatedTractor){\n if( ! err ){\n modules.logger.info(\"updated tractor detail for tractor with ID of \" + tractorStatusData.TrackerID );\n queueCount++;\n if( queueCount === updateDataArr.length ){\n response.body = {service: 'twotrack tractor detail update status'}\n response.complete();\n }\n }\n else {\n modules.logger.info(\"Error occured \");\n queueCount++;\n\t\t\t\t\tif( queueCount === updateDataArr.length ){\n response.body = {service: 'twotrack tractor detail update status'}\n response.complete();\n }\n }\n });\n \t\t}\n } else {\n \t\tmodules.logger.info('exiting');\n \t\treturn response.complete();\n }\n \n \n // Sample posted data \n /* \n \n { \n \"returnCode\":\"200\",\n \"isSuccess\":true,\n \"data\":[ \n { \n \"trackerId\":\"100001\",\n \"speed\":0,\n \"odometer\":0,\n \"isGPSValid\":false,\n \"lat\":0,\n \"lon\":0,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":0,\n \"altitude\":0,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":-1,\n \"satelliteNumber\":0,\n \"street\":\"\",\n \"town\":\"\",\n \"county\":\"\",\n \"country\":\"\",\n \"lastReportUTCDate\":\"1900-01-01 00:00:00.0\"\n },\n { \n \"trackerId\":\"100002\",\n \"speed\":0,\n \"odometer\":9138086,\n \"isGPSValid\":false,\n \"lat\":6.0854,\n \"lon\":0.1011,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":198,\n \"altitude\":5752,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"Akuse Rd\",\n \"town\":\"\",\n \"county\":\"Eastern Region\",\n \"country\":\"Ghana\",\n \"lastReportUTCDate\":\"2019-04-14 17:04:38.0\"\n },\n { \n \"trackerId\":\"100003\",\n \"speed\":0,\n \"odometer\":183069,\n \"isGPSValid\":false,\n \"lat\":7.7928,\n \"lon\":8.8779,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":209,\n \"altitude\":9433,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"BN\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2017-07-17 22:11:51.0\"\n },\n { \n \"trackerId\":\"100004\",\n \"speed\":0,\n \"odometer\":1252,\n \"isGPSValid\":false,\n \"lat\":8.9207,\n \"lon\":7.2557,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":159,\n \"altitude\":31079,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":9,\n \"street\":\"Unnamed Road\",\n \"town\":\"Kuje\",\n \"county\":\"Nasarawa\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2016-06-25 12:31:58.0\"\n },\n { \n \"trackerId\":\"100005\",\n \"speed\":0,\n \"odometer\":0,\n \"isGPSValid\":true,\n \"lat\":10.5416,\n \"lon\":7.4637,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":321,\n \"altitude\":64047,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"Inuwa Wada Road\",\n \"town\":\"Kaduna\",\n \"county\":\"Kaduna\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2015-11-27 14:32:20.0\"\n },\n { \n \"trackerId\":\"100006\",\n \"speed\":0,\n \"odometer\":9529754,\n \"isGPSValid\":true,\n \"lat\":11.6299,\n \"lon\":8.9803,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":159,\n \"altitude\":45753,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"Kano\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2016-11-30 11:04:06.0\"\n },\n { \n \"trackerId\":\"100007\",\n \"speed\":1,\n \"odometer\":-3907538,\n \"isGPSValid\":true,\n \"lat\":11.0798,\n \"lon\":7.7003,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":46,\n \"altitude\":68633,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":9,\n \"street\":\"A 236\",\n \"town\":\"Zaria\",\n \"county\":\"Kaduna\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2018-02-23 12:09:35.0\"\n },\n { \n \"trackerId\":\"100008\",\n \"speed\":0,\n \"odometer\":11869727,\n \"isGPSValid\":true,\n \"lat\":10.8483,\n \"lon\":8.2028,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":136,\n \"altitude\":71589,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"Anchau-Kuzuntu-Dutsen Road\",\n \"town\":\"Dutsen Wai\",\n \"county\":\"KD\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2018-06-03 01:51:49.0\"\n },\n { \n \"trackerId\":\"100009\",\n \"speed\":0,\n \"odometer\":18993850,\n \"isGPSValid\":true,\n \"lat\":9.1721,\n \"lon\":7.6811,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":39,\n \"altitude\":42687,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2018-05-13 20:26:12.0\"\n },\n { \n \"trackerId\":\"100010\",\n \"speed\":0,\n \"odometer\":707,\n \"isGPSValid\":true,\n \"lat\":13.0646,\n \"lon\":5.2165,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":112,\n \"altitude\":29814,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"Abdulahi Fodio Rd\",\n \"town\":\"Sokoto\",\n \"county\":\"Sokoto\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2017-01-01 18:19:19.0\"\n },\n { \n \"trackerId\":\"100011\",\n \"speed\":0,\n \"odometer\":320,\n \"isGPSValid\":false,\n \"lat\":0,\n \"lon\":0,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":0,\n \"altitude\":0,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"18-419 Obafemi Awolowo Way\",\n \"town\":\"Abuja\",\n \"county\":\"FCT\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2017-01-20 00:00:00.0\"\n },\n { \n \"trackerId\":\"100012\",\n \"speed\":0,\n \"odometer\":1236,\n \"isGPSValid\":true,\n \"lat\":11.6028,\n \"lon\":8.4304,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":25,\n \"altitude\":51718,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":6,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"KN\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2018-01-21 19:17:53.0\"\n },\n { \n \"trackerId\":\"100013\",\n \"speed\":1,\n \"odometer\":0,\n \"isGPSValid\":false,\n \"lat\":9.0631,\n \"lon\":7.4257,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":335,\n \"altitude\":48280,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"495-637 Obafemi Awolowo Way\",\n \"town\":\"Abuja\",\n \"county\":\"FCT\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2017-08-04 10:18:41.0\"\n },\n { \n \"trackerId\":\"100014\",\n \"speed\":2,\n \"odometer\":60141,\n \"isGPSValid\":true,\n \"lat\":6.5444,\n \"lon\":7.0367,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":66,\n \"altitude\":6160,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":8,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"AN\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2018-08-02 12:14:16.0\"\n },\n { \n \"trackerId\":\"100015\",\n \"speed\":0,\n \"odometer\":3557177,\n \"isGPSValid\":true,\n \"lat\":-1.209,\n \"lon\":36.8939,\n \"directionEW\":\"E\",\n \"directionNS\":\"S\",\n \"headingDegree\":195,\n \"altitude\":155814,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":12,\n \"street\":\"123 Kamiti Rd\",\n \"town\":\"Githurai\",\n \"county\":\"Nairobi County\",\n \"country\":\"Kenya\",\n \"lastReportUTCDate\":\"2017-12-09 07:13:37.0\"\n },\n { \n \"trackerId\":\"100016\",\n \"speed\":0,\n \"odometer\":1640958,\n \"isGPSValid\":false,\n \"lat\":6.8421,\n \"lon\":3.3251,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":327,\n \"altitude\":4318,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"OG\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-02-11 00:05:02.0\"\n },\n { \n \"trackerId\":\"100017\",\n \"speed\":6,\n \"odometer\":1348,\n \"isGPSValid\":true,\n \"lat\":6.0156,\n \"lon\":7.8308,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":81,\n \"altitude\":6713,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":9,\n \"street\":\"Unnamed Road\",\n \"town\":\"Okposi\",\n \"county\":\"EB\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-02-08 10:09:09.0\"\n },\n { \n \"trackerId\":\"100018\",\n \"speed\":0,\n \"odometer\":10774038,\n \"isGPSValid\":true,\n \"lat\":10.5236,\n \"lon\":7.4355,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":0,\n \"altitude\":64240,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"Crescent Road\",\n \"town\":\"Zaria\",\n \"county\":\"KD\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-01-14 13:42:03.0\"\n },\n { \n \"trackerId\":\"100019\",\n \"speed\":0,\n \"odometer\":4130287,\n \"isGPSValid\":true,\n \"lat\":8.5001,\n \"lon\":8.9282,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":253,\n \"altitude\":16344,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2017-08-30 16:52:56.0\"\n },\n { \n \"trackerId\":\"100020\",\n \"speed\":0,\n \"odometer\":153830,\n \"isGPSValid\":true,\n \"lat\":9.0978,\n \"lon\":5.8523,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":344,\n \"altitude\":11962,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":12,\n \"street\":\"Unnamed Road\",\n \"town\":\"Jima\",\n \"county\":\"NG\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2018-07-22 15:16:14.0\"\n },\n { \n \"trackerId\":\"100021\",\n \"speed\":0,\n \"odometer\":4975856,\n \"isGPSValid\":true,\n \"lat\":0.0587,\n \"lon\":37.1525,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":43,\n \"altitude\":203345,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":9,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"Laikipia County\",\n \"country\":\"Kenya\",\n \"lastReportUTCDate\":\"2018-04-11 14:09:47.0\"\n },\n { \n \"trackerId\":\"100022\",\n \"speed\":0,\n \"odometer\":4,\n \"isGPSValid\":true,\n \"lat\":0.0711,\n \"lon\":37.1459,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":312,\n \"altitude\":201426,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"\",\n \"town\":\"Kalalu\",\n \"county\":\"Central\",\n \"country\":\"Kenya\",\n \"lastReportUTCDate\":\"2019-04-14 09:03:46.0\"\n },\n { \n \"trackerId\":\"100023\",\n \"speed\":0,\n \"odometer\":0,\n \"isGPSValid\":false,\n \"lat\":0,\n \"lon\":0,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":0,\n \"altitude\":0,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":-1,\n \"satelliteNumber\":0,\n \"street\":\"226 Wall St\",\n \"town\":\"Eatontown\",\n \"county\":\"NJ\",\n \"country\":\"US\",\n \"lastReportUTCDate\":\"1900-01-01 00:00:00.0\"\n },\n { \n \"trackerId\":\"100024\",\n \"speed\":5,\n \"odometer\":46332,\n \"isGPSValid\":true,\n \"lat\":-1.2612,\n \"lon\":36.801,\n \"directionEW\":\"E\",\n \"directionNS\":\"S\",\n \"headingDegree\":356,\n \"altitude\":169030,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":8,\n \"street\":\"Karuna Rd\",\n \"town\":\"Nairobi\",\n \"county\":\"Nairobi County\",\n \"country\":\"Kenya\",\n \"lastReportUTCDate\":\"2017-03-27 08:39:56.0\"\n },\n { \n \"trackerId\":\"100025\",\n \"speed\":0,\n \"odometer\":2446351,\n \"isGPSValid\":false,\n \"lat\":-0.5976,\n \"lon\":35.8351,\n \"directionEW\":\"E\",\n \"directionNS\":\"S\",\n \"headingDegree\":110,\n \"altitude\":275588,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"Narok County\",\n \"country\":\"Kenya\",\n \"lastReportUTCDate\":\"2017-06-21 07:48:48.0\"\n },\n { \n \"trackerId\":\"100026\",\n \"speed\":0,\n \"odometer\":14289298,\n \"isGPSValid\":true,\n \"lat\":11.0466,\n \"lon\":7.8879,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":55,\n \"altitude\":67839,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"KD\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 14:05:03.0\"\n },\n { \n \"trackerId\":\"100027\",\n \"speed\":0,\n \"odometer\":6556462,\n \"isGPSValid\":true,\n \"lat\":9.5677,\n \"lon\":7.4228,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":278,\n \"altitude\":57451,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":9,\n \"street\":\"Abuja - Kaduna - Zaria Express Way\",\n \"town\":\"\",\n \"county\":\"KD\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-02-17 16:26:17.0\"\n },\n { \n \"trackerId\":\"100028\",\n \"speed\":8,\n \"odometer\":14746635,\n \"isGPSValid\":true,\n \"lat\":8.3151,\n \"lon\":7.5566,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":144,\n \"altitude\":21898,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":9,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 09:07:41.0\"\n },\n { \n \"trackerId\":\"100029\",\n \"speed\":0,\n \"odometer\":9101598,\n \"isGPSValid\":true,\n \"lat\":9.647,\n \"lon\":7.7165,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":20,\n \"altitude\":64881,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"\",\n \"town\":\"Awon\",\n \"county\":\"KD\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2018-11-03 10:37:43.0\"\n },\n { \n \"trackerId\":\"100030\",\n \"speed\":0,\n \"odometer\":11769179,\n \"isGPSValid\":true,\n \"lat\":7.0377,\n \"lon\":3.4488,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":301,\n \"altitude\":16099,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"Unnamed Road\",\n \"town\":\"Lemode\",\n \"county\":\"OG\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 14:06:08.0\"\n },\n { \n \"trackerId\":\"100031\",\n \"speed\":0,\n \"odometer\":15637496,\n \"isGPSValid\":false,\n \"lat\":9.1367,\n \"lon\":6.4656,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":0,\n \"altitude\":16735,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"NG\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2018-08-13 08:46:01.0\"\n },\n { \n \"trackerId\":\"100033\",\n \"speed\":0,\n \"odometer\":6602429,\n \"isGPSValid\":true,\n \"lat\":7.2849,\n \"lon\":8.3626,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":214,\n \"altitude\":17885,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"Makurdi - Otupko Road\",\n \"town\":\"\",\n \"county\":\"BN\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 09:04:06.0\"\n },\n { \n \"trackerId\":\"100034\",\n \"speed\":39,\n \"odometer\":15784252,\n \"isGPSValid\":true,\n \"lat\":8.395,\n \"lon\":11.0664,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":221,\n \"altitude\":23108,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"Bali - Jalingo Rd\",\n \"town\":\"\",\n \"county\":\"TR\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 17:40:07.0\"\n },\n { \n \"trackerId\":\"100036\",\n \"speed\":0,\n \"odometer\":15667316,\n \"isGPSValid\":true,\n \"lat\":8.3452,\n \"lon\":7.6054,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":71,\n \"altitude\":26164,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"\",\n \"town\":\"Kanah-Ondo-Apawu\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 18:18:20.0\"\n },\n { \n \"trackerId\":\"100037\",\n \"speed\":0,\n \"odometer\":16750394,\n \"isGPSValid\":false,\n \"lat\":11.0345,\n \"lon\":7.9153,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":0,\n \"altitude\":66447,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"Zaria-Panbeguwa Road\",\n \"town\":\"\",\n \"county\":\"KD\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-03-12 00:00:12.0\"\n },\n { \n \"trackerId\":\"100038\",\n \"speed\":0,\n \"odometer\":11684479,\n \"isGPSValid\":true,\n \"lat\":8.3261,\n \"lon\":7.6498,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":2,\n \"altitude\":26168,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"\",\n \"town\":\"Kanah-Ondo-Apawu\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 17:45:16.0\"\n },\n { \n \"trackerId\":\"100039\",\n \"speed\":0,\n \"odometer\":9746903,\n \"isGPSValid\":false,\n \"lat\":12.3995,\n \"lon\":9.9764,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":331,\n \"altitude\":37958,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"KW\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2018-04-24 11:44:32.0\"\n },\n { \n \"trackerId\":\"100040\",\n \"speed\":0,\n \"odometer\":15921990,\n \"isGPSValid\":false,\n \"lat\":10.0544,\n \"lon\":7.3846,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":199,\n \"altitude\":56743,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"KD\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-11 08:02:51.0\"\n },\n { \n \"trackerId\":\"100041\",\n \"speed\":0,\n \"odometer\":4714113,\n \"isGPSValid\":true,\n \"lat\":11.0803,\n \"lon\":7.7022,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":253,\n \"altitude\":67527,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":8,\n \"street\":\"A236\",\n \"town\":\"Zaria\",\n \"county\":\"KD\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-11 12:09:31.0\"\n },\n { \n \"trackerId\":\"100042\",\n \"speed\":0,\n \"odometer\":10604648,\n \"isGPSValid\":true,\n \"lat\":8.8747,\n \"lon\":9.5176,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":236,\n \"altitude\":24253,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"\",\n \"town\":\"Shendam Central (B)\",\n \"county\":\"PL\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-06 09:47:01.0\"\n },\n { \n \"trackerId\":\"100043\",\n \"speed\":0,\n \"odometer\":1555161,\n \"isGPSValid\":false,\n \"lat\":9.0885,\n \"lon\":7.0666,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":323,\n \"altitude\":21699,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"Federal Capital Territory\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 05:55:33.0\"\n },\n { \n \"trackerId\":\"100044\",\n \"speed\":0,\n \"odometer\":12346493,\n \"isGPSValid\":false,\n \"lat\":8.4674,\n \"lon\":8.1668,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":230,\n \"altitude\":11888,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2018-07-29 07:53:42.0\"\n },\n { \n \"trackerId\":\"100045\",\n \"speed\":7,\n \"odometer\":17283224,\n \"isGPSValid\":true,\n \"lat\":8.3102,\n \"lon\":7.5535,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":70,\n \"altitude\":22582,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-03-20 13:07:15.0\"\n },\n { \n \"trackerId\":\"100046\",\n \"speed\":0,\n \"odometer\":14726748,\n \"isGPSValid\":false,\n \"lat\":8.4246,\n \"lon\":8.0983,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":0,\n \"altitude\":12830,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2018-11-16 08:19:34.0\"\n },\n { \n \"trackerId\":\"100047\",\n \"speed\":4,\n \"odometer\":19734366,\n \"isGPSValid\":false,\n \"lat\":8.4722,\n \"lon\":8.1732,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":207,\n \"altitude\":13972,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"\",\n \"town\":\"Bassa\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 15:39:22.0\"\n },\n { \n \"trackerId\":\"100048\",\n \"speed\":14,\n \"odometer\":9716609,\n \"isGPSValid\":true,\n \"lat\":8.5008,\n \"lon\":8.1897,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":66,\n \"altitude\":16391,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2018-04-07 15:57:21.0\"\n },\n { \n \"trackerId\":\"100049\",\n \"speed\":7,\n \"odometer\":3430511,\n \"isGPSValid\":true,\n \"lat\":9.8921,\n \"lon\":5.2971,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":265,\n \"altitude\":28539,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"Masheru-Safo-Kizhi-Asa Road\",\n \"town\":\"\",\n \"county\":\"NG\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2018-06-11 07:41:00.0\"\n },\n { \n \"trackerId\":\"100050\",\n \"speed\":28,\n \"odometer\":1707911,\n \"isGPSValid\":true,\n \"lat\":8.3551,\n \"lon\":7.6499,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":343,\n \"altitude\":28812,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"\",\n \"town\":\"Kanah-Ondo-Apawu\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 17:40:57.0\"\n },\n { \n \"trackerId\":\"100051\",\n \"speed\":0,\n \"odometer\":11057536,\n \"isGPSValid\":false,\n \"lat\":9.535,\n \"lon\":7.5034,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":188,\n \"altitude\":62028,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"KD\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 18:45:31.0\"\n },\n { \n \"trackerId\":\"100052\",\n \"speed\":0,\n \"odometer\":20209208,\n \"isGPSValid\":true,\n \"lat\":11.0466,\n \"lon\":7.8879,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":1,\n \"altitude\":67696,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":8,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"KD\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 14:07:47.0\"\n },\n { \n \"trackerId\":\"100053\",\n \"speed\":9,\n \"odometer\":2677664,\n \"isGPSValid\":true,\n \"lat\":8.5782,\n \"lon\":8.3974,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":292,\n \"altitude\":13353,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-13 18:14:29.0\"\n },\n { \n \"trackerId\":\"100054\",\n \"speed\":0,\n \"odometer\":15136931,\n \"isGPSValid\":true,\n \"lat\":9.5155,\n \"lon\":7.4926,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":95,\n \"altitude\":59598,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"\",\n \"town\":\"Jere North\",\n \"county\":\"KD\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2018-12-18 18:58:47.0\"\n },\n { \n \"trackerId\":\"100055\",\n \"speed\":5,\n \"odometer\":11071737,\n \"isGPSValid\":true,\n \"lat\":8.277,\n \"lon\":7.6354,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":154,\n \"altitude\":16002,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"\",\n \"town\":\"Tunga-Bakono\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 08:10:45.0\"\n },\n { \n \"trackerId\":\"100056\",\n \"speed\":0,\n \"odometer\":10358337,\n \"isGPSValid\":true,\n \"lat\":8.8044,\n \"lon\":6.941,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":229,\n \"altitude\":17408,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"Federal Capital Territory\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 15:54:13.0\"\n },\n { \n \"trackerId\":\"100057\",\n \"speed\":6,\n \"odometer\":10282065,\n \"isGPSValid\":true,\n \"lat\":8.8209,\n \"lon\":6.8106,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":117,\n \"altitude\":13812,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"\",\n \"town\":\"Gurdi\",\n \"county\":\"Federal Capital Territory\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 14:54:28.0\"\n },\n { \n \"trackerId\":\"100058\",\n \"speed\":0,\n \"odometer\":209411,\n \"isGPSValid\":false,\n \"lat\":8.4186,\n \"lon\":7.5121,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":201,\n \"altitude\":17934,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"\",\n \"town\":\"Ara I\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 14:14:32.0\"\n },\n { \n \"trackerId\":\"100059\",\n \"speed\":0,\n \"odometer\":6462119,\n \"isGPSValid\":true,\n \"lat\":8.4316,\n \"lon\":10.9829,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":109,\n \"altitude\":25917,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"\",\n \"town\":\"Kaigama\",\n \"county\":\"TR\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 18:02:58.0\"\n },\n { \n \"trackerId\":\"100060\",\n \"speed\":13,\n \"odometer\":13846853,\n \"isGPSValid\":true,\n \"lat\":8.3643,\n \"lon\":7.5874,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":148,\n \"altitude\":23576,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":12,\n \"street\":\"\",\n \"town\":\"Kanah-Ondo-Apawu\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 16:32:36.0\"\n },\n { \n \"trackerId\":\"100061\",\n \"speed\":7,\n \"odometer\":16619285,\n \"isGPSValid\":true,\n \"lat\":8.384,\n \"lon\":7.5045,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":346,\n \"altitude\":18385,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"\",\n \"town\":\"Tunga-Bakono\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-13 15:35:00.0\"\n },\n { \n \"trackerId\":\"100062\",\n \"speed\":0,\n \"odometer\":11089755,\n \"isGPSValid\":true,\n \"lat\":8.8904,\n \"lon\":6.6238,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":88,\n \"altitude\":15045,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"NG\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 17:36:40.0\"\n },\n { \n \"trackerId\":\"100063\",\n \"speed\":6,\n \"odometer\":9700871,\n \"isGPSValid\":true,\n \"lat\":8.2891,\n \"lon\":7.6359,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":97,\n \"altitude\":18936,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":12,\n \"street\":\"\",\n \"town\":\"Tunga-Bakono\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-13 10:05:40.0\"\n },\n { \n \"trackerId\":\"100064\",\n \"speed\":14,\n \"odometer\":6112982,\n \"isGPSValid\":true,\n \"lat\":8.7237,\n \"lon\":6.7864,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":12,\n \"altitude\":11015,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"\",\n \"town\":\"Yaba\",\n \"county\":\"Federal Capital Territory\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 17:52:18.0\"\n },\n { \n \"trackerId\":\"100065\",\n \"speed\":5,\n \"odometer\":5549587,\n \"isGPSValid\":true,\n \"lat\":11.7645,\n \"lon\":8.5853,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":235,\n \"altitude\":44620,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":12,\n \"street\":\"A2\",\n \"town\":\"Kura\",\n \"county\":\"KN\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2017-11-12 14:58:03.0\"\n },\n { \n \"trackerId\":\"100066\",\n \"speed\":0,\n \"odometer\":12895854,\n \"isGPSValid\":true,\n \"lat\":8.4012,\n \"lon\":10.5949,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":118,\n \"altitude\":18995,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":12,\n \"street\":\"\",\n \"town\":\"Yarima\",\n \"county\":\"TR\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 19:58:55.0\"\n },\n { \n \"trackerId\":\"100067\",\n \"speed\":0,\n \"odometer\":16458427,\n \"isGPSValid\":true,\n \"lat\":8.3211,\n \"lon\":9.6941,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":134,\n \"altitude\":15970,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":9,\n \"street\":\"Wukari-Amper Rd\",\n \"town\":\"Aundu\",\n \"county\":\"TR\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2018-11-29 09:33:33.0\"\n },\n { \n \"trackerId\":\"100068\",\n \"speed\":0,\n \"odometer\":7547657,\n \"isGPSValid\":true,\n \"lat\":8.8202,\n \"lon\":9.5338,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":319,\n \"altitude\":21727,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":12,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"PL\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-13 13:46:27.0\"\n },\n { \n \"trackerId\":\"100069\",\n \"speed\":0,\n \"odometer\":6742008,\n \"isGPSValid\":true,\n \"lat\":9.0217,\n \"lon\":7.2428,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":129,\n \"altitude\":36453,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":9,\n \"street\":\"Unnamed Road\",\n \"town\":\"Abuja\",\n \"county\":\"Federal Capital Territory\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 14:25:51.0\"\n },\n { \n \"trackerId\":\"100070\",\n \"speed\":0,\n \"odometer\":8396511,\n \"isGPSValid\":false,\n \"lat\":6.3091,\n \"lon\":8.1546,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":43,\n \"altitude\":6654,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"Enugu-Abakaliki Road\",\n \"town\":\"\",\n \"county\":\"EB\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 16:11:53.0\"\n },\n { \n \"trackerId\":\"100071\",\n \"speed\":0,\n \"odometer\":0,\n \"isGPSValid\":false,\n \"lat\":0,\n \"lon\":0,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":0,\n \"altitude\":0,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"\",\n \"town\":\"\",\n \"county\":\"\",\n \"country\":\"\",\n \"lastReportUTCDate\":\"2017-10-03 10:27:28.0\"\n },\n { \n \"trackerId\":\"100072\",\n \"speed\":0,\n \"odometer\":9759380,\n \"isGPSValid\":false,\n \"lat\":11.0341,\n \"lon\":7.9153,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":118,\n \"altitude\":67416,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"Zaria-Panbeguwa Road\",\n \"town\":\"\",\n \"county\":\"KD\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-02 09:39:32.0\"\n },\n { \n \"trackerId\":\"100073\",\n \"speed\":0,\n \"odometer\":5745880,\n \"isGPSValid\":true,\n \"lat\":9.1991,\n \"lon\":7.2153,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":4,\n \"altitude\":46505,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":9,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"NG\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 11:29:40.0\"\n },\n { \n \"trackerId\":\"100074\",\n \"speed\":0,\n \"odometer\":4256833,\n \"isGPSValid\":true,\n \"lat\":9.0932,\n \"lon\":7.2133,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":213,\n \"altitude\":40297,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"Unnamed Road\",\n \"town\":\"Madalla\",\n \"county\":\"Federal Capital Territory\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-03-20 06:07:18.0\"\n },\n { \n \"trackerId\":\"100075\",\n \"speed\":0,\n \"odometer\":3681495,\n \"isGPSValid\":true,\n \"lat\":8.4891,\n \"lon\":10.7924,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":284,\n \"altitude\":25604,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"\",\n \"town\":\"Gunduma\",\n \"county\":\"TR\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 12:20:09.0\"\n },\n { \n \"trackerId\":\"100076\",\n \"speed\":0,\n \"odometer\":8082340,\n \"isGPSValid\":true,\n \"lat\":11.0344,\n \"lon\":7.9155,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":270,\n \"altitude\":67337,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"KD\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-03-18 08:33:36.0\"\n },\n { \n \"trackerId\":\"100077\",\n \"speed\":0,\n \"odometer\":14438162,\n \"isGPSValid\":true,\n \"lat\":7.839,\n \"lon\":11.0317,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":47,\n \"altitude\":20398,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"Mambila Plateau Rd\",\n \"town\":\"Bali\",\n \"county\":\"TR\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 18:17:38.0\"\n },\n { \n \"trackerId\":\"100078\",\n \"speed\":38,\n \"odometer\":11736993,\n \"isGPSValid\":true,\n \"lat\":8.323,\n \"lon\":7.7651,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":274,\n \"altitude\":18484,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 17:16:26.0\"\n },\n { \n \"trackerId\":\"100079\",\n \"speed\":0,\n \"odometer\":11079132,\n \"isGPSValid\":true,\n \"lat\":8.3467,\n \"lon\":7.6008,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":111,\n \"altitude\":25598,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"Unnamed Road\",\n \"town\":\"Zangwan Daji\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 17:03:43.0\"\n },\n { \n \"trackerId\":\"100080\",\n \"speed\":0,\n \"odometer\":0,\n \"isGPSValid\":false,\n \"lat\":0,\n \"lon\":0,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":0,\n \"altitude\":0,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"\",\n \"town\":\"\",\n \"county\":\"\",\n \"country\":\"\",\n \"lastReportUTCDate\":\"2017-08-07 14:45:30.0\"\n },\n { \n \"trackerId\":\"100081\",\n \"speed\":0,\n \"odometer\":14756117,\n \"isGPSValid\":false,\n \"lat\":8.3434,\n \"lon\":7.6004,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":132,\n \"altitude\":25117,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"Unnamed Road\",\n \"town\":\"Zangwan Daji\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 15:28:30.0\"\n },\n { \n \"trackerId\":\"100082\",\n \"speed\":0,\n \"odometer\":22508502,\n \"isGPSValid\":true,\n \"lat\":9.0932,\n \"lon\":7.2135,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":0,\n \"altitude\":40621,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"A234\",\n \"town\":\"Madalla\",\n \"county\":\"Federal Capital Territory\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-03-20 05:57:20.0\"\n },\n { \n \"trackerId\":\"100083\",\n \"speed\":10,\n \"odometer\":7829867,\n \"isGPSValid\":true,\n \"lat\":8.228,\n \"lon\":7.4517,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":20,\n \"altitude\":21104,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"\",\n \"town\":\"Tunga-Bakono\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 08:46:34.0\"\n },\n { \n \"trackerId\":\"100084\",\n \"speed\":0,\n \"odometer\":8834714,\n \"isGPSValid\":false,\n \"lat\":11.0802,\n \"lon\":7.7023,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":0,\n \"altitude\":66678,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"A 236\",\n \"town\":\"Zaria\",\n \"county\":\"KD\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 00:01:15.0\"\n },\n { \n \"trackerId\":\"100085\",\n \"speed\":0,\n \"odometer\":7079117,\n \"isGPSValid\":true,\n \"lat\":7.7178,\n \"lon\":10.018,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":191,\n \"altitude\":14813,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"Rafin Kada-Gembu Rd\",\n \"town\":\"\",\n \"county\":\"TR\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 17:17:48.0\"\n },\n { \n \"trackerId\":\"100086\",\n \"speed\":6,\n \"odometer\":8371643,\n \"isGPSValid\":true,\n \"lat\":8.2278,\n \"lon\":7.4351,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":287,\n \"altitude\":22298,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"\",\n \"town\":\"Tunga-Bakono\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-13 07:37:30.0\"\n },\n { \n \"trackerId\":\"100087\",\n \"speed\":0,\n \"odometer\":5126282,\n \"isGPSValid\":true,\n \"lat\":11.0804,\n \"lon\":7.7022,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":274,\n \"altitude\":67926,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":9,\n \"street\":\"A236\",\n \"town\":\"Zaria\",\n \"county\":\"KD\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 12:25:53.0\"\n },\n { \n \"trackerId\":\"100088\",\n \"speed\":0,\n \"odometer\":12492816,\n \"isGPSValid\":true,\n \"lat\":11.0802,\n \"lon\":7.7022,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":0,\n \"altitude\":67576,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":12,\n \"street\":\"A236\",\n \"town\":\"Zaria\",\n \"county\":\"KD\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 19:14:23.0\"\n },\n { \n \"trackerId\":\"100089\",\n \"speed\":9,\n \"odometer\":10681293,\n \"isGPSValid\":true,\n \"lat\":8.8126,\n \"lon\":6.7509,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":349,\n \"altitude\":19826,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"\",\n \"town\":\"Gurdi-Zago\",\n \"county\":\"NG\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 15:05:03.0\"\n },\n { \n \"trackerId\":\"100090\",\n \"speed\":1,\n \"odometer\":12679128,\n \"isGPSValid\":false,\n \"lat\":9.1167,\n \"lon\":8.1918,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":235,\n \"altitude\":50091,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"Keffi Road\",\n \"town\":\"Nasarawa\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2018-11-09 00:00:12.0\"\n },\n { \n \"trackerId\":\"100091\",\n \"speed\":3,\n \"odometer\":10570997,\n \"isGPSValid\":false,\n \"lat\":8.8365,\n \"lon\":6.469,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":180,\n \"altitude\":18313,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"NG\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2018-04-25 10:28:44.0\"\n },\n { \n \"trackerId\":\"100092\",\n \"speed\":5,\n \"odometer\":21472399,\n \"isGPSValid\":true,\n \"lat\":8.4937,\n \"lon\":6.5121,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":94,\n \"altitude\":7724,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"NG\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2017-09-12 08:22:59.0\"\n },\n { \n \"trackerId\":\"100093\",\n \"speed\":0,\n \"odometer\":6350089,\n \"isGPSValid\":false,\n \"lat\":9.0884,\n \"lon\":7.1981,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":263,\n \"altitude\":38349,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":8,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"Federal Capital Territory\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-13 13:25:03.0\"\n },\n { \n \"trackerId\":\"100094\",\n \"speed\":6,\n \"odometer\":442783,\n \"isGPSValid\":false,\n \"lat\":10.1793,\n \"lon\":5.3167,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":256,\n \"altitude\":34842,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"A1\",\n \"town\":\"\",\n \"county\":\"NG\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2018-06-23 00:00:12.0\"\n },\n { \n \"trackerId\":\"100095\",\n \"speed\":10,\n \"odometer\":14836657,\n \"isGPSValid\":true,\n \"lat\":8.3448,\n \"lon\":7.6008,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":146,\n \"altitude\":26177,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"Unnamed Road\",\n \"town\":\"Zangwan Daji\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-13 17:19:46.0\"\n },\n { \n \"trackerId\":\"100096\",\n \"speed\":0,\n \"odometer\":8882066,\n \"isGPSValid\":true,\n \"lat\":8.3361,\n \"lon\":10.4355,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":152,\n \"altitude\":20279,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"A4\",\n \"town\":\"Nasarawa\",\n \"county\":\"TR\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 17:17:42.0\"\n },\n { \n \"trackerId\":\"100097\",\n \"speed\":7,\n \"odometer\":1812464,\n \"isGPSValid\":true,\n \"lat\":8.325,\n \"lon\":7.5588,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":279,\n \"altitude\":20969,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-13 15:45:26.0\"\n },\n { \n \"trackerId\":\"100098\",\n \"speed\":0,\n \"odometer\":5302720,\n \"isGPSValid\":true,\n \"lat\":11.0804,\n \"lon\":7.7021,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":108,\n \"altitude\":67275,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"A236\",\n \"town\":\"Zaria\",\n \"county\":\"KD\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 16:54:31.0\"\n },\n { \n \"trackerId\":\"100099\",\n \"speed\":35,\n \"odometer\":2034494,\n \"isGPSValid\":true,\n \"lat\":10.1974,\n \"lon\":5.4033,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":4,\n \"altitude\":34040,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":9,\n \"street\":\"A1\",\n \"town\":\"Kabchi\",\n \"county\":\"NG\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2018-05-16 10:53:28.0\"\n },\n { \n \"trackerId\":\"100100\",\n \"speed\":0,\n \"odometer\":1104625,\n \"isGPSValid\":false,\n \"lat\":11.0065,\n \"lon\":7.8771,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":354,\n \"altitude\":65702,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"\",\n \"town\":\"Kinkiba\",\n \"county\":\"KD\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-01-15 13:22:17.0\"\n },\n { \n \"trackerId\":\"100101\",\n \"speed\":5,\n \"odometer\":13635279,\n \"isGPSValid\":true,\n \"lat\":8.3661,\n \"lon\":7.5183,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":287,\n \"altitude\":15962,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"\",\n \"town\":\"Tunga-Bakono\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 16:14:47.0\"\n },\n { \n \"trackerId\":\"100102\",\n \"speed\":8,\n \"odometer\":5792972,\n \"isGPSValid\":false,\n \"lat\":8.3041,\n \"lon\":7.5041,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":181,\n \"altitude\":19940,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"\",\n \"town\":\"Tunga-Bakono\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 11:47:08.0\"\n },\n { \n \"trackerId\":\"100103\",\n \"speed\":0,\n \"odometer\":5252242,\n \"isGPSValid\":true,\n \"lat\":8.4373,\n \"lon\":7.2827,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":311,\n \"altitude\":18352,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":9,\n \"street\":\"Unnamed Road\",\n \"town\":\"Gadabuke\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 19:03:29.0\"\n },\n { \n \"trackerId\":\"100104\",\n \"speed\":0,\n \"odometer\":8535616,\n \"isGPSValid\":false,\n \"lat\":11.0343,\n \"lon\":7.9155,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":98,\n \"altitude\":67779,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"Zaria-Panbeguwa Road\",\n \"town\":\"\",\n \"county\":\"KD\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-07 12:13:42.0\"\n },\n { \n \"trackerId\":\"100105\",\n \"speed\":11,\n \"odometer\":9516406,\n \"isGPSValid\":true,\n \"lat\":8.2655,\n \"lon\":10.5296,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":96,\n \"altitude\":15901,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":9,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"TR\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-13 12:46:19.0\"\n },\n { \n \"trackerId\":\"100106\",\n \"speed\":0,\n \"odometer\":15068181,\n \"isGPSValid\":false,\n \"lat\":11.6029,\n \"lon\":8.4304,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":292,\n \"altitude\":51137,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"\",\n \"town\":\"Garun Babba\",\n \"county\":\"KN\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 08:43:03.0\"\n },\n { \n \"trackerId\":\"100107\",\n \"speed\":0,\n \"odometer\":6707504,\n \"isGPSValid\":true,\n \"lat\":8.52,\n \"lon\":11.1523,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":211,\n \"altitude\":24656,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":12,\n \"street\":\"Bali - Jalingo Rd\",\n \"town\":\"\",\n \"county\":\"TR\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 17:27:48.0\"\n },\n { \n \"trackerId\":\"100108\",\n \"speed\":0,\n \"odometer\":5915006,\n \"isGPSValid\":true,\n \"lat\":8.3966,\n \"lon\":10.5196,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":23,\n \"altitude\":15762,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":12,\n \"street\":\"A4\",\n \"town\":\"\",\n \"county\":\"TR\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 16:35:09.0\"\n },\n { \n \"trackerId\":\"100109\",\n \"speed\":0,\n \"odometer\":6311064,\n \"isGPSValid\":false,\n \"lat\":8.3442,\n \"lon\":7.6024,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":347,\n \"altitude\":25964,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2018-08-31 12:03:32.0\"\n },\n { \n \"trackerId\":\"100110\",\n \"speed\":0,\n \"odometer\":1460200,\n \"isGPSValid\":true,\n \"lat\":6.7938,\n \"lon\":3.5784,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":149,\n \"altitude\":12213,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"Ikorodu - Shagamu Road\",\n \"town\":\"\",\n \"county\":\"OG\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 10:14:17.0\"\n },\n { \n \"trackerId\":\"100111\",\n \"speed\":0,\n \"odometer\":17219316,\n \"isGPSValid\":false,\n \"lat\":6.2187,\n \"lon\":7.0612,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":0,\n \"altitude\":10234,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"Ada Road\",\n \"town\":\"Awka\",\n \"county\":\"AN\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-02 08:57:16.0\"\n },\n { \n \"trackerId\":\"100112\",\n \"speed\":0,\n \"odometer\":11624225,\n \"isGPSValid\":false,\n \"lat\":7.9872,\n \"lon\":10.9966,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":199,\n \"altitude\":24645,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":12,\n \"street\":\"Bali - Jalingo Rd\",\n \"town\":\"Mai Fula\",\n \"county\":\"TR\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 16:45:22.0\"\n },\n { \n \"trackerId\":\"100113\",\n \"speed\":12,\n \"odometer\":11588096,\n \"isGPSValid\":true,\n \"lat\":8.3851,\n \"lon\":7.6545,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":230,\n \"altitude\":27332,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":12,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 19:03:19.0\"\n },\n { \n \"trackerId\":\"100114\",\n \"speed\":15,\n \"odometer\":9619747,\n \"isGPSValid\":true,\n \"lat\":8.469,\n \"lon\":8.1697,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":294,\n \"altitude\":12229,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"Unnamed Road\",\n \"town\":\"Bassan Zarangi\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 17:53:29.0\"\n },\n { \n \"trackerId\":\"100115\",\n \"speed\":0,\n \"odometer\":10933029,\n \"isGPSValid\":false,\n \"lat\":8.4974,\n \"lon\":7.7983,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":97,\n \"altitude\":27626,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 17:42:30.0\"\n },\n { \n \"trackerId\":\"100116\",\n \"speed\":0,\n \"odometer\":5116039,\n \"isGPSValid\":true,\n \"lat\":8.4974,\n \"lon\":7.5178,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":177,\n \"altitude\":23373,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"NS\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-11 17:05:12.0\"\n },\n { \n \"trackerId\":\"100117\",\n \"speed\":0,\n \"odometer\":5332551,\n \"isGPSValid\":false,\n \"lat\":9.535,\n \"lon\":7.5034,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":189,\n \"altitude\":62267,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":0,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"KD\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 18:42:52.0\"\n },\n { \n \"trackerId\":\"100118\",\n \"speed\":0,\n \"odometer\":10557277,\n \"isGPSValid\":true,\n \"lat\":8.7051,\n \"lon\":10.8662,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":56,\n \"altitude\":16955,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"A4\",\n \"town\":\"\",\n \"county\":\"TR\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-02-20 09:09:14.0\"\n },\n { \n \"trackerId\":\"100119\",\n \"speed\":0,\n \"odometer\":3169350,\n \"isGPSValid\":true,\n \"lat\":6.7001,\n \"lon\":6.9281,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":346,\n \"altitude\":4453,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":10,\n \"street\":\"Unnamed Road\",\n \"town\":\"\",\n \"county\":\"AN\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-11 14:44:40.0\"\n },\n { \n \"trackerId\":\"100120\",\n \"speed\":0,\n \"odometer\":9980372,\n \"isGPSValid\":true,\n \"lat\":7.839,\n \"lon\":11.0317,\n \"directionEW\":\"E\",\n \"directionNS\":\"N\",\n \"headingDegree\":70,\n \"altitude\":20424,\n \"ignitionStatus\":\"On\",\n \"batteryVoltage\":0,\n \"satelliteNumber\":11,\n \"street\":\"Mambila Plateau Rd\",\n \"town\":\"Bali\",\n \"county\":\"TR\",\n \"country\":\"Nigeria\",\n \"lastReportUTCDate\":\"2019-04-14 17:20:26.0\"\n }\n ],\n \"message\":\"\"\n}\n */ \n\n}" }, "UpdateAllTractorsDetailAddressOnPOSTFromAWSBACKEND" : { "code" : "function onRequest(request, response, modules) {\n \n var TractorDetail = modules.collectionAccess.collection('TractorDetail');\n var updateData = request.body;\n var tractorId = +updateData.tractor_id;\n \n var tractorDetailUpdateData = {};\n tractorDetailUpdateData.Street = updateData.street ? updateData.street : '';\n tractorDetailUpdateData.Town = updateData.town ? updateData.town: '';\n tractorDetailUpdateData.Country = updateData.country ? updateData.country : '';\n \n TractorDetail.update({\"TractorID\":tractorId}, {$set:tractorDetailUpdateData}, function(err, updatedTractor){\n if( !err ){\n modules.logger.info( \"successfully updated tractor address for tractorID \" + tractorId);\n response.complete();\n }\n });\n \n \n // Sample Data \n /*\n [ \n 'tractor_id' => '500182',\n 'latitude' => 6.526657,\n 'longitude' => 7.008498,\n 'street' => 'Unnamed Road',\n 'town' => ' Umuabu',\n 'country' => ' Nigeria',\n\t] */\n}" }, "deprecated_getTractorLatLngSummaryForDateRange" : { "code" : "// function onRequest(request, response, modules) {\n \n// var Tractor = modules.collectionAccess.collection('DailyTractorActivity');\n// var findQuery = {updatedAt: {$gte:\"2018-11-01\", $lte:\"2018-11-07\"}, TractorID:500645}\n// //\n// Tractor.find({TractorID:500645}, function(err, _summaries){\n// \tmodules.logger.info(JSON.stringify(_summaries));\n// \tresponse.complete();\n// })\n \n// }" }, "deprecated_update-daily-real-time-tractor-activity" : { "code" : "// function onRequest(request, response, modules){\n \n// //This endpoint fetches the data from 2track for activity summary and updates the active, idle and distance values\n \n// var collectionAccess = modules.collectionAccess,\n// logger = modules.logger,\n// async = modules.async,\n// moment = modules.moment,\n// requestContext = modules.requestContext, \n// token = \"\";\n \n// //var today = moment.utc().format('2017-06-27');\n// \tvar today = moment.utc().format('YYYY-MM-DD');\n// //logger.info(\"Today's date is: \"+today);\n \n// //Get 2track access token\n// collectionAccess.collection('TwoTrackApiToken').findOneAsync({id: 9228383772})\n// .then(function(accessToken) {\n// token = accessToken;\n \n// },\n// function(err) {\n \n// return response.error(err);\n// });\n \n// modules.collectionAccess.collection('DailyTractorActivity').find({day: today}, function (err, activities) {\n\n// activities.forEach(function(activity, a){\n// //copy the data over to the new collection\n// async.parallel({\n// updateClone: async.apply(updateClone, activity)\n// });\n// }\n// );\n// //response.complete();\n// \t});\n \n// function updateClone(activity){\n// //logger.info('\"'+activity.TractorID+'\"');\n \n// var payloadOptions = {\n// token: \"\"+token.token+\"\",\n// trackerId: \"\"+activity.TractorID+\"\",\n// startDateTime: \"\"+today+\" 00:00:00\",\n// endDateTime: \"\"+today+\" 23:59:59\",\n// timezoneDifference: 100\n// },\n// requestOptions = {\n// url: 'https://hellotractor.2-track.com:8080/api/summary/activity',\n// method: 'POST',\n// headers: {\n// 'Content-Type': 'application/json'\n// },\n// json: true,\n// body: payloadOptions\n// };\n \n// modules.request.request(requestOptions, function(err, resp, body) {\n \n// if(err) {\n// logger.error(\"Error placing request to 2track\");\n// //return;\n// } else {\n// if(!resp.body.data[0]) {\n// logger.error(\"Error: No data available for tractor \"+activity.TractorID);\n// //return;\n// } else {\n// var data = resp.body.data,\n// startDate = new Date(''+today+' 00:00:00'),\n// endDate = new Date(),\n// seconds = (endDate - startDate) / 1000;\n \n// var inactiveTime = parseInt((seconds - (resp.body.data[0].operateTime)).toFixed());\n// //logger.error(\"inactiveTime for: \"+activity.TractorID+\" is: \" +inactiveTime);\n \n// collectionAccess.collection('DailyTractorActivity').update(\n// {\n// TractorID: activity.TractorID, \n// day: resp.body.data[0].summaryDate\n// },\n// {\n// $set: {\n// TotalTimeActive: resp.body.data[0].operateTime,\n// TotalTimeIdle : inactiveTime,\n// DistanceTravelled : resp.body.data[0].distance\n// }\n// }, function(err) {\n// if(err) {\n// //return response.error(err);\n// logger.info(\"error\");\n// }\n\n// //return response.complete(200);\n// logger.info(\"Successfully updated for tractor \" +activity.TractorID+\" on day: \"+ activity.day+ \" with data: \"+resp.body.data[0].operateTime+\" \"+resp.body.data[0].distance+ \" \"+ inactiveTime);\n// });\n// }\n// }\n \n// });\n \n// }\n \n// //response.complete();\n \n// }" }, "deprecated_aeris-tractors-location" : { "code" : "// function onRequest(request, response, modules){\n \n// /*\n// This endpoint gets the status of each tractor from AERIS and updates it with the latest reading from the monitoring device\n// */\n \n// var collectionAccess = modules.collectionAccess,\n// async = modules.async,\n// logger = modules.logger,\n// moment = modules.moment,\n// token = \"\",\n// JOHN_DEERE_5065 = 3,\n// JOHN_DEERE_5075 = 19,\n// MAHINDRA_6005 = 9;\n// var req = modules.request;\n \n// //Get tractors and loop through the tractors\n// modules.collectionAccess.collection('TractorDetail').find({ServiceProvider: \"AERIS\"}, function (err, tractors) {\n\n// tractors.forEach(function(tractor, a){\n\n// if(tractor.TractorID.toString().length === 6){\n \n// var payloadOptions = {\n// \"tractor_id\": \"\"+tractor.TractorID+\"\"\n// },\n// requestOptions = {\n// url: 'https://cloud.hellotractor.com/api/v1/tractor/'+tractor.TractorID+'/location',\n// method: 'POST',\n// headers: {\n// 'Content-Type': 'application/json',\n// 'Accept': 'application/json'\n// },\n// json: true,\n// body: payloadOptions\n// };\n \n// modules.request.request(requestOptions, function(err, resp, body) {\n// logger.info(\"Data returned is:\" + JSON.stringify(body.data));\n// if(err) {\n// return cb(err);\n// } else {\n// if(!body.data) {\n// logger.info(\"There was no data in body for tractor: \"+ tractor.TractorID);\n// return;\n// } else {\n// logger.info(\"Successfully placed http request for tractor status for: \" + tractor.TractorID);\n \n// async.parallel({\n// updateAerisTractorData: async.apply(updateAerisTractorData, body, tractor.TractorID, tractor)\n// });\n// }\n// }\n\n// //response.complete(200);\n// });\n// }\n// }); //end forEach tractors\n// });//end collectionAccess get all tractors\n \n\n// function updateAerisTractorData(aerisData, cb, tractor) {\n \n// logger.info('AERIS data -> last_reported_time' + ((aerisData.last_reported_time)));\n\n// if(aerisData.length === 0) {\n// logger.info(\"AERIS: No status for tractor \" + tractor.TractorID);\n// return;\n// }\n \n// var dataObject = {\n// PositionLongitude: parseFloat(aerisData.longitude),\n// PositionLatitude: parseFloat(aerisData.latitude),\n// Speed: aerisData.speed,\n// UpdatedAt: modules.moment().format('YYYY-MM-DD HH:mm:ss'),\n// LastActiveTime: aerisData.last_reported_time\n// };\n \n// var fuel = getFuelPercentage(aerisData.status_from_2track, tractor);\n// var heading = getHeading(aerisData.status_from_2track, tractor);\n \n// if (fuel){\n// dataObject.FuelVolume = fuel;\n// }\n \n// if (heading){\n// dataObject.Heading = heading;\n// }\n \n// dataObject['_kmd.lmt'] = moment().toISOString();\n// //logger.info(\"LastActiveTime is: \"+ setObject.LastActiveTime);\n \n// collectionAccess.collection('TractorDetail').update({TractorID: tractor.TractorID},\n// {\n// $set: dataObject\n\n// }, function(err) {\n// if(err) {\n// return response.error(err);\n// }\n\n// //return response.complete(200);\n// }); \n \n// logger.info(\"AERIS: Finished updating tractor: \" + tractor.TractorID + \" \" + aerisData.latitude + \" \" + aerisData.longitude);\n// }\n\n \n// var getFuelPercentage = function(status_from_2track, tractor){\n// if (status_from_2track){\n// var fuelRawValue = JSON.parse(status_from_2track).fuelRawValue;\n// if (fuelRawValue && fuelRawValue != 0){\n// var fuelLitres;\n// if (tractor.TractorModelID == JOHN_DEERE_5065 || tractor.TractorModelID == JOHN_DEERE_5075){\n// //John Deere 5065\n// // fuelLitres = (-0.0151 * fuelRawValue) + 74.763;\n// fuelLitres = fuelRawValue/100.0;\n// } else if (tractor.TractorModelID == MAHINDRA_6005) {\n// //Mahindra 6005\n// // fuelLitres = (-0.0201 * fuelRawValue * fuelRawValue) + (0.6209 * fuelRawValue) + 1.3056;\n// fuelLitres = fuelRawValue/100.0;\n// } else {\n// //Others\n// fuelLitres = 0.0; \n// }\n// return parseInt(fuelLitres);\n// } else {\n// return;\n// }\n// } else {\n// return;\n// }\n// }\n \n// var getHeading = function(status_from_2track2, tractor){\n// if (status_from_2track2){\n// var heading = JSON.parse(status_from_2track2).heading;\n// if (heading){\n// return heading;\n// }\n// }\n// return;\n// }\n\n// }\n" }, "deprecated_temp-update-daily-activities-from-web-app" : { "code" : "// function onRequest(request, response, modules){\n \n// var collectionAccess = modules.collectionAccess,\n// logger = modules.logger,\n// async = modules.async,\n// moment = modules.moment,\n// requestContext = modules.requestContext,\n// token = \"\";\n \n// \tvar today = moment.utc().format('2017-05-02');\n// modules.collectionAccess.collection('DailyTractorActivity').find({day: today}, function (err, activities) {\n\n// activities.forEach(function(activity, a){\n// //copy the data over to the new collection\n// async.parallel({\n// updateClone: async.apply(updateClone, activity)\n// });\n// }\n \n// );\n// //response.complete();\n// \t});\n \n// function updateClone(activity){\n// //logger.info('\"'+activity.TractorID+'\"');\n \n// var payloadOptions = {\n// token: \"\"+token.token+\"\",\n// trackerId: \"\"+activity.TractorID+\"\",\n// startDateTime: \"\"+today+\" 00:00:00\",\n// endDateTime: \"\"+today+\" 23:59:59\",\n// timezoneDifference: 100\n// },\n// requestOptions = {\n// url: 'https://hellotractor.2-track.com:8080/api/summary/activity',\n// method: 'POST',\n// headers: {\n// 'Content-Type': 'application/json'\n// },\n// json: true,\n// body: payloadOptions\n// };\n \n// modules.request.request(requestOptions, function(err, resp, body) {\n// //logger.info(\"about to make request\");\n// if(err) {\n// logger.error(\"Error placing request to 2track\");\n// //return;\n// } else {\n// if(!resp.body.data[0]) {\n// logger.error(\"Error: No data available for tractor \"+activity.TractorID);\n// //return;\n \n \n// } else {\n// var data = resp.body.data; \n// //logger.info(\"Successfully placed http request for t \"+activity.TractorID+\" and data is: \" + JSON.stringify(resp.body));\n// var inactiveTime = 86400 - (resp.body.data[0].operateTime);\n// //logger.error(\"inactiveTime: \"+inactiveTime);\n \n// collectionAccess.collection('DailyTractorActivity').update(\n// {\n// TractorID: activity.TractorID, \n// day: resp.body.data[0].summaryDate\n// },\n// {\n// $set: {\n// TotalTimeActive: resp.body.data[0].operateTime,\n// TotalTimeIdle : inactiveTime,\n// DistanceTravelled : resp.body.data[0].distance\n// }\n// }, function(err) {\n// if(err) {\n// //return response.error(err);\n// logger.info(\"error\");\n// }\n\n// //return response.complete(200);\n// logger.info(\"Successfully updated for tractor \" +activity.TractorID+\" on day: \"+ activity.day);\n// });\n// }\n// }\n \n// });\n \n// }\n \n// }" }, "deprecated_UpdateAerisTractorActiveTimeToday" : { "code" : "// //Runs every three minutes to retrieve the total active time for today\n// //for all aeris tractors on cloud.hellotractor.com\n// //Created by Abdulmajid on 19/06/2018\n\n// function onRequest(request, response, modules) {\n// var tractorDetailCollection = modules.collectionAccess.collection(\"TractorDetail\");\n// var log = modules.logger;\n// var loggerCollection= modules.collectionAccess.collection(\"Logger\");\n// var LOG_ID = 105;\n// var count = 0;\n// var size = 0;\n// var startTime = modules.moment().valueOf();\n// var todaysDate = modules.moment.utc().format('YYYY-MM-DD');\n \n \n// loggerCollection.find({logID:LOG_ID}, {}, function(err1, logs){ \n// tractorDetailCollection.find({TractorID: {$gte:500000}, LastActiveTime: {$gte:todaysDate}}, {}, function(err, docs){\n// var startFrom = 0;\n// if (logs[0].Message < docs.length){\n// startFrom = logs[0].Message;\n// }\n \n// size = docs.length;\n// count = startFrom;\n// log.info(\"Size: \"+size+\", Start From: \"+startFrom);\n \n// //Iterate through all tractors to request weather data via geonames api\n// for (var i = startFrom; i < docs.length; i++){\n// var tractorDetail = docs[i];\n\n// if (tractorDetail.TractorID){\n// // modules.logger.info(JSON.stringify(booking));\n// makeRequest(tractorDetail);\n\n// } else {\n// count++;\n// \t\t\t\t\t\t\t\tshouldCompleteRequest(); \n// } //End if booking is not 0\n \n// } //end for loop\n// });\n// });\n \n// var makeRequest = function (tractorDetail){\n// \tmodules.request.request(getRequestOptions(tractorDetail), function(err2, resp, body) {\n// if(err2) {\n// count++;\n// \t\t\t\t\t\tshouldCompleteRequest();\n// } else {\n// if(!body) {\n// modules.logger.info(\"There was no data in body for booking: \"+ url);\n// count++;\n// \t\t\t\t\t\t\tshouldCompleteRequest(); \n// } else {\n// updateTractorDetailCollection(tractorDetail, body);\n// }\n// }\n// }); //end request \n// } \n \n// var updateTractorDetailCollection = function (tractorDetail, activityToday){ \n// tractorDetailCollection.update({_id:tractorDetail._id}, \n// {$set: {\n// \"ActiveTimeToday\":computeActiveTimeToday(activityToday), \n// \"UpdatedAt\":modules.moment().format('YYYY-MM-DD HH:mm:ss')\n// }}, \n// {upsert: false, _id:1}, \n// function(tractorErr, tractorDetailDoc){\n// \t\t\tcount++;\n// shouldCompleteRequest();\n// }); //End update tractor detail with active time today \n// } //end updateTractorDetailCollection function \n\n\n// var shouldCompleteRequest = function(){\n// var duration = modules.moment().valueOf() - startTime;\n// if (count >= size || duration >= 19000){\n// log.info(\"Total: \"+count);\n\n// //Update logger and finish task\n// loggerCollection.update({logID:LOG_ID}, {$set: {Message:count}}, {upsert: false}, function(logErr, logDoc){\n// response.complete(); \n// }); //End update logger collection with last count \n// }//end if \n// }\n// } //end onRequest function\n\n\n// function computeActiveTimeToday(activityToday){\n// try {\n// if (activityToday[0]){\n// var totalActiveTime = Number(activityToday[0].total_active_time) + Number(activityToday[0].total_inactive_time);\n// return totalActiveTime;\n// } \n// } catch(err){\n// } \n \n// return 0;\n// }\n\n// function getRequestOptions(tractorDetail){\n// \tvar url = \"https://cloud.hellotractor.com/api/v1/tractors/daily/activities/summary?tractor_id=\"+tractorDetail.TractorID+\"&day=\"+modules.moment.utc().format('YYYY-MM-DD');\n// var requestOptions = {url:url, method: 'GET', \n// \t\t\t\theaders: {\n// \t'Content-Type': 'application/json',\n// \t'Accept': 'application/json'\n// \t},\n// json: true\n// }; \n// return requestOptions;\n// }" }, "deprecated_UpdateTractorDetailAddress" : { "code" : "// //Retrieves the country, state and town of tractors every 3 minutes from http://api.geonames.org\n// //Logs the last tractor processed in the logger collection and continues from where it left off\n// //Created by Abdulmajid on 2018/06/17\n\n// function onRequest(request, response, modules) {\n// var tractorDetailCollection = modules.collectionAccess.collection(\"TractorDetail\");\n// var log = modules.logger;\n// var loggerCollection= modules.collectionAccess.collection(\"Logger\");\n// var LOG_ID = 104; //Unique ID to log tractor detail address updated endpoint\n// var count = 0;\n// var size = 0;\n// var startTime = modules.moment().valueOf();\n// var todaysDate = modules.moment.utc().format('YYYY-MM-DD');\n// var todaysDateTime = modules.moment().utc().format('YYYY-MM-DD HH:mm:ss');\n \n// var shouldCompleteRequest = function(){\n// var duration = modules.moment().valueOf() - startTime;\n// if (count >= size || duration >= 19000){\n// log.info(\"Total: \"+count);\n\n// //Update logger and finish task\n// loggerCollection.update({logID:LOG_ID}, {$set: {Message:count}}, {upsert: false}, function(logErr, logDoc){\n// response.complete(); \n// }); //End update logger collection with last count \n// } //end if \n// }\n\n// var updateTractorDetailCollection = function (tractorDetail, geoData){\n// if (geoData.geonames){\n// \t\t\tmodules.logger.info(geoData.geonames[0].name);\n// } \n \n// var filteredAddress = {\n// \"Town\":extractState(geoData), \n// \"Country\":extractCountry(geoData),\n// \"Street\":extractStreet(geoData)\n// };\n \n// if (filteredAddress.Town || filteredAddress.Country || filteredAddress.Street){\n// tractorDetailCollection.update({_id:tractorDetail._id}, \n// {$set: filteredAddress},\n// {upsert: false, _id:1}, \n// function(tractorErr, bookingDoc){\n// count++;\n// shouldCompleteRequest();\n// }); //End update booking with local government \n// } else {\n// count++;\n// shouldCompleteRequest(); \n// }\n// } //end updateBookingsCollection function\n \n// var makeRequest = function (tractorDetail){\n// \tmodules.request.request(getRequestOptions(tractorDetail), function(err2, resp, body) {\n// if(err2) {\n// count++;\n// \t\t\t\t\t\tshouldCompleteRequest();\n// } else {\n// if(!body) {\n// modules.logger.info(\"There was no data in body for booking: \"+ url);\n// count++;\n// shouldCompleteRequest();\n// } else {\n// updateTractorDetailCollection(tractorDetail, body);\n// }\n// }\n// }); //end request \n// }\n\n// //Find last data logged\n// loggerCollection.find({logID:LOG_ID}, {}, function(err1, logs){\n \n// //Find all tractors in the database: LastActiveTime: {$gte: todaysDate}\n// var lastActiveTimeQuery = {LastActiveTime: {$gte:todaysDate}};\n// tractorDetailCollection.find(lastActiveTimeQuery, {\"sort\":{\"_id\":1}}, function(err, docs){\n \n// //Start from where it left off\n// var startFrom = 0;\n// if (logs[0].Message < docs.length){\n// startFrom = logs[0].Message; \n// }\n \n// size = docs.length;\n// count = startFrom;\n// log.info(\"Size: \"+size+\", Start From: \"+startFrom);\n \n// //Iterate through all tractors to request weather data via geonames api\n// for (var i = startFrom; i < docs.length; i++){\n// \t\t\tvar tractorDetail = docs[i];\n \n// if (tractorDetail.PositionLatitude && tractorDetail.PositionLongitude){\n// // modules.logger.info(JSON.stringify(booking));\n// makeRequest(tractorDetail);\n \n// } else {\n// count++;\n// shouldCompleteRequest();\n// //end if \n// } //End if booking is not 0\n \n\n// } //end for loop\n// }); //end find bookings collection \n// }); //end find logID data\n// } //End onRequest function\n\n// function getRequestOptions(tractorDetail){\n// var requestOptions = {url:\"http://api.geonames.org/findNearbyPlaceNameJSON?lat=\"+tractorDetail.PositionLatitude+\"&lng=\"+tractorDetail.PositionLongitude+\"&username=hellofuture\", method: 'POST', \n// \t\t\t\theaders: {\n// \t'Content-Type': 'application/json',\n// \t'Accept': 'application/json'\n// \t},\n// json: true\n// }; \n// return requestOptions;\n// }\n\n// function extractCountry(body){ \n// if (body.geonames){\n// \t\t\treturn body.geonames[0].countryName;\n// }\n// return;\n// \t}\n \n \n// function extractState(body){\n// if (body.geonames){ \n// \t\treturn body.geonames[0].adminName1;\n// }\n// return;\n// }\n\n\n// function extractStreet(body){\n// if (body.geonames){\n// \t\treturn body.geonames[0].name;\n// } else {\n// return;\n// }\n// }" }, "deprecated_fetch-store-tractor-activities-one" : { "code" : "// function onRequest(request, response, modules){\n \n// var collectionAccess = modules.collectionAccess,\n// logger = modules.logger,\n// async = modules.async,\n// moment = modules.moment;\n// var token = \"\";\n\n// collectionAccess.collection('TwoTrackApiToken').findOneAsync({id: 9228383772})\n// .then(function(accessToken) {\n// token = accessToken;\n \n// },\n// function(err) {\n \n// return response.error(err);\n// });\n \n// modules.collectionAccess.collection('TractorDetail').find({\n// TractorID: {\n// $gte: 100001,\n// $lte: 100050\n// }\n// }, function (err, tractors) {\n\n// tractors.forEach(function(tractor, a){\n// if(tractor.TractorID.toString().length === 6){\n\n// //Make request to 2track and store data in collection\n// var startActivityId = tractor.LastActivityId ? tractor.LastActivityId : 0,\n// payloadOptions = {\n// token: \"\"+token.token+\"\",\n// trackerId: tractor.TractorID,\n// startActivityId: startActivityId,\n// rowCount: 101,\n// startUTCTime: \"\",\n// endUTCTime: \"\"\n// },\n// requestOptions = {\n// url: 'https://hellotractor.2-track.com:8080/api/activity',\n// method: 'POST',\n// headers: {\n// 'Content-Type': 'application/json',\n// 'Accept': 'application/json',\n// 'Version': 'v1'\n// },\n// json: true,\n// body: payloadOptions\n// };\n\n// modules.request.request(requestOptions, function(err, resp, body) {\n// if(err) {\n// logger.error(\"Error placing request to 2track\");\n// return;\n// } else {\n// if(!body.data) {\n// logger.error(\"Error: No data available for tractor\");\n// return;\n// } else {\n// //logger.info(\"Successfully placed http request for tractor updates for: \" + tractor.TractorID);\n// async.parallel({\n// saveTractorActivities: async.apply(saveTractorActivities, body.data, tractor.TractorID),\n// updateTractorDetail: async.apply(updateTractorDetail, body.data, tractor.TractorID, tractor)\n// });\n// }\n// }\n// //response.complete(200);\n// });\n// }\n// });\n// });\n \n// function saveTractorActivities(tractorActivities, tractorId){\n// //logger.info(\"in function saveTractorActivities and tractor activityId is: \"+tractor.activityId);\n \n// tractorActivities.forEach(function(tractor, a) {\n \n// var entity = modules.kinvey.entity();\n// entity.TractorID = tractorId;\n// entity.ActivityID = tractor.activityId;\n// entity.EventCode = tractor.eventCode;\n// entity.EventName = tractor.eventName;\n// entity.Speed = tractor.speed;\n// entity.Odometer = tractor.odometer;\n// entity.Idle = tractor.idle;\n// entity.IsGPSValid = tractor.isGPSValid;\n// entity.Lat = tractor.lat;\n// entity.Lng = tractor.lon;\n// entity.DirectionEW = tractor.directionEW;\n// entity.DirectionNS = tractor.directionNS;\n// entity.Altitude = tractor.altitude;\n// entity.IgnitionStatus = tractor.ignitionStatus;\n// entity.BatteryVoltage = tractor.batteryVoltage;\n// entity.SatelliteNumber = tractor.satelliteNumber;\n// entity.Street = tractor.street;\n// entity.Town = tractor.town;\n// entity.County = tractor.county;\n// entity.Country = tractor.country;\n// entity.ActivityUTCDate = tractor.activityUTCDate;\n\n// collectionAccess.collection('TractorActivityData').save(entity, function(err) {\n// logger.info(\"Successfully saved data for tractor with ID: \" + tractorId);\n// });\n// });\n \n// //response.complete();\n// }\n \n// //update coordinates and address of tractor, send geofence push notifications\n// function updateTractorDetail(activities, cb, tractor) {\n// //logger.info(\"Begining process for updating tractor and tractor data is:\" + tractor.TractorID);\n\n// if(activities.length === 0) {\n// logger.info(\"No activities data for tractor \" + tractor.TractorID);\n// return;\n// //return cb();\n// }\n// var lastActivity = activities.reduce(function(prev, curr) {\n// return prev.activityUTCDate > curr.activityUTCDate ? prev : curr;\n// });\n\n// var setObject = {\n// LastActiveTime: lastActivity.activityUTCDate\n// };\n\n// if(lastActivity.lat && lastActivity.lon) {\n\n// setObject.PositionLatitude = lastActivity.lat;\n// setObject.PositionLongitude = lastActivity.lon;\n// setObject.LastActivityId = lastActivity.activityId;\n\n// // if(lastActivity.country){\n// // setObject.Street = lastActivity.street;\n// // setObject.Town = lastActivity.town;\n// // setObject.Country = lastActivity.country;\n// // }\n// setObject['_kmd.lmt'] = moment().toISOString();\n\n// collectionAccess.collection('TractorDetail').update({TractorID: cb},\n// {\n// $set: setObject\n\n// }, function(err) {\n// if(err) {\n// return response.error(err);\n// }\n\n// //return response.complete(200);\n// });\n\n// }\n// else{\n// response.complete(400);\n// //return cb();\n// }\n// }\n// //response.complete();\n// }" }, "deprecated_update-2track-token" : { "code" : "// function onRequest(request, response, modules){\n \n// var collectionAccess = modules.collectionAccess,\n// logger = modules.logger,\n// async = modules.async;\n// var req = modules.request;\n \n// req.get('https://cloud.hellotractor.com/kinvey/api/twotrack/token', function(error, resp, body){\n// if (error){\n// response.body = {error: error.message};\n// response.complete(400);\n// return;\n// }\n \n// async.parallel({\n// updateToken: async.apply(updateToken, body),\n// });\n \n// logger.info(\"Successfully placed http request for token and body is: \" + body);\n// response.complete();\n// });\n\n// function updateToken(data) {\n \n// collectionAccess.collection('TwoTrackApiToken').update({id: 9228383772}, {\n// $set: {\n// token: data\n// }\n// }, function(err) {\n// if(err) {\n// return response.error(err);\n// }\n// response.body = {};\n// return response.complete(200);\n// });\n// }\n// }" }, "PushNotificationWhenTractorNearby" : { "code" : "function onRequest(request, response, modules) {\n var bookingsCol = modules.collectionAccess.collection(\"ServiceBookings\");\n var tractorsCol = modules.collectionAccess.collection(\"TractorDetail\");\n var userCol = modules.collectionAccess.collection(\"user\");\n var notificationCol = modules.collectionAccess.collection(\"Notification\");\n var tractorOperatorCol = modules.collectionAccess.collection(\"TractorOperator\");\n var now = modules.moment().utc().format('YYYY-MM-DD HH:mm:ss');\n var threeDaysLater = modules.moment().utc().add(3, 'days').format('YYYY-MM-DD HH:mm:ss');\n var count = 0;\n var countBookings = 0;\n var push = modules.push;\n var log = modules.logger;\n \n \n //retrieve paired bookings whose service date is between now and three days time && where tractor availability is true\n //if bookings are found, for each booking, retrieve tractor and calculate distance between booking and tractor\n //if distance is less than 30 km, find user and 1. send notification to agent, 2. save notification to Notifications, 3. update tractor availability to false\n \n \n \n bookingsCol.find({serviceDate: {\"$gt\": now}, serviceDate: {\"$lte\": threeDaysLater}, $or: [{bookingStatus: 1}, {bookingStatus: 2}], ReceiveTractorAvailabilityNotification: true}, {}, function(bookingsErr, bookings){\n if (bookings){\n countBookings = bookings.length;\n log.info(\"Bookings found: \"+countBookings);\n bookings.forEach(function(booking){\n log.info(\"Processing booking: \"+booking.bookingID);\n calculateTractorDistance(booking, Number(booking.tractorPairedTo));\n });\n } else {\n log.info(\"No bookings found\"); \n response.complete(); \n }\n // modules.logger.info(bookings.length);\n });\n \n \n var calculateTractorDistance = function(booking, tractorId){\n tractorsCol.findOne({TractorID: tractorId}, function(tractorErr, tractor){\n if (tractor){\n log.info(\"Tractor found: \"+tractor.TractorID);\n var distanceBetween = distance(tractor.PositionLatitude, tractor.PositionLongitude, booking.latitude, booking.longitude, \"K\");\n if (distanceBetween < 15 && tractor.PositionLatitude != 0 && tractor.PositionLongitude != 0 && booking.latitude != 0 && booking.longitude != 0){\n log.info(\"Distance: \"+distanceBetween);\n pushNotificationToAgent(booking, tractor, distanceBetween);\n } else {\n log.info(\"Distance greater than 15: \"+distanceBetween);\n count++\n shouldComplete();\n }\n } else {\n log.info(\"Tractor not found: \"+tractorId);\n count++;\n shouldComplete();\n }\n });\n }\n \n var pushNotificationToAgent = function(booking, tractor, distanceBetween){\n userCol.findOne({\"_acl.creator\": booking._acl.creator}, function(userErr, user){\n if (user){\n log.info(\"User found: \"+user._id);\n tractorOperatorCol.findOne({OperatorID: tractor.OperatorID}, function(tractorOperatorErr, tractorOperator){\n if (tractorOperator){\n log.info(\"Operator found: \"+tractorOperator.OperatorID);\n var pushNotification = buildTractorNearbyNotification(user, tractor, booking, distanceBetween, tractorOperator);\n var notificationToSave = buildNotificationToSave(pushNotification);\n \n notificationCol.save(notificationToSave, function(notificationErr){\n log.info(\"Notificaiton saved\");\n \n pushNotification.id = pushNotification._id;\n push.sendPayload(user, {}, {}, pushNotification, function(res) {\n log.info(\"Push notification sent\"); \n bookingsCol.update({_id: booking._id}, {$set: {\"ReceiveTractorAvailabilityNotification\": false}}, {upsert: false}, function(updateBookingErr, updatedBooking){\n log.info(\"Booking updated\");\n count++;\n shouldComplete();\n });\n });\n \n });\n } else {\n log.info(\"Operator not found\");\n count++;\n shouldComplete();\n }\n });\n // modules.kinvey.entity(notification);\n } else {\n log.info(\"User not found\");\n count++;\n shouldComplete();\n }\n });\n }\n \n var shouldComplete = function(){\n if (count >= countBookings){\n response.complete();\n }\n }\n }\n \n function buildTractorNearbyNotification(user, tractor, booking, distance, tractorOperator){\n var message, hectaresDistance;\n if (booking.serviceType == 107){\n message = \"Tractor \"+tractor.license_plate_number+\" is \"+distance+\" km away. Call the operator to make preparations for your \"+booking.distanceToDestination+\" km \"+getServiceName(booking.serviceType)+\" request scheduled for \"+booking.serviceDate;\n hectaresDistance = booking.distanceToDestination;\n } else{\n message = \"Tractor \"+tractor.license_plate_number+\" is \"+distance+\" km away. Call the operator to make preparations for your \"+booking.hectaresServiced+\" Ha \"+getServiceName(booking.serviceType)+\" request located at \"+booking.farmLocation+\" scheduled for \"+booking.serviceDate;\n hectaresDistance = booking.hectaresServiced;\n }\n \n var notification = {\n message: message,\n type: \"action\",\n _acl: user._acl,\n userId: user._id,\n read: false,\n action: \"tractor_nearby\",\n tractorId: tractor.TractorID,\n tractorName: tractor.TractorName,\n licensePlate: tractor.license_plate_number,\n farmLocation: booking.farmLocation,\n hectaresDistance: hectaresDistance,\n serviceType: booking.serviceType,\n serviceDate: booking.serviceDate,\n tractorDistance: distance,\n orgID: booking.orgID,\n operatorId: tractorOperator.OperatorID,\n operatorPhone: tractorOperator.MobileNumber,\n clusterID: booking.clusterID\n };\n \n return modules.kinvey.entity(notification);\n }\n \n function buildNotificationToSave(pNotification){\n var notification = {\n message: pNotification.message,\n read: pNotification.read,\n type: pNotification.type,\n action: pNotification.action,\n orgID: pNotification.orgID,\n serviceType: pNotification.serviceType,\n clusterID: pNotification.clusterID,\n userId: pNotification.userId,\n _id: pNotification._id,\n _acl: pNotification._acl,\n _kmd: pNotification._kmd,\n extras: pNotification\n } \n \n return notification;\n }\n \n function distance (lat1, lon1, lat2, lon2, unit) {\n var radlat1 = Math.PI * lat1/180;\n var radlat2 = Math.PI * lat2/180;\n var theta = lon1-lon2;\n var radtheta = Math.PI * theta/180;\n var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);\n if (dist > 1) {\n dist = 1;\n }\n dist = Math.acos(dist);\n dist = dist * 180/Math.PI;\n dist = dist * 60 * 1.1515;\n if (unit==\"K\") {\n dist = dist * 1.609344\n }\n if (unit==\"N\") { \n dist = dist * 0.8684 \n }\n return dist;\n } " }, "getTractorServiceTypes" : { "code" : "function onRequest(request, response, modules) {\n \n var serviceTypes = {\n '101': 'Tilling',\n '102': 'Ploughing',\n '103': 'Ridging',\n '104': 'Planting/Seeding',\n '105': 'Irrigating',\n\t\t'106': 'Harvesting',\n '107': 'Trailing',\n '108': 'Harvesting',\n\t\t'109': 'Harrowing',\n '110': 'Spreading',\n '113': 'Bioagtive',\n '114': 'Dozer',\n '115': 'Mower',\n '116': 'Drilling',\n '117': 'Rotavator',\n '118': 'Laser Leveler',\n '119': 'Threshing',\n '120': 'Threshing',\n '121': 'Blade Leveling'\n }\n \n response.complete();\n \n \n}" }, "SyncTractorsFromAWSBackend" : { "code" : "function onRequest(request, response, modules) {\n var Tractor = modules.collectionAccess.collection('TractorDetail');\n var Log = modules.logger;\n var tractor_data = request.body;\n\n // Save Tractor To TractorDetail collection \n var tractor = {};\n tractor.TractorID = tractor_data.tracker_id;\n tractor.BookingRequests = true;\n tractor.Characteristic = \"\";\n tractor.Country = \"Nigeria\";\n tractor.CreatedAt = tractor_data.created_at;\n tractor.Currency = \"\";\n tractor.DailyTractorUpdates = true;\n tractor.Efficiency = 0;\n tractor.EngineHours = tractor_data.total_engine_hours;\n tractor.FixedEngineHours = 0;\n tractor.FuelVolume = 0;\n tractor.Group = \"Atman Corporation\";\n tractor.Heading = 0;\n tractor.ImplementsAttached = \"\";\n tractor.LastActiveTime = tractor_data.last_reported_time;\n tractor.LastGeofenceNotificationTime = \"\";\n tractor.Latitude = tractor_data.latitude;\n tractor.Longitude = tractor_data.longitude;\n tractor.NeedToSendGeofenceOutNotification = true;\n tractor.OperatorID = tractor_data.operator_id;\n tractor.PositionLatitude = tractor_data.latitude;\n tractor.PositionLongitude = tractor_data.longitude;\n tractor.ServiceProvider = \"AERIS\";\n tractor.Speed = 0;\n tractor.Status = 0;\n tractor.Street = \"\";\n tractor.TotalDistanceCovered = tractor_data.total_distance_covered;\n tractor.TotalHectaresTilled = 0;\n tractor.Town = \"\";\n tractor.TractorModelID = tractor_data.tractor_model_id;\n tractor.TractorName = tractor_data.name;\n tractor.UpdatedAt = tractor_data.updated_at;\n tractor.UtcOffset = 0;\n tractor.WasImmobilized = false;\n tractor.WasInArea = true;\n tractor._acl = {\"creator\":\"5a8317528651f253f07b38fc\",\"gr\":true};\n tractor.license_plate_number = \"\";\n tractor.FuelRawValue = 0;\n tractor.IgnitionStatus = 0;\n tractor.AssetState = \"Off\";\n tractor.FuelLevelVoltage = 0;\n tractor._kmd = { \"lmt\": \"2019-05-05T11:24:36.965Z\", \"ect\": \"2019-05-05T05:14:05.023Z\"};\n\nTractor.save(tractor, function(err, saved){\n if(err){\n Log.info('an error occured' + err );\n response.body = {\"service\": \"syncing service : tractor not saved successfully\"};\n response.complete();\n }\n Log.info(\"successfully saved tractor with the id of \" + tractor_data.tracker_id );\n response.body = {\"service\": \"syncing service : tractor saved successfully\"};\n response.complete();\n})\n\n }\n \n " }, "updateTractorIDsToNewIDUsingOldID" : { "code" : " var tractors = [\n {\n \"TRAXI ID\": \"TRAXI/TRJD0001-148\",\n \"TRACTOR ID\": 500356,\n \"OLD ID\": 100084,\n \"LICENCE PLATE\": \"YAB148YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101228,\n \"IMSI\": 204043397060028,\n \"BRAND\": \"John Deere\",\n \"MODEL\": 5065,\n \"IMEI\": 352431066063554,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRJD0002-149\",\n \"TRACTOR ID\": 500376,\n \"OLD ID\": 100123,\n \"LICENCE PLATE\": \"YAB149YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101299,\n \"IMSI\": 204043397060077,\n \"BRAND\": \"John Deere\",\n \"MODEL\": 5065,\n \"IMEI\": 352431066099913,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Partial\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRJD0003-150\",\n \"TRACTOR ID\": 500283,\n \"OLD ID\": 100036,\n \"LICENCE PLATE\": \"YAB150YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731100949,\n \"IMSI\": 204043397059982,\n \"BRAND\": \"John Deere\",\n \"MODEL\": 5065,\n \"IMEI\": 352431066057663,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Partial\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRJD0004-151\",\n \"TRACTOR ID\": 500264,\n \"OLD ID\": 100077,\n \"LICENCE PLATE\": \"YAB151YR\",\n \"EDIT AERTRAK\": \"TRUE\",\n \"ESN\": 1731100922,\n \"IMSI\": 204043397060003,\n \"BRAND\": \"John Deere\",\n \"MODEL\": 5065,\n \"IMEI\": 352431066085425,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Partial\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRJD0005-152\",\n \"TRACTOR ID\": 500346,\n \"OLD ID\": 100066,\n \"LICENCE PLATE\": \"YAB152YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101217,\n \"IMSI\": 204043397060045,\n \"BRAND\": \"John Deere\",\n \"MODEL\": 5065,\n \"IMEI\": 352431066083651,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Pending\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRJD0006-153\",\n \"TRACTOR ID\": 500375,\n \"OLD ID\": 100124,\n \"LICENCE PLATE\": \"YAB153YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101298,\n \"IMSI\": 204043397059986,\n \"BRAND\": \"John Deere\",\n \"MODEL\": 5065,\n \"IMEI\": 352431066090011,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRJD0007-154\",\n \"TRACTOR ID\": 500363,\n \"OLD ID\": 100052,\n \"LICENCE PLATE\": \"YAB154YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101252,\n \"IMSI\": 204043397060051,\n \"BRAND\": \"John Deere\",\n \"MODEL\": 5065,\n \"IMEI\": 352431066059511,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Partial\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRJD0008-155\",\n \"TRACTOR ID\": 500349,\n \"OLD ID\": 100081,\n \"LICENCE PLATE\": \"YAB155YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101197,\n \"IMSI\": 204043397060016,\n \"BRAND\": \"John Deere\",\n \"MODEL\": 5065,\n \"IMEI\": 352431066085623,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRJD0009-156\",\n \"TRACTOR ID\": 500279,\n \"OLD ID\": 100026,\n \"LICENCE PLATE\": \"YAB156YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731100944,\n \"IMSI\": 204043397059975,\n \"BRAND\": \"John Deere\",\n \"MODEL\": 5065,\n \"IMEI\": 352431066085664,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRJD0010-157\",\n \"TRACTOR ID\": 500289,\n \"OLD ID\": 100127,\n \"LICENCE PLATE\": \"YAB157YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101035,\n \"IMSI\": 204043397059989,\n \"BRAND\": \"John Deere\",\n \"MODEL\": 5065,\n \"IMEI\": 352431066084725,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Partial\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRJD0011-158\",\n \"TRACTOR ID\": 500269,\n \"OLD ID\": 100041,\n \"LICENCE PLATE\": \"YAB158YR\",\n \"EDIT AERTRAK\": \"TRUE\",\n \"ESN\": 1731100929,\n \"IMSI\": 204043397060032,\n \"BRAND\": \"John Deere\",\n \"MODEL\": 5065,\n \"IMEI\": 352431066087009,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Partial\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRJD0012-159\",\n \"TRACTOR ID\": 500353,\n \"OLD ID\": 100088,\n \"LICENCE PLATE\": \"YAB159YR\",\n \"EDIT AERTRAK\": \"TRUE\",\n \"ESN\": 1731101038,\n \"IMSI\": 204043397060000,\n \"BRAND\": \"John Deere\",\n \"MODEL\": 5065,\n \"IMEI\": 352431066086324,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRJD0023-643\",\n \"TRACTOR ID\": 500385,\n \"OLD ID\": 100062,\n \"LICENCE PLATE\": \"YAB643YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101322,\n \"IMSI\": 204043397060061,\n \"BRAND\": \"John Deere\",\n \"MODEL\": 5065,\n \"IMEI\": 352431066062895,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Partial\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRJD0024-644\",\n \"TRACTOR ID\": 500274,\n \"OLD ID\": 100112,\n \"LICENCE PLATE\": \"YAB644YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731100935,\n \"IMSI\": 204043397060063,\n \"BRAND\": \"John Deere\",\n \"MODEL\": 5065,\n \"IMEI\": 352431066088338,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRJD0025-645\",\n \"TRACTOR ID\": 500266,\n \"OLD ID\": 100076,\n \"LICENCE PLATE\": \"YAB645YR\",\n \"EDIT AERTRAK\": \"TRUE\",\n \"ESN\": 1731100924,\n \"IMSI\": 204043397059977,\n \"BRAND\": \"John Deere\",\n \"MODEL\": 5065,\n \"IMEI\": 352431066057440,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRJD0026-646\",\n \"TRACTOR ID\": 500383,\n \"OLD ID\": 100068,\n \"LICENCE PLATE\": \"YAB646YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101315,\n \"IMSI\": 204043397060047,\n \"BRAND\": \"John Deere\",\n \"MODEL\": 5065,\n \"IMEI\": 352431066062879,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Partial\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRJD0027-647\",\n \"TRACTOR ID\": 500374,\n \"OLD ID\": 100125,\n \"LICENCE PLATE\": \"YAB647YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101297,\n \"IMSI\": 204043397059987,\n \"BRAND\": \"John Deere\",\n \"MODEL\": 5065,\n \"IMEI\": 352431066089005,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRJD0028-648\",\n \"TRACTOR ID\": 500345,\n \"OLD ID\": 100120,\n \"LICENCE PLATE\": \"YAB648YR\",\n \"EDIT AERTRAK\": \"TRUE\",\n \"ESN\": 1731101222,\n \"IMSI\": 204043397060074,\n \"BRAND\": \"John Deere\",\n \"MODEL\": 5065,\n \"IMEI\": 352431066057671,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Partial\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRJD0029-649\",\n \"TRACTOR ID\": 500287,\n \"OLD ID\": 100060,\n \"LICENCE PLATE\": \"YAB649YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731100955,\n \"IMSI\": 204043397060059,\n \"BRAND\": \"John Deere\",\n \"MODEL\": 5065,\n \"IMEI\": 352431066088965,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRJD0030-650\",\n \"TRACTOR ID\": 500288,\n \"OLD ID\": 100122,\n \"LICENCE PLATE\": \"YAB650YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731100960,\n \"IMSI\": 204043397060076,\n \"BRAND\": \"John Deere\",\n \"MODEL\": 5065,\n \"IMEI\": 352431066085920,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Partial\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0061-116\",\n \"TRACTOR ID\": 500265,\n \"OLD ID\": 100043,\n \"LICENCE PLATE\": \"YAB116YR\",\n \"EDIT AERTRAK\": \"TRUE\",\n \"ESN\": 1731100923,\n \"IMSI\": 204043397059985,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066085896,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0062-128\",\n \"TRACTOR ID\": 500273,\n \"OLD ID\": 100063,\n \"LICENCE PLATE\": \"YAB128YR\",\n \"EDIT AERTRAK\": \"TRUE\",\n \"ESN\": 1731100934,\n \"IMSI\": 204043397060042,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066054538,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Pending\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0063-125\",\n \"TRACTOR ID\": 500784,\n \"OLD ID\": 100067,\n \"LICENCE PLATE\": \"YAB125YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101317,\n \"IMSI\": 204043397060046,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066091340,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0065-126\",\n \"TRACTOR ID\": 500344,\n \"OLD ID\": 100058,\n \"LICENCE PLATE\": \"YAB126YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101037,\n \"IMSI\": 204043397060057,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066084683,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Pending\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0066-124\",\n \"TRACTOR ID\": 500359,\n \"OLD ID\": 100101,\n \"LICENCE PLATE\": \"YAB124YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101246,\n \"IMSI\": 204043397059995,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066059776,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Pending\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0067-119\",\n \"TRACTOR ID\": 500262,\n \"OLD ID\": 100042,\n \"LICENCE PLATE\": \"YAB119YR\",\n \"EDIT AERTRAK\": \"TRUE\",\n \"ESN\": 1731100919,\n \"IMSI\": 204043397060033,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066059552,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0068-120\",\n \"TRACTOR ID\": 500389,\n \"OLD ID\": 100034,\n \"LICENCE PLATE\": \"YAB120YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731100933,\n \"IMSI\": 204043397059984,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066099145,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0069-115\",\n \"TRACTOR ID\": 500275,\n \"OLD ID\": 100092,\n \"LICENCE PLATE\": \"YAB115YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731100936,\n \"IMSI\": 204043397060024,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066100711,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Pending\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0070-114\",\n \"TRACTOR ID\": 500272,\n \"OLD ID\": 100037,\n \"LICENCE PLATE\": \"YAB114YR\",\n \"EDIT AERTRAK\": \"TRUE\",\n \"ESN\": 1731100932,\n \"IMSI\": 204043397060079,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066088874,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Pending\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0071-113\",\n \"TRACTOR ID\": 500354,\n \"OLD ID\": 100121,\n \"LICENCE PLATE\": \"YAB113YR\",\n \"EDIT AERTRAK\": \"TRUE\",\n \"ESN\": 1731101224,\n \"IMSI\": 204043397060075,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066055766,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Pending\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0073-127\",\n \"TRACTOR ID\": 500271,\n \"OLD ID\": 100038,\n \"LICENCE PLATE\": \"YAB127YR\",\n \"EDIT AERTRAK\": \"TRUE\",\n \"ESN\": 1731100931,\n \"IMSI\": 204043397060030,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066063570,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/MaxRetries\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0074-110\",\n \"TRACTOR ID\": 500371,\n \"OLD ID\": 100126,\n \"LICENCE PLATE\": \"YAB110YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101279,\n \"IMSI\": 204043397059988,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066087561,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Pending\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0076-122\",\n \"TRACTOR ID\": 500355,\n \"OLD ID\": 100087,\n \"LICENCE PLATE\": \"YAB122YR\",\n \"EDIT AERTRAK\": \"TRUE\",\n \"ESN\": 1731101227,\n \"IMSI\": 204043397060007,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066057846,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0077-121\",\n \"TRACTOR ID\": 500388,\n \"OLD ID\": 100082,\n \"LICENCE PLATE\": \"YAB121YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101274,\n \"IMSI\": 204043397059999,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066086928,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0078-118\",\n \"TRACTOR ID\": 500270,\n \"OLD ID\": 100040,\n \"LICENCE PLATE\": \"YAB118YR\",\n \"EDIT AERTRAK\": \"TRUE\",\n \"ESN\": 1731100930,\n \"IMSI\": 204043397060031,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066055998,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0079-111\",\n \"TRACTOR ID\": 500373,\n \"OLD ID\": 100089,\n \"LICENCE PLATE\": \"YAB111YR\",\n \"EDIT AERTRAK\": \"TRUE\",\n \"ESN\": 1731101296,\n \"IMSI\": 204043397060019,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066062788,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Partial\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0080-117\",\n \"TRACTOR ID\": 500781,\n \"OLD ID\": 100090,\n \"LICENCE PLATE\": \"YAB117YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101196,\n \"IMSI\": 204043397060018,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066083602,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0081-677\",\n \"TRACTOR ID\": 500366,\n \"OLD ID\": 100105,\n \"LICENCE PLATE\": \"YAB677YR\",\n \"EDIT AERTRAK\": \"TRUE\",\n \"ESN\": 1731101272,\n \"IMSI\": 204043397059991,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066055964,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Partial\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0082-634\",\n \"TRACTOR ID\": 500358,\n \"OLD ID\": 100104,\n \"LICENCE PLATE\": \"YAB634YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101245,\n \"IMSI\": 204043397059992,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066057655,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Pending\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0083-632\",\n \"TRACTOR ID\": 500372,\n \"OLD ID\": 100107,\n \"LICENCE PLATE\": \"YAB632YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101295,\n \"IMSI\": 204043397060069,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066088999,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0084-641\",\n \"TRACTOR ID\": 500284,\n \"OLD ID\": 100028,\n \"LICENCE PLATE\": \"YAB641YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731100950,\n \"IMSI\": 204043397059981,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066094823,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Pending\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0085-628\",\n \"TRACTOR ID\": 500357,\n \"OLD ID\": 100059,\n \"LICENCE PLATE\": \"YAB628YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101230,\n \"IMSI\": 204043397060058,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066071383,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0086-633\",\n \"TRACTOR ID\": 500368,\n \"OLD ID\": 100114,\n \"LICENCE PLATE\": \"YAB633YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101276,\n \"IMSI\": 204043397060065,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066086019,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0088-630\",\n \"TRACTOR ID\": 500280,\n \"OLD ID\": 100075,\n \"LICENCE PLATE\": \"YAB630YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731100946,\n \"IMSI\": 204043397060012,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066057804,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Partial\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0089-664\",\n \"TRACTOR ID\": 500268,\n \"OLD ID\": 100097,\n \"LICENCE PLATE\": \"YAB664YR\",\n \"EDIT AERTRAK\": \"TRUE\",\n \"ESN\": 1731100926,\n \"IMSI\": 204043397060020,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066057481,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0090-624\",\n \"TRACTOR ID\": 500362,\n \"OLD ID\": 100053,\n \"LICENCE PLATE\": \"YAB624YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101250,\n \"IMSI\": 204043397060052,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066057333,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0091-623\",\n \"TRACTOR ID\": 500380,\n \"OLD ID\": 100061,\n \"LICENCE PLATE\": \"YAB623YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101312,\n \"IMSI\": 204043397060060,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066056103,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Partial\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0092-626\",\n \"TRACTOR ID\": 500386,\n \"OLD ID\": 100096,\n \"LICENCE PLATE\": \"YAB626YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101323,\n \"IMSI\": 204043397060025,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066088957,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Partial\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0093-627\",\n \"TRACTOR ID\": 500277,\n \"OLD ID\": 100079,\n \"LICENCE PLATE\": \"YAB627YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731100940,\n \"IMSI\": 204043397060014,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066086316,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Pending\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0094-625\",\n \"TRACTOR ID\": 500378,\n \"OLD ID\": 100115,\n \"LICENCE PLATE\": \"YAB625YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101301,\n \"IMSI\": 204043397060066,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066099046,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Partial\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0095-622\",\n \"TRACTOR ID\": 500379,\n \"OLD ID\": 100056,\n \"LICENCE PLATE\": \"YAB622YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101302,\n \"IMSI\": 204043397060055,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066085805,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Partial\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0096-621\",\n \"TRACTOR ID\": 500276,\n \"OLD ID\": 100095,\n \"LICENCE PLATE\": \"YAB621YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731100938,\n \"IMSI\": 204043397060022,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066091498,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0097-642\",\n \"TRACTOR ID\": 500352,\n \"OLD ID\": 100093,\n \"LICENCE PLATE\": \"YAB642YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101041,\n \"IMSI\": 204043397060021,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066057820,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Partial\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0098-658\",\n \"TRACTOR ID\": 500381,\n \"OLD ID\": 100064,\n \"LICENCE PLATE\": \"YAB658YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101313,\n \"IMSI\": 204043397060043,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066086415,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Partial\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0099-659\",\n \"TRACTOR ID\": 500278,\n \"OLD ID\": 100069,\n \"LICENCE PLATE\": \"YAB659YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731100941,\n \"IMSI\": 204043397060041,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066063620,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0100-660.\",\n \"TRACTOR ID\": 500281,\n \"OLD ID\": 100078,\n \"LICENCE PLATE\": \"YAB660YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731100947,\n \"IMSI\": 204043397060013,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066057796,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0102-661\",\n \"TRACTOR ID\": 500350,\n \"OLD ID\": 100085,\n \"LICENCE PLATE\": \"YAB661YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101193,\n \"IMSI\": 204043397060029,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066100646,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0103-663\",\n \"TRACTOR ID\": 500361,\n \"OLD ID\": 100055,\n \"LICENCE PLATE\": \"YAB663YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101249,\n \"IMSI\": 204043397060054,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066057648,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0104-679\",\n \"TRACTOR ID\": 500382,\n \"OLD ID\": 100113,\n \"LICENCE PLATE\": \"YAB679YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101314,\n \"IMSI\": 204043397060064,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066057002,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0105-657\",\n \"TRACTOR ID\": 500347,\n \"OLD ID\": 100103,\n \"LICENCE PLATE\": \"YAB657YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101200,\n \"IMSI\": 204043397059993,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066099681,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0106-656\",\n \"TRACTOR ID\": 500348,\n \"OLD ID\": 100100,\n \"LICENCE PLATE\": \"YAB656YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101199,\n \"IMSI\": 204043397059996,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066100620,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Pending\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0107-655\",\n \"TRACTOR ID\": 500370,\n \"OLD ID\": 100109,\n \"LICENCE PLATE\": \"YAB655YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101278,\n \"IMSI\": 204043397060067,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066081804,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Pending\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0108-685\",\n \"TRACTOR ID\": 500369,\n \"OLD ID\": 100108,\n \"LICENCE PLATE\": \"YAB685YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101277,\n \"IMSI\": 204043397060068,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066083560,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0109-684\",\n \"TRACTOR ID\": 500360,\n \"OLD ID\": 100102,\n \"LICENCE PLATE\": \"YAB684YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101247,\n \"IMSI\": 204043397059994,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066087637,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0110-683\",\n \"TRACTOR ID\": 500351,\n \"OLD ID\": 100116,\n \"LICENCE PLATE\": \"YAB683YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101044,\n \"IMSI\": 204043397060070,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066056095,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0111-682\",\n \"TRACTOR ID\": 500367,\n \"OLD ID\": 100083,\n \"LICENCE PLATE\": \"YAB682YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101273,\n \"IMSI\": 204043397059997,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066086035,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0113-654\",\n \"TRACTOR ID\": 500263,\n \"OLD ID\": 100050,\n \"LICENCE PLATE\": \"YAB654YR\",\n \"EDIT AERTRAK\": \"TRUE\",\n \"ESN\": 1731100921,\n \"IMSI\": 204043397060049,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066085797,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/MaxRetries\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0114-635\",\n \"TRACTOR ID\": 500390,\n \"OLD ID\": 100049,\n \"LICENCE PLATE\": \"YAB635YR\",\n \"EDIT AERTRAK\": \"\",\n \"ESN\": 1731101251,\n \"IMSI\": 204043397060048,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066054462,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0115-637\",\n \"TRACTOR ID\": 500282,\n \"OLD ID\": 100072,\n \"LICENCE PLATE\": \"YAB637YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731100948,\n \"IMSI\": 204043397060009,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066055782,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0116-636\",\n \"TRACTOR ID\": 500365,\n \"OLD ID\": 100106,\n \"LICENCE PLATE\": \"YAB636YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101269,\n \"IMSI\": 204043397059990,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066057861,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0117-638\",\n \"TRACTOR ID\": 500267,\n \"OLD ID\": 100098,\n \"LICENCE PLATE\": \"YAB638YR\",\n \"EDIT AERTRAK\": \"TRUE\",\n \"ESN\": 1731100925,\n \"IMSI\": 204043397060026,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066083594,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0118-653\",\n \"TRACTOR ID\": 500364,\n \"OLD ID\": 100057,\n \"LICENCE PLATE\": \"YAB653YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731101268,\n \"IMSI\": 204043397060056,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066057275,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Delivery Impossible/Partial\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0119-676\",\n \"TRACTOR ID\": 500387,\n \"OLD ID\": 100074,\n \"LICENCE PLATE\": \"YAB676YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731100943,\n \"IMSI\": 204043397060011,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066085649,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n },\n {\n \"TRAXI ID\": \"TRAXI/TRMH0120-631\",\n \"TRACTOR ID\": 500285,\n \"OLD ID\": 100073,\n \"LICENCE PLATE\": \"YAB631YR\",\n \"EDIT AERTRAK\": \"FALSE\",\n \"ESN\": 1731100953,\n \"IMSI\": 204043397060010,\n \"BRAND\": \"Mahindra\",\n \"MODEL\": 6005,\n \"IMEI\": 352431066085656,\n \"ICCID\": 89185000161110300000,\n \"DEVICE TYPE\": \"TTU12G400-G1000\",\n \"STATUS\": \"Completed\"\n }\n];\n\n\nvar tractorsHash = { 100026: \n { 'TRAXI ID': 'TRAXI/TRJD0009-156',\n 'TRACTOR ID': 500279,\n 'OLD ID': 100026,\n 'LICENCE PLATE': 'YAB156YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731100944,\n IMSI: 204043397059975,\n BRAND: 'John Deere',\n MODEL: 5065,\n IMEI: 352431066085664,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100028: \n { 'TRAXI ID': 'TRAXI/TRMH0084-641',\n 'TRACTOR ID': 500284,\n 'OLD ID': 100028,\n 'LICENCE PLATE': 'YAB641YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731100950,\n IMSI: 204043397059981,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066094823,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Pending' },\n 100034: \n { 'TRAXI ID': 'TRAXI/TRMH0068-120',\n 'TRACTOR ID': 500389,\n 'OLD ID': 100034,\n 'LICENCE PLATE': 'YAB120YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731100933,\n IMSI: 204043397059984,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066099145,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: '' },\n 100036: \n { 'TRAXI ID': 'TRAXI/TRJD0003-150',\n 'TRACTOR ID': 500283,\n 'OLD ID': 100036,\n 'LICENCE PLATE': 'YAB150YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731100949,\n IMSI: 204043397059982,\n BRAND: 'John Deere',\n MODEL: 5065,\n IMEI: 352431066057663,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Partial' },\n 100037: \n { 'TRAXI ID': 'TRAXI/TRMH0070-114',\n 'TRACTOR ID': 500272,\n 'OLD ID': 100037,\n 'LICENCE PLATE': 'YAB114YR',\n 'EDIT AERTRAK': 'TRUE',\n ESN: 1731100932,\n IMSI: 204043397060079,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066088874,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Pending' },\n 100038: \n { 'TRAXI ID': 'TRAXI/TRMH0073-127',\n 'TRACTOR ID': 500271,\n 'OLD ID': 100038,\n 'LICENCE PLATE': 'YAB127YR',\n 'EDIT AERTRAK': 'TRUE',\n ESN: 1731100931,\n IMSI: 204043397060030,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066063570,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/MaxRetries' },\n 100040: \n { 'TRAXI ID': 'TRAXI/TRMH0078-118',\n 'TRACTOR ID': 500270,\n 'OLD ID': 100040,\n 'LICENCE PLATE': 'YAB118YR',\n 'EDIT AERTRAK': 'TRUE',\n ESN: 1731100930,\n IMSI: 204043397060031,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066055998,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100041: \n { 'TRAXI ID': 'TRAXI/TRJD0011-158',\n 'TRACTOR ID': 500269,\n 'OLD ID': 100041,\n 'LICENCE PLATE': 'YAB158YR',\n 'EDIT AERTRAK': 'TRUE',\n ESN: 1731100929,\n IMSI: 204043397060032,\n BRAND: 'John Deere',\n MODEL: 5065,\n IMEI: 352431066087009,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Partial' },\n 100042: \n { 'TRAXI ID': 'TRAXI/TRMH0067-119',\n 'TRACTOR ID': 500262,\n 'OLD ID': 100042,\n 'LICENCE PLATE': 'YAB119YR',\n 'EDIT AERTRAK': 'TRUE',\n ESN: 1731100919,\n IMSI: 204043397060033,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066059552,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100043: \n { 'TRAXI ID': 'TRAXI/TRMH0061-116',\n 'TRACTOR ID': 500265,\n 'OLD ID': 100043,\n 'LICENCE PLATE': 'YAB116YR',\n 'EDIT AERTRAK': 'TRUE',\n ESN: 1731100923,\n IMSI: 204043397059985,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066085896,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100049: \n { 'TRAXI ID': 'TRAXI/TRMH0114-635',\n 'TRACTOR ID': 500390,\n 'OLD ID': 100049,\n 'LICENCE PLATE': 'YAB635YR',\n 'EDIT AERTRAK': '',\n ESN: 1731101251,\n IMSI: 204043397060048,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066054462,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: '' },\n 100050: \n { 'TRAXI ID': 'TRAXI/TRMH0113-654',\n 'TRACTOR ID': 500263,\n 'OLD ID': 100050,\n 'LICENCE PLATE': 'YAB654YR',\n 'EDIT AERTRAK': 'TRUE',\n ESN: 1731100921,\n IMSI: 204043397060049,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066085797,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/MaxRetries' },\n 100052: \n { 'TRAXI ID': 'TRAXI/TRJD0007-154',\n 'TRACTOR ID': 500363,\n 'OLD ID': 100052,\n 'LICENCE PLATE': 'YAB154YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101252,\n IMSI: 204043397060051,\n BRAND: 'John Deere',\n MODEL: 5065,\n IMEI: 352431066059511,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Partial' },\n 100053: \n { 'TRAXI ID': 'TRAXI/TRMH0090-624',\n 'TRACTOR ID': 500362,\n 'OLD ID': 100053,\n 'LICENCE PLATE': 'YAB624YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101250,\n IMSI: 204043397060052,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066057333,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100055: \n { 'TRAXI ID': 'TRAXI/TRMH0103-663',\n 'TRACTOR ID': 500361,\n 'OLD ID': 100055,\n 'LICENCE PLATE': 'YAB663YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101249,\n IMSI: 204043397060054,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066057648,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100056: \n { 'TRAXI ID': 'TRAXI/TRMH0095-622',\n 'TRACTOR ID': 500379,\n 'OLD ID': 100056,\n 'LICENCE PLATE': 'YAB622YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101302,\n IMSI: 204043397060055,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066085805,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Partial' },\n 100057: \n { 'TRAXI ID': 'TRAXI/TRMH0118-653',\n 'TRACTOR ID': 500364,\n 'OLD ID': 100057,\n 'LICENCE PLATE': 'YAB653YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101268,\n IMSI: 204043397060056,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066057275,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Partial' },\n 100058: \n { 'TRAXI ID': 'TRAXI/TRMH0065-126',\n 'TRACTOR ID': 500344,\n 'OLD ID': 100058,\n 'LICENCE PLATE': 'YAB126YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101037,\n IMSI: 204043397060057,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066084683,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Pending' },\n 100059: \n { 'TRAXI ID': 'TRAXI/TRMH0085-628',\n 'TRACTOR ID': 500357,\n 'OLD ID': 100059,\n 'LICENCE PLATE': 'YAB628YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101230,\n IMSI: 204043397060058,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066071383,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100060: \n { 'TRAXI ID': 'TRAXI/TRJD0029-649',\n 'TRACTOR ID': 500287,\n 'OLD ID': 100060,\n 'LICENCE PLATE': 'YAB649YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731100955,\n IMSI: 204043397060059,\n BRAND: 'John Deere',\n MODEL: 5065,\n IMEI: 352431066088965,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100061: \n { 'TRAXI ID': 'TRAXI/TRMH0091-623',\n 'TRACTOR ID': 500380,\n 'OLD ID': 100061,\n 'LICENCE PLATE': 'YAB623YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101312,\n IMSI: 204043397060060,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066056103,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Partial' },\n 100062: \n { 'TRAXI ID': 'TRAXI/TRJD0023-643',\n 'TRACTOR ID': 500385,\n 'OLD ID': 100062,\n 'LICENCE PLATE': 'YAB643YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101322,\n IMSI: 204043397060061,\n BRAND: 'John Deere',\n MODEL: 5065,\n IMEI: 352431066062895,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Partial' },\n 100063: \n { 'TRAXI ID': 'TRAXI/TRMH0062-128',\n 'TRACTOR ID': 500273,\n 'OLD ID': 100063,\n 'LICENCE PLATE': 'YAB128YR',\n 'EDIT AERTRAK': 'TRUE',\n ESN: 1731100934,\n IMSI: 204043397060042,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066054538,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Pending' },\n 100064: \n { 'TRAXI ID': 'TRAXI/TRMH0098-658',\n 'TRACTOR ID': 500381,\n 'OLD ID': 100064,\n 'LICENCE PLATE': 'YAB658YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101313,\n IMSI: 204043397060043,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066086415,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Partial' },\n 100066: \n { 'TRAXI ID': 'TRAXI/TRJD0005-152',\n 'TRACTOR ID': 500346,\n 'OLD ID': 100066,\n 'LICENCE PLATE': 'YAB152YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101217,\n IMSI: 204043397060045,\n BRAND: 'John Deere',\n MODEL: 5065,\n IMEI: 352431066083651,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Pending' },\n 100067: \n { 'TRAXI ID': 'TRAXI/TRMH0063-125',\n 'TRACTOR ID': 500784,\n 'OLD ID': 100067,\n 'LICENCE PLATE': 'YAB125YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101317,\n IMSI: 204043397060046,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066091340,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: '' },\n 100068: \n { 'TRAXI ID': 'TRAXI/TRJD0026-646',\n 'TRACTOR ID': 500383,\n 'OLD ID': 100068,\n 'LICENCE PLATE': 'YAB646YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101315,\n IMSI: 204043397060047,\n BRAND: 'John Deere',\n MODEL: 5065,\n IMEI: 352431066062879,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Partial' },\n 100069: \n { 'TRAXI ID': 'TRAXI/TRMH0099-659',\n 'TRACTOR ID': 500278,\n 'OLD ID': 100069,\n 'LICENCE PLATE': 'YAB659YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731100941,\n IMSI: 204043397060041,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066063620,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100072: \n { 'TRAXI ID': 'TRAXI/TRMH0115-637',\n 'TRACTOR ID': 500282,\n 'OLD ID': 100072,\n 'LICENCE PLATE': 'YAB637YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731100948,\n IMSI: 204043397060009,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066055782,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100073: \n { 'TRAXI ID': 'TRAXI/TRMH0120-631',\n 'TRACTOR ID': 500285,\n 'OLD ID': 100073,\n 'LICENCE PLATE': 'YAB631YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731100953,\n IMSI: 204043397060010,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066085656,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100074: \n { 'TRAXI ID': 'TRAXI/TRMH0119-676',\n 'TRACTOR ID': 500387,\n 'OLD ID': 100074,\n 'LICENCE PLATE': 'YAB676YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731100943,\n IMSI: 204043397060011,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066085649,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100075: \n { 'TRAXI ID': 'TRAXI/TRMH0088-630',\n 'TRACTOR ID': 500280,\n 'OLD ID': 100075,\n 'LICENCE PLATE': 'YAB630YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731100946,\n IMSI: 204043397060012,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066057804,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Partial' },\n 100076: \n { 'TRAXI ID': 'TRAXI/TRJD0025-645',\n 'TRACTOR ID': 500266,\n 'OLD ID': 100076,\n 'LICENCE PLATE': 'YAB645YR',\n 'EDIT AERTRAK': 'TRUE',\n ESN: 1731100924,\n IMSI: 204043397059977,\n BRAND: 'John Deere',\n MODEL: 5065,\n IMEI: 352431066057440,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100077: \n { 'TRAXI ID': 'TRAXI/TRJD0004-151',\n 'TRACTOR ID': 500264,\n 'OLD ID': 100077,\n 'LICENCE PLATE': 'YAB151YR',\n 'EDIT AERTRAK': 'TRUE',\n ESN: 1731100922,\n IMSI: 204043397060003,\n BRAND: 'John Deere',\n MODEL: 5065,\n IMEI: 352431066085425,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Partial' },\n 100078: \n { 'TRAXI ID': 'TRAXI/TRMH0100-660.',\n 'TRACTOR ID': 500281,\n 'OLD ID': 100078,\n 'LICENCE PLATE': 'YAB660YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731100947,\n IMSI: 204043397060013,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066057796,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100079: \n { 'TRAXI ID': 'TRAXI/TRMH0093-627',\n 'TRACTOR ID': 500277,\n 'OLD ID': 100079,\n 'LICENCE PLATE': 'YAB627YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731100940,\n IMSI: 204043397060014,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066086316,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Pending' },\n 100081: \n { 'TRAXI ID': 'TRAXI/TRJD0008-155',\n 'TRACTOR ID': 500349,\n 'OLD ID': 100081,\n 'LICENCE PLATE': 'YAB155YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101197,\n IMSI: 204043397060016,\n BRAND: 'John Deere',\n MODEL: 5065,\n IMEI: 352431066085623,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100082: \n { 'TRAXI ID': 'TRAXI/TRMH0077-121',\n 'TRACTOR ID': 500388,\n 'OLD ID': 100082,\n 'LICENCE PLATE': 'YAB121YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101274,\n IMSI: 204043397059999,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066086928,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: '' },\n 100083: \n { 'TRAXI ID': 'TRAXI/TRMH0111-682',\n 'TRACTOR ID': 500367,\n 'OLD ID': 100083,\n 'LICENCE PLATE': 'YAB682YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101273,\n IMSI: 204043397059997,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066086035,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100084: \n { 'TRAXI ID': 'TRAXI/TRJD0001-148',\n 'TRACTOR ID': 500356,\n 'OLD ID': 100084,\n 'LICENCE PLATE': 'YAB148YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101228,\n IMSI: 204043397060028,\n BRAND: 'John Deere',\n MODEL: 5065,\n IMEI: 352431066063554,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100085: \n { 'TRAXI ID': 'TRAXI/TRMH0102-661',\n 'TRACTOR ID': 500350,\n 'OLD ID': 100085,\n 'LICENCE PLATE': 'YAB661YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101193,\n IMSI: 204043397060029,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066100646,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100087: \n { 'TRAXI ID': 'TRAXI/TRMH0076-122',\n 'TRACTOR ID': 500355,\n 'OLD ID': 100087,\n 'LICENCE PLATE': 'YAB122YR',\n 'EDIT AERTRAK': 'TRUE',\n ESN: 1731101227,\n IMSI: 204043397060007,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066057846,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100088: \n { 'TRAXI ID': 'TRAXI/TRJD0012-159',\n 'TRACTOR ID': 500353,\n 'OLD ID': 100088,\n 'LICENCE PLATE': 'YAB159YR',\n 'EDIT AERTRAK': 'TRUE',\n ESN: 1731101038,\n IMSI: 204043397060000,\n BRAND: 'John Deere',\n MODEL: 5065,\n IMEI: 352431066086324,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100089: \n { 'TRAXI ID': 'TRAXI/TRMH0079-111',\n 'TRACTOR ID': 500373,\n 'OLD ID': 100089,\n 'LICENCE PLATE': 'YAB111YR',\n 'EDIT AERTRAK': 'TRUE',\n ESN: 1731101296,\n IMSI: 204043397060019,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066062788,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Partial' },\n 100090: \n { 'TRAXI ID': 'TRAXI/TRMH0080-117',\n 'TRACTOR ID': 500781,\n 'OLD ID': 100090,\n 'LICENCE PLATE': 'YAB117YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101196,\n IMSI: 204043397060018,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066083602,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: '' },\n 100092: \n { 'TRAXI ID': 'TRAXI/TRMH0069-115',\n 'TRACTOR ID': 500275,\n 'OLD ID': 100092,\n 'LICENCE PLATE': 'YAB115YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731100936,\n IMSI: 204043397060024,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066100711,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Pending' },\n 100093: \n { 'TRAXI ID': 'TRAXI/TRMH0097-642',\n 'TRACTOR ID': 500352,\n 'OLD ID': 100093,\n 'LICENCE PLATE': 'YAB642YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101041,\n IMSI: 204043397060021,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066057820,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Partial' },\n 100095: \n { 'TRAXI ID': 'TRAXI/TRMH0096-621',\n 'TRACTOR ID': 500276,\n 'OLD ID': 100095,\n 'LICENCE PLATE': 'YAB621YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731100938,\n IMSI: 204043397060022,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066091498,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100096: \n { 'TRAXI ID': 'TRAXI/TRMH0092-626',\n 'TRACTOR ID': 500386,\n 'OLD ID': 100096,\n 'LICENCE PLATE': 'YAB626YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101323,\n IMSI: 204043397060025,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066088957,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Partial' },\n 100097: \n { 'TRAXI ID': 'TRAXI/TRMH0089-664',\n 'TRACTOR ID': 500268,\n 'OLD ID': 100097,\n 'LICENCE PLATE': 'YAB664YR',\n 'EDIT AERTRAK': 'TRUE',\n ESN: 1731100926,\n IMSI: 204043397060020,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066057481,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100098: \n { 'TRAXI ID': 'TRAXI/TRMH0117-638',\n 'TRACTOR ID': 500267,\n 'OLD ID': 100098,\n 'LICENCE PLATE': 'YAB638YR',\n 'EDIT AERTRAK': 'TRUE',\n ESN: 1731100925,\n IMSI: 204043397060026,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066083594,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100100: \n { 'TRAXI ID': 'TRAXI/TRMH0106-656',\n 'TRACTOR ID': 500348,\n 'OLD ID': 100100,\n 'LICENCE PLATE': 'YAB656YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101199,\n IMSI: 204043397059996,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066100620,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Pending' },\n 100101: \n { 'TRAXI ID': 'TRAXI/TRMH0066-124',\n 'TRACTOR ID': 500359,\n 'OLD ID': 100101,\n 'LICENCE PLATE': 'YAB124YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101246,\n IMSI: 204043397059995,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066059776,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Pending' },\n 100102: \n { 'TRAXI ID': 'TRAXI/TRMH0109-684',\n 'TRACTOR ID': 500360,\n 'OLD ID': 100102,\n 'LICENCE PLATE': 'YAB684YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101247,\n IMSI: 204043397059994,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066087637,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100103: \n { 'TRAXI ID': 'TRAXI/TRMH0105-657',\n 'TRACTOR ID': 500347,\n 'OLD ID': 100103,\n 'LICENCE PLATE': 'YAB657YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101200,\n IMSI: 204043397059993,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066099681,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100104: \n { 'TRAXI ID': 'TRAXI/TRMH0082-634',\n 'TRACTOR ID': 500358,\n 'OLD ID': 100104,\n 'LICENCE PLATE': 'YAB634YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101245,\n IMSI: 204043397059992,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066057655,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Pending' },\n 100105: \n { 'TRAXI ID': 'TRAXI/TRMH0081-677',\n 'TRACTOR ID': 500366,\n 'OLD ID': 100105,\n 'LICENCE PLATE': 'YAB677YR',\n 'EDIT AERTRAK': 'TRUE',\n ESN: 1731101272,\n IMSI: 204043397059991,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066055964,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Partial' },\n 100106: \n { 'TRAXI ID': 'TRAXI/TRMH0116-636',\n 'TRACTOR ID': 500365,\n 'OLD ID': 100106,\n 'LICENCE PLATE': 'YAB636YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101269,\n IMSI: 204043397059990,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066057861,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100107: \n { 'TRAXI ID': 'TRAXI/TRMH0083-632',\n 'TRACTOR ID': 500372,\n 'OLD ID': 100107,\n 'LICENCE PLATE': 'YAB632YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101295,\n IMSI: 204043397060069,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066088999,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100108: \n { 'TRAXI ID': 'TRAXI/TRMH0108-685',\n 'TRACTOR ID': 500369,\n 'OLD ID': 100108,\n 'LICENCE PLATE': 'YAB685YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101277,\n IMSI: 204043397060068,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066083560,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100109: \n { 'TRAXI ID': 'TRAXI/TRMH0107-655',\n 'TRACTOR ID': 500370,\n 'OLD ID': 100109,\n 'LICENCE PLATE': 'YAB655YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101278,\n IMSI: 204043397060067,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066081804,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Pending' },\n 100112: \n { 'TRAXI ID': 'TRAXI/TRJD0024-644',\n 'TRACTOR ID': 500274,\n 'OLD ID': 100112,\n 'LICENCE PLATE': 'YAB644YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731100935,\n IMSI: 204043397060063,\n BRAND: 'John Deere',\n MODEL: 5065,\n IMEI: 352431066088338,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100113: \n { 'TRAXI ID': 'TRAXI/TRMH0104-679',\n 'TRACTOR ID': 500382,\n 'OLD ID': 100113,\n 'LICENCE PLATE': 'YAB679YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101314,\n IMSI: 204043397060064,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066057002,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100114: \n { 'TRAXI ID': 'TRAXI/TRMH0086-633',\n 'TRACTOR ID': 500368,\n 'OLD ID': 100114,\n 'LICENCE PLATE': 'YAB633YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101276,\n IMSI: 204043397060065,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066086019,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100115: \n { 'TRAXI ID': 'TRAXI/TRMH0094-625',\n 'TRACTOR ID': 500378,\n 'OLD ID': 100115,\n 'LICENCE PLATE': 'YAB625YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101301,\n IMSI: 204043397060066,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066099046,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Partial' },\n 100116: \n { 'TRAXI ID': 'TRAXI/TRMH0110-683',\n 'TRACTOR ID': 500351,\n 'OLD ID': 100116,\n 'LICENCE PLATE': 'YAB683YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101044,\n IMSI: 204043397060070,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066056095,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100120: \n { 'TRAXI ID': 'TRAXI/TRJD0028-648',\n 'TRACTOR ID': 500345,\n 'OLD ID': 100120,\n 'LICENCE PLATE': 'YAB648YR',\n 'EDIT AERTRAK': 'TRUE',\n ESN: 1731101222,\n IMSI: 204043397060074,\n BRAND: 'John Deere',\n MODEL: 5065,\n IMEI: 352431066057671,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Partial' },\n 100121: \n { 'TRAXI ID': 'TRAXI/TRMH0071-113',\n 'TRACTOR ID': 500354,\n 'OLD ID': 100121,\n 'LICENCE PLATE': 'YAB113YR',\n 'EDIT AERTRAK': 'TRUE',\n ESN: 1731101224,\n IMSI: 204043397060075,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066055766,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Pending' },\n 100122: \n { 'TRAXI ID': 'TRAXI/TRJD0030-650',\n 'TRACTOR ID': 500288,\n 'OLD ID': 100122,\n 'LICENCE PLATE': 'YAB650YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731100960,\n IMSI: 204043397060076,\n BRAND: 'John Deere',\n MODEL: 5065,\n IMEI: 352431066085920,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Partial' },\n 100123: \n { 'TRAXI ID': 'TRAXI/TRJD0002-149',\n 'TRACTOR ID': 500376,\n 'OLD ID': 100123,\n 'LICENCE PLATE': 'YAB149YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101299,\n IMSI: 204043397060077,\n BRAND: 'John Deere',\n MODEL: 5065,\n IMEI: 352431066099913,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Partial' },\n 100124: \n { 'TRAXI ID': 'TRAXI/TRJD0006-153',\n 'TRACTOR ID': 500375,\n 'OLD ID': 100124,\n 'LICENCE PLATE': 'YAB153YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101298,\n IMSI: 204043397059986,\n BRAND: 'John Deere',\n MODEL: 5065,\n IMEI: 352431066090011,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100125: \n { 'TRAXI ID': 'TRAXI/TRJD0027-647',\n 'TRACTOR ID': 500374,\n 'OLD ID': 100125,\n 'LICENCE PLATE': 'YAB647YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101297,\n IMSI: 204043397059987,\n BRAND: 'John Deere',\n MODEL: 5065,\n IMEI: 352431066089005,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Completed' },\n 100126: \n { 'TRAXI ID': 'TRAXI/TRMH0074-110',\n 'TRACTOR ID': 500371,\n 'OLD ID': 100126,\n 'LICENCE PLATE': 'YAB110YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101279,\n IMSI: 204043397059988,\n BRAND: 'Mahindra',\n MODEL: 6005,\n IMEI: 352431066087561,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Pending' },\n 100127: \n { 'TRAXI ID': 'TRAXI/TRJD0010-157',\n 'TRACTOR ID': 500289,\n 'OLD ID': 100127,\n 'LICENCE PLATE': 'YAB157YR',\n 'EDIT AERTRAK': 'FALSE',\n ESN: 1731101035,\n IMSI: 204043397059989,\n BRAND: 'John Deere',\n MODEL: 5065,\n IMEI: 352431066084725,\n ICCID: 89185000161110300000,\n 'DEVICE TYPE': 'TTU12G400-G1000',\n STATUS: 'Delivery Impossible/Partial' } \n }\n \n\nfunction onRequest(request, response, modules) {\n var Tractor = modules.collectionAccess.collection('TractorDetail');\n var tractor_ids_arr = [];\n var Log = modules.logger;\n var count = 0;\n var old_id;\n var new_id;\n \tfor(var i=0; i<tractors.length;i++)\n {\n (function(i){\n \t old_id = tractors[i][\"OLD ID\"];\n \t new_id = tractorsHash[old_id][\"TRACTOR ID\"];\n \n Tractor.update( {TractorID:old_id}, {$set: {TractorID:new_id} },\n function(err, saved){\n \tif(err){\n Log.info('error updating tractor with an ID of ' + old_id + \" with new ID of \" + new_id );\n count++;\n if( count === tractors.length ){\n response.complete();\n }\n }\n else {\n Log.info('successfully updated tractor with the id of ' \n + tractors[i][\"OLD ID\"] + ' with new ID of ' + tractorsHash[ tractors[i][\"OLD ID\"]][\"TRACTOR ID\"] );\n count++\n if( count === tractors.length ){\n response.complete();\n }\n }\n });\n }).call(this, i)\n }\n}\n" }, "generateAndStoreSubscriptionCode" : { "code" : "function onRequest(request, response, modules) {\n \n const SubscriptionCode = modules.collectionAccess.collection('TrackerIds');\n const kinvey = modules.kinvey;\n \n var generateUniqueUid = function() {\n return Math.random().toString(36).substring(2, 15) +\n Math.random().toString(36).substring(2, 15);\n }\n \n var sub_code = generateUniqueUid();\n \n // Persist the code to storage \n var subcription_code_object = kinvey.entity();\n subcription_code_object.tracker_id = sub_code;\n \n \n SubscriptionCode.save(subcription_code_object, function(err, saved_object){\n if( err ) {\n response.body = {\n success: false,\n error: new Error(err).message,\n data: null,\n code: 400\n }\n }\n \n else {\n response.body = {\n success: true,\n error: null,\n data: sub_code,\n code: 200\n }\n }\n \n response.complete(); \n })\n \n}\n\n" }, "attemptLogin" : { "code" : "function onRequest(request, response, modules) {\n \n\tvar http = modules.request;\n var request_endpoint = 'https://baas.kinvey.com/user/kid_bkFYnCzzzb/login'\n var request_data = {\n username: request.body.email,\n password: request.body.password\n }\n \n http.request({\n uri: request_endpoint,\n method:'POST',\n headers: {\n 'Content-Type':'application/json',\n 'Accept':'application/json',\n 'Authorization': 'Basic a2lkX2JrRlluQ3p6emI6ZTczMWY5YTI4NTgzNDkwMGEzNWMyODEzZGQxNzYyYzI='\n },\n \n body: JSON.stringify(request_data),\n \n }, function(error, res, body){\n if(res.status === 200 ){\n response.body = {\n success:true,\n error: null,\n data: body,\n code: 200\n };\n \n return response.complete();\n }\n \n response.body = {\n \t success:false,\n error: error,\n data: body,\n code: 400\n }\n \n });\n \n}\n\n" }, "HandleTractorsAlertsEventFromAWSBACKEND" : { "code" : "//Captures alerts (deviceOffline, lowBattery, stopThreshold, unpluggedDevice) pushed from AWS \n//and sends notifications (push and email) to all users concerned\n//Created by Abdulmajid on 16th May 2019, Updated on 21st June 2019\n\nfunction onRequest(request, response, modules) {\n var tractorOwnerCol = modules.collectionAccess.collection('TractorOwner');\n var tractorDetailCol = modules.collectionAccess.collection('TractorDetail');\n var usersCol = modules.collectionAccess.collection('user');\n var userAccountsCol = modules.collectionAccess.collection('UserAccounts');\n var notificationCol = modules.collectionAccess.collection('Notification');\n var tractorOperatorCol = modules.collectionAccess.collection('TractorOperator');\n var logger = modules.logger;\n var pushModule = modules.push;\n var emailModule = modules.email;\n var userAcctCreatorIds = [];\n var countNotificationsSaved = 0;\n var alertBody = request.body;\n var supportEmail = \"Hello Tractor <support@hellotractor.com>\";\n var dummyEmail = \"abdulmajid@hellotractor.com\";\n var appsEmail = \"apps2@hellotractor.com\";\n var alertEmail = \"aerishellotractor@yahoo.com\";\n\n modules.logger.info(\"Data posted \" + JSON.stringify(alertBody));\n \n if (alertBody){\n\n //Validate the alert body for success\n var alert = alertBody;\n if (alert.code == 200){\n\n //Alert was successful, continue\n var alertData = alert.data;\n var tractorId = Number(alertData.tractor_id); //Convert tractor id to an integer\n\n logger.info(\"Alert type: \"+alertData.alert_type);\n \n //Find the tractor in tractor detail collection\n tractorDetailCol.findOne({\"TractorID\": tractorId}, function (tractorErr, tractor) {\n if (!tractor || tractorErr) { //If tractor doesnt exist or an error occured, end\n logger.error('Query failed: '+ err);\n finish();\n } else {\n //The tractor has been found\n logger.info(\"Tractor found: \"+tractor.TractorName);\n \n //If an operator was assigned to tractor, find tractor operator\n if (tractor.OperatorID){\n \n //Find operator\n tractorOperatorCol.findOne({\"OperatorID\":tractor.OperatorID}, function(tractorOperatorErr, tractorOperator){\n //Find users (parent and child) and push notification to them with operator details\n findUsersAndPushNotification(alertData, tractor, tractorOperator);\n });\n } else {\n //Find users (parent and child) and push notification to them \n findUsersAndPushNotification(alertData, tractor, null);\n }\n }\n });\n } else {\n //Alert was not a successful one, so end\n finish();\n }\n } else {\n //Alert does not have body, so end\n finish();\n }\n \n function findUsersAndPushNotification(alertData, tractor, tractorOperator){ \n //Add creator Id of child accounts to userAcctCreatorIds\n userAccountsCol.find({\"_acl.creator\": tractor._acl.creator}, function(userActErr, userActs){\n if (userActs){\n userActs.forEach(function(userAct){\n userAcctCreatorIds.push(userAct.accountHolderId);\n });\n }\n\n //Add creator id of parent tractor owner account\n userAcctCreatorIds.push(tractor._acl.creator);\n logger.info(userAcctCreatorIds); //Log tractor owner creator ids\n\n //Find users with creator ids in array\n usersCol.find({\"_acl.creator\": {$in: userAcctCreatorIds}}, function(userErr, users){\n \n //Check if users with those creator ids exist\n if (users){ \n\n //If users exists, find corresponding tractor owner for each user\n users.forEach(function(user){\n tractorOwnerCol.findOne({\"_acl.creator\":user._acl.creator}, function(tractorOwnerErr, tractorOwner){\n if (tractorOwner && canReceiveNotification(tractorOwner, alertData)){\n //Build notification for the traget tractor owner\n var entity = buildNotification(alertData, user, tractorOwner, tractor, tractorOperator)\n //Build push notification here\n logger.info(\"Notification built\");\n\n //Save notification to Notification collection\n notificationCol.save(entity, function(notificationErr, savedNotification){\n logger.info(\"Notification saved\");\n \n //Check if the tractor owner has email notifications turned on\n\n //Build the email subject based on the alert type\n var title = getMessageTitle(entity.action, tractor);\n logger.info(\"Notification email title created\");\n\n \n //Send email notification to tractor owner\n emailModule.send(supportEmail, tractorOwner.username, title, JSON.stringify(entity.message), supportEmail, null, null, appsEmail, function(emailErr, emailResult){\n logger.info(\"New email sent\");\n\n //Assign a unique id to that notification on the user's device\n entity.id = tractor.TractorID + entity.action;\n logger.info(JSON.stringify(entity));\n\n //Send a push notification to that user \n pushModule.sendMessage(user, JSON.stringify(savedNotification), function(pushErr, pushResult) {\n logger.info(\"Push notification sent\");\n countNotificationsSaved++;\n canFinish(users);\n });\n });\n });\n } else {\n //That tractor owner could not be found in the tractor owner collection\n countNotificationsSaved++;\n canFinish(users);\n }\n });\n });\n } else {\n //No users match the creator id in the creator ids array\n finish();\n } \n });\n });\n }\n \n function buildNotification(alertData, user, tractorOwner, tractor, tractorOperator){\n var alertType = alertData.alert_type;\n var notification = {};\n var lastActiveTime = dateToHumanReadable(tractor.LastActiveTime);\n var alerts = JSON.parse(alertData.alerts);\n modules.logger.info(\"Alerts stringify: \"+JSON.stringify(alerts));\n var actualValue, unit;\n if (alerts && alerts[0] && alerts[0].actualValue){\n var baseAlertDetails = alerts[0];\n actualValue = baseAlertDetails.actualValue[0].value? Number(baseAlertDetails.actualValue[0].value).toFixed(2): 0;\n unit = baseAlertDetails.actualValue[0].unit;\n // modules.logger.info(\"Alerts property exists: \"+actualValue+\", \"+unit);\n }\n notification._acl = user._acl;\n notification.userId = user._acl.creator; \n notification.tractorId = tractor.TractorID;\n notification.operatorId = tractor.OperatorID;\n notification.country = tractor.Country;\n notification.street = tractor.Street;\n notification.town = tractor.Town;\n notification.tractorName = tractor.TractorName;\n notification.type = \"alert\"; //TODO: Change to action on production\n notification.read = false;\n \n if (alertType == \"deviceOffline\"){\n notification.action = \"device_offline\";\n notification.message = \"Device Offline! \"+tractor.TractorName +\" (\"+tractor.TractorID+\") has been offline since \"+lastActiveTime+\" at \"+tractor.Street +\", \"+tractor.Town+\", \"+tractor.Country;\n \n } else if(alertType == \"lowBattery\"){\n notification.action = \"low_battery\";\n notification.message = \"Low Battery! \"+tractor.TractorName +\" (\"+tractor.TractorID+\") has low (\"+actualValue+\" \"+unit+\") battery voltage. It was last active on \"+lastActiveTime+\" at \"+tractor.Street +\", \"+tractor.Town+\", \"+tractor.Country; \n \n } else if (alertType == \"stopThreshold\"){\n notification.action = \"stop_threshold\";\n notification.message = \"Stopped! \"+tractor.TractorName +\" (\"+tractor.TractorID+\") has stopped. It was last active on \"+lastActiveTime+\" at \"+tractor.Street +\", \"+tractor.Town+\", \"+tractor.Country;\n \n } else if (alertType == \"unpluggedDevice\"){\n notification.action = \"unplugged_device\";\n if (tractorOperator){\n notification.message = \"Tampering alert! \"+tractor.TractorName +\" (\"+tractor.TractorID+\") has been unplugged. It was last active on \"+lastActiveTime+\" at \"+tractor.Street +\", \"+tractor.Town+\", \"+tractor.Country+\" and operated by \"+tractorOperator.OperatorName;\n } else {\n notification.message = \"Tampering alert! \"+tractor.TractorName +\" (\"+tractor.TractorID+\") has been unplugged. It was last active on \"+lastActiveTime+\" at \"+tractor.Street +\", \"+tractor.Town+\", \"+tractor.Country;\n }\n } else {\n notification.action = \"\";\n notification.message = \"\";\n }\n var notificationToSave = modules.kinvey.entity(notification); \n notificationToSave.extras = JSON.parse(JSON.stringify(notification));\n notificationToSave.data = alertData;\n\n return notificationToSave;\n }\n \n function getMessageTitle(alertType, tractor){\n logger.info(\"MessageTitle: \"+alertType);\n if (alertType == \"device_offline\"){\n return tractor.TractorName+\" (\"+tractor.TractorID+\") is offline\";\n } else if (alertType == \"low_battery\"){\n return tractor.TractorName+\" (\"+tractor.TractorID+\") has low battery\"; \n } else if (alertType == \"stop_threshold\"){\n return tractor.TractorName+\" (\"+tractor.TractorID+\") has stopped\";\n } else if (alertType == \"unplugged_device\"){\n return \"Critical! \"+tractor.TractorName+\" (\"+tractor.TractorID+\") \"+\" has been tampered with\";\n } else {\n return \"Tractor Alert\";\n }\n }\n\n var dateToHumanReadable = function(date) {\n return modules.moment(date).format(\"dddd Do MMMM YYYY LT\") + \" UTC\";\n } \n \n function canFinish(users){\n modules.logger.info(\"canFinish\");\n if (users.length == countNotificationsSaved){\n response.complete();\n }\n }\n\n function finish(){\n modules.logger.info('alert posted');\n response.complete();\n }\n\n var canReceiveNotification = function (tractorOwner, alertData){\n var alertType = alertData.alert_type;\n if (alertType == \"deviceOffline\" && tractorOwner.tractorOfflineNotifications){\n return true;\n } else if (alertType == \"lowBattery\" && tractorOwner.batteryAlertNotifications){\n return true;\n } else if (alertType == \"stopThreshold\" && tractorOwner.tractorStoppedNotifications){\n return true;\n } else if (alertType == \"unpluggedDevice\" && tractorOwner.deviceUnpluggedNotifications){\n return true;\n } else {\n return false;\n }\n } \n}" }, "generateMultipleSubCodes" : { "code" : "function onRequest(request, response, modules) {\n var SubscriptionCode = modules.collectionAccess.collection('TrackerIds');\n var serial = 700000; \n var start = 0;\n var count = 0;\n var Log = modules.logger;\n var end = 101;\n var subscriptionCodeArray = [];\n\n for( var i=1; i<= end;i++ )\n {\n try { \n throw i\n }\n catch(ii){\n var subscription = modules.kinvey.entity();\n Log.info( ii );\n \t\t\tsubscription.tracker_id = serial+ii;\n \t\t\tsubscriptionCodeArray.push( subscription.tracker_id );\n \t\t\tSubscriptionCode.save( subscription , function(err, done){\n \t\tstart++;\n \t\tif( err ){\n Log.info( 'There was an error ' + new Error(err).message );\n response.complete();\n\t\t\t\t}\n \tif( start === end ){\n Log.info( 'Done creating the ' + start + ' subscription code' );\n \t response.body = subscriptionCodeArray;\n \t response.complete(); \n }\n \n })\n }\n\n }\n \n \n}" }, "UpdateOrgIdOfTestAccounts" : { "code" : "function onRequest(request, response, modules) {\n\tvar userIds = ['57755c856a0ce9903c9d3360','57a32ef51286159774582f6e','584ab380a82816222bb6d235','595d1e186d7414261985b7ee','5880ceab2775caa763da389e','5880a40eb51efa0054073db5','588621ca4bf2860e29506232','58ad707fd7f0c00f677d0386','59675180aa94bb31662d0542','59693c14d9e084db0ed13c61','59693f125091bdd865488844','596c83e1aaff309d209d03bf','596c926c47ce5fb83e7bb60d','596e007222b97f07224e5148','5970ad82e37359542c9224d5','5970bb1fd9e084db0efeb585','5971c91dd9e084db0e051899','5978baeebb9a08bd5f973694','5979b5bcb1a40d825f25c327','590dfe014cdaa8cc46317f95','590e3a5403c033054bb47296','59119fd27f26c7f677dc1ec2','59119fc666396a6a5a033b24','5914835937af0ce271ce4781','591c480d7f26c7f677fffc75','59244b26f6c276070450a95c','5926b59b2d2abd0b48f5033c','5c4acae51be4947c2a82c969','5cc1b61c0d81981916435db1','5926eaff412a52876283c3e9','594a57373148999f14c6fd19','594a5e61c6cc75e018a58728','594a683d95a78b6652defd99','594a6e2695a78b6652df067e','594a6eb8fb78dc8541572ab8','594a6ee43a75447a71e0b28d','594a6f07fdd3007a204b4b90','594a6f5797ff353725fd8579','594a6f6d97ff353725fd87b0','594a6f9497ff353725fd889f','594a6fa997ff353725fd88d7','594a6fd13148999f14c788f1','580f7b6296db64743e9bb919','574370f9d9f4789c35cb0338','59649de496a2e4ce722cac50','59692ec2aaff309d20887db7','597876aad9e084db0e2d9293','59789e7522b97f07228e4a6a','597a108eed54c22e2dac70c2','597a10bb0068fddd63048e47','597a1129bc01340f44fe7a1f','597a15690068fddd6304aa37','597b20a5bc01340f44049d5d','597b6d63da41c985393d60e4','59fc516562142d61702ba3f4','599597dd57a0ac6131e3a3a7','597f85f9223ed6cc64ee4d88','573e280d8b6dec5a0a19e8d3','5981d7e3db498fb8698fc4bf','5981deeea7e3a72002e18b57','59832f73bac152c62b9e3e8b','59833e4d4bf677be29ca95b3','598452896bcc6cd6286e9677','5984646e2e7d8e5057f4c99f','57d59a8ae442d5cd62fff18a','5989dddda98d39d52ff6de94','598abc86a98d39d52ffbe64f','598b31b4a98d39d52ffe817b','598bad3f0a9cd91972d87289','59918c22996ab5127d256fcd','5991d0cdad79140d50e1a03f','5994541f9e31abd55344c086','5994b75f072de6d901c43366','5995511abd51c9fe6c82dab1','599552bd2065fcf86c0e5fc0','599b229abd51c9fe6c95b2e0','59a02bdaa86d05de4f82721f','59aff545e884417c04ee20fd','59aff91e68c53f4a04558583','59affd086c3eec5704e9e34f','59affe9a3044bb86044a7d81','59afff3c6c3eec5704e9eba5','59b0009c14ee5050048d59f2','59b001821de368500469e67a','59b001fe253ea95d04cff24a','59b002ef68c53f4a0455acc2','59b004c2e884417c04ee6329','59b0064dacf229560435e891','59b0083a253ea95d04d00a5c','59b0098e68c53f4a0455c4f0','59b00a516c3eec5704ea14b0','59b00c026c3eec5704ea1b9c','59b014dce3ca225a046ad714','59b015abffa95a8c04e0b3ac','59b0226968c53f4a04562725','59b0be08acf2295604389bd2','59b0bfa58be17b630433e69b','59b140a6ffa95a8c04e535e3','59b2b9d8253ea95d04db6677','59b2bc1d3044bb8604560a7d','59b2bccf14ee50500498d9d6','59b2bd60829a57510498744f','59b69fb13044bb86046cfb22','59b9130e666de6dd686ec0d5','59ba19772956d208391461fb','59ba31991da0293553f57881','59ba70021da0293553f6e6ca','59ba72e8444b82101008de09','59bbb4201da0293553fdb765','59bbb67793fb1a4b3fbf657b','59bbb5400d2d000e39497a89','59bbb76970e1a5af611a5be5','59bbec962956d208391e6738','59bc2c36a4359e427b73a8e5','59bfc6e53957270a10c9962b','59c8da3e57f0e7db0439456f','59c8e50b4b8e59835001b402','59cbadacf2a357b87910d060','59ccc6dcf2a357b879146caf','59d371a077d93b4c45ea0bf9','59db4eaaeac3a7be79a0dcd4','59ddfe8b0316794906e37ab4','59e60c91602ab435acc98f4f','59e794b5c4e088352e955b33','59e8b2cef471b935d4b30756','59ea859ea1c6270c5aba3d07','59f0b19f41189d6db7cb8152','59f0e330dc32af6c0e81c891','59f72dcf54d7f86185c1c38b','59f87cd822007259c01ec633','59f87d43a7be19616aa0729b','59fb0fd68275075ad4238eaa','5a006e7762142d617038da14','5a1423574fdd9839b3d91b03','5a2e1bd8ccaefc7c9871f9c0','5a621b6cbb0c8d08f577c1c9','5a780db3272e722e375b34a0','5a81a40e70545c51289cb8bd','5a8daa17dace1e70f4fd29e5','5a9807a6aadf852d1e3611f5','5ab3ee0b0265ee1eeef72913','5abb684e34fcd45ca018000d','5ac8cdc66c6c072f1ab37283','5b0c1e7ddc7f736e7b2c52d5','5b0d37c034d5081b1a182c54','5b1a6e32b64219456096fd62','5b0ea9d06ea97e7e0d5aab72','5b2b75acec708e78196fb86a','5b2fe92bbe3a4735a9703c8a','5b3ba2d77f20c939e41c61a7','590ba4790bda67ce2a9e242f','5a5f722ebb9512014010d057','597f2fbc06bc90625230fb14','5981f7eddb498fb869907ad6','598441c5e0dad61876b95ebe','599453d6bce993cf532f8729','59b77da5acf22956045ccf52','59b8fc9249665b910c54cdb3','59bbbad370e1a5af611a6f1a','59bbbca893fb1a4b3fbf8886','59bbbdd932e59719494a55c9','59bbcc54a543fc0932a86c49','59cb82e783fa92e10440805d','59e7712d998e2b587472f3d2','59edbeee07d30f0bfc21ba68','5a006b28a1fc7e0799e0fa30','5a17dda9ee5e4a7959752e97','5a4e0c6ef39f437e698725e4','5a5f7b6d50518b24649c8dd5','5a6078d46915eb0706c1c0dd','5a827b28c6265606b5eae28a','5a8e5db1cce302426fc33930','5a9ece06aadf852d1e4a49b0','5aa25e5422764d7bdbd9297b','5abebfcfc92757629c9501f8','5abedbc415e7187c15c678a9','5adf331e4c356779d5336e8b','5b0e92a49e8a967e08900288','5b801fb4e0738f05bfb750ef','5b802cc89789c1262f7b0fe2','5b8afa5e21c8c67a83d62451','5c5c40cb45e75e68f283a8d4','5c5c5774c892215f50c7d315','5c684fa9c341455f55b551db','5ca8372186f15650735548ac','5cb813d815266c5a4df92397','598ad07cbac152c62bcfb83a','5af40bd426860c399aba621b','5c040de2a8df1f4ec30f70d9','5c08be0e8a7e2a7e4632f1c3','5c0a99d7e7fad106f6c370a7','5c5a8e941be4947c2af2ddd2','5a8831637ab19c0d42abd747','5c5bc107c892215f50c3b6ea','5c828bce0d5f9d0c944e5fee','5cc1b2fd21125a1911533f04','598ad681bac152c62bcfd9ef','59c8d84f8c59558e131dd898'];\n var userCol = modules.collectionAccess.collection('user');\n var tractorOwnerCol = modules.collectionAccess.collection('TractorOwner');\n var bookingAgentCol = modules.collectionAccess.collection('BookingAgents');\n \n var doc = {orgID: \"111\"};\n bookingAgentCol.update({\"_acl.creator\": {$in: userIds}}, {$set: doc}, {multi: true, upsert: false}, function(err){\n modules.logger.info(\"Docs Updated\");\n response.complete();\n });\n}" }, "PostDataToAwsBackend" : { "code" : "function onRequest(request, response, modules) {\n\n var Model = modules.collectionAccess.collection('FarmMeasures');\n var httpClient = modules.request;\n var aws_backend_syncronize_url = 'https://cloud.hellotractor.com/api/v1/farmMeasures';\n var count = 0;\n var skip = 0;\n var modelCount = 0;\n var log = modules.logger;\n var Logger = modules.collectionAccess.collection('Logger');\n \n var makePostRequest = function(data){\n httpClient.post({\n uri: aws_backend_syncronize_url,\n method: 'POST',\n json:data\n },function(err, res, body){\n \t count++;\n if( count == modelCount ){\n response.complete();\n modules.logger.info(\"done\");\n }\n })\n\n }\n \n \n Logger.find({logID:998}, function(err, val){\n \n \t\tmodules.logger.info(\"The log count is \" + val[0].Message );\n Model.find({},{\"limit\":1000, \"skip\": val[0].Message }, function(err, docs){\n if ( docs.length === 0 ) {\n modules.logger.info(\"successfully posted all farm measures\");\n response.complete();\n }\n \t\t \tmodelCount = docs.length; \n \n \tdocs.forEach( function(doc){\n \tmakePostRequest(doc);\n count++;\n \n if( count == modelCount ){\n Logger.update({logID:998}, {$set:{\"Message\": val[0].Message+=400 }}, function(err, updated){\n log.info(\"successfully updated log count\");\n response.complete();\n });\n \t }\n \n \t});\n \n });\n \n })\n \n \n }\n\n \n\n\n\n" }, "syncUserProfileImageUrl" : { "code" : "function onRequest(request, response, modules) {\n \n var Model = modules.collectionAccess.collection('TractorOwner');\n var http = modules.request;\n var filesHash = {};\n var uri = 'https://' + request.headers.host + '/blob/' + modules.backendContext.getAppKey();\n var headers = {\n \t \"Authorization\": request.headers.authorization\n\t}\n\n http.get({\n uri:uri,\n headers: headers\n }, function(error, res, body){\n if(error){\n modules.logger.info( error.message );\n response.complete(400);\n }\n \t\n var count = 0;\n var images = JSON.parse(body);\n for(var i=0; i < images.length;i++){\n filesHash[images[i]._id] = images[i]._downloadURL;\n count++;\n if( count === images.length){\n \n Model.find({}, function(err, docs){\n var savedCount = 0;\n if( err ){\n modules.logger.info(\"error occured\" + err.message);\n response.complete(400);\n }\n \n for(var i=0; i<docs.length;i++){\n \n if( docs[i].ProfileImage && docs[i].ProfileImage._id ){\n \tif( filesHash[docs[i].ProfileImage._id] ){\n Model.update({_id: docs[i]._id}, {$set:{profile_image_url: filesHash[docs[i].ProfileImage._id]}}, \n function(error, updated){\n if( error ){\n modules.logger.info(\"error updating doc\");\n response.complete(400);\n }\n \t\tmodules.logger.info(\"successfully updated doc profile_image_url\");\n \t\tsavedCount++;\n \tif( savedCount === docs.length){\n modules.logger.info(\"Done updating\");\n response.complete(200);\n }\n \t\t\n })\n }\n else {\n \t\tsavedCount++;\n \tif( savedCount === docs.length){\n modules.logger.info(\"Done updating\");\n response.complete(200);\n } \n }\n }\n else {\n savedCount++;\n \tif( savedCount === docs.length){\n modules.logger.info(\"Done updating\");\n response.complete(200);\n }\n }\n }\n \n }) \n \n }\n\n }\n\n });\n\n}" }, "PostBookingsDataToBackend" : { "code" : "function onRequest(request, response, modules) {\n\n var Booking = modules.collectionAccess.collection('ServiceBookings');\n var httpClient = modules.request;\n var aws_backend_syncronize_url = 'https://cloud.hellotractor.com/api/v1/synchronize/';\n \n var count = 0;\n var modelCount = 0;\n var index = 0;\n var Logger = modules.logger;\n \n var makePostRequest = function(data){\n httpClient.postAsync({\n uri: aws_backend_syncronize_url,\n method: 'POST',\n json:data\n }).then( \n \t\tfunction(res, body){\n count++;\n if( count == modelCount ){\n response.complete();\n }\n },function(error){\n if( error ){\n Logger.info(\"An error occured\" + new Error(error).message );\n response.complete()\n\n }\n })\n \n };\n \n// var postAllBookingsInChunk = function(indexCount){\n// var bookingsCount=3318, limit=200, skip=0;\n// if( index > 0 ){\n// skip+= limit;\n// }\n \n// bookingsCount-= limit;\n// if( bookingsCount < 0 ){\n// return;\n// }\n \n// Booking.find({},{\"limit\": limit, \"skip\": skip}, function(err, docs){\n// modelCount = docs.length; \n// var booking_agent;\n// docs.forEach( function(doc){\n// if( doc.bookingAgentData != null ){\n// if( booking_agent = JSON.parse(doc.bookingAgentData) ){\n// doc.booking_agent_name = booking_agent.name ? booking_agent.name : \"\";\n// doc.booking_agent_phone = booking_agent.phone ? booking_agent.phone : \"\" ;\n// doc.booking_agent_latitude = booking_agent.latitude ? booking_agent.latitude :\"\" ;\n// doc.booking_agent_longitude = booking_agent.longitude ? booking_agent.longitude : \"\";\n// doc.booking_agent_profile_image_url = booking_agent.profileImageURL ? booking_agent.profileImageURL :\"\";\n// }\n// }\n \n// makePostRequest(doc);\n \n// });\n// });\n \n// postAllBookingsInChunk(indexCount+1);\n \n// }\n \n\n Booking.find({},{\"limit\": 200, \"skip\":3357}, function(err, docs){\n modelCount = docs.length; \n var booking_agent;\n docs.forEach( function(doc){\n if( doc.bookingAgentData != null ){\n if( booking_agent = JSON.parse(doc.bookingAgentData) ){\n doc.booking_agent_name = booking_agent.name ? booking_agent.name : \"\";\n doc.booking_agent_phone = booking_agent.phone ? booking_agent.phone : \"\" ;\n doc.booking_agent_latitude = booking_agent.latitude ? booking_agent.latitude :\"\" ;\n doc.booking_agent_longitude = booking_agent.longitude ? booking_agent.longitude : \"\";\n doc.booking_agent_profile_image_url = booking_agent.profileImageURL ? booking_agent.profileImageURL :\"\";\n }\n }\n \n makePostRequest(doc);\n \n });\n });\n \n}\n" }, "HandleTractorFuelDataPostedFromAWSBackend" : { "code" : "function onRequest(request, response, modules) {\n modules.logger.info('fuel data posted');\n}" }, "ComputeTempFuelVolumes" : { "code" : "//Retrieves the current fuel raw value of recently updated tractors, \n//converts the raw value to fuel litres and fuel volume and updates\n//the PrevTempFuelData field\n//Created by Abdulmajid on 2nd July 2019, Last Update: 24th February 2020\n\nfunction onRequest(request, response, modules) {\n var tractorDetailCol = modules.collectionAccess.collection(\"TractorDetail\");\n var fuelCalibrationResultsCol = modules.collectionAccess.collection(\"FuelCalibrationResults\");\n var logCol = modules.collectionAccess.collection(\"Logs\");\n var dateTimeAgo = modules.moment.utc().subtract(1, \"minutes\").format(\"YYYY-MM-DD HH:mm:ss\");\n var dateTimeAgoThirtyMins = modules.moment.utc().subtract(30, \"minutes\").format(\"YYYY-MM-DD HH:mm:ss\"); \n var countTractorsToUpdate = 0;\n var log = modules.logger;\n\n var tractorDetailQuery = {\n $and: [\n {LastActiveTime: {$gt: dateTimeAgoThirtyMins}},\n {UpdatedAt: {$gt: dateTimeAgo}}\n ]\n };\n var now = modules.moment.utc().format(\"YYYY-MM-DD HH:mm:ss\");\n var log = modules.logger;\n\n tractorDetailCol.find(tractorDetailQuery, function(tractorErr, tractorDetailList){\n if (tractorDetailList && tractorDetailList.length > 0){\n countTractorsToUpdate = tractorDetailList.length;\n log.info(\"Tractors were found: \"+countTractorsToUpdate);\n fetchFuelCalibrationResults(tractorDetailList);\n } else {\n log.info(\"No tractors found meeting the query parameters, \"+tractorErr);\n shouldFinish();\n }\n });\n\n var fetchFuelCalibrationResults = function(tractorDetailList){\n // Create an array of all the tractor model id's\n var tractorModelIdArr = tractorDetailList.reduce(function(acc, tractor, index){\n if (tractor.TractorModelID) acc.push(tractor.TractorModelID);\n return acc;\n }, []);\n\n log.info(\"Tractor model id array created, \"+JSON.stringify(tractorModelIdArr));\n //Retrieve calibration results for tractor models in array and map each result to tractor model\n fuelCalibrationResultsCol.find({tractorModelId: {$in: tractorModelIdArr}}, function(fuelCalibrationErr, fuelCalibrationList){\n if (fuelCalibrationList && fuelCalibrationList.length > 0){\n var tractorModelCalibrationMap = fuelCalibrationList.reduce(function(acc, fuelCalibration, index){\n acc[fuelCalibration.tractorModelId] = fuelCalibration;\n return acc;\n }, {});\n\n log.info(\"About to compute fuel volumes for all tractors, \"+JSON.stringify(tractorModelCalibrationMap));\n computeFuelVolumesForTractors(tractorDetailList, tractorModelCalibrationMap);\n } else {\n log.info(\"Fuel calibration result not found for tractor model array: \"+JSON.stringify(tractorModelIdArr))\n response.complete()\n }\n });\n }\n\n var computeFuelVolumesForTractors = function(tractorDetailList, tractorModelCalibrationMap){\n tractorDetailList.forEach(function(tractorDetail){\n if (tractorDetail.TractorModelID && tractorDetail.FuelRawValue){\n var tempFuelVols = computeTempFuelFolumeForTractor(tractorDetail, tractorModelCalibrationMap[tractorDetail.TractorModelID]);\n log.info(\"Update prev temp fuel volumes: \"+JSON.stringify(tempFuelVols));\n var prevTempFuelData = {PrevTempFuelData: tempFuelVols};\n tractorDetailCol.update({TractorID: tractorDetail.TractorID}, {$set: prevTempFuelData}, {upsert: false, multi: true}, function(updateErr, updateDoc){\n log.info(\"Tractor ID:- \"+tractorDetail.TractorID+\" updated successfully - \"+JSON.stringify(tempFuelVols));\n updateFuelLog(tractorDetail, prevTempFuelData);\n }); \n\n } else {\n log.info(\"Temp fuel volumes is empty: \"+tractorDetail.TractorID);\n countTractorsToUpdate--;\n shouldFinish(); \n }\n });\n }\n\n var updateFuelLog = function (tractorDetail, prevTempFuelData){\n var fuelLevel = Number(tractorDetail.FuelVolume?(tractorDetail.FuelVolume).toFixed(0):0);\n \tvar fuelLitres = Number(tractorDetail.FuelLitres?(tractorDetail.FuelLitres).toFixed(0):0);\n var operatorId = tractorDetail.OperatorID;\n\n var fuelHistory = {_acl: tractorDetail._acl, TractorID: tractorDetail.TractorID, FuelLevel: fuelLevel, FuelLitres: fuelLitres,\n CreatedAt: now, UpdatedAt: now, OperatorID: operatorId, TractorAddress: tractorDetail.Street+\", \"+tractorDetail.Town+\", \"+tractorDetail.Country,\n TractorName: tractorDetail.TractorName, TractorModelID: tractorDetail.TractorModelID, FuelRawValue: tractorDetail.FuelRawValue,\n ImplementsAttached: tractorDetail.ImplementsAttached\n };\n\n fuelHistory = modules.kinvey.entity(fuelHistory);\n var fuelLog = modules.kinvey.entity({\n message: fuelHistory,\n type: \"fuel_update\",\n extras: prevTempFuelData\n });\n\n logCol.save(fuelLog, function(fuelLogErr, fuelLog){\n modules.logger.info(\"Fuel log saved for \"+tractorDetail.TractorID);\n countTractorsToUpdate--;\n shouldFinish();\n });\n } \n \n var shouldFinish = function (){\n if (countTractorsToUpdate <= 0){\n log.info(\"Compute temp fuel volumes finished successfully\");\n response.complete();\n }\n } \n}\n\nfunction computeTempFuelFolumeForTractor(tractorDetail, tractorCalibration){\n var fuelRawValue = tractorDetail.FuelRawValue; \n var lastActiveTime = tractorDetail.LastActiveTime; \n\n var prevTempFuelData = tractorDetail.PrevTempFuelData? tractorDetail.PrevTempFuelData: [];\n var minMeasurableRawValue = tractorCalibration.MinMeasurableRawValue;\n var maxMeasurableRawValue = tractorCalibration.MaxMeasurableRawValue;\n var minMeasurableLitres = tractorCalibration.MinMeasurableLitres;\n var maxMeasurableLitres = tractorCalibration.MaxMeasurableLitres;\n var reserveLitres = tractorCalibration.ReserveLitres;\n var maxLitres = tractorCalibration.MaxLitres;\n var intercept = tractorCalibration.intercept;\n var gradient = tractorCalibration.gradient;\n\n var fuelLitres;\n if (fuelRawValue < maxMeasurableRawValue && fuelRawValue > minMeasurableRawValue){\n fuelLitres = (gradient * fuelRawValue) + intercept;\n fuelLitres = fuelLitres > maxMeasurableLitres? maxMeasurableLitres: fuelLitres < minMeasurableLitres? minMeasurableLitres: fuelLitres;\n } else {\n if (gradient < 0){ //Negative graph of values\n fuelLitres = fuelRawValue >= maxMeasurableRawValue? minMeasurableLitres: maxMeasurableLitres;\n } else { //Positive graph of values\n fuelLitres = fuelRawValue >= maxMeasurableRawValue? maxMeasurableLitres: minMeasurableLitres;\n }\n }\n\n var fuelData = {};\n var fuelVolume = fuelLitres/maxMeasurableLitres * 100.0;\n fuelData.FuelLitres = parseFloat(fuelLitres.toFixed(0));\n fuelData.FuelVolume = parseFloat(fuelVolume.toFixed(0));\n fuelData.FuelRawValue = fuelRawValue;\n fuelData.LastActiveTime = lastActiveTime;\n prevTempFuelData.push(fuelData);\n\n return prevTempFuelData;\n}" }, "PopulateFuelHistoryAndSendAlert" : { "code" : "//For all new updated tractors, extracts the PrevTempFuelData, filters the noise \n//from the group of fuel data and saves the data in FuelHistory\n//Created by Abdulmajid on 2nd July 2019, Updated: 17th Feb 2020\n\nfunction onRequest(request, response, modules) {\n var tractorDetailCol = modules.collectionAccess.collection(\"TractorDetail\");\n var tractorOperatorCol = modules.collectionAccess.collection(\"TractorOperator\"); \n var notificationCol = modules.collectionAccess.collection('Notification');\n var userCol = modules.collectionAccess.collection('user');\n var tractorOwnerCol = modules.collectionAccess.collection('TractorOwner');\n var fuelHistoryCol = modules.collectionAccess.collection('FuelHistory');\n var userAccountsCol = modules.collectionAccess.collection('UserAccounts');\n\n //Notification modules\n var pushModule = modules.push;\n var emailModule = modules.email;\n\n var today = modules.moment.utc().format(\"YYYY-MM-DD HH:mm:ss\");\n var dateTimeAgo = modules.moment.utc().subtract(2, \"minutes\").format(\"YYYY-MM-DD HH:mm:ss\");\n var countTractorsToUpdate = 0;\n// var tractorDetailQuery = {LastActiveTime: {$gt: dateTimeAgo}};\n \tvar dateTimeAgoThirtyMins = modules.moment.utc().subtract(30, \"minutes\").format(\"YYYY-MM-DD HH:mm:ss\");\n \n var tractorDetailQuery = {\n $and: [\n {LastActiveTime: {$gt: dateTimeAgoThirtyMins}},\n {UpdatedAt: {$gt: dateTimeAgo}}\n ]\n };\n \n var hellotractorSupport = 'Hello Tractor <support@hellotractor.com>';\n //var dummyEmail = 'abdulmajid@hellotractor.com';\n var log = modules.logger;\n \n var n = 5; //Smoothning threshold\n var outlierThresh = 20; //Outliers over 20% are not tolorated\n var tractorCreatorIds = [];\n var tractorOperatorIdOperatorMap = {};\n\n //Fuel change constants\n var fuelChangeType = {\n NORMAL: \"Normal\",\n DROP: \"Drop\",\n RISE: \"Rise\"\n };\n\n //Find all recently updated tractors within the last 5 minutes\n tractorDetailCol.find(tractorDetailQuery, function(tractorErr, tractorDetailList){\n if (tractorDetailList && tractorDetailList.length > 0){\n countTractorsToUpdate = tractorDetailList.length;\n modules.logger.info(\"Count Tractors Updated: \"+countTractorsToUpdate);\n tractorDetailList.forEach(function(tractorDetail){\n tractorCreatorIds.push(tractorDetail._acl.creator);\n });\n\n\n //TODO: Add fiel name to query and refactor map to be OperatorID to tractorOperator\n tractorOperatorCol.find({\"_acl.creator\": {$in: tractorCreatorIds}}, function(tractorOperatorErr, tractorOperatorList){\n if (tractorOperatorList && tractorOperatorList.length > 0){\n tractorOperatorList.forEach(function(tractorOperator){\n tractorOperatorIdOperatorMap[tractorOperator.OperatorID] = tractorOperator;\n });\n }\n\n tractorDetailList.forEach(function(tractorDetail){\n var fuelData = getSmoothenedFuelData(tractorDetail);\n if (fuelData != null){\n //Go ahead to: \n // 1. Update the FuelVolume and FuelLitres on TractorDetail and save fuelData to FuelHistory\n // 2. Compare the initial FuelVolume and NewFuelVolume, an send alert for increase or decrease by 20%,\n // 3. Reset the PrevTempFuelData array to empty\n alertUserOfSuddenChangeAndUpdateTractor(tractorDetail, fuelData);\n\n } else {\n log.info(\"Filtered fuel data is null\");\n countTractorsToUpdate--;\n shouldFinish();\n }\n });\n });\n\n } else {\n log.info(\"Tractors not found\");\n shouldFinish();\n }\n });\n\n var getSmoothenedFuelData = function (tractorDetail){\n var tempFuelValues = tractorDetail.PrevTempFuelData;\n if (tempFuelValues && tempFuelValues.length >= n){\n var count = tempFuelValues.length;\n var totalFuelLitres = 0;\n var averageFuelLitres = 0;\n \n tempFuelValues.forEach(function(fuelValue){\n totalFuelLitres += fuelValue.FuelLitres;\n });\n \n averageFuelLitres = totalFuelLitres/count;\n var newTempFuelValues = tempFuelValues;\n\n tempFuelValues.forEach(function(fuelValue){\n var percentChange = Math.abs((fuelValue.FuelLitres - averageFuelLitres)/averageFuelLitres * 100);\n if (percentChange > outlierThresh && newTempFuelValues.length > 1){\n newTempFuelValues.pop(fuelValue);\n }\n });\n \n var newTotalFuelLitres = 0; \n var newTotalFuelVolume = 0;\n var newTotalRawValue = 0;\n\n newTempFuelValues.forEach(function(fuelValue){\n newTotalFuelLitres += fuelValue.FuelLitres;\n newTotalFuelVolume += fuelValue.FuelVolume;\n newTotalRawValue += fuelValue.FuelRawValue;\n });\n \n count = newTempFuelValues.length;\n var newAverageFuelVolume = newTotalFuelVolume/count;\n var newAverageFuelLitres = newTotalFuelLitres/count;\n var newAverageFuelRawValue = newTotalRawValue/count;\n \n var data = {\n FuelLitres: parseFloat(newAverageFuelLitres.toFixed(0)),\n FuelVolume: parseFloat(newAverageFuelVolume.toFixed(0)),\n FuelRawValue: parseFloat(newAverageFuelRawValue.toFixed(0))\n };\n \n return data;\n }\n \n return;\n }\n\n /**\n * Initiates a push notification when there's a sudden change in tractor fuel level\n * @param {*} tractorDetail The tractor whose fuel level has changed\n * @param {*} newFuelData \n */\n var alertUserOfSuddenChangeAndUpdateTractor = function (tractorDetail, newFuelData){\n var initFuelVol = tractorDetail.FuelVolume, finalFuelVol = newFuelData.FuelVolume;\n var fuelChange = initFuelVol - finalFuelVol;\n //Notifications are sent when the fuel volume (%) changes by more than 15%\n log.info(\"Fuel Diff: \"+fuelChange);\n\n if (finalFuelVol != 0 && finalFuelVol != 100){\n if (fuelChange > 10 && tractorDetail.Speed <= 3){\n //There was a sudden drop in fuel level while tractor is idle (travelling less than 3m/s)\n log.info(\"Fuel data dropped\");\n findUserAndSendNotification(tractorDetail, initFuelVol, finalFuelVol, newFuelData, fuelChangeType.DROP);\n } else if (fuelChange < -10 && tractorDetail.Speed <= 3){\n //There was a sudden increase in fuel level while tractor is idle (travelling less than 3m/s)\n log.info(\"Fuel data rose\");\n findUserAndSendNotification(tractorDetail, initFuelVol, finalFuelVol, newFuelData, fuelChangeType.RISE);\n } else {\n //Normal change in fuel level: No notification required, just update tractor\n log.info(\"Fuel data changed normally 1\");\n updateTractorFuelVolume(tractorDetail, newFuelData);\n }\n } else {\n //Normal change in fuel level: No notification required, just update tractor\n log.info(\"Fuel data changed normally 2\");\n updateTractorFuelVolume(tractorDetail, newFuelData); \n }\n }\n\n //Builds the notification to be sent (with a message of rise or drop) to the user\n var buildNotificaton = function (type, tractorDetail, user, tractorOwner, initFuelVol, finalFuelVol, newFuelData){\n\n log.info(\"Tractor Owner User id: \"+user._acl.creator);\n\n var notificationMessage;\n var action;\n if (type == fuelChangeType.DROP){\n notificationMessage = tractorDetail.TractorName + \" (\" + tractorDetail.TractorID + \") has a sudden drop in fuel from \"+initFuelVol+\"% to \"+finalFuelVol+\"%\";\n action = \"fuel_change_drop\";\n } else {\n notificationMessage = tractorDetail.TractorName + \" (\" + tractorDetail.TractorID + \") has a sudden rise in fuel from \"+initFuelVol+\"% to \"+finalFuelVol+\"%\";\n action = \"fuel_change_rise\";\n }\n\n var notification = {\n _acl: user._acl,\n userId: user._acl.creator,\n tractorId: tractorDetail.TractorID,\n operatorId: tractorDetail.OperatorID,\n operatorId: tractorDetail.OperatorID,\n country: tractorDetail.Country,\n street: tractorDetail.Street,\n town: tractorDetail.Town,\n tractorName: tractorDetail.TractorName,\n read: false,\n message: notificationMessage,\n type: 'alert',\n action: action,\n tractorModelID: tractorDetail.TractorModelID,\n engineHours: tractorDetail.EngineHours,\n data: JSON.parse(JSON.stringify(newFuelData))\n };\n\n var notificationToSave = modules.kinvey.entity(notification); \n notificationToSave.extras = JSON.parse(JSON.stringify(notification)); \n return notificationToSave;\n }\n\n\n /**\n * Sends a push notification and/or email to the creator of that tractor\n * @param {*} tractorDetail The tractor whose fuel level changed beyond 20%\n * @param {*} initFuelVol The previous fuel volume (%)\n * @param {*} finalFuelVol The new fuel volume (%)\n * @param {*} newFuelData The fuel information to be updated: FuelVolume and FuelLitres\n * @param {*} fuelChangeType The type of change that occured: Can be Normal, Rise or Drop\n */\n var findUserAndSendNotification = function (tractorDetail, initFuelVol, finalFuelVol, newFuelData, fuelChangeType){\n userCol.findOne({\"_acl.creator\": tractorDetail._acl.creator}, function(userErr, user){\n if (user){\n log.info(\"User found \"+JSON.stringify(user));\n tractorOwnerCol.findOne({\"_acl.creator\": tractorDetail._acl.creator}, function(tractorOwnerErr, tractorOwner){\n if (tractorOwner){\n log.info(\"Tractor owner found\");\n var notification = buildNotificaton(fuelChangeType, tractorDetail, user, tractorOwner, initFuelVol, finalFuelVol, newFuelData);\n notificationCol.save(notification, function(notificationErr, notificationSaved){\n notificationSaved.id = tractorDetail.TractorID+user._id+\"FUELCHANGE\";\n log.info(\"Notification saved\");\n pushModule.sendMessage(user, JSON.stringify(notificationSaved), function(pushErr, pushResult) {\n log.info(\"Push notification sent to \"+user.username);\n if (tractorOwner.emailNotifications){\n log.info(\"Email notifications true\");\n var emailTitle = notificationSaved.message;\n var emailBody = notificationSaved.message;\n // JSON.stringify(tractorOwner.username) //TODO: Replace dummyEmail in production\n emailModule.send(hellotractorSupport, JSON.stringify(tractorOwner.username), emailTitle, emailBody, function(emailErr, emailResult) {\n log.info(\"Email notifications sent to \"+JSON.stringify(tractorOwner.username));\n updateTractorFuelVolume(tractorDetail, newFuelData);\n });\n } else {\n log.info(\"Email notifications false\");\n updateTractorFuelVolume(tractorDetail, newFuelData);\n }\n }); \n });\n } else {\n log.info(\"Tractor owner not found \"+tractorDetail._acl.creator);\n updateTractorFuelVolume(tractorDetail, newFuelData);\n }\n });\n \n } else {\n log.info(\"User not found\");\n updateTractorFuelVolume(tractorDetail, newFuelData);\n }\n });\n }\n\n //Updates the TractorDetail collection with the newest fuel information (FuelVolume and FuelLitres)\n var updateTractorFuelVolume = function (tractorDetail, newFuelData){\n var fuelData = {\n FuelVolume: newFuelData.FuelVolume,\n FuelLitres: newFuelData.FuelLitres,\n PrevTempFuelData: []\n }; //Reset prev temp fuel data and update fuel volume and fuel litres\n \n tractorDetailCol.update({TractorID: tractorDetail.TractorID}, {$set: fuelData}, {upsert: false}, function(updateErr, updateData){\n log.info(\"Tractor \"+tractorDetail.TractorID+\" updated successfully: \"+JSON.stringify(newFuelData));\n updateFuelHistoryCol(tractorDetail, fuelData, newFuelData);\n });\n }\n\n\n var updateFuelHistoryCol = function (tractorDetail, fuelData, newFuelData){\n var fuelLevel = parseFloat(fuelData.FuelVolume?(fuelData.FuelVolume).toFixed(0):0);\n \tvar fuelLitres = parseFloat(fuelData.FuelLitres?(fuelData.FuelLitres).toFixed(0):0);\n var tractorOperator = tractorOperatorIdOperatorMap[tractorDetail.OperatorID];\n var operatorName = tractorOperator? tractorOperator.OperatorName:\"Operator Unassigned\";\n var operatorId = tractorOperator? tractorOperator.OperatorID:null;\n\n var fuelHistory = {\n _acl: tractorDetail._acl,\n TractorID: tractorDetail.TractorID,\n FuelLevel: fuelLevel,\n FuelLitres: fuelLitres,\n CreatedAt: today,\n UpdatedAt: today,\n OperatorName: operatorName,\n OperatorID: operatorId,\n \tTractorAddress: buildTractorAddress(tractorDetail.Street, tractorDetail.Town, tractorDetail.Country),\n TractorName: tractorDetail.TractorName,\n TractorModelID: tractorDetail.TractorModelID,\n FuelRawValue: newFuelData.FuelRawValue,\n PositionLatitude: tractorDetail.PositionLatitude,\n PositionLongitude: tractorDetail.PositionLongitude,\n LastActiveTime: tractorDetail.LastActiveTime,\n ImplementsAttached: tractorDetail.ImplementsAttached \n };\n\n fuelHistory = modules.kinvey.entity(fuelHistory);\n fuelHistoryCol.save(fuelHistory, function(fuelHistoryErr, fuelHistory){\n modules.logger.info(\"Fuel history saved for \"+tractorDetail.TractorID);\n countTractorsToUpdate--;\n shouldFinish();\n });\n }\n\n var buildTractorAddress = function (street, town, country){\n var address = street? street: \"\";\n if (town){\n address += address?\", \"+town: town;\n }\n\n if (country){\n address += address?\", \"+country: country;\n }\n\n return address;\n }\n\n var shouldFinish = function (){\n if(countTractorsToUpdate <= 0){\n response.complete();\n }\n }\n}" }, "FireMaintenanceAlert" : { "code" : "//Sends maintenance notification (push and email) to the user (parent and child)\n//with the list of maintenance having the specified engine hours and tractor model\n//for all recently updated tractors\n//Created by Abdulmajid on 2nd July 2019, Updated on 26th March 2020\n\nfunction onRequest(request, response, modules) {\n\n var tractorOwnerCol = modules.collectionAccess.collection('TractorOwner');\n var tractorDetailCol = modules.collectionAccess.collection('TractorDetail'); \n var userCol = modules.collectionAccess.collection('user');\n var userAccountsCol = modules.collectionAccess.collection('UserAccounts');\n var maintenanceRepoCol = modules.collectionAccess.collection('MaintenanceRepo');\n var notificationCol = modules.collectionAccess.collection('Notification');\n var maintenanceHistoryCol = modules.collectionAccess.collection(\"MaintenanceHistory\");\n var emailModule = modules.email;\n var pushModule = modules.push;\n var log = modules.logger;\n var hellotractorSupport = 'Hello Tractor <support@hellotractor.com>';\n var dummyEmail = 'abdulmajid@hellotractor.com';\n var dateTimeOneMinuteAgo = modules.moment.utc().subtract(1, \"minutes\").format(\"YYYY-MM-DD HH:mm:ss\");\n var dateTimeThirtyMinutesAgo = modules.moment.utc().subtract(30, \"minutes\").format(\"YYYY-MM-DD HH:mm:ss\");\n var now = modules.moment.utc().format(\"YYYY-MM-DD HH:mm:ss\");\n\n var userAccountsMap = {};\n var countNotificationsToSend = 0;\n var countNotificationsToSendPerTractorOwner = 0;\n\n //Query tractor detail collection\n var tractorDetailQuery = {UpdatedAt: {$gte: dateTimeOneMinuteAgo}, LastActiveTime: {$gte: dateTimeThirtyMinutesAgo}};\n tractorDetailCol.find(tractorDetailQuery, function(tractorDetailErr, tractorDetailList){\n\n if (tractorDetailList && tractorDetailList.length > 0){\n log.info(\"Number of tractors found: \"+tractorDetailList.length);\n var tractorDetailsMap = {};\n var tractorModelIds = [];\n var tractorCreatorIds = [];\n\n tractorDetailList.forEach(function(tractorDetail){\n if (tractorDetail.TractorModelID != null){\n var currTractorDetails = tractorDetailsMap[tractorDetail._acl.creator];\n if (!currTractorDetails) currTractorDetails = []; \n currTractorDetails.push(tractorDetail);\n tractorDetailsMap[tractorDetail._acl.creator] = currTractorDetails; \n tractorModelIds.push(tractorDetail.TractorModelID);\n tractorCreatorIds.push(tractorDetail._acl.creator);\n }\n });\n\n log.info(tractorModelIds.length+\" tractor non-unique tractor models found and \"+tractorCreatorIds+\" non-unique tractor owners found\");\n tractorModelIds = tractorModelIds.filter (function (value, index, array) { \n return array.indexOf (value) == index;\n });\n\n tractorCreatorIds = tractorCreatorIds.filter (function (value, index, array) { \n return array.indexOf (value) == index;\n });\n\n log.info(\"About to fetch maintenance list for \"+tractorModelIds.length+\" tractor models owned by \"+tractorCreatorIds.length+\" tractor owners\");\n fetchMaintenanceList(tractorModelIds, tractorDetailsMap, tractorCreatorIds);\n } else {\n log.info(\"No tractors found to be updated one minute ago\")\n shouldFinish(); \n }\n });\n\n var fetchMaintenanceList = function(tractorModelIds, tractorDetailsMap, tractorCreatorIds){\n maintenanceRepoCol.find({tractorModelId: {$in: tractorModelIds}}, function(tractorMaintenanceErr, tractorMaintenanceList){\n if (tractorMaintenanceList){\n modules.logger.info(\"Maintenance fetched: \"+tractorMaintenanceList.length);\n var tractorMaintenanceMap = {};\n tractorMaintenanceList.forEach(function(maintenanceItem){\n var tractorMaintenance = tractorMaintenanceMap[maintenanceItem.tractorModelId];\n if (!tractorMaintenance) tractorMaintenance = [];\n tractorMaintenance.push(maintenanceItem);\n tractorMaintenanceMap[maintenanceItem.tractorModelId] = tractorMaintenance;\n });\n\n findTractorOwners(tractorModelIds, tractorDetailsMap, tractorCreatorIds, tractorMaintenanceMap);\n } else {\n log.info(\"Tractor maintenance not found for tractor models: \"+JSON.stringify(tractorModelIds));\n shouldFinish();\n }\n });\n }\n\n var findTractorOwners = function(tractorModelIds, tractorDetailsMap, tractorCreatorIds, tractorMaintenanceMap){\n tractorOwnerCol.find({\n $and: [\n {\"_acl.creator\": {$in: tractorCreatorIds}},\n {maintenanceNotifications: true}\n ]\n }, function(tractorOwnerErr, tractorOwners){\n if (tractorOwners && tractorOwners.length > 0){\n countNotificationsToSend = tractorOwners.length; //Total number of parent tractor owners to send notification\n log.info(tractorOwners.length + \" tractor owners found\");\n var tractorOwnersMap = {};\n tractorOwners.forEach(function(tractorOwner){\n tractorOwnersMap[tractorOwner._acl.creator] = tractorOwner;\n });\n\n findCorrespondingChildAccounts(tractorModelIds, tractorDetailsMap, tractorCreatorIds, tractorMaintenanceMap, tractorOwners, tractorOwnersMap);\n } else {\n log.info(\"No tractor owner found to own these tractors or receive maintenance notifications\");\n shouldFinish();\n }\n });\n }\n\n var findCorrespondingChildAccounts = function(tractorModelIds, tractorDetailsMap, tractorCreatorIds, tractorMaintenanceMap, tractorOwners, tractorOwnersMap){\n var creatorIdAccountHolderIdListMap = {};\n userAccountsCol.find({\"_acl.creator\": {$in: tractorCreatorIds}}, function(userAccountColErr, userAccounts){\n if (userAccounts && userAccounts.length > 0){\n userAccounts.forEach(function(userAccount){\n //Creates a map of tractor owner creator id to user accounts\n var tractorOwnerUserAccounts = userAccountsMap[userAccount._acl.creator];\n if (!tractorOwnerUserAccounts) tractorOwnerUserAccounts = [];\n tractorOwnerUserAccounts.push(userAccount);\n userAccountsMap[userAccount._acl.creator] = tractorOwnerUserAccounts;\n\n //Creates a map of tractor owner creator id to user account holder ids\n var accountHolderIdList = creatorIdAccountHolderIdListMap[userAccount._acl.creator];\n if (!accountHolderIdList) accountHolderIdList = [];\n accountHolderIdList.push(userAccount.accountHolderId);\n creatorIdAccountHolderIdListMap[userAccount._acl.creator] = accountHolderIdList;\n });\n\n log.info(\"Count user accounts found: \"+userAccounts.length);\n }\n //Go ahead and find users even if child accounts were not found\n findUsers(tractorModelIds, tractorDetailsMap, tractorCreatorIds, tractorMaintenanceMap, tractorOwners, tractorOwnersMap, creatorIdAccountHolderIdListMap);\n });\n }\n\n var findUsers = function(tractorModelIds, tractorDetailsMap, tractorCreatorIds, tractorMaintenanceMap, tractorOwners, tractorOwnersMap, creatorIdAccountHolderIdListMap){\n tractorOwners.forEach(function(tractorOwner){\n var tractorOwnerTractors = tractorDetailsMap[tractorOwner._acl.creator];\n var userCreatorIds = [];\n userCreatorIds.push(tractorOwner._acl.creator);\n if (creatorIdAccountHolderIdListMap[tractorOwner._acl.creator])\n userCreatorIds = userCreatorIds.concat(creatorIdAccountHolderIdListMap[tractorOwner._acl.creator]);\n userCol.find({\"_acl.creator\": {$in: userCreatorIds}}, function(userErr, users){\n if (users && users.length > 0){\n var tractorIdFilteredTractorMaintenanceList = filterTractorsRequiringMaintenance(tractorMaintenanceMap, tractorOwnerTractors);\n log.info(users.length+\" users found for \"+tractorOwner._acl.creator);\n notifyUsersIfNeccessary(tractorOwner, users, tractorOwnerTractors, tractorIdFilteredTractorMaintenanceList, tractorCreatorIds);\n } else {\n log.info(\"Couldn't find users for \"+tractorOwner._acl.creator+\", \"+tractorOwner.username);\n countNotificationsToSend--;\n shouldFinish();\n }\n });\n });\n }\n\n var filterTractorsRequiringMaintenance = function(tractorMaintenanceMap, tractorOwnerTractors){\n var tractorIdFilteredTractorMaintenanceList = {};\n tractorOwnerTractors.forEach(function(tractorOwnerTractor){\n log.info(\"Main tractor id: \"+tractorOwnerTractor.TractorID+\", model id: \"+tractorOwnerTractor.TractorModelID);\n var tractorMaintenanceList = tractorMaintenanceMap[tractorOwnerTractor.TractorModelID];\n if (tractorMaintenanceList){ //Maintenance exists for tractor model\n modules.logger.info(\"Tractor maintenance list exist for \"+tractorOwnerTractor.TractorID+\": \"+tractorMaintenanceList.length);\n var maintenanceList = tractorIdFilteredTractorMaintenanceList[tractorOwnerTractor.TractorID];\n tractorMaintenanceList.forEach(function(maintenance){\n var lastMaintenanceNotification = tractorOwnerTractor.LastMaintenanceNotificationEngineHours? tractorOwnerTractor.LastMaintenanceNotificationEngineHours: 0;\n var tractorEngineHours = (tractorOwnerTractor.FixedEngineHours? tractorOwnerTractor.FixedEngineHours: 0) + tractorOwnerTractor.EngineHours;\n if ((tractorEngineHours % maintenance.engineHours ) == 0 && tractorEngineHours > lastMaintenanceNotification){\n if (!maintenanceList) maintenanceList = [];\n maintenanceList.push(maintenance);\n tractorIdFilteredTractorMaintenanceList[tractorOwnerTractor.TractorID] = maintenanceList;\n }\n });\n }\n\n modules.logger.info(\"Filtered maintenance count for \"+tractorOwnerTractor.TractorID);\n });\n \n return tractorIdFilteredTractorMaintenanceList;\n }\n\n var notifyUsersIfNeccessary = function(tractorOwner, users, tractorOwnerTractors, tractorIdFilteredTractorMaintenanceList, tractorCreatorIds){\n if (tractorIdFilteredTractorMaintenanceList && tractorOwnerTractors){\n countNotificationsToSendPerTractorOwner = users.length * tractorOwnerTractors.length;\n log.info(\"About to notify users about maintenance alerts\")\n users.forEach(function(user){\n tractorOwnerTractors.forEach(function(tractor){\n var maintenanceList = tractorIdFilteredTractorMaintenanceList[tractor.TractorID];\n if (maintenanceList && maintenanceList.length > 0){\n var checks = maintenanceList.reduce(function(acc, maintenance, index){\n acc.push(maintenance.maintenanceCheck);\n return acc;\n }, []);\n var notificationPerUserPerTractor = buildNotification(tractor, tractorOwner, user, maintenanceList, checks);\n var maintenanceHistoryListPerUserPerTractor = buildMaintenanceHistory(user, tractor, tractorOwner, maintenanceList);\n saveAndSendMaintenanceHistoryAndNotification(tractor, tractorOwner, user, notificationPerUserPerTractor, maintenanceHistoryListPerUserPerTractor, checks);\n } else {\n log.info(\"Tractor not due for maintenance \"+tractor.TractorID);\n countNotificationsToSendPerTractorOwner--;\n if (countNotificationsToSendPerTractorOwner <= 0) {\n countNotificationsToSend--;\n shouldFinish();\n }\n }\n });\n \n })\n } else {\n log.info(\"No notification to send for \"+tractorOwner._acl.creator);\n countNotificationsToSend--;\n shouldFinish();\n }\n }\n\n var buildNotification = function (tractorDetail, tractorOwner, user, maintenanceList, checks){\n var tractorEngineHours = (tractorDetail.FixedEngineHours? tractorDetail.FixedEngineHours: 0) + tractorDetail.EngineHours;\n var notificationMessage = (maintenanceList.length < 4)? \n notificationMessage = tractorDetail.TractorName + \" (\" + tractorDetail.TractorID + \") is due for \"+tractorEngineHours+\"-hour maintenance: \" + checks.join(', '):\n notificationMessage = tractorDetail.TractorName + \" (\" + tractorDetail.TractorID + \") is due for \"+tractorEngineHours+\"-hour maintenance: You have \"+checks.length+\" pending maintenance activities\";\n\n var notification = {\n _acl: user._acl,\n userId: user._acl.creator,\n tractorId: tractorDetail.TractorID,\n operatorId: tractorDetail.OperatorID,\n operatorId: tractorDetail.OperatorID,\n country: tractorDetail.Country,\n street: tractorDetail.Street,\n town: tractorDetail.Town,\n tractorName: tractorDetail.TractorName,\n read: false,\n message: notificationMessage,\n type: 'action',\n action: 'maintenance',\n tractorModelID: tractorDetail.TractorModelID,\n engineHours: tractorDetail.EngineHours,\n data: JSON.parse(JSON.stringify(maintenanceList))\n };\n\n var notificationToSave = modules.kinvey.entity(notification); \n notificationToSave.extras = JSON.parse(JSON.stringify(notification)); \n return notificationToSave;\n }\n\n var buildMaintenanceHistory = function(user, tractorDetail, tractorOwner, maintenanceList){\n var maintenanceHistoryList = [];\n maintenanceList.forEach(function(maintenance){\n var tractorEngineHours = (tractorDetail.FixedEngineHours? tractorDetail.FixedEngineHours: 0) + tractorDetail.EngineHours;\n var maintenance = {\n _acl: user._acl,\n createdAt: now,\n updatedAt: now,\n dateDone: \"\",\n done: 0,\n engineHours: tractorEngineHours,\n maintenanceHours: maintenance.engineHours,\n maintenanceCheck: maintenance.maintenanceCheck,\n tractorId: tractorDetail.TractorID,\n tractorModelId: tractorDetail.TractorModelID,\n latitude: tractorDetail.PositionLatitude,\n longitude: tractorDetail.PositionLongitude,\n lastActiveTime: tractorDetail.LastActiveTime\n }\n\n var maintenanceToSave = modules.kinvey.entity(maintenance);\n maintenanceHistoryList.push(maintenanceToSave);\n })\n \n return maintenanceHistoryList;\n }\n\n var saveAndSendMaintenanceHistoryAndNotification = function(tractorDetail, tractorOwner, user, notificationPerUserPerTractor, maintenanceHistoryListPerUserPerTractor, checks){\n var tractorEngineHours = (tractorDetail.FixedEngineHours? tractorDetail.FixedEngineHours: 0) + tractorDetail.EngineHours;\n var tractorUpdateDoc = {\"LastMaintenanceNotificationEngineHours\": tractorEngineHours};\n tractorDetailCol.update({_id: tractorDetail._id}, {$set: tractorUpdateDoc}, {upsert: false}, function(tractorUpdatedErr, tractorUpdatedDoc){\n maintenanceHistoryCol.insert(maintenanceHistoryListPerUserPerTractor, function(maintenanceHistoryErr, maintenanceHistoryResult){\n notificationCol.save(notificationPerUserPerTractor, function(notificationErr, notificationSaved){\n notificationSaved.id = tractorOwner._id + tractorDetail.TractorID + notificationPerUserPerTractor.action;\n pushModule.sendMessage(user, JSON.stringify(notificationSaved), function(pushErr, pushResult) {\n var emailTitle = tractorDetail.TractorName + \" (\"+tractorDetail.TractorID+\") is due for \"+tractorEngineHours+\"-hour maintenance\";\n var emailBody = tractorDetail.TractorName + \" (\" + tractorDetail.TractorID + \") is due for \"+tractorEngineHours+\"-hour maintenance: \\n\" + createNumberedList(checks);\n // JSON.stringify(tractorOwner.username) //TODO: Replace dummyEmail in production\n emailModule.send(hellotractorSupport, JSON.stringify(tractorOwner.username), emailTitle, emailBody, function(emailErr, emailResult) {\n log.info(\"Errors: \"+tractorUpdatedErr+\", \"+maintenanceHistoryErr+\", \"+notificationErr+\", \"+pushErr+\", \"+emailErr);\n countNotificationsToSendPerTractorOwner--;\n if (countNotificationsToSendPerTractorOwner <= 0){\n countNotificationsToSend--;\n shouldFinish();\n }\n });\n });\n });\n })\n });\n }\n\n var shouldFinish = function(){\n if (countNotificationsToSend <= 0){\n modules.logger.info(\"Should Finish: \"+countNotificationsToSend);\n response.complete();\n }\n }\n \n var createNumberedList = function(maintenanceDescList){\n var orderedList = \"\\n\";\n for(var i = 0; i < maintenanceDescList.length; i++){\n orderedList += (i+1) + \". \"+maintenanceDescList[i]+\"\\n\";\n }\n\n return orderedList;\n }\n}" }, "ExportTractorOperatorIDAndTractorID" : { "code" : "function onRequest(request, response, modules) {\n var tractorIdOperatorId = {};\n var Tractor = modules.collectionAccess.collection('TractorDetail');\n Tractor.find({}, function(err, docs){\n \n if( err ){\n modules.logger.info(err.message);\n response.error(\"there was an error\");\n }\n \n docs.reduce( function(tractorIdMap, tractor){\n tractorIdMap[tractor.TractorID] = tractor.OperatorID\n return tractorIdOperatorId;\n \n }, tractorIdOperatorId)\n \n modules.logger.info(\"The map is \" + JSON.stringify(tractorIdOperatorId));\n response.complete();\n \n });\n \n \n}" }, "updateTractorCreator" : { "code" : "function onRequest(request, response, modules) {\n \n var Tractor = modules.collectionAccess.collection(\"TractorDetail\")\n var tractorIDsToUpdateCreator = [501022,501032,501037]\n var newOwnerCreator = \"5d3f1cc7ecc87c44b90447d7\"\n Tractor.find({\"TractorID\": { $in: tractorIDsToUpdateCreator }}, function(err, docs){\n if( err ) {\n modules.logger.info(\"Whoops! there was an error \" + err.message)\n return response.error( err );\n }\n var count = 0;\n \n //log the old records\n modules.logger.info( JSON.stringify(docs));\n \n // update the doc creator \n \tdocs.forEach( function(doc){\n Tractor.update({\"TractorID\": doc.TractorID}, {$set:{\"_acl.creator\":newOwnerCreator}}, function(err, done){\n if(err){\n modules.logger.info(\"Whoops! an error occured \" + err.message );\n response.error(err)\n }\n else {\n count++;\n if( count === docs.length){\n modules.logger.info(\"updation successfull\")\n response.complete();\n }\n }\n })\n \n })\n \n \n })\n \n}" }, "PostTractorOperatorIDToAWS" : { "code" : "function onRequest(request, response, modules) {\n \n var Client = modules.request;\n var totalTractorsCount = 1319\n var currentTractorsCount = 0\n var totalLoop = 10;\n var data = [];\n \n var postTractorOperatorID = function(){\n var count = currentTractorsCount++;\n if( count >= totalTractorsCount ){\n modules.logger.info(\"nothing else for this worker\");\n response.complete();\n }\n Client.postAsync({\n uri: \"https://cloud.hellotractor.com/api/v1/posttest\",\n method: \"POST\",\n json: {\"name\": \"paul\"}\n }).then( function(res, body){\n \n \tmodules.logger.info( \"The response data is \" + res );\n modules.logger.info( \"The response body is \" + body );\n\n postTractorOperatorID();\n \n }, function(err){\n \n modules.logger.info(\"Whoops! there was an error\")\n postTractorOperatorID();\n\n })\n }\n \n for(var i=0; i<totalLoop; i++){\n postTractorOperatorID();\n }\n \n \n}" }, "CreateUserApi" : { "code" : "function onRequest(request, response, modules) {\n \n var httpClient = modules.request;\n var cnt = 0;\n \n var usersObj = [\n {\n \"username\": \"bwibopatrick@gmail.com\",\n \t\t\t\"password\": \"bwibopatrick\",\n \t\t\t\"first_name\":\"Bwibo\",\n \t\t\t\"last_name\": \"Patrick\",\n \t\t\t\"phone\": \"727433259\",\n \t\t\t\"orgIDs\":\"6000\",\n \t\t\t\"user_type\": \"2\",\n \t\t\t\"email\":\"bwibopatrick@gmail.com\",\n },\n \n {\n \"username\": \"erastusadongo@gmail.com\",\n \t\t\t\"password\": \"erastusadongo\",\n \t\t\t\"first_name\":\"Erastus \",\n \t\t\t\"last_name\": \"Adongo\",\n \t\t\t\"phone\": \"735488307\",\n \t\t\t\"orgIDs\":\"60002\",\n \t\t\t\"user_type\": \"2\",\n \t\t\t\"email\":\"erastusadongo@gmail.com\",\n },\n {\n \"username\": \"knyakibwoga@gmail.com\",\n \t\t\t\"password\": \"knyakibwoga\",\n \t\t\t\"first_name\":\"Kepha\",\n \t\t\t\"last_name\": \"Nyakibuonga\",\n \t\t\t\"phone\": \"727845849\",\n \t\t\t\"orgIDs\":\"6004\",\n \t\t\t\"user_type\": \"2\",\n \t\t\t\"email\":\"knyakibwoga@gmail.com\",\n },\n \n {\n \"username\": \"moonstone254@gmail.com\",\n \t\t\t\"password\": \"moonstone254\",\n \t\t\t\"first_name\":\"Lydia\",\n \t\t\t\"last_name\": \"Makori\",\n \t\t\t\"phone\": \"702417235\",\n \t\t\t\"orgIDs\":\"6005\",\n \t\t\t\"user_type\": \"2\",\n \t\t\t\"email\":\"moonstone254@gmail.com\",\n },\n \n {\n \"username\": \"wemoadams1234@gmail.com\",\n \t\t\t\"password\": \"wemoadams1234\",\n \t\t\t\"first_name\":\"Moses\",\n \t\t\t\"last_name\": \"Emmanuel\",\n \t\t\t\"phone\": \"713057127\",\n \t\t\t\"orgIDs\":\"6006\",\n \t\t\t\"user_type\": \"2\",\n \t\t\t\"email\":\"wemoadams1234@gmail.com\",\n },\n \n {\n \"username\": \"moruma57@gmail.com\",\n \t\t\t\"password\": \"moruma57\",\n \t\t\t\"first_name\":\"Moses\",\n \t\t\t\"last_name\": \"Odhiambo Oruma\",\n \t\t\t\"phone\": \"722221876\",\n \t\t\t\"orgIDs\":\"6007\",\n \t\t\t\"user_type\": \"2\",\n \t\t\t\"email\":\"moruma57@gmail.com\",\n },\n \n \n ];\n \n var createUser = function(userObj){\n \n httpClient.request({\n \t\t\turi: \"https://baas.kinvey.com/user/kid_bkFYnCzzzb\",\n \t\tjson: userObj,\n \t\tmethod:\"POST\",\n \t\theaders: {\n \"Authorization\":\"Basic a2lkX2JrRlluQ3p6emI6OTIyNjYwNWI3YjA5NDc3YWI3ZmZiZTVkYmFiNWUxODE===\"\n }\n \t\t\t}, function(res,body){\n modules.logger.info(\"request successful\");\n \t\t\t\tresponse.body = body;\n \t\t\t cnt++\n \n if( usersObj.length === cnt ){\n response.complete();\n }\n\n }, function(error){\n modules.logger.info(\"There was an error \" + error.message);\n cnt++;\n if( usersObj.length === cnt ){\n response.complete();\n }\n \n })\n }\n \n usersObj.forEach(createUser);\n \n}\n\n\n// function onRequest(request, response, modules) {\n \n// var httpClient = modules.request;\n// var cnt = 0;\n \n// var usersObj = [\n// {\n// \"username\": \"test_paul\",\n// \t\t\t\"password\": \"123456\",\n// }\n// ];\n \n// var createUser = function(userObj){\n \n// httpClient.request({\n// \t\t\turi: \"https://baas.kinvey.com/user/kid_bkFYnCzzzb/login\",\n// \t\tjson: userObj,\n// \t\tmethod:\"POST\",\n// \t\theaders: {\n// \"Authorization\":\"Basic a2lkX2JrRlluQ3p6emI6OTIyNjYwNWI3YjA5NDc3YWI3ZmZiZTVkYmFiNWUxODE===\"\n// }\n// \t\t\t}, function(res,body){\n// modules.logger.info(\"request successful\");\n// \t\t\t\tresponse.body = body;\n// \t\t\t cnt++\n \n// if( usersObj.length === cnt ){\n// response.complete();\n// }\n\n// }, function(error){\n// modules.logger.info(\"There was an error \" + error.message);\n// cnt++;\n// if( usersObj.length === cnt ){\n// response.complete();\n// }\n \n// })\n// }\n \n// usersObj.forEach(createUser);\n \n// }\n\n" }, "AutomateReportsGeneration" : { "code" : "/**\n * Sends an email report and/or push notification to tractor owners requiring automated tractor activities which\n * can either be sent weekly, monthly or quarterly\n * Created by Abdulmajid on 22nd August 2019\n * @param {*} request \n * @param {*} response \n * @param {*} modules \n */\n\nfunction onRequest(request, response, modules) {\n var tractorOwnerCol = modules.collectionAccess.collection(\"TractorOwner\")\n var userCol = modules.collectionAccess.collection(\"user\");\n var tractorDetailCol = modules.collectionAccess.collection(\"TractorDetail\");\n var userAccountsCol = modules.collectionAccess.collection(\"UserAccounts\");\n var notificationCol = modules.collectionAccess.collection(\"Notification\");\n var pushEmail = modules.email;\n var push = modules.push;\n var counter = 0;\n var log = modules.logger;\n var moment = modules.moment;\n\n var debugProps = {\n nowHourMinutes: modules.moment.utc().format(\"HH:mm\"),\n fromEmail: \"Hello Tractor <support@hellotractor.com>\",\n now: moment.utc().format(\"YYYY-MM-DD HH:mm:ss\"),\n nowDay: moment.utc().format(\"YYYY-MM-DD\"),\n nowV2: moment.utc().format(\"YYYY-MM-DD HH:mm\"),\n nowISO: moment.utc().toISOString(),\n oneHourAgoISO: moment.utc().subtract(1, \"hours\").toISOString(),\n oneWeekAgo: moment.utc().subtract(1, \"weeks\").format(\"YYYY-MM-DD HH:mm\"),\n oneMonthAgo: moment.utc().subtract(1, \"months\").format(\"YYYY-MM-DD HH:mm\"),\n threeMonthsAgo: moment.utc().subtract(3, \"months\").format(\"YYYY-MM-DD HH:mm\"),\n oneWeekAgoDay: moment.utc().subtract(1, \"weeks\").format(\"YYYY-MM-DD\"),\n oneMonthAgoDay: moment.utc().subtract(1, \"months\").format(\"YYYY-MM-DD\"),\n threeMonthsAgoDay: moment.utc().subtract(3, \"months\").format(\"YYYY-MM-DD\"),\n nowHourMinutes: \"17:00\",\n csvReportUri: \"https://cloud.hellotractor.com/report/log/csv/\",\n appEmail: \"apps2@hellotractor.com\"\n }\n\n var releaseProps = {\n nowHourMinutes: moment.utc().format(\"HH:mm\"),\n fromEmail: \"Hello Tractor <support@hellotractor.com>\",\n now: moment.utc().format(\"YYYY-MM-DD HH:mm:ss\"),\n nowV2: moment.utc().format(\"YYYY-MM-DD HH:mm\"),\n nowISO: moment.utc().toISOString(),\n oneHourAgoISO: moment.utc().subtract(1, \"hours\").toISOString(),\n oneWeekAgo: moment.utc().subtract(1, \"weeks\").format(\"YYYY-MM-DD HH:mm\"),\n oneMonthAgo: moment.utc().subtract(1, \"months\").format(\"YYYY-MM-DD HH:mm\"),\n threeMonthsAgo: moment.utc().subtract(3, \"months\").format(\"YYYY-MM-DD HH:mm\"),\n oneWeekAgoDay: moment.utc().subtract(1, \"weeks\").format(\"YYYY-MM-DD\"),\n oneMonthAgoDay: moment.utc().subtract(1, \"months\").format(\"YYYY-MM-DD\"),\n threeMonthsAgoDay: moment.utc().subtract(3, \"months\").format(\"YYYY-MM-DD\"),\n nowDay: moment.utc().format(\"YYYY-MM-DD\"), \n nowHourMinutes: moment.utc().format(\"HH:mm\"),\n csvReportUri: \"https://cloud.hellotractor.com/report/log/csv/\",\n appEmail: \"apps2@hellotractor.com\"\n } \n\n var props = releaseProps; //TODO: Replace with releaseProps in production;\n\n log.info(\"Initializations: \"+props.nowISO);\n log.info(\"Timestamp- nowV2: \"+props.nowV2);\n\n //Tractor owner query\n var tractorOwnerQuery = {\n $and: [\n {\"tractorActivityReports\": true},\n {\n $or: [\n {\"lastAutomatedReportTime\": {$exists: false}}, \n {$and: [{\"lastAutomatedReportTime\": {$lte: props.oneWeekAgo}}, {\"reportInterval\": 0}]},\n {$and: [{\"lastAutomatedReportTime\": {$lte: props.oneMonthAgo}}, {\"reportInterval\": 1}]},\n {$and: [{\"lastAutomatedReportTime\": {$lte: props.threeMonthsAgo}}, {\"reportInterval\": 2}]}\n ]\n },\n {\n $or: [\n {\"endWorkingTime\": props.nowHourMinutes}, \n {\"endWorkingTime\": {$exists: false}}\n ]\n }\n ]\n }\n\n //Find tractor owners requiring automated tractor activity reports\n tractorOwnerCol.find(tractorOwnerQuery, function(tractorOwnerErr, tractorOwnerList){\n if (tractorOwnerList && tractorOwnerList.length > 0){\n log.info(\"Tractor owners list: \"+tractorOwnerList.length);\n counter = tractorOwnerList.length;\n tractorOwnerList.forEach(function(tractorOwner){\n var tractorDetailQuery = {\"_acl.creator\": tractorOwner._acl.creator};\n \n //For each tractor owner, find their corresponding tractors\n tractorDetailCol.find(tractorDetailQuery, function(tractorDetailErr, tractorDetailList){\n if (tractorDetailList && tractorDetailList.length > 0){\n var userAccountsQuery = {\"_acl.creator\": tractorOwner._acl.creator}; \n\n //For each tractor owner, find all user accounts associated with the user\n userAccountsCol.find(userAccountsQuery, function(userAccountsErr, userAccountsList){\n //Create an array of creatorIds requiring tractor activity reports\n var userIds = userAccountsList.map(function(userAccount){\n return userAccount.accountHolderId;\n });\n\n userIds.push(tractorOwner._acl.creator); //Add the main creator id to the user ids array\n\n log.info(\"Tractor detail length: \"+tractorDetailList.length);\n var reportInterval = tractorOwner.reportInterval;\n var tractorListCSV = buildTractorsCSVList(tractorDetailList);\n var dateRange = getReportDateRange(reportInterval);\n var timeZone = getTimeZone(tractorOwner);\n var body = buildRequestBody(tractorOwner, tractorListCSV, dateRange, timeZone);\n var reportsUri = props.csvReportUri;\n log.info(\"Initial reports request body: \"+JSON.stringify(body));\n executeReportsRequest(body, reportsUri, userIds, tractorOwner, dateRange, tractorListCSV);\n });\n } else {\n log.info(\"No tractor found for tractor owner\");\n counter--\n canFinish(); \n }\n });\n });\n\n } else {\n log.info(\"No tractor owner exists meeting query criteria\");\n canFinish();\n }\n });\n\n var canFinish = function (){\n if (counter <= 0){\n log.info(\"Finished:: AutomateReportsGeneration\");\n response.complete();\n }\n }\n\n /**\n * Makes a request against the AWS CSV report enpoint - https://cloud.hellotractor.com/report/log/csv/\n * @param {*} reportsRequestBody The body of the report including tractors in csv, customer name, customer email, and timezone\n * @param {*} reportsUri The AWS CSV report endpoint\n * @param {*} userIds The users (main and sub-account) who should receive the report\n * @param {*} tractorOwner The main tractor owner to whom the reports belong to\n * @param {*} dateRange The start and end date separated by the pipe character\n * @param {*} tractorListCSV The list of tractors separated by comma\n */\n\n var executeReportsRequest = function(reportsRequestBody, reportsUri, userIds, tractorOwner, dateRange, tractorListCSV){\n var header = {\"Content-Type\": \"application/json\"};\n var options = {method: \"POST\", uri: reportsUri, body: JSON.stringify(reportsRequestBody), headers: header};\n log.info(\"Options: \"+JSON.stringify(options));\n modules.request.request(options, function(reportsError, reportsRes, reportsBody){\n if (reportsError || !reportsBody){\n log.info(\"An error occured or report body was empty: \"+JSON.stringify(reportsError));\n log.info(\"Error occured: \"+JSON.stringify(reportsRes));\n log.info(\"Error occured, reports body: \"+JSON.stringify(reportsBody));\n counter--;\n canFinish();\n } else {\n log.info(\"Reports body: \"+JSON.parse(reportsBody));\n log.info(\"Reports sent to: \"+tractorOwner.username);\n sendCSVReportToSubAccounts(JSON.parse(reportsBody), userIds, tractorOwner, dateRange, tractorListCSV);\n }\n });\n }\n\n /**\n * Build the CSV endpoint request body\n * @param {*} tractorOwner The main tractor owner to whom the reports belong to\n * @param {*} tractorCSVList The list of tractors separated by comma\n * @param {*} dateRange The start and end date separated by the pipe character\n * @param {*} timeZone Timezone of the tractor owner based on the phone number\n */\n var buildRequestBody = function(tractorOwner, tractorCSVList, dateRange, timeZone){\n var body = {\n dates: dateRange,\n tractor_ids: tractorCSVList,\n customer_name: tractorOwner.first_name,\n customer_email: tractorOwner.username\n };\n if (timeZone) body.tz = timeZone;\n return body;\n }\n\n /**\n * Builds the report date range (start and end date) based on the report interval\n * @param {*} reportInterval The report interval which can either be one week, one month, or three months\n * @returns A pipe separated character of start time and end time\n */\n var getReportDateRange = function (reportInterval){\n var startTime = \"\", endTime = props.nowDay;\n if (reportInterval == 0){ //Weekly report\n startTime = props.oneWeekAgoDay;\n } else if (reportInterval == 1){ //Monthly report\n startTime = props.oneMonthAgoDay;\n } else if (reportInterval == 2){ //Quarterly report\n startTime = props.threeMonthsAgoDay;\n } else {\n startTime = props.oneWeekAgoDay; \n }\n\n return startTime +\"|\"+endTime;\n }\n\n\n\n /**\n * Builds the reports date messaging which can either be \"last week\", \"last month\", and \"last quarter\"\n * @param {*} reportInterval The interval can either be 0 = weekly, 1 = monthly, or 2 = quarterly\n * @returns The report interval messaging\n */\n var getReportsDateMessaging = function (reportInterval){\n var messaging = \"\";\n if (reportInterval == 0){ //Weekly report\n messaging = \"last week\";\n } else if (reportInterval == 1){ //Monthly report\n messaging = \"last month\";\n } else if (reportInterval == 2){ //Quarterly report\n messaging = \"last quarter\";\n } else {\n messaging = \"last week\"; \n }\n\n return messaging;\n }\n\n /**\n * Builds the user's time zone using the user's phone number country code\n * @param {*} user The user object retrieved from the User's collection\n * @returns The user's three-character timezone\n */\n var getTimeZone = function(user){\n // var countryCode = tractorOwner.phone? tractorOwner.phone.lastIndexOf(needle, 0) === 0\n var timeZone, phone = user.phone? user.phone: \"\";\n if (phone.lastIndexOf(CountryCodesTZMap.NG.Code, 0) === 0){\n timeZone = CountryCodesTZMap.NG.TZ;\n } else if (phone.lastIndexOf(CountryCodesTZMap.KE.Code, 0) === 0){\n timeZone = CountryCodesTZMap.KE.TZ;\n } else if (phone.lastIndexOf(CountryCodesTZMap.MW.Code, 0) === 0){\n timeZone = CountryCodesTZMap.MW.TZ;\n } else if (phone.lastIndexOf(CountryCodesTZMap.IN.Code, 0) === 0){\n timeZone = CountryCodesTZMap.IN.TZ;\n } else if (phone.lastIndexOf(CountryCodesTZMap.PK.Code, 0) === 0){\n timeZone = CountryCodesTZMap.PK.TZ;\n } else if (phone.lastIndexOf(CountryCodesTZMap.SN.Code, 0) === 0){\n timeZone = CountryCodesTZMap.SN.TZ;\n } else if (phone.lastIndexOf(CountryCodesTZMap.MZ.Code, 0) === 0){\n timeZone = CountryCodesTZMap.MZ.TZ;\n } else if (phone.lastIndexOf(CountryCodesTZMap.CI.Code, 0) === 0){\n timeZone = CountryCodesTZMap.CI.TZ;\n } else if (phone.lastIndexOf(CountryCodesTZMap.GH.Code, 0) === 0){\n timeZone = CountryCodesTZMap.GH.TZ;\n } else if (phone.lastIndexOf(CountryCodesTZMap.BD.Code, 0) === 0){\n timeZone = CountryCodesTZMap.BD.TZ;\n } else if (phone.lastIndexOf(CountryCodesTZMap.UG.Code, 0) === 0){\n timeZone = CountryCodesTZMap.UG.TZ;\n } else if (phone.lastIndexOf(CountryCodesTZMap.AO.Code, 0) === 0){\n timeZone = CountryCodesTZMap.AO.TZ;\n } else {\n timeZone = \"\";\n }\n\n return timeZone;\n }\n\n /**\n * Builds a csv list of tractor id's for which reports will be generated \n * @param {*} tractorList The array list of tractors retrieved from the TractorDetail collection\n * @returns A csv tractor list \n */\n var buildTractorsCSVList = function (tractorList){\n var separator = \"\", tractorIds = \"\";\n tractorList.forEach(function(tractor){\n tractorIds = tractorIds + separator + tractor.TractorID;\n separator = \",\";\n });\n\n return tractorIds;\n }\n\n /**\n * Generates a CSV report and sends the report to the users involved\n * @param {*} reportsBody The response body of hitting the CSV report endpoint\n * @param {*} userIds The user ids requiring the maintenance information \n * @param {*} tractorOwner The main tractor owner requiring the csv report\n * @param {*} dateRange The start time and end time of the report\n * @param {*} tractorListCSV The tractor id's in csv\n */\n var sendCSVReportToSubAccounts = function (reportsBody, userIds, tractorOwner, dateRange, tractorListCSV){\n var usersQuery = {\"_acl.creator\": {$in: userIds}};\n var countReportsToSend = 0;\n userCol.find(usersQuery, function(usersErr, userList){\n countReportsToSend = userList.length;\n log.info(\"Users found: \"+userList.length);\n userList.forEach(function(user){\n var reportsDateMessaging = getReportsDateMessaging(tractorOwner.reportInterval);\n var notification = buildNotification(tractorOwner, user, dateRange, reportsDateMessaging, tractorListCSV);\n push.sendMessage(user, notification);\n log.info(\"Push notification sent to \"+user.username +\", \"+notification.message);\n notificationCol.save(notification, function(notificationErr, notificationSaved){\n if (tractorOwner._acl.creator != user._acl.creator){\n var emailMessage = \"Click the link below to download your automated tractor activity report.\\n\"+reportsBody.download_link;\n pushEmail.send(props.fromEmail, user.username, notification.title, emailMessage);\n log.info(\"Email sent to \"+user.username+\", \"+emailMessage);\n }\n \n countReportsToSend--;\n if (countReportsToSend <= 0){\n tractorOwnerCol.update({_id: tractorOwner._id}, {$set: {lastAutomatedReportTime: props.nowV2}}, {upsert: false}, function(tractorOwnerUpdateErr, tractorOwnersUpdated){\n counter--;\n canFinish();\n });\n }\n })\n });\n });\n }\n\n /**\n * Builds a notification object to be sent to the user \n * \n * @param {*} tractorOwner The main tractor owner requiring the CSV report\n * @param {*} user The user (main or sub) to receive the notification\n * @param {*} dateRange The date range (start time or end time) separated using pipe characters\n * @param {*} reportsDateMessaging The date-range messaging to be appended to the notification message\n * @param {*} tractorListCSV A list of tractor ids comma separated\n */\n var buildNotification = function (tractorOwner, user, dateRange, reportsDateMessaging, tractorListCSV){\n var message = \"Your automated tractor activity reports for \"+reportsDateMessaging+\" has been sent to \"+user.username;\n var notification = {\n _acl: user._acl,\n message: message,\n userId: user._acl.creator,\n read: false,\n type: \"alert\",\n title: \"Automated Tractor Reports\",\n action: \"automated_tractor_reports\",\n orgID: user.orgIDs\n }\n \n notification = modules.kinvey.entity(notification);\n var extras = JSON.parse(JSON.stringify(notification));\n extras.tractorIDs = \"[\"+tractorListCSV+\"]\";\n notification.extras = JSON.stringify(extras);\n notification.id = notification._id;\n return notification; \n }\n\n //An object mapping of country codes and timezone to countries\n var CountryCodesTZMap = {\n NG: {\n Code: \"+234\",\n TZ: \"WAT\"\n },\n KE: {\n Code: \"+254\",\n TZ: \"EAT\"\n },\n MW: {\n Code: \"+265\",\n TZ: \"CAT\"\n },\n IN: {\n Code: \"+91\",\n TZ: \"IST\"\n },\n PK: {\n Code: \"+92\",\n TZ: \"PST\"\n },\n SN: {\n Code: \"+221\",\n TZ: \"GMT\"\n },\n MZ: {\n Code: \"+258\",\n TZ: \"GMT\"\n },\n CI: {\n Code: \"+225\",\n TZ: \"GMT\"\n },\n GH: {\n Code: \"+233\",\n TZ: \"GMT\"\n },\n BD: {\n Code: \"+880\",\n TZ: \"BST\"\n },\n UG: {\n Code: \"+256\",\n TZ: \"EAT\"\n },\n AO: {\n Code: \"+244\",\n TZ: \"WAT\"\n }\n }\n}" }, "TractorWorkingOvertimeAlert" : { "code" : "/**\n * Sends a push/email notification to the tractor owner whose tractors \n * are working overtime\n * Created by Abdulmajid on 20th August 2019, Updated: 9th March 2020\n * @param {*} request \n * @param {*} response \n * @param {*} modules \n */\n\nfunction onRequest(request, response, modules) {\n var tractorOwnerCol = modules.collectionAccess.collection(\"TractorOwner\")\n var userCol = modules.collectionAccess.collection(\"user\");\n var tractorDetailCol = modules.collectionAccess.collection(\"TractorDetail\");\n var userAccountsCol = modules.collectionAccess.collection(\"UserAccounts\");\n var notificationCol = modules.collectionAccess.collection(\"Notification\");\n\n var pushEmail = modules.email;\n var push = modules.push;\n var counter = 0;\n var log = modules.logger;\n var moment = modules.moment;\n\n var debugProps = {\n today: moment.utc().format(\"YYYY-MM-DD\"),\n thirtyMinutesAgo: moment.utc().subtract(30, \"minute\").format(\"YYYY-MM-DD HH:mm:ss\"),\n oneMinuteAgo: moment.utc().subtract(1, \"minute\").format(\"YYYY-MM-DD HH:mm:ss\"),\n fromEmail: \"Hello Tractor <support@hellotractor.com>\",\n nowISO: moment.utc().toISOString(),\n oneHourAgoISO: moment.utc().subtract(1, \"hours\").toISOString(),\n now: moment.utc().format(\"YYYY-MM-DD\")\n }\n\n var releaseProps = {\n today: moment.utc().format(\"YYYY-MM-DD\"),\n thirtyMinutesAgo: moment.utc().subtract(30, \"minute\").format(\"YYYY-MM-DD HH:mm:ss\"),\n oneMinuteAgo: moment.utc().subtract(1, \"minute\").format(\"YYYY-MM-DD HH:mm:ss\"),\n fromEmail: \"Hello Tractor <support@hellotractor.com>\",\n nowISO: moment.utc().toISOString(),\n oneHourAgoISO: moment.utc().subtract(1, \"hours\").toISOString(),\n now: moment.utc().format(\"YYYY-MM-DD\") \n }\n\n var props = releaseProps;\n\n log.info(\"Today: \"+props.nowISO);\n log.info(\"One Hour Ago: \"+props.oneHourAgoISO);\n log.info(\"One minute ago: \"+props.oneMinuteAgo);\n\n //Finds tractor owners with working hours notification enabled\n var tractorDetailQuery = \n {\n $and: [\n {LastActiveTime: {$gte: props.thirtyMinutesAgo}},\n {UpdatedAt: {$gte: props.oneMinuteAgo}},\n {$or: [{LastWorkingHourNotificationTime: {$lte: props.oneHourAgoISO}}, {LastWorkingHourNotificationTime: {$exists: false}}]}\n ]\n }; \n\n //Find tractors recently updated and working beyond working hours\n tractorDetailCol.find(tractorDetailQuery, function(tractorDetailErr, tractorDetailList){\n if (tractorDetailList && tractorDetailList.length > 0){\n //Create a map of creator id to tractors of that user\n log.info(\"Tractors found: \"+tractorDetailList.length);\n var creatorIdTractorDetailListMap = tractorDetailList.reduce(function(acc, tractorDetail, index){\n if (!acc[tractorDetail._acl.creator]) acc[tractorDetail._acl.creator] = [];\n acc[tractorDetail._acl.creator].push(tractorDetail);\n return acc;\n }, {});\n\n log.info(\"Creator ID Tractor List Map: \"+JSON.stringify(creatorIdTractorDetailListMap));\n //Find corresponding tractor owners willing to accept working hours notifications\n var tractorOwnerQuery = {workingHoursNotifications: true, '_acl.creator': {$in: Object.keys(creatorIdTractorDetailListMap)}};\n tractorOwnerCol.find(tractorOwnerQuery, function(tractorOwnerListErr, tractorOwnerList){\n if (tractorOwnerList && tractorOwnerList.length > 0){\n findUsersAndSendNotification(tractorOwnerList, creatorIdTractorDetailListMap);\n } else {\n log.info(\"Corresponding tractor owners were not found\");\n response.complete();\n }\n });\n } else {\n log.info(\"No tractor meeting the query criteria found to be recently updated\");\n response.complete();\n }\n });\n\n var findUsersAndSendNotification = function (tractorOwnerList, creatorIdTractorDetailListMap){\n log.info(\"Tractor owners found: \"+tractorOwnerList.length);\n var filteredTractorOwnerList = [];\n tractorOwnerList.forEach(function(tractorOwner){\n var startTime = props.today +\" \"+tractorOwner.startWorkingTime+\":00\";\n var endTime = props.today + \" \"+tractorOwner.endWorkingTime+\":00\";\n var tractorsForOwner = creatorIdTractorDetailListMap[tractorOwner._acl.creator];\n var filteredTractorsForOwner = tractorsForOwner.filter(function(tractor, index){\n return (tractor.LastActiveTime < startTime || tractor.LastActiveTime > endTime);\n })\n\n if (filteredTractorsForOwner.length < 1){\n delete creatorIdTractorDetailListMap[tractorOwner._acl.creator];\n } else {\n creatorIdTractorDetailListMap[tractorOwner._acl.creator] = filteredTractorsForOwner;\n filteredTractorOwnerList.push(tractorOwner);\n }\n\n });\n\n log.info(\"Filtered tractor owner list: \"+JSON.stringify(filteredTractorOwnerList));\n log.info(\"Filtered Creator ID Tractor Detail List Map: \"+JSON.stringify(creatorIdTractorDetailListMap));\n\n if (filteredTractorOwnerList && filteredTractorOwnerList.length){\n counter = filteredTractorOwnerList.length;\n filteredTractorOwnerList.forEach(function(tractorOwner){\n var tractorDetailList = creatorIdTractorDetailListMap[tractorOwner._acl.creator];\n var tractorNamesTractorID = formatTractorNamesTractorID(tractorDetailList);\n userAccountsCol.find({\"_acl.creator\": tractorOwner._acl.creator}, function(userAccountErr, userAccountList){\n var userIds = [];\n if (userAccountList && userAccountList.length > 0){\n userIds = userAccountList.map(function(userAccount){\n return userAccount.accountHolderId;\n });\n }\n\n userIds.push(tractorOwner._acl.creator);\n\n userCol.find({\"_acl.creator\": {$in: userIds}}, function(userErr, users){\n if (users && users.length > 0){\n var countUsers = users.length;\n users.forEach(function(user){\n var notification = buildNotification(user, tractorDetailList, tractorNamesTractorID);\n push.sendMessage(user, JSON.stringify(notification), function(pushNotificationErr, pushNotificationResult){\n log.info(\"Push notification sent to \"+user.username +\", \"+notification.message);\n pushEmail.send(props.fromEmail, user.username, notification.title, notification.message);\n log.info(\"Email sent to \"+user.username+\", \"+notification.message);\n \n //Save the working hours notification in Notification collection\n notificationCol.save(notification, function(notificationErr, notificationSaved){\n countUsers--; \n if (countUsers <= 0) updateTractorDetail(tractorNamesTractorID, notification, tractorOwner);\n });\n });\n });\n } else {\n log.info(\"Push notification not sent to \"+tractorOwner.username+\", user does not exist\");\n counter--;\n canFinish();\n }\n });\n });\n })\n } else {\n log.info(\"None of the tractor owners have tractors working overtime\");\n canFinish();\n }\n }\n\n var canFinish = function (){\n if (counter <= 0){\n response.complete();\n }\n }\n\n var updateTractorDetail = function(tractorNamesTractorID, notification, tractorOwner){\n tractorDetailCol.update(\n {\"TractorID\": {$in: tractorNamesTractorID.TractorIDsArr}},\n {$set: {LastWorkingHourNotificationTime: props.nowISO, '_kmd.lmt': new Date()}}, \n {upsert: false, multi: true},\n function(tractorOwnerUpdateErr, tractorOwnerUpdate){\n log.info(\"Done updating tractor owner collection for \"+tractorOwner.username);\n counter--;\n canFinish();\n });\n }\n}\n\nfunction buildNotification(user, tractorDetailList, tractorNamesTractorID){\n var message = tractorDetailList.length > 1? (\"We noticed that the following tractors were working overtime: \"+tractorNamesTractorID.TractorNamesCSV): \"We noticed that \"+tractorNamesTractorID.TractorNamesCSV+\" was working overtime\";\n var notification = {\n _acl: user._acl,\n message: message,\n userId: user._acl.creator,\n read: false,\n type: \"alert\",\n title: tractorDetailList.length > 1? \"Tractors Working Overtime\": \"Tractor Working Overtime\",\n action: \"tractor_working_overtime\",\n tractorId: tractorDetailList[0].TractorID,\n tractorName: tractorDetailList[0].TractorName,\n data: JSON.stringify(tractorNamesTractorID.filteredList),\n orgID: user.orgIDs\n }\n\n notification = modules.kinvey.entity(notification);\n var extras = JSON.parse(JSON.stringify(notification));\n delete extras[\"data\"];\n notification.extras = JSON.stringify(extras);\n notification.id = notification._id;\n return notification;\n}\n\nfunction formatTractorNamesTractorID (tractorDetailList){\n var tractorsCSV = \"\";\n var separator = \"\";\n var tractorIds = [];\n var filteredList = [];\n tractorDetailList.forEach(function(tractor){\n tractorsCSV += separator + tractor.TractorName + \" (\"+tractor.TractorID + \": \"+tractor.LastActiveTime +\" UTC)\";\n separator = \", \";\n tractorIds.push(tractor.TractorID);\n filteredList.push({TractorID: tractor.TractorID, TractorName: tractor.TractorName, LastActiveTime: tractor.LastActiveTime})\n });\n\n return {TractorNamesCSV: tractorsCSV, TractorIDsArr: tractorIds, filteredList: filteredList};\n}" }, "_UpdateTractorOwnerOrgId" : { "code" : "function onRequest(request, response, modules) {\n var TractorOwnerCol = modules.collectionAccess.collection(\"TractorOwner\");\n var UserCol = modules.collectionAccess.collection(\"user\");\n var log = modules.logger;\n var userCount = 0;\n \n log.info(\"Init\");\n \n UserCol.find({user_type: {$exists: false}}, function(userErr, userList) {\n if (userList) {\n log.info(\"User collection \" + userList.length);\n userList.forEach(function(user) {\n TractorOwnerCol.findOne({\"username\": user.username}, function(tractorOwnerErr, tractorOwner) {\n userCount++;\n if (tractorOwner){\n TractorOwnerCol.update({username: tractorOwner.username}, {$set: {orgID: user.orgIDs}}, {upsert: false, multi: false}, function(updateTractorOwnerErr, tractorOwnerUpdate){\n log.info(\"Tractor owner updated: \"+ tractorOwner.username);\n if (userCount >= userList.length) {\n log.info(\"Completed: \" + \"User Account: \"+userCount); \n log.info(JSON.stringify(tractorOwner));\n response.complete();\n }\n });\n } else {\n if (userCount >= userList.length){\n log.info(\"Completed: \" + \"User Account: \"+userCount); \n log.info(JSON.stringify(tractorOwner));\n response.complete();\n }\n }\n });\n });\n } else {\n log.info(\"Query failed : \" + userErr);\n response.complete();\n }\n });\n }\n " }, "_ProperlyFormatOrgIDsInUserCollection" : { "code" : "function onRequest(request, response, modules) {\n var userCol = modules.collectionAccess.collection(\"user\");\n var countUsers = 0;\n var totalUsers = 0;\n\n userCol.find({}, function(userErr, users){\n if (users){\n totalUsers = users.length;\n\n users.forEach(function(user){\n if (user.orgIDs){\n var orgId = String(user.orgIDs);\n userCol.update({_id: user._id}, {$set: {orgIDs: orgId}}, {upsert: false, multi: false}, function(userUpdatedErr, userUpdated){\n countUsers++;\n finish();\n });\n } else {\n countUsers++\n finish();\n }\n });\n } else {\n modules.logger.info(\"Users not found\");\n finish();\n }\n });\n \n var finish = function(){\n if (countUsers >= totalUsers){\n modules.logger.info(\"Users retrieved: \"+totalUsers);\n response.complete();\n } \n }\n \n// response.complete();\n}" }, "_UpdateStatusOfTractorsForThoseAssignedOperators" : { "code" : "function onRequest(request, response, modules) {\n var tractorDetailCol = modules.collectionAccess.collection(\"TractorDetail\");\n var now = modules.moment.utc().format(\"YYYY-MM-DD HH:mm:ss\") \n var log = modules.logger;\n var countTractors = 0;\n var countTractorsUpdated = 0;\n var tractorsUpdatedArr = [];\n tractorDetailCol.find({ Status: 0 }, function (tractorDetailErr, tractorDetailList) {\n countTractors = tractorDetailList.length;\n tractorDetailList.forEach(function (tractor) {\n var operatorId = tractor.OperatorID;\n if (operatorId && operatorId > 0) {\n tractorDetailCol.update({ _id: tractor._id }, {$set: {Status: 1, UpdatedAt: now}}, {upsert: false, multi: false}, function (tractorUpdateErr, tractorUpdated) {\n countTractors--;\n countTractorsUpdated++;\n tractorsUpdatedArr.push(tractor.TractorID);\n finish();\n });\n } else {\n countTractors--;\n finish();\n }\n });\n });\n\n var finish = function () {\n if (countTractors <= 0) {\n log.info(\"Done: \"+countTractorsUpdated);\n log.info(JSON.stringify(tractorsUpdatedArr));\n response.complete();\n }\n }\n\n \n\n // var tractorStatusUpdated = [\n // 501545,\n // 500233,\n // 501101,\n // 501754,\n // 501601,\n // 500236,\n // 500457,\n // 500246,\n // 500690,\n // 501554,\n // 501556,\n // 500560,\n // 501749,\n // 500247,\n // 500561,\n // 501562,\n // 501301,\n // 500821,\n // 502142,\n // 501788\n // ]\n\n // log.info(\"Now: \"+now);\n\n // tractorDetailCol.update({TractorID: {$in: tractorStatusUpdated}}, {$set: {UpdatedAt: now}}, {upsert: false, multi: true}, function(tractorsUpdatedErr, tractorsUpdatedData){\n // log.info(\"Done: \"+tractorsUpdatedData+\", Err: \"+tractorsUpdatedErr);\n // response.complete();\n // });\n}" }, "UpdateTractorGeofenceV2" : { "code" : " /**\n * Updates the geofence information of an array of tractors for the tractor ids passed in the request body.\n * Created by Abdulmajid/Sulaiman on 26th September 2019\n * @param request \n * - The http request containing tractorIds, geofence latitude,\n * - geofence longitude, updated at, need to send geofence notification, \n * - geofence created, and was in area.\n * @param response\n * - The http response\n * @param modules \n * - The javascript modules\n */\n\nfunction onRequest(request, response, modules) {\n var log = modules.logger;\n var tractorIds = request.body.tractorIds;\n var geofenceLatitude = request.body.latitude;\n var geofenceLongitude = request.body.longitude;\n var updatedAt = request.body.updatedAt;\n var needToSendGeofenceNotification = request.body.needToSendGeofenceNotification;\n var geofenceCreated = request.body.geofenceCreated;\n var wasInArea = request.body.wasInArea;\n var countNotificationsSent = 0;\n \n if (!tractorIds){\n return response.error(400);\n }\n \n log.info(JSON.stringify(request.body)); \n \n var tractorDetailCol = modules.collectionAccess.collection(\"TractorDetail\");\n var tractorDetailQuery = {TractorID: {$in: tractorIds}};\n\n var tractorDetailData = {\n Latitude: geofenceLatitude,\n Longitude: geofenceLongitude,\n NeedToSendGeofenceOutNotification: needToSendGeofenceNotification,\n WasInArea: wasInArea,\n LastGeofenceNotificationTime: '',\n UpdatedAt: updatedAt\n }\n \n tractorDetailCol.update(tractorDetailQuery, {$set: tractorDetailData}, {multi: true, upsert: false}, function(tractorDetailErrUpdated, tractorDetailUpdated){\n log.info(\"Finished updating geofence info for \"+tractorIds);\n if (geofenceCreated){\n tractorDetailCol.find(tractorDetailQuery, function(tractorDetailErr, tractorDetailList){\n if (tractorDetailList && !tractorDetailErr){\n countNotificationsSent = tractorDetailList.length;\n sendGeofenceNotification(tractorDetailList);\n } else {\n log.info(\"An error occured while trying find tractors with ids: \"+tractorIds);\n return response.error(400);\n }\n });\n } else {\n log.info(\"No need to send notification\");\n finish();\n }\n });\n\n var sendGeofenceNotification = function(tractorDetailList){\n tractorDetailList.forEach(function(tractor){\n c_sendGeoFenceNotification(tractor, 'geofenceCreated', function(err2) {\n countNotificationsSent--;\n finish();\n }); \n });\n }\n\n var finish = function (){\n if (countNotificationsSent <= 0){\n response.complete();\n }\n }\n}\n\n\n" }, "_UploadMaintenanceCSVSheet" : { "code" : "function onRequest(request, response, modules) {\n var data = [\n {\n \"maintenanceActivity\": \"fill\",\n \"maintenanceCheck\": \"Keep the tank completely filled after each day of work\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Water tank\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"check\",\n \"maintenanceCheck\": \"Check the lubricant oil level in the engine\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Engine oil\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \" clean and dust\",\n \"maintenanceCheck\": \"Clean the air filter dust exhaust valve\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Exhaust valve\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Drain\",\n \"maintenanceCheck\": \"Drain the decenter pre-filter\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Filter\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Clean\",\n \"maintenanceCheck\": \"Clean the radiator mask and vanes\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Radiator\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the tightness of the fuel and cooling system air filter clamps\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Air filter\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Replace the engine lubricant oil\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Engine oil\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 250\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Replace the engine oil filter\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Engine oil filter\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 250\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Replace the fuel filter\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Fuel filter\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 250\n },\n {\n \"maintenanceActivity\": \"clean\",\n \"maintenanceCheck\": \"Clean fuel tank screen filter\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Tank screen filter\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 250\n },\n {\n \"maintenanceActivity\": \"check\",\n \"maintenanceCheck\": \"Check belt tension\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Belt tension\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 250\n },\n {\n \"maintenanceActivity\": \"check\",\n \"maintenanceCheck\": \"Check engine valve clearance\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Engine valve \",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"check\",\n \"maintenanceCheck\": \"Check the pressures, spray and integrity of the injector nozzles\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Injector nozzles \",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"check\",\n \"maintenanceCheck\": \"Check the turbo charger rotor slack\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Rotor slack\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"Drain and Clean\",\n \"maintenanceCheck\": \"Drain and clean engine cooling system\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Cooling system\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"Change\",\n \"maintenanceCheck\": \"Change engine coolant\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Engine coolant\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the slack of the water pump\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Water tank\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"Clean \",\n \"maintenanceCheck\": \"Check fuel tank\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Fuel tank\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Replace the main filtering element on the engine air filter\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Engine air filter\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Replace the safety filter element on the engine's air filter\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Engine air filter\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the free play of the clutch pedal\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Clutch pedal\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Lubricate \",\n \"maintenanceCheck\": \"Lubricate the journal felt and the dual clutch bearing \",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Clutch bearing \",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 250\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the operation of the clutch and drive system\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Clutch and Drive system\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"Clean \",\n \"maintenanceCheck\": \"Clean the radiator mask and vanes\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Radiator mask\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the tightness of the wheel nuts\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Wheel nuts\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Check \",\n \"maintenanceCheck\": \"Check the tire Pressure\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Tire \",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the level of lubricant oil in the gearbox, final drive and hydroulics\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Gearbox\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 250\n },\n {\n \"maintenanceActivity\": \"Lubricate \",\n \"maintenanceCheck\": \"Lubricate rear axle bearing\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Rear axle\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 250\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the protective cover of the group and gearshift lever\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Gearsift lever\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 250\n },\n {\n \"maintenanceActivity\": \"Clean\",\n \"maintenanceCheck\": \"Clean the gearbox breather\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Gearbox\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 250\n },\n {\n \"maintenanceActivity\": \"Check and Replace\",\n \"maintenanceCheck\": \"Check the breather cap of the hydroulic system\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Breather cap\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 500\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Replace the Hydroulic system pressure\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Hydroulic system\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 500\n },\n {\n \"maintenanceActivity\": \"Clean\",\n \"maintenanceCheck\": \"Clean the hydroulic system suction filter\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Hydroulic system\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 500\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the pressure of the 3-point hyroulic system\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Gearbox\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 500\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Replace the oil and filter in the gearbox, final drive and hydroulic system\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Hydroulic system\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Hydroulic system oil\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Hydroulic system\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check yhe operation of the gearbox and splitter/creeper\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Gearbox\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"Clean\",\n \"maintenanceCheck\": \"Clean the gearbox breather\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Gearbox\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the operation of the hydroulic sensitivity system\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Hyroulic sensitivity system\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the free play of the service brake\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Brake\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the free play of the park brake\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Brake\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the level of the brake fluid\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Brake\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the operation of the service and brake system\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Brake\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"Replace \",\n \"maintenanceCheck\": \"Replace the brake fluid\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Brake\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Lubricate \",\n \"maintenanceCheck\": \"Lubricate the front axle bearing(4 x 4) and the wheel hub( 4 x 2 )\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Front axle and Wheel hub\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the tightness of the wheel nuts\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Wheel nuts\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the tire \",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Tire \",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Lubricate \",\n \"maintenanceCheck\": \"Lubricate the front axle journals\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Axle journals\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 250\n },\n {\n \"maintenanceActivity\": \"Clean\",\n \"maintenanceCheck\": \"Clean the front axle breather\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Axle breather\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 250\n },\n {\n \"maintenanceActivity\": \"Check \",\n \"maintenanceCheck\": \"Check the level of lubricant oil in the differential and front-wheel drive axle gear( 4x4 )\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Axle gear\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 250\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Replace the lubricant oil in the front axle wheel hubs \",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Front axle\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 250\n },\n {\n \"maintenanceActivity\": \"Check \",\n \"maintenanceCheck\": \"Check the operation of the throttle system\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Throttle system\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 500\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Replace the lubricant oil in the front axle differential\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Front axle \",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the slack of the front wheel hub bearing (4x2)\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Front wheel\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the operation of the front axle/steering system\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Axle/ Stearing system\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the operation of the streering system\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Steering system\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"Check \",\n \"maintenanceCheck\": \"Check the wheel toe-in (4x2 or 4x4 )\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Wheel\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"Check \",\n \"maintenanceCheck\": \"Check the general condition of the steering rod terminals \",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Steering rods\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"Check \",\n \"maintenanceCheck\": \"Check the conditions of the cardian shaft\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Cardian shaft\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"Clean\",\n \"maintenanceCheck\": \"Clean the air conditioner condenser\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Air Conditioner condenser\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the condition and tension of the air compressor and alternator\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Air Compressor and alternator\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 250\n },\n {\n \"maintenanceActivity\": \"Clean\",\n \"maintenanceCheck\": \"Clean the cap air filter\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Cap air filter\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 250\n },\n {\n \"maintenanceActivity\": \"Wash\",\n \"maintenanceCheck\": \"Wash the cap air reciculation filter\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Air reciculation filter\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 250\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Replace the cap reciculation filter and air filter\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Cap reciculation filter and air filter\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1000\n },\n {\n \"maintenanceActivity\": \"Remove\",\n \"maintenanceCheck\": \"Remove the roof cover and clean the box and the entire air conditioning system\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Air conditioning system\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Proper operation and adjustment of all work and auxiliary lights\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Auxiliary lights\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the indicator lights, audible alarms and instruments for proper operation\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Indicator lights\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Operation of all start-up safety switches\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Start-up switches \",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the electronic systems for proper operation\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Electronic systems\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the electronic components for their proper operation\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Electronic componenet\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the tightness of the battery's cables and mounting . In addition to Check the battery's condition, coatthe terminals with petroleum jelly \",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Battery\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 250\n },\n {\n \"maintenanceActivity\": \"Check \",\n \"maintenanceCheck\": \"Load conditions on the alternator \",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Alternator\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 500\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the operation of the starter motor\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Starter motor\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 500\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the operation and general condition of the electrical system\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Electrical system\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 500\n },\n {\n \"maintenanceActivity\": \"Check \",\n \"maintenanceCheck\": \"Check the condition of wiring hernesses and their fasteners\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"fasteners\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 500\n },\n {\n \"maintenanceActivity\": \"Lubricate \",\n \"maintenanceCheck\": \"Lubricate the grease fittings (except the front anxle journals and the rear axle bearing )\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Axle bearing \",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check the safety guards are in place and have legible adhesives \",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Safety guards are \",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Engage\",\n \"maintenanceCheck\": \"Enagege the hydroulic systems and the PTO to check their functionality\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"Hydroulic system\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Check tightening torgue of the ROPS bolts\",\n \"tractorModelId\": 57,\n \"maintenanceComponent\": \"ROPS bolts\",\n \"tractorModel\": \"Valtra BL88\",\n \"engineHours\": 500\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"General tractor inspection\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Tractor \",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Engine oil level\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Engine oil\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Coolant\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Coolant\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Fuel level\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Fuel\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Lights\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Lights\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Roll over protection frame\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Protection frame\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Seat belt\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Seat belt\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Transmission oil level\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Oil level\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Grease\",\n \"maintenanceCheck\": \"Grease the rear axle\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Rear axle\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Grease\",\n \"maintenanceCheck\": \"Greasing the pivot system of the 2WD front axle\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Front axle\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Grease\",\n \"maintenanceCheck\": \"Greasing the 4WD front axle\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Front axle \",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Brake reservoir oil level \",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Reservoir oil\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Battery\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Battery\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Grease\",\n \"maintenanceCheck\": \"Grease the 3-point linkage\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"3-point linkage\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Wheels and tyres\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Wheel and tyres\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Braking distance\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Brake\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 100\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Belt tension\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Belt tension\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 100\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Engine oil\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Engine oil\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 100\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Change the engine oil filter cartridge\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Filter catridge\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 100\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Cooler\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Cooler\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 100\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Fuel filter\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Fuel filter\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 100\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Transmission oil filter\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Oil filter\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 100\n },\n {\n \"maintenanceActivity\": \"Clean\",\n \"maintenanceCheck\": \"Parking brake lever\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Brake\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 100\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Oil pipe - Hydrostatic steering\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Hydrostatic steering\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 100\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Braking distance\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Braking\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 300\n },\n {\n \"maintenanceActivity\": \"Clean\",\n \"maintenanceCheck\": \"Cooler\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Cooler\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 300\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Parking brake lever\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Brake\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 300\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Engine oil\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Engine oil\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 300\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Engine oil filter cartridge\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Filter catridge\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 300\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Front axle/final drive unit level\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Front axle\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 300\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Mechanical clutch control\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Clutch control\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 300\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Oil pipes - Hydrostatic steering\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Hydrostatic steering\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 300\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Engine drive belt tension\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Belt \",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 600\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Fuel filter\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Fuel filter\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 600\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Transmission oil filter\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Oil filter\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 600\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Differential lock system\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Lock system\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 600\n },\n {\n \"maintenanceActivity\": \"Grease\",\n \"maintenanceCheck\": \"Front wheel hub bearings\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Front wheel\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 600\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Braking system with Safety Brakes valve\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Brakes\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 600\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Air filter catridge and safety catridge \",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Safety catridge\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Drain water\",\n \"maintenanceCheck\": \"Bleeding air and water from the filters and fuel system\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Fuel system\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Coolant and flushing the circuit\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Coolant \",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Transmission oil\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Transmission oil\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Replace\",\n \"maintenanceCheck\": \"Front axle/final drive units oil level\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Front axle\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Clean engine air filter\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Air flter\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Clean\",\n \"maintenanceCheck\": \"Front and rear hydroulic brake circuits\",\n \"tractorModelId\": 46,\n \"maintenanceComponent\": \"Brake circuits\",\n \"tractorModel\": \"Same Tiger 80.4E\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Engine oil level\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Engine oil\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Coolant \",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Coolant\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Fuel level\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Fuel\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Lights\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Lights\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 10\n },\n {\n \"maintenanceActivity\": \"Grease\",\n \"maintenanceCheck\": \"Rear axle\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Rear axle\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Grease\",\n \"maintenanceCheck\": \"4WD front axle\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Front axle\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Clutch and brake fluid reservoir level\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Fluid reservoir\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Battery\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Battery\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Grease\",\n \"maintenanceCheck\": \"Rear 3-point linkage\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Rear 3-point linkage\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Wheels and tyres\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Wheels and tyres\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 50\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Braking distance\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Brakes\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 100\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Engine drive belt/s tension\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Engine drive\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 100\n },\n {\n \"maintenanceActivity\": \"Renew\",\n \"maintenanceCheck\": \"Engine oil\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Engine oil\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 100\n },\n {\n \"maintenanceActivity\": \"Renew\",\n \"maintenanceCheck\": \"Engine oil filter cartridges\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Filter catridge\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 100\n },\n {\n \"maintenanceActivity\": \"Clean\",\n \"maintenanceCheck\": \"Engine coolant radiator\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Radiator\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 100\n },\n {\n \"maintenanceActivity\": \"Renew\",\n \"maintenanceCheck\": \"Fuel filter\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Fuel filter\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 100\n },\n {\n \"maintenanceActivity\": \"Renew\",\n \"maintenanceCheck\": \"Fuel pre-filter\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Filter\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 100\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Parking brake lever\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Brake\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 100\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Screen wash system\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Wash\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 100\n },\n {\n \"maintenanceActivity\": \"Clean\",\n \"maintenanceCheck\": \"Air conditioning system filters\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Air conditioning system\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 100\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Oil lines\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Oil\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 100\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Braking distance\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Brake\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 300\n },\n {\n \"maintenanceActivity\": \"Renew\",\n \"maintenanceCheck\": \"Engine oil\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Engine oil\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 300\n },\n {\n \"maintenanceActivity\": \"Renew\",\n \"maintenanceCheck\": \"Engine oil filter cattridges\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Filter catridge\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 300\n },\n {\n \"maintenanceActivity\": \"Clean\",\n \"maintenanceCheck\": \"Engine coolant radiator\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Coolant radiator\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 300\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Parking brake lever\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Brake lever\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 300\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Front axle/final drives oil level\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Front axle\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 300\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Screen wash system\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Screen wash system\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 300\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Oil lines\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Oil\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 300\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Engine drive belt/s tension\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Engine drive\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 600\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Engine valve clearances and fuel injectors\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Engine valve \",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 600\n },\n {\n \"maintenanceActivity\": \"Renew\",\n \"maintenanceCheck\": \"Fuel filter\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Fuel filter\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 600\n },\n {\n \"maintenanceActivity\": \"Renew\",\n \"maintenanceCheck\": \"Transmission oil filters\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Oil filter\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 600\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Differentials lock system\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Lock sytsem\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 600\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Injection pump\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Injection pump\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Renew \",\n \"maintenanceCheck\": \"Air filter cartridge\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Filter cattridge\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Renew\",\n \"maintenanceCheck\": \"Fuel pre-filter\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"fuel Filter \",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Starter motor\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Starter\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Clean\",\n \"maintenanceCheck\": \"Rear brakes hydraulic circuit\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Hydraulic circuit\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Clean\",\n \"maintenanceCheck\": \"Air conditioning system filters\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"System filters\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Cab heating system\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Heating system\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Cab air conditioning system\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Conditioning system\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Clean\",\n \"maintenanceCheck\": \"Hydraulic clutch circuit\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Clutch circuit\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Renew \",\n \"maintenanceCheck\": \"Coolant level\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Coolant\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Renew \",\n \"maintenanceCheck\": \"Transmission oil\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Transmission oil\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Renew \",\n \"maintenanceCheck\": \"Front axle/final drives oil\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Front axle\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Clean engine air cleaner\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Engine cleaner\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Renew \",\n \"maintenanceCheck\": \"Air filter internal safety cartridge or after the main catridge has been cleaned 3 times\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Internal safety catridge\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Bleeding the fuel system\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Fuel system\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Bleeding the fuel prefilter( Specific filter for cold climates)\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Fuel profilers\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 1200\n },\n {\n \"maintenanceActivity\": \"Check\",\n \"maintenanceCheck\": \"Bleeding the hydroulic circuit of the hydrostatic steering system\",\n \"tractorModelId\": 45,\n \"maintenanceComponent\": \"Hydroulic circuit\",\n \"tractorModel\": \"Same Laser 130\",\n \"engineHours\": 1200\n }\n ];\n\n var maintenanceRepoCol = modules.collectionAccess.collection(\"MaintenanceRepo\");\n var today = modules.moment.utc().format(\"YYYY-MM-DD HH:mm:ss\");\n\n data.forEach(function(maintenance){\n maintenance.createdAt = today;\n maintenance.updatedAt = today;\n maintenanceRepoCol.save(modules.kinvey.entity(maintenance), function(saveErr, savedMaintenance){\n count++;\n finish();\n });\n });\n \n var count = 0;\n var finish = function(){\n if (count >= data.length){\n modules.logger.info(\"Done: \"+count);\n response.complete();\n }\n }\n}" }, "updateTractorDetailOnUpdateFromQueue" : { "code" : "function onRequest(request, response, modules) {\n response.complete();\n}" }, "TestConsumer" : { "code" : "function onRequest(request, response, modules) {\n var bookingsCol = modules.collectionAccess.collection(\"ServiceBookings\");\n var query = {orgID:\"6022\"};\n var updateDoc = {$set: {\n \"orgID\": \"111\"\n }};\n var options = {upsert: false, multi: true};\n bookingsCol.update(query, updateDoc, options, function(updateErr, updateDoc){\n modules.logger.info(\"Bookings updated: \"+JSON.stringify(updateDoc)+\", \"+JSON.stringify(updateErr));\n response.complete();\n });\n}" }, "PushRecentBookings" : { "code" : "//Sends a CSV report of service bookings every 5 minutes to emails\n//Created on 21/10/2019 by Abdulmajid\nfunction onRequest(request, response, modules) {\n var fiveMinutesAgo = modules.moment.utc().subtract(5, \"minutes\").format('YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); //.format(\"YYYY-MM-DD\"); //.format(\"YYYY-MM-DD HH:mm:ss\")\n modules.logger.info(\"Five minutes ago: \"+fiveMinutesAgo);\n var email = modules.email;\n var kinvey = modules.kinvey;\n var cServiceBookings = modules.collectionAccess.collection(\"ServiceBookings\");\n var cEmails = modules.collectionAccess.collection(\"Emails\");\n\n //Constants\n var from = \"Hello Tractor Support <support@hellotractor.com>\";\n var to = \"abubakar@hellotractor.com, david@hellotractor.com\";\n var cc = \"deborah@hellotractor.com\";\n var bcc = \"apps2@hellotractor.com\";\n var replyTo = \"Hello Tractor App <apps2@hellotractor.com>\";\n var subject = \"New Bookings Report (5 Minutes Ago)\";\n var emailType = \"HTBookingCSVReport\";\n var userType = \"0\"; //Hello Tractor Admin\n var query = {\"_kmd.ect\": {$gte: fiveMinutesAgo}};\n\n cServiceBookings.find(query, function(\n err,\n serviceBookings\n ) {\n if (err || serviceBookings.length < 1) {\n modules.logger.info(\"No service bookings found: \"+err);\n response.complete();\n } else {\n modules.logger.info(\"Bookings found: \"+serviceBookings.length);\n var report = buildBookingsReport(serviceBookings);\n pushCSVBookingsReport(\n response,\n email,\n cEmails,\n kinvey,\n from,\n to,\n subject,\n report,\n replyTo,\n cc,\n bcc,\n emailType,\n userType\n );\n }\n });\n}\n\nfunction buildBookingsReport(serviceBookings) {\n //Extract headers\n var report = \"\";\n var comma = \",\";\n var headers = \"_id,creator,ect,Service Date,Booking Id,BookingAgentID,Tractor Paired To,\"+\n \"Operator ID,Booking Status,Cluster Id,Created At,Updated At,Distance To Destination,\"+\n \"Farm Location,Farmer Name,Farmer Phone,Gender,Hectares Serviced,Latitude,Longitude,Org Id,Primary Crop,Secondary Crop, BAName, BAPhone, Service Type\"+\"\\n\";\n\n \n\n report += headers;\n\n serviceBookings.forEach(function(booking){\n var bookingAgent = booking.bookingAgentData? JSON.parse(booking.bookingAgentData):\"\";\n var row = \n toString(booking._id) + comma + \n toString(booking._acl.creator) + comma +\n toString(booking._kmd.ect) + comma +\n toString(booking.serviceDate) + comma +\n toString(booking.bookingID) + comma +\n toString(booking.bookingAgentID) + comma + \n toString(booking.tractorPairedTo) + comma +\n toString(booking.OperatorID) + comma +\n bookingStatus(booking.bookingStatus) + comma +\n toString(booking.clusterID) + comma +\n toString(booking.createdAt) + comma +\n toString(booking.updatedAt) + comma +\n toString(booking.distanceToDestination) + comma +\n toString(booking.farmLocation) + comma +\n toString(booking.farmerName) + comma +\n toString(booking.farmerPhone) + comma +\n toString(booking.gender) + comma +\n toString(booking.hectaresServiced) + comma +\n toString(booking.latitude) + comma +\n toString(booking.longitude) + comma +\n toString(booking.orgID) + comma +\n toString(booking.primaryCrop) + comma +\n toString(booking.secondaryCrop) + comma +\n toString(bookingAgent?bookingAgent.name:\"\") + comma +\n toString(bookingAgent?bookingAgent.phone:\"\") + comma +\n getServiceName(booking.serviceType) + \"\\n\";\n report += row; \n });\n \n return report;\n}\n\nfunction toString(text){\n return JSON.stringify(text);\n}\n\n\n\n\n\nfunction getServiceName (serviceCode) {\n var service_name;\n switch (serviceCode) {\n case \"109\":\n service_name = 'Harrowing'\n break;\n case \"104\":\n service_name = 'Planting/Seeding'\n break;\n case \"105\":\n service_name = 'Irrigating'\n break;\n case \"102\":\n service_name = 'Ploughing'\n break;\n case \"101\":\n service_name = 'Tilling'\n break;\n case \"103\":\n service_name = 'Ridging'\n break;\n case \"107\":\n service_name = 'Trailing'\n break;\n case \"108\":\n service_name = 'Harvesting'\n break;\n case \"106\":\n service_name = 'Harvesting'\n break;\n case \"110\":\n service_name = 'Spreading'\n break;\n case \"112\":\n service_name = 'Sprayer'\n break;\n case \"113\":\n service_name = 'Bioagtive'\n break;\n case \"114\":\n service_name = 'Dozer'\n break;\n case \"115\":\n service_name = 'Mower'\n break;\n default:\n service_name = \"Service Code: \"+serviceCode;\n break;\n }\n return service_name;\n }\n\n\n\n\n\n\n\n//Sends the provided report to the user's email\nfunction pushCSVBookingsReport(\n response,\n email,\n cEmails,\n kinvey,\n from,\n to,\n subject,\n report,\n replyTo,\n cc,\n bcc,\n emailType,\n userType\n) {\n email.send(\n from, //from\n to, //to\n subject, //subject\n report, //text_body\n replyTo, //reply_to\n null, //html_body\n cc, //cc\n bcc, //bcc\n function(err, result) {\n if (err) {\n response.complete();\n } else {\n var mail = {\n _acl: kinvey.entity()._acl,\n _kmd: kinvey.entity()._kmd,\n from: from,\n message: report,\n to: to,\n cc: cc,\n bcc: bcc,\n emailType: emailType,\n userType: userType,\n reply_to: replyTo\n };\n\n cEmails.save(mail, function(err2) {\n// response.body = mail;\n response.complete();\n });\n }\n }\n );\n}\n\nfunction bookingStatus(status){\n if (status == 0){\n return \"New\";\n } else if (status == 1 || status == 2){\n return \"Paired\";\n } else if (status == 3){\n return \"Completed\"\n } else {\n return \"Unknown Status\";\n }\n}" }, "PushAdNotificationToCustomer" : { "code" : "function onRequest(request, response, modules) {\n var push = modules.push;\n var usersCol = modules.collectionAccess.collection(\"user\");\n var notificationCol = modules.collectionAccess.collection(\"Notification\");\n var pushModule = modules.push;\n var logger = modules.logger;\n var count = 0;\n \n var customers = [\"abedkithome@gmail.com\",\"aemservices95@gmail.com\",\"akinyikisia@gmail.com\",\"albertkiprotichmisoi@gmail.com\",\"andrewcheruiyot@gmail.com\",\"angelinechemutai72@gmail.com\",\"boscomulwa2018@gmail.com\",\"bwibopatrick@gmail.com\",\"Carolinengina97@gmail.com\",\"cetiang05@gmail.com\",\"charlesmakau@gmail.com\",\"charlesodhiambo36@gmail.com\",\"chepkwonykibitok@gmail.com\",\"ckavere@yahoo.com\",\"colcher2012@yahoo.com\",\"cooperativelessos@yahoo.com\",\"davidkayi004@gmail.com\",\"Davidkimeli45@gmail.com\",\"e.nyakeriga@gmail.com\",\"erastusadongo@gmail.com\",\"fdikir@gmail.com\",\"franciskihara0@gmail.com\",\"githaigajm16@gmail.com\",\"henry.emuye@rentco.co.ke\",\"hezngeno@yahoo.co.uk\",\"imbo.fred@gmail.com\",\"jakaluore@gmail.com\",\"james.wabala@gmail.com\",\"jeff.tirop@gmail.com\",\"jimmykemboi72@gmail.com\",\"johnkoech2009@gmail.com\",\"josemwangi2003@gmail.com\",\"juliuskibet29@yahoo.com\",\"juliussugut@yahoo.com\",\"kandyandrew98@gmail.com\",\"kenkipngorem@gmail.com\",\"kenmusomba@gmail.com\",\"kennedymk2015@gmail.com\",\"kennethsaruni@gmail.com\",\"kimagrovet@gmail.com\",\"kimanijohn608@gmail.com\",\"kimutaikigen123@gmail.com\",\"kimutaimeli@gmail.com\",\"kipsangjohn@gmail.com\",\"kiptelatele@gmail.com\",\"kiroreypius@gmail.com\",\"kjoshuamatata@yahoo.com\",\"knyakibwoga@gmail.com\",\"korirjonah37@gmail.com\",\"malanachola@gmail.com\",\"martinkyengo2016@gmail.com\",\"marymasaku@gmail.com\",\"mashsang74@gmail.com\",\"moonstone254@gmail.com\",\"moruma57@gmail.com\",\"mr.peterwanga@gmail.com\",\"mungaip19@gmail.com\",\"mutua60@gmail.com\",\"mutungimagdalene@gmail.com\",\"mutwotapaul@yahoo.com\",\"mwololo.nfcc@yahoo.com\",\"n.kosgei01@gmail.com\",\"ndetei@yahoo.com\",\"nicholaskiptoo64@gmail.com\",\"nundoroto@gmail.com\",\"nziliajoseph4@gmail.com\",\"nzomot@gmail.com\",\"okalmugan@gmail.com\",\"Okapu.law@gmail.com\",\"okisaimoffats@gmail.com\",\"omadirechosit@gmail.com\",\"pasilizarutto@gmail.com\",\"patricketyang21@gmail.com\",\"paulinakemey@gmail.com\",\"paulkemei8066@gmail.com\",\"petrorotich@yahoo.com\",\"philipmasai@gmail.com\",\"pkaranja22@gmail.com\",\"rugut49@gmail.com\",\"samuelkamiri1977@gmail.com\",\"samwelkiboor1970@gmail.com\",\"sawelink@yahoo.com\",\"shadrackyaloh@gmail.com\",\"silasimbayi2007@yahoo.co.uk\",\"silvestermunyao@gmail.com\",\"stanleykiptanui9@gmail.com\",\"taruskennedy52@gmail.com\",\"timskaru@agrimechafrica.co.ke\",\"titusgicheru@gmail.com\",\"tkeng2018@gmail.com\",\"trixnnoli@gmail.com\",\"waltersang@gmail.com\",\"wambuawaita1980@gmail.com\",\"waruibenson@gmail.com\",\"wemoadams1234@gmail.com\",\"wilfredketer@gmail.com\",\"wilfredkipkorir2@gmail.com\",\"yegoearnest@gmail.com\"];\n usersCol.find({username: {$in: customers}}, function (err, users){\n logger.info('Users found'+users.length);\n sendNotification(users);\n });\n \n function sendNotification(users){\n count = users.length;\n users.forEach(function(user){\n var notification = buildNotification(user);\n notificationCol.save(notification, function(err, notificationSaved){\n logger.info(\"Notification saved\");\n pushModule.sendMessage(user, JSON.stringify(notification), function(pushErr, pushResult){\n logger.info(\"Message sent\");\n count--;\n shouldFinish(count);\n });\n });\n });\n }\n\n function shouldFinish(count){\n if (count <= 0){\n response.complete();\n }\n }\n \n function buildNotification(user){\n var message = \"Hello \"+user.first_name+\", save up to KSh 202,100 when you purchase a John Deere 5075E MFWD Tractor from 18 - 29th Nov. 2019. Visit www.hellotractor.com to learn more or call +254 724 443 389\";\n var notification = {\n _acl: user._acl,\n message: message,\n userId: user._acl.creator,\n read: false,\n type: \"alert\",\n title: \"Black Friday\",\n action: \"ad\",\n orgID: user.orgIDs\n };\n\n return modules.kinvey.entity(notification);\n }\n }" }, "updateUserOrgIdByEmail" : { "code" : "function onRequest(request, response, modules) {\n\n const User = modules.collectionAccess.collection('user');\n const TractorOwner = modules.collectionAccess.collection('TractorOwner');\n const userEmail = request.body.email;\n const orgId = request.body.orgId;\n \n if(! userEmail || ! orgId ){\n return response.complete(422);\n }\n \n const stringOrgId = orgId.toString();\n modules.logger.info(\"The email is \" + userEmail + \" and the orgID is \" + orgId );\n // Update the user orgId \n User.update({email: userEmail}, {\"$set\":{orgIDs: stringOrgId}}, function(err, doc){\n if( err ){\n return response.complete(422);\n }\n \n // Update the user tractorOwner orgId\n TractorOwner.update({email: userEmail}, {\"$set\":{orgID: stringOrgId} }, function(err, doc){\n if( err ){\n \treturn response.complete(422);\n \t}\n response.body = {updated:true};\n return response.complete(200);\n })\n })\n \n}" }, "UpdateTractorsRealTimeLocation" : { "code" : "function onRequest(request, response, modules) {\n modules.logger.info('data posted, count is ' + request.body.count);\n response.complete();\n}" }, "getFuelDataByTractorId" : { "code" : "function onRequest(request, response, modules) {\n const tractorId = Number(request.body.tractorId);\n const day = request.body.day;\n const FuelHistory = modules.collectionAccess.collection('FuelHistory');\n \n FuelHistory.find({TractorID: tractorId, CreatedAt: {$gte: day}}, function(err, tractorFuelHistory){\n if( err ) return response.error();\n \n \t if( ! tractorFuelHistory.length || !tractorFuelHistory ){\n \t\tresponse.body = {error: \"can\\'t find tractor fuel history with the tractorId of \" + tractorId}\n \t\t\treturn response.complete(422);\n \t \t}\n \n if(tractorFuelHistory.length){\n const lastFuelEntry = tractorFuelHistory[tractorFuelHistory.length - 1];\n const firstFuelEntry = tractorFuelHistory[0]\n \tresponse.body = {\n \t\tfinal_fuel_litres: lastFuelEntry ? lastFuelEntry.FuelLitres : 0,\n \t\tinitial_fuel_litres: firstFuelEntry ? firstFuelEntry.FuelLitres: 0,\n \ttractor_id: tractorId\n \t};\n \t return response.complete();\n \n } else {\n response.body = {\n \tmessage: \"The provided tractorId has no fuel data history for the provided day\"\n \t};\n return response.complete(422);\n } \n \n });\n \n}" }, "TriggerPushNotification" : { "code" : "function onRequest(request, response, modules) {\n var userCol = modules.collectionAccess.collection('user');\n var userAccountsCol = modules.collectionAccess.collection('UserAccounts');\n var notificationCol = modules.collectionAccess.collection('Notification');\n var pushModule = modules.push;\n \n var userId = request.body.userId;\n var receipients = request.body.receipients;\n var orgId = request.body.orgId;\n var title = request.body.title;\n var message = request.body.message;\n var count = 0;\n\n var received = [];\n \n modules.logger.info(JSON.stringify(request.body));\n \n if (userId && receipients && orgId && title && message){\n modules.logger.info(\"User id, receipients, orgId, title and message exists\");\n userCol.findOne({\"_acl.creator\": userId}, function(userSenderErr, userSender){\n if (!userSender){\n response.body = {message: \"Failed to send push notification. Unauthorized user\"};\n response.error(\"Failed to send push notification. Unauthorized user request\");\n }\n \n modules.logger.info(\"Sender found: \"+userSender.username);\n userCol.find({\"username\": {$in: receipients}}, function(receipientErr, receipientList){\n if (!receipientList){\n response.body = \"Failed to send push notifications. No receipient found\";\n response.error(\"Failed to send push notifications. No receipient found\");\n }\n \n modules.logger.info(\"Receipients found: \"+receipientList.length);\n count = receipientList.length;\n receipientList.forEach(function(receipient){\n var notification = modules.kinvey.entity(buildNotification(userId, receipient._acl, message, title, orgId));\n notificationCol.save(notification, function(err, notificationSaved){\n modules.logger.info(\"Notification saved\");\n pushModule.sendMessage(receipient, JSON.stringify(notification), function(pushErr, pushResult){\n modules.logger.info(\"Message sent to: \"+receipient.username);\n received.push(receipient.username);\n count--;\n shouldFinish();\n });\n });\n \n });\n })\n }); \n } else {\n modules.logger.info(\"Some fields are missing\");\n response.error(\"Some fields are missing\");\n }\n \n var shouldFinish = function(){\n if (count <= 0){\n response.body = {status: 200, message: \"Message sent\", received: received}\n response.complete();\n }\n } \n \n var buildNotification = function(userId, acl, message, title, orgId) {\n return {\n _acl: acl, \n title: title,\n message: message,\n userId: userId,\n read: false,\n type: \"alert\",\n action: \"ad\",\n orgID: orgId \n }\n } \n }" }, "PopulateDemoData" : { "code" : "function onRequest(request, response, modules) {\n \n const TractorDetail = modules.collectionAccess.collection('TractorDetail');\n \n const getTractorDetail = function(count){\n \n var TractorID = 601570 + count;\n var TractorName = \"HTDEMO\" + count;\n return {\n \"ActiveTimeToday\": 16853,\n \"BookingRequests\": true,\n \"Characteristic\": \"102\",\n \"Country\": \"Kenya\",\n \"Currency\": \"Ksh\",\n \"DailyTractorUpdates\": false,\n \"Efficiency\": 0,\n \"EngineHours\": 79,\n \"FixedEngineHours\": 0,\n \"FixedOdometerReading\": 0,\n \"FuelLitres\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"HTDEMO\" +count,\n \"Heading\": 193,\n \"LastActiveTime\": \"2020-01-21 11:46:32\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"\",\n \"Longitude\": \"\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 1579172410038,\n \"PositionLatitude\": 0.298896,\n \"PositionLongitude\": 30.179938,\n \"Speed\": 0,\n \"Status\": 1,\n \"Street\": \"Muthangari\",\n \"TotalDistanceCovered\": 711,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Nairobi\",\n \"TractorID\": TractorID ,\n \"TractorModelID\": 19,\n \"TractorName\": TractorName,\n \"UpdatedAt\": \"2020-01-21 11:53:06\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"_acl\": {\n \"creator\": \"5e26e75b443e190015fd0bee\"\n },\n \"license_plate_number\": \"HT 472 NAI\",\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"FuelLevelVoltage\": 0,\n \"LastMaintenanceNotificationEngineHours\": 75\n }\n }\n \n const count = 21;\n var start = 1;\n \n while( start < count ){\n var tractorDetail = getTractorDetail(start);\n TractorDetail.save(tractorDetail, function(err, tractorDetail){\n if(!err){\n modules.logger.info('new tractor created with tractorID of ' + tractorDetail.TractorID);\n } \n })\n start++;\n if(start === count ){\n modules.logger.info('DONE');\n response.complete();\n }\n }\n \n \n}" }, "PopulateDemoBookings" : { "code" : "function onRequest(request, response, modules) {\n var Booking = modules.collectionAccess.collection('ServiceBookings');\n\t Booking.remove({bookingAgentID: \"1579600001000\"}, function(err, done){\n modules.logger.info('done');\n response.complete();\n })\n \n var getBooking = function(count){\n \n var bookingID = (1579619103763 + count) * 2 ;\n var clusterID = ( 1579619106135 + count ) * 2;\n var randDay = count < 9 ? \"0\" + count : count;\n var serviceDate = \"2020-02-\" + randDay;\n var serviceTypeId = Math.floor( Math.random(1, 10) );\n var serviceType = 100 + serviceTypeId;\n var hectaresServiced = (count * 2 / 10 * count )\n \n var booking = {\n \"BAAgreeToPairing\": false,\n \"BAServiceDate\": \"2020-01-21\",\n \"OperatorID\": 0,\n \"ReceiveTractorAvailabilityNotification\": true,\n \"bookingAgentData\": \"{\\\"_id\\\":\\\"5e26f2b46706a300167614a3\\\",\\\"bookingAgentID\\\":1579600001000,\\\"country\\\":\\\"Nigeria\\\",\\\"createdAt\\\":\\\"2020-01-21 15:46:44\\\",\\\"latitude\\\":0.0,\\\"longitude\\\":0.0,\\\"name\\\":\\\"Htdemo Booking Agent \\\",\\\"orgID\\\":\\\"6045\\\",\\\"password\\\":\\\"yebOqrQ13s2wNzDzSdJiIg\\\\u003d\\\\u003d\\\",\\\"phone\\\":\\\"08000000000\\\",\\\"profileImage\\\":\\\"http://storage.googleapis.com/449962836b6c4ea5b59b03abd32fbedb/1579600001000_1579611692155_booking_agent_profile_image.jpg/1579600001000_1579611692155_booking_agent_profile_image.jpg\\\",\\\"profileImageURL\\\":\\\"http://storage.googleapis.com/449962836b6c4ea5b59b03abd32fbedb/1579600001000_1579611692155_booking_agent_profile_image.jpg/1579600001000_1579611692155_booking_agent_profile_image.jpg\\\",\\\"syncStatus\\\":1,\\\"updatedAt\\\":\\\"2020-01-21 13:01:41\\\",\\\"userId\\\":\\\"5e26f2b46706a300167614a3\\\",\\\"username\\\":\\\"08000000000\\\"}\",\n \"bookingAgentID\": \"1579600001000\",\n \"bookingID\": bookingID,\n \"bookingStatus\": 0,\n \"clusterID\": clusterID,\n \"distanceToDestination\": 0,\n \"farmLocation\": \"65 Muguga Green, Nairobi, Kenya\",\n \"farmerName\": \"Bohra\",\n \"farmerPhone\": \"+254 7066845431\",\n \"farmerTitle\": 0,\n \"gender\": 0,\n \"createdAt\": \"2020-01-20\",\n \"hectaresServiced\": hectaresServiced,\n \"latitude\": -1.2583604,\n \"longitude\": 36.7906792,\n \"orgID\": \"6045\",\n \"primaryCrop\": \"Beans\",\n \"secondaryCrop\": \"\",\n \"serviceDate\": serviceDate,\n \"serviceType\": serviceType,\n \"syncStatus\": 1,\n \"_acl\": {\n \"creator\": \"5e26f2b46706a300167614a3\"\n }\n\t\t}\n \n return booking;\n }\n \n var start = 1;\n var end = 31;\n var Booking = modules.collectionAccess.collection('ServiceBookings');\n while ( start < end )\n {\n var booking = getBooking(start);\n Booking.save(booking, function(err, booking){\n if(!err){\n modules.logger.info('booking created successfully having ID of ' + booking.bookingID);\n }\n })\n \n start++;\n if( start === end ){\n response.complete();\n }\n }\n\n\t\n\n}" }, "ComputeDailyFuelConsumed" : { "code" : "//Computes daily fuel consumed from FuelHistory collection every 1 minute\n//for every updated tractor in TractorDetail\n//Updated by Abdulmajid on 7th February 2020, Updated: 26th February 2020\n\nfunction onRequest(request, response, modules) {\n var tractorDetailCol = modules.collectionAccess.collection(\"TractorDetail\");\n var fuelHistoryCol = modules.collectionAccess.collection(\"FuelHistory\");\n var dailyFuelConsumedCol = modules.collectionAccess.collection(\"DailyFuelConsumed\");\n var log = modules.logger;\n var fiveMinutesAgo = modules.moment.utc().subtract(5, \"minutes\").format('YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); //2020-02-05T17:22:48.126Z\n var todaysDate = modules.moment.utc().format(\"YYYY-MM-DD\"); //2020-02-05\n var twoMinutesAgo = modules.moment.utc().subtract(2, \"minutes\").format(\"YYYY-MM-DD HH:mm:ss\"); //2020-02-05 23:09:32\n // var now = modules.moment.utc().format('YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); //2020-02-05T17:23:48.126Z\n var counter = 0;\n var tractorQuery = {\n $or: [\n {\"_kmd.lmt\": {$gte: twoMinutesAgo}},\n {\"UpdatedAt\": {$gte: twoMinutesAgo}},\n ]\n }\n \n tractorDetailCol.find(tractorQuery, function(tractorDetailErr, tractorDetailList){\n if (tractorDetailList && tractorDetailList.length > 0 && !tractorDetailErr){\n counter = tractorDetailList.length;\n log.info(\"Found tractors: \"+counter);\n tractorDetailList.forEach(function(tractorDetail){\n fuelHistoryCol.find(\n {$and: [\n {TractorID: tractorDetail.TractorID},\n {\"CreatedAt\": {$gte: todaysDate}}\n ]},\n {sort: {\"_kmd.ect\": 1}},\n function(fuelHistoryErr, fuelHistoryList){\n if (fuelHistoryList && fuelHistoryList.length > 0 && !fuelHistoryErr){\n var fuelConsumedLitresForDay = computeFuelConsumedForDay(fuelHistoryList);\n saveFuelConsumedForTractorForDay(fuelConsumedLitresForDay, tractorDetail, todaysDate)\n } else{\n log.info(\"No fuel history found for \"+tractorDetail.TractorID+\" for \"+todaysDate);\n counter--;\n finish();\n }\n }\n );\n })\n } else {\n log.info(\"Could not find tractors: \"+tractorDetailErr);\n finish();\n }\n });\n \n var computeFuelConsumedForDay = function (fuelHistoryList){\n var totalFuelConsumed = 0;\n for (var i = 0; i < fuelHistoryList.length; i++){\n if (fuelHistoryList.length > (i + 1)){\n var currFuelLitres = fuelHistoryList[i].FuelLitres;\n var nextFuelLitres = fuelHistoryList[i + 1].FuelLitres;\n if (currFuelLitres > nextFuelLitres) totalFuelConsumed += (currFuelLitres - nextFuelLitres);\n }\n } \n return totalFuelConsumed;\n }\n\n\n var saveFuelConsumedForTractorForDay = function(fuelConsumedLitresForDay, tractorDetail, todaysDate){\n var dailyFuelConsumed = {\n _acl: tractorDetail._acl,\n _kmd: modules.kinvey.entity()._kmd,\n Day: todaysDate,\n FinalLatitude: tractorDetail.PositionLatitude,\n FinalLongitude: tractorDetail.PositionLongitude,\n TractorID: tractorDetail.TractorID,\n FuelLitres: fuelConsumedLitresForDay,\n TractorModelID: tractorDetail.TractorModelID,\n ActiveTimeToday: tractorDetail.ActiveTimeToday,\n CreatedAt: modules.moment.utc().format(\"YYYY-MM-DD HH:mm:ss\"),\n UpdatedAt: modules.moment.utc().format(\"YYYY-MM-DD HH:mm:ss\"),\n ImplementsAttached: tractorDetail.ImplementsAttached? tractorDetail.ImplementsAttached.split(\",\"): [],\n OperatorID: tractorDetail.OperatorID? [tractorDetail.OperatorID]: [],\n LastActiveTime: tractorDetail.LastActiveTime,\n }\n\n dailyFuelConsumedCol.update({\n $and: [\n {Day: todaysDate},\n {TractorID: tractorDetail.TractorID}\n ]\n }, {$set: dailyFuelConsumed}, \n {upsert: true},\n function(updateFuelConsumedErr, updateFuelConsumedRes){\n log.info(\"Daily fuel consumed saved for \"+tractorDetail.TractorID + \" for \" + todaysDate);\n counter--;\n finish();\n })\n }\n\n var finish = function(){\n if (counter == 0){\n log.info(\"Finished computing fuel consumed\");\n response.complete();\n }\n }\n}" }, "_ComputeDailyFuelConsumedInit" : { "code" : "/**\n * Compute fuel consumed for previously computed fuel volumes\n * stored in the FuelHistory collection. \n * Use skip and limit to avoid timing constraints\n * Updated by Abdulmajid on 6th February 2020\n */\nfunction onRequest(request, response, modules) {\n var tractorDetailCol = modules.collectionAccess.collection(\"TractorDetail\");\n var fuelHistoryCol = modules.collectionAccess.collection(\"FuelHistory\");\n var dailyFuelConsumedCol = modules.collectionAccess.collection(\"DailyFuelConsumed\");\n var log = modules.logger;\n var todaysDate = modules.moment.utc().format(\"YYYY-MM-DD\"); //2020-02-05\n var tractorCounter = 0;\n var fuelDaysCounter = 0;\n\n tractorDetailCol.find({\"_kmd.lmt\": {$gt: \"2020-02-13\"}}, {sort: {\"_kmd.ect\": -1}, skip: 15, limit: 2}, function(tractorDetailErr, tractorDetailList){\n tractorCounter = tractorDetailList.length;\n log.info(\"Tractors found: \"+tractorDetailList.length);\n tractorDetailList.forEach(function(tractorDetail){\n fuelHistoryCol.find({TractorID: tractorDetail.TractorID}, {sort: {\"_kmd.ect\": 1}}, function(fuelHistoryListErr, fuelHistoryList){\n if (fuelHistoryList && fuelHistoryList.length > 0 && !fuelHistoryListErr){\n var tractorDayFuelHistoryListMap = {};\n fuelHistoryList.forEach(function(fuelHistory){\n var day = modules.moment(fuelHistory._kmd.ect).format(\"YYYY-MM-DD\");\n var fuelHistoryListForDayForTractor = tractorDayFuelHistoryListMap[day];\n if (!fuelHistoryListForDayForTractor) fuelHistoryListForDayForTractor = [];\n fuelHistoryListForDayForTractor.push(fuelHistory);\n tractorDayFuelHistoryListMap[day] = fuelHistoryListForDayForTractor;\n })\n\n fuelDaysCounter = Object.keys(tractorDayFuelHistoryListMap).length;\n log.info(\"Fuel days for \"+tractorDetail.TractorID +\" count \"+fuelDaysCounter);\n if (fuelDaysCounter){\n for (var day in tractorDayFuelHistoryListMap){\n var fuelHistoryListForDay = tractorDayFuelHistoryListMap[day];\n var fuelConsumedLitresForDay = computeFuelConsumedForDay(fuelHistoryListForDay);\n saveFuelConsumedForTractorForDay(fuelConsumedLitresForDay, tractorDetail, day);\n }\n } else {\n log.info(\"No fuel history found for \"+tractorDetail.TractorID+\" for \"+todaysDate);\n tractorCounter--;\n finish();\n }\n } else{\n log.info(\"No fuel history found for \"+tractorDetail.TractorID+\" for \"+todaysDate);\n tractorCounter--;\n finish();\n }\n })\n });\n });\n\n var computeFuelConsumedForDay = function (fuelHistoryList){\n var totalFuelConsumed = 0;\n for (var i = 0; i < fuelHistoryList.length; i++){\n if (fuelHistoryList.length > (i + 1)){\n var currFuelLitres = fuelHistoryList[i].FuelLitres;\n var nextFuelLitres = fuelHistoryList[i + 1].FuelLitres;\n if (currFuelLitres >= nextFuelLitres) totalFuelConsumed += (currFuelLitres - nextFuelLitres);\n }\n } \n return totalFuelConsumed;\n }\n\n var saveFuelConsumedForTractorForDay = function(fuelConsumedLitresForDay, tractorDetail, day){\n var dailyFuelConsumed = {\n _acl: tractorDetail._acl,\n Day: day,\n _kmd: modules.kinvey.entity()._kmd,\n FinalLatitude: tractorDetail.PositionLatitude,\n FinalLongitude: tractorDetail.PositionLongitude,\n TractorID: tractorDetail.TractorID,\n FuelLitres: fuelConsumedLitresForDay,\n TractorModelID: tractorDetail.TractorModelID,\n ActiveTimeToday: null,\n CreatedAt: modules.moment.utc().format(\"YYYY-MM-DD HH:mm:ss\"),\n UpdatedAt: modules.moment.utc().format(\"YYYY-MM-DD HH:mm:ss\"),\n ImplementsAttached: tractorDetail.ImplementsAttached? tractorDetail.ImplementsAttached.split(\",\"): [],\n OperatorID: [tractorDetail.OperatorID],\n LastActiveTime: modules.moment(day).format(\"YYYY-MM-DD HH:mm:ss\")\n }\n\n dailyFuelConsumedCol.update({\n TractorID: tractorDetail.TractorID,\n Day: day\n },\n {$set: dailyFuelConsumed},\n {multi: false, upsert: true},\n function(updateFuelConsumedErr, updateFuelConsumedRes){\n log.info(\"Daily fuel consumed saved for \"+tractorDetail.TractorID + \" for \" + day + \", \"+updateFuelConsumedRes + \", \"+updateFuelConsumedErr);\n fuelDaysCounter--;\n if (fuelDaysCounter === 0) {\n tractorCounter--;\n }\n finish();\n })\n }\n\n\n var finish = function(){\n if (tractorCounter <= 0){\n log.info(\"Finished computing fuel consumed\");\n response.complete();\n }\n }\n}" }, "__updateTractorLocationOnPostFromLocationService" : { "code" : "function onRequest(request, response, modules) {\n const Tractor = modules.collectionAccess.collection('TractorDetail');\n const tractorLocationUpdate = request.body;\n\tvar tractor = {}\n\n var getFormattedDateAndTime = function(timestamp){\n var seconds = new Date(timestamp*1000).toISOString()\n seconds = seconds.split(\"T\");\n var date = seconds[1].split(\".\")[0]\n var dateAndTime = seconds[0] + \" \" + date;\n return dateAndTime;\n }\n \n if(tractorLocationUpdate.latitude && tractorLocationUpdate.longitude){\n \n tractor.PositionLatitude = tractorLocationUpdate.latitude;\n \ttractor.PositionLongitude = tractorLocationUpdate.longitude;\n \n }\n \n tractor.Status = tractorLocationUpdate.ignitionStatus;\n tractor.IgnitionStatus = tractorLocationUpdate.ignitionStatus;\n tractor.Speed = tractorLocationUpdate.speed;\n tractor.AssetState = tractorLocationUpdate.ignitionStatus == 1 ? \"On\" : \"Off\";\n\n \n var last_active_time = getFormattedDateAndTime(tractorLocationUpdate.updateTime);\n \n if( last_active_time != \"1970-01-01 00:00:00\"){\n tractor.LastActiveTime = last_active_time\n }\n \n tractor.UpdatedAt = modules.moment.utc().format('YYYY-MM-DD HH:mm:ss');\n tractor.FuelLevelVoltage = tractorLocationUpdate.fuelLevelVoltage;\n tractor.FuelRawValue = tractorLocationUpdate.fuelRawValue;\n \n if(tractorLocationUpdate.street && tractorLocationUpdate.town && tractorLocationUpdate.country){\n \ttractor.Street = tractorLocationUpdate.street;\n \t\ttractor.Town = tractorLocationUpdate.town;\n \t\ttractor.Country = tractorLocationUpdate.country;\n }\n \n\n\tvar ASSET_ID = Number(tractorLocationUpdate.assetId);\n \n Tractor.update({TractorID: ASSET_ID}, {$set:tractor}, function(err, updated){\n \n if(err){\n modules.logger.info('cannot find tractor with ID of ' + tractorLocationUpdate.assetId )\n }\n \n if( updated ){\n \t\tmodules.logger.info('successfully updated tractor with the id of ' + tractorLocationUpdate.assetId);\n }\n \t\t\n })\n \n response.complete(200);\n}" }, "playground" : { "code" : "function onRequest(request, response, modules) {\n \n const Tractor = modules.collectionAccess.collection('TractorDetail');\n Tractor.find({\"LastActiveTime\": {\"$gte\": \"2020-03-09\"}}, function(err, activeTractors){\n \n if( err ){\n modules.logger.info(\"There was an error \" + err.message);\n response.complete();\n }\n modules.logger.info(\"we had \" + activeTractors.length + \" tractors active for \" + activeTractors[activeTractors.length-1].LastActiveTime)\n })\n response.complete();\n \n}" }, "genericUpdate" : { "code" : "function onRequest(request, response, modules) {\n modules.logger.info(\"Started\");\n const collection = modules.collectionAccess.collection(request.body.collectionName);\n \n collection.update(\n \t request.body.query,\n {$set:request.body.changes}, {\"upsert\":false},\n function(err, updated) {\n \n response.body = {\"success\": false}\n if (!err) {\n response.body = {\"success\": true, \"updated\": updated};\n } else {\n response.body = {\"success\": false}\n }\n modules.logger.info(\"Completing response\");\n response.complete();\n }\n )\n modules.logger.info(\"Finished?\");\n}\n" }, "_FixTractorDetailGeofence" : { "code" : "var tractorDetailDocs = {\n \"100003\": {\n \"_id\": \"576d164fc2a105e65b9101d0\",\n \"Characteristic\": \"101,102,103,104\",\n \"Latitude\": \"6.6903\",\n \"Longitude\": \"7.0551\",\n \"OperatorID\": 200010,\n \"Speed\": 0,\n \"Status\": 1,\n \"TotalHectaresTilled\": 0,\n \"TractorID\": 100003,\n \"TractorName\": \"ST - Adani-Enugu\",\n \"UtcOffset\": 0,\n \"_acl\": {\n \"creator\": \"573f5f1dc974a4187580c2a1\"\n },\n \"LastActivityId\": 2222252,\n \"PositionLatitude\": 7.7928,\n \"PositionLongitude\": 8.8779,\n \"Street\": \"Unnamed Road\",\n \"Town\": \"\",\n \"Country\": \"Nigeria\",\n \"Currency\": \"RAND\",\n \"DailyTractorUpdates\": false,\n \"BookingRequests\": true,\n \"LastActiveTime\": \"2017-07-17 22:11:51.0\",\n \"EngineHours\": 12,\n \"LastGeofenceNotificationTime\": \"\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"ActiveTimeToday\": 0,\n \"UpdatedAt\": \"2019-10-30 01:59:09\",\n \"WasInArea\": true,\n \"_kmd\": {\n \"lmt\": \"2019-04-17T08:53:03.172Z\",\n \"ect\": \"2016-06-24T11:15:27.189Z\"\n },\n \"TotalDistanceCovered\": 0,\n \"LastOdometerValue\": 183069,\n \"IgnitionStatus\": \"On\",\n \"TrackerID\": 100003,\n \"ServiceProvider\": \"2TRACK\"\n },\n \"100004\": {\n \"_id\": \"57a9a17f560f24772f788b49\",\n \"Characteristic\": \"101,102,104,103,105,106,107\",\n \"Latitude\": \"8.921\",\n \"Longitude\": \"7.2557\",\n \"OperatorID\": 200012,\n \"Speed\": 0,\n \"Status\": 1,\n \"TotalHectaresTilled\": 0,\n \"TractorID\": 100004,\n \"TractorName\": \"ST - Sauka-Abuja\",\n \"UtcOffset\": 0,\n \"_acl\": {\n \"creator\": \"573f5f1dc974a4187580c2a1\"\n },\n \"LastActivityId\": 467405,\n \"PositionLatitude\": 8.9207,\n \"PositionLongitude\": 7.2557,\n \"Street\": \"Unnamed Road\",\n \"Town\": \"Kuje\",\n \"Country\": \"Nigeria\",\n \"Currency\": \"RAND\",\n \"DailyTractorUpdates\": false,\n \"BookingRequests\": true,\n \"LastActiveTime\": \"2016-06-25 12:31:58.0\",\n \"EngineHours\": 0,\n \"LastGeofenceNotificationTime\": \"\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"ActiveTimeToday\": 0,\n \"UpdatedAt\": \"2019-10-30 01:59:09\",\n \"WasInArea\": true,\n \"TotalDistanceCovered\": 0,\n \"license_plate_number\": \"\",\n \"_kmd\": {\n \"lmt\": \"2019-04-17T08:53:02.866Z\",\n \"ect\": \"2016-08-09T09:25:19.373Z\"\n },\n \"LastOdometerValue\": 1252,\n \"IgnitionStatus\": \"On\",\n \"TrackerID\": 100004,\n \"ServiceProvider\": \"2TRACK\"\n },\n \"100006\": {\n \"_id\": \"581f98301cefe568583e635d\",\n \"BookingRequests\": true,\n \"Characteristic\": \"101,109,103,107\",\n \"Country\": \"Nigeria\",\n \"Currency\": \"Nigerian naira\",\n \"DailyTractorUpdates\": false,\n \"EngineHours\": 68,\n \"LastActiveTime\": \"2016-11-30 11:04:06.0\",\n \"Latitude\": \"11.683303399360158,11.683303399360158,11.683303399360158,11.683303399360158,11.683303399360158,11.683303399360158,11.683303399360158,11.685544898044192,11.687786378591534,11.688682703072708,11.689131192548386,11.689131192548386,11.689131192548386,11.689131192548386,11.689131192548386,11.689131192548386,11.690027512677046,11.690475999974769,11.690475999974769,11.690475999974769,11.690475999974769,11.690475999974769,11.690475999974769,11.690475999974769,11.690475999974769,11.690475999974769,11.690475999974769,11.690475999974769,11.690475999974769,11.690475999974769,11.688234541194724,11.684200066675727,11.682855228779388,11.67657912285859,11.670303203203286,11.66402681320257,11.655508886333045,11.646990369864753,11.638471920713469,11.629953210696781,11.621882509664195,11.614708137952661,11.607085617267693,11.602601336516168,11.599014254145425,11.593184572223475,11.591390976307318,11.58959736887455,11.58735509705865,11.586009791021313,11.586458117605316,11.586458117605316,11.586458117605316,11.586906771913686,11.586906771913686,11.58825207363273,11.58959736887455,11.59004568970237,11.59004568970237,11.59004568970237,11.59004568970237,11.589148718886381,11.589148718886381,11.58825207363273,11.58825207363273,11.587803421484338,11.58735509705865,11.58735509705865,11.58735509705865,11.58735509705865,11.58735509705865,11.588700396619245,11.59094265763846,11.595426797246038,11.599014254145425,11.602601336516168,11.609776019752015,11.616053305665764,11.626366151870771,11.634436722940638,11.643852093354933,11.652818925845343,11.661785140581939,11.668509775777737,11.674786064356036,11.683751897545326,11.69316559523332\",\n \"Longitude\": \"8.942913338541985,8.942913338541985,8.942913338541985,8.942913338541985,8.942913338541985,8.942913338541985,8.942913338541985,8.947948850691319,8.955730609595776,8.96625928580761,8.978161253035069,8.990520872175694,9.002422504127027,9.01295118033886,9.021648578345774,9.028057381510735,9.03217725455761,9.035839475691317,9.03767041862011,9.038586057722567,9.038128070533276,9.038128070533276,9.038128070533276,9.038128070533276,9.038128070533276,9.038128070533276,9.038128070533276,9.038128070533276,9.038128070533276,9.038128070533276,9.037212766706944,9.035839475691317,9.035381488502026,9.03492383658886,9.032634906470776,9.031719602644444,9.030803963541986,9.029888324439526,9.028973020613192,9.028973020613192,9.029888324439526,9.029888324439526,9.029888324439526,9.029888324439526,9.029888324439526,9.029888324439526,9.029888324439526,9.02943067252636,9.028973020613192,9.028973020613192,9.028973020613192,9.028973020613192,9.028973020613192,9.027141742408276,9.025310799479485,9.017071053385733,9.011120237410069,9.003338143229485,8.994182758033276,8.98548536002636,8.975872322916985,8.96625928580761,8.9571039006114,8.950237445533276,8.947033211588861,8.944744281470777,8.942913338541985,8.94337099045515,8.94337099045515,8.94337099045515,8.94337099045515,8.94337099045515,8.94428662955761,8.944744281470777,8.94428662955761,8.94428662955761,8.94428662955761,8.94428662955761,8.945659920573235,8.947033211588861,8.94886415451765,8.950237445533276,8.9516107365489,8.953899666666985,8.95527295768261,8.95801953971386,8.960308469831944\",\n \"OperatorID\": 200024,\n \"PositionLatitude\": 11.6299,\n \"PositionLongitude\": 8.9803,\n \"Speed\": 0,\n \"Status\": 1,\n \"Street\": \"Unnamed Road\",\n \"TotalHectaresTilled\": 63.98039999999998,\n \"Town\": \"\",\n \"TractorID\": 100006,\n \"TractorModelID\": 1,\n \"TractorName\": \"Smart Tractor\",\n \"_acl\": {\n \"creator\": \"574370f9d9f4789c35cb0338\"\n },\n \"_kmd\": {\n \"lmt\": \"2019-04-17T08:53:03.691Z\",\n \"ect\": \"2016-11-06T20:53:04.706Z\"\n },\n \"license_plate_number\": \"ABJ-100006\",\n \"UtcOffset\": 0,\n \"LastActivityId\": 577372,\n \"NeedToSendGeofenceOutNotification\": true,\n \"LastGeofenceNotificationTime\": \"\",\n \"WasInArea\": true,\n \"ActiveTimeToday\": 0,\n \"UpdatedAt\": \"2019-10-30 01:59:09\",\n \"TotalDistanceCovered\": 72,\n \"LastOdometerValue\": 9529754,\n \"IgnitionStatus\": \"On\",\n \"TrackerID\": 100006,\n \"ServiceProvider\": \"2TRACK\"\n },\n \"100007\": {\n \"_id\": \"576a4551e7e23c1c6af98181\",\n \"ActiveTimeToday\": 0,\n \"BookingRequests\": true,\n \"Characteristic\": \"101,103,104,105,106,107\",\n \"Country\": \"Nigeria\",\n \"Currency\": \"Kenyan shilling\",\n \"DailyTractorUpdates\": false,\n \"Efficiency\": 0,\n \"EngineHours\": 2342,\n \"FixedEngineHours\": 0,\n \"FixedOdometerReading\": 0,\n \"FuelLitres\": 0,\n \"FuelVolume\": 0,\n \"Heading\": 0,\n \"ImplementsAttached\": \"101,106\",\n \"LastActiveTime\": \"2018-02-23 12:09:35.0\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"10.968369429166206,10.969268011196519,10.969268011196519,10.969268011196519,10.970616208269321,10.97331258396556,10.978255985215984,10.984996703973835,10.994882703309676,11.003420659297309,11.013755263714485,11.02678572107173,11.039815600981564,11.051496753102958,11.063177769151824,11.073510600202674,11.083842737545897,11.096420985404299,11.109447438997163,11.123372079376106,11.137744758124983,11.15346441226369,11.170979474486504,11.187595241426743,11.202863263855992,11.214987121837828,11.232947348195168,11.239682186029667,11.245518808624833,11.250457599309273,11.25360024265837,11.25674318053576,11.259436912077993,11.261232609492504,11.262579457404454,11.262579457404454,11.261232609492504,11.257192027934865,11.25090645650642,11.241927206634047,11.234743210710949,11.225314232296705,11.213190807561734,11.200169004170773,11.188044525221741,11.172775721729545,11.157506443459999,11.143583764565616,11.131456921820774,11.120677082039979,11.109896843575331,11.099565298272527,11.089682823153924,11.079350563051927,11.071264277758601,11.064525536087595,11.05868527761734,11.053294065278743,11.04610540864066,11.038916905000146,11.032177420199105,11.02678572107173,11.022741881839204,11.01824877163074,11.012856817180994,11.007464763978293,11.00252185212558,10.998028433387537,10.994882703309676,10.99173726880121,10.988142210344721,10.985895564557177,10.98409784065328,10.983199303730652,10.981401563407424,10.979604141277685,10.977806708208213,10.976458214799925,10.97555965463244,10.974211480112007,10.972413685084664,10.96971763033732,10.967470515252176,10.968369429166206\",\n \"Longitude\": \"7.740582972764969,7.720441259443761,7.71311715245247,7.704877406358718,7.693891078233719,7.678784877061844,7.664136327803135,7.652692347764969,7.642163671553135,7.633008286356926,7.624310888350011,7.615155503153801,7.607373744249343,7.601880580186844,7.597760707139968,7.594556137919426,7.5931828469038,7.591809555888176,7.592267543077469,7.594556137919426,7.599133998155594,7.60783139616251,7.619275376200675,7.632092982530595,7.645367905497551,7.656812220811844,7.673291712999344,7.682904750108719,7.691144496202468,7.699384242296219,7.707623988389968,7.718610316514968,7.730969935655594,7.743787206709386,7.757520116865635,7.7744572609663,7.790479101240636,7.807416245341301,7.824353724718094,7.839459925889968,7.851819545030593,7.86326352506876,7.871960923075676,7.877912074327469,7.879285365343094,7.878369726240636,7.876538783311845,7.875623144209385,7.874707505106926,7.87424985319376,7.873792201280595,7.873792201280595,7.871960923075676,7.868756689131261,7.86692574620247,7.865552455186843,7.863721176981926,7.861890234053136,7.860059291124345,7.856854721903802,7.85319283604622,7.849988266825677,7.847241684794425,7.843121811747552,7.836255356669426,7.830304540693759,7.824353724718094,7.8184025734663,7.813367396593095,7.807874232530594,7.801923081278802,7.797345556318761,7.794141322374344,7.791394740343093,7.787732519209386,7.783154994249345,7.779035121202468,7.775372900068761,7.772626318037509,7.768506444990635,7.7634709328413,7.755689173936845,7.75065366178751,7.746991440653801\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 200008,\n \"PositionLatitude\": 11.0798,\n \"PositionLongitude\": 7.7003,\n \"ServiceProvider\": \"2TRACK\",\n \"Speed\": 1,\n \"Status\": 1,\n \"Street\": \"A 236\",\n \"TotalDistanceCovered\": 5595,\n \"TotalHectaresTilled\": 241.3,\n \"Town\": \"Zaria\",\n \"TractorID\": 100007,\n \"TractorModelID\": 3,\n \"TractorName\": \"55-i7 Tractor \",\n \"UpdatedAt\": \"2019-10-30 14:34:56\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"_acl\": {\n \"creator\": \"574370f9d9f4789c35cb0338\"\n },\n \"license_plate_number\": \"135762\",\n \"_kmd\": {\n \"lmt\": \"2019-10-30T14:34:56.637Z\",\n \"ect\": \"2016-06-22T07:59:13.273Z\"\n }\n },\n \"100017\": {\n \"_id\": \"5938572c944525fa3b90dd2c\",\n \"ActiveTimeToday\": 0,\n \"BookingRequests\": true,\n \"Characteristic\": \"101,102,103,104,105,106,107\",\n \"Country\": \"Nigeria\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 47,\n \"FixedEngineHours\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"vcdp111\",\n \"Heading\": 0,\n \"LastActiveTime\": \"2019-02-08 10:09:09.0\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"6.4006249698685185,6.4006249698685185,6.399019342800156,6.397949144076344,6.397414043873856,6.394737868077313,6.3915269050987025,6.387780478485175,6.382428345296009,6.377076156182538,6.370653655414687,6.365301343432165,6.358878695359991,6.351920486162613,6.344962516118979,6.331045961026744,6.303211393282941,6.287687741514472,6.274840437762916,6.268951900991439,6.264133776030762,6.259851183135003,6.255033307477385,6.251821143512776,6.249144547327627,6.24753844972999,6.245932347203625,6.244326239749767,6.242720127369673,6.240578747631807,6.23522542665143,6.2314778694695505,6.232013141193195,6.233084016296322,6.2357606945509145,6.2395082211258455,6.242184866577926,6.244861831639559,6.24753844972999,6.252356394449881,6.258245118425702,6.266810628703741,6.278052460054905,6.287687741514472,6.29518202212718,6.304817319254159,6.3176642146443776,6.3294401164378815,6.338004118890134,6.346568312386502,6.355667174623511,6.363160469661226,6.370118526689532,6.376541034157717,6.379216971895849,6.380822661112007,6.382963461172944,6.385104252285823,6.3867099230453634,6.388850698491669,6.392597117267979,6.395808406715248,6.398484243718457,6.4027656870461715,6.406512003803913,6.410258293057541,6.414004554791266,6.419891434279956,6.423102551927795,6.426848719187138,6.429524393266931,6.431664989026081,6.432735450107755,6.432735450107755,6.432735450107755,6.433805575770027,6.4332705132206,6.432200053265949,6.431664989026081,6.430059459759979,6.428989326210783,6.425778245712027,6.424172697861498,6.423102551927795,6.42256714494521,6.42149699563573,6.419356357094327,6.416680296382352,6.413469471422766,6.411328799152853,6.4097232057573414,6.4097232057573414,6.4097232057573414,6.413469471422766,6.414539637598028\",\n \"Longitude\": \"8.166347779333591,8.166347779333591,8.151268735527992,8.142651803791525,8.13403520733118,8.125418610870836,8.115724772214888,8.105492144823074,8.095798306167126,8.087181709706782,8.07964202016592,8.072641119360924,8.06617833673954,8.060254342854023,8.05486913770437,8.045713752508163,8.03332731127739,8.034942671656609,8.043021149933338,8.04732944816351,8.05217619985342,8.057561740279198,8.064562976360321,8.072641119360924,8.082334958016872,8.091490007936953,8.098491244018078,8.104953691363335,8.111954927444458,8.118955828249454,8.132957965135576,8.155577033758163,8.17065641283989,8.180349916219713,8.192197903990746,8.201891742646694,8.210508674383163,8.21697112172842,8.222895115613937,8.232588954269886,8.242282792925835,8.251438178122044,8.259516321122646,8.265978768467905,8.27244121581316,8.277826756238937,8.282673507928848,8.28644335269928,8.287520594894886,8.288059048354626,8.289674744009972,8.289674744009972,8.289674744009972,8.289674744009972,8.289674744009972,8.289136290550232,8.288597501814365,8.287520594894886,8.28590489923954,8.283750750124454,8.280519358813763,8.276211060583591,8.271902762353418,8.268671371042728,8.264363072812557,8.260593228042126,8.255746476352215,8.250899389386179,8.247129544615744,8.242821246385574,8.237974494695663,8.232588954269886,8.22612650692463,8.219663724303246,8.213201276957989,8.205661587417126,8.19973759353161,8.193275146186352,8.187889605760574,8.183042854070663,8.178195767104626,8.172810561954973,8.167963474988937,8.164193630218506,8.16150102764368,8.159346878528595,8.156115487217903,8.151807188987734,8.148037344217302,8.144805952906609,8.142651803791525,8.14319059252739,8.14319059252739,8.144805952906609,8.145344741642475\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": 6.0156,\n \"PositionLongitude\": 7.8308,\n \"Speed\": 6,\n \"Status\": 1,\n \"Street\": \"Unnamed Road\",\n \"TotalDistanceCovered\": 0,\n \"TotalHectaresTilled\": 0,\n \"Town\": \"Okposi\",\n \"TractorID\": 100017,\n \"TractorModelID\": 8,\n \"TractorName\": \"VCDP EBONYI\",\n \"UpdatedAt\": \"2019-10-30 01:59:09\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"license_plate_number\": \"vcdp Ebonyi 111\",\n \"_acl\": {\n \"creator\": \"5937bcc903f5fcc4201ee286\"\n },\n \"_kmd\": {\n \"lmt\": \"2019-04-17T08:53:03.660Z\",\n \"ect\": \"2017-06-07T19:42:36.977Z\"\n },\n \"LastActivityId\": 96896916,\n \"LastOdometerValue\": 1348,\n \"IgnitionStatus\": \"On\",\n \"TrackerID\": 100017,\n \"ServiceProvider\": \"2TRACK\"\n },\n \"100018\": {\n \"_id\": \"580f7c54a56e04b64d17c82d\",\n \"BookingRequests\": true,\n \"Characteristic\": \"101,102\",\n \"Currency\": \"Nigerian naira\",\n \"DailyTractorUpdates\": true,\n \"Latitude\": \"5.132716055814091,5.133171872446192,5.13362802268376,5.13408383866409,5.13408383866409,5.134539654318615,5.134539654318615,5.134539654318615,5.134539654318615,5.134539654318615,5.134995803577819,5.135451618580394,5.135907433257078,5.136363581537649,5.136363581537649,5.134539654318615,5.132260238856277,5.1299804813160845,5.127244895092555,5.1240534743323485,5.121773687493688,5.119038066130716,5.117214423367859,5.115846604399381,5.114478782507515,5.113110957693023,5.1117431299566976,5.110375299299299,5.1090074657216045,5.104903947474478,5.1035361022233205,5.102168254055759,5.100800402972521,5.099888389314654,5.098976374361194,5.098064692062178,5.09715267451869,5.096696832236612,5.095328969498485,5.094872791971046,5.093961103848573,5.093504925350224,5.09259323528764,5.09259323528764,5.0916812099791455,5.090769183377108,5.090313336568006,5.089401308026338,5.088945460247905,5.088033429767144,5.087577581019634,5.087121731949246,5.086665548600272,5.085753848844831,5.0852976645265136,5.0852976645265136,5.084385962834052,5.084385962834052,5.083929777546644,5.08301807391767,5.082561887661427,5.082561887661427,5.082106035040218,5.081193994871639,5.08073814128265,5.080282287371191,5.079826099178055,5.078914389742647,5.078458200581451,5.077546489211592,5.077090299082592,5.076178585778802,5.0757223946822645,5.07435448738122,5.072986577180261,5.072074858077774,5.070706943045794,5.069794886759677,5.0693390251159345,5.067971104288984,5.066603180565718,5.0661469827035805,5.065235253946914,5.064323189937024,5.063411124640472,5.0624993920257415,5.061587324157063,5.061131456724939,5.060219386927636,5.059307315844714,5.058395577446743,5.0579393737955884,5.057027633470914,5.056571428855822,5.054747609098303,5.052923784205701,5.052011702847501,5.050187870255235,5.048819908950231,5.047451944759712,5.046083977684506,5.04471600772534,5.043348034883012,5.038787881942042,5.036508127450971,5.034683917322972,5.0333159233605915,5.030579926806464,5.029211924216256,5.027843918751653,5.02647591041342,5.025107899202345,5.023739885119177,5.022371868164719,5.021003848339735,5.020092056188761,5.019179928772669,5.01735600410627,5.01598797376309,5.014619940553008,5.01279566915208,5.010971726651065,5.007779731525913,5.006411681130581,5.005043627873756,5.004131479447123,5.003219329748994,5.002763421422621,5.001395360538672,5.000939450942012,5.000027296796067,4.998659230195581,4.998203318694188,4.997291160737964,4.995467175018974,4.994099098898006,4.993186935230207,4.990906687512837,4.989538601879313,4.988170513393837,4.9858905822541235,4.98361030919094,4.980418180816754,4.97722570293256,4.975857588814333,4.972665422817049,4.971297299221366,4.969929172784036,4.968561043505859,4.9671929113875875,4.965368842152639,4.964000703410747,4.964000703410747,4.963544433853652,4.96308849800005,4.961720354529195,4.960808145966162,4.960808145966162,4.960808145966162,4.960808145966162,4.960352208222126,4.95989627016319,4.95989627016319,4.958984059079617,4.958071846735896,4.956247752291388,4.954879594647218,4.950775104723753,4.9484947101949315,4.94484646343889,4.943478282215767,4.942110098166747,4.940741911292606,4.939373721594132,4.9384614822159625,4.937549241582798,4.936181045296746,4.936181045296746,4.936181045296746,4.936181045296746,4.936637333727278,4.938005529072102,4.939373721594132,4.940741911292606,4.9411978625544695,4.942566048487217,4.943934231594577,4.94484646343889,4.94530241187581,4.946214641835351,4.9484947101949315,4.949862881050298,4.952599214271762,4.955335536169014,4.958071846735896,4.961264417415253,4.964912573541924,4.967648844403614,4.969016975575506,4.970385103907047,4.970385103907047,4.970385103907047,4.969929172784036,4.968561043505859,4.965824776430022,4.964456638633913,4.961720354529195,4.960352208222126,4.957615907102445,4.956247752291388,4.953511434170701,4.952599214271762,4.952599214271762,4.952599214271762,4.952599214271762,4.952599214271762,4.952599214271762,4.9539673766363075,4.956247752291388,4.956703692869144,4.958984059079617,4.96308849800005,4.964456638633913,4.970385103907047,4.972665422817049,4.9767697765465915,4.979505998143932,4.986346502313906,4.988626765876557,4.991362938093241,4.991818854351879,4.993186935230207,4.998659230195581,5.002763421422621,5.006411681130581,5.010515823729001,5.010971726651065,5.01279566915208,5.0141637061839806,5.015531740349997,5.016443872865434,5.01735600410627,5.017811902253023,5.019179928772669,5.020547952423594,5.022371868164719,5.022828096794296,5.025107899202345,5.0255641259166675,5.030124037590784,5.031947926521501,5.036508127450971,5.039699981887226,5.045171886706401,5.0479078218185345,5.053835530307421,5.0624993920257415,5.067971104288984,5.07435448738122,5.078458200581451,5.082561887661427,5.086665548600272,5.091225363816473,5.093504925350224,5.095784812751116,5.101256242341453,5.104903947474478,5.10763962922439,5.110375299299299,5.112198961545929,5.113110957693023,5.114478782507515,5.116302433066966,5.117214423367859,5.117214423367859,5.117214423367859,5.115390441466361,5.114022618599719,5.112654792810731,5.111286964100151,5.110831131861908,5.110831131861908,5.111286964100151,5.112654792810731,5.114934612149241,5.117214423367859,5.119950052531561,5.123597317253356,5.128156869780892,5.1299804813160845,5.13362802268376,5.13408383866409,5.134995803577819,5.135451618580394,5.135451618580394,5.133171872446192,5.131804087640573,5.131348270031165,5.1299804813160845,5.1299804813160845,5.1295246624040605,5.1295246624040605,5.1295246624040605,5.1295246624040605,5.1295246624040605,5.1295246624040605\",\n \"Longitude\": \"8.514507561922073,8.513591922819614,8.513134270906448,8.51221863180399,8.511760979890823,8.511303327977657,8.510845340788364,8.510387688875198,8.510387688875198,8.509930036962032,8.509930036962032,8.509930036962032,8.509930036962032,8.510387688875198,8.511760979890823,8.517711795866491,8.520916365087032,8.524578250944616,8.527782820165157,8.53144470602274,8.534191288053988,8.536937870085238,8.539226800203322,8.540600091218948,8.541973382234573,8.542889021337032,8.543346673250198,8.54517761617899,8.546093255281447,8.548839837312698,8.550213128328323,8.55067078024149,8.551586419343948,8.552044071257114,8.552959710359573,8.55341736227274,8.554333001375198,8.554790653288364,8.555706292390823,8.555706292390823,8.555706292390823,8.555706292390823,8.555706292390823,8.555706292390823,8.55616394430399,8.55616394430399,8.55616394430399,8.556621931493282,8.556621931493282,8.556621931493282,8.556621931493282,8.557079583406448,8.557079583406448,8.557537235319614,8.557995222508907,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557537235319614,8.557079583406448,8.556621931493282,8.556621931493282,8.55616394430399,8.55616394430399,8.555706292390823,8.555248640477657,8.555248640477657,8.554790653288364,8.554333001375198,8.554333001375198,8.55341736227274,8.552502058446407,8.552502058446407,8.552044071257114,8.551586419343948,8.55067078024149,8.55067078024149,8.550213128328323,8.550213128328323,8.54792419821024,8.547466546297073,8.547466546297073,8.547008894383907,8.546550907194614,8.546093255281447,8.545635603368282,8.545635603368282,8.54517761617899,8.54517761617899,8.544719964265823,8.544719964265823,8.544719964265823,8.544262312352657,8.544262312352657,8.544262312352657,8.544262312352657,8.544262312352657,8.544262312352657,8.544262312352657,8.544262312352657,8.544262312352657,8.544262312352657,8.544262312352657,8.544262312352657,8.544262312352657,8.544262312352657,8.543804325163364,8.543346673250198,8.543346673250198,8.54243103414774,8.541515730321406,8.540600091218948,8.540142439305782,8.538769148290159,8.537853509187698,8.537395857274532,8.536022566258907,8.535106927156448,8.532360345125198,8.529156111180784,8.527782820165157,8.525036238133907,8.523662947118282,8.522289656102659,8.520916365087032,8.519543074071407,8.516796492040157,8.514965213835241,8.514507561922073,8.513134270906448,8.51221863180399,8.50947204977274,8.507183454930782,8.50123230367899,8.49848572164774,8.496654778718948,8.492534905672073,8.488872684538364,8.48749939352274,8.48475281149149,8.483379520475864,8.480632938444614,8.478801995515823,8.475597761571407,8.47376648336649,8.47101990133524,8.469646610319614,8.467815667390823,8.466442376375198,8.464153446257114,8.462322503328322,8.459575921297075,8.455456048250198,8.453167118132114,8.44904724508524,8.447216302156448,8.444469720125198,8.440807498991491,8.43806091696024,8.43531433492899,8.433483392000198,8.431194461882114,8.42982117086649,8.427990227937698,8.427532576024532,8.426159285008907,8.423870354890823,8.422497063875198,8.419750481843948,8.417003899812698,8.414257317781448,8.410137444734573,8.404644280672073,8.39960876852274,8.39686218649149,8.39319996535778,8.39136902242899,8.388164788484572,8.386791497468948,8.383129276335238,8.379467390477657,8.378094099462034,8.375347182154655,8.37397389113903,8.371227309107779,8.370312005281448,8.368938714265825,8.36848072707653,8.367107436060905,8.366192132234575,8.365276493132114,8.364360854029654,8.36298756301403,8.359325677156448,8.352001234889032,8.348797000944614,8.340557254850864,8.329113274812698,8.324993401765823,8.313091434538364,8.310344852507114,8.306224979460238,8.304851688444614,8.3016474545002,8.3016474545002,8.3016474545002,8.3016474545002,8.3016474545002,8.304851688444614,8.308971561491488,8.31446472555399,8.320415541529655,8.322246819734573,8.324993401765823,8.32728199660778,8.33002857863903,8.331401869654655,8.33277516067028,8.334606438875198,8.33826832473278,8.341472893953323,8.345134779810905,8.346050418913364,8.348339349031448,8.348797000944614,8.351085931062698,8.351543582975864,8.35291687399149,8.353374525904655,8.353832513093948,8.353832513093948,8.353832513093948,8.353832513093948,8.353832513093948,8.353832513093948,8.353832513093948,8.353832513093948,8.353832513093948,8.352459222078323,8.352001234889032,8.351085931062698,8.34925465285778,8.34650807082653,8.34467712789774,8.342846184968948,8.341472893953323,8.341472893953323,8.341472893953323,8.343303836882114,8.348797000944614,8.354290165007114,8.359783329069614,8.368023075163364,8.37397389113903,8.379467390477657,8.384502567350864,8.392742313444614,8.395488895475864,8.400066755712032,8.40418629348278,8.408306501805782,8.411510735750198,8.415172956883907,8.419750481843948,8.426616936922073,8.429363518953323,8.437145613133907,8.440349847078323,8.443096429109575,8.45179382711649,8.461406864225864,8.471935540437698,8.477428704500198,8.48475281149149,8.494823835790157,8.502147942781448,8.508556745946407,8.517254143953325,8.522289656102659,8.524120599031448,8.53144470602274,8.532360345125198\",\n \"OperatorID\": 200022,\n \"Speed\": 0,\n \"Status\": 1,\n \"TotalHectaresTilled\": 0,\n \"TractorID\": 100018,\n \"TractorName\": \"Tohfan 5503-1\",\n \"_acl\": {\n \"creator\": \"580f7b6296db64743e9bb919\"\n },\n \"UtcOffset\": 0,\n \"LastActivityId\": 95965906,\n \"PositionLatitude\": 10.5236,\n \"PositionLongitude\": 7.4355,\n \"Street\": \"Crescent Road\",\n \"Town\": \"Zaria\",\n \"Country\": \"Nigeria\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"LastGeofenceNotificationTime\": \"2019-01-14T13:32:02.171Z\",\n \"WasInArea\": false,\n \"LastActiveTime\": \"2019-01-14 13:42:03.0\",\n \"EngineHours\": 1112,\n \"_kmd\": {\n \"lmt\": \"2019-04-17T08:53:03.005Z\",\n \"ect\": \"2016-10-25T15:37:56.413Z\"\n },\n \"ActiveTimeToday\": 0,\n \"UpdatedAt\": \"2019-10-30 01:59:09\",\n \"TotalDistanceCovered\": 1335,\n \"LastOdometerValue\": 10774038,\n \"IgnitionStatus\": \"On\",\n \"TrackerID\": 100018,\n \"ServiceProvider\": \"2TRACK\"\n },\n \"100027\": {\n \"_id\": \"591dc3261d1446a550d408f0\",\n \"BookingRequests\": true,\n \"Characteristic\": \"102,109,103,107\",\n \"Country\": \"Nigeria\",\n \"Currency\": null,\n \"DailyTractorUpdates\": true,\n \"EngineHours\": 545,\n \"LastActiveTime\": \"2019-04-24 17:42:01.0\",\n \"Latitude\": \"7.323563599380041,7.317687229032866,7.315755136308585,7.314064465176215,7.312213166290722,7.310361527178573,7.308751313218685,7.307382859576424,7.306336313950473,7.305772967435108,7.305128809421868,7.304645939718976,7.304323693738604,7.304001780081477,7.303921301630968,7.303760344686493,7.303357619515714,7.303035705162897,7.302633311895925,7.302069628156755,7.301586755149597,7.301023070091121,7.300379237792276,7.299976509576268,7.299735072007859,7.299654592789412,7.299654592789412,7.299654592789412,7.299654592789412,7.299654592789412,7.2995741135565,7.299493634309099,7.299332675770872,7.299171384615581,7.299010425961392,7.298688508479254,7.298366590765456,7.297883381200348,7.297400503673788,7.296917293065279,7.296273454857269,7.295870722945253,7.295548803204171,7.295307363246389,7.295226883231532,7.295226883231532,7.295307363246389,7.295548803204171,7.295951202844339,7.296434414496121,7.296917293065279,7.297400503673788,7.298044340260046,7.298768987871511,7.299493634309099,7.300056988736792,7.30062067501295,7.301184028020995,7.301586755149597,7.301908670545648,7.302311064464774,7.302713790578283,7.303277140949242,7.304001780081477,7.3048068963445685,7.305772967435108,7.30689999230906,7.307866058874637,7.308993078468995,7.30995914050835,7.310844390704281,7.311649494636795,7.312374120189906,7.313098744567013,7.31374255853861,7.3143062275499675,7.3147890868096095,7.315352754499409,7.315755136308585,7.3161575177549505,7.3164797551970855,7.31680165986052,7.317123564291722,7.317445801036235,7.31849232062292,7.319297078215892,7.320585352431132,7.321229155600599,7.321873290382878,7.322517091692917,7.323080749617992,7.324207730789761,7.324610104610567,7.325012810608047,7.325334709112325,7.325656607384142,7.326059312436069,7.3263007357691805,7.32654215897152,7.327105811806664,7.327508183010918,7.327749605559069,7.328393730918612,7.328715626980592,7.328957048874439,7.329601172488174,7.329762120111983,7.33024529517049,7.33024529517049,7.3303257688732835,7.3303257688732835,7.3303257688732835,7.33024529517049,7.330164821453144,7.330164821453144,7.330084347721256,7.330084347721256,7.3299230676776395,7.3299230676776395,7.3298425939020895,7.329762120111983,7.329762120111983,7.329762120111983,7.329762120111983,7.3298425939020895,7.3299230676776395,7.330406242561547,7.33056718989445,7.331050031544189,7.331211311179714,7.33145273172082,7.331694152131079,7.3317746255720735,7.331855098998539,7.331855098998539,7.331855098998539,7.331855098998539,7.3317746255720735,7.331694152131079,7.331694152131079,7.33145273172082,7.331130837636916,7.331050031544189,7.33056718989445,7.3303257688732835,7.329762120111983,7.329440224806212,7.329198803174213,7.328554678978678,7.3282327828003915,7.327669131390899,7.327347234572823,7.326944863223232,7.3263007357691805,7.325898363474645,7.325656607384142,7.325495658277303,7.32509328525591,7.324288205582975,7.323563599380041,7.322275666310587,7.321631864651959,7.321148680255241\",\n \"Longitude\": \"8.220258504152298,8.218716569244862,8.21822974830866,8.217661455273628,8.217255771160126,8.217012025415897,8.216606341302395,8.216362930834293,8.216444067656996,8.216444067656996,8.216444067656996,8.216444067656996,8.216444067656996,8.216606341302395,8.216687478125095,8.216930888593197,8.217336907982826,8.217742592096329,8.21822974830866,8.218797706067562,8.219528272747993,8.220339976251125,8.221313618123531,8.222368732094765,8.223504982888699,8.224560096859932,8.225534074008465,8.226426914334297,8.22748202830553,8.228618279099464,8.229754529893398,8.230809643864632,8.232027031481264,8.2331632822752,8.234381005167961,8.235598392784595,8.23681578040123,8.238033168017864,8.239169418811798,8.240549080073833,8.241766802966596,8.242903053760529,8.244039304554462,8.245175555348396,8.246555216610432,8.247772604227066,8.248989991843699,8.250288851559162,8.251506239175797,8.252885900437834,8.254184424877167,8.255401812493801,8.256375789642334,8.257349766790867,8.2584860175848,8.259541131556034,8.260271698236465,8.261083401739597,8.2616513594985,8.26213851571083,8.262706473469734,8.263193629682064,8.263680450618267,8.264248743653297,8.2647355645895,8.265060111880302,8.265384994447231,8.265709541738033,8.265952952206135,8.266196362674236,8.266277499496937,8.266358971595764,8.266440108418465,8.266440108418465,8.266440108418465,8.266440108418465,8.266440108418465,8.266358971595764,8.266196362674236,8.266115225851536,8.265871815383434,8.265790678560734,8.265628404915331,8.265466131269932,8.265060111880302,8.2646544277668,8.263680450618267,8.263274766504765,8.262787610292435,8.26213851571083,8.261570222675802,8.260271698236465,8.259703405201435,8.259135447442532,8.2584860175848,8.257918059825897,8.257430903613567,8.256862945854664,8.256538063287735,8.255482949316502,8.254996128380299,8.254508972167969,8.253453858196735,8.252967037260532,8.252561353147032,8.251506239175797,8.251100219786167,8.250207379460335,8.249882832169533,8.24939601123333,8.248908855021,8.248422034084797,8.247204646468163,8.246555216610432,8.245986923575401,8.245256692171097,8.244607262313366,8.243958167731762,8.24322760105133,8.242497034370901,8.241036236286162,8.24030566960573,8.2395751029253,8.238357715308666,8.23746521025896,8.23689691722393,8.235517255961895,8.234786689281464,8.23365043848753,8.233082145452498,8.232514187693596,8.231377936899662,8.23105338960886,8.23048509657383,8.229511119425295,8.229024298489094,8.228293731808662,8.22796918451786,8.227644301950932,8.22731975466013,8.226670324802399,8.226426914334297,8.226021230220795,8.225371800363064,8.224966116249561,8.224478960037231,8.22431668639183,8.22415441274643,8.223748728632927,8.223586454987526,8.223261572420597,8.223099298775196,8.223018161952494,8.222937025129795,8.222612477838991,8.222693614661694,8.222612477838991,8.222531341016293,8.222287595272062,8.22196304798126,8.221394754946232,8.221313618123531,8.221394754946232\",\n \"PositionLatitude\": 9.5351,\n \"PositionLongitude\": 7.5034,\n \"Speed\": 0,\n \"Status\": 1,\n \"Street\": \"Unnamed Road\",\n \"TotalHectaresTilled\": 0,\n \"Town\": \"\",\n \"TractorID\": 100027,\n \"TractorModelID\": 8,\n \"TractorName\": \"JD02 (Jibril)\",\n \"_acl\": {\n \"creator\": \"591dc2511d1446a550d405dc\"\n },\n \"_kmd\": {\n \"lmt\": \"2019-04-17T08:53:03.642Z\",\n \"ect\": \"2017-05-18T15:52:06.278Z\"\n },\n \"license_plate_number\": \"ABC0000\",\n \"NeedToSendGeofenceOutNotification\": false,\n \"LastGeofenceNotificationTime\": \"2018-08-08T21:32:06.988Z\",\n \"WasInArea\": false,\n \"LastActivityId\": 97214720,\n \"UtcOffset\": 0,\n \"ActiveTimeToday\": 0,\n \"UpdatedAt\": \"2019-10-30 01:59:09\",\n \"TotalDistanceCovered\": 3,\n \"LastOdometerValue\": 6567593,\n \"IgnitionStatus\": \"On\",\n \"TrackerID\": 100027,\n \"ServiceProvider\": \"2TRACK\"\n },\n \"100111\": {\n \"_id\": \"5917ec10236217e752cfb100\",\n \"BookingRequests\": true,\n \"Characteristic\": \"105\",\n \"Country\": \"Nigeria\",\n \"Currency\": null,\n \"DailyTractorUpdates\": false,\n \"EngineHours\": 2098,\n \"LastActiveTime\": \"2019-04-02 08:57:16.0\",\n \"Latitude\": \"6.416730272744577,6.418094958714589,6.419459641028245,6.421506657641429,6.423553666023529,6.426282997724661,6.428329986890892,6.430376967817453,6.43242394050177,6.433788584377686,6.433788584377686,6.433106262897817,6.429694641757609,6.425600666171988,6.419459641028245,6.412636192904151,6.406495011500763,6.398989022755068,6.39284767720324,6.387388641459815,6.381929547490127,6.375787997236554,6.368963966238156,6.363504676116118,6.356680481889721,6.351903492049282,6.346444020801816,6.341666935996007,6.33757225664367,6.333477544790312,6.330747718842129,6.3273354161160125,6.325288023663105,6.321875684887845,6.31914579765611,6.317780848638541,6.317098372779649,6.316415896020812,6.3157334183621465,6.3157334183621465,6.315050939803728,6.31436846034567,6.3136859799880485,6.3136859799880485,6.3136859799880485,6.315050939803728,6.317098372779649,6.319828270814621,6.323923090855576,6.32938280045657,6.334842452351386,6.340984491695177,6.348491329302622,6.355315632175583,6.360775009297484,6.364869504087182,6.36964637342199,6.375105598221859,6.38124715665231,6.389435786689618,6.3969419157703795,6.402400849500083,6.406495011500763,6.409906788076152,6.410589140652801,6.410589140652801,6.409906788076152,6.409906788076152,6.4085420801841435,6.407859724868961\",\n \"Longitude\": \"6.9858304783701906,6.982397250831127,6.979650668799877,6.974157504737377,6.968664340674878,6.959737613797188,6.952184848487378,6.941198520362376,6.929525546729565,6.9199125096201906,6.9109857827425,6.900686100125314,6.891073063015937,6.881460025906562,6.871846988797188,6.863607242703438,6.856740787625313,6.850560978055001,6.845754459500313,6.84232123196125,6.840947940945625,6.839574649929999,6.837514713406563,6.837514713406563,6.83682806789875,6.837514713406563,6.838201358914375,6.838888004422188,6.840947940945625,6.84232123196125,6.844381168484688,6.847127750515938,6.850560978055001,6.854680851101874,6.859487369656563,6.862233951687813,6.865667179226875,6.868413761258126,6.872533634305,6.876653507351876,6.881460025906562,6.88626654446125,6.890386417508125,6.893819645047189,6.896566227078437,6.902059391140939,6.906179264187813,6.9116727635264406,6.917852237820625,6.924032382667065,6.930212192237377,6.935705356299877,6.93913858383894,6.941198520362376,6.942571476101875,6.943258121609688,6.943258121609688,6.943258121609688,6.943258121609688,6.942571476101875,6.941884830594063,6.93913858383894,6.935705356299877,6.930212192237377,6.924032382667065,6.917852237820625,6.909612491726875,6.901372745633125,6.894506290555,6.88626654446125\",\n \"OperatorID\": 85538,\n \"PositionLatitude\": 6.2187,\n \"PositionLongitude\": 7.0612,\n \"Speed\": 0,\n \"Status\": 1,\n \"Street\": \"Ada Road\",\n \"TotalHectaresTilled\": 0,\n \"Town\": \"Awka\",\n \"TractorID\": 100111,\n \"TractorModelID\": 7,\n \"TractorName\": \"JD/BUJ0009/NR\",\n \"_acl\": {\n \"creator\": \"574370f9d9f4789c35cb0338\"\n },\n \"_kmd\": {\n \"lmt\": \"2019-04-17T08:53:03.369Z\",\n \"ect\": \"2017-05-14T05:33:04.728Z\"\n },\n \"license_plate_number\": \"BUJ999089\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"LastGeofenceNotificationTime\": \"2019-03-31T20:27:01.866Z\",\n \"WasInArea\": false,\n \"LastActivityId\": 121376025,\n \"UtcOffset\": 0,\n \"ActiveTimeToday\": 0,\n \"UpdatedAt\": \"2019-10-30 01:59:09\",\n \"TotalDistanceCovered\": 3281,\n \"LastOdometerValue\": 17219316,\n \"IgnitionStatus\": \"On\",\n \"TrackerID\": 100111,\n \"ServiceProvider\": \"2TRACK\"\n },\n \"500022\": {\n \"_id\": \"5a8721da8452c20d3f2e9ca4\",\n \"ActiveTimeToday\": 0,\n \"BookingRequests\": true,\n \"Characteristic\": \"109,102,107\",\n \"Country\": \"Nigeria\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 3015,\n \"FixedEngineHours\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"traxi\",\n \"Heading\": 129,\n \"LastActiveTime\": \"2019-08-30 17:52:48\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"4.066367820899903,4.066367820899903,4.066367820899903,4.066367820899903,4.066367820899903,4.066367820899903,4.066367820899903,4.066367820899903,4.066367820899903,4.066367820899903,4.066367820899903,4.066367820899903,4.066367820899903,4.066367820899903,4.066367820899903,4.066367820899903,4.066367820899903,4.066367820899903,4.091582267957389,4.091582267957389,4.116795252467211,4.116795252467211,4.116795252467211,4.116795252467211,4.142008107237246,4.142008107237246,4.167219824177699,4.1924307328438015,4.217643503325779,4.24285244643447,4.268061235420033,4.29326886235796,4.318475656753626,4.343681948069075,4.368886728514719,4.368886728514719,4.368886728514719,4.394091330471018,4.394091330471018,4.394091330471018,4.394091330471018,4.394091330471018,4.394091330471018,4.394091330471018,4.419294411904374,4.444499644982109,4.469701676444838,4.469701676444838,4.5201024665394804,4.595697068276792,4.746864765154221,4.822435259779707,4.897999684539018,4.998735382415435,5.0490974423487165,5.0742773421320955,5.149812796462205,5.174988069194163,5.2505091928256755,5.326023506683554,5.351191999285435,5.426691244595952,5.4770191666837205,5.5525049260867645,5.602822179807057,5.67828975425818,5.778899682125109,5.854343995919609,5.954920104675401,6.03034278728308,6.130886806311416,6.23141421009374,6.281669377401285,6.382165451923777,6.432408281725098,6.482644146082241,6.5077600374430284,6.532874672961941,6.557988047876566,6.5831001574257435,6.5831001574257435,6.6082113298981575,6.633323225642752,6.633323225642752,6.633323225642752,6.6082113298981575,6.6082113298981575,6.5831001574257435,6.557988047876566,6.557988047876566,6.5077600374430284,6.532874672961941,6.482644146082241,6.432408281725098,6.40728865140855,6.357043352700854,6.331919693005137,6.281669377401285,6.25654239782352,6.23141421009374,6.206284818987344,6.1560197790097675,6.181151562665053,6.181151562665053,6.181151562665053,6.206284818987344,6.23141421009374,6.25654239782352,6.306795144052856,6.331919693005137,6.382165451923777,6.432408281725098,6.482644146082241,6.557988047876566,6.5831001574257435,6.6584315104046246,6.708644221977778,6.783953906082237,6.834153607276044,6.9094459274986075,6.959632713458318,7.009813801067792,7.03490232095751,7.085077950947852,7.1101623897045565,7.13524545866273,7.210486399430758,7.360933650594215,7.461201544049257,7.561449121558782,7.68672283364648,7.7618718171541845,7.862046002200682,7.937161122126721,7.987232353081259,8.062324523463067,8.112378013517171,8.212468914672069,8.312532264750889,8.487583597536805,8.63756487380022,8.762501288867588,8.887398376177813,9.01225058680247,9.162018831956166,9.33666778517616,9.486297695476749,9.586013338254432,9.735532599075231,9.835175763160805,9.93478856418252,10.03437104063878,10.133923231081123,10.183687919233675,10.283192320116935,10.382666368207852,10.482108783655264,10.581519606638585,10.705737392795712,10.805075005886437,10.929200451041279,11.053275309056952,11.152495671662322,11.226889806035341,11.326051708393827,11.375619462852763,11.44995573108001,11.499502839209365,11.549039918115973,11.598569560443893,11.648089431434572,11.796596303269443,11.870820325000041,11.994481192077005,12.093369366505888,12.192220985893153,12.291036097209378,12.340429260561713,12.439187938412717,12.537909736244224,12.636593720289701,12.735239285369303,12.784548350686954,12.83384648117367,12.907776858323592,13.006316568185197,13.08019446193074,13.154051535450945,13.252492904463516,13.301697858815594,13.375487530049247,13.44925493749982,13.473838924681644,13.473838924681644,13.498420058782019,13.54757603271809,13.522998987599335,13.572149886021817,13.596720869335238,13.596720869335238,13.596720869335238,13.621288978504717,13.621288978504717,13.621288978504717,13.621288978504717,13.621288978504717,13.64585649006412,13.64585649006412,13.670419815592389,13.670419815592389,13.670419815592389,13.670419815592389,13.670419815592389,13.670419815592389,13.670419815592389,13.670419815592389,13.670419815592389,13.670419815592389,13.670419815592389,13.670419815592389,13.670419815592389,13.670419815592389,13.64585649006412,13.621288978504717,13.621288978504717,13.596720869335238,13.572149886021817,13.54757603271809,13.498420058782019,13.44925493749982,13.42466777528767,13.326297897496731,13.301697858815594,13.301697858815594,13.277096628041315,13.227886365986507,13.203276690385138,13.17866518753667,13.17866518753667,13.154051535450945,13.129435085496594,13.104815515327061,13.08019446193074,13.03094498405588,12.9324150306755,12.907776858323592,12.88313527716836,12.858491925580662,12.858491925580662,12.83384648117367,12.83384648117367,12.83384648117367,12.83384648117367,12.83384648117367,12.83384648117367,12.83384648117367,12.83384648117367,12.83384648117367,12.83384648117367,12.83384648117367,12.83384648117367,12.809198294501705,12.809198294501705,12.809198294501705,12.83384648117367,12.83384648117367,12.858491925580662,12.858491925580662,12.907776858323592,12.9324150306755,12.95705109715591,13.03094498405588,13.055571276682466,13.08019446193074,13.08019446193074,13.129435085496594,13.129435085496594,13.154051535450945,13.227886365986507,13.227886365986507,13.252492904463516,13.301697858815594,13.326297897496731,13.326297897496731,13.375487530049247,13.400079072855988,13.42466777528767,13.498420058782019,13.522998987599335,13.522998987599335,13.54757603271809,13.54757603271809,13.54757603271809,13.572149886021817,13.621288978504717,13.621288978504717,13.64585649006412,13.694980254327392,13.694980254327392,13.694980254327392,13.694980254327392,13.694980254327392,13.694980254327392,13.694980254327392,13.694980254327392,13.670419815592389,13.64585649006412,13.596720869335238,13.522998987599335,13.400079072855988,13.326297897496731,13.252492904463516,13.203276690385138,13.17866518753667,13.154051535450945,13.055571276682466,13.006316568185197,12.95705109715591,12.858491925580662,12.858491925580662,12.83384648117367,12.759894038278532,12.685921608744225,12.587256963214545,12.513233230091206,12.439187938412717,12.414502349932137,12.414502349932137,12.365123170501125,12.340429260561713,12.266336197600232,12.24163267207841,12.216928146117564,12.167512178925849,12.118085709358837,12.118085709358837,12.118085709358837,12.093369366505888,12.093369366505888,12.06865139469177,12.043930486903744,12.043930486903744,12.043930486903744,12.043930486903744,12.043930486903744,12.043930486903744,12.043930486903744,12.043930486903744,12.043930486903744,12.043930486903744,12.043930486903744,12.043930486903744,12.043930486903744,12.043930486903744,12.043930486903744,12.043930486903744,12.043930486903744,12.019206647352625,11.994481192077005,11.96975379766745,11.96975379766745,11.96975379766745,11.945024140596013,11.945024140596013,11.870820325000041,11.84608166118564,11.771850930652493,11.722353179348946,11.623330432187894,11.57380517842431,11.474729715184344,11.400401257849298,11.350836497296573,11.301264771906126,11.17729671596212,11.078083805414813,10.805075005886437,10.60636687872947,10.482108783655264,10.382666368207852,10.357801140243035,10.258319229368988,10.183687919233675,10.133923231081123,10.03437104063878,9.959686707395484,9.959686707395484,9.884986596603603,9.860082451033458,9.785358412552718,9.735532599075231,9.710617562773113,9.660781932313583,9.660781932313583,9.635861347307328,9.586013338254432,9.486297695476749,9.386550730497495,9.286777698491663,9.211926611320898,9.137061979292124,9.112103709135798,9.037218453866148,8.987283643246608,8.78748355309646,8.537583255089253,8.337544042501039,8.212468914672069,8.162427926524234,8.062324523463067,8.03729545309986,7.937161122126721,7.736824528155176,7.661671095487833,7.611562870758931,7.586506725900056,7.511329553261893,7.360933650594215,7.235564274492326,7.03490232095751,6.934539822393719,6.884350700709736,6.783953906082237,6.758852090868564,6.6584315104046246,6.633323225642752,6.633323225642752,6.5831001574257435,6.6082113298981575,6.5831001574257435,6.532874672961941,6.557988047876566,6.432408281725098,6.40728865140855,6.306795144052856,6.25654239782352,6.23141421009374,6.1560197790097675,6.10575264934998,6.005203941076255,5.954920104675401,5.929778125151571,5.879489732500933,5.854343995919609,5.804049132723949,5.728595765950164,5.577664259209847,5.451855899920122,5.376359456346726,5.351191999285435,5.200163007924559,5.0742773421320955,4.897999684539018,4.772056078962826,4.671286327006654,4.4949021729115115,4.343681948069075,4.29326886235796,4.24285244643447,4.268061235420033,4.24285244643447,4.116795252467211,3.9655011891725267,3.940282846347171,3.8898442063713654,3.8646242534810513,3.8646242534810513,3.839403216133546,3.839403216133546,3.7889585764951232,3.8141810991639677,3.8141810991639677,3.8141810991639677,3.8141810991639677,3.8141810991639677,3.839403216133546,3.839403216133546,3.8646242534810513\",\n \"Longitude\": \"5.874641910195351,5.874641910195351,5.874641910195351,5.874641910195351,5.874641910195351,5.874641910195351,5.874641910195351,5.874641910195351,5.874641910195351,5.874641910195351,5.874641910195351,5.874641910195351,5.874641910195351,5.874641910195351,5.874641910195351,5.950477682054043,6.102148219943046,6.380210816860199,6.708831042051315,7.0121731236577025,7.264957241714002,7.366071492433548,7.467185407876968,7.416629120707512,7.517743036150932,7.568299658596516,7.64413509517908,7.694691717624664,7.745249345898628,7.795805633068085,7.846363261342049,7.947477176785469,7.998033799231053,8.073869571089745,8.124425858259201,8.200261630117893,8.225539773702621,8.250818252563477,8.250818252563477,8.301375545561314,8.326654024422169,8.301375545561314,8.301375545561314,8.301375545561314,8.326654024422169,8.326654024422169,8.326654024422169,8.377211652696133,8.377211652696133,8.402489796280861,8.478324227035046,8.50360371172428,8.554159998893738,8.579438477754595,8.62999577075243,8.655274249613285,8.705830536782742,8.680552393198012,8.731110021471979,8.756388165056705,8.806944452226164,8.8322239369154,8.857502415776253,8.933337852358818,8.958616331219673,9.00917261838913,9.085008390247822,9.186122305691242,9.236678928136826,9.31251436471939,9.337792843580246,9.413628615438938,9.464184902608395,9.540021009743215,9.565298818051815,9.641134925186632,9.666413068771362,9.716970697045326,9.742248840630054,9.792805463075638,9.843362756073475,9.893919043242931,9.919197522103786,9.995033293962479,10.045590922236443,10.07086906582117,10.121425688266754,10.171982981264591,10.222539603710175,10.247817412018774,10.323653519153595,10.374210812151432,10.45004591345787,10.525881685316563,10.576437637209892,10.626995265483856,10.702831372618673,10.778666138648985,10.879779718816279,10.955615490674974,11.082008220255375,11.183122135698795,11.233678422868252,11.334792338311672,11.385349966585636,11.46118439733982,11.511742025613785,11.537020169198513,11.562298648059368,11.61285627633333,11.663412898778915,11.688691042363642,11.764526478946209,11.789804622530935,11.8150844424963,11.8150844424963,11.865640729665756,11.840362250804901,11.865640729665756,11.890918873250484,11.890918873250484,11.916198022663593,11.916198022663593,11.916198022663593,11.966754645109177,12.017310932278631,12.042590752243996,12.067868895828724,12.093146704137325,12.118424847722054,12.168982475996016,12.2195390984416,12.270096726715565,12.371210977435112,12.472324557602406,12.522881180047987,12.623995430767538,12.725109010934831,12.851501405239105,12.952613979578018,13.079007379710674,13.20540077984333,13.306513689458368,13.407626934349537,13.508741855621336,13.609854765236378,13.68569154292345,13.736248165369036,13.761526308953762,13.837360739707949,13.86264156550169,13.88791970908642,13.938475996255873,13.938475996255873,13.963754139840603,13.989032618701458,14.039588905870914,14.090147539973257,14.115426018834114,14.140704162418842,14.191260449588299,14.241816736757757,14.26709521561861,14.342932328581812,14.368209801614285,14.393488280475141,14.393488280475141,14.444044567644596,14.444044567644596,14.444044567644596,14.444044567644596,14.444044567644596,14.444044567644596,14.444044567644596,14.444044567644596,14.444044567644596,14.444044567644596,14.418766424059866,14.418766424059866,14.368209801614285,14.342932328581812,14.342932328581812,14.292373359203339,14.241816736757757,14.216538593173027,14.191260449588299,14.140704162418842,14.064866714179516,14.014310762286184,13.938475996255873,13.913198187947273,13.86264156550169,13.837360739707949,13.812082596123219,13.736248165369036,13.710969686508177,13.635135255753994,13.609854765236378,13.559298142790793,13.534020334482195,13.508741855621336,13.432907089591026,13.331791833043098,13.230679258704185,13.154842481017113,13.053729236125946,12.952613979578018,12.876779548823832,12.775665633380413,12.750387154519558,12.750387154519558,12.725109010934831,12.699831202626227,12.674551382660866,12.649273239076136,12.59871695190668,12.548159323632717,12.497602701187134,12.447045408189295,12.34593115746975,12.320653349161146,12.244817577302458,12.168982475996016,12.14370433241129,12.067868895828724,12.017310932278631,11.941476501524448,11.890918873250484,11.739248670637608,11.663412898778915,11.562298648059368,11.334792338311672,11.183122135698795,11.05672974139452,10.930337347090244,10.728109516203403,10.601717457175255,10.525881685316563,10.4753240570426,10.424767434597015,10.374210812151432,10.323653519153595,10.247817412018774,10.222539603710175,10.07086906582117,9.995033293962479,9.919197522103786,9.843362756073475,9.792805463075638,9.716970697045326,9.716970697045326,9.641134925186632,9.59057729691267,9.514742530882359,9.38835047185421,9.28723655641079,9.160844162106514,8.983894474804401,8.882780224084854,8.806944452226164,8.705830536782742,8.554159998893738,8.402489796280861,8.351932168006897,8.276097737252712,8.200261630117893,8.174983486533165,8.124425858259201,8.073869571089745,7.998033799231053,7.972755655646325,7.922197692096233,7.896919548511505,7.846363261342049,7.795805633068085,7.770527489483357,7.694691717624664,7.618856951594353,7.467185407876968,7.416629120707512,7.315514869987964,7.189122810959817,7.088008895516395,6.986894980072974,6.8605025857687,6.759388670325279,6.658274419605732,6.5571605041623116,6.481324732303619,6.430768445134163,6.380210816860199,6.3296541944146165,6.304376050829888,6.279097907245158,6.203262135386466,6.152704507112504,6.127426363527774,6.001033969223499,5.77352799475193,5.647135600447655,5.2679577469825745,5.0910090655088425,4.989895150065422,4.91405937820673,4.888781234622002,4.838224612176419,4.8129454627633095,4.762389175593853,4.711831212043762,4.610717296600341,4.509604722261429,4.43376861512661,4.408490471541882,4.357932843267918,4.332654699683189,4.231540784239769,4.1809844970703125,4.1051483899354935,4.0545907616615295,4.004034474492073,3.978756330907345,3.978756330907345,3.9534781873226166,3.9281987026333804,3.8270847871899605,3.751250021159649,3.7006927281618114,3.7006927281618114,3.7006927281618114,3.6754142493009567,3.6754142493009567,3.650136105716228,3.650136105716228,3.650136105716228,3.6248579621315002,3.574299998581409,3.5995784774422646,3.5995784774422646,3.5995784774422646,3.5995784774422646,3.549022190272808,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.574299998581409,3.5995784774422646,3.650136105716228,3.7006927281618114,3.776528164744377,3.8270847871899605,3.8270847871899605,3.8523639366030693,3.8523639366030693,3.8523639366030693,3.8523639366030693,3.8523639366030693,3.8523639366030693,3.8523639366030693,3.8523639366030693,3.8523639366030693,3.8523639366030693,3.8523639366030693,3.8523639366030693,3.8523639366030693,3.8523639366030693,3.8270847871899605,3.8018066436052322,3.7259705364704128,3.6248579621315002,3.574299998581409,3.498464561998844,3.4479079395532604,3.422629795968533,3.2962377369403835,3.2709582522511487,3.1445658579468727,2.942338027060032,2.8159456327557564,2.7401112020015717,2.714831717312336,2.6389966160058975,2.6389966160058975,2.563161179423332,2.4873260781168938,2.3862121626734734,2.3862121626734734,2.335655204951763,2.335655204951763,2.335655204951763,2.3103763908147816,2.285098247230053,2.285098247230053,2.259819433093071,2.259819433093071,2.2092628106474876,2.234541289508343,2.234541289508343,2.2092628106474876,2.2092628106474876,2.2092628106474876,2.2092628106474876,2.2092628106474876,2.2092628106474876,2.2092628106474876,2.2092628106474876,2.2092628106474876,2.2092628106474876,2.234541289508343,2.285098247230053,2.3103763908147816,2.3862121626734734,2.4114903062582016,2.462047263979912,2.4873260781168938,2.563161179423332,2.6137184724211693,2.8159456327557564,3.018173798918724,3.2962377369403835,3.4479079395532604,3.549022190272808,3.8018066436052322,4.004034474492073,4.130426868796349,4.2820970714092255,4.484325237572193,4.737110696732998,5.01517329365015,5.29323723167181,5.369071662425995,5.444907769560814,5.470185913145542,5.546021685004234,5.697692222893238,5.77352799475193,5.849363766610622,5.89992005378008,6.076870076358319,6.253818422555924,6.304376050829888,6.430768445134163,6.5571605041623116,6.885780729353428,7.0121731236577025,7.189122810959817,7.239679098129273,7.34079334884882,7.366071492433548,7.391350977122784\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": 8.819431,\n \"PositionLongitude\": 6.783216,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 2.75,\n \"Status\": 0,\n \"Street\": \"Zui\",\n \"TotalDistanceCovered\": 13086,\n \"TotalHectaresTilled\": null,\n \"Town\": \"FCT\",\n \"TractorID\": 500022,\n \"TractorModelID\": 5,\n \"TractorName\": \"TRAXI/TRCIH0004-666\",\n \"UpdatedAt\": \"2019-10-30 16:09:32\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"license_plate_number\": \"YAB666YR\",\n \"_acl\": {\n \"creator\": \"593aa855ecdebb2558589e6f\"\n },\n \"_kmd\": {\n \"lmt\": \"2019-04-13T23:01:24.273Z\",\n \"ect\": \"2018-02-16T18:24:26.131Z\"\n },\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 1,\n \"AssetState\": \"On\",\n \"FuelLevelVoltage\": 0,\n \"LastMaintenanceNotificationEngineHours\": 3000\n },\n \"500032\": {\n \"_id\": \"5a8727268452c20d3f2ea9c8\",\n \"ActiveTimeToday\": 0,\n \"BookingRequests\": true,\n \"Characteristic\": \"109,102,107\",\n \"Country\": \"Nigeria\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 2398,\n \"FixedEngineHours\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"traxi\",\n \"Heading\": 13,\n \"LastActiveTime\": \"2019-09-04 13:18:36\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"4.2687901100746215,4.2687901100746215,4.2687901100746215,4.2687901100746215,4.2687901100746215,4.2687901100746215,4.2687901100746215,4.2687901100746215,4.2687901100746215,4.2687901100746215,4.2687901100746215,4.2687901100746215,4.2687901100746215,4.2687901100746215,4.2687901100746215,4.2687901100746215,4.2687901100746215,4.335264231418505,4.4848075721800456,4.617707354240458,4.750584247323218,4.83361980769208,4.866830925281535,4.866830925281535,4.90004006976798,4.933248900296566,4.983057190641745,5.049462143096121,5.099262902816422,5.165656231689587,5.198849792888859,5.248639187811516,5.315016410944216,5.348203680854284,5.414570474750773,5.464340376599979,5.514107811749314,5.58045589237263,5.6467981352465255,5.713131115607682,5.746294730498299,5.8126178224669625,5.8623536005487304,5.9120852796607295,5.97838867100303,6.061254351463469,6.127539542910127,6.210382196537419,6.276648744095952,6.342905196883585,6.409154799828534,6.44227554750228,6.4919524457913145,6.525069434190528,6.574738143958488,6.591293501711899,6.624402224639826,6.6409559201363315,6.674062638331241,6.690614659258047,6.707165786299516,6.756816454411616,6.773365657222768,6.78991395939704,6.78991395939704,6.78991395939704,6.78991395939704,6.78991395939704,6.78991395939704,6.756816454411616,6.773365657222768,6.723716684067837,6.707165786299516,6.674062638331241,6.6575103908783335,6.6409559201363315,6.6409559201363315,6.607848306739447,6.591293501711899,6.574738143958488,6.5416264419158905,6.525069434190528,6.508512212311066,6.4919524457913145,6.4919524457913145,6.458834944798971,6.458834944798971,6.458834944798971,6.4257152766139205,6.44227554750228,6.44227554750228,6.44227554750228,6.44227554750228,6.44227554750228,6.44227554750228,6.44227554750228,6.44227554750228,6.44227554750228,6.44227554750228,6.458834944798971,6.458834944798971,6.4919524457913145,6.525069434190528,6.574738143958488,6.591293501711899,6.6409559201363315,6.6575103908783335,6.674062638331241,6.707165786299516,6.723716684067837,6.740266685249421,6.773365657222768,6.823010852643877,6.872649237372655,6.9222827722018,7.004994933410676,7.087692425783477,7.170373749057532,7.269572975553948,7.3522207260618195,7.434854759173979,7.5174719134191,7.600074679380027,7.666145926950505,7.732205259416212,7.781742811982422,7.831276505080483,7.864294479847882,7.897309826646708,7.946827729856297,7.9963416518120205,8.06234842474718,8.111847935196602,8.14484322954603,8.194330903250732,8.227319379466197,8.27679876650278,8.309780357493315,8.359247375870257,8.375735210525832,8.408709777876282,8.458164542151447,8.491130750630518,8.557056320137601,8.606491604000174,8.655920764532913,8.721817644942448,8.771231272831654,8.853574458452906,8.902970805684367,8.968823323933913,9.018204051647752,9.067578025726272,9.100490128425236,9.133400527164586,9.166306563042184,9.215660723657473,9.248559116619184,9.314347657695969,9.347236792046488,9.396565491093284,9.42944683743381,9.495200780130075,9.560942103953186,9.643100885309906,9.692386889104572,9.725240315075085,9.774513571685771,9.80735890735963,9.873039474482274,9.922290398316603,9.971534908173917,10.037182564918076,10.102816581168469,10.168437533735261,10.217643500944696,10.283240484160771,10.348824174576498,10.414393829397573,10.447173820948711,10.529107826041066,10.561875011537044,10.627399879646665,10.692910360361644,10.742034275171116,10.791149542382081,10.823889147367424,10.840257115410038,10.856624517392339,10.889357288574436,10.92208514587952,10.938448051712347,10.971171481984758,11.003890960456081,11.036607135118189,11.05296369235449,11.069318679444784,11.11838045881014,11.134732442905309,11.151083508526,11.200131510633906,11.216478560669803,11.249171200302369,11.281858814889537,11.31454369598275,11.347224518143193,11.379901928647575,11.412574931242126,11.445245159005829,11.461578202191543,11.49424178394683,11.510571991400829,11.559558235892862,11.59221141403001,11.62485979012766,11.673825996769486,11.739100381297655,11.836982965296325,11.902218574703115,11.934830187078557,12.032643085914629,12.097831498366503,12.16300401733171,12.211872600379237,12.244447520954683,12.293300725604716,12.309583658017441,12.342145837443345,12.42353322388193,12.472353968673936,12.537433869727534,12.60249733624111,12.667543961370136,12.732573992773077,12.797587677880378,12.878830480917648,12.960047280024217,13.025001983825504,13.089939331142853,13.15485989626265,13.219761968149893,13.28464807957293,13.333301366353014,13.430577559395724,13.47920137804401,13.511611874038342,13.511611874038342,13.544017639231622,13.560218541060982,13.560218541060982,13.5764193158062,13.5764193158062,13.5764193158062,13.527815307840555,13.511611874038342,13.47920137804401,13.4629946443139,13.446787139144199,13.398157072528397,13.349516846018847,13.333301366353014,13.317084798956602,13.300867471338274,13.252207676595365,13.252207676595365,13.235986015317076,13.235986015317076,13.235986015317076,13.235986015317076,13.219761968149893,13.219761968149893,13.203538147366382,13.187313248717256,13.15485989626265,13.138630791875206,13.122401267455745,13.106170997822337,13.073705941999151,13.041237593650044,13.008764983012512,12.992526592381154,12.976287466530499,12.960047280024217,12.943806360854687,12.943806360854687,12.943806360854687,12.943806360854687,12.943806360854687,12.943806360854687,12.943806360854687,12.943806360854687,12.943806360854687,12.976287466530499,12.960047280024217,12.960047280024217,12.960047280024217,12.960047280024217,12.943806360854687,12.927563403209303,12.927563403209303,12.911320042129908,12.895075952160267,12.895075952160267,12.895075952160267,12.878830480917648,12.86258330271312,12.86258330271312,12.86258330271312,12.86258330271312,12.86258330271312,12.86258330271312,12.86258330271312,12.86258330271312,12.86258330271312,12.86258330271312,12.86258330271312,12.86258330271312,12.846336053078463,12.846336053078463,12.830087752726728,12.830087752726728,12.830087752726728,12.830087752726728,12.830087752726728,12.830087752726728,12.830087752726728,12.86258330271312,12.878830480917648,12.927563403209303,12.943806360854687,12.960047280024217,13.025001983825504,13.05747246453101,13.15485989626265,13.171086946975642,13.203538147366382,13.219761968149893,13.219761968149893,13.219761968149893,13.219761968149893,13.219761968149893,13.219761968149893,13.219761968149893,13.235986015317076,13.268428256321824,13.268428256321824,13.268428256321824,13.300867471338274,13.349516846018847,13.430577559395724,13.430577559395724,13.430577559395724,13.446787139144199,13.4629946443139,13.4629946443139,13.511611874038342,13.544017639231622,13.5764193158062,13.625012717315217,13.641208408622866,13.641208408622866,13.641208408622866,13.641208408622866,13.641208408622866,13.625012717315217,13.625012717315217,13.592618332619892,13.5764193158062,13.560218541060982,13.544017639231622,13.544017639231622,13.527815307840555,13.47920137804401,13.446787139144199,13.414367536738546,13.398157072528397,13.398157072528397,13.349516846018847,13.300867471338274,13.252207676595365,13.203538147366382,13.122401267455745,13.106170997822337,13.05747246453101,13.008764983012512,12.960047280024217,12.895075952160267,12.797587677880378,12.71631739082969,12.71631739082969,12.651283203369246,12.58623309651763,12.521165513911008,12.488625398475532,12.472353968673936,12.42353322388193,12.390981839716616,12.358425409541198,12.325865253184869,12.277017112355688,12.277017112355688,12.228160890051756,12.228160890051756,12.195584291619102,12.179294654288327,12.16300401733171,12.130419421774056,12.114125793455607,12.032643085914629,11.934830187078557,11.902218574703115,11.836982965296325,11.804359644687404,11.739100381297655,11.64118270796345,11.59221141403001,11.59221141403001,11.559558235892862,11.526902236615289,11.445245159005829,11.39623906372313,11.298202543021189,11.183783208133654,11.151083508526,11.069318679444784,11.003890960456081,10.90572133824578,10.840257115410038,10.758406700670102,10.72566063264479,10.676534062620714,10.643778491464936,10.561875011537044,10.529107826041066,10.496336497853026,10.447173820948711,10.381611050176568,10.283240484160771,10.201242136350483,10.086409659602229,9.987947983097902,9.856619979626732,9.741665652885244,9.675959464546242,9.462325711595172,9.347236792046488,9.314347657695969,9.215660723657473,9.1169465345957,9.051120676610005,8.902970805684367,8.771231272831654,8.705344759906424,8.557056320137601,8.458164542151447,8.27679876650278,8.210825649859204,8.128345755650493,8.078848272599062,7.979838119863651,7.946827729856297,7.913816345156139,7.864294479847882,7.831276505080483,7.732205259416212,7.666145926950505,7.533994926034354,7.467903429697705,7.302633977009067,7.219975084173557,7.054614467932054,7.004994933410676,6.856103794135425,6.78991395939704,6.756816454411616,6.707165786299516,6.674062638331241,6.674062638331241,6.6575103908783335,6.6409559201363315,6.6409559201363315,6.624402224639826,6.624402224639826,6.624402224639826,6.624402224639826,6.607848306739447,6.574738143958488,6.591293501711899,6.558182567925173,6.5416264419158905,6.409154799828534,6.2435173516444475,6.1772466227039295,6.028109529881145,5.961813823032585,5.796038028815892,5.679965580189754,5.630212198677843,5.547282784803422,5.514107811749314,5.447750644452044,5.414570474750773,5.381387816094681,5.364796140984274,5.331609435580017,5.331609435580017,5.348203680854284,5.364796140984274,5.381387816094681,5.414570474750773,5.431160454189454,5.514107811749314,5.547282784803422,5.613627123442249,5.630212198677843,5.630212198677843,5.597041909997011,5.58045589237263,5.514107811749314,5.480929649255099,5.414570474750773,5.381387816094681,5.281828354153114,5.248639187811516,5.165656231689587,5.099262902816422,4.949852192226463,4.883435536064893,4.767193367904293,4.750584247323218,4.684149792364522,4.66754002179126,4.567872856830074,4.551260697644191,4.4515770653785705,4.368498269602158,4.335264231418505,4.218932157137638,4.185691629921543,4.1358266913890205,4.036088774876952,4.0194647009816284,4.036088774876952,4.036088774876952,4.036088774876952,4.0194647009816284,4.0194647009816284,4.002840288148498,4.002840288148498,4.0194647009816284,4.0194647009816284,4.052713846192952,4.052713846192952,4.085959952283313,4.1358266913890205,4.152448019326622,4.169068997204181,4.169068997204181,4.202311903462621,4.202311903462621,4.235552055173805,4.2687901100746215,4.285408932864651,4.302027394453663,4.335264231418505,4.351881266732363\",\n \"Longitude\": \"8.772325515747072,8.772325515747072,8.772325515747072,8.772325515747072,8.772325515747072,8.772325515747072,8.772325515747072,8.772325515747072,8.772325515747072,8.772325515747072,8.772325515747072,8.772325515747072,8.772325515747072,8.772325515747072,8.772325515747072,8.772325515747072,8.772325515747072,8.788990750908852,8.805655650794506,8.822320885956287,8.822320885956287,8.838985785841942,8.855651691555977,8.855651691555977,8.855651691555977,8.888981826603413,8.888981826603413,8.905647061765194,8.922312967479229,8.938977867364883,8.955643102526665,8.955643102526665,8.9889732375741,8.9889732375741,9.005638808012009,9.022304043173792,9.055634178221226,9.088964983820915,9.105630218982697,9.138961024582386,9.172291159629822,9.188956394791603,9.238952435553074,9.288948476314545,9.32227861136198,9.388939552009106,9.438935592770576,9.505596533417702,9.572256803512573,9.622252844274044,9.688914120197296,9.73890982568264,9.822236001491547,9.888897277414799,9.972223453223705,10.03888439387083,10.088880434632301,10.122210569679737,10.172206610441208,10.205536745488642,10.255532786250116,10.272197686135769,10.322193726897238,10.355523861944675,10.372189097106457,10.422184802591799,10.438850037753584,10.455515943467617,10.472180843353271,10.505510978400707,10.538842119276524,10.572172254323958,10.60550305992365,10.655498430132866,10.688829235732555,10.755490511655807,10.822151452302933,10.855481587350367,10.90547762811184,10.95547266304493,11.022133938968182,11.055464744567871,11.105460785329342,11.13879092037678,11.188786961138248,11.205451861023901,11.238781996071339,11.28877803683281,11.322108171880243,11.372104212641716,11.405435353517532,11.438765153288841,11.472096294164658,11.48876119405031,11.505426429212095,11.53875656425953,11.53875656425953,11.555422469973564,11.588752605021,11.605417504906656,11.605417504906656,11.638748310506344,11.672078780829908,11.688744351267815,11.705409586429596,11.722074486315252,11.755404621362686,11.73873972147703,11.772070862352848,11.788735762238504,11.822065897285938,11.855396702885628,11.855396702885628,11.88872717320919,11.88872717320919,11.905392073094845,11.905392073094845,11.938723213970661,11.955387778580187,12.00538381934166,12.02204905450344,12.05537986010313,12.088710330426693,12.138706371188164,12.172036170959473,12.238697446882725,12.272028252482412,12.322023622691631,12.388684563338758,12.438680604100226,12.488675974309444,12.538672015070915,12.60533295571804,12.63866376131773,12.688659131526945,12.721989937126637,12.73865517228842,12.771984972059727,12.805316112935541,12.821981012821198,12.838646247982979,12.855312153697012,12.88864228874445,12.921972423791887,12.955303564667702,13.005299270153046,13.038629405200483,13.08862544596195,13.121955916285513,13.188616521656513,13.22194766253233,13.271943032741547,13.305273838341236,13.338603638112545,13.371935114264488,13.405264914035797,13.455260954797268,13.488591089844704,13.55525303632021,13.6052480712533,13.655243441462517,13.688573576509953,13.738570287823679,13.755235522985457,13.805230557918547,13.821895793080332,13.855227269232275,13.871892504394053,13.90522263944149,13.888557739555836,13.888557739555836,13.921887874603271,13.90522263944149,13.921887874603271,13.921887874603271,13.95521767437458,13.95521767437458,13.971882909536362,13.988549821078777,14.021879620850086,14.021879620850086,14.038544856011868,14.055209755897522,14.055209755897522,14.071874991059303,14.088540226221085,14.121870025992393,14.121870025992393,14.121870025992393,14.13853693753481,14.171867072582247,14.1885319724679,14.205196872353556,14.25519224256277,14.271857142448424,14.288524053990841,14.305188953876495,14.338519424200058,14.321854189038277,14.35518432408571,14.371849223971367,14.40517969429493,14.438511505722998,14.471840970218182,14.488506205379963,14.521836340427399,14.555166810750963,14.555166810750963,14.571833051741123,14.571833051741123,14.571833051741123,14.571833051741123,14.571833051741123,14.571833051741123,14.571833051741123,14.571833051741123,14.571833051741123,14.53850157558918,14.521836340427399,14.505171440541746,14.488506205379963,14.471840970218182,14.455176405608656,14.438511505722998,14.421844594180584,14.40517969429493,14.388514459133148,14.371849223971367,14.338519424200058,14.321854189038277,14.288524053990841,14.271857142448424,14.221862107515333,14.205196872353556,14.155201837420462,14.121870025992393,14.071874991059303,14.038544856011868,13.988549821078777,13.921887874603271,13.888557739555836,13.838561028242111,13.788565658032894,13.671908676624298,13.57191827148199,13.488591089844704,13.455260954797268,13.438595049083233,13.438595049083233,13.405264914035797,13.371935114264488,13.355268873274326,13.271943032741547,13.155286721885204,13.038629405200483,12.98863336443901,12.921972423791887,12.805316112935541,12.671993896365167,12.538672015070915,12.45534583926201,12.372019663453102,12.272028252482412,12.15537127107382,12.105375230312346,12.05537986010313,11.988719254732134,11.955387778580187,11.905392073094845,11.872061938047409,11.838731802999973,11.805400662124157,11.772070862352848,11.722074486315252,11.688744351267815,11.62208341062069,11.588752605021,11.522091329097748,11.422100253403187,11.372104212641716,11.30544327199459,11.238781996071339,11.188786961138248,11.122126020491123,11.072129979729652,10.95547266304493,10.838816687464714,10.705494470894337,10.60550305992365,10.555507019162178,10.505510978400707,10.455515943467617,10.405519902706146,10.322193726897238,10.222201645374298,10.172206610441208,10.105545334517956,10.022219493985176,9.922227412462234,9.888897277414799,9.838901236653328,9.788905195891857,9.772239960730074,9.722244925796986,9.588922709226608,9.472265727818012,9.338943511247635,9.305613376200197,9.255617335438728,9.238952435553074,9.205621294677258,9.188956394791603,9.155626259744167,9.122295118868351,9.07230008393526,9.022304043173792,8.9889732375741,8.905647061765194,8.838985785841942,8.68899866938591,8.589007593691349,8.505681417882442,8.489016182720661,8.45568537712097,8.43902014195919,8.389024101197721,8.372359201312065,8.322363160550594,8.239036984741688,8.189041949808598,8.155710808932781,8.089049868285656,8.039053827524185,7.8890667110681525,7.8557365760207185,7.8224054351449,7.7890753000974655,7.72241435945034,7.655753083527088,7.639088183641435,7.572426907718181,7.439105026423932,7.405774891376495,7.339113615453244,7.272452674806118,7.155795693397522,7.08913441747427,6.922482401132584,6.789160184562207,6.639173403382302,6.622507832944393,6.58917736262083,6.572512127459048,6.555846892297269,6.522516086697578,6.455855481326581,6.405859440565109,6.322533264756203,6.189211383461952,6.0892196372151375,6.039223931729793,5.905901715159416,5.839241445064545,5.772580169141293,5.6059274822473535,5.522601306438446,5.405944660305977,5.372614189982415,5.3226181492209435,5.305952914059162,5.272622443735599,5.23929163813591,5.189296267926692,5.1726310327649125,5.1059697568416595,5.02264391630888,4.955982640385628,4.822660759091377,4.672673307359219,4.606012701988221,4.456025585532188,4.389364309608936,4.3393682688474655,4.289372563362122,4.222711622714996,4.206046722829342,4.172715917229652,4.106054976582527,4.056059271097183,4.056059271097183,4.006063230335712,3.9893983304500584,3.9727327600121494,3.9727327600121494,3.9727327600121494,3.9727327600121494,3.956067524850369,3.939402289688587,3.906071819365025,3.8394112139940266,3.822745643556118,3.822745643556118,3.822745643556118,3.8060804083943367,3.8060804083943367,3.789415173232555,3.789415173232555,3.789415173232555,3.7727499380707745,3.7394194677472115,3.7060886621475215,3.6894237622618675,3.6894237622618675,3.656092956662178,3.6227628216147423,3.6394280567765236,3.6394280567765236,3.6227628216147423,3.6227628216147423,3.6227628216147423,3.6227628216147423,3.6227628216147423,3.6227628216147423,3.6227628216147423,3.6227628216147423,3.6394280567765236,3.656092956662178,3.672758191823959,3.6894237622618675,3.7060886621475215,3.7060886621475215,3.7060886621475215,3.7394194677472115,3.7727499380707745,3.789415173232555,3.822745643556118,3.8394112139940266,3.8394112139940266,3.8394112139940266,3.8394112139940266,3.789415173232555,3.7394194677472115,3.6894237622618675,3.656092956662178,3.5227714106440544,3.439444899559021,3.38944885879755,3.3394534885883336,3.2894574478268623,3.2394620776176453,3.1394699960947037,3.0728090554475784,3.0394785851240163,2.9728176444768906,2.956153079867363,2.9061570391058917,2.889491803944111,2.8561609983444214,2.83949576318264,2.789499722421169,2.772834822535515,2.756169587373733,2.722839117050171,2.722839117050171,2.6895083114504814,2.6561781764030457,2.6228470355272293,2.6228470355272293,2.556186094880104,2.5228562951087947,2.4895254895091057,2.4395301192998886,2.356203943490982,2.3228728026151657,2.28954266756773,2.2562118619680405,2.239546626806259,2.222881391644478,2.2062158212065697,2.2062158212065697,2.2062158212065697,2.2062158212065697,2.2062158212065697,2.2062158212065697,2.2062158212065697,2.222881391644478,2.2562118619680405,2.2728774324059486,2.28954266756773,2.3062079027295113,2.389534078538418,2.4895254895091057,2.5395215302705765,2.5895175710320473,2.6228470355272293,2.739504352211952,2.83949576318264,2.9061570391058917,3.00614845007658,3.0728090554475784,3.306122682988644,3.3727839589118958,3.439444899559021,3.489440605044365,3.6394280567765236,3.672758191823959,3.7227542325854306,3.7394194677472115,3.789415173232555,3.8394112139940266,3.8560757786035538,3.956067524850369,4.02272880077362,4.206046722829342,4.372698739171028,4.422694779932499,4.639343172311783,4.706004112958908,4.789330288767814,4.805995523929596,4.905986934900284,4.939317405223846,5.0059786811470985,5.02264391630888,5.089304521679878,5.1059697568416595,5.23929163813591,5.28928767889738,5.38927908986807,5.4392751306295395,5.539266541600227,5.589262582361697,5.789245404303075,5.889236815273762,6.155880577862264,6.339198499917984,6.389194540679455,6.655838303267956,6.739164479076862,7.055804282426834,7.37244375050068,7.455769926309586,7.539096772670747,7.605758048593999,7.655753083527088,7.839071340858936,7.872401475906372,8.022388592362404,8.089049868285656,8.272367790341377,8.30569826066494,8.489016182720661,8.539011552929878,8.7223294749856,8.805655650794506,8.822320885956287,8.855651691555977,8.872316926717758,8.905647061765194,8.922312967479229,8.955643102526665,8.97230800241232,8.97230800241232,8.97230800241232,8.9889732375741,9.005638808012009\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": 8.426911,\n \"PositionLongitude\": 7.602061,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 0.16,\n \"Status\": 0,\n \"Street\": \"Roguwa\",\n \"TotalDistanceCovered\": 6205,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Nassarawa\",\n \"TractorID\": 500032,\n \"TractorModelID\": 5,\n \"TractorName\": \"TRAXI/TRCIH0003-672\",\n \"UpdatedAt\": \"2019-10-30 16:10:12\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"license_plate_number\": \"YAB672YR\",\n \"_acl\": {\n \"creator\": \"593aa855ecdebb2558589e6f\"\n },\n \"_kmd\": {\n \"lmt\": \"2019-04-13T23:01:24.157Z\",\n \"ect\": \"2018-02-16T18:47:02.167Z\"\n },\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"FuelLevelVoltage\": 0\n },\n \"500034\": {\n \"_id\": \"5ab2ae84ddf9f631257eae43\",\n \"ActiveTimeToday\": 0,\n \"BookingRequests\": true,\n \"Characteristic\": \"109,102,107\",\n \"Country\": \"Nigeria\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 593,\n \"FixedEngineHours\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"TRAXI\",\n \"LastActiveTime\": \"2019-03-08 15:13:49\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"11.180987136993807,11.183553300467008,11.18509292186268,11.184066398871481,11.182526772022074,11.179447493787775,11.17636818284666,11.1727753928078,11.168155978956994,11.161483947250916,11.154297954223564,11.147112112434924,11.138899410383425,11.127606319890415,11.11579990254365,11.101425812756215,11.087051015351573,11.07318913399299,11.060353229665571,11.048544096069717,11.03570711301508,11.02235618723707,11.00900465545443,10.995652518364663,10.984354235852372,10.974596250274091,10.966892193870766,10.959701757607776,10.953538152314463,10.949429120545032,10.945833876714026,10.944806515100312,10.945320031763957,10.948915611004711,10.954051983005595,10.962783347530843,10.973055520888458,10.98743556869216,11.004382982208503,11.02235618723707,11.040841973584598,11.060353229665571,11.079350234024677,11.097832097458582,11.11579990254365,11.131712859213359,11.14813876612271,11.160970479967583,11.171235706003845,11.176881293968759,11.176881293968759,11.174315071439667,11.1727753928078\",\n \"Longitude\": \"7.859328053891658,7.870837412774563,7.884439565241336,7.897518351674081,7.91059747338295,7.925769053399564,7.937278412282468,7.947741709649563,7.958728037774563,7.969714365899563,7.979654297232628,7.988548167049886,7.997964732348918,8.00738163292408,8.014706075191496,8.020983785390856,8.024646006524563,8.027261830866337,8.02935428917408,8.02935428917408,8.028307892382143,8.025692403316498,8.021507151424883,8.016275502741337,8.008428029716015,8.000057525932789,7.990640625357629,7.978607900440693,7.966575510799885,7.955065816640854,7.940417602658271,7.925769053399564,7.911643870174886,7.896995320916176,7.884439565241336,7.871360443532467,7.859851084649562,7.848864756524564,7.838924825191498,7.830554321408272,7.823753245174885,7.817998565733433,7.815382741391659,7.816428802907467,7.820614390075208,7.827415131032468,7.835785970091819,7.847818359732628,7.863513305783271,7.883393168449402,7.898041717708112,7.905889190733432,7.907981649041175\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"PositionLatitude\": 11.034167,\n \"PositionLongitude\": 7.915306,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": null,\n \"Status\": 0,\n \"Street\": \"Maigana\",\n \"TotalHectaresTilled\": null,\n \"Town\": \"Kaduna\",\n \"TractorID\": 500034,\n \"TractorModelID\": 5,\n \"TractorName\": \"TRAXI/TRCIH0001-681\",\n \"UpdatedAt\": \"2019-10-30 16:10:18\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"license_plate_number\": \"YAB681YR\",\n \"_acl\": {\n \"creator\": \"593aa855ecdebb2558589e6f\"\n },\n \"TotalDistanceCovered\": 3323,\n \"Heading\": null,\n \"FuelRawValue\": null,\n \"IgnitionStatus\": null,\n \"AssetState\": null,\n \"FuelLevelVoltage\": 0,\n \"_kmd\": {\n \"lmt\": \"2019-05-05T21:43:10.622Z\",\n \"ect\": \"2018-03-21T19:12:04.923Z\"\n },\n \"OperatorID\": 0\n },\n \"500042\": {\n \"_id\": \"5a87252ac27e511b8242c4ec\",\n \"ActiveTimeToday\": 0,\n \"BookingRequests\": true,\n \"Characteristic\": \"109,102,107\",\n \"Country\": \"Nigeria\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 1900,\n \"FixedEngineHours\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"traxi\",\n \"Heading\": null,\n \"LastActiveTime\": \"2019-03-27 20:50:53\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.70507745560498,13.657103907909853,13.545128807666972,13.449107222483601,13.3690603593313,13.337035140108767,13.337035140108767,13.337035140108767,13.321020448932176,13.321020448932176,13.321020448932176,13.321020448932176,13.321020448932176,13.321020448932176,13.321020448932176,13.321020448932176,13.321020448932176,13.321020448932176,13.321020448932176,13.321020448932176,13.321020448932176,13.321020448932176,13.321020448932176,13.321020448932176,13.321020448932176,13.337035140108767,13.337035140108767,13.3690603593313,13.3690603593313,13.3690603593313,13.3690603593313,13.3690603593313,13.385072842159227,13.40108262945514,13.40108262945514,13.433100310005647,13.417092003242736,13.417092003242736,13.449107222483601,13.433100310005647,13.433100310005647,13.433100310005647,13.433100310005647,13.433100310005647,13.433100310005647,13.433100310005647,13.433100310005647,13.449107222483601,13.433100310005647,13.433100310005647,13.417092003242736,13.385072842159227,13.385072842159227,13.3690603593313,13.3690603593313,13.337035140108767,13.321020448932176,13.305004045256396,13.272969694135906,13.25695109658746,13.25695109658746,13.25695109658746,13.240931117501427,13.22490943161187,13.176840346198116,13.160814782285332,13.128761490714291,13.112733112487165,13.112733112487165,13.096703036593276,13.096703036593276,13.080672896974267,13.064641715215155,13.048609492503267,13.032575903386288,13.032575903386288,13.032575903386288,13.016540622327698,13.016540622327698,13.016540622327698,13.016540622327698,13.016540622327698,13.016540622327698,13.016540622327698,13.016540622327698,13.016540622327698,13.016540622327698,13.016540622327698,13.016540622327698,13.016540622327698,13.016540622327698,13.016540622327698,13.000505283801154,13.000505283801154,13.000505283801154,13.000505283801154,13.000505283801154,13.000505283801154,13.000505283801154,13.000505283801154,13.032575903386288,13.016540622327698,13.032575903386288,13.048609492503267,13.080672896974267,13.080672896974267,13.080672896974267,13.112733112487165,13.096703036593276,13.096703036593276,13.112733112487165,13.112733112487165,13.128761490714291,13.128761490714291,13.144788496707593,13.144788496707593,13.160814782285332,13.176840346198116,13.176840346198116,13.192864534342176,13.192864534342176,13.192864534342176,13.192864534342176,13.208887672002968,13.208887672002968,13.208887672002968,13.208887672002968,13.22490943161187,13.22490943161187,13.22490943161187,13.22490943161187,13.22490943161187,13.22490943161187,13.22490943161187,13.22490943161187,13.22490943161187,13.22490943161187,13.22490943161187,13.22490943161187,13.22490943161187,13.22490943161187,13.22490943161187,13.22490943161187,13.22490943161187,13.208887672002968,13.208887672002968,13.192864534342176,13.192864534342176,13.176840346198116,13.176840346198116,13.192864534342176,13.192864534342176,13.192864534342176,13.192864534342176,13.208887672002968,13.208887672002968,13.22490943161187,13.22490943161187,13.22490943161187,13.240931117501427,13.240931117501427,13.240931117501427,13.240931117501427,13.25695109658746,13.25695109658746,13.288987561625746,13.288987561625746,13.305004045256396,13.353048443947001,13.3690603593313,13.40108262945514,13.433100310005647,13.481118816363729,13.513125797218297,13.561128209891907,13.60912124988738,13.641110988861195,13.657103907909853,13.673096719668045,13.70507745560498,13.737054490308346,13.769026185938788,13.800994487118277,13.832957756332206,13.848937908027127,13.86491663551751,13.86491663551751,13.86491663551751,13.86491663551751,13.86491663551751,13.86491663551751,13.86491663551751,13.86491663551751,13.86491663551751,13.86491663551751,13.86491663551751,13.86491663551751,13.86491663551751,13.86491663551751,13.848937908027127,13.816976507107645,13.800994487118277,13.769026185938788,13.753041209607522,13.72106570337001,13.70507745560498,13.689087468250348,13.673096719668045,13.657103907909853,13.641110988861195,13.60912124988738,13.59312508399014,13.57712686045157,13.545128807666972,13.497122843247443,13.417092003242736,13.337035140108767,13.272969694135906,13.25695109658746,13.208887672002968,13.176840346198116,13.128761490714291,13.128761490714291,13.096703036593276,13.048609492503267,12.98446858237193,12.936351945765335,12.888226025703545,12.87218243071942,12.824045163587233,12.807996488245887,12.759846623823202,12.679576280784026,12.599279646938768,12.535024741089444,12.502891601170996,12.43861268617154,12.406467585057884,12.35824167801964,12.326086020295238,12.293927073888883,12.245680789485304,12.213511698317072,12.181338369443083,12.116981659242505,12.068702869614317,12.020415380438845,11.97211922445181,11.907712018270958,11.843288884671184,11.730511888140677,11.682164420838038,11.66604683137837,11.649928634097666,11.601567123851337,11.553198217217654,11.537072186984831,11.488692156193165,11.456433420014617,11.424171659890856,11.375771317450031,11.343500726234579,11.295086689925318,11.262806013965498,11.246664481440146,11.21437903354264,11.21437903354264,11.19823413399049,11.16594360760288,11.14979666765998,11.14979666765998,11.13364915975552,11.13364915975552,11.13364915975552,11.117499769239979,11.117499769239979,11.117499769239979,11.101350471197513,11.101350471197513,11.085199950942844,11.085199950942844,11.085199950942844,11.085199950942844,11.085199950942844,11.085199950942844,11.069048538694158,11.069048538694158,11.069048538694158,11.069048538694158,11.0528959066288,11.0528959066288,11.0528959066288,11.0528959066288,11.0528959066288,11.036742714077189,11.036742714077189,11.036742714077189,11.020588633235484,11.004433994450215,10.988278469881918,10.939805277107455,10.907485299032558,10.85899957008109,10.84283547038427,10.826670826516892,10.810505310445864,10.778172325375378,10.745834878324127,10.713494626062491,10.713494626062491,10.69732238043699,10.66497695081507,10.648802780973213,10.648802780973213,10.632627423065241,10.616451537356483,10.58409785815011,10.519378619068892,10.503197096765021,10.470830192709755,10.438461228033438,10.389900147632037,10.341331519654675,10.325140745381667,10.276562106514199,10.19558167766703,10.065970229585977,10.017352808376584,9.96872776886577,9.920095144839586,9.87145629136067,9.822809260687867,9.790374481910247,9.709272207062853,9.660602459128816,9.628151276805623,9.579469486203584,9.547010527218223,9.482084001800516,9.384671524808887,9.335954505437503,9.287231336950112,9.222256135896146,9.124770592912592,9.07601830773855,8.99474857399264,8.897201942402226,8.864681158113102,8.750833155988055,8.685762339833023,8.63695032148965,8.539310351543513,8.474201811012263,8.441644064448923,8.39280080666036,8.311384063238364,8.246237294890689,8.115914285187838,7.985547661695903,7.904046678039652,7.740997906248155,7.626826146132573,7.561572094988164,7.447352317377839,7.349425557839017,7.3167790467305815,7.235151177369058,7.186167889668669,7.153509539601199,7.104516139743774,6.990181620217794,6.941170951011977,6.908495332100155,6.875817455168816,6.843137330692251,6.826796595348233,6.7777690492867215,6.745082244966417,6.712393235034695,6.712393235034695,6.663354109017581,6.6470069751977325,6.597962983849126,6.597962983849126,6.581614016827748,6.548914136207565,6.516210447432675,6.499858802135815,6.499858802135815,6.499858802135815,6.499858802135815,6.467153584622622,6.418091626966171,6.418091626966171,6.418091626966171,6.418091626966171,6.401736811178733,6.401736811178733,6.401736811178733,6.352667226941315,6.352667226941315,6.336309990535969,6.303594629855627,6.303594629855627,6.254517056268278,6.270876539009017,6.254517056268278,6.221794889735595,6.2054335417225595,6.172709656285739,6.10725416462351,6.074524246270672,6.009058784088124,5.976322927971886,5.8944732432299975,5.8617305798337185,5.828985995324156,5.681610373745602,5.566958760187228,5.452284113162611,5.386745590471007,5.353974340285903,5.272038385418098,5.222870542935728,5.190090281409545,5.140917366054426,5.042558510182642,4.8949928776037055,4.714591102307565,4.599764916914262,4.452104534878056,4.320826286883533,4.288003062904608,4.22235172708648,4.205938189128325,4.189524639760541,4.173110745956713,4.140281595999411,4.156696174662511,4.123866342512247,4.091033816344511,4.107450749935614,4.091033816344511,4.074617549590066,4.074617549590066,4.074617549590066,4.074617549590066,4.058201282203632,4.0089501486748516,4.025367078734814,4.025367078734814,4.0417843466619585,4.0417843466619585,4.058201282203632,4.058201282203632,4.074617549590066,4.091033816344511,4.107450749935614,4.123866342512247,4.123866342512247,4.140281595999411,4.156696174662511,4.156696174662511,4.189524639760541,4.22235172708648,4.27159125586025,4.288003062904608,4.353647421586928,4.386467459276059,4.517734419510782,4.550548811005275,4.616169754342087,4.681785966633134,4.829398646407871,4.8949928776037055,5.026163966703564,5.0589523057713714,5.108133199468941,5.140917366054426,5.1737001789523145,5.190090281409545,5.206480625787512,5.272038385418098,5.288426580331246,5.32120133336296,5.353974340285903,5.435900650578594,5.468667462353709,5.566958760187228,5.648854077685191,5.79623783247416,5.845358693823153,5.8944732432299975,5.9108436844576335,5.976322927971886,5.992690934734714,6.041792671507335,6.041792671507335,6.074524246270672,6.09088962152684,6.123620207812877,6.1399837493573814,6.172709656285739,6.221794889735595,6.270876539009017,6.287235841737472,6.352667226941315,6.352667226941315,6.3853798056045985,6.401736811178733,6.418091626966171,6.418091626966171,6.450800015014331,6.450800015014331,6.450800015014331,6.467153584622622,6.467153584622622,6.467153584622622,6.467153584622622,6.467153584622622,6.467153584622622,6.467153584622622,6.467153584622622,6.467153584622622,6.4835062920099436,6.499858802135815,6.4835062920099436,6.450800015014331,6.450800015014331,6.450800015014331,6.418091626966171,6.418091626966171,6.418091626966171,6.3853798056045985,6.3853798056045985,6.352667226941315,6.352667226941315,6.319952568807602,6.287235841737472,6.303594629855627,6.303594629855627,6.287235841737472,6.287235841737472,6.287235841737472,6.287235841737472,6.287235841737472,6.287235841737472,6.287235841737472,6.287235841737472,6.287235841737472,6.287235841737472,6.287235841737472,6.287235841737472,6.287235841737472,6.287235841737472,6.303594629855627,6.336309990535969,6.336309990535969,6.336309990535969,6.352667226941315,6.352667226941315,6.369023610261592,6.369023610261592,6.369023610261592,6.3853798056045985,6.3853798056045985,6.3853798056045985,6.3853798056045985,6.3853798056045985,6.3853798056045985,6.401736811178733,6.450800015014331,6.532561559717868,6.597962983849126,6.597962983849126,6.597962983849126,6.614311411289581,6.663354109017581,6.679700364982684,6.712393235034695,6.810453637506863,6.8921568416590455,7.006516703987839,7.186167889668669,7.284130479557393,7.382069669888884,7.398392319192542,7.545256871069231,7.577886369867276,7.6594491133639675,7.675759993212209,7.675759993212209,7.757305644185009,7.952948147829833,8.067030725456439,8.278812689902427,8.441644064448923,8.474201811012263,8.506756469802419,8.506756469802419,8.63695032148965,8.653221034983746,8.685762339833023,8.71829916448387,8.750833155988055,8.897201942402226,8.880941910789376,8.929721162177485,9.124770592912592,9.173516878121173,9.287231336950112,9.335954505437503,9.368433387499651,9.530780052546335,9.660602459128816,9.693049852080614,9.887669932557184,9.96872776886577,10.082175181449827,10.19558167766703,10.357522448539685,10.632627423065241,10.85899957008109,10.988278469881918,11.036742714077189,11.101350471197513,11.21437903354264,11.278946969743938,11.31122550209925,11.343500726234579,11.39190557117278,11.52094687283393,11.553198217217654,11.633809173497655,11.649928634097666,11.66604683137837,11.762737954324187,11.778850557465578,11.827180067910742,11.843288884671184,11.859396095514159,11.891607335449581,11.988219450677676,12.036512065458592,12.165250405629715,12.197426013594153,12.310006875667435,12.342164834033548,12.422540468477253,12.486823695538119,12.518958507660406,12.551090300196023,12.599279646938768,12.647460590613937,12.856137809062407,12.888226025703545,13.064641715215155,13.096703036593276,13.160814782285332,13.176840346198116,13.192864534342176,13.25695109658746,13.272969694135906,13.385072842159227,13.40108262945514,13.481118816363729,13.497122843247443,13.513125797218297,13.57712686045157,13.57712686045157,13.59312508399014,13.60912124988738,13.60912124988738,13.60912124988738,13.60912124988738,13.60912124988738,13.60912124988738\",\n \"Longitude\": \"13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.714639618992807,13.648806139826775,13.418394662439821,13.039859533309937,12.792989015579224,12.611950635910034,12.595492601394653,12.562576867640018,12.5790349021554,12.562576867640018,12.5790349021554,12.513201758265495,12.48028602451086,12.414454892277718,12.348622083663939,12.299248315393923,12.249874547123907,12.233416847884655,12.18404173851013,12.167583703994751,12.151126004755499,12.118210606276989,12.101752907037737,12.085292860865593,12.068835161626337,12.035919763147831,12.003004029393196,11.986545994877815,11.937171220779419,11.904255151748659,11.871339417994022,11.821965649724007,11.789048574864866,11.73967480659485,11.706759743392466,11.657385975122452,11.62446890026331,11.575095131993296,11.509262323379517,11.459888555109499,11.410514786839483,11.361139677464962,11.295308545231821,11.245934776961803,11.163643933832644,11.097812466323376,11.04843735694885,10.999063588678835,10.949690490961075,10.916773080825804,10.86739931255579,10.834483914077282,10.801568180322647,10.752193070948124,10.719277337193489,10.669903904199598,10.636986494064331,10.587613061070442,10.538239292800426,10.472406148910522,10.406575016677381,10.357199907302856,10.30782613903284,10.258452706038952,10.209077596664429,10.176161862909794,10.110330730676651,10.07741466164589,10.011581853032112,9.962207414209843,9.8963762819767,9.86345920711756,9.814085438847544,9.764711670577528,9.731794930994512,9.68242183327675,9.665962792932987,9.616589359939098,9.58367295563221,9.567214921116829,9.534299187362194,9.501382783055305,9.46846704930067,9.452008344233036,9.402634911239147,9.386176876723766,9.369718506932259,9.353260472416878,9.303886033594608,9.287428334355354,9.2709706351161,9.238054230809212,9.205138497054575,9.188680462539196,9.139306023716927,9.106390625238419,9.07347422093153,9.02409978210926,8.991184048354626,8.941809609532356,8.908893875777721,8.859519772231579,8.843061737716198,8.793687298893929,8.744313530623913,8.727855160832405,8.678481727838516,8.662022687494755,8.645565323531628,8.612649254500866,8.579732850193977,8.546817116439342,8.513900712132454,8.480984978377817,8.448068574070929,8.43161053955555,8.398694805800913,8.365778401494024,8.349320366978645,8.332862667739391,8.316404968500139,8.28348822891712,8.267030529677868,8.250572830438614,8.217656090855598,8.201198391616344,8.151823952794075,8.135366253554821,8.102450519800186,8.06953378021717,8.053076080977917,8.036618381738663,8.020160347223282,8.003701642155647,7.987243942916393,7.970786243677138,7.92141180485487,7.8720373660326,7.822663597762585,7.773289494216443,7.723915055394173,7.674541622400284,7.6087091490626335,7.559335045516492,7.526419311761856,7.4770448729395875,7.444129139184952,7.39475503563881,7.345380596816539,7.29600615799427,7.2466327250003815,7.213716320693492,7.197258286178112,7.147883847355843,7.0820527151227,7.065594010055066,7.03267827630043,7.016220577061177,7.016220577061177,6.999761871993542,6.966846138238907,6.966846138238907,6.950388103723526,6.933929398655891,6.9010140001773825,6.884555965662003,6.868097931146622,6.835181526839733,6.818723827600478,6.802265793085098,6.76934938877821,6.736433655023575,6.719975285232066,6.6706015169620505,6.637685112655163,6.588311344385148,6.522479206323624,6.4566470682621,6.407272629439832,6.341440491378308,6.242692619562149,6.19331818073988,6.127486042678356,6.078112609684467,6.028738170862197,5.995821766555308,5.962906032800674,5.94644833356142,5.913531593978404,5.897073894739151,5.864158160984516,5.847699455916881,5.831241756677628,5.798326022922994,5.765409283339976,5.748951584100723,5.716035850346088,5.666661411523819,5.650203712284566,5.6008292734622955,5.5843715742230415,5.534997135400772,5.485622696578503,5.452706962823868,5.37041712552309,5.3539590910077095,5.304584987461567,5.2716682478785515,5.238752514123917,5.172920376062393,5.123545937240123,5.074172504246235,5.008340366184711,4.975423961877822,4.909591823816299,4.827301651239394,4.745011478662491,4.712095744907856,4.679179340600967,4.6462636068463326,4.613347202539444,4.629804901778698,4.596889168024063,4.563973769545555,4.5475150644779205,4.498141296207905,4.465224891901016,4.448767192661762,4.415850453078747,4.399392753839493,4.366477020084858,4.366477020084858,4.3171025812625885,4.267728477716446,4.251270443201065,4.234812743961811,4.234812743961811,4.201897010207176,4.185438305139542,4.185438305139542,4.168980270624161,4.136064872145652,4.136064872145652,4.136064872145652,4.103148132562637,4.070232734084129,4.053774029016495,4.004400260746479,3.9714838564395905,3.938568122684956,3.9221100881695747,3.905651718378067,3.889193683862686,3.889193683862686,3.872735984623432,3.8398192450404167,3.8398192450404167,3.790445812046528,3.7410717085003857,3.7246136739850044,3.7081556394696236,3.7081556394696236,3.7081556394696236,3.675239235162735,3.691697269678116,3.691697269678116,3.691697269678116,3.675239235162735,3.675239235162735,3.675239235162735,3.675239235162735,3.675239235162735,3.675239235162735,3.675239235162735,3.675239235162735,3.675239235162735,3.675239235162735,3.675239235162735,3.675239235162735,3.675239235162735,3.675239235162735,3.675239235162735,3.675239235162735,3.675239235162735,3.6587815359234814,3.6587815359234814,3.6423235014081,3.6423235014081,3.6423235014081,3.6423235014081,3.6423235014081,3.6423235014081,3.6423235014081,3.6423235014081,3.6423235014081,3.6423235014081,3.6423235014081,3.6423235014081,3.6423235014081,3.6423235014081,3.6258658021688457,3.592949397861958,3.5764913633465767,3.5764913633465767,3.543574959039688,3.543574959039688,3.5271172598004346,3.5106592252850533,3.4942015260457993,3.461284786462784,3.4448270872235303,3.428369052708149,3.411911353468895,3.3954526484012604,3.3954526484012604,3.3954526484012604,3.3789949491620064,3.3789949491620064,3.3789949491620064,3.3789949491620064,3.3789949491620064,3.3789949491620064,3.3789949491620064,3.3789949491620064,3.3789949491620064,3.3789949491620064,3.362536914646625,3.362536914646625,3.3296208456158634,3.3460788801312447,3.3296208456158634,3.313162811100483,3.296704776585102,3.2802464067935944,3.2473310083150864,3.2308726385235786,3.2308726385235786,3.197956569492817,3.181498870253563,3.132124431431294,3.1156663969159126,3.0827503278851514,3.0662926286458974,3.0004604905843735,2.9675444215536118,2.918169982731342,2.8852535784244537,2.8523381799459457,2.835879810154438,2.835879810154438,2.835879810154438,2.835879810154438,2.835879810154438,2.835879810154438,2.819422110915184,2.819422110915184,2.8029637411236767,2.8029637411236767,2.786506041884422,2.7535896375775337,2.7700476720929146,2.7700476720929146,2.7700476720929146,2.7700476720929146,2.7700476720929146,2.7700476720929146,2.7700476720929146,2.7700476720929146,2.7700476720929146,2.7700476720929146,2.7700476720929146,2.7700476720929146,2.7700476720929146,2.7700476720929146,2.786506041884422,2.786506041884422,2.786506041884422,2.786506041884422,2.786506041884422,2.786506041884422,2.786506041884422,2.786506041884422,2.786506041884422,2.786506041884422,2.786506041884422,2.786506041884422,2.8029637411236767,2.819422110915184,2.835879810154438,2.8523381799459457,2.8523381799459457,2.8523381799459457,2.8687958791851997,2.9017119482159615,2.918169982731342,2.951086051762104,2.951086051762104,3.0004604905843735,3.0169181898236275,3.0827503278851514,3.1650405004620557,3.197956569492817,3.296704776585102,3.3789949491620064,3.5271172598004346,3.6094070971012115,3.790445812046528,3.872735984623432,3.955025821924209,4.02085829526186,4.152522571384907,4.185438305139542,4.267728477716446,4.3171025812625885,4.415850453078747,4.448767192661762,4.498141296207905,4.662721641361713,4.810843616724015,5.074172504246235,5.189378410577774,5.2552105486392975,5.37041712552309,5.403332859277725,5.436249263584614,5.485622696578503,5.534997135400772,5.6008292734622955,5.6831194460392,5.732493884861468,5.831241756677628,5.897073894739151,5.94644833356142,5.995821766555308,6.012280471622944,6.078112609684467,6.111028343439101,6.19331818073988,6.226234920322895,6.357898525893688,6.407272629439832,6.440189369022846,6.50602150708437,6.654143817722797,6.687059216201305,6.752891689538955,6.785807088017463,6.868097931146622,6.98330383747816,7.114968113601208,7.345380596816539,7.592251449823379,7.641625218093395,7.773289494216443,7.8391216322779655,7.92141180485487,7.937869504094124,8.036618381738663,8.053076080977917,8.135366253554821,8.184740357100964,8.267030529677868,8.299946263432503,8.43161053955555,8.480984978377817,8.579732850193977,8.612649254500866,8.69493942707777,8.744313530623913,8.859519772231579,8.892436176538467,8.941809609532356,8.991184048354626,9.040558151900767,9.05701618641615,9.106390625238419,9.122847989201546,9.188680462539196,9.22159619629383,9.22159619629383,9.22159619629383,9.22159619629383,9.22159619629383,9.22159619629383,9.205138497054575,9.205138497054575,9.205138497054575,9.205138497054575,9.205138497054575,9.238054230809212,9.303886033594608,9.32034507393837,9.353260472416878,9.386176876723766,9.452008344233036,9.46846704930067,9.51784048229456,9.534299187362194,9.534299187362194,9.567214921116829,9.58367295563221,9.616589359939098,9.698879197239876,9.715337231755257,9.78116936981678,9.814085438847544,9.86345920711756,9.8963762819767,9.978666119277477,10.028039887547493,10.110330730676651,10.15970416367054,10.209077596664429,10.241995006799698,10.30782613903284,10.357199907302856,10.373659282922745,10.390116982161997,10.423032715916634,10.439490750432013,10.439490750432013,10.439490750432013,10.439490750432013,10.439490750432013,10.455948449671268,10.50532355904579,10.571155026555061,10.587613061070442,10.653445869684221,10.669903904199598,10.702819302678108,10.702819302678108,10.735735036432743,10.735735036432743,10.785108469426632,10.785108469426632,10.88385734707117,10.966148525476456,11.097812466323376,11.114270165562628,11.147186234593391,11.163643933832644,11.180101968348028,11.196560002863407,11.196560002863407,11.21301770210266,11.21301770210266,11.22947707772255,11.245934776961803,11.278850845992565,11.295308545231821,11.3117665797472,11.394057422876358,11.44343052059412,11.459888555109499,11.558637097477913,11.690301708877088,11.706759743392466,11.75613284111023,11.772590540349482,11.789048574864866,11.789048574864866,11.805508285760881,11.805508285760881,11.805508285760881,11.805508285760881,11.805508285760881,11.805508285760881,11.805508285760881,11.805508285760881,11.821965649724007,11.854881383478643,11.887797452509403,11.937171220779419,11.920713186264038,11.920713186264038,11.986545994877815,12.019462063908577,12.035919763147831,12.035919763147831,12.068835161626337,12.085292860865593,12.134668640792368,12.18404173851013,12.216957472264767,12.233416847884655,12.233416847884655,12.249874547123907,12.28279061615467,12.33216404914856,12.36508011817932,12.36508011817932,12.381539158523083,12.430912926793098,12.463828660547732,12.611950635910034,12.809448055922983,12.891737222671509,12.908194921910761,12.99048576503992,13.122150376439095,13.17152414470911,13.187982179224491,13.204439878463745,13.237355276942253,13.303188756108284,13.303188756108284,13.336103819310665,13.369019888341429,13.369019888341429,13.418394662439821,13.434852696955206,13.451310731470585,13.500684499740599,13.533601574599743,13.533601574599743,13.615891076624393,13.648806139826775,13.714639618992807,13.747555017471313,13.780470751225948,13.862761594355106,13.928593397140503,13.994426205754278,14.043799974024296,14.09317307174206,14.159005880355835,14.175463914871216,14.224837683141232,14.224837683141232,14.224837683141232,14.241295382380484,14.241295382380484,14.241295382380484,14.241295382380484,14.257754758000374,14.257754758000374,14.257754758000374,14.257754758000374,14.257754758000374,14.290670491755009,14.30712852627039,14.30712852627039,14.30712852627039,14.30712852627039,14.30712852627039,14.290670491755009,14.274212792515755,14.241295382380484,14.224837683141232,14.191921949386597,14.175463914871216,14.175463914871216,14.159005880355835,14.09317307174206,14.076715037226679,13.945051096379757,13.945051096379757,13.912135362625122,13.895677328109741,13.895677328109741,13.862761594355106,13.846303559839725,13.79692878574133,13.780470751225948,13.731096982955933,13.731096982955933,13.698181919753551,13.665264174342155,13.648806139826775,13.648806139826775,13.615891076624393,13.615891076624393,13.615891076624393,13.615891076624393,13.615891076624393,13.615891076624393\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": 8.43579,\n \"PositionLongitude\": 7.574201,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": null,\n \"Status\": 0,\n \"Street\": \"Roguwa\",\n \"TotalDistanceCovered\": 151638,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Nassarawa\",\n \"TractorID\": 500042,\n \"TractorModelID\": 5,\n \"TractorName\": \"TRAXI/TRCIH0005-671 UA\",\n \"UpdatedAt\": \"2019-10-30 16:10:16\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"_acl\": {\n \"creator\": \"593aa855ecdebb2558589e6f\"\n },\n \"license_plate_number\": \"YAB671YR\",\n \"_kmd\": {\n \"lmt\": \"2019-04-13T23:01:24.034Z\",\n \"ect\": \"2018-02-16T18:38:34.031Z\"\n },\n \"FuelRawValue\": null,\n \"IgnitionStatus\": null,\n \"AssetState\": null,\n \"FuelLevelVoltage\": 0\n },\n \"500232\": {\n \"_id\": \"5af5d2dfa432ce4037101f52\",\n \"ActiveTimeToday\": 0,\n \"BookingRequests\": true,\n \"Characteristic\": \"109,102,103,104\",\n \"Country\": \"Nigeria\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 41,\n \"FixedEngineHours\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"oke eri\",\n \"ImplementsAttached\": \"\",\n \"LastActiveTime\": \"2019-05-05 14:52:08\",\n \"LastGeofenceNotificationTime\": \"2019-03-25T09:13:08.648Z\",\n \"Latitude\": \"0.07147682839380448,0.07147682839380448,0.07147682839380448,0.07147682839380448,0.07147682839380448,0.07147682839380448,0.07147682839380448,0.07101079493774277,0.06961269454150518,0.06914666106683086,0.06868062758760199,0.06681649362550994,0.06495235959268233,0.06308822549110388,0.05889392352138677,0.0551656548382078,0.050971352291220025,0.04724308313055074,0.042116712711230096,0.03745604039669753,0.03186363562610354,0.02627123055194468,0.01834865628112949,0.010426081659486398,0.002969540654281299,-0.00541873275425164,-0.01427337512511469,-0.02266198337594344,-0.031050591141012433,-0.0399052319451088,-0.04922624071808267,-0.05901294648341382,-0.06833361704434508,-0.07718825240604166,-0.08604288592421243,-0.0921013182128107,-0.10002388194899267,-0.1056162787379211,-0.10841247675839023,-0.10934454270816685,-0.11074264157848882,-0.1116747074554689,-0.11214074038288425,-0.11214074038288425,-0.11214074038288425,-0.11214074038288425,-0.11214074038288425,-0.10934454270816685,-0.10515024570987298,-0.10048991505187287,-0.0907032185428464,-0.08604288592421243,-0.08091651938743304,-0.07485808537568657,-0.06879965052697078,-0.062275181370008176,-0.05621674499938424,-0.05015830800020637,-0.04363350148442948,-0.035710928512171156,-0.025458186027160254,-0.0170695779182733,-0.00868096944348261,-0.002156496047464008,0.002969540654281299,0.008095912608384971,0.015552453505743821,0.05563168843670747,0.05656375562262575,0.05702978920999347,0.05702978920999347,0.05702978920999347,0.05702978920999347,0.05702978920999347,0.05702978920999347,0.059359957089569385,0.07334096217044477,0.07520509586945406,0.078467329649966,0.08033146312530597,0.08126352983121493,0.08266162984966625,0.08312766317825133,0.08359369650134041,0.08359369650134041,0.08405972981890804,0.08452576313089061,0.08499179643730086,0.08499179643730086,0.08499179643730086,0.08545782973808788,0.08499179643730086,0.08405972981890804,0.08405972981890804,0.08359369650134041,0.08359369650134041,0.08219559651561063,0.0789333630266665,0.07800129626808755,0.07753526288103116,0.07660319609156266,0.07613716268922688,0.07613716268922688,0.07473906245208062,0.07334096217044477,0.07334096217044477,0.07240889529171718,0.06821459410380586,0.05842788994929843\",\n \"Longitude\": \"0.0029658526182174683,0.0029658526182174683,0.0029658526182174683,-0.009616725146770477,-0.013811029493808745,-0.020335502922534943,-0.024995841085910797,-0.028724111616611484,-0.03198634833097457,-0.03478255122900009,-0.03664668649435043,-0.03804478794336319,-0.039442889392375946,-0.04130702465772629,-0.043637193739414215,-0.04596736282110214,-0.04922959953546524,-0.05295787006616593,-0.05575407296419144,-0.0571521744132042,-0.05855027586221694,-0.06088044494390487,-0.06181251257658005,-0.06227854639291763,-0.06274458020925522,-0.06274458020925522,-0.0636766478419304,-0.0632106140255928,-0.0636766478419304,-0.0636766478419304,-0.0636766478419304,-0.0632106140255928,-0.06181251257658005,-0.05901630967855454,-0.05528803914785386,-0.05202580243349075,-0.04550132900476456,-0.039442889392375946,-0.031054280698299408,-0.022199638187885284,-0.011480860412120819,-0.0021601840853691097,0.0062280893325805655,0.010888427495956421,0.01927737146615982,0.02719994634389877,0.03232631832361221,0.03885079175233841,0.045375265181064606,0.05096767097711564,0.06261851638555527,0.06634678691625595,0.06960902363061905,0.07287126034498215,0.07520142942667007,0.07706556469202042,0.07846366614103317,0.07892969995737076,0.08219193667173387,0.08545417338609697,0.08825037628412247,0.09011451154947281,0.08964847773313524,0.09011451154947281,0.09011451154947281,0.09011451154947281,0.09011451154947281,0.09011451154947281,0.08964847773313524,0.08964847773313524,0.08918244391679765,0.08918244391679765,0.08918244391679765,0.08918244391679765,0.08918244391679765,0.08778434246778488,0.08452210575342178,0.08312400430440903,0.0807938352227211,0.07986176759004593,0.07939573377370834,0.07753159850835799,0.07054109126329422,0.061686448752880096,0.055628009140491486,0.05516197532415391,0.052831806242465966,0.05236577242612839,0.0518997386097908,0.05143370479345322,0.04910353571176529,0.03139425069093704,0.026733912527561188,0.023471675813198093,0.02114150673151016,0.01927737146615982,0.01321859657764435,0.005762055516242981,-2.960488200187683E-4,-0.004024319350719452,-0.006354488432407379,-0.0077525898814201355,-0.009616725146770477,-0.0217336043715477,-0.025927908718585968,-0.03152031451463699,-0.03664668649435043,-0.043637193739414215,-0.0566861405968666\",\n \"NeedToSendGeofenceOutNotification\": false,\n \"OperatorID\": 0,\n \"PositionLatitude\": 11.079955,\n \"PositionLongitude\": 7.699982,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 0.02,\n \"Status\": 0,\n \"Street\": \"Tudun Wada\",\n \"TotalHectaresTilled\": null,\n \"Town\": \"Kaduna\",\n \"TractorID\": 500232,\n \"TractorModelID\": 9,\n \"TractorName\": \"GL0066\",\n \"UpdatedAt\": \"2019-10-30 01:59:09\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": false,\n \"_acl\": {\n \"creator\": \"5af571828026bf1bf79e839f\"\n },\n \"_kmd\": {\n \"lmt\": \"2019-04-13T23:01:08.754Z\",\n \"ect\": \"2018-05-11T17:29:03.490Z\"\n },\n \"license_plate_number\": \"GL0066\",\n \"TotalDistanceCovered\": 162,\n \"Heading\": 0,\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"FuelLevelVoltage\": 0\n },\n \"500249\": {\n \"_id\": \"5c4206ebb39e562cf9f10597\",\n \"ActiveTimeToday\": 6335,\n \"BookingRequests\": true,\n \"Characteristic\": \"109,102,103\",\n \"Country\": \"Nigeria\",\n \"CreatedAt\": \"2019-01-18 17:03:38\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 302,\n \"FixedEngineHours\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"\",\n \"Heading\": 0,\n \"LastActiveTime\": \"2019-10-30 14:30:49\",\n \"LastGeofenceNotificationTime\": \"2019-10-09T11:00:33.905Z\",\n \"Latitude\": \"6.786599350539119,6.786599350539119,6.786599350539119,6.786599350539119,6.786599350539119,6.786599350539119,6.786599350539119,6.786599017612217,6.786599017612217,6.786599017612217,6.786599017612217,6.786599017612217,6.786598351758401,6.786598351758401,6.786597685904595,6.786597352977694,6.786596687123864,6.786596021270059,6.786595355416242,6.7865943566355105,6.786593357854779,6.786592692000961,6.786591693220242,6.786591360293328,6.7865896956587655,6.786588363951118,6.7865863663896295,6.786585034681982,6.78658370297431,6.786581705412821,6.786579374924391,6.786576711509022,6.786573382239795,6.786570052970558,6.786566390774367,6.786563061505065,6.786559732235751,6.786556070039484,6.786551076135416,6.786546082231311,6.786540089546321,6.786533431007349,6.786527105395242,6.786520446856091,6.786514121243805,6.786508794412352,6.786503467580824,6.786498473676235,6.786494145625527,6.7864901505017725,6.786486488304984,6.786483159035136,6.786481161473213,6.786479163911278,6.786478498057309,6.7864788309843,6.786480162692253,6.786482826108143,6.786485822451014,6.786489817574794,6.786495477333455,6.786502468799914,6.786508794412352,6.786515120024702,6.786521445636963,6.786526439541324,6.786532099299537,6.786538424911595,6.78654475052355,6.786551409062357,6.786558067601088,6.78656239565121,6.786567056628223,6.7865720505321105,6.786575379801336,6.786578709070535,6.786581039558979,6.786583370047396,6.786586033462727,6.786588363951118,6.786590361512594,6.786591027366413,6.786592359074058,6.786594023708608\",\n \"Longitude\": \"3.8910846412181854,3.8910846412181854,3.8910846412181854,3.8910846412181854,3.8910846412181854,3.8910846412181854,3.8910846412181854,3.8910846412181854,3.8910846412181854,3.8910843059420586,3.8910843059420586,3.8910836353898044,3.891083300113678,3.891082964837551,3.8910819590091705,3.891080617904663,3.891078941524029,3.891077935695648,3.89107558876276,3.8910742476582527,3.8910719007253647,3.891069553792476,3.8910675421357155,3.8910655304789543,3.8910638540983205,3.891061507165432,3.891059160232544,3.8910564780235295,3.891053460538387,3.8910501077771187,3.8910460844635963,3.8910427317023277,3.8910390436649323,3.8910360261797905,3.8910330086946487,3.8910306617617603,3.891027979552746,3.8910259678959846,3.8910239562392235,3.891022615134716,3.8910216093063354,3.8910212740302086,3.8910216093063354,3.891022615134716,3.8910242915153503,3.8910266384482384,3.891029320657253,3.891032673418522,3.891037702560425,3.8910427317023277,3.8910487666726112,3.891056142747402,3.8910628482699394,3.891068883240223,3.89107558876276,3.8910826295614247,3.8910886645317078,3.891095705330372,3.8911020755767822,3.8911081105470657,3.8911131396889687,3.8911164924502373,3.8911185041069984,3.8911198452115054,3.8911208510398865,3.891121856868267,3.8911225274205203,3.8911225274205203,3.8911215215921406,3.8911205157637596,3.8911188393831253,3.891117498278618,3.8911161571741104,3.891114480793476,3.8911131396889687,3.891112133860588,3.8911107927560806,3.8911091163754463,3.8911067694425583,3.891103751957416,3.891100063920021,3.8910946995019913,3.8910863175988197,3.891078941524029\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"PositionLatitude\": 7.457505,\n \"PositionLongitude\": 3.919238,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 0.02,\n \"Status\": 0,\n \"Street\": \"Ojo\",\n \"TotalDistanceCovered\": 3294,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Oyo\",\n \"TractorID\": 500249,\n \"TractorModelID\": 4,\n \"TractorName\": \"MF 4610Tractor (500249)\",\n \"UpdatedAt\": \"2019-10-30 15:30:04\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": false,\n \"_acl\": {\n \"creator\": \"5c4069eef0705c629a75dc8d\"\n },\n \"license_plate_number\": \"MF 4610\",\n \"_kmd\": {\n \"lmt\": \"2019-04-13T22:59:27.718Z\",\n \"ect\": \"2019-01-18T17:03:39.151Z\"\n },\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 1,\n \"AssetState\": \"On\",\n \"FuelLevelVoltage\": 0\n },\n \"500251\": {\n \"_id\": \"5c4222207ae97a3da6d4db0b\",\n \"ActiveTimeToday\": 5945,\n \"BookingRequests\": true,\n \"Characteristic\": \"108\",\n \"Country\": \"Nigeria\",\n \"CreatedAt\": \"2019-01-18 18:59:43\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 288,\n \"FixedEngineHours\": 0,\n \"FixedOdometerReading\": 0,\n \"FuelLitres\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"\",\n \"Heading\": 66,\n \"ImplementsAttached\": \"101,102,108\",\n \"LastActiveTime\": \"2019-10-30 11:14:19\",\n \"LastGeofenceNotificationTime\": \"2019-10-14T10:54:11.919Z\",\n \"Latitude\": \"6.7866123346882405,6.7866123346882405,6.7866123346882405,6.78661133590756,6.786609005419282,6.786607340784771,6.786605010296469,6.786603345661971,6.786600349319839,6.786597685904595,6.786594689562425,6.786591360293328,6.786588363951118,6.78658436882814,6.786580373705136,6.786576378582106,6.786571717605183,6.786566390774367,6.786561063943487,6.786556070039484,6.786550077354596,6.78654441759661,6.7865374261307485,6.786531100518679,6.786526439541324,6.78652111271001,6.786514787097738,6.786508461485386,6.786502468799914,6.786498806603201,6.786495477333455,6.786494478552519,6.786494478552519,6.786495810260421,6.786498473676235,6.78650180294597,6.786506463923566,6.786511124901127,6.786518116367368,6.786525107833498,6.786532432226491,6.786538757838535,6.7865454163774315,6.786551409062357,6.786558400528028,6.786564393212788,6.786570385897472,6.786576378582106,6.786581705412821,6.786587698097289,6.786593357854779,6.786599017612217,6.786602679808154,6.7866060090771745,6.786609338346172,6.7866123346882405,6.78661499810342,6.78661632981099,6.786617994445463,6.786618327372352,6.786618660299241,6.786617328591671,6.786615663957198,6.786613000542044,6.7866123346882405\",\n \"Longitude\": \"3.89106921851635,3.89106921851635,3.89106921851635,3.8910678774118423,3.8910648599267006,3.891062512993813,3.8910601660609245,3.8910581544041634,3.8910558074712753,3.8910527899861336,3.8910501077771187,3.8910477608442307,3.8910454139113426,3.8910430669784546,3.891041055321694,3.8910387083888054,3.891037367284298,3.8910353556275368,3.891034349799156,3.8910340145230293,3.891034349799156,3.8910356909036636,3.891037367284298,3.8910390436649323,3.8910403847694397,3.8910427317023277,3.891047090291977,3.891052454710007,3.891059160232544,3.891065195202828,3.8910719007253647,3.891078270971775,3.891084976494312,3.8910920172929764,3.8910997286438938,3.8911084458231926,3.8911164924502373,3.891123868525028,3.8911302387714386,3.8911359384655952,3.891140967607498,3.891143649816513,3.891146332025528,3.8911470025777817,3.8911470025777817,3.8911470025777817,3.8911466673016544,3.8911456614732747,3.8911439850926395,3.891139961779117,3.891135267913341,3.8911302387714386,3.8911252096295352,3.8911198452115054,3.891114480793476,3.8911081105470657,3.891103751957416,3.8910993933677673,3.891095705330372,3.8910920172929764,3.891087993979454,3.891083300113678,3.8910776004195213,3.891071565449238,3.8910702243447304\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": 6.568566,\n \"PositionLongitude\": 7.007863,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 0.69,\n \"Status\": 0,\n \"Street\": \"Umumbo\",\n \"TotalDistanceCovered\": 972,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Anambra\",\n \"TractorID\": 500251,\n \"TractorModelID\": 22,\n \"TractorName\": \"DC60 Rice Combine Harvest\",\n \"UpdatedAt\": \"2019-10-30 15:29:33\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": false,\n \"_acl\": {\n \"creator\": \"5c4069eef0705c629a75dc8d\"\n },\n \"license_plate_number\": \"DC60\",\n \"_kmd\": {\n \"lmt\": \"2019-09-30T10:25:46.673Z\",\n \"ect\": \"2019-01-18T18:59:44.264Z\"\n },\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 1,\n \"AssetState\": \"On\",\n \"FuelLevelVoltage\": 0\n },\n \"500325\": {\n \"_id\": \"5b28e4bc2a0796167b35f6ce\",\n \"ActiveTimeToday\": 0,\n \"BookingRequests\": true,\n \"Characteristic\": \"109,102,103,107\",\n \"Country\": \"Nigeria\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 353,\n \"FixedEngineHours\": 0,\n \"FuelVolume\": 39,\n \"Group\": \"\",\n \"LastActiveTime\": \"2019-05-03 10:25:18\",\n \"LastGeofenceNotificationTime\": \"2019-10-01T11:20:30.187Z\",\n \"Latitude\": \"8.732170076837642,8.730360352341265,8.645288126511145,8.630805737764975,8.624469787239176,8.616323124855512,8.60093428502475,8.597313563644718,8.588260945847692,8.584639771927717,8.577397651978393,8.575587183294534,8.56924997767467,8.567439470180586,8.562912666432503,8.561102128776914,8.55929158250841,8.558386140373482,8.558386140373482,8.554764681848354,8.554764681848354,8.553859560496335,8.552954105446167,8.550238058934205,8.550238058934205,8.547521993064649,8.544805907843479,8.544805907843479,8.540279166673635,8.539373679370149,8.535752040233685,8.535752040233685,8.533035871223666,8.532130698303787,8.528508990466579,8.528508990466579,8.525792769951138,8.524887248298668,8.523076530131819,8.520360271014559,8.518549531410732,8.518549531410732,8.516738451656595,8.515833240144337,8.514022147533291,8.512211377934989,8.51130582413197,8.51040059977148,8.51130582413197,8.51040059977148,8.508589481458587,8.508589481458587,8.509495041685742,8.509495041685742,8.51130582413197,8.51130582413197,8.512211377934989,8.512211377934989,8.51311692959593,8.514022147533291,8.514022147533291,8.514022147533291,8.512211377934989,8.51311692959593,8.51130582413197,8.51040059977148,8.51130582413197,8.506778686168428,8.504062311389,8.498629504067681,8.497723918163858,8.493196619769561,8.491385751772773,8.489574543628715,8.488669267954936,8.4877636585424,8.486858046993763,8.48595276491478,8.485047149095347,8.485047149095347,8.484141531140477,8.48323624265826,8.48233062043394,8.48233062043394,8.48233062043394,8.480519701191406,8.479614072564171,8.477803140520134,8.477803140520134,8.473275275663465,8.471464313764246,8.466936705910465,8.464220049306768,8.458786678599614,8.457880998820752,8.451541844044783,8.450636478879153,8.446108294613662,8.443391491201998,8.437957827016323,8.436146699180814,8.434335562854406,8.434335562854406,8.43071293308289,8.43071293308289,8.429807187421536,8.427996021388594,8.427996021388594,8.427090269362822,8.431618676622076,8.432524086387328,8.437957827016323,8.438863553572494,8.44429720501142,8.445202916695342,8.449730779951278,8.450636478879153,8.452447538719122,8.454258590052255,8.45606996450813,8.456975316913082,8.459692024621258,8.460597700142603,8.461503373534491,8.462408713170827,8.466031045298529,8.468747689120645,8.471464313764246,8.471464313764246,8.47689750549197,8.480519701191406,8.4877636585424,8.494102216362338,8.503156738319529,8.507684250676977,8.522171002045239,8.530319682893834,8.536657536129924,8.543900431285305,8.550238058934205,8.560196690948585,8.570155393955224,8.576492252951484,8.583734721689225,8.586450528966454\",\n \"Longitude\": \"6.4649538695812225,6.4649538695812225,6.4594607055187225,6.4594607055187225,6.458545066416264,6.457629427313805,6.4567141234874725,6.457629427313805,6.4567141234874725,6.454882845282555,6.4539675414562225,6.454882845282555,6.453051902353764,6.4539675414562225,6.453051902353764,6.4512209594249725,6.450305320322514,6.449389681220055,6.4484743773937225,6.446643099188805,6.4457277953624725,6.443896517157555,6.4429812133312225,6.442065574228764,6.441149935126305,6.438403353095055,6.4356567710638055,6.432910189032555,6.429248303174972,6.426501721143723,6.4200929179787645,6.4182619750499725,6.4109375327825555,6.409106589853763,6.4017824828624725,6.3990359008312225,6.395373679697514,6.391711458563805,6.387133933603764,6.3798098266124725,6.3770632445812225,6.376147605478764,6.3715700805187225,6.3688234984874725,6.366076916456223,6.3624146953225145,6.360583752393722,6.357837170362473,6.356005892157555,6.3541749492287645,6.353259310126305,6.3505127280950555,6.346850842237473,6.3450195640325555,6.3404420390725145,6.3386110961437225,6.3358645141124725,6.332202292978764,6.329455710947514,6.323962546885014,6.3221316039562225,6.317553743720055,6.314807161688805,6.3083986937999725,6.306567415595055,6.301074251532555,6.299243308603764,6.295581087470055,6.293750144541264,6.291003562510014,6.291003562510014,6.288256980478764,6.288256980478764,6.287341341376305,6.287341341376305,6.286426037549972,6.285510398447514,6.286426037549972,6.286426037549972,6.286426037549972,6.285510398447514,6.285510398447514,6.285510398447514,6.285510398447514,6.2845947593450555,6.2845947593450555,6.2845947593450555,6.2845947593450555,6.2845947593450555,6.2845947593450555,6.2845947593450555,6.285510398447514,6.287341341376305,6.291003562510014,6.2919192016124725,6.297412365674973,6.3001589477062225,6.307483054697514,6.312060579657555,6.3541749492287645,6.3633303344249725,6.391711458563805,6.3990359008312225,6.426501721143723,6.434741467237472,6.461291648447514,6.4677004516124725,6.4878418296575555,6.4924196898937225,6.512561067938805,6.516223289072514,6.529956199228764,6.5336184203624725,6.545520052313805,6.5473513305187225,6.556506380438805,6.560168601572513,6.564746126532554,6.5693239867687225,6.5784790366888055,6.5821412578225145,6.594958528876305,6.600451692938805,6.603198274970055,6.6050295531749725,6.6160158812999725,6.623339988291264,6.6297487914562225,6.633410677313804,6.637072898447513,6.641650423407554,6.645312644541263,6.6480592265725145,6.651721447706223,6.653552390635013,6.659045554697514,6.661792136728764,6.6645387187600145,6.667285300791264,6.669116243720055,6.671862825751305,6.674609407782555,6.675525046885014,6.677355989813805,6.677355989813805\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": 7.798398,\n \"PositionLongitude\": 6.74189,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": null,\n \"Status\": 0,\n \"Street\": \"Lokoja\",\n \"TotalHectaresTilled\": null,\n \"Town\": \"Kogi\",\n \"TractorID\": 500325,\n \"TractorModelID\": 9,\n \"TractorName\": \"02 KOGI WEST\",\n \"UpdatedAt\": \"2019-10-30 16:10:11\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": false,\n \"license_plate_number\": \"KG102LKJ\",\n \"_acl\": {\n \"creator\": \"5afeb568d0f0061782c40b12\"\n },\n \"_kmd\": {\n \"lmt\": \"2019-04-13T23:01:13.411Z\",\n \"ect\": \"2018-06-19T11:10:52.510Z\"\n },\n \"TotalDistanceCovered\": 59724,\n \"Heading\": null,\n \"FuelRawValue\": null,\n \"IgnitionStatus\": null,\n \"AssetState\": null,\n \"FuelLevelVoltage\": 0\n },\n \"500339\": {\n \"_id\": \"5af574d14c356779d5bb40a1\",\n \"BookingRequests\": true,\n \"Characteristic\": \"109,102,103,107\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 619,\n \"FixedEngineHours\": 0,\n \"FuelVolume\": 52,\n \"Group\": \"sawonjo\",\n \"LastActiveTime\": \"2019-10-03 16:43:10\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"38.79894932566223,40.55469249812395,35.86937327950376,30.13384528068626,25.478980839076183,17.8201641281377,10.681495212698072,-2.9432481722329658,-11.981876882967889,-18.746198364908395,-25.567245491064458,-32.909507875101994,-36.93679966016061,-40.76202438133939,-44.253582810499815,-46.10882996422889,-48.1384293251279,-48.951671633440206,-49.296216001688435,-49.41053037288745,-49.06679009059163,-46.83400664517555,-44.504448163320575,-42.33791559645093,-38.18874241559357,-33.35039351137441,-28.38203060874967,-21.872779275822598,-15.052839281125827,-9.22220351605437,-2.5926690431767656,4.5967183771835,10.508997053754618,17.65301328753066,21.94484582756054,26.268477382826756,31.49029361375234,31.78910873523986,35.584437013079594,39.07196017020207,40.55469249812395,42.13556727576628,42.91157808883026,43.039975749630244,43.29597001532017,43.29597001532017,42.005295396074075,41.48153302120895\",\n \"Longitude\": \"21.865004114806652,-14.637532755732536,-23.412186428904533,-32.362329997122295,-38.504584953188896,-42.365425676107414,-44.47134967893362,-46.22627913951874,-45.87528929114342,-44.822329804301255,-43.59388276934624,-41.31247121840716,-37.802612632513046,-33.5907793790102,-30.431905947625637,-24.64063815772533,-19.726835265755653,-15.514998659491539,-9.723733551800251,-4.107953645288944,1.8588030338287356,10.984442196786402,18.004161715507507,22.04050373286009,29.060223251581192,33.79853121936321,38.18586174398661,41.344725787639625,44.50360424816609,45.03007661551237,45.381071493029594,45.381071493029594,44.85458437353372,43.80163460969925,42.222197726368904,39.940791204571724,36.25542797148228,36.25542797148228,32.21909198909998,28.533741161227226,27.12979417294264,25.72585489600897,24.146415665745735,21.514021642506123,16.073740012943745,7.123598791658878,-6.213872954249381,-9.197251796722412\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": 6.567458,\n \"PositionLongitude\": 3.035225,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 0,\n \"Status\": 0,\n \"TotalHectaresTilled\": null,\n \"TractorID\": 500339,\n \"TractorModelID\": 9,\n \"TractorName\": \"FAD001OG\",\n \"UtcOffset\": 0,\n \"WasInArea\": true,\n \"license_plate_number\": \"FAD001OG\",\n \"_acl\": {\n \"creator\": \"5af571828026bf1bf79e839f\"\n },\n \"_kmd\": {\n \"lmt\": \"2019-04-13T23:01:08.634Z\",\n \"ect\": \"2018-05-11T10:47:45.000Z\"\n },\n \"ActiveTimeToday\": 0,\n \"Town\": \"Ogun\",\n \"Country\": \"Nigeria\",\n \"Street\": \"Araromi\",\n \"UpdatedAt\": \"2019-10-30 16:09:32\",\n \"TotalDistanceCovered\": 5068,\n \"Heading\": 111,\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"FuelLevelVoltage\": 0,\n \"PrevTempFuelData\": []\n },\n \"500371\": {\n \"_id\": \"594a8cffc6cc75e018a68ff8\",\n \"ActiveTimeToday\": 0,\n \"BookingRequests\": true,\n \"Characteristic\": \"102,103,107\",\n \"Country\": \"Nigeria\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 282,\n \"FixedEngineHours\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"TRAXI\",\n \"Heading\": 292,\n \"ImplementsAttached\": \"102,103,107\",\n \"LastActiveTime\": \"2019-10-17 16:49:22\",\n \"LastGeofenceNotificationTime\": \"2019-05-09T04:28:17.359Z\",\n \"Latitude\": \"9.990129902809482,9.990129902809482,9.991482368696945,9.991482368696945,9.993511056982314,9.997568395579124,9.996892175996377,10.062478911548828,10.060450654988962,10.060450654988962,10.06315499423759,10.067211460636273,10.070591810354589,10.07397212465416,10.078028455044844,10.081408691383052,10.084788892266053,10.087493027437036,10.089521113915788,10.089521113915788,10.08884508650873,10.084788892266053,10.080056601101758,10.072620003185301,10.06315499423759,9.984043736734638,9.984043736734638,9.984043736734638,9.983367489033077,9.983367489033077,9.984043736734638,9.986072471408525,9.986072471408525,9.986072471408525,9.983367489033077,9.9806624841779,9.976604934758441,9.973899873729541,9.96916596288986,9.964431983299999,9.957669036116048,9.951582263818539,9.942113725869078,9.933321266456701,9.925881308534112,9.920470323849328,9.91844118154797,9.917764797988301,9.917764797988301,9.919793944478576,9.922499453582303,9.926557675333186,9.933997617880324,9.94279005910746,9.950229632342495,9.954287509961622,9.95564012462719,9.96172682125041,9.96172682125041,9.962403113866124,9.963079405079684,9.963079405079684,9.965108270306562,9.966460840112031,9.96713712291076,9.96848968429977,9.96848968429977,9.971871063218648,9.974576141092555,9.976604934758441,9.978633715787716,9.98133873749884,9.986072471408525,9.988777431298432\",\n \"Longitude\": \"7.37471491098404,7.376088201999664,7.378148138523101,7.380208075046539,7.385701239109039,7.391881048679351,7.396000921726227,7.392567694187164,7.396687567234039,7.398747503757476,7.400120794773103,7.402867376804353,7.402867376804353,7.404927313327789,7.40767389535904,7.409047186374664,7.411793768405914,7.415913641452789,7.421406805515289,7.428273260593414,7.439946234226227,7.452992498874664,7.46809870004654,7.481144964694978,7.496937811374664,7.52303034067154,7.52303034067154,7.52440396696329,7.525090612471104,7.525090612471104,7.52646390348673,7.52715054899454,7.52715054899454,7.528523840010167,7.52989713102579,7.530583776533604,7.532643713057042,7.532643713057042,7.532643713057042,7.531957067549229,7.52989713102579,7.529210485517979,7.525090612471104,7.520284093916415,7.516850866377355,7.51067105680704,7.505177892744541,7.498311437666416,7.489384710788727,7.477712072432042,7.466038763523101,7.453679144382477,7.440632879734038,7.426899969577788,7.415913641452789,7.406987249851228,7.402180731296539,7.37746149301529,7.372654974460602,7.368535101413726,7.36098200082779,7.358235418796539,7.352742254734038,7.349309027194978,7.347935736179352,7.346562445163727,7.346562445163727,7.345875799655914,7.346562445163727,7.347935736179352,7.348622381687164,7.349309027194978,7.349995672702788,7.349309027194978\",\n \"NeedToSendGeofenceOutNotification\": false,\n \"OperatorID\": 0,\n \"PositionLatitude\": 11.167208,\n \"PositionLongitude\": 7.951952,\n \"Speed\": 0,\n \"Status\": 0,\n \"Street\": \"Ricifa\",\n \"TotalDistanceCovered\": 1928,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Kaduna\",\n \"TractorID\": 500371,\n \"TractorModelID\": 9,\n \"TractorName\": \"TRAXI/TRMH0074-110\",\n \"UpdatedAt\": \"2019-10-30 16:10:24\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": false,\n \"_acl\": {\n \"creator\": \"593aa855ecdebb2558589e6f\"\n },\n \"license_plate_number\": \"YAB110YR\",\n \"_kmd\": {\n \"lmt\": \"2019-05-08T12:04:46.322Z\",\n \"ect\": \"2017-06-21T15:13:03.931Z\"\n },\n \"FuelRawValue\": 12400,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"FuelLevelVoltage\": 0,\n \"PrevTempFuelData\": []\n },\n \"500459\": {\n \"_id\": \"5ca45ec55d18a8036b7955c3\",\n \"ActiveTimeToday\": 0,\n \"BookingRequests\": true,\n \"Characteristic\": \"109,102,103\",\n \"Country\": \"Nigeria\",\n \"CreatedAt\": \"2019-04-03 07:20:38\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 91,\n \"FixedEngineHours\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"\",\n \"Heading\": 12,\n \"ImplementsAttached\": \"103\",\n \"LastActiveTime\": \"2019-09-07 14:18:45\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"7.126032468334042,7.125980236574781,7.125953954349724,7.125898063030659,7.125741035002532,7.1255430864582125,7.125262964170414,7.1248520956594845,7.124571972949397,7.124258248618381,7.12385103877413,7.123455139967675,7.122678312324535,7.121998628643314,7.12124408875115,7.120698809811194,7.1201608494163615,7.119343095177259,7.118401578116947,7.118035616900647,7.117643372691096,7.117329643620545,7.117102081785108,7.116829273588053,7.116597719186218,7.116246727736527,7.115910374540924,7.115686471634078,7.115510809247366,7.115387712459013,7.115406343326405,7.1154436050589,7.115481199482362,7.115694123592575,7.116037796205842,7.116463643811045,7.116874519836825,7.117326316693937,7.117778113106219,7.11821893023729,7.118738262178109,7.119212680208568,7.11991465830166,7.120777657385611,7.121550495973457,7.122402180554004,7.123444161256407,7.124127835047505,7.124478820466304,7.125024094910902,7.125565709153313,7.1260737214390435,7.126458306658705,7.126794319432467,7.127003578748255,7.1270894116355334,7.1271379837274,7.127063129474088,7.1265700891533665,7.125535767350742,7.124639175800439,7.124008067449728,7.123671719945333\",\n \"Longitude\": \"3.325838595628739,3.3257178962230682,3.32542821764946,3.3252662792801857,3.3249048516154285,3.3245474472641945,3.3241974189877506,3.323775976896286,3.3234259486198425,3.323162421584129,3.3227822184562683,3.322526402771473,3.322180062532425,3.3219919726252556,3.321894071996212,3.3218186348676677,3.321826346218586,3.321943022310734,3.322071097791195,3.3221461996436124,3.322390951216221,3.322586752474308,3.322816416621208,3.323008194565773,3.3231966197490697,3.323437348008156,3.323844037950039,3.3241149410605426,3.3244649693369865,3.3249356970190997,3.325601890683174,3.326015956699848,3.326430022716522,3.3269530534744263,3.3275478333234787,3.3281349018216133,3.328556343913078,3.3289744332432742,3.329392187297344,3.329685553908348,3.3299303054809575,3.33013717085123,3.330114707350731,3.3300355821847916,3.3298813551664357,3.3296778425574307,3.3292902633547783,3.329060599207878,3.328819535672664,3.3284356445074077,3.328010179102421,3.327671550214291,3.327343985438347,3.3269376307725906,3.32650076597929,3.3260756358504295,3.3256954327225685,3.325326628983021,3.3249125629663467,3.32446463406086,3.324170932173729,3.324061967432499,3.324009329080582\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": 7.118708,\n \"PositionLongitude\": 3.325646,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 0.72,\n \"Status\": 0,\n \"Street\": \"Apana\",\n \"TotalDistanceCovered\": 2862,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Ogun\",\n \"TractorID\": 500459,\n \"TractorModelID\": 32,\n \"TractorName\": \"Hunters farm\",\n \"UpdatedAt\": \"2019-10-30 15:34:37\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"_acl\": {\n \"creator\": \"5ca3b7bebbe8a3456d30b2a9\"\n },\n \"license_plate_number\": \"001\",\n \"_kmd\": {\n \"lmt\": \"2019-05-14T07:32:58.861Z\",\n \"ect\": \"2019-04-03T07:20:37.614Z\"\n },\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"FuelLevelVoltage\": 0\n },\n \"500505\": {\n \"_id\": \"5af167e026860c399aaa7a4b\",\n \"ActiveTimeToday\": 0,\n \"BookingRequests\": true,\n \"Characteristic\": \"101,102,103,104,115\",\n \"Country\": \"Nigeria\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 337,\n \"FixedEngineHours\": 0,\n \"FuelVolume\": 2673871,\n \"Group\": \"\",\n \"Heading\": 0,\n \"ImplementsAttached\": \"103,102\",\n \"LastActiveTime\": \"2019-03-22 16:40:25\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"6.868159172855465,6.865886995653977,6.862705396746553,6.857706269011194,6.851797657140675,6.820891263087424,6.794527939480037,6.764072323851795,6.7322509680004226,6.700882051642392,6.66996567196788,6.640411754465232,6.614038647738086,6.58993827861708,6.5672006871319395,6.549464731029113,6.532182825670382,6.516719772626977,6.504894567330872,6.499436737630093,6.499891781115418,6.507168756585501,6.517629161648553,6.5340022121163805,6.561743537108293,6.595394785898691,6.6276799710967165,6.664055097428197,6.698608752243771,6.731341641542712,6.75998110961792,6.785437101309771,6.807255356815636,6.824527217301801,6.8408896680087175,6.853615853000594,6.861796649902491,6.866341365388092,6.864523550975848,6.860887568448733,6.858160646552501\",\n \"Longitude\": \"5.511471815407276,5.501858778297902,5.494077019393444,5.484921634197234,5.475766249001026,5.444638542830944,5.425870120525359,5.409390628337859,5.397488661110401,5.388791263103485,5.38467139005661,5.386502332985401,5.392453484237194,5.402066521346569,5.415341444313525,5.429989993572236,5.449673719704151,5.47530859708786,5.504147708415986,5.534817762672901,5.566403456032275,5.595700554549694,5.620419792830944,5.641476809978485,5.661618523299693,5.677640028297901,5.687253065407276,5.691830925643444,5.690915286540985,5.684964470565319,5.677182376384735,5.665280409157276,5.650632195174694,5.6336947157979,5.61263769865036,5.59066504240036,5.567319095134734,5.545804090797901,5.524289421737195,5.508725233376026,5.503690056502818\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": 6.64314,\n \"PositionLongitude\": 5.58151,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 0,\n \"Status\": 0,\n \"Street\": \"Ute\",\n \"TotalDistanceCovered\": 2435,\n \"TotalHectaresTilled\": 0,\n \"Town\": \"Ondo\",\n \"TractorID\": 500505,\n \"TractorModelID\": 9,\n \"TractorName\": \"JD5065+PLANTER\",\n \"UpdatedAt\": \"2019-10-30 01:59:09\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"_acl\": {\n \"creator\": \"59c8d84f8c59558e131dd898\"\n },\n \"license_plate_number\": \"1PY5065EAHP022688\",\n \"_kmd\": {\n \"lmt\": \"2019-09-20T08:38:15.014Z\",\n \"ect\": \"2019-09-20T08:38:06.661Z\"\n }\n },\n \"500511\": {\n \"_id\": \"59d363018f57b7f96ef862a0\",\n \"ActiveTimeToday\": 25207,\n \"BookingRequests\": true,\n \"Characteristic\": \"101,102,103,104,107,110,109\",\n \"Country\": \"Senegal\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 2339,\n \"FixedEngineHours\": 0,\n \"FixedOdometerReading\": 0,\n \"FuelLitres\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"\",\n \"Heading\": 99,\n \"ImplementsAttached\": \"102,107\",\n \"LastActiveTime\": \"2019-10-30 15:58:06\",\n \"LastGeofenceNotificationTime\": \"2019-10-30T15:10:34.192Z\",\n \"Latitude\": \"16.242390025748108,16.24239066953661,16.242391313325125,16.242391313325125,16.242392279007888,16.242392600902132,16.242392600902132,16.242393244690636,16.242393244690636,16.242392279007888,16.24239195711363,16.24239066953661,16.242389381959594,16.242388094382576,16.24238712869979,16.242385841122758,16.242383587862903,16.242381978391577,16.242379725131673,16.24237811566032,16.242374574823256,16.24237167777472,16.242368780726135,16.242366205571805,16.24236395231172,16.2423588020029,16.242352686010985,16.242347535701867,16.242343672969923,16.24234077592093,16.24233916644925,16.24233820076622,16.24233659129451,16.242335303717148,16.24233401613976,16.242332406668016,16.242329187724497,16.24232661256965,16.242324037414757,16.24232242794295,16.24232017468237,16.242318887104894,16.242317599527404,16.242316955738648,16.242315668161144,16.242315024372388,16.242314380583633,16.24231341490049,16.242313093006118,16.242313093006118,16.242313093006118,16.242313093006118,16.242312449217348,16.242312127322975,16.242312127322975,16.242313093006118,16.24231341490049,16.242314380583633,16.242315668161144,16.242316955738648,16.242318565210507,16.24232017468237,16.24232242794295,16.242324681203478,16.24232661256965,16.24233015340756,16.242334338034112,16.242336913188872,16.242339488343582,16.242343029181267,16.24234624812456,16.242348823279155,16.242351398433712,16.242353329799613,16.24235590495412,16.24235719253137,16.242359123897195,16.24236234284023,16.242364274206018,16.242366849360383,16.24236910262043,16.242370712091873,16.242372643457568,16.242373931034702,16.242375218611823,16.24237650618893,16.242377793766035,16.242378437554592,16.242379725131673,16.242380690814496,16.242381978391577,16.242383265968645,16.24238423165143,16.242384875439974,16.242385841122758,16.242386163017017,16.242387450594048,16.242388094382576,16.24238873817108,16.242389703853863,16.242390025748108,16.24239066953661,16.242390991430884,16.242391313325125,16.242391313325125,16.242391313325125,16.242391313325125,16.242390991430884,16.242390991430884,16.242390991430884,16.24239066953661,16.24239066953661,16.242390025748108,16.242390025748108,16.242390025748108,16.242390025748108,16.242389703853863,16.242389703853863,16.242389703853863,16.24238873817108,16.242389381959594,16.24238873817108,16.24238873817108,16.242388416276835,16.242388094382576,16.242388094382576,16.242387450594048,16.24238712869979\",\n \"Longitude\": \"-16.21344354003668,-16.213443875312805,-16.213444210588932,-16.213444210588932,-16.213445216417313,-16.21344622224569,-16.21344655752182,-16.21344789862633,-16.213448233902454,-16.213449575006962,-16.21345091611147,-16.213452257215977,-16.213453598320484,-16.213455609977245,-16.21345695108175,-16.21345829218626,-16.21346030384302,-16.213461309671402,-16.21346298605204,-16.21346365660429,-16.213465332984924,-16.213466674089428,-16.21346801519394,-16.213469356298447,-16.213469691574574,-16.213471703231335,-16.213473044335842,-16.21347337961197,-16.21347337961197,-16.21347337961197,-16.21347237378359,-16.21347237378359,-16.213471703231335,-16.21347103267908,-16.213470362126827,-16.213469691574574,-16.21346835047007,-16.213466674089428,-16.213464327156544,-16.213462315499786,-16.213459968566895,-16.21345728635788,-16.21345493942499,-16.213452257215977,-16.213450245559216,-16.21344789862633,-16.213444881141186,-16.213438846170902,-16.213433146476746,-16.213429123163223,-16.213425435125828,-16.213422752916813,-16.213418394327164,-16.213414035737514,-16.213409677147865,-16.213404648005962,-16.213401965796947,-16.213398277759552,-16.21339526027441,-16.213392578065395,-16.213390231132507,-16.213388554751873,-16.213385872542858,-16.21338352560997,-16.21338151395321,-16.21337816119194,-16.21337614953518,-16.21337480843067,-16.213374137878418,-16.21337380260229,-16.21337380260229,-16.21337380260229,-16.213374137878418,-16.2133751437068,-16.213375478982925,-16.21337648481131,-16.213377825915813,-16.213378831744194,-16.213380843400955,-16.213382855057716,-16.213384866714478,-16.21338687837124,-16.213388554751873,-16.21338989585638,-16.213391236960888,-16.213392913341522,-16.21339526027441,-16.213396936655048,-16.213398948311806,-16.213400959968567,-16.213403642177582,-16.213405653834343,-16.213407330214977,-16.213409677147865,-16.213411353528496,-16.213412694633007,-16.213414035737514,-16.213415376842022,-16.213416717946526,-16.21341772377491,-16.21341872960329,-16.21342074126005,-16.213422417640686,-16.213425435125828,-16.213428117334843,-16.21343046426773,-16.21343281120062,-16.213434487581253,-16.213435493409634,-16.21343716979027,-16.21343817561865,-16.213438510894775,-16.213439851999283,-16.213440857827663,-16.21344119310379,-16.21344219893217,-16.21344219893217,-16.213442869484425,-16.21344354003668,-16.213443875312805,-16.213444210588932,-16.213445216417313,-16.21344555169344,-16.21344622224569,-16.213446892797947,-16.213448233902454,-16.213448904454708,-16.213448904454708\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": 16.273214,\n \"PositionLongitude\": -16.15888,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 2.33,\n \"Status\": 0,\n \"Street\": \"Ross-Bétio\",\n \"TotalDistanceCovered\": 13594,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Saint-Louis\",\n \"TractorID\": 500511,\n \"TractorModelID\": 2,\n \"TractorName\": \"TracteurNewHolland2\",\n \"UpdatedAt\": \"2019-10-30 16:03:28\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": false,\n \"_acl\": {\n \"creator\": \"59d35f4257f0e7db045c2e9f\"\n },\n \"_kmd\": {\n \"lmt\": \"2019-08-22T12:04:12.816Z\",\n \"ect\": \"2017-10-03T10:14:25.732Z\"\n },\n \"license_plate_number\": \"1333109006\",\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 1,\n \"AssetState\": \"On\",\n \"FuelLevelVoltage\": 0\n },\n \"500512\": {\n \"_id\": \"59d363643297aa7369fc4c9c\",\n \"ActiveTimeToday\": 0,\n \"BookingRequests\": false,\n \"Characteristic\": \"108\",\n \"Country\": \"Senegal\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 0,\n \"FixedEngineHours\": 0,\n \"FuelLitres\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"\",\n \"Heading\": null,\n \"ImplementsAttached\": \"108\",\n \"LastActiveTime\": \"1970-01-01 00:00:00\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"16.328743949113463,16.328241692734622,16.32623361959142,16.320208632946816,16.31117096604907,16.306652137036192,16.304643520588947,16.30263520533968,16.300626547703015,16.295605135329044,16.28706869650737,16.278531564235426,16.270998870617273,16.264972185737662,16.259949860693663,16.25593197258049,16.250407282515596,16.24387781536713,16.23684596286142,16.230818230726584,16.226297551911994,16.22278118200325,16.22026949675654,16.219265071234528,16.219265071234528,16.219265071234528,16.219767284635818,16.22026949675654,16.22278118200325,16.22931134932403,16.23684596286142,16.24387781536713,16.248398412119606,16.25090973831712,16.253923158651318,16.256936532779388,16.26095440034867,16.26748330009722,16.273509907894574,16.278531564235426,16.282046936854304,16.285562246476946,16.288575134965292,16.292592354873122,16.296107475440184,16.299622211162173,16.30263520533968,16.30614982396067,16.309664701297915,16.31368148880911,16.31769819390293,16.322217089698565,16.32522941440983,16.326735559371013,16.32773975682018,16.328743949113463,16.329245882450717,16.32974781449972,16.330751996482103,16.330751996482103,16.33125392466532,16.330751996482103,16.330751996482103,16.330751996482103,16.330250067010507,16.330250067010507,16.32974781449972,16.32974781449972,16.32974781449972,16.330250067010507,16.331756173307774\",\n \"Longitude\": \"-16.19981825351715,-16.200341284275055,-16.204003505408764,-16.215512864291668,-16.231730841100216,-16.237485520541668,-16.240624375641346,-16.242717169225216,-16.244809627532955,-16.247948817908764,-16.253180466592312,-16.258935146033764,-16.262074001133442,-16.264166794717312,-16.26521285623312,-16.264166794717312,-16.26364342868328,-16.260504573583603,-16.257365718483925,-16.254226528108116,-16.250564642250538,-16.24690242111683,-16.242717169225216,-16.23957831412554,-16.236439123749733,-16.233300268650055,-16.230684444308277,-16.226499192416668,-16.21969811618328,-16.207142360508445,-16.194586604833603,-16.186216101050377,-16.180461421608925,-16.17732223123312,-16.17470640689135,-16.172613948583603,-16.16947509348393,-16.16685926914215,-16.165289841592312,-16.16476647555828,-16.163720078766346,-16.163197048008442,-16.163197048008442,-16.162150651216507,-16.162674017250538,-16.161627620458603,-16.161627620458603,-16.1611045897007,-16.1611045897007,-16.161627620458603,-16.161627620458603,-16.161627620458603,-16.161627620458603,-16.162150651216507,-16.162150651216507,-16.162674017250538,-16.163197048008442,-16.164243444800377,-16.165812872350216,-16.168951727449894,-16.17941502481699,-16.193017177283767,-16.200864650309086,-16.205572932958603,-16.209235154092312,-16.21080458164215,-16.211850643157963,-16.21237400919199,-16.212897039949894,-16.212897039949894,-16.21237400919199\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": 16.2423715,\n \"PositionLongitude\": -16.213420499999998,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": null,\n \"Status\": 0,\n \"Street\": \"Nditi\",\n \"TotalDistanceCovered\": 0,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Saint-Louis\",\n \"TractorID\": 500512,\n \"TractorModelID\": 29,\n \"TractorName\": \"MoissoneuseSakpattana\",\n \"UpdatedAt\": \"2019-10-30 16:03:28\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"_acl\": {\n \"creator\": \"59d35f4257f0e7db045c2e9f\"\n },\n \"license_plate_number\": \"1333119011\",\n \"_kmd\": {\n \"lmt\": \"2019-07-10T18:38:10.871Z\",\n \"ect\": \"2017-10-03T10:16:04.493Z\"\n },\n \"FuelRawValue\": null,\n \"IgnitionStatus\": null,\n \"AssetState\": null,\n \"FuelLevelVoltage\": 0\n },\n \"500513\": {\n \"_id\": \"59d3615f8c59558e13413540\",\n \"ActiveTimeToday\": 0,\n \"BookingRequests\": true,\n \"Characteristic\": \"108\",\n \"Country\": \"Senegal\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 537,\n \"FixedEngineHours\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"\",\n \"Heading\": 28,\n \"ImplementsAttached\": \"108\",\n \"LastActiveTime\": \"2019-10-29 22:05:40\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"16.25648881049271,16.25648881049271,16.256714763923778,16.256714763923778,16.257166991876446,16.257845170919353,16.258975571411177,16.261010404651177,16.2646274762997,16.268244803181588,16.270731415253838,16.27253986987282,16.273670185779075,16.274800495175906,16.275704866742235,16.276608912302684,16.277513275534943,16.27864356279645,16.280225696557892,16.281130043119575,16.28180813939018,16.282260309544682,16.28248623331679,16.282938401908204,16.282938401908204,16.282938401908204,16.28271247865688,16.28248623331679,16.282034385512354,16.281582214837094,16.28090411778556,16.280225696557892,16.27909541841066,16.27773920477357,16.27615672912358,16.274348307829943,16.271861741573918,16.269601082425403,16.267340397245093,16.265531894731375,16.26327116270266,16.261010404651177,16.258523669489197,16.256262856801822,16.25377573967567,16.251741153391862,16.249932507275705,16.248575770354574,16.247445310044053,16.246088877846674,16.244280179730268,16.242471464977765,16.240888705212576,16.239305932710824,16.238175419112434,16.23727119669762,16.236140671406478,16.2350101396193,16.233879601336483,16.232749056558443,16.23161850528558,16.230487947518295,16.23026164203708,16.229809674123732,16.229357383257003,16.228905091350967,16.22867910596659,16.228452798405705,16.228452798405705,16.228452798405705,16.22867910596659,16.22913107647591,16.229357383257003,16.229583367862663,16.230035658210138,16.230713930825946,16.231392201104313,16.23184448729511,16.232522753677195,16.233201017721626,16.2343315599031,16.235462095589195,16.23727119669762,16.239079959270768,16.240888705212576,16.242471464977765,16.24405389011374,16.246088877846674,16.24767159575754,16.24948026267574,16.251288912953118,16.25264530927024,16.254002018101634,16.255358395693886,16.25694103896543,16.258071444659176,16.25942779416003,16.26055818554553,16.261688570426287,16.262593002391707,16.263497108332736,16.264401531970076,16.265531894731375,16.26598410238523,16.26711445603693,16.267792600734072,16.26847074308902,16.26937514381877,16.27005328070755,16.270731415253838,16.271409547457573,16.27208767731865,16.27253986987282,16.272992061385242,16.27344425185591,16.273670185779075,16.274122374687416,16.274348307829943,16.27457456255393,16.274800495175906,16.27525268148002,16.275704866742235,16.27615672912358,16.276608912302684,16.27728702419909,16.2770610944398,16.27728702419909,16.277513275534943,16.27773920477357,16.278191384306044,16.27796513375208,16.27796513375208,16.27796513375208,16.27796513375208,16.27796513375208,16.278191384306044,16.278191384306044,16.278417312763896,16.278417312763896,16.278417312763896,16.27864356279645,16.27864356279645,16.278869490733634,16.27909541841066,16.27909541841066,16.279321667661268,16.279321667661268,16.27954759481761,16.27977384354679,16.279999770182435,16.280225696557892,16.280451944505096,16.280451944505096,16.280677870359842,16.280677870359842,16.280677870359842,16.280677870359842,16.280677870359842,16.280677870359842,16.280451944505096,16.280451944505096,16.280225696557892,16.280225696557892,16.279999770182435,16.27977384354679,16.279999770182435,16.279999770182435\",\n \"Longitude\": \"-16.17950890213251,-16.17950890213251,-16.17950890213251,-16.17950890213251,-16.179744265973568,-16.17997996509075,-16.17997996509075,-16.18021532893181,-16.180921755731106,-16.182099245488644,-16.182806007564068,-16.183512434363365,-16.18421886116266,-16.18492528796196,-16.186102777719498,-16.18751596659422,-16.189399883151054,-16.192461289465427,-16.195758059620857,-16.198584102094173,-16.20093908160925,-16.202587634325027,-16.204235851764675,-16.2056490406394,-16.207768321037292,-16.210123300552365,-16.212949343025684,-16.21530432254076,-16.217188239097595,-16.219307854771614,-16.22072070837021,-16.2221335619688,-16.223546750843525,-16.225195303559303,-16.22707922011614,-16.22872743755579,-16.23037599027157,-16.232024542987347,-16.233202032744884,-16.233908459544182,-16.23461488634348,-16.235321648418903,-16.23555701225996,-16.23555701225996,-16.23555701225996,-16.23555701225996,-16.235321648418903,-16.23508594930172,-16.234850585460663,-16.234379522502422,-16.233673095703125,-16.232730969786644,-16.231553480029106,-16.23037599027157,-16.22919850051403,-16.228256709873676,-16.22707922011614,-16.22543066740036,-16.224017813801765,-16.222369261085987,-16.220249645411965,-16.218601427972317,-16.217188239097595,-16.215068958699703,-16.212713979184628,-16.210358999669552,-16.207768321037292,-16.20612010359764,-16.204235851764675,-16.202822998166084,-16.201174445450306,-16.19881946593523,-16.19599375873804,-16.192932352423668,-16.19081273674965,-16.189164184033867,-16.187986694276333,-16.187044903635982,-16.18633847683668,-16.185160987079147,-16.18421886116266,-16.182806007564068,-16.180921755731106,-16.179273538291454,-16.177860349416733,-16.176682859659195,-16.175505369901657,-16.174563579261303,-16.173386089503765,-16.172443963587284,-16.171266473829743,-16.17056004703045,-16.17008898407221,-16.169618256390095,-16.16938255727291,-16.169147193431858,-16.16891149431467,-16.168676130473614,-16.168676130473614,-16.168676130473614,-16.168676130473614,-16.168676130473614,-16.168676130473614,-16.168676130473614,-16.16891149431467,-16.169147193431858,-16.16938255727291,-16.16985362023115,-16.170324683189392,-16.171266473829743,-16.172208599746227,-16.173150390386585,-16.174092516303066,-16.17479894310236,-16.175505369901657,-16.1759764328599,-16.176682859659195,-16.17691855877638,-16.177860349416733,-16.178567111492157,-16.179273538291454,-16.17997996509075,-16.180451028048992,-16.180921755731106,-16.181392818689346,-16.18162851780653,-16.182099245488644,-16.182334944605824,-16.182570308446884,-16.182806007564068,-16.18327673524618,-16.183747798204422,-16.18445422500372,-16.185160987079147,-16.18586741387844,-16.186809204518795,-16.187986694276333,-16.189399883151054,-16.19104810059071,-16.191990226507187,-16.192932352423668,-16.193874143064022,-16.19458056986332,-16.1955226957798,-16.196229122579098,-16.196935549378395,-16.197641976177692,-16.198348738253113,-16.199055165052414,-16.19976159185171,-16.20046801865101,-16.201174445450306,-16.20188120752573,-16.202822998166084,-16.203765124082565,-16.204471550881863,-16.204942613840103,-16.205413341522217,-16.206355467438698,-16.207061894238,-16.207532957196236,-16.208239383995533,-16.209181509912014,-16.210123300552365,-16.21106542646885,-16.21153648942709,-16.212007217109207\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": 16.242279,\n \"PositionLongitude\": -16.213388,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 0.02,\n \"Status\": 0,\n \"Street\": \"Nditi\",\n \"TotalDistanceCovered\": 1360,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Saint-Louis\",\n \"TractorID\": 500513,\n \"TractorModelID\": 29,\n \"TractorName\": \"MoissoneuseNewHolland1\",\n \"UpdatedAt\": \"2019-10-30 16:03:27\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"_acl\": {\n \"creator\": \"59d35f4257f0e7db045c2e9f\"\n },\n \"_kmd\": {\n \"lmt\": \"2019-08-01T17:53:32.578Z\",\n \"ect\": \"2017-10-03T10:07:27.365Z\"\n },\n \"license_plate_number\": \"549806007\",\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"FuelLevelVoltage\": 0\n },\n \"500514\": {\n \"_id\": \"59d362438c59558e13413859\",\n \"ActiveTimeToday\": 14807,\n \"BookingRequests\": true,\n \"Characteristic\": \"101,102,103,104,110,109\",\n \"Country\": \"Senegal\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 2583,\n \"FixedEngineHours\": 0,\n \"FixedOdometerReading\": 0,\n \"FuelLitres\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"\",\n \"Heading\": 78,\n \"ImplementsAttached\": \"102,104,103,101,110,109\",\n \"LastActiveTime\": \"2019-10-30 15:20:27\",\n \"LastGeofenceNotificationTime\": \"2019-10-30T14:43:33.872Z\",\n \"Latitude\": \"16.309586507788957,16.309586507788957,16.310088490266228,16.31109277314162,16.311595073538022,16.31109277314162,16.31109277314162,16.31109277314162,16.31109277314162,16.31109277314162,16.31109277314162,16.31109277314162,16.310088490266228,16.308080230849537,16.30506764221432,16.30356100872646,16.30054835058587,16.298037659480915,16.296029276519665,16.29301618077186,16.290505714991966,16.285484043350195,16.27845335830575,16.271422743172522,16.262382826936314,16.25334249462245,16.241790657731965,16.23224687627084,16.22471240858893,16.219186841724074,16.21516779906749,16.212656338686113,16.211148996368927,16.211148996368927,16.211148996368927,16.21165155240391,16.212656338686113,16.213660797903568,16.21516779906749,16.216172567418653,16.218182088747227,16.220191267645,16.222200747974153,16.224209885874565,16.226721520860977,16.229233123804864,16.231744694701813,16.235763077087277,16.239279215066915,16.242292813659077,16.246813124963587,16.252840366917123,16.25886742403728,16.261880722334613,16.26439187622371,16.26790718024277,16.27242722413824,16.276946842112082,16.284981676018685,16.291007746356893,16.296029276519665,16.299042004143555,16.30105067802517,16.30255700902425,16.304063328441035,16.305569636274583,16.30657394232435,16.30707593252394,16.308080230849537,16.307578243224185\",\n \"Longitude\": \"-16.158525310456753,-16.15957137197256,-16.15957137197256,-16.160094738006592,-16.160094738006592,-16.161141134798527,-16.16323359310627,-16.166895814239975,-16.173173524439335,-16.181544028222557,-16.18677567690611,-16.192007325589657,-16.198808401823044,-16.20560947805643,-16.211887188255787,-16.217642202973366,-16.224443279206753,-16.230197958648205,-16.234906241297722,-16.239091493189335,-16.242753714323044,-16.245892569422722,-16.249031759798527,-16.251647248864174,-16.25321701169014,-16.252170614898205,-16.250601187348362,-16.24746199697256,-16.24380011111498,-16.239091493189335,-16.234383210539818,-16.230197958648205,-16.22705910354853,-16.223919913172722,-16.22130408883095,-16.21868826448917,-16.21659580618143,-16.212933585047722,-16.207701936364174,-16.202470622956753,-16.195669546723366,-16.188345104455948,-16.182590425014496,-16.178405173122883,-16.174742951989177,-16.171081066131592,-16.167418844997883,-16.163756623864174,-16.161141134798527,-16.159048341214657,-16.156955882906914,-16.154863089323044,-16.152770295739174,-16.152770295739174,-16.15224726498127,-16.151724234223366,-16.151724234223366,-16.15224726498127,-16.152770295739174,-16.15381669253111,-16.15434005856514,-16.15434005856514,-16.15434005856514,-16.15434005856514,-16.15434005856514,-16.15434005856514,-16.154863089323044,-16.154863089323044,-16.154863089323044,-16.155386120080948\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": 16.279957,\n \"PositionLongitude\": -16.136543,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 0,\n \"Status\": 0,\n \"Street\": \"Ross-Bétio\",\n \"TotalDistanceCovered\": 13704,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Saint-Louis\",\n \"TractorID\": 500514,\n \"TractorModelID\": 2,\n \"TractorName\": \"TracteurNewHolland1\",\n \"UpdatedAt\": \"2019-10-30 16:03:27\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": false,\n \"_acl\": {\n \"creator\": \"59d35f4257f0e7db045c2e9f\"\n },\n \"_kmd\": {\n \"lmt\": \"2019-08-25T11:56:57.187Z\",\n \"ect\": \"2017-10-03T10:11:15.181Z\"\n },\n \"license_plate_number\": \"1333118832\",\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"FuelLevelVoltage\": 0\n },\n \"500540\": {\n \"_id\": \"5a1bd0dcca023909ce1ed09a\",\n \"BookingRequests\": true,\n \"Characteristic\": \"102\",\n \"Currency\": null,\n \"DailyTractorUpdates\": true,\n \"EngineHours\": 145,\n \"LastActiveTime\": \"2019-08-23 11:10:24\",\n \"Latitude\": \"-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0037018251725653,-2.0037018251725653,-1.999440720085368,-1.999440720085368,-1.998020349263285,-1.9951799390077138,-1.9937595645033754,-1.9909188118182826,-1.9909188118182826,-1.9894984336392585,-1.9894984336392585,-1.9894984336392585,-1.9894984336392585,-1.9894984336392585,-1.9894984336392585,-1.9894984336392585,-1.9894984336392585,-1.9894984336392585,-1.988078054237082,-1.9866576736126185,-1.9866576736126185,-1.9852372917667582,-1.9852372917667582,-1.983816908700341,-1.983816908700341,-1.983816908700341,-1.983816908700341,-1.983816908700341,-1.983816908700341,-1.983816908700341,-1.983816908700341,-1.983816908700341,-1.9852372917667582,-1.9866576736126185,-1.9866576736126185,-1.988078054237082,-1.9894984336392585,-1.9909188118182826,-1.9909188118182826,-1.9937595645033754,-1.9937595645033754,-1.9951799390077138,-1.9951799390077138,-1.996599977212821,-1.996599977212821,-1.996599977212821,-1.996599977212821,-1.998020349263285,-1.998020349263285,-1.998020349263285,-2.0037018251725653,-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0051221910723838,-2.0079629191729085,-2.0093832813718846,-2.0093832813718846,-2.0065425557394576,-2.0065425557394576,-2.0037018251725653,-2.002281458040867,-1.999440720085368,-1.998020349263285,-1.998020349263285,-1.9951799390077138,-1.9894984336392585,-1.988078054237082,-1.988078054237082,-1.988078054237082,-1.988078054237082,-1.9866576736126185,-1.9866576736126185,-1.9852372917667582,-1.9852372917667582,-1.9852372917667582,-1.9852372917667582,-1.9852372917667582,-1.9852372917667582,-1.9852372917667582,-1.983816908700341,-1.9823965244142703,-1.9795557521866027,-1.9781353642467616,-1.9710334063222652,-1.9681926146636222,-1.9653518181646839,-1.9639314181022858,-1.9639314181022858,-1.9639314181022858,-1.9639314181022858,-1.9681926146636222,-1.9710334063222652,-1.9752945847193901,-1.9795557521866027,-1.9937595645033754,-2.0051221910723838,-2.032108572888395,-2.054833879652065,-2.09744262032972,-2.1102247827828555,-2.1258476925274223,-2.140050200562726,-2.175555223123479,-2.1883370685749526,-2.2096399018823347,-2.2195807846620075,-2.2266816136109746,-2.2394630194179626,-2.265025160883902,-2.2749660024221745,-2.299107425303075,-2.3047877797322864,-2.328928697519323,-2.340289144188594,-2.35164949880162,-2.3644294521594977,-2.3899896751047516,-2.402769273447513,-2.41270913892873,-2.4240688962084604,-2.4311683611453576,-2.4538874693214665,-2.4666664632800748,-2.479445669422328,-2.5007437367901315,-2.5121027435049608,-2.536240304179471,-2.540499492130186,-2.5646365224736276,-2.5731550309035667,-2.5845134001546044,-2.5958716677675824,-2.6015507633206054,-2.6256862984854434,-2.6455625474851585,-2.656919926249664,-2.6824740644542944,-2.723643699776149,-2.7491967679304965,-2.754874818494888,-2.777588088962923,-2.783266338464114,-2.7988810484861757,-2.80881778699245,-2.81449588533993,-2.81875444094934,-2.8286906751910985,-2.8272711705239635,-2.8286906751910985,-2.8329491787630086,-2.834368676474258,-2.8414661388959903,-2.8542414612163203,-2.861338466321959,-2.8712746684282715,-2.8812107841113943,-2.889727385685193,-2.9010824201694043,-2.913857074326045,-2.925212200778158,-2.9294703435751193,-2.932309096444383,-2.932309096444383,-2.932309096444383,-2.932309096444383,-2.932309096444383,-2.932309096444383,-2.932309096444383,-2.930889386072291,-2.922373429928289,-2.919534651898356,-2.9081794681168347,-2.9025018333263324,-2.888307956522072,-2.8826302221366475,-2.878371902752301,-2.8684357623464085,-2.862758263903359,-2.8542414612163203,-2.8528219879601644,-2.8528219879601644,-2.8528219879601644,-2.8528219879601644,-2.858499870461463,-2.865596849216551,-2.8698552162687734,-2.874113567455181,-2.8769524594201776,-2.8826302221366475,-2.8840496583912225,-2.888307956522072,-2.8925662386854434,-2.895405084578591,-2.8925662386854434,-2.8925662386854434,-2.8925662386854434,-2.879791344316315,-2.861338466321959,-2.8357881724443703,-2.8003005877237017,-2.760553176870116,-2.716545863754811,-2.693831436960855,-2.6441428259512407,-2.590192546693687,-2.5050033758577834,-2.45104760183876,-2.3985093089306333,-2.3459693330299993,-2.3260885715204833,-2.2849067754429915,-2.208219722470345,-2.171294918905052,-2.1556724723833263,-2.134369213086381,-2.1102247827828555,-2.0875006055891094,-2.0647760998796367,-2.0392102657758064,-2.0306885656250597,-2.0136443605531458,-2.0065425557394576,-1.998020349263285,-1.9752945847193901,-1.9681926146636222,-1.9625110168324091,-1.9554093274825883,-1.9525685092891503,-1.9525685092891503,-1.9525685092891503,-1.9525685092891503,-1.9525685092891503,-1.9525685092891503,-1.9554093274825883,-1.9596702106737953,-1.9639314181022858,-1.9639314181022858,-1.9653518181646839,-1.9681926146636222,-1.9724538003342942,-1.9738741931336283,-1.9752945847193901,-1.9795557521866027,-1.9866576736126185,-1.9894984336392585,-1.9937595645033754,-1.9937595645033754,-1.9937595645033754,-1.9937595645033754\",\n \"Longitude\": \"36.31938323378563,36.31938323378563,36.31938323378563,36.31938323378563,36.31938323378563,36.31938323378563,36.33785929530859,36.356335021555424,36.376231983304024,36.40039298683405,36.42455365508795,36.45013555884361,36.475717797875404,36.502720937132835,36.526881605386734,36.552463844418526,36.57946698367596,36.60504888743163,36.63205236196518,36.657634265720844,36.68179493397474,36.70595593750477,36.7329590767622,36.758540980517864,36.78128041327,36.80544141680002,36.82533837854862,36.84381444007158,36.866553872823715,36.88218746334314,36.897820718586445,36.91061183810234,36.924823857843876,36.93761497735977,36.947563625872135,36.95609103888273,36.96319688111544,36.97030305862427,36.98025170713663,36.98735788464546,36.994463726878166,37.00299113988876,37.00725484639406,37.01293978840113,37.01720349490642,37.02288843691349,37.02715214341879,37.03283675014973,37.03567922115326,37.04278539866209,37.048470340669155,37.055576518177986,37.06126146018505,37.06552483141422,37.07120977342129,37.078315950930126,37.08968583494425,37.098213247954845,37.096792012453086,37.096792012453086,37.096792012453086,37.096792012453086,37.096792012453086,37.096792012453086,37.096792012453086,37.096792012453086,37.096792012453086,37.096792012453086,37.096792012453086,37.096792012453086,37.096792012453086,37.096792012453086,37.096792012453086,37.096792012453086,37.096792012453086,37.096792012453086,37.10389818996191,37.10816156119108,37.106740325689316,37.11384650319815,37.11953144520521,37.12379515171051,37.129480093717575,37.13232256472111,37.138007171452045,37.145113684237,37.15221952646971,37.160746939480305,37.16358941048383,37.172116823494434,37.17922266572714,37.18348637223243,37.1891713142395,37.19485625624657,37.20054119825363,37.20764737576246,37.2133319824934,37.22043816000223,37.226123102009296,37.23322927951813,37.2431779280305,37.250283770263195,37.26449612528086,37.27444477379322,37.28865712881088,37.31423903256655,37.32987228780984,37.342663407325745,37.349769584834576,37.35687542706728,37.35687542706728,37.35971789807081,37.373930253088474,37.37250901758671,37.37250901758671,37.37250901758671,37.37535148859024,37.37819395959377,37.373930253088474,37.37535148859024,37.37535148859024,37.37535148859024,37.37250901758671,37.37250901758671,37.369666546583176,37.369666546583176,37.37250901758671,37.37250901758671,37.37250901758671,37.37250901758671,37.37250901758671,37.373930253088474,37.37535148859024,37.37535148859024,37.37535148859024,37.37535148859024,37.37250901758671,37.369666546583176,37.369666546583176,37.369666546583176,37.369666546583176,37.369666546583176,37.369666546583176,37.36540284007788,37.36540284007788,37.36540284007788,37.362560369074345,37.362560369074345,37.362560369074345,37.35971789807081,37.35971789807081,37.35971789807081,37.35971789807081,37.35971789807081,37.35971789807081,37.35971789807081,37.35687542706728,37.35687542706728,37.35687542706728,37.35261205583811,37.35261205583811,37.35261205583811,37.35261205583811,37.35261205583811,37.35687542706728,37.35687542706728,37.35687542706728,37.35687542706728,37.35687542706728,37.35687542706728,37.35687542706728,37.35687542706728,37.35687542706728,37.35687542706728,37.35261205583811,37.35261205583811,37.35261205583811,37.35687542706728,37.35119082033634,37.35261205583811,37.35261205583811,37.35261205583811,37.349769584834576,37.349769584834576,37.349769584834576,37.349769584834576,37.349769584834576,37.349769584834576,37.349769584834576,37.349769584834576,37.32845105230808,37.284393422305584,37.26449612528086,37.210489846765995,37.18206513673067,37.075473479926586,37.03425832092762,36.994463726878166,36.91487554460764,36.875081285834305,36.80117771029472,36.76422592252493,36.73153784126043,36.69884975999594,36.63205236196518,36.565254628658295,36.5041421726346,36.475717797875404,36.42455365508795,36.40323545783758,36.344965137541294,36.325068175792694,36.305171214044094,36.255428306758404,36.21563404798508,36.20426416397095,36.197157986462116,36.197157986462116,36.192894615232944,36.19147337973118,36.18578843772411,36.17583978921175,36.17157608270645,36.174418553709984,36.174418553709984,36.177261024713516,36.184367202222354,36.197157986462116,36.20568539947271,36.21563404798508,36.227003931999214,36.22984640300274,36.23837348073721,36.24690089374781,36.25258583575487,36.255428306758404,36.25684954226017,36.263955719769,36.26964066177606,36.27248279750347,36.27248279750347,36.27248279750347,36.27248279750347,36.27248279750347,36.27390403300524,36.27248279750347,36.26964066177606,36.26964066177606,36.26679819077253,36.26679819077253,36.26679819077253,36.26679819077253,36.26679819077253,36.26679819077253,36.26679819077253,36.27248279750347,36.2795889750123,36.2881163880229,36.289537623524666,36.293801330029964,36.30232874304056,36.31085582077503,36.313698291778564,36.316540762782104,36.32648941129446,36.34354390203953,36.35065007954836,36.363441199064255,36.36201996356249,36.36201996356249,36.36201996356249\",\n \"OperatorID\": 0,\n \"PositionLatitude\": -1.191367,\n \"PositionLongitude\": 34.621131,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 0.02,\n \"Status\": 0,\n \"TotalHectaresTilled\": null,\n \"TractorID\": 500540,\n \"TractorModelID\": 8,\n \"TractorName\": \"Namanga 75HP 456R\",\n \"_acl\": {\n \"creator\": \"5915628d63067b1a5d1a010f\"\n },\n \"license_plate_number\": \"KTCB 456R\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"LastGeofenceNotificationTime\": \"2019-10-01T11:12:35.697Z\",\n \"WasInArea\": false,\n \"UtcOffset\": 0,\n \"FixedEngineHours\": 883,\n \"_kmd\": {\n \"lmt\": \"2019-04-13T23:01:02.624Z\",\n \"ect\": \"2017-11-27T08:46:20.242Z\"\n },\n \"ActiveTimeToday\": 0,\n \"Town\": \"Migori\",\n \"Country\": \"Kenya\",\n \"Street\": \"Butende\",\n \"UpdatedAt\": \"2019-10-30 01:59:09\",\n \"TotalDistanceCovered\": 1091,\n \"Heading\": 0,\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"FuelLevelVoltage\": 0,\n \"LastMaintenanceNotificationEngineHours\": 73\n },\n \"500917\": {\n \"_id\": \"5be97fe373796c5283732731\",\n \"ActiveTimeToday\": 0,\n \"BookingRequests\": true,\n \"Characteristic\": \"109,102,107\",\n \"Country\": \"Bangladesh\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 5,\n \"FixedEngineHours\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"The Metal (Pvt.) Limited\",\n \"Heading\": 0,\n \"ImplementsAttached\": \"102,109\",\n \"LastActiveTime\": \"2019-10-20 06:21:16\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"24.08857817365685,24.090249965118577,24.091921428699425,24.092757305348098,24.094428736221648,24.094428736221648,24.09359287047701,24.09359287047701,24.091921428699425,24.090249965118577,24.0894140721139,24.086070751657598,24.081891708016066,24.075204893600713,24.068517424357,24.060993834311503,24.052633976540957,24.043437075495955,24.030895063739877,24.018351827741913,24.004971231352307,23.989916167143804,23.97485934229445,23.95980075763826,23.94055646888593,23.918798932537506,23.894526575621658,23.871923983353717,23.850992035891284,23.82921943207166,23.807442866728305,23.789014066972257,23.76974438187857,23.75717579128358,23.74628223561459,23.737063522086743,23.727844463195602,23.72197728241427,23.716110144571402,23.71359548841663,23.71275715660172,23.71359548841663,23.717786452753675,23.72197728241427,23.730358844562037,23.740415884934404,23.752148015188755,23.764717091313,23.778960781216014,23.792364784927788,23.805767712985286,23.818331606101765,23.828381845064452,23.839268827619588,23.851829476853922,23.864388908745376,23.87862135711778,23.892015371467828,23.909592776455472,23.92382025144178,23.938046159271373,23.94892391705043,23.957290822495164,23.964820481339586,23.97485934229445,23.981551379648113,23.988243069322998,23.99409820396572,23.999116591327898,24.00329832922331,24.00831635781307,24.012498102955764,24.01667940588654,24.020860572857732,24.02504191008186,24.02838651446422,24.031731338021267,24.035076074513515,24.037584493190824,24.040928771107215,24.040928771107215,24.04260118360173,24.043437075495955,24.044273268134138,24.04510945532764,24.04594533089578,24.048453537302812,24.0501258518011,24.0509616947132,24.052633976540957,24.05597786252872,24.05765007900766,24.059321967550094,24.060993834311503,24.06266598543139,24.063501746681002,24.06433780862332,24.067681695781353,24.068517424357\",\n \"Longitude\": \"90.48283115029335,90.48099987208843,90.47550670802593,90.4672669619322,90.45170310884714,90.43247703462838,90.41233532130718,90.39127830415966,90.3720522299409,90.35282615572214,90.3336000815034,90.31437400728464,90.29606357216836,90.27775313705206,90.2603580057621,90.24296287447213,90.22648338228464,90.21183516830206,90.19901756197213,90.18711593002081,90.1779605448246,90.16972079873086,90.16331233084203,90.15690352767704,90.15324130654335,90.15232600271702,90.15232600271702,90.15690352767704,90.1614810526371,90.16880549490453,90.1779605448246,90.18894687294959,90.20084884017707,90.21366611123085,90.22556807845831,90.24113193154335,90.25669578462839,90.27409091591834,90.29331699013711,90.31254306435585,90.33268477767706,90.35282615572214,90.3720522299409,90.39127830415966,90.4086734354496,90.42423728853464,90.43888583779335,90.45353405177593,90.46543601900339,90.47550670802593,90.48283115029335,90.48832431435586,90.49198620021345,90.49290183931589,90.49473278224468,90.49564842134713,90.49564842134713,90.49564842134713,90.49473278224468,90.49473278224468,90.49381747841835,90.49290183931589,90.49107089638711,90.49015525728464,90.48923961818217,90.48740867525339,90.48649303615093,90.4855777323246,90.48466209322214,90.48374645411968,90.4819155111909,90.48099987208843,90.4800845682621,90.47916892915963,90.47825329005718,90.47733798623085,90.47550670802593,90.4745914041996,90.47367576509714,90.47276012599468,90.47184482216835,90.47184482216835,90.47184482216835,90.47184482216835,90.47184482216835,90.47184482216835,90.47184482216835,90.47184482216835,90.47092918306589,90.47092918306589,90.47092918306589,90.47092918306589,90.46909824013709,90.46909824013709,90.46909824013709,90.46909824013709,90.46909824013709,90.46909824013709,90.46909824013709\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": 23.920304,\n \"PositionLongitude\": 90.322497,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 0,\n \"Status\": 0,\n \"Street\": \"Bighatpatti\",\n \"TotalDistanceCovered\": 2,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Dhaka\",\n \"TractorID\": 500917,\n \"TractorModelID\": 12,\n \"TractorName\": \"METAL-079-BD\",\n \"UpdatedAt\": \"2019-10-30 01:59:09\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"_acl\": {\n \"creator\": \"5be97e709eae6852e6f63d5c\"\n },\n \"_kmd\": {\n \"lmt\": \"2019-05-06T05:24:51.311Z\",\n \"ect\": \"2019-05-04T11:24:20.378Z\"\n },\n \"license_plate_number\": \"METAL-079-BD\",\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"FuelLevelVoltage\": 0\n },\n \"501374\": {\n \"_id\": \"5cf90ce6c65f7a6ccc3782b6\",\n \"ActiveTimeToday\": 9326,\n \"BookingRequests\": true,\n \"Characteristic\": \"109,102,103,107\",\n \"Country\": \"Ghana\",\n \"CreatedAt\": \"2019-06-06 12:53:57\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 698,\n \"FixedEngineHours\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"\",\n \"Heading\": 2,\n \"ImplementsAttached\": \"102,107\",\n \"LastActiveTime\": \"2019-10-30 14:47:18\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"11.05644377729934,11.05733485140976,11.058671128447118,11.060898133624121,11.063570649118468,11.066688333694122,11.070697018567117,11.075151158186602,11.079159398159854,11.083167912249582,11.086285717125275,11.088512512245828,11.089848646980094,11.09118477560706,11.091630260129875,11.091630260129875,11.091630260129875,11.091630260129875,11.091630260129875,11.091630260129875,11.089848646980094,11.087621862036352,11.084949566108758,11.080495575625752,11.073814956319504,11.064906897725637,11.055998568282112,11.04887151241783,11.044417302519232,11.041744612508245,11.039963025032321,11.038626662795803,11.037290294478764,11.035508350906527,11.03283557982297,11.030162784429455,11.027044711810039,11.023481018716291,11.01991695334843,11.016353173903541,11.012789351304972,11.009225485565988,11.005661576699849,10.999424550170113,10.991850817036296,10.98427688944221,10.977593753959217,10.972247136694449,10.967346095608255,10.962890323746125,10.957098082059181,10.950414332189435,10.943285052170822,10.937492426999427,10.932145085347225,10.929025648465934,10.927243380549395,10.92635191337909,10.925906507988426,10.925015036802735,10.922341594790266,10.917439398896372,10.91030932644587,10.90228754358587,10.894711326436825,10.888917754072075,10.883124069009918,10.875992845169852,10.866633328408179,10.858164533606319,10.850141676623734,10.843009664957272,10.836769221064973,10.830528647060785,10.823842385167412,10.81760121255897,10.811360239369026,10.806010965684008,10.799769751458795,10.792190936315286,10.782828471111499,10.773911676476894,10.766332209872557,10.759644190005087,10.75295635117058,10.74537635775639,10.735120730905345,10.725756493471385,10.715500201084629,10.704797827382608,10.694540825374508,10.68472957007283,10.67313389173865,10.661091643580775,10.65083316617847,10.64369677358495,10.63923652575432,10.637452210648672,10.635667885106185,10.633883878646767,10.62897731282534,10.622286264389889,10.61514920422224,10.610242007958604,10.606673358124214,10.605335062510676,10.605335062510676,10.605335062510676,10.605335062510676,10.605335062510676,10.606227479935454,10.60934993178919,10.615595069404183,10.621394223367776,10.627639114866486,10.63254570219785,10.637006047862723,10.642358640184245,10.65083316617847,10.658415523709794,10.664659656977676,10.670011763355863,10.6753637755401,10.68249942554022,10.690080993534098,10.697216627122184,10.703459962909376,10.708811055929942,10.715500201084629,10.725310789782728,10.735120730905345,10.74537635775639,10.75295635117058,10.759644190005087,10.76766979603561,10.777032732860862,10.787732546122413,10.798877903596196,10.811360239369026,10.8225050490213,10.831865947390165,10.839889623926377,10.847467233343554,10.855936002123094,10.86351320473973,10.871090215055986,10.877775749434981,10.885352397425347,10.894265873631877,10.903179082960696,10.911200512554093,10.918330892826768,10.923232744802757,10.926797647298958,10.930808234870538,10.942393962400965,10.948632192857874,10.954424600219872,10.959325855422772,10.964672706378416,10.971801471172842,10.978930393155752,10.984722207006959,10.988732009627325,10.991405181103417,10.993187391671745,10.994078328356302,10.994523631128178,10.995860193650955,10.996751451380407,10.998978925682572,11.000761090475313,11.004325058620122,11.006106861972835,11.00788898365601,11.009670765451292,11.01145286556973,11.01368022872432,11.016353173903541,11.019471688962248,11.022144581536606,11.024817120734978,11.02838112672065,11.029271956924855,11.03060836171031,11.033726396526065,11.035953920081916,11.038626662795803,11.041744612508245,11.043971746184797,11.04664441591868,11.048426291907363,11.051989682364306,11.053325983758684,11.054216738287481,11.054662279064857,11.054662279064857\",\n \"Longitude\": \"-1.8891136720776558,-1.8909291923046114,-1.8918367847800257,-1.8945598974823954,-1.898190602660179,-1.9036368280649183,-1.914982907474041,-1.9285984709858897,-1.943121291697025,-1.9562828913331034,-1.9667213782668116,-1.9757983088493345,-1.9821521267294882,-1.9889599084854124,-1.9953137263655663,-2.0043906569480896,-2.0139212161302567,-2.024359703063965,-2.0338905975222588,-2.0434211567044254,-2.0543136075139046,-2.065659686923027,-2.0792752504348755,-2.0947059988975525,-2.110590375959873,-2.1264750882983208,-2.1419058367609978,-2.1541595086455345,-2.1623288467526436,-2.1664135158061977,-2.1691366285085674,-2.171405777335167,-2.173674926161766,-2.175036482512951,-2.175944074988365,-2.17730563133955,-2.179575115442276,-2.1836594492197037,-2.188198082149029,-2.1922827512025833,-2.1959134563803673,-2.199544161558151,-2.203174866735935,-2.2077134996652603,-2.2122517973184586,-2.2172440588474274,-2.222236320376396,-2.2267749533057213,-2.2304056584835052,-2.234036363661289,-2.237667068839073,-2.2412981092929845,-2.2444748505949974,-2.247197963297367,-2.249467112123966,-2.249921075999737,-2.2503750398755074,-2.2503750398755074,-2.2503750398755074,-2.2503750398755074,-2.2503750398755074,-2.2503750398755074,-2.2503750398755074,-2.2503750398755074,-2.2503750398755074,-2.249921075999737,-2.2490134835243225,-2.2476519271731377,-2.2458364069461823,-2.2444748505949974,-2.2431132942438126,-2.2417517378926277,-2.2408441454172134,-2.240390181541443,-2.2399365529417996,-2.239028625190258,-2.2385749965906148,-2.2381210327148438,-2.236305847764015,-2.2344903275370602,-2.2313132509589195,-2.2276825457811356,-2.224959433078766,-2.222236320376396,-2.219967171549797,-2.216336466372013,-2.211798168718815,-2.2077134996652603,-2.203174866735935,-2.197728641331196,-2.1913748234510426,-2.1841134130954742,-2.175036482512951,-2.164144366979599,-2.151890359818936,-2.1387287601828575,-2.1264750882983208,-2.115582637488842,-2.1065057069063187,-2.09879033267498,-2.0924365147948265,-2.085175104439259,-2.0770057663321495,-2.0688367635011673,-2.0602134615182877,-2.052498087286949,-2.044329084455967,-2.0366137102246284,-2.0284443721175194,-2.0184598490595813,-2.0066598057746887,-1.992136649787426,-1.9744367524981496,-1.9576444476842882,-1.9435752555727959,-1.931775212287903,-1.9217906892299652,-1.9127137586474416,-1.901821307837963,-1.8922907486557963,-1.8845753744244576,-1.8777675926685333,-1.8727753311395645,-1.8677830696105955,-1.8623368442058563,-1.856890618801117,-1.8518983572721484,-1.8478136882185938,-1.8428214266896248,-1.8364676088094711,-1.830567754805088,-1.8251215294003484,-1.8219444528222082,-1.819675303995609,-1.8178601190447807,-1.8155906349420545,-1.8133214861154558,-1.811506301164627,-1.8101447448134422,-1.8087831884622574,-1.8078752607107165,-1.806514039635658,-1.8051524832844732,-1.8042445555329325,-1.8037909269332884,-1.803336963057518,-1.8024293705821035,-1.8019754067063332,-1.8015214428305628,-1.8006138503551483,-1.800159886479378,-1.7987986654043195,-1.7983447015285492,-1.7974367737770083,-1.7969831451773643,-1.7965291813015938,-1.7956215888261795,-1.7960755527019499,-1.7960755527019499,-1.7960755527019499,-1.7960755527019499,-1.7960755527019499,-1.7965291813015938,-1.7969831451773643,-1.7974367737770083,-1.7992522940039635,-1.7992522940039635,-1.8010678142309187,-1.8028829991817477,-1.8056061118841173,-1.8078752607107165,-1.8101447448134422,-1.8133214861154558,-1.8142294138669968,-1.8155906349420545,-1.8169521912932394,-1.8178601190447807,-1.8192216753959656,-1.821036860346794,-1.8228523805737498,-1.8251215294003484,-1.8269370496273043,-1.830567754805088,-1.8323829397559166,-1.8337444961071014,-1.8369215726852415,-1.8405522778630257,-1.8455445393919945,-1.8505368009209635,-1.854621469974518,-1.8582521751523018,-1.8618832156062128,-1.86869066208601,-1.8714137747883797,-1.8736829236149786,-1.8741368874907494,-1.8741368874907494\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": 10.997795,\n \"PositionLongitude\": -1.957953,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 0.02,\n \"Status\": 0,\n \"Street\": \"Katinia\",\n \"TotalDistanceCovered\": 5386,\n \"TotalHectaresTilled\": null,\n \"Town\": \"\",\n \"TractorID\": 501374,\n \"TractorModelID\": 4,\n \"TractorName\": \"VR302-15\",\n \"UpdatedAt\": \"2019-10-30 15:49:32\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"_acl\": {\n \"creator\": \"5ceff71f6ce9e42a00f2067a\"\n },\n \"_kmd\": {\n \"lmt\": \"2019-06-13T15:44:56.534Z\",\n \"ect\": \"2019-06-06T12:53:58.931Z\"\n },\n \"license_plate_number\": \"VR302-15\",\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"FuelLevelVoltage\": 0\n },\n \"501549\": {\n \"_id\": \"5cff8f88844195038524cbbf\",\n \"ActiveTimeToday\": 0,\n \"BookingRequests\": true,\n \"Characteristic\": \"101\",\n \"Country\": \"Kenya\",\n \"CreatedAt\": \"2019-06-11 11:24:57\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": null,\n \"FixedEngineHours\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"\",\n \"Heading\": 0,\n \"ImplementsAttached\": \"101\",\n \"LastActiveTime\": \"2019-08-16 05:22:19\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"-1.1542397393347297,-1.1448247339938131,-1.1291328781101782,-1.112918340688632,-1.0967033789100122,-1.0804883292835308,-1.0642731931074392,-1.044919640124602,-1.0266121969017536,-1.0083046488537644,-0.9920891431485529,-0.9779657121287471,-0.9622733510556535,-0.9486730899161756,-0.9376882503369406,-0.92513415366644,-0.9131029769553286,-0.9026413283474939,-0.8911330443252886,-0.8806713329175798,-0.869686286438772,-0.8592241799719362,-0.848762044854524,-0.8383002166755363,-0.8278380253041496,-0.8090061456042553,-0.8011597825194291,-0.794359365523757,-0.787035955955907,-0.7818047975655718,-0.7765736326577838,-0.7718654446061496,-0.7676805704312759,-0.765065315331189,-0.763495692160713,-0.7608804345124419,-0.7598341298609369,-0.7598341298609369,-0.7587878249560307,-0.7587878249560307,-0.7577415197980796,-0.7572185347477356,-0.7556492439713425,-0.7551259234218418,-0.75407995262806,-0.7530336463357832,-0.7514643540502296,-0.7504180471307982,-0.7493717399611081,-0.7483254325415026,-0.7472794601199385,-0.7457098305252509,-0.7457098305252509,-0.7446638574815321,-0.7441405356187167,-0.7446638574815321,-0.7430945622027713,-0.7420482532911422,-0.7420482532911422,-0.7420482532911422,-0.7425712401539316,-0.7425712401539316,-0.7425712401539316,-0.7430945622027713,-0.7441405356187167,-0.7446638574815321,-0.7467561385680797,-0.7493717399611081,-0.7519873397923696,-0.7535566318897744,-0.75407995262806,-0.7556492439713425,-0.7572185347477356,-0.7582648400320438,-0.7593108098168009,-0.7608804345124419,-0.7619264036637089,-0.763495692160713,-0.7640190116967108,-0.765065315331189,-0.7655882994296566,-0.7661112834643476,-0.7661112834643476,-0.7661112834643476,-0.7661112834643476,-0.7661112834643476,-0.7661112834643476,-0.7661112834643476,-0.7666346026813232,-0.7661112834643476,-0.7661112834643476,-0.7661112834643476,-0.7661112834643476,-0.7661112834643476,-0.7655882994296566,-0.7655882994296566,-0.765065315331189,-0.7645419959226805,-0.7640190116967108,-0.7629727078074321,-0.7629727078074321,-0.7629727078074321,-0.7629727078074321,-0.7629727078074321,-0.7629727078074321,-0.7624497233905783,-0.7624497233905783,-0.7619264036637089,-0.7614034191197983,-0.7614034191197983,-0.7614034191197983,-0.7608804345124419,-0.7608804345124419,-0.7608804345124419,-0.7608804345124419,-0.7608804345124419,-0.7608804345124419,-0.7608804345124419,-0.7608804345124419,-0.7614034191197983,-0.7624497233905783,-0.7661112834643476,-0.7713424612761931,-0.7765736326577838,-0.7812814802203781,-0.7875589373370232,-0.794882345982016,-0.8042983295647109,-0.8137142914238357,-0.8231302313051748,-0.8330691244621881,-0.8445772499114659,-0.8545164238370578,-0.8634089589686601,-0.8743940237664453,-0.8864253281332662,-0.8984565934110067,-0.9094415542430621,-0.9204264816431622,-0.9314113752076438,-0.9423962345328308,-0.9533810592150475,-0.9648888054841939,-0.9758735579717375,-0.9868582745861485,-0.9978429549237762,-1.0083046488537644,-1.0187659739409076,-1.0281813721436837,-1.0370734623184468,-1.045442583861716,-1.0548579027287235,-1.0642731931074392,-1.0731655157734468,-1.0815345398372316,-1.0914726840224196,-1.1003645917233282,-1.1082106072527236,-1.1160566019981737,-1.123379310418749,-1.1291328781101782,-1.135409697736137,-1.1416861685241888,-1.1469167738564707,-1.1526702945954577,-1.1584241389172587,-1.164177636347996,-1.1709773004991362,-1.1777769481558307,-1.184053324990259,-1.189807104878704,-1.1960834544094572,-1.2023601247878748,-1.208113531091344,-1.2154360001035152,-1.2206664666203226,-1.2243278541709846,-1.2269427448474035,-1.22955796816679,-1.2337422531067983,-1.2358345607094268,-1.2389726838241857,-1.2405417439881894,-1.2410649873011257,-1.2421111384190378,-1.242634046224077,-1.2447260116055865,-1.2457721612726058,-1.2457721612726058,-1.2468183105242574,-1.247341217395855,-1.2483873660238252,-1.249433514235537,-1.2499564205870248,-1.2499564205870248,-1.2510025681737706,-1.2520487153434057,-1.2536177677170224,-1.2551868191503528,-1.2562329646481103,-1.2588481589616014,-1.2625091584367822,-1.2651243464460962,-1.2672166290334583,-1.270877616702344,-1.2755850720677633,-1.2797692833900804,-1.2844763872700613,-1.288660584060055,-1.291798978536088,-1.2944141367100306,-1.2970289569966396,-1.3012134682883023,-1.3059205324092378,-1.3106275877146933,-1.314288848073676,-1.3174268754311824,-1.3205652340232816,-1.324749370793664,-1.3268412689373568,-1.3289335004979863,-1.3310253951005768,-1.3336405122469541,-1.335732738037612,-1.3383478501781272,-1.3393936261062191,-1.3404397367723864,-1.3420087343414837,-1.3430548438897625,-1.3435777309040247,-1.3441009529902317,-1.3451467264588386,-1.3451467264588386,-1.3446238397805448,-1.3441009529902317,-1.3441009529902317,-1.3441009529902317,-1.3441009529902317,-1.3441009529902317,-1.3441009529902317,-1.3435777309040247,-1.3435777309040247,-1.3441009529902317,-1.3446238397805448,-1.3446238397805448,-1.3446238397805448,-1.3456699482087464,-1.3467160561882738,-1.3477618285354172,-1.3482850497239063,-1.348807935616705,-1.348807935616705,-1.348807935616705,-1.348807935616705,-1.348807935616705,-1.348807935616705,-1.348807935616705,-1.348807935616705,-1.348807935616705,-1.3482850497239063,-1.347238942417957,-1.3456699482087464,-1.3414858469916475,-1.33730173861928,-1.3336405122469541,-1.3299792804280302,-1.3252722616986734,-1.3205652340232816,-1.3163807550215005,-1.313242726348453,-1.306966657191928,-1.3022592598379175,-1.2975521888820338,-1.291798978536088,-1.2834305883951833,-1.2802921836286947,-1.277154110213067,-1.274016032965698,-1.270877616702344,-1.2677395318193025,-1.2651243464460962,-1.2630323973660744,-1.260940111407108,-1.2583249191914214,-1.255709724353762,-1.2525716211736768,-1.247864459360147,-1.240018835769398,-1.2316502790573487,-1.2211893786331596,-1.209159695075999,-1.1955605375635003,-1.1803922186272966,-1.1631314553575256,-1.1463938478363311,-1.1270408253602058,-1.1082106072527236,-1.0935650971576718,-1.0794421183695369,-1.0679347802892034,-1.057473282659017,-1.051196635310309,-1.047535028378916,-1.0433504731705738,-1.0407350814349265,-1.038119687530497,-1.0370734623184468,-1.036027571981872,-1.036027571981872,-1.036027571981872,-1.0355042914627306,-1.0349813460786235,-1.0339351198302467,-1.0339351198302467\",\n \"Longitude\": \"35.42245019227266,35.42297322303057,35.424542650580406,35.426112078130245,35.42715847492218,35.42925093322992,35.43029733002186,35.4318667575717,35.43239012360573,35.433436185121536,35.43605200946331,35.43814480304718,35.44128365814686,35.44337645173073,35.446515306830406,35.44913113117218,35.451746955513954,35.45436277985573,35.457501634955406,35.46011745929718,35.462733283638954,35.46587213873863,35.4690109938383,35.472150184214115,35.47476600855589,35.47999732196331,35.482613146305084,35.48575233668089,35.48889119178057,35.491507016122334,35.493599474430084,35.49516890197992,35.49673866480589,35.49883112311363,35.49987751990557,35.50040055066348,35.5009239166975,35.501446947455406,35.501446947455406,35.501446947455406,35.501446947455406,35.50196997821331,35.50196997821331,35.50249334424734,35.50249334424734,35.503016375005245,35.503016375005245,35.503016375005245,35.50353940576315,35.50353940576315,35.50406277179719,35.504585802555084,35.505109168589115,35.505109168589115,35.505109168589115,35.50563219934702,35.506678596138954,35.506678596138954,35.50824802368879,35.510340481996536,35.51347967237234,35.51818795502186,35.52551206201315,35.5349289625883,35.54486889392138,35.55585522204638,35.56788794696331,35.57939764112234,35.590907000005245,35.60293972492218,35.614972449839115,35.62648180872202,35.638514533638954,35.65002389252186,35.66362604498863,35.67618180066347,35.689260587096214,35.70338610559702,35.715418830513954,35.72692818939686,35.73896091431379,35.74942387640476,35.75779438018799,35.766688250005245,35.775581784546375,35.78290622681379,35.78918393701314,35.795985013246536,35.801739692687995,35.80749470740557,35.81272602081298,35.8169112727046,35.821619890630245,35.82580514252186,35.82999039441347,35.834175646305084,35.8383608981967,35.842023119330406,35.84568500518799,35.84882419556379,35.85248608142138,35.85667133331299,35.8608565852046,35.865565203130245,35.86975045502186,35.87393570691347,35.878120958805084,35.88178317993879,35.88492203503847,35.88806089013815,35.89119974523783,35.89433893561363,35.896954759955406,35.89852418750525,35.89957058429718,35.90218607336283,35.9048018977046,35.90689469128847,35.908987149596214,35.911079943180084,35.91421879827976,35.91735765337944,35.920496843755245,35.92311266809702,35.9262515231967,35.92886734753847,35.930959805846214,35.93357563018799,35.93566842377186,35.93671482056379,35.93828424811363,35.93985367566347,35.94194613397122,35.944038927555084,35.94560835510493,35.94717778265476,35.9482241794467,35.94927057623863,35.949793606996536,35.95031663775445,35.95084000378847,35.951363034546375,35.951363034546375,35.9518864005804,35.95240943133831,35.95240943133831,35.95240943133831,35.95240943133831,35.95240943133831,35.95240943133831,35.953455828130245,35.95450188964605,35.95554828643799,35.95607165247202,35.95711771398783,35.95711771398783,35.95764108002186,35.95764108002186,35.95764108002186,35.95711771398783,35.95607165247202,35.95450188964605,35.95397885888815,35.95293246209621,35.95293246209621,35.95293246209621,35.95293246209621,35.95240943133831,35.9518864005804,35.9518864005804,35.9518864005804,35.9518864005804,35.95240943133831,35.95293246209621,35.95293246209621,35.953455828130245,35.95397885888815,35.955025255680084,35.95554828643799,35.95554828643799,35.95554828643799,35.95554828643799,35.95554828643799,35.95554828643799,35.95607165247202,35.956594683229916,35.956594683229916,35.956594683229916,35.956594683229916,35.956594683229916,35.956594683229916,35.956594683229916,35.956594683229916,35.956594683229916,35.95607165247202,35.95554828643799,35.955025255680084,35.955025255680084,35.955025255680084,35.95450188964605,35.95450188964605,35.95450188964605,35.95397885888815,35.953455828130245,35.95240943133831,35.9518864005804,35.951363034546375,35.951363034546375,35.95031663775445,35.949793606996536,35.94927057623863,35.9487472102046,35.9482241794467,35.94717778265476,35.94613138586283,35.94560835510493,35.94456195831299,35.942469500005245,35.93985367566347,35.9372378513217,35.93305259943008,35.92729791998863,35.92101987451315,35.914741829037666,35.90637132525444,35.89852418750525,35.89172311127186,35.88492203503847,35.87916735559702,35.872889310121536,35.867134630680084,35.85562527179718,35.85039362311363,35.84411557763815,35.83783786743879,35.8315598219633,35.825281776487834,35.819527097046375,35.81324938684702,35.8059249445796,35.79860083758831,35.79284615814686,35.786568112671375,35.78133646398783,35.77505875378847,35.76878070831299,35.76250299811363,35.757271349430084,35.75256306678057,35.74837781488895,35.744192227721214,35.7394839450717,35.733729265630245,35.72797458618879,35.722742937505245,35.7175112888217,35.71227964013815,35.70600192993879,35.699200853705406,35.69239977747202,35.68559870123863,35.67827459424734,35.660487189888954,35.642176419496536,35.63171345740556,35.622296556830406,35.61183325946331,35.60189332813025,35.59143003076315,35.58044370263815,35.568934343755245,35.557424984872334,35.54748471826315,35.53649839013815,35.51714155822992,35.50772465765476,35.499354153871536,35.49098365008831,35.482613146305084,35.47267321497202,35.46377934515476,35.45488581061363,35.44756170362234,35.44180702418089,35.43762143701315,35.43448258191348,35.43134372681379,35.42925093322992,35.426112078130245,35.42297322303057,35.42140379548073,35.42035739868879,35.41983436793089,35.418787971138954,35.418264605104916,35.41774157434702,35.416695177555084,35.416695177555084,35.41721854358911,35.41774157434702,35.41774157434702,35.418264605104916,35.41931100189686,35.42035739868879,35.42035739868879,35.42035739868879,35.42035739868879,35.42035739868879,35.4208804294467,35.4208804294467,35.4208804294467,35.42140379548073,35.421926826238625,35.421926826238625\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": -1.077506,\n \"PositionLongitude\": 35.789817,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 0,\n \"Status\": 0,\n \"Street\": \"Ewaso Ng’iro\",\n \"TotalDistanceCovered\": null,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Narok\",\n \"TractorID\": 501549,\n \"TractorModelID\": 8,\n \"TractorName\": \"John Deere 5503 KTCB 771M\",\n \"UpdatedAt\": \"2019-10-30 15:40:15\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"_acl\": {\n \"creator\": \"5cff8e7bb119264a16015316\"\n },\n \"license_plate_number\": \"KTCB 771M\",\n \"_kmd\": {\n \"lmt\": \"2019-08-02T17:20:38.632Z\",\n \"ect\": \"2019-06-11T11:24:56.382Z\"\n },\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 1,\n \"AssetState\": \"On\",\n \"FuelLevelVoltage\": 0\n },\n \"501554\": {\n \"_id\": \"5d0756130e4a813cd1214db5\",\n \"ActiveTimeToday\": 15884,\n \"BookingRequests\": true,\n \"Characteristic\": \"101,102,107\",\n \"Country\": \"Kenya\",\n \"CreatedAt\": \"2019-06-17 08:57:54\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 169,\n \"FixedEngineHours\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"\",\n \"Heading\": 121,\n \"ImplementsAttached\": \"101,107,102\",\n \"LastActiveTime\": \"2019-10-30 12:59:48\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"0.4279303997976261,0.4274727606353288,0.42609950771806937,0.42518389388154504,0.4238106405567293,0.4228953617162234,0.4224373869884612,0.4215221079861032,0.42014885401385377,0.4192332394758263,0.41831762483074136,0.41740234534603315,0.4169443702964879,0.41602909065206495,0.4151134756341554,0.41419786051021884,0.41328258054791855,0.4123669652127041,0.4114513497721752,0.4105360694941094,0.40962045384370205,0.40870483808867986,0.407331581894355,0.40595832546604305,0.4041274282882353,0.40275417131700264,0.40138091411440374,0.3995500159083736,0.39817675816899883,0.3963455239820724,0.3940569835815822,0.39176810728409883,0.38993720695680406,0.3871906880855986,0.38444416832467754,0.3821552894259457,0.37986640991732346,0.3771198878145981,0.3743733648453116,0.3716268410157486,0.36842267389215705,0.36476052771962536,0.36155635813915704,0.35835218742792524,0.35560565870600763,0.35240115065155897,0.3491969767646832,0.3469080888791287,0.3441615567940163,0.3414150239180653,0.3382108463284259,0.33500633241063743,0.33134450846559654,0.32768234789647493,0.32402052125941255,0.32127364750596143,0.3189850883868001,0.316238548555523,0.31349200799756555,0.3107454667192379,0.30799892472685025,0.3047944013273957,0.30113256666324945,0.29838602222133853,0.29563947709377636,0.292892931286835,0.29014638480687555,0.28831512993485553,0.28602656383877856,0.28328001570382383,0.28007548520934056,0.2773289356719139,0.27458238549720587,0.27275146345391066,0.2709205411321006,0.26908928326121195,0.26725836038790646,0.26542743724168394,0.2640541608858993,0.26222290199395076,0.2603919781067862,0.25810307141958627,0.25581449959324387,0.2530679446449304,0.24986340628873932,0.24711685008836864,0.24437029332015445,0.24162373599039427,0.238877178105411,0.23613061967148943,0.23338406069497797,0.23063750118214865,0.22834892469866,0.22606001257732974,0.2237711000952228,0.22194017101638797,0.22010924171091953,0.21873596076579802,0.21782032830795298,0.2164470471538181,0.21507376587534902,0.213700484473309,0.2123272029485123,0.21095392130173496,0.20912299067561116,0.20774970874730386,0.2054607935106203,0.20317187794603425,0.20088329733127222,0.1985943811218987,0.19676344909050408,0.19493218158399775,0.19218561522568606,0.188981399008032,0.18577718219932912,0.18257262953518383,0.17891076189812538,0.1752485582557059,0.1715863538973181,0.1679244841126092,0.163804293054826,0.15831115069694898,0.15373364270996978,0.14915613374173856,0.14549392471525066,0.1413740645788518,0.1363385672188011,0.13176105478814173,0.12809884307151526,0.12397897999375213,0.11985911627498001,0.1166548891559748,0.11299301065251312,0.10887281005301498,0.10566858172481376,0.10292200424419139,0.10017542652707567,0.09788649982813104,0.09605555952173463,0.093766632544237,0.09193569201975633,0.08964676477553739,0.08781582404243778,0.08598488321964651,0.08415360703327923,0.0832383041835166,0.0818650145933294,0.08094937641509137,0.08003373821619246,0.07957608674696785,0.07911843527265436,0.07866044851749746,0.07820279703310795,0.0777451455437568,0.0777451455437568,0.0772871587736004,0.0772871587736004,0.0772871587736004,0.0772871587736004,0.07820279703310795,0.07866044851749746,0.07957608674696785,0.08049172495612088,0.0814070278689221,0.08278031747487213,0.08415360703327923,0.08506924513732128,0.08598488321964651,0.08690018600425865,0.08735817266399891,0.0882734754152534,0.08873146205817489,0.08873146205817489,0.08918911341970592,0.08918911341970592,0.08873146205817489,0.08873146205817489,0.0882734754152534,0.08781582404243778,0.08690018600425865,0.08598488321964651,0.08506924513732128,0.08415360703327923,0.0832383041835166,0.0823226660367279,0.0814070278689221,0.08049172495612088,0.08003373821619246,0.07957608674696785,0.07911843527265436,0.07866044851749746,0.07820279703310795,0.07820279703310795,0.07820279703310795,0.07820279703310795,0.07820279703310795,0.07820279703310795,0.07820279703310795,0.07866044851749746,0.07866044851749746,0.07911843527265436,0.07911843527265436,0.07957608674696785,0.08003373821619246,0.08049172495612088,0.08049172495612088,0.08094937641509137,0.0814070278689221,0.0823226660367279,0.08369595561107594,0.08506924513732128,0.0864425346147133,0.0882734754152534,0.08964676477553739,0.09102005408433457,0.09285132993169287,0.09468227040854157,0.09605555952173463,0.09788649982813104,0.09925978881135392,0.10109106421720034,0.10292200424419139,0.10521093058659584,0.10841515896261987,0.11070408489591595,0.1134506616721218,0.11619723818764939,0.11848616350535546,0.12123240425115021,0.12489461693672634,0.12809884307151526,0.13084541809005754,0.1331343421344985,0.13588091659696533,0.13954312715182426,0.14320533713658784,0.14686721126126537,0.15052942006099246,0.1532759924393054,0.15648021467675713,0.1601424218302927,0.1633466430067241,0.1670088489213064,0.17112870403090222,0.17479090847772216,0.17799512723684294,0.1811993454392649,0.18440389834939427,0.1871504659425627,0.18989703310566927,0.19218561522568606,0.19401688303014672,0.19722109829872325,0.19951001469870105,0.20134094642518227,0.20500314453341117,0.20683407563741965,0.2086650065302139,0.21003828837854932,0.21141157010621453,0.21278485171243341,0.21415813319640453,0.21553141455735178,0.21690469579448637,0.21782032830795298,0.2191936093369521,0.22010924171091953,0.22102453875506303,0.22194017101638797,0.22285580322104814,0.2237711000952228,0.22468673218582827,0.22560236421905655,0.22651766092117592,0.2274332928389628,0.22834892469866,0.22880657296992593,0.22926422122659948,0.22972220474206884,0.2301798529694558,0.2301798529694558,0.23063750118214865,0.23109548465353552,0.23201078100520867,0.23246876443222042,0.23292641257103533,0.2338420440773602,0.23429969217148194,0.23475734025066783,0.23567297163735296,0.23658860296383652,0.23750389895666676,0.23841953016211115,0.23933516130665428,0.24025045711690796,0.24116608813899973,0.24208171909951595,0.24253936692002095,0.24345499778771587,0.24391264556172115,0.24482827633607318,0.24528592406327343,0.2457435717748508,0.24665920242393982,0.24711685008836864,0.24711685008836864,0.24757483301004116,0.24803248064289343,0.2489481111340743,0.2494057587193582,0.24986340628873932,0.2507790366525453,0.25123668417400186,0.2516946669523077,0.2526099619149308,0.2539832395107374,0.25581449959324387,0.2576454241416839,0.2599343309115528,0.2631385314735244,0.2658850842356009,0.26863163638668025,0.27137818792047746,0.2741247388306697,0.27870221052067545,0.2814487597370951,0.28328001570382383,0.28648421004024127,0.2892307574077918,0.29151965813059927,0.2933505772109915,0.2951814959918391,0.29792804123313793,0.30204785780946136,0.30433675588000436,0.30616767282410706,0.31028748625579067,0.31211873744804886,0.3139496530503901,0.316238548555523,0.31852710828502007,0.32035835802796314,0.32264691683997193,0.3263090792459529,0.3281399923146515,0.32997124031882347,0.33180215271542,0.33363306477318566,0.33546431176063607,0.3377532023776891,0.3386684902575732,0.3418730029654787,0.3446195357099964,0.34645044534346703,0.3482813546231454,0.35011259881703827,0.3519435073834836,0.3542323940382143,0.3560633017933511,0.35835218742792524,0.35972545148048474,0.36155635813915704,0.3643028850689848,0.36567614822037864,0.367507053672234,0.3693382940179738,0.3707115563952334,0.37254246081048237,0.3739157226896289,0.37574662643787743,0.37757786507130836,0.37940876805023155,0.3830709081125615,0.3849018099235087,0.3867327113414157,0.3881059709628773,0.38993720695680406,0.3913104660567819,0.3926837249319709,0.3940569835815822,0.3958878830060702,0.39680350020087857,0.39771878202629696,0.39863439901823683,0.3990920398420559,0.4000076566812147,0.400465297428535,0.40138091411440374,0.4022965306977569,0.40275417131700264,0.40275417131700264,0.4032118119105495,0.40366978774618795,0.4041274282882353,0.40458506880449463,0.40458506880449463,0.4050430445627184,0.40595832546604305,0.4064163011465594,0.40687394153343387,0.4077895574969223,0.408247197805835,0.40870483808867986,0.40916281361304374,0.40962045384370205,0.4105360694941094,0.4105360694941094,0.4109937096462462,0.4114513497721752,0.4114513497721752,0.4119093251393306,0.4119093251393306\",\n \"Longitude\": \"34.72554389387369,34.724170602858074,34.72233932465315,34.72005072981119,34.71730414777994,34.71501521766186,34.71318427473307,34.71135299652815,34.7086064144969,34.70585983246565,34.7031132504344,34.69990901648998,34.696704782545574,34.69304256141185,34.68892268836498,34.685260467231274,34.68159858137369,34.67839401215315,34.67473212629557,34.67106990516186,34.66832332313061,34.66557674109935,34.66237250715494,34.659167937934406,34.65596370398998,34.65321712195873,34.65047053992748,34.64726630598307,34.64451972395182,34.64177314192057,34.638568572700024,34.63536433875561,34.6317021176219,34.62849788367748,34.62529364973307,34.62254706770182,34.61888484656811,34.61568061262369,34.61156073957682,34.608356170356274,34.60515193641186,34.60148971527815,34.59828548133373,34.595538899302475,34.59233466535807,34.58913009613753,34.58592586219311,34.58317928016186,34.580890350043774,34.578143768012524,34.57585517317057,34.57310859113932,34.57036200910807,34.568073078989975,34.56532649695873,34.563495554029934,34.561664275825024,34.55983333289623,34.55800238996744,34.556629098951824,34.55525580793619,34.55342452973127,34.55159358680248,34.55022029578686,34.54884700477123,34.54747371375561,34.54655807465315,34.54564277082682,34.54472713172436,34.54426947981119,34.54335384070873,34.54335384070873,34.54289618879557,34.54289618879557,34.54289618879557,34.54289618879557,34.54335384070873,34.5438114926219,34.54426947981119,34.545184783637524,34.54610042273998,34.54701606184244,34.547931365668774,34.5493046566844,34.550677947700024,34.55159358680248,34.55296687781811,34.5547978207469,34.556171111762524,34.557544402778156,34.55937568098307,34.56074897199869,34.56257991492748,34.564410857856274,34.56624213606119,34.56853073090315,34.57036200910807,34.57219295203686,34.57356624305248,34.57493953406811,34.57722846418619,34.57951705902815,34.58134833723307,34.583636932075024,34.58684150129557,34.59004573523998,34.59370795637369,34.597369842231274,34.60103206336498,34.6042362973094,34.60698287934065,34.6097294613719,34.61247604340315,34.61568061262369,34.61796920746565,34.62025813758373,34.62300471961499,34.62529364973307,34.62804023176432,34.630328826606274,34.63261775672436,34.63536433875561,34.63811092078685,34.64039985090494,34.64223079383373,34.644061736762524,34.64635066688061,34.64863959699869,34.65047053992748,34.652301482856274,34.6536747738719,34.654590412974365,34.65550605207682,34.65642135590315,34.65687934309244,34.65733699500561,34.657794646918774,34.657794646918774,34.657794646918774,34.657794646918774,34.65733699500561,34.65687934309244,34.65596370398998,34.65550605207682,34.654590412974365,34.654590412974365,34.65413276106119,34.6536747738719,34.6536747738719,34.65321712195873,34.65321712195873,34.65321712195873,34.65321712195873,34.65321712195873,34.6536747738719,34.654590412974365,34.65642135590315,34.65871028602123,34.66237250715494,34.66649238020182,34.67061225324869,34.67473212629557,34.67885199934244,34.68342952430248,34.68709174543619,34.69121161848307,34.69487350434065,34.69807807356119,34.70128230750561,34.70402888953685,34.707233123481274,34.709979705512524,34.71318427473307,34.71638850867748,34.71913509070873,34.72279731184244,34.72554389387369,34.72874812781811,34.731952361762524,34.73469927906991,34.73790351301432,34.74065009504557,34.74385432898998,34.74660091102123,34.74934749305248,34.7511787712574,34.75346736609936,34.756213948130615,34.75850287824869,34.76079147309065,34.763080403208725,34.76536933332682,34.7676582634449,34.769031554460526,34.77086249738932,34.77315142750739,34.77544002234936,34.77727130055427,34.77910224348307,34.78093318641186,34.78230647742748,34.7841377556324,34.78596869856119,34.78688433766365,34.788257628679276,34.78917293250561,34.790546223521225,34.79191951453686,34.79375079274178,34.79603938758373,34.79878596961498,34.80107489973307,34.80382148176432,34.8061104118824,34.80794135481119,34.810230284929276,34.81206122785807,34.81389217078686,34.81526546180248,34.8170967400074,34.818470031023026,34.81984332203865,34.821216613054276,34.82304755598307,34.82442084699869,34.825794138014324,34.82716742902994,34.82854072004557,34.83037166297436,34.83220294117928,34.83403388410807,34.83540717512369,34.836780466139324,34.83815375715494,34.8390693962574,34.840442687273026,34.84135799109936,34.84227363020182,34.84318926930427,34.843646921217434,34.84410457313061,34.8445625603199,34.8445625603199,34.84502021223307,34.84547786414623,34.845935851335526,34.84639350324869,34.84685115516186,34.84730914235115,34.84776679426432,34.848682433366776,34.84914008527994,34.84959773719311,34.85051337629557,34.851429015398026,34.85325995832682,34.854175597429276,34.8555488884449,34.85646419227123,34.85783748328686,34.85875312238932,34.86012641340494,34.8610420525074,34.862415343523026,34.86333064734936,34.864246286451824,34.865161925554276,34.86607722938061,34.86699286848307,34.867908507585526,34.86882381141186,34.86973945051432,34.87019710242748,34.871112741529934,34.87157039344311,34.8720283806324,34.87248603254557,34.87294368445873,34.873401671648026,34.87385932356119,34.873401671648026,34.873401671648026,34.873401671648026,34.873401671648026,34.873401671648026,34.873401671648026,34.87294368445873,34.87294368445873,34.8720283806324,34.87157039344311,34.87065508961677,34.86928179860115,34.867908507585526,34.8665352165699,34.865161925554276,34.86378863453866,34.862415343523026,34.8605840653181,34.85875312238932,34.856922179460526,34.85463324934244,34.85234431922436,34.8500557243824,34.84776679426432,34.845935851335526,34.84410457313061,34.84227363020182,34.840442687273026,34.83861140906811,34.837238118052475,34.83632281422616,34.83540717512369,34.834949523210526,34.83403388410807,34.8335762321949,34.8331182450056,34.832660593092434,34.83220294117928,34.83220294117928,34.832660593092434,34.8331182450056,34.83403388410807,34.834949523210526,34.83586482703686,34.837696105241776,34.83861140906811,34.8390693962574,34.840442687273026,34.84135799109936,34.84227363020182,34.84273128211498,34.843646921217434,34.84410457313061,34.84502021223307,34.84547786414623,34.845935851335526,34.84685115516186,34.84730914235115,34.84730914235115,34.84730914235115,34.84730914235115,34.84730914235115,34.84730914235115,34.84730914235115,34.84685115516186,34.84639350324869,34.84639350324869,34.845935851335526,34.84547786414623,34.84502021223307,34.84410457313061,34.84318926930427,34.84181597828865,34.84090033918619,34.83998470008373,34.8390693962574,34.837696105241776,34.836780466139324,34.83540717512369,34.83403388410807,34.8331182450056,34.83220294117928,34.82991401106119,34.82854072004557,34.82716742902994,34.82533648610116,34.823963195085526,34.822131916880615,34.82030097395182,34.81801204383373,34.815723448991776,34.81343451887369,34.80885699391365,34.80656806379557,34.80382148176432,34.80153255164623,34.79878596961498,34.79603938758373,34.79375079274178,34.791004210710526,34.785511046648026,34.78322211652994,34.78047553449869,34.77818660438061,34.77635566145182,34.774066731333725,34.77223578840494,34.77040484547615,34.76628497242928,34.76399604231119,34.76216509938241,34.75987616926432,34.758045226335526,34.75575629621745,34.75300971418619,34.75072078406811,34.74888984113932,34.74614325910807,34.74385432898998,34.74110774695873,34.73836116492748,34.735614582896225,34.73286800086498,34.7305790707469,34.72783248871565,34.72325496375561,34.72142402082682,34.7195927426219,34.71776179969311,34.71684616059065,34.71593085676432,34.71593085676432\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 1560782750037,\n \"PositionLatitude\": 1.085103,\n \"PositionLongitude\": 34.9263,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 0.05,\n \"Status\": 1,\n \"Street\": \"Endebess\",\n \"TotalDistanceCovered\": 16795,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Trans Nzoia\",\n \"TractorID\": 501554,\n \"TractorModelID\": 8,\n \"TractorName\": \"John Deere 5503E\",\n \"UpdatedAt\": \"2019-10-30 15:40:23\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"_acl\": {\n \"creator\": \"5d07559021e7a97a0482a71a\"\n },\n \"_kmd\": {\n \"lmt\": \"2019-08-31T10:47:09.169Z\",\n \"ect\": \"2019-06-17T08:57:55.373Z\"\n },\n \"license_plate_number\": \"001\",\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"FuelLevelVoltage\": 0,\n \"LastMaintenanceNotificationEngineHours\": 100\n },\n \"501555\": {\n \"_id\": \"5cff90091b377648653a3d3f\",\n \"ActiveTimeToday\": 14877,\n \"BookingRequests\": true,\n \"Characteristic\": \"101\",\n \"Country\": \"Kenya\",\n \"CreatedAt\": \"2019-06-11 11:27:06\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": null,\n \"FixedEngineHours\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"\",\n \"Heading\": 139,\n \"ImplementsAttached\": \"101\",\n \"LastActiveTime\": \"2019-10-30 14:48:58\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"-0.15749945027640494,-0.16273107853000696,-0.1648235282891553,-0.1653468921507499,-0.1653468921507499,-0.1658699207238296,-0.16743934163465304,-0.16900876241984458,-0.17057851835288143,-0.17110154678573686,-0.17162457520434338,-0.17267096727319028,-0.1742403876311061,-0.17580980785827566,-0.17685619969468763,-0.17685619969468763,-0.17685619969468763,-0.17790259147211943,-0.17894898319020205,-0.17947201138964292,-0.18051840301808478,-0.18051840301808478,-0.18051840301808478,-0.18051840301808478,-0.18051840301808478,-0.18051840301808478,-0.18051840301808478,-0.18104143117252716,-0.18104143117252716,-0.18051840301808478,-0.18051840301808478,-0.17999503957413515,-0.17894898319020205,-0.17685619969468763,-0.1763331714211017,-0.17580980785827566,-0.17528677955532684,-0.17476375123778562,-0.17476375123778562,-0.1742403876311061,-0.17319433092334163,-0.17267096727319028,-0.17214793888324692,-0.17162457520434338,-0.17057851835288143,-0.1695321261699035,-0.1695321261699035,-0.17057851835288143,-0.17057851835288143,-0.17214793888324692,-0.17267096727319028,-0.17267096727319028,-0.17371735928446916,-0.17476375123778562,-0.1742403876311061,-0.1742403876311061,-0.17371735928446916,-0.17319433092334163,-0.17267096727319028,-0.17214793888324692,-0.17162457520434338,-0.17110154678573686,-0.1700551546311549,-0.1684857339303753,-0.16743934163465304,-0.1658699207238296,-0.16377747107425775,-0.16168468593147048,-0.15959223584779106,-0.15749945027640494,-0.15645305741173235,-0.15593002859724855,-0.15436060680111136,-0.15174479179242523,-0.14912897646745205,-0.14703652514843246,-0.1444207092679054,-0.14180489308635794,-0.13814268288181802,-0.1365732598419949,-0.133957442790095,-0.13134162545898057,-0.1287258078540967,-0.12558696048468465,-0.12401753665804317,-0.1224481127383514,-0.11983229424349745,-0.11512368621679255,-0.11303123205662163,-0.10989204762129892,-0.10675319813164005,-0.10204492329937286,-0.09942910300090269,-0.09629025247990443,-0.09315106639424278,-0.09053524541337823,-0.08791975951953411,-0.08530393816672278,-0.08268811663610573,-0.08007229493314078,-0.07850286888606503,-0.0758870469186942,-0.07379425512029092,-0.07170179849931213,-0.06856261047557313,-0.06647015362073451,-0.06437736140131485,-0.06071547772624581,-0.05862268527738093,-0.05600686224461334,-0.053391039095106674,-0.05025218527968988,-0.04711333131343846,-0.043451111324087466,-0.03717340268168482,-0.03298815157549738,-0.030372327633803594,-0.028279534324178835,-0.026187076252918003,-0.025663710272463305,-0.025663710272463305,-0.025140679565969302,-0.024094282870636655,-0.024094282870636655,-0.023047886167263568,-0.02252485545071901,-0.021478458735946813,-0.019909031288523733,-0.018862634556500207,-0.017816573094289932,-0.016770176350027633,-0.01572377960018028,-0.01572377960018028,-0.015200748861320952,-0.01415435210373849,-0.012584924596673647,-0.011015497080168916,-0.009445734279283998,-0.008922703528096838,-0.008399672776171789,-0.007876306747423548,-0.00683024524024023,-0.00683024524024023,-0.006306879209659991,-0.005260482423058149,-0.004214420910849554,-0.003691054878068371,-0.003691054878068371,-0.0031680241210926014,-0.002121627330292427,-0.0015985965726678245,-0.0010752305387798085,-5.521997809262059E-4,-2.9169023034436803E-5,-2.9169023034436803E-5,-2.9169023034436803E-5,-5.521997809262059E-4,-0.0010752305387798085,-0.002121627330292427,-0.002121627330292427,-0.00264499336387511,-0.00264499336387511,-0.00264499336387511,-0.0031680241210926014,-0.0031680241210926014,-0.0031680241210926014,-0.00264499336387511,-0.00264499336387511,-0.00264499336387511,-0.00264499336387511,-0.00264499336387511,-0.00264499336387511,-0.00264499336387511,-0.00264499336387511,-0.00264499336387511,-0.0031680241210926014,-0.0031680241210926014,-0.0031680241210926014,-0.0031680241210926014,-0.0031680241210926014,-0.0031680241210926014,-0.0047374516671510455,-0.0057838484546561654,-0.006306879209659991,-0.008399672776171789,-0.011015497080168916,-0.01415435210373849,-0.01572377960018028,-0.019909031288523733,-0.023571252157985095,-0.028279534324178835,-0.03508060951396369,-0.040835287690144155,-0.04711333131343846,-0.05182161220683783,-0.05705325852722449,-0.06333130053514052,-0.07013237215169942,-0.07641007721465493,-0.08268811663610573,-0.08844278965798105,-0.09419746178767262,-0.1009985281500824,-0.10832262291711697,-0.11564705118954574,-0.12297114229672877,-0.1302952313945137,-0.13709628910833374,-0.143897344890463,-0.14912897646745205,-0.1522678207096664,-0.15645305741173235,-0.16116165724936135,-0.1648235282891553,-0.1684857339303753,-0.17162457520434338,-0.17476375123778562,-0.17737956322804901,-0.17894898319020205,-0.17999503957413515,-0.18104143117252716,-0.18261085081956355,-0.18313421418779052,-0.18365724226634486,-0.18313421418779052,-0.1841806056039749,-0.1841806056039749\",\n \"Longitude\": \"36.05306938290596,36.059870459139354,36.06614850461482,36.07138015329838,36.07504203915596,36.079750657081604,36.08341254293919,36.08655173331499,36.090736985206604,36.09492223709822,36.0985841229558,36.10224634408951,36.105908565223224,36.1095704510808,36.11061684787274,36.112709641456604,36.11532546579838,36.117940954864025,36.120033748447895,36.12212620675564,36.12474203109741,36.127357855439186,36.12945064902306,36.1315431073308,36.13520532846451,36.13939058035612,36.143575832247734,36.14671468734741,36.149330511689186,36.15194633603096,36.15508519113064,36.15822438150644,36.161886267364025,36.16502545773983,36.16816431283951,36.171303167939186,36.17391899228096,36.17653481662274,36.178627610206604,36.181243099272244,36.183858923614025,36.18542868643999,36.18699811398983,36.18804417550564,36.189613938331604,36.19065999984741,36.19170639663935,36.19170639663935,36.19170639663935,36.19170639663935,36.19170639663935,36.19170639663935,36.19170639663935,36.19170639663935,36.19170639663935,36.19170639663935,36.19170639663935,36.19170639663935,36.19170639663935,36.19170639663935,36.19170639663935,36.19170639663935,36.19170639663935,36.19170639663935,36.19170639663935,36.19170639663935,36.192229427397244,36.19275279343128,36.19275279343128,36.19275279343128,36.193275824189186,36.194845251739025,36.194845251739025,36.195368617773056,36.19589164853096,36.19589164853096,36.196414679288864,36.196414679288864,36.196938045322895,36.1974610760808,36.19798444211483,36.198507472872734,36.198507472872734,36.198507472872734,36.198507472872734,36.19903050363064,36.19955386966467,36.19955386966467,36.200600266456604,36.20164632797241,36.20216969400644,36.20321575552225,36.20373912155629,36.20478551834822,36.206354945898056,36.207401007413864,36.207401007413864,36.208447404205806,36.20897077023983,36.209493800997734,36.21001683175564,36.21054019778967,36.21106322854757,36.211586594581604,36.21210962533951,36.21263265609741,36.21315602213144,36.21420208364725,36.214725449681275,36.215248480439186,36.21577184647322,36.216817907989025,36.216817907989025,36.217341274023056,36.218910701572895,36.2194337323308,36.21995709836483,36.220480129122734,36.220480129122734,36.220480129122734,36.220480129122734,36.220480129122734,36.2194337323308,36.21786430478096,36.21420208364725,36.21210962533951,36.21001683175564,36.207401007413864,36.20478551834822,36.20269272476435,36.200076900422566,36.1974610760808,36.194845251739025,36.19170639663935,36.18909057229757,36.1864747479558,36.18333589285612,36.17967367172241,36.17653481662274,36.172872595489025,36.16921070963144,36.16607151925564,36.16293266415596,36.15979380905628,36.15717798471451,36.154562160372734,36.15194633603096,36.14880748093128,36.145145259797566,36.14148337393999,36.13782115280628,36.13415893167258,36.131020076572895,36.127357855439186,36.12474203109741,36.12108014523983,36.11689489334821,36.112709641456604,36.1095704510808,36.105908565223224,36.10224634408951,36.09910748898983,36.096491664648056,36.09439887106418,36.09282944351435,36.09178304672242,36.09021361917257,36.089167557656765,36.088644191622734,36.0875977948308,36.0870747640729,36.08655173331499,36.08602836728096,36.085505336523056,36.085505336523056,36.08393590897322,36.08341254293919,36.08288951218128,36.082366481423385,36.082366481423385,36.08132008463144,36.08079671859741,36.079750657081604,36.07870426028967,36.076088435947895,36.073995642364025,36.072426214814186,36.07033375650644,36.06771793216467,36.0656251385808,36.06300964951515,36.061439886689186,36.05934742838144,36.05673160403967,36.05516217648983,36.054115779697895,36.053592748939984,36.052546352148056,36.05149995535612,36.050976924598224,36.050453558564186,36.050453558564186,36.050453558564186,36.050453558564186,36.050453558564186,36.04993052780628,36.04993052780628,36.04993052780628,36.04993052780628,36.04993052780628,36.050453558564186,36.05202332139015,36.05202332139015,36.052546352148056,36.052546352148056,36.052546352148056,36.05306938290596,36.05306938290596,36.053592748939984,36.0546388104558,36.0546388104558,36.05516217648983,36.05516217648983,36.055685207247734,36.055685207247734,36.055685207247734,36.056208573281765\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": -0.187978,\n \"PositionLongitude\": 36.16425,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 0.05,\n \"Status\": 0,\n \"Street\": \"Bahati Settlement\",\n \"TotalDistanceCovered\": null,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Nakuru\",\n \"TractorID\": 501555,\n \"TractorModelID\": 19,\n \"TractorName\": \"John Deere 5075E\",\n \"UpdatedAt\": \"2019-10-30 15:55:21\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"_acl\": {\n \"creator\": \"5cff8e7bb119264a16015316\"\n },\n \"license_plate_number\": \"KTCB 806W\",\n \"_kmd\": {\n \"lmt\": \"2019-06-17T16:00:43.009Z\",\n \"ect\": \"2019-06-11T11:27:05.488Z\"\n },\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"FuelLevelVoltage\": 0,\n \"LastMaintenanceNotificationEngineHours\": 219\n },\n \"501601\": {\n \"_id\": \"5d5546a520b56d2ef3884456\",\n \"ActiveTimeToday\": 54039,\n \"BookingRequests\": true,\n \"Characteristic\": \"102,103,109\",\n \"Country\": \"Kenya\",\n \"CreatedAt\": \"2019-08-15 11:48:51\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 100,\n \"FixedEngineHours\": 0,\n \"FixedOdometerReading\": 0,\n \"FuelLitres\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"\",\n \"Heading\": 261,\n \"ImplementsAttached\": \"\",\n \"LastActiveTime\": \"2019-10-30 14:53:23\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"-0.17904923026292965,-0.17848026944496084,-0.17825261805794063,-0.17779765054997312,-0.1759764393081293,-0.17472452411338193,-0.17358660219554536,-0.17199337728578767,-0.16994484927095743,-0.16755467612946362,-0.16527849610556028,-0.16277466425065673,-0.16027116735971159,-0.1576533414366261,-0.1550358504593444,-0.15230436567840114,-0.1498005322645551,-0.14752435030132763,-0.14524816810527083,-0.14297198567997235,-0.14046848649928229,-0.13785065822231918,-0.13557447507682863,-0.13341228529174484,-0.13136375362520528,-0.1294288801079977,-0.12760800004385275,-0.1256731262421509,-0.12373858757248068,-0.12169005513596698,-0.1196411872684877,-0.11759265452344747,-0.11565811527919095,-0.11383723428598057,-0.11213001156736511,-0.11076409921051941,-0.10939852206623699,-0.1081466032645752,-0.1072363301880556,-0.10609806970993114,-0.10518746129726465,-0.10427718813359785,-0.10336657966803238,-0.10245630645193732,-0.10188700849369649,-0.10097673523568172,-0.10029377881874271,-0.09972481609819152,-0.09904185965519742,-0.0987005490662343,-0.0987005490662343,-0.0988142075043988,-0.09904185965519742,-0.09926951180443119,-0.09949716395210013,-0.09983847453284471,-0.10029377881874271,-0.10074908309829232,-0.10143203950568967,-0.10222865432496742,-0.10291161070102994,-0.10359423178687277,-0.10439084655215743,-0.10541511340292482,-0.10655337390622656,-0.1081466032645752,-0.10962617414054962,-0.11099175127438711,-0.11235766362066064,-0.11383723428598057,-0.11531646959993781,-0.11679604011246388,-0.11804795854107204,-0.11918621855246919,-0.12055179522863758,-0.12157606150970403,-0.12294163806550752,-0.12430754982681344,-0.1256731262421509,-0.12715269618877997,-0.12874592437093405,-0.13056680435360588,-0.1326156713610123,-0.13477786121646268,-0.1370540444372433,-0.13933022744172077,-0.14149275196615219,-0.14365494101394521,-0.14558981337816357,-0.14763834380630966,-0.14968687404572162,-0.1515077524007637,-0.15355628227656193,-0.15537716030422313,-0.15742568980704408,-0.15924656749902955,-0.1610677803049938,-0.1630023158208133,-0.16505084456129343,-0.16675806344220073,-0.16846528217505954,-0.1702861588636945,-0.1723346868420756,-0.17426955651923412,-0.17609043265324398,-0.17779765054997312,-0.1795045330143754,-0.18109809255501108,-0.18269131668114372,-0.1843985339591405,-0.18576410649911204,-0.18690202765612174,-0.18792629074414027,-0.1888368957827853,-0.18974750077372202,-0.19077176369408716,-0.19168203330866204,-0.1923649869435317,-0.19304794055107405,-0.19373055885697213,-0.19452717036189565,-0.19521012388226533,-0.19589307737490058,-0.1964620376270869,-0.19691733992455301,-0.1973726422095895,-0.19782760920803213,-0.19805526033962836,-0.19828291146810764,-0.19828291146810764,-0.1983969046682399,-0.19851056259345726,-0.19851056259345726,-0.19828291146810764,-0.19805526033962836,-0.1979416024112813,-0.19760029334743234,-0.19714499106862973,-0.19668968877737206,-0.19634837968786237,-0.19600673531721663,-0.1955517682691319,-0.19498247271187907,-0.19452717036189565,-0.1939582100442408,-0.19338924970745172,-0.19293394731460717,-0.19225132897673813,-0.19156837533732662,-0.19088542167070233,-0.19020246797695423,-0.18951984953047563,-0.1888368957827853,-0.18826793527637092,-0.1876989747513948,-0.18701602093238373,-0.1863330670868087,-0.18553645520402257,-0.18485350130121025,-0.1843985339591405,-0.18394323133102392,-0.1834879286913047,-0.18314661934111673,-0.18269131668114372,-0.18223601400963166,-0.181780711326606,-0.1813254086321049,-0.18087044120061066,-0.18041513848324772,-0.1799598357544984,-0.1795045330143754,-0.17904923026292965,-0.17859426277465615,-0.17813896000062845,-0.17791130860938448\",\n \"Longitude\": \"36.27358887344599,36.27290591597557,36.27245094627141,36.27188164740801,36.26949179917574,36.26789856702089,36.26664664596319,36.26516707241535,36.263801492750645,36.26243557780981,36.26118365675212,36.26015938818454,36.25924911350012,36.25845216214657,36.25776953995228,36.25708658248186,36.256745271384716,36.25651761889458,36.25651761889458,36.25651761889458,36.25663127750158,36.25708658248186,36.257655546069145,36.258224844932556,36.259135119616985,36.26015938818454,36.26141130924225,36.26289088279009,36.26459810882807,36.26664664596319,36.268922835588455,36.271312683820724,36.27381652593612,36.27632036805153,36.2787102162838,36.281100399792194,36.28337658941746,36.28565277904272,36.287473663687706,36.28997750580311,36.29213970154524,36.2944158911705,36.29657842218876,36.29874061793089,36.30067549645901,36.30329299718142,36.30545552819967,36.307731717824936,36.309893913567066,36.31217010319234,36.314218640327454,36.31626717746257,36.3183157145977,36.32047824561595,36.32241278886796,36.32423400878906,36.325940899550915,36.32730681449175,36.32878638803959,36.330151967704296,36.331631541252136,36.33288346230984,36.334021389484406,36.33493199944496,36.335956268012524,36.33709419518709,36.33823245763779,36.339370384812355,36.34039465337992,36.34141892194748,36.342329531908035,36.34312614798546,36.343809105455875,36.344491727650166,36.34517468512058,36.345857642591,36.346426606178284,36.3471095636487,36.34756486862898,36.34801983833313,36.34847514331341,36.348930448293686,36.34915810078383,36.34927175939083,36.34927175939083,36.34927175939083,36.34927175939083,36.34927175939083,36.34915810078383,36.34915810078383,36.34915810078383,36.34904410690069,36.348930448293686,36.34870279580355,36.34858913719655,36.3483614847064,36.348133832216256,36.347906179726124,36.34756486862898,36.3471095636487,36.34665425866842,36.346198953688145,36.345743648707874,36.34517468512058,36.3446057215333,36.34415041655302,36.3434674590826,36.34267084300518,36.342101879417896,36.34141892194748,36.34073629975319,36.33993934839964,36.33925672620534,36.338460110127926,36.33754950016737,36.33652523159981,36.33550096303225,36.33436303585768,36.33322477340698,36.332086846232414,36.330607272684574,36.329127699136734,36.327648125588894,36.32616855204105,36.32457531988621,36.32286809384823,36.321047209203236,36.319112330675125,36.31706379354,36.31490159779786,36.31273906677961,36.31046287715435,36.30818668752909,36.30613815039396,36.30408961325884,36.30249638110399,36.300561502575874,36.29874061793089,36.297147385776036,36.29578180611133,36.294529885053635,36.2931639701128,36.292026042938225,36.29088778048754,36.289863511919975,36.28872558474541,36.287701316177845,36.286904700100415,36.285994090139866,36.28519747406244,36.28440085798502,36.2836042419076,36.28280729055405,36.28212466835976,36.28144171088934,36.28075875341892,36.28018978983164,36.27973448485136,36.27927951514721,36.27882421016693,36.27848256379366,36.278141252696514,36.27779994159937,36.27734463661909,36.27688933163881,36.276434026658535,36.275979056954384,36.275523751974106,36.27484079450369,36.274271830916405,36.27358887344599,36.273019909858704,36.27245094627141,36.27199564129114,36.271767988801\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 1566321821812,\n \"PositionLatitude\": -0.15612,\n \"PositionLongitude\": 36.412721,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 3.33,\n \"Status\": 1,\n \"Street\": \"Ol Kalou Settlement\",\n \"TotalDistanceCovered\": 4546,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Nyandarua\",\n \"TractorID\": 501601,\n \"TractorModelID\": 57,\n \"TractorName\": \"VALTRA\",\n \"UpdatedAt\": \"2019-10-30 15:54:10\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"_acl\": {\n \"creator\": \"5d55463b61276e3b4be973b1\"\n },\n \"license_plate_number\": \"KAT 063S\",\n \"_kmd\": {\n \"lmt\": \"2019-10-08T14:09:22.062Z\",\n \"ect\": \"2019-08-15T11:48:53.021Z\"\n },\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 1,\n \"AssetState\": \"On\",\n \"FuelLevelVoltage\": 0,\n \"LastWorkingHourNotificationTime\": \"2019-10-08T23:28:00.534Z\",\n \"LastMaintenanceNotificationEngineHours\": 20\n },\n \"501630\": {\n \"_id\": \"5d2ee357ecc87c44b9cbcbcd\",\n \"ActiveTimeToday\": 23091,\n \"BookingRequests\": true,\n \"Characteristic\": \"102\",\n \"Country\": \"Kenya\",\n \"CreatedAt\": \"2019-07-17 08:59:03\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 648,\n \"FixedEngineHours\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"\",\n \"Heading\": 43,\n \"ImplementsAttached\": \"\",\n \"LastActiveTime\": \"2019-10-30 14:40:54\",\n \"LastGeofenceNotificationTime\": \"2019-10-14T12:54:08.117Z\",\n \"Latitude\": \"0.34499470290222134,0.34499470290222134,0.34499470290222134,0.34499470290222134,0.34499470290222134,0.34499470290222134,0.34499470290222134,0.34499470290222134,0.34499470290222134,0.34499470290222134,0.34499470290222134,0.34499470290222134,0.34499470290222134,0.34499470290222134,0.34499470290222134,0.34499470290222134,0.34499470290222134,0.3448086280232137,0.3446225531405675,0.34443647825427004,0.34425040336435947,0.3440643284708103,0.3440643284708103,0.34387858884371575,0.34369251394291495,0.34369251394291495,0.34369251394291495,0.3433203641304613,0.3433203641304613,0.343134289218783,0.3429482143034916,0.3427624746547311,0.34239032480609544,0.34220424987635156,0.34183210000606273,0.34164602506549224,0.34127421044375783,0.3409020605374396,0.3405299106167453,0.340158095951908,0.33959987102243944,0.33922772105154325,0.3384837563371101,0.33792586658141477,0.3371815664968791,0.3368094164332761,0.3362515265815789,0.33587937648246824,0.33569330142760134,0.33532148657765576,0.3351354115121785,0.33494933644317726,0.3343914464853895,0.3338332212254613,0.3334610710345725,0.33290318099230914,0.3325310307662943,0.3319731406714628,0.3314149152746435,0.33085668984634947,0.33048487481391636,0.3297405741661808,0.3295548342661183,0.3288105335488686,0.3284383831694365,0.32788049284493076,0.3275083424308943,0.32713652727369436,0.3267643768320506,0.326392226376616,0.326020075907416,0.32546218544853817,0.32509003494498817,0.32471821969847825,0.32453214443471257,0.32415999389692707,0.3236017680646008,0.32322995276343625,0.3228578021778661,0.32248565157865766,0.3222999115447829,0.3219277609251808,0.3217416856102972,0.32136953497033954,0.3209977195877019,0.32081164425587233,0.32043949358206086,0.319323376750506,0.3191373013882957,0.3187651506537866,0.3182072597977719,0.31764903364060926,0.31764903364060926,0.31746329351916747,0.317277218123396,0.31709114272429134,0.3167189919160315,0.31634684109441324,0.31616110094962613,0.315975025530484,0.3156028746822,0.314858908216757,0.3146728327743459,0.3146728327743459,0.3144867573286016,0.31430068187953675,0.31392853097147105,0.31374279078358114,0.3135567153212597,0.3131845643867445,0.3129984889145253,0.312812413439011,0.31262667323132526,0.3122545222638086,0.3120684467751141,0.3118823712831245,0.31169629578783986,0.3113244800585981,0.3111384045534665,0.3109523290450525,0.3107662535333562,0.31039410250014204,0.31002228672506216,0.30983621119700505,0.30983621119700505,0.30965013566567834,0.3094640601310821,0.30927798459324163,0.30890616877898996,0.3087200932313661,0.3085340176804854,0.3085340176804854,0.30779005071572074,0.30779005071572074,0.3074178995782226,0.30723182400459453,0.30723182400459453,0.307045748427735,0.307045748427735,0.307045748427735,0.30685967284764404,0.30685967284764404,0.30685967284764404,0.30667359726432164,0.3064878569490823,0.3059296301700194,0.3055574789678287,0.3055574789678287,0.3053717386332643,0.3053717386332643,0.3053717386332643,0.3053717386332643,0.30518566302412853,0.30518566302412853,0.30518566302412853,0.304999587411774,0.304999587411774,0.3048135117961881,0.3048135117961881,0.3048135117961881,0.3046274361774089,0.30444136055541093,0.30425528493019427,0.30406954457316243,0.30388346894153373,0.30388346894153373,0.3036973933067118,0.3035113176686712,0.3035113176686712,0.3033252420274372,0.3033252420274372,0.3031391663829973,0.3031391663829973,0.30295342600680575,0.302767350355992,0.3023951990447592,0.3023951990447592,0.30220912338437833,0.30220912338437833,0.30202304772079147,0.30202304772079147,0.30202304772079147,0.30202304772079147,0.30183697205402404,0.30183697205402404,0.30183697205402404,0.30183697205402404,0.30183697205402404,0.30183697205402404,0.30183697205402404,0.30183697205402404,0.3016512316555559,0.3016512316555559,0.30146515598242735,0.30146515598242735,0.30146515598242735,0.30146515598242735,0.30146515598242735,0.30146515598242735,0.30127908030610556,0.30109300462662864,0.30109300462662864,0.30090692894395843,0.30072085325813314,0.30034903714847155,0.30034903714847155,0.30016296145314275,0.2999768857546334,0.2999768857546334,0.2997908100529562,0.2997908100529562,0.2997908100529562,0.2996047343481366,0.2996047343481366,0.2996047343481366,0.2996047343481366,0.2996047343481366,0.2994189939116927,0.2994189939116927,0.2994189939116927,0.2994189939116927,0.29923291820055015,0.2990468424862398,0.2990468424862398,0.2986746910481792,0.2986746910481792,0.29848861532444165,0.29848861532444165,0.29830253959753633,0.29830253959753633,0.29830253959753633,0.29830253959753633,0.29830253959753633,0.29830253959753633,0.2981167991390702,0.2981167991390702,0.29793072340588006,0.29793072340588006,0.29774464766956027,0.2975585719300854,0.2975585719300854,0.2973724961874808,0.2971864204417338,0.2970003446928445,0.296814604212458,0.296628528457322,0.2964424526990564,0.2964424526990564,0.2964424526990564,0.2964424526990564,0.2962563769376611,0.2962563769376611,0.2962563769376611,0.2962563769376611,0.2962563769376611,0.29607030117314886,0.29607030117314886,0.29588422540550696,0.29588422540550696,0.29551240913253035,0.29551240913253035,0.29551240913253035,0.29551240913253035,0.29551240913253035,0.29551240913253035,0.2953263333555503,0.2953263333555503,0.2953263333555503,0.29514025757542794,0.29495418179221405,0.29458236548814426,0.29458236548814426,0.294396289695605,0.294396289695605,0.294396289695605,0.2942102138999488,0.29402413810120104,0.2938380622993618,0.2938380622993618,0.29365198649440566,0.29365198649440566,0.29346591068635797,0.29346591068635797,0.2932801701469531,0.2932801701469531,0.29309409433273514,0.29309409433273514,0.292908018515413,0.29272194269499935,0.29272194269499935,0.29272194269499935,0.29272194269499935,0.29272194269499935,0.29272194269499935,0.29272194269499935,0.29272194269499935,0.29272194269499935,0.29272194269499935,0.29272194269499935,0.29272194269499935,0.29272194269499935,0.29272194269499935,0.29272194269499935,0.29272194269499935,0.29272194269499935,0.29272194269499935,0.29272194269499935,0.29272194269499935,0.29272194269499935,0.29272194269499935,0.292908018515413,0.292908018515413,0.292908018515413,0.292908018515413,0.29309409433273514,0.29309409433273514,0.2932801701469531,0.2932801701469531,0.29346591068635797,0.29346591068635797,0.29365198649440566,0.29365198649440566,0.2938380622993618,0.2938380622993618,0.29402413810120104,0.29402413810120104,0.2942102138999488,0.294396289695605,0.29495418179221405,0.29495418179221405,0.29495418179221405,0.2953263333555503,0.2953263333555503,0.29551240913253035,0.2956984849064061,0.29607030117314886,0.29607030117314886,0.2964424526990564,0.2964424526990564,0.296814604212458,0.296814604212458,0.2971864204417338,0.2970003446928445,0.2973724961874808,0.2973724961874808,0.2973724961874808,0.29774464766956027,0.29774464766956027,0.29793072340588006,0.2981167991390702,0.29830253959753633,0.29848861532444165,0.29886076676879975,0.2990468424862398,0.2994189939116927,0.2996047343481366,0.2999768857546334,0.2999768857546334,0.30034903714847155,0.30072085325813314,0.30109300462662864,0.30146515598242735,0.30202304772079147,0.30220912338437833,0.302767350355992,0.30295342600680575,0.30295342600680575,0.3031391663829973,0.3035113176686712,0.3036973933067118,0.30388346894153373,0.30406954457316243,0.30425528493019427,0.30444136055541093,0.3048135117961881,0.3048135117961881,0.3053717386332643,0.30611570576626757,0.30611570576626757,0.30611570576626757,0.30630178135929703,0.30667359726432164,0.307045748427735,0.30723182400459453,0.30723182400459453,0.30834794212634775,0.3085340176804854,0.3087200932313661,0.3094640601310821,0.30965013566567834,0.30983621119700505,0.3102083622498369,0.31039410250014204,0.3105801780183903,0.3107662535333562,0.3109523290450525,0.3111384045534665,0.3111384045534665,0.3111384045534665,0.3115102202892729,0.3118823712831245,0.3120684467751141,0.3122545222638086,0.3124405977492081,0.31262667323132526,0.312812413439011,0.3131845643867445,0.31374279078358114,0.31374279078358114,0.31430068187953675,0.3146728327743459,0.3150449836558731,0.31523072382059586,0.3157889501079959,0.315975025530484,0.31616110094962613,0.316532916506889,0.316905067321828,0.31709114272429134,0.31746329351916747,0.31746329351916747,0.31764903364060926,0.3182072597977719,0.3187651506537866,0.31895122602272685,0.31895122602272685,0.31950945210934484,0.31988160281689565,0.3202534182400917,0.3206255689206459,0.32081164425587233,0.3209977195877019,0.32136953497033954,0.3215556102920168,0.3217416856102972,0.3221138362366803,0.3222999115447829,0.32267172687995394,0.3228578021778661,0.3236017680646008,0.3237878433454524,0.32415999389692707,0.32434606916752456,0.32471821969847825,0.3249039596880797,0.325276110198487,0.32564826069516706,0.3258343359383609,0.326392226376616,0.3265783016060572,0.3267643768320506,0.32713652727369436,0.3275083424308943,0.32769441763964907,0.3284383831694365,0.3288105335488686,0.3289966087333876,0.32936875909203156,0.329926649333334,0.3302987996572081,0.33048487481391636,0.3306709499671514,0.33085668984634947,0.3314149152746435,0.3319731406714628,0.3319731406714628,0.3323449556480199,0.33290318099230914,0.333274995933842,0.33364714613176616,0.33457718629457717,0.3347632613706392,0.3351354115121785,0.33550756163958345,0.33587937648246824,0.3360654515337856,0.33662367666647885,0.336995491466846,0.33755371654627137,0.33792586658141477,0.3384837563371101,0.33885590633660584,0.3390419813309913,0.3394137960387915,0.33959987102243944,0.33997202097899765,0.340158095951908,0.3409020605374396,0.34127421044375783,0.34164602506549224,0.34201817494300735,0.34220424987635156,0.34239032480609544,0.3427624746547311,0.3429482143034916,0.343134289218783,0.3433203641304613,0.3433203641304613,0.34350643903850103,0.34369251394291495,0.34369251394291495,0.34387858884371575,0.34387858884371575,0.34387858884371575,0.3440643284708103,0.3440643284708103,0.3440643284708103,0.3440643284708103,0.3440643284708103,0.34387858884371575\",\n \"Longitude\": \"34.18603330850601,34.18603330850601,34.18603330850601,34.18603330850601,34.18603330850601,34.18603330850601,34.18603330850601,34.18603330850601,34.18603330850601,34.18603330850601,34.18603330850601,34.18603330850601,34.18603330850601,34.18603330850601,34.18603330850601,34.18603330850601,34.18603330850601,34.18473109602928,34.18380104005337,34.18342888355256,34.182684905827045,34.18249882757664,34.18212667107582,34.181754514575005,34.181382693350315,34.1810105368495,34.18063838034868,34.180266559124,34.17989440262318,34.17952224612236,34.179150089621544,34.178778268396854,34.17840611189603,34.17784821242094,34.177476055920124,34.17710389941931,34.17654599994421,34.176173843443394,34.17580168694258,34.17524378746747,34.174871630966656,34.17431339621544,34.17356941848993,34.17282544076443,34.172081127762794,34.171709306538105,34.17133715003729,34.17096499353647,34.17096499353647,34.170407094061375,34.17022101581096,34.170407094061375,34.17003493756056,34.169476702809334,34.16929095983505,34.16929095983505,34.16873272508383,34.16854664683342,34.16836056858301,34.16836056858301,34.16817482560873,34.16817482560873,34.167802669107914,34.167802669107914,34.167802669107914,34.167616590857506,34.167616590857506,34.167616590857506,34.1674305126071,34.1674305126071,34.1674305126071,34.1674305126071,34.1674305126071,34.16724443435669,34.16724443435669,34.16705835610628,34.16705835610628,34.16705835610628,34.16705835610628,34.16705835610628,34.16705835610628,34.16705835610628,34.16705835610628,34.16705835610628,34.16705835610628,34.16705835610628,34.16705835610628,34.16705835610628,34.16705835610628,34.16705835610628,34.16705835610628,34.16705835610628,34.16724443435669,34.16724443435669,34.16724443435669,34.16724443435669,34.1674305126071,34.1674305126071,34.1674305126071,34.1674305126071,34.1674305126071,34.167616590857506,34.167616590857506,34.167616590857506,34.167616590857506,34.167616590857506,34.167802669107914,34.167802669107914,34.16798874735832,34.16798874735832,34.16798874735832,34.16798874735832,34.16798874735832,34.16817482560873,34.16817482560873,34.16817482560873,34.16836056858301,34.16836056858301,34.16854664683342,34.16854664683342,34.16873272508383,34.168918803334236,34.168918803334236,34.169104881584644,34.169104881584644,34.16929095983505,34.16929095983505,34.169476702809334,34.16966278105974,34.16966278105974,34.16966278105974,34.16966278105974,34.17003493756056,34.17003493756056,34.17003493756056,34.17022101581096,34.17022101581096,34.17022101581096,34.170407094061375,34.170407094061375,34.170407094061375,34.170407094061375,34.170407094061375,34.17059317231178,34.17059317231178,34.17096499353647,34.17133715003729,34.1715232282877,34.1715232282877,34.1715232282877,34.1715232282877,34.171709306538105,34.171709306538105,34.171709306538105,34.171895049512386,34.172081127762794,34.1722672060132,34.1722672060132,34.1722672060132,34.17245328426361,34.17263936251402,34.17282544076443,34.17282544076443,34.173011519014835,34.17319726198912,34.17319726198912,34.173383340239525,34.173383340239525,34.17356941848993,34.17356941848993,34.17356941848993,34.17375549674034,34.17375549674034,34.17394157499075,34.17412765324116,34.17431339621544,34.17449947446585,34.17449947446585,34.174685552716255,34.174685552716255,34.174685552716255,34.174685552716255,34.174871630966656,34.174871630966656,34.174871630966656,34.174871630966656,34.175057709217064,34.175057709217064,34.175057709217064,34.175057709217064,34.175057709217064,34.175057709217064,34.17524378746747,34.17524378746747,34.17524378746747,34.17524378746747,34.17524378746747,34.17542986571788,34.17542986571788,34.17542986571788,34.17561560869217,34.17561560869217,34.17580168694258,34.175987765192986,34.176173843443394,34.176173843443394,34.1763599216938,34.17654599994421,34.17654599994421,34.17673174291849,34.17673174291849,34.17673174291849,34.1769178211689,34.1769178211689,34.1769178211689,34.1769178211689,34.1769178211689,34.17710389941931,34.17710389941931,34.17710389941931,34.17710389941931,34.177289977669716,34.177476055920124,34.177476055920124,34.178033955395215,34.178033955395215,34.17822003364562,34.17840611189603,34.17840611189603,34.178592190146446,34.178592190146446,34.178592190146446,34.178592190146446,34.178592190146446,34.178778268396854,34.178778268396854,34.17896434664726,34.17933616787195,34.17933616787195,34.17952224612236,34.17970832437277,34.17989440262318,34.18008048087359,34.180452302098274,34.18063838034868,34.18082445859909,34.1810105368495,34.18119661509991,34.18119661509991,34.181382693350315,34.181382693350315,34.181382693350315,34.181568436324596,34.181568436324596,34.181754514575005,34.181568436324596,34.18194059282541,34.18194059282541,34.18212667107582,34.18249882757664,34.182684905827045,34.182684905827045,34.182684905827045,34.18287064880133,34.18287064880133,34.18287064880133,34.18305672705174,34.18342888355256,34.18361496180296,34.18380104005337,34.18454501777887,34.18454501777887,34.18491717427969,34.18491717427969,34.18491717427969,34.18547507375479,34.185661152005196,34.18640512973071,34.18659120798111,34.18677728623152,34.187149442732334,34.187149442732334,34.18752159923315,34.188265576958656,34.18863773345947,34.18900955468416,34.18938171118498,34.1899399459362,34.19068392366171,34.191056080162525,34.19124182313681,34.19161397963762,34.19161397963762,34.19291619211435,34.19310227036476,34.19347442686558,34.194032326340675,34.19459056109189,34.195148460567,34.19570669531822,34.19607851654291,34.19645067304373,34.19645067304373,34.19700890779495,34.19775288552046,34.19831112027168,34.19868294149637,34.19886901974678,34.19961333274842,34.20017123222351,34.200729466974735,34.201101288199425,34.20147344470024,34.20184560120106,34.20203134417534,34.20258957892657,34.20296173542738,34.20351963490248,34.203705713152885,34.2040778696537,34.20426394790411,34.2046357691288,34.20482184737921,34.205007925629616,34.20538008213043,34.20575190335513,34.20612405985594,34.20668229460716,34.20761235058308,34.20798450708389,34.20835632830858,34.209286384284496,34.20984461903572,34.21021677553654,34.21058859676123,34.21096075326204,34.21151898801327,34.21226296573877,34.21282120049,34.21319302171469,34.21319302171469,34.213751256465905,34.21393733471632,34.21393733471632,34.214681312441826,34.214681312441826,34.214867390692234,34.214867390692234,34.21505346894264,34.21579744666815,34.215983524918556,34.21635568141937,34.216541424393654,34.21691358089447,34.21709965914488,34.217471815645695,34.2176578938961,34.21802971512079,34.21802971512079,34.218401871621616,34.21858794987201,34.21877402812242,34.219145849347115,34.21933192759752,34.21951800584793,34.21989016234875,34.21970408409834,34.21970408409834,34.21989016234875,34.21989016234875,34.21989016234875,34.21989016234875,34.21989016234875,34.21989016234875,34.21989016234875,34.21989016234875,34.21989016234875,34.21970408409834,34.21970408409834,34.21970408409834,34.21970408409834,34.21951800584793,34.21951800584793,34.21933192759752,34.219145849347115,34.21877402812242,34.21858794987201,34.218401871621616,34.2182157933712,34.21802971512079,34.21802971512079,34.217843636870384,34.2176578938961,34.2176578938961,34.217471815645695,34.217471815645695,34.217471815645695,34.21728573739529,34.21728573739529,34.21709965914488,34.21691358089447,34.216727502644055,34.216541424393654,34.216541424393654,34.21635568141937,34.21635568141937,34.216169603168964,34.21561136841774,34.21542529016733,34.21542529016733,34.21523954719305,34.21505346894264,34.21505346894264,34.214681312441826,34.214681312441826,34.21449523419142,34.2141230776906,34.213751256465905,34.213565178215504,34.213379099965096,34.21319302171469,34.21300694346428,34.21282120049,34.21244904398918,34.21244904398918,34.21226296573877,34.212076887488365,34.21170473098755,34.21133290976286,34.21058859676123,34.21021677553654,34.21003069728613,34.20965854078531,34.209472462534904,34.209286384284496,34.20891456305981,34.2087284848094,34.20854240655899,34.208170250058174,34.207426272332675,34.20724019408226,34.206868037581444,34.20668229460716,34.206496216356754,34.20612405985594,34.20575190335513,34.20575190335513,34.20556616038084,34.205194003880024,34.205194003880024,34.205007925629616,34.20482184737921,34.20444969087839,34.2040778696537,34.203705713152885,34.20351963490248,34.20314781367779,34.20296173542738,34.20258957892657,34.20240350067616,34.202217422425754,34.20203134417534,34.20165952295065,34.20128736644983,34.200729466974735,34.20035731047392,34.20017123222351,34.199799075722694,34.19961333274842,34.19942725449801,34.198496863245964,34.198125042021275,34.197938963770866,34.19756680727004,34.19700890779495,34.196636751294136,34.19645067304373,34.19607851654291,34.195148460567,34.19477663934231,34.194032326340675,34.19366016983986,34.19310227036476,34.192730113863945,34.192358292639256,34.19198613613844,34.19161397963762,34.19087000191212,34.1904978454113,34.18956778943539,34.18938171118498,34.18900955468416,34.188823476433754,34.188451655209064,34.18807949870825,34.18770734220743,34.18733552098274,34.186963364481926,34.18659120798111,34.18621938675642,34.185847230255604,34.185661152005196,34.18547507375479,34.18528899550438,34.1851032525301,34.18491717427969,34.18491717427969,34.18473109602928,34.18473109602928,34.18473109602928\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": 1.149961,\n \"PositionLongitude\": 34.93084,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 0.02,\n \"Status\": 0,\n \"Street\": \"Kwanza\",\n \"TotalDistanceCovered\": 10636,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Trans Nzoia\",\n \"TractorID\": 501630,\n \"TractorModelID\": 21,\n \"TractorName\": \"Massey Ferguson 275\",\n \"UpdatedAt\": \"2019-10-30 15:40:24\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": false,\n \"_acl\": {\n \"creator\": \"5d2ee28120b56d2ef3a07613\"\n },\n \"license_plate_number\": \"KTCB 661W\",\n \"_kmd\": {\n \"lmt\": \"2019-09-27T09:54:17.345Z\",\n \"ect\": \"2019-07-17T08:59:03.344Z\"\n },\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 1,\n \"AssetState\": \"On\",\n \"FuelLevelVoltage\": 0\n },\n \"501745\": {\n \"_id\": \"5d55473f5e24b02eee4e79f3\",\n \"ActiveTimeToday\": 55174,\n \"BookingRequests\": true,\n \"Characteristic\": \"102,103,109\",\n \"Country\": \"Kenya\",\n \"CreatedAt\": \"2019-08-15 11:51:23\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 272,\n \"FixedEngineHours\": 0,\n \"FixedOdometerReading\": 0,\n \"FuelLitres\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"\",\n \"Heading\": 342,\n \"ImplementsAttached\": \"109\",\n \"LastActiveTime\": \"2019-10-30 14:53:46\",\n \"LastGeofenceNotificationTime\": \"2019-10-03T03:19:01.881Z\",\n \"Latitude\": \"-1.6089318580438576,-1.6089228091573353,-1.6089191225739232,-1.6089137602707875,-1.6089083979676138,-1.6089047113841761,-1.60889901393705,-1.608893651633838,-1.608888289330626,-1.608884602747163,-1.6088829270274012,-1.608879240443913,-1.608879240443913,-1.6088809161636872,-1.6088829270274012,-1.608884602747163,-1.6088899650503876,-1.6088956624975392,-1.6089010248007385,-1.608906387103925,-1.6089154359905238,-1.6089207982936593,-1.6089318580438576,-1.608939231210618,-1.6089462692334011,-1.6089536424001107,-1.608961015566795,-1.608970064453152,-1.6089754267561476,-1.6089864865060406,-1.6089938596726103,-1.6090029085588147,-1.6090099465813812,-1.609019330611436,-1.609032066080747,-1.6090427906864075,-1.6090555261555533,-1.6090702724881585,-1.6090830079571388,-1.6090974191456262,-1.6091084788948575,-1.6091192035001238,-1.6091339498322583,-1.6091429987178392,-1.6091537233229147,-1.6091647830718534,-1.6091755076768142,-1.6091848917061058,-1.6091939405914704,-1.6092046651962786,-1.609217400664419,-1.609232146995854,-1.6092448824638164,-1.609261304514504,-1.6092740399822885,-1.6092901268888584,-1.6093028623564647,-1.609317608687276,-1.6093320198741097,-1.6093504527873408,-1.6093665396933001,-1.6093866483255805,-1.609410443540179,-1.609435914473814,-1.6094576988246856,-1.6094811588946065,-1.6094995918064892,-1.6095156787112779,-1.60953210075979,-1.6095505336712148,-1.609570307157838,-1.6095904157880956,-1.6096105244181624,-1.6096323087671767,-1.609650406533873,-1.609666828581291,-1.6096812397656566,-1.6096939752308201,-1.6097067106959073,-1.6097194461609055,-1.60973218162584,-1.6097486036725965,-1.6097650257192258,-1.6097868100665862,-1.6098340653423782,-1.6098615471334679,-1.6099178512896628,-1.6099506953800586,-1.609988901770257,-1.6100214107157464,-1.6100542548044758,-1.610088774611453,-1.610126980999056,-1.6101635116672535,-1.6101980314723732,-1.6102325512769202,-1.6102600330626284,-1.610287179704257,-1.6103143263455166,-1.610345494710973,-1.6103726413514567,-1.6104017988537969,-1.61043095635573,-1.6104564272766047,-1.6104855847777488,-1.6105180937153123,-1.6105526135144272,-1.610583781876232,-1.6106129393755444,-1.6106601946321895,-1.6106819789699827,-1.6107419696836238,-1.6107691163188405,-1.6108093335555143,-1.6108220690136297,-1.6108348044716687,-1.6108455290678387,-1.6108582645257379,-1.6108947951808188,-1.6109128929362941,-1.6109547858882005,-1.6109748945047944,-1.6110201388914407,-1.6110784538771776,-1.6111384445791523,-1.611171288649867,-1.6112148573143088,-1.6112296036312785,-1.6112530636808058,-1.6112657991361479,-1.6112748480122634,-1.6112859077496884,-1.6112969674870372,-1.6113040055016905,-1.6113224383970852,-1.6113331629907106,-1.6113586339003005,-1.611367682776009,-1.6113914779674785,-1.611398515981801,-1.6114058891396432,-1.6114149380151355,-1.61143136004833,-1.6114404089237204,-1.6114440955025526,-1.6114424197849027,-1.6114404089237204,-1.611436722344863,-1.61143136004833,-1.611420635455239,-1.6114149380151355,-1.6114095757185518,-1.6114005268430343,-1.611393153685179,-1.6113914779674785,-1.6113894671062325,-1.6113877913885446,-1.6113857805272986,-1.6113804182306386,-1.6113767316516792,-1.6113696936372677,-1.6113660070582956,-1.6113532716035768,-1.611338525287485,-1.6113294764116495,-1.6113167409567144,-1.6112986432048142,-1.611289594328813,-1.611276858873611,-1.6112641234183325,-1.6112366416461608,-1.6112239061906406,-1.6112111707350443,-1.6111840241057307,-1.6111602289118312,-1.6111002382104926,-1.6110804647387162,-1.6110657184206651,-1.6110385717894051,-1.6110184631734346,-1.6109983545572604,-1.6109876299618795,-1.6109802568025358,-1.6109691970634568,-1.6109584724679231,-1.610949423590408,-1.6109346772713902,-1.6109165795161058,-1.6108766974251654,-1.6108582645257379,-1.6108401667697665,-1.6108056469755243,-1.6107728028989066,-1.6107275585067644,-1.6106856655502015,-1.6106437725927738,-1.610625674834894,-1.610583781876232,-1.6105328400373327,-1.6104782116165732,-1.61043095635573,-1.6103763279322352,-1.6103180129263972,-1.6102670710808695,-1.6102198158151153,-1.6101671982484138,-1.6101397164614462,-1.6101105589553528,-1.610061627967178,-1.6100123618340714,-1.6099852151887788,-1.6099269001717578,-1.6098977426626238,-1.6098451250876147,-1.6097904966484335,-1.6097358682077638,-1.6097124081407816,-1.6096886129297072,-1.6096339844863277,-1.6095723180208652,-1.6095176895743686,-1.6094922186417642,-1.6094684234281198,-1.609384972606226,-1.6093611773913221,-1.6092884511694274,-1.6092666668167364,-1.6091956163109649,-1.6091755076768142,-1.6091228900831671,-1.6091101546144413,-1.6090682616246226,-1.609057537019102,-1.6090173197478619,-1.6089938596726103,-1.6089737510364623,-1.6089626912864932,-1.6089429177939922,-1.6089137602707875,-1.608888289330626,-1.608857456086858,-1.6088701915571741\",\n \"Longitude\": \"37.36930746585131,37.369287349283695,37.36927092075348,37.36925482749939,37.36923638731241,37.36921828240156,37.36919816583395,37.369176372885704,37.36914921551943,37.36911803483964,37.36908350139857,37.36905265599489,37.369025498628616,37.36899431794882,37.36896514892578,37.368932627141476,37.368899770081036,37.36886892467737,37.3688380792737,37.368808910250664,37.3687743768096,37.3687395080924,37.368704974651344,37.36867245286703,37.36864127218723,37.368612103164196,37.36858125776053,37.36854840070009,37.368517555296414,37.36848670989275,37.36845921725035,37.36843038350344,37.36839752644301,37.36836835741997,37.368337512016296,37.36831001937389,37.36828286200762,37.36825369298458,37.36822284758091,37.36818999052047,37.368159145116806,37.368128299713135,37.36810281872749,37.36808069050313,37.36805722117424,37.368035428225994,37.36801162362099,37.36798983067274,37.36796971410513,37.367949932813644,37.36793350428343,37.36791707575321,37.367900647222996,37.36787885427476,37.36785873770714,37.36783526837826,37.36781347543001,37.36779335886241,37.36777525395155,37.36775681376457,37.36774407327175,37.36773133277893,37.36772060394287,37.36770585179328,37.367687746882446,37.36767131835222,37.36765321344137,37.36763309687376,37.36761298030615,37.3675948753953,37.36757844686509,37.36756570637226,37.367551289498806,37.36754022538662,37.3675274848938,37.36751474440097,37.36750200390816,37.36749295145273,37.36748389899731,37.36747484654188,37.36746579408646,37.36745472997427,37.367445677518845,37.36743662506342,37.36741483211517,37.36740577965975,37.36738733947277,37.367378287017345,37.36737124621868,37.367365546524525,37.367360182106495,37.367352806031704,37.367347441613674,37.36734576523304,37.36733838915825,37.36733637750149,37.36733302474022,37.36733101308346,37.36733302474022,37.36733637750149,37.367342077195644,37.367347441613674,37.367354817688465,37.367360182106495,37.367367558181286,37.367378287017345,37.36738935112953,37.36740209162235,37.36741852015257,37.367451041936874,37.36746579408646,37.36749496310949,37.36750569194555,37.36752949655056,37.367538549005985,37.36754760146141,37.3675586655736,37.36756939440966,37.36759856343269,37.36761499196291,37.36765321344137,37.36767333000899,37.36771322786808,37.36776586622,37.36781682819128,37.36784599721432,37.3678969591856,37.36792076379061,37.3679643496871,37.36798245459795,37.36800089478493,37.36802067607641,37.368040792644024,37.368058897554874,37.3680991306901,37.368118911981576,37.368164509534836,37.36818999052047,37.368237264454365,37.36825905740261,37.36828118562698,37.36830096691847,37.368348240852356,37.36837204545736,37.368420995771885,37.36844312399626,37.368464916944504,37.36848670989275,37.36851017922163,37.36856684088707,37.368593998253345,37.36862149089575,37.36864697188139,37.36870128661394,37.36873045563698,37.36878510564566,37.36882533878088,37.368839755654335,37.36887261271477,37.36889239400626,37.36893631517887,37.36895978450775,37.369001694023616,37.369041591882706,37.36906170845032,37.36910529434681,37.36914720386267,37.36916899681091,37.369185425341136,37.369201853871346,37.36923471093178,37.36925281584263,37.36927293241024,37.36930746585131,37.36933831125498,37.36937653273344,37.36938759684563,37.36939664930105,37.369416765868664,37.36943855881691,37.369460351765156,37.36946940422058,37.36947678029537,37.369485832750804,37.36949488520622,37.36950393766164,37.369515001773834,37.36952405422926,37.369538471102715,37.36954417079687,37.36954752355814,37.36955691128969,37.36956227570772,37.36956764012575,37.36957300454378,37.36957870423794,37.36958239227533,37.369589433074,37.36959513276815,37.36960418522358,37.3696095496416,37.369613237679005,37.36961491405964,37.36961491405964,37.36961491405964,37.36961122602224,37.3696095496416,37.369607873260975,37.36960418522358,37.369602173566825,37.369602173566825,37.36960586160422,37.369607873260975,37.36961122602224,37.36961491405964,37.3696169257164,37.3696169257164,37.36961491405964,37.36961491405964,37.3696169257164,37.3696169257164,37.3696169257164,37.3696169257164,37.369620613753796,37.369618602097034,37.369613237679005,37.36961122602224,37.369600497186184,37.36959848552942,37.3695857450366,37.36958239227533,37.36956965178251,37.36956764012575,37.3695495352149,37.369533106684685,37.36951131373644,37.36949857324362,37.36946940422058,37.36941307783127,37.3693510517478,37.369165644049644,37.36906908452511\",\n \"NeedToSendGeofenceOutNotification\": false,\n \"OperatorID\": 1569395513771,\n \"PositionLatitude\": -2.154365,\n \"PositionLongitude\": 38.073964,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 2.63,\n \"Status\": 1,\n \"Street\": \"Kilawa\",\n \"TotalDistanceCovered\": 1659,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Kitui\",\n \"TractorID\": 501745,\n \"TractorModelID\": 46,\n \"TractorName\": \"SAME\",\n \"UpdatedAt\": \"2019-10-30 15:53:19\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": false,\n \"_acl\": {\n \"creator\": \"5d55463b61276e3b4be973b1\"\n },\n \"license_plate_number\": \"KTCB 273T\",\n \"_kmd\": {\n \"lmt\": \"2019-10-06T15:12:40.554Z\",\n \"ect\": \"2019-08-15T11:51:27.187Z\"\n },\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 1,\n \"AssetState\": \"On\",\n \"FuelLevelVoltage\": 0,\n \"LastWorkingHourNotificationTime\": \"2019-10-29T03:18:48.526Z\"\n },\n \"501750\": {\n \"_id\": \"5d4ad92c7e910233edf8a1ec\",\n \"ActiveTimeToday\": 2762,\n \"BookingRequests\": true,\n \"Characteristic\": \"109,102,103\",\n \"Country\": \"Kenya\",\n \"CreatedAt\": \"2019-08-07 13:59:04\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": true,\n \"Efficiency\": 0,\n \"EngineHours\": 51,\n \"FixedEngineHours\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"\",\n \"Heading\": 296,\n \"ImplementsAttached\": \"109,103,102\",\n \"LastActiveTime\": \"2019-10-30 08:40:09\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"0.4595352614891534,0.4595352614891534,0.4567887672700075,0.4506091514488676,0.4430562805561132,0.434130150494083,0.42657726297220555,0.416964486331433,0.408038326078331,0.39842552704403633,0.3888127167945079,0.37988652604278716,0.37027369492791673,0.36134748526849814,0.3537945317746649,0.3462415721326541,0.34006187339880467,0.3325089029145756,0.32564256109307516,0.3180895796914776,0.3119098635181762,0.30641677942687773,0.29886378421289456,0.28993751045615185,0.2796379550830506,0.2700250285753685,0.26178537122298784,0.25491898595306217,0.24873923607703846,0.24461940121435757,0.2391262861003741,0.2350064483196997,0.2301999693747193,0.22745340924806837,0.22539348880972976,0.22402020835549505,0.22196028743306329,0.22127364706170777,0.22127364706170777,0.22196028743306329,0.22333356808006505,0.22470684859875054,0.22608012898834365,0.22814004932897564,0.2301999693747193,0.2322598891229157,0.2350064483196997,0.23843964655554295,0.24187284393525726,0.24667931880512015,0.25217243081444973,0.2576655405059055,0.26315864782896764,0.2700250285753685,0.276204767934163,0.28307114122787536,0.2906241471515749,0.2974905117939623,0.3050435079619974,0.313969769315989,0.3222093884223396,0.33319553683571534,0.3421217734198524,0.35173463429468954,0.3620341170948991,0.370960326070702,0.37919989560028367,0.3867528274507476,0.39430575258033057,0.40048541350475103,0.40460518487057107,0.41078483799033016,0.4155912315611697,0.42108424920188975,0.4258906364643154,0.42932376839021175,0.4334435246654957,0.436876653183962,0.4403097801338297,0.4437429055028472,0.44580277996028844,0.4478626538415149,0.4485492783400833,0.44923590277422637,0.44923590277422637,0.44923590277422637\",\n \"Longitude\": \"35.37591151893139,35.37385158240795,35.36767177283764,35.35668544471264,35.34638576209545,35.3326528519392,35.32097987830639,35.31274013221263,35.3051870316267,35.29900722205639,35.292827412486076,35.29008083045483,35.286647602915764,35.284587666392326,35.283901020884514,35.28252772986889,35.2832143753767,35.2832143753767,35.283901020884514,35.28527431190013,35.286647602915764,35.2887075394392,35.29145412147045,35.295573994517326,35.301753804087646,35.30793361365795,35.314113423228264,35.31891994178295,35.325099751353264,35.32990626990795,35.33745937049389,35.34569911658764,35.353252217173576,35.35943202674389,35.366298481822014,35.374538227915764,35.38277797400951,35.38964442908764,35.397197529673576,35.4040639847517,35.41024379432201,35.415736958384514,35.421916767954826,35.42809657752514,35.43358974158764,35.43908290565014,35.443202778697014,35.44732265174389,35.451442524790764,35.45556239783764,35.459682270884514,35.463115498423576,35.46654872596264,35.469295307993896,35.47204189002514,35.474101826548576,35.476848408579826,35.478908345103264,35.479594990611076,35.481654927134514,35.48302821815014,35.48302821815014,35.48302821815014,35.48302821815014,35.48302821815014,35.482341572642326,35.4809682816267,35.479594990611076,35.476848408579826,35.474101826548576,35.47204189002514,35.46860866248607,35.463115498423576,35.4589956253767,35.45281581580638,35.446636006236076,35.43908290565014,35.43015651404858,35.41985683143139,35.410930439829826,35.402004048228264,35.393764302134514,35.388271138072014,35.38277797400951,35.37865810096264,35.37316493690014\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": 0.293747,\n \"PositionLongitude\": 35.406023,\n \"ServiceProvider\": \"AERIS\",\n \"Speed\": 0,\n \"Status\": 0,\n \"Street\": \"Tarakwa\",\n \"TotalDistanceCovered\": 185,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Uasin Gishu\",\n \"TractorID\": 501750,\n \"TractorModelID\": 8,\n \"TractorName\": \"JD 5503\",\n \"UpdatedAt\": \"2019-10-30 15:39:27\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"_acl\": {\n \"creator\": \"5d4ad8714b96d6774a566d3d\"\n },\n \"license_plate_number\": \"KTCB 283L\",\n \"_kmd\": {\n \"lmt\": \"2019-08-21T06:11:38.784Z\",\n \"ect\": \"2019-08-07T13:59:08.048Z\"\n },\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"FuelLevelVoltage\": 0\n },\n \"502142\": {\n \"_id\": \"5d777486b28df22a2dda2bd0\",\n \"ActiveTimeToday\": 0,\n \"BookingRequests\": true,\n \"Characteristic\": \"110,112,117\",\n \"Country\": \"India\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": false,\n \"Efficiency\": 0,\n \"EngineHours\": 13,\n \"FixedEngineHours\": 0,\n \"FixedOdometerReading\": 0,\n \"FuelLitres\": 64,\n \"FuelVolume\": 100,\n \"Group\": \"JOHN DEERE\",\n \"Heading\": 6,\n \"ImplementsAttached\": \"\",\n \"LastActiveTime\": \"2019-10-24 12:43:17\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"18.63195698694721,18.631971601350187,18.631958893173753,18.63194999744969,18.631937289271637,18.63193347681804,18.63193347681804,18.631938877793935,18.63194999744969,18.631960799400286,18.631975096098547,18.63198589804754,18.63199320524795,18.632004007195786,18.632014809142955,18.632029423540963,18.632042131712122,18.63205642840354,18.63207453754428,18.63208343326183,18.6320999538789,18.632118063014996,18.632134265924602,18.632157776025995,18.632181286124133,18.632208290962588,18.63223910824356,18.632271514038152,18.6323093207907,18.632350939979148,18.63239255915741,18.632436084546676,18.63247929222134,18.632513604190457,18.63254060897609,18.63256062428503,18.632578733372032,18.632594936237723,18.63260764436659,18.632623847229517,18.63264386252865,18.632676268246055,18.632714074908556,18.632759506433036,18.632790005911176,18.632815422138787,18.632837025929263,18.63285164025656,18.632871337826142,18.632884045934336,18.632898660257602,18.632904061202822,18.632905649716097,18.632905649716097,18.632905649716097,18.632892941609505,18.632891353096127,18.63288754066393,18.632880551204682,18.632873244042433,18.632867843096232,18.632860535933435,18.632849734040015,18.632844333093075,18.632833531198642,18.632828130251156,18.632824317817544,18.6328173283557,18.63281351592185,18.632810021190743,18.63280462024252,18.632790005911176,18.632777297795947,18.632764907382683,18.632748386830258,18.632734090197054,18.632717887344633,18.632701684490677,18.632685163932102,18.63266546634093,18.632647357263167,18.63263115440249,18.63261495154025,18.632596842457115,18.63258413432743,18.63256951997712,18.632553317109018,18.632533619502567,18.63250629701243,18.632488187917694,18.63247389126261,18.63245578216444,18.632443074024206,18.63243036588302,18.63241797544447,18.63239986634033,18.63237985101247,18.632360153385907,18.63234013805335,18.632316627977197,18.632293117897774,18.632269607815108,18.632246097729183,18.632220999120364,18.63219558280385,18.632173978931824,18.632152375057036,18.63213235970002,18.632112344340644,18.632096141428953,18.632081844740867,18.63207104279797,18.63206182937554,18.632052933656862,18.63204562645903,18.632031329766694,18.632018621594735,18.632005913421807,18.631991299021777,18.631982403299407,18.631980497073133,18.631973507576568,18.631969695123786,18.631966200375327,18.631964294148858,18.631960799400286,18.631960799400286,18.63195698694721,18.63195349219848,18.631946184996373,18.63194269024743,18.631938877793935,18.631938877793935,18.631938877793935\",\n \"Longitude\": \"74.03200205415487,74.03191220015286,74.0318588912487,74.0318189933896,74.03176736086607,74.03171002864838,74.03165470808744,74.03160709887744,74.03155580163002,74.03151389211416,74.03146594762802,74.03142236173153,74.0313821285963,74.03132680803537,74.03127919882536,74.03122957795858,74.03118766844273,74.03114944696428,74.03111156076193,74.03107702732086,74.03105221688747,74.03102573007345,74.03100829571486,74.03098952025177,74.03097610920668,74.03096470981836,74.03095498681068,74.03095129877329,74.03095129877329,74.03096068650486,74.03097778558731,74.03099521994591,74.03102170675993,74.03104450553656,74.03106361627579,74.03107702732086,74.03109043836594,74.03109982609749,74.03110954910517,74.03112094849348,74.03113804757595,74.03116654604673,74.0312010794878,74.03124298900366,74.03127551078796,74.03130769729616,74.03133653104304,74.03136871755123,74.03141062706709,74.03145287185907,74.03149645775558,74.03153467923403,74.03156720101833,74.03160139918327,74.03163593262435,74.03166811913252,74.03169695287943,74.03173316270113,74.03176534920932,74.03180155903101,74.03183206915855,74.03186861425638,74.03189711272717,74.03192561119795,74.03194840997458,74.0319675207138,74.03198461979628,74.03199803084135,74.03200775384903,74.03201714158058,74.03203055262566,74.03204396367073,74.03206106275321,74.03207816183567,74.03209526091814,74.03210867196321,74.03212208300829,74.032137170434,74.03215058147907,74.03216198086739,74.03217170387506,74.03217941522598,74.03218511492014,74.03219249099493,74.03219819068909,74.03220221400261,74.03220221400261,74.03220422565938,74.03220422565938,74.03220422565938,74.03220422565938,74.03220422565938,74.03220422565938,74.03220422565938,74.03220422565938,74.03220422565938,74.03219819068909,74.03219450265169,74.03218880295753,74.03218109160662,74.03217539191247,74.03216768056154,74.03215829282999,74.03214890509844,74.03214119374752,74.03213549405336,74.03212778270245,74.03212007135153,74.03211437165737,74.03210666030645,74.03209928423166,74.03209358453752,74.03208956122398,74.03208788484335,74.03208386152983,74.03207615017891,74.03206877410412,74.03206307440996,74.03205536305904,74.03205167502163,74.03204765170813,74.03204564005136,74.03204195201397,74.03203994035721,74.03203826397657,74.03203826397657,74.03203424066305,74.03203424066305,74.03203055262566,74.0320248529315,74.03201512992382,74.03200943022966,74.03200775384903,74.03200775384903\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 1568115921865,\n \"PositionLatitude\": 18.632475,\n \"PositionLongitude\": 74.031782,\n \"Speed\": 0.05,\n \"Status\": 1,\n \"Street\": \"Loni Kand\",\n \"TotalDistanceCovered\": 13,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Maharashtra\",\n \"TractorID\": 502142,\n \"TractorModelID\": 3,\n \"TractorName\": \"JD INDIA TEST 3\",\n \"UpdatedAt\": \"2019-10-30 16:01:21\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"_acl\": {\n \"creator\": \"5d77739348201157f63b687a\"\n },\n \"license_plate_number\": \"JDR-003-IN\",\n \"_kmd\": {\n \"lmt\": \"2019-09-27T06:21:29.789Z\",\n \"ect\": \"2019-09-10T10:01:42.407Z\"\n },\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"FuelLevelVoltage\": 0,\n \"PrevTempFuelData\": [\n {\n \"FuelLitres\": 64,\n \"FuelVolume\": 100,\n \"FuelRawValue\": 1216,\n \"LastActiveTime\": \"2019-10-01 04:59:36\"\n }\n ],\n \"LastMaintenanceNotificationEngineHours\": 12\n },\n \"502143\": {\n \"_id\": \"5d9ea19520835325fa3a6600\",\n \"BookingRequests\": true,\n \"Characteristic\": \"102\",\n \"FixedEngineHours\": 775,\n \"FixedOdometerReading\": 0,\n \"Group\": \"RentCo\",\n \"Latitude\": \"-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214272039776164,-0.8214298859109773,-0.8214329030860226,-0.8214352497777118,-0.8214379317110727,-0.8214406136444335,-0.8214432955777945,-0.8214453070278247,-0.8214473184778421,-0.8214500004111903,-0.8214513413778771,-0.8214533528278946,-0.8214556995195711,-0.8214577109695885,-0.8214603929029367,-0.8214627395946259,-0.8214654215279613,-0.8214681034613095,-0.8214707853946577,-0.8214734673279931,-0.8214761492613285,-0.8214795016780074,-0.8214821836113428,-0.8214855360280089,-0.8214885532030034,-0.8214915703779978,-0.8214942523113204,-0.821497269486315,-0.8215009571446273,-0.8215043095612807,-0.8215076619779341,-0.8215110143945747,-0.8215140315695565,-0.8215170487445381,-0.8215204011611661,-0.8215230830944761,-0.8215261002694451,-0.821529117444414,-0.821532134619383,-0.8215351517943393,-0.8215381689692955,-0.8215408509025928,-0.8215442033192081,-0.8215462147691873,-0.8215488967024719,-0.8215512433940975,-0.821553254844064,-0.8215549310523717,-0.8215562720190076,-0.8215576129856562,-0.8215586187106332,-0.8215596244356101,-0.8215606301605998,-0.8215623063688947,-0.8215633120938716,-0.8215643178188613,-0.8215653235438382,-0.8215666645104741,-0.8215669997521331,-0.8215680054771101,-0.821568340718769,-0.8215696816854177,-0.8215703521687356,-0.8215713578937125,-0.8215720283770305,-0.8215726988603484,-0.8215733693436664,-0.8215737045853254,-0.8215737045853254,-0.8215740398269844,-0.8215743750686434,-0.8215750455519614,-0.8215753807936202,-0.8215757160352792,-0.8215763865185972,-0.8215770570019152,-0.8215777274852332,-0.8215783979685511,-0.821579068451869,-0.821579068451869,-0.821579068451869,-0.8215797389351743,-0.8215797389351743,-0.821580074176846,-0.8215797389351743,-0.821580074176846,-0.8215804094184922,-0.821580744660164,-0.8215810799018102,-0.8215814151434692,-0.8215820856267871,-0.8215820856267871,-0.8215824208684461,-0.8215827561101051,-0.8215830913517641,-0.8215830913517641,-0.8215834265934231,-0.8215834265934231,-0.8215840970767411,-0.8215837618350821,-0.8215837618350821,-0.8215837618350821,-0.8215834265934231,-0.8215830913517641,-0.8215827561101051,-0.8215824208684461,-0.8215820856267871,-0.8215814151434692,-0.8215810799018102,-0.8215797389351743,-0.821579068451869,-0.821579068451869,-0.8215780627268922,-0.8215777274852332,-0.8215770570019152,-0.8215767217602562,-0.8215763865185972,-0.8215760512769382,-0.8215757160352792,-0.8215757160352792,-0.8215750455519614,-0.8215747103103024,-0.8215743750686434,-0.8215737045853254,-0.8215733693436664,-0.8215723636186895,-0.8215713578937125,-0.8215700169270767,-0.821568340718769,-0.8215663292688151,-0.8215646530605075,-0.8215623063688947,-0.8215592891939512,-0.8215566072606666,-0.8215529196024051,-0.8215492319441309,-0.8215455442858567,-0.8215411861442518,-0.8215381689692955,-0.8215341460693496,-0.8215304584110626,-0.821526770752763,-0.8215224126111454,-0.8215190601945175,-0.8215150372945461,-0.8215110143945747,-0.8215069914946034,-0.821502968594632,-0.8214996161779786,-0.8214962637613252,-0.8214922408613284,-0.8214885532030034,-0.8214841950613349,-0.8214798369196663,-0.8214751435363261,-0.8214704501529859,-0.8214654215279613,-0.821460057661265,-0.8214546937945687,-0.8214489946861879,-0.8214443013028095,-0.8214392726777595,-0.8214352497777118,-0.8214315621193358,-0.8214285449442905,-0.8214261982525886,-0.8214245220442301,-0.8214235163192277,-0.821423181077556,-0.821423181077556,-0.821423181077556,-0.8214228458358716,-0.8214228458358716,-0.8214225105941999,-0.8214225105941999,-0.8214221753525281,-0.8214218401108565,-0.8214211696275131,-0.8214211696275131,-0.8214211696275131,-0.8214204991441697,-0.8214204991441697,-0.8214198286608263,-0.8214191581774829,-0.8214191581774829,-0.8214191581774829,-0.8214184876941395,-0.8214184876941395,-0.8214184876941395,-0.8214191581774829,-0.8214194934191545,-0.8214198286608263,-0.8214204991441697,-0.8214215048691847,-0.8214221753525281,-0.8214225105941999,-0.8214225105941999,-0.8214228458358716,-0.8214228458358716,-0.8214228458358716,-0.821423181077556,-0.821423181077556,-0.8214235163192277,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994\",\n \"Longitude\": \"34.38148085027933,34.38148085027933,34.38148085027933,34.38148085027933,34.38148085027933,34.381479509174824,34.38147883862257,34.38147749751806,34.38147682696581,34.381476156413555,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.381476156413555,34.381476491689675,34.38147682696581,34.38147749751806,34.38147749751806,34.381478168070316,34.381478168070316,34.38147883862257,34.381479509174824,34.38147984445095,34.381480515003204,34.38148085027933,34.381481520831585,34.38148219138384,34.38148219138384,34.381482526659966,34.38148319721222,34.38148319721222,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148319721222,34.38148286193609,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148185610771,34.38148185610771,34.381481520831585,34.381481520831585,34.38148118555546,34.38148118555546,34.38148085027933,34.38148085027933,34.38148085027933,34.381480515003204,34.38148017972707,34.38148017972707,34.38147984445095,34.38147984445095,34.38147984445095,34.38147984445095,34.38147984445095,34.38148085027933,34.38148085027933,34.38148185610771,34.38148319721222,34.38148487359285,34.38148822635412,34.38149090856313,34.381494261324406,34.381497614085674,34.38150096684694,34.381504990160465,34.38150901347398,34.38151236623526,34.381516724824905,34.38152108341455,34.381526447832584,34.38153114169836,34.38153650611639,34.38154220581055,34.3815479055047,34.38155360519886,34.381559640169144,34.3815653398633,34.38157103955746,34.381576739251614,34.38158243894577,34.38158880919218,34.38159517943859,34.38160087913275,34.381606578826904,34.381612278521054,34.381617307662964,34.381622672080994,34.38162703067064,34.38163138926029,34.381635412573814,34.38163876533508,34.381642788648605,34.381646141409874,34.38164949417114,34.38165284693241,34.38165552914142,34.381657876074314,34.381659887731075,34.38166122883558,34.38166290521622,34.38166458159685,34.38166558742523,34.38166692852974,34.381667599081986,34.381668604910374,34.38166927546263,34.38166994601488,34.38167028129101,34.38167095184326,34.381671622395515,34.38167229294777,34.38167296350002,34.38167329877616,34.38167363405228,34.3816739693284,34.3816739693284,34.38167430460453,34.38167430460453,34.381674639880664,34.381674975156784,34.381674975156784,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.381674975156784,34.381674975156784,34.38167430460453,34.38167430460453,34.3816739693284,34.3816739693284,34.38167363405228,34.38167296350002,34.381672628223896,34.38167195767164,34.381671622395515,34.38167028129101,34.38166927546263,34.38166826963425,34.38166692852974,34.38166625797748,34.381665252149105,34.38166491687298,34.381664246320724,34.381664246320724,34.38166357576847,34.38166357576847,34.381663240492344,34.381663240492344,34.381663240492344,34.38166290521622,34.38166256994008,34.38166189938784,34.38165921717882,34.38165687024593,34.38165418803692,34.38165049999952,34.38164681196213,34.38164245337248,34.38163742423057,34.38163172453642,34.38162501901388,34.38161797821522,34.38161060214043,34.38160389661789,34.38159652054309,34.38159015029669,34.38158344477416,34.38157640397549,34.38156936317682,34.381561651825905,34.38155394047499,34.38154522329569,34.381537176668644,34.3815291300416,34.38152175396681,34.38151504844427,34.38150331377983,34.38149895519018,34.38149560242891,34.38149157911539,34.38148755580187,34.3814842030406,34.38148185610771,34.38147984445095,34.38147883862257,34.38147783279419,34.381478168070316\",\n \"Speed\": 0.13,\n \"Status\": 0,\n \"TotalHectaresTilled\": null,\n \"TractorID\": 502143,\n \"TractorModelID\": 46,\n \"TractorName\": \"KTCB_568X\",\n \"license_plate_number\": \"KTCB 568X\",\n \"UpdatedAt\": \"2019-10-30 15:40:14\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"LastGeofenceNotificationTime\": \"\",\n \"WasInArea\": true,\n \"Currency\": null,\n \"_acl\": {\n \"creator\": \"5d5ff918ecc87c44b9752888\"\n },\n \"_kmd\": {\n \"lmt\": \"2019-10-10T03:12:21.465Z\",\n \"ect\": \"2019-10-10T03:12:21.465Z\"\n },\n \"EngineHours\": 40,\n \"TotalDistanceCovered\": 188,\n \"UtcOffset\": 0,\n \"ActiveTimeToday\": 0,\n \"PositionLatitude\": -0.821496,\n \"PositionLongitude\": 34.381559,\n \"LastActiveTime\": \"2019-10-30 12:21:30\",\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"Heading\": 229,\n \"FuelLevelVoltage\": 0,\n \"Street\": \"Otange\",\n \"Town\": \"Homa Bay\",\n \"Country\": \"Kenya\",\n \"PrevTempFuelData\": [\n {\n \"FuelLitres\": 16,\n \"FuelVolume\": 25,\n \"FuelRawValue\": 6444,\n \"LastActiveTime\": \"2019-10-14 13:14:03\"\n }\n ],\n \"FuelVolume\": 24,\n \"FuelLitres\": 16,\n \"LastMaintenanceNotificationEngineHours\": 24\n },\n \"502144\": {\n \"_id\": \"5d9e2d5c0a08663e8d100ecc\",\n \"ActiveTimeToday\": 0,\n \"BookingRequests\": true,\n \"Characteristic\": \"102\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": false,\n \"Efficiency\": 0,\n \"EngineHours\": 11,\n \"FixedEngineHours\": 645,\n \"FixedOdometerReading\": 0,\n \"FuelLitres\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"RentCo\",\n \"Heading\": 0,\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214272039776164,-0.8214298859109773,-0.8214329030860226,-0.8214352497777118,-0.8214379317110727,-0.8214406136444335,-0.8214432955777945,-0.8214453070278247,-0.8214473184778421,-0.8214500004111903,-0.8214513413778771,-0.8214533528278946,-0.8214556995195711,-0.8214577109695885,-0.8214603929029367,-0.8214627395946259,-0.8214654215279613,-0.8214681034613095,-0.8214707853946577,-0.8214734673279931,-0.8214761492613285,-0.8214795016780074,-0.8214821836113428,-0.8214855360280089,-0.8214885532030034,-0.8214915703779978,-0.8214942523113204,-0.821497269486315,-0.8215009571446273,-0.8215043095612807,-0.8215076619779341,-0.8215110143945747,-0.8215140315695565,-0.8215170487445381,-0.8215204011611661,-0.8215230830944761,-0.8215261002694451,-0.821529117444414,-0.821532134619383,-0.8215351517943393,-0.8215381689692955,-0.8215408509025928,-0.8215442033192081,-0.8215462147691873,-0.8215488967024719,-0.8215512433940975,-0.821553254844064,-0.8215549310523717,-0.8215562720190076,-0.8215576129856562,-0.8215586187106332,-0.8215596244356101,-0.8215606301605998,-0.8215623063688947,-0.8215633120938716,-0.8215643178188613,-0.8215653235438382,-0.8215666645104741,-0.8215669997521331,-0.8215680054771101,-0.821568340718769,-0.8215696816854177,-0.8215703521687356,-0.8215713578937125,-0.8215720283770305,-0.8215726988603484,-0.8215733693436664,-0.8215737045853254,-0.8215737045853254,-0.8215740398269844,-0.8215743750686434,-0.8215750455519614,-0.8215753807936202,-0.8215757160352792,-0.8215763865185972,-0.8215770570019152,-0.8215777274852332,-0.8215783979685511,-0.821579068451869,-0.821579068451869,-0.821579068451869,-0.8215797389351743,-0.8215797389351743,-0.821580074176846,-0.8215797389351743,-0.821580074176846,-0.8215804094184922,-0.821580744660164,-0.8215810799018102,-0.8215814151434692,-0.8215820856267871,-0.8215820856267871,-0.8215824208684461,-0.8215827561101051,-0.8215830913517641,-0.8215830913517641,-0.8215834265934231,-0.8215834265934231,-0.8215840970767411,-0.8215837618350821,-0.8215837618350821,-0.8215837618350821,-0.8215834265934231,-0.8215830913517641,-0.8215827561101051,-0.8215824208684461,-0.8215820856267871,-0.8215814151434692,-0.8215810799018102,-0.8215797389351743,-0.821579068451869,-0.821579068451869,-0.8215780627268922,-0.8215777274852332,-0.8215770570019152,-0.8215767217602562,-0.8215763865185972,-0.8215760512769382,-0.8215757160352792,-0.8215757160352792,-0.8215750455519614,-0.8215747103103024,-0.8215743750686434,-0.8215737045853254,-0.8215733693436664,-0.8215723636186895,-0.8215713578937125,-0.8215700169270767,-0.821568340718769,-0.8215663292688151,-0.8215646530605075,-0.8215623063688947,-0.8215592891939512,-0.8215566072606666,-0.8215529196024051,-0.8215492319441309,-0.8215455442858567,-0.8215411861442518,-0.8215381689692955,-0.8215341460693496,-0.8215304584110626,-0.821526770752763,-0.8215224126111454,-0.8215190601945175,-0.8215150372945461,-0.8215110143945747,-0.8215069914946034,-0.821502968594632,-0.8214996161779786,-0.8214962637613252,-0.8214922408613284,-0.8214885532030034,-0.8214841950613349,-0.8214798369196663,-0.8214751435363261,-0.8214704501529859,-0.8214654215279613,-0.821460057661265,-0.8214546937945687,-0.8214489946861879,-0.8214443013028095,-0.8214392726777595,-0.8214352497777118,-0.8214315621193358,-0.8214285449442905,-0.8214261982525886,-0.8214245220442301,-0.8214235163192277,-0.821423181077556,-0.821423181077556,-0.821423181077556,-0.8214228458358716,-0.8214228458358716,-0.8214225105941999,-0.8214225105941999,-0.8214221753525281,-0.8214218401108565,-0.8214211696275131,-0.8214211696275131,-0.8214211696275131,-0.8214204991441697,-0.8214204991441697,-0.8214198286608263,-0.8214191581774829,-0.8214191581774829,-0.8214191581774829,-0.8214184876941395,-0.8214184876941395,-0.8214184876941395,-0.8214191581774829,-0.8214194934191545,-0.8214198286608263,-0.8214204991441697,-0.8214215048691847,-0.8214221753525281,-0.8214225105941999,-0.8214225105941999,-0.8214228458358716,-0.8214228458358716,-0.8214228458358716,-0.821423181077556,-0.821423181077556,-0.8214235163192277,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994\",\n \"Longitude\": \"34.38148085027933,34.38148085027933,34.38148085027933,34.38148085027933,34.38148085027933,34.381479509174824,34.38147883862257,34.38147749751806,34.38147682696581,34.381476156413555,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.381476156413555,34.381476491689675,34.38147682696581,34.38147749751806,34.38147749751806,34.381478168070316,34.381478168070316,34.38147883862257,34.381479509174824,34.38147984445095,34.381480515003204,34.38148085027933,34.381481520831585,34.38148219138384,34.38148219138384,34.381482526659966,34.38148319721222,34.38148319721222,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148319721222,34.38148286193609,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148185610771,34.38148185610771,34.381481520831585,34.381481520831585,34.38148118555546,34.38148118555546,34.38148085027933,34.38148085027933,34.38148085027933,34.381480515003204,34.38148017972707,34.38148017972707,34.38147984445095,34.38147984445095,34.38147984445095,34.38147984445095,34.38147984445095,34.38148085027933,34.38148085027933,34.38148185610771,34.38148319721222,34.38148487359285,34.38148822635412,34.38149090856313,34.381494261324406,34.381497614085674,34.38150096684694,34.381504990160465,34.38150901347398,34.38151236623526,34.381516724824905,34.38152108341455,34.381526447832584,34.38153114169836,34.38153650611639,34.38154220581055,34.3815479055047,34.38155360519886,34.381559640169144,34.3815653398633,34.38157103955746,34.381576739251614,34.38158243894577,34.38158880919218,34.38159517943859,34.38160087913275,34.381606578826904,34.381612278521054,34.381617307662964,34.381622672080994,34.38162703067064,34.38163138926029,34.381635412573814,34.38163876533508,34.381642788648605,34.381646141409874,34.38164949417114,34.38165284693241,34.38165552914142,34.381657876074314,34.381659887731075,34.38166122883558,34.38166290521622,34.38166458159685,34.38166558742523,34.38166692852974,34.381667599081986,34.381668604910374,34.38166927546263,34.38166994601488,34.38167028129101,34.38167095184326,34.381671622395515,34.38167229294777,34.38167296350002,34.38167329877616,34.38167363405228,34.3816739693284,34.3816739693284,34.38167430460453,34.38167430460453,34.381674639880664,34.381674975156784,34.381674975156784,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.381674975156784,34.381674975156784,34.38167430460453,34.38167430460453,34.3816739693284,34.3816739693284,34.38167363405228,34.38167296350002,34.381672628223896,34.38167195767164,34.381671622395515,34.38167028129101,34.38166927546263,34.38166826963425,34.38166692852974,34.38166625797748,34.381665252149105,34.38166491687298,34.381664246320724,34.381664246320724,34.38166357576847,34.38166357576847,34.381663240492344,34.381663240492344,34.381663240492344,34.38166290521622,34.38166256994008,34.38166189938784,34.38165921717882,34.38165687024593,34.38165418803692,34.38165049999952,34.38164681196213,34.38164245337248,34.38163742423057,34.38163172453642,34.38162501901388,34.38161797821522,34.38161060214043,34.38160389661789,34.38159652054309,34.38159015029669,34.38158344477416,34.38157640397549,34.38156936317682,34.381561651825905,34.38155394047499,34.38154522329569,34.381537176668644,34.3815291300416,34.38152175396681,34.38151504844427,34.38150331377983,34.38149895519018,34.38149560242891,34.38149157911539,34.38148755580187,34.3814842030406,34.38148185610771,34.38147984445095,34.38147883862257,34.38147783279419,34.381478168070316\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": -0.821522,\n \"PositionLongitude\": 34.381578,\n \"Speed\": 0,\n \"Status\": 0,\n \"TotalDistanceCovered\": 73,\n \"TotalHectaresTilled\": null,\n \"TractorID\": 502144,\n \"TractorModelID\": 46,\n \"TractorName\": \"KTCB_479X\",\n \"UpdatedAt\": \"2019-10-30 15:55:58\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"_acl\": {\n \"creator\": \"5d5ff918ecc87c44b9752888\"\n },\n \"license_plate_number\": \"KTCB 479X\",\n \"_kmd\": {\n \"lmt\": \"2019-10-09T18:56:50.963Z\",\n \"ect\": \"2019-10-09T18:56:28.124Z\"\n },\n \"LastActiveTime\": \"2019-10-30 08:52:25\",\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"FuelLevelVoltage\": 0,\n \"Street\": \"Otange\",\n \"Town\": \"Homa Bay\",\n \"Country\": \"Kenya\"\n },\n \"502145\": {\n \"_id\": \"5d9ea4abeba6c6630a29dc10\",\n \"ActiveTimeToday\": 0,\n \"BookingRequests\": true,\n \"Characteristic\": \"102\",\n \"Country\": \"Kenya\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": false,\n \"Efficiency\": 0,\n \"EngineHours\": 96,\n \"FixedEngineHours\": 768,\n \"FixedOdometerReading\": 0,\n \"FuelLitres\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"RentCo\",\n \"Heading\": 305,\n \"LastActiveTime\": \"2019-10-30 12:25:11\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214272039776164,-0.8214298859109773,-0.8214329030860226,-0.8214352497777118,-0.8214379317110727,-0.8214406136444335,-0.8214432955777945,-0.8214453070278247,-0.8214473184778421,-0.8214500004111903,-0.8214513413778771,-0.8214533528278946,-0.8214556995195711,-0.8214577109695885,-0.8214603929029367,-0.8214627395946259,-0.8214654215279613,-0.8214681034613095,-0.8214707853946577,-0.8214734673279931,-0.8214761492613285,-0.8214795016780074,-0.8214821836113428,-0.8214855360280089,-0.8214885532030034,-0.8214915703779978,-0.8214942523113204,-0.821497269486315,-0.8215009571446273,-0.8215043095612807,-0.8215076619779341,-0.8215110143945747,-0.8215140315695565,-0.8215170487445381,-0.8215204011611661,-0.8215230830944761,-0.8215261002694451,-0.821529117444414,-0.821532134619383,-0.8215351517943393,-0.8215381689692955,-0.8215408509025928,-0.8215442033192081,-0.8215462147691873,-0.8215488967024719,-0.8215512433940975,-0.821553254844064,-0.8215549310523717,-0.8215562720190076,-0.8215576129856562,-0.8215586187106332,-0.8215596244356101,-0.8215606301605998,-0.8215623063688947,-0.8215633120938716,-0.8215643178188613,-0.8215653235438382,-0.8215666645104741,-0.8215669997521331,-0.8215680054771101,-0.821568340718769,-0.8215696816854177,-0.8215703521687356,-0.8215713578937125,-0.8215720283770305,-0.8215726988603484,-0.8215733693436664,-0.8215737045853254,-0.8215737045853254,-0.8215740398269844,-0.8215743750686434,-0.8215750455519614,-0.8215753807936202,-0.8215757160352792,-0.8215763865185972,-0.8215770570019152,-0.8215777274852332,-0.8215783979685511,-0.821579068451869,-0.821579068451869,-0.821579068451869,-0.8215797389351743,-0.8215797389351743,-0.821580074176846,-0.8215797389351743,-0.821580074176846,-0.8215804094184922,-0.821580744660164,-0.8215810799018102,-0.8215814151434692,-0.8215820856267871,-0.8215820856267871,-0.8215824208684461,-0.8215827561101051,-0.8215830913517641,-0.8215830913517641,-0.8215834265934231,-0.8215834265934231,-0.8215840970767411,-0.8215837618350821,-0.8215837618350821,-0.8215837618350821,-0.8215834265934231,-0.8215830913517641,-0.8215827561101051,-0.8215824208684461,-0.8215820856267871,-0.8215814151434692,-0.8215810799018102,-0.8215797389351743,-0.821579068451869,-0.821579068451869,-0.8215780627268922,-0.8215777274852332,-0.8215770570019152,-0.8215767217602562,-0.8215763865185972,-0.8215760512769382,-0.8215757160352792,-0.8215757160352792,-0.8215750455519614,-0.8215747103103024,-0.8215743750686434,-0.8215737045853254,-0.8215733693436664,-0.8215723636186895,-0.8215713578937125,-0.8215700169270767,-0.821568340718769,-0.8215663292688151,-0.8215646530605075,-0.8215623063688947,-0.8215592891939512,-0.8215566072606666,-0.8215529196024051,-0.8215492319441309,-0.8215455442858567,-0.8215411861442518,-0.8215381689692955,-0.8215341460693496,-0.8215304584110626,-0.821526770752763,-0.8215224126111454,-0.8215190601945175,-0.8215150372945461,-0.8215110143945747,-0.8215069914946034,-0.821502968594632,-0.8214996161779786,-0.8214962637613252,-0.8214922408613284,-0.8214885532030034,-0.8214841950613349,-0.8214798369196663,-0.8214751435363261,-0.8214704501529859,-0.8214654215279613,-0.821460057661265,-0.8214546937945687,-0.8214489946861879,-0.8214443013028095,-0.8214392726777595,-0.8214352497777118,-0.8214315621193358,-0.8214285449442905,-0.8214261982525886,-0.8214245220442301,-0.8214235163192277,-0.821423181077556,-0.821423181077556,-0.821423181077556,-0.8214228458358716,-0.8214228458358716,-0.8214225105941999,-0.8214225105941999,-0.8214221753525281,-0.8214218401108565,-0.8214211696275131,-0.8214211696275131,-0.8214211696275131,-0.8214204991441697,-0.8214204991441697,-0.8214198286608263,-0.8214191581774829,-0.8214191581774829,-0.8214191581774829,-0.8214184876941395,-0.8214184876941395,-0.8214184876941395,-0.8214191581774829,-0.8214194934191545,-0.8214198286608263,-0.8214204991441697,-0.8214215048691847,-0.8214221753525281,-0.8214225105941999,-0.8214225105941999,-0.8214228458358716,-0.8214228458358716,-0.8214228458358716,-0.821423181077556,-0.821423181077556,-0.8214235163192277,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994\",\n \"Longitude\": \"34.38148085027933,34.38148085027933,34.38148085027933,34.38148085027933,34.38148085027933,34.381479509174824,34.38147883862257,34.38147749751806,34.38147682696581,34.381476156413555,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.381476156413555,34.381476491689675,34.38147682696581,34.38147749751806,34.38147749751806,34.381478168070316,34.381478168070316,34.38147883862257,34.381479509174824,34.38147984445095,34.381480515003204,34.38148085027933,34.381481520831585,34.38148219138384,34.38148219138384,34.381482526659966,34.38148319721222,34.38148319721222,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148319721222,34.38148286193609,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148185610771,34.38148185610771,34.381481520831585,34.381481520831585,34.38148118555546,34.38148118555546,34.38148085027933,34.38148085027933,34.38148085027933,34.381480515003204,34.38148017972707,34.38148017972707,34.38147984445095,34.38147984445095,34.38147984445095,34.38147984445095,34.38147984445095,34.38148085027933,34.38148085027933,34.38148185610771,34.38148319721222,34.38148487359285,34.38148822635412,34.38149090856313,34.381494261324406,34.381497614085674,34.38150096684694,34.381504990160465,34.38150901347398,34.38151236623526,34.381516724824905,34.38152108341455,34.381526447832584,34.38153114169836,34.38153650611639,34.38154220581055,34.3815479055047,34.38155360519886,34.381559640169144,34.3815653398633,34.38157103955746,34.381576739251614,34.38158243894577,34.38158880919218,34.38159517943859,34.38160087913275,34.381606578826904,34.381612278521054,34.381617307662964,34.381622672080994,34.38162703067064,34.38163138926029,34.381635412573814,34.38163876533508,34.381642788648605,34.381646141409874,34.38164949417114,34.38165284693241,34.38165552914142,34.381657876074314,34.381659887731075,34.38166122883558,34.38166290521622,34.38166458159685,34.38166558742523,34.38166692852974,34.381667599081986,34.381668604910374,34.38166927546263,34.38166994601488,34.38167028129101,34.38167095184326,34.381671622395515,34.38167229294777,34.38167296350002,34.38167329877616,34.38167363405228,34.3816739693284,34.3816739693284,34.38167430460453,34.38167430460453,34.381674639880664,34.381674975156784,34.381674975156784,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.381674975156784,34.381674975156784,34.38167430460453,34.38167430460453,34.3816739693284,34.3816739693284,34.38167363405228,34.38167296350002,34.381672628223896,34.38167195767164,34.381671622395515,34.38167028129101,34.38166927546263,34.38166826963425,34.38166692852974,34.38166625797748,34.381665252149105,34.38166491687298,34.381664246320724,34.381664246320724,34.38166357576847,34.38166357576847,34.381663240492344,34.381663240492344,34.381663240492344,34.38166290521622,34.38166256994008,34.38166189938784,34.38165921717882,34.38165687024593,34.38165418803692,34.38165049999952,34.38164681196213,34.38164245337248,34.38163742423057,34.38163172453642,34.38162501901388,34.38161797821522,34.38161060214043,34.38160389661789,34.38159652054309,34.38159015029669,34.38158344477416,34.38157640397549,34.38156936317682,34.381561651825905,34.38155394047499,34.38154522329569,34.381537176668644,34.3815291300416,34.38152175396681,34.38151504844427,34.38150331377983,34.38149895519018,34.38149560242891,34.38149157911539,34.38148755580187,34.3814842030406,34.38148185610771,34.38147984445095,34.38147883862257,34.38147783279419,34.381478168070316\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": -0.821506,\n \"PositionLongitude\": 34.381549,\n \"Speed\": 0,\n \"Status\": 0,\n \"Street\": \"Otange\",\n \"TotalDistanceCovered\": 527,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Homa Bay\",\n \"TractorID\": 502145,\n \"TractorModelID\": 46,\n \"TractorName\": \"KTCB_472X\",\n \"UpdatedAt\": \"2019-10-30 15:40:20\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"_acl\": {\n \"creator\": \"5d5ff918ecc87c44b9752888\"\n },\n \"license_plate_number\": \"KTCB 472X\",\n \"_kmd\": {\n \"lmt\": \"2019-10-16T08:35:00.324Z\",\n \"ect\": \"2019-10-10T03:25:31.468Z\"\n },\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"FuelLevelVoltage\": 0\n },\n \"502146\": {\n \"_id\": \"5d9eaa5866e707056ab6ea8e\",\n \"BookingRequests\": true,\n \"Characteristic\": \"102\",\n \"FixedEngineHours\": 958,\n \"FixedOdometerReading\": 0,\n \"Group\": \"RentCo\",\n \"Latitude\": \"-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214272039776164,-0.8214298859109773,-0.8214329030860226,-0.8214352497777118,-0.8214379317110727,-0.8214406136444335,-0.8214432955777945,-0.8214453070278247,-0.8214473184778421,-0.8214500004111903,-0.8214513413778771,-0.8214533528278946,-0.8214556995195711,-0.8214577109695885,-0.8214603929029367,-0.8214627395946259,-0.8214654215279613,-0.8214681034613095,-0.8214707853946577,-0.8214734673279931,-0.8214761492613285,-0.8214795016780074,-0.8214821836113428,-0.8214855360280089,-0.8214885532030034,-0.8214915703779978,-0.8214942523113204,-0.821497269486315,-0.8215009571446273,-0.8215043095612807,-0.8215076619779341,-0.8215110143945747,-0.8215140315695565,-0.8215170487445381,-0.8215204011611661,-0.8215230830944761,-0.8215261002694451,-0.821529117444414,-0.821532134619383,-0.8215351517943393,-0.8215381689692955,-0.8215408509025928,-0.8215442033192081,-0.8215462147691873,-0.8215488967024719,-0.8215512433940975,-0.821553254844064,-0.8215549310523717,-0.8215562720190076,-0.8215576129856562,-0.8215586187106332,-0.8215596244356101,-0.8215606301605998,-0.8215623063688947,-0.8215633120938716,-0.8215643178188613,-0.8215653235438382,-0.8215666645104741,-0.8215669997521331,-0.8215680054771101,-0.821568340718769,-0.8215696816854177,-0.8215703521687356,-0.8215713578937125,-0.8215720283770305,-0.8215726988603484,-0.8215733693436664,-0.8215737045853254,-0.8215737045853254,-0.8215740398269844,-0.8215743750686434,-0.8215750455519614,-0.8215753807936202,-0.8215757160352792,-0.8215763865185972,-0.8215770570019152,-0.8215777274852332,-0.8215783979685511,-0.821579068451869,-0.821579068451869,-0.821579068451869,-0.8215797389351743,-0.8215797389351743,-0.821580074176846,-0.8215797389351743,-0.821580074176846,-0.8215804094184922,-0.821580744660164,-0.8215810799018102,-0.8215814151434692,-0.8215820856267871,-0.8215820856267871,-0.8215824208684461,-0.8215827561101051,-0.8215830913517641,-0.8215830913517641,-0.8215834265934231,-0.8215834265934231,-0.8215840970767411,-0.8215837618350821,-0.8215837618350821,-0.8215837618350821,-0.8215834265934231,-0.8215830913517641,-0.8215827561101051,-0.8215824208684461,-0.8215820856267871,-0.8215814151434692,-0.8215810799018102,-0.8215797389351743,-0.821579068451869,-0.821579068451869,-0.8215780627268922,-0.8215777274852332,-0.8215770570019152,-0.8215767217602562,-0.8215763865185972,-0.8215760512769382,-0.8215757160352792,-0.8215757160352792,-0.8215750455519614,-0.8215747103103024,-0.8215743750686434,-0.8215737045853254,-0.8215733693436664,-0.8215723636186895,-0.8215713578937125,-0.8215700169270767,-0.821568340718769,-0.8215663292688151,-0.8215646530605075,-0.8215623063688947,-0.8215592891939512,-0.8215566072606666,-0.8215529196024051,-0.8215492319441309,-0.8215455442858567,-0.8215411861442518,-0.8215381689692955,-0.8215341460693496,-0.8215304584110626,-0.821526770752763,-0.8215224126111454,-0.8215190601945175,-0.8215150372945461,-0.8215110143945747,-0.8215069914946034,-0.821502968594632,-0.8214996161779786,-0.8214962637613252,-0.8214922408613284,-0.8214885532030034,-0.8214841950613349,-0.8214798369196663,-0.8214751435363261,-0.8214704501529859,-0.8214654215279613,-0.821460057661265,-0.8214546937945687,-0.8214489946861879,-0.8214443013028095,-0.8214392726777595,-0.8214352497777118,-0.8214315621193358,-0.8214285449442905,-0.8214261982525886,-0.8214245220442301,-0.8214235163192277,-0.821423181077556,-0.821423181077556,-0.821423181077556,-0.8214228458358716,-0.8214228458358716,-0.8214225105941999,-0.8214225105941999,-0.8214221753525281,-0.8214218401108565,-0.8214211696275131,-0.8214211696275131,-0.8214211696275131,-0.8214204991441697,-0.8214204991441697,-0.8214198286608263,-0.8214191581774829,-0.8214191581774829,-0.8214191581774829,-0.8214184876941395,-0.8214184876941395,-0.8214184876941395,-0.8214191581774829,-0.8214194934191545,-0.8214198286608263,-0.8214204991441697,-0.8214215048691847,-0.8214221753525281,-0.8214225105941999,-0.8214225105941999,-0.8214228458358716,-0.8214228458358716,-0.8214228458358716,-0.821423181077556,-0.821423181077556,-0.8214235163192277,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994\",\n \"Longitude\": \"34.38148085027933,34.38148085027933,34.38148085027933,34.38148085027933,34.38148085027933,34.381479509174824,34.38147883862257,34.38147749751806,34.38147682696581,34.381476156413555,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.381476156413555,34.381476491689675,34.38147682696581,34.38147749751806,34.38147749751806,34.381478168070316,34.381478168070316,34.38147883862257,34.381479509174824,34.38147984445095,34.381480515003204,34.38148085027933,34.381481520831585,34.38148219138384,34.38148219138384,34.381482526659966,34.38148319721222,34.38148319721222,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148319721222,34.38148286193609,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148185610771,34.38148185610771,34.381481520831585,34.381481520831585,34.38148118555546,34.38148118555546,34.38148085027933,34.38148085027933,34.38148085027933,34.381480515003204,34.38148017972707,34.38148017972707,34.38147984445095,34.38147984445095,34.38147984445095,34.38147984445095,34.38147984445095,34.38148085027933,34.38148085027933,34.38148185610771,34.38148319721222,34.38148487359285,34.38148822635412,34.38149090856313,34.381494261324406,34.381497614085674,34.38150096684694,34.381504990160465,34.38150901347398,34.38151236623526,34.381516724824905,34.38152108341455,34.381526447832584,34.38153114169836,34.38153650611639,34.38154220581055,34.3815479055047,34.38155360519886,34.381559640169144,34.3815653398633,34.38157103955746,34.381576739251614,34.38158243894577,34.38158880919218,34.38159517943859,34.38160087913275,34.381606578826904,34.381612278521054,34.381617307662964,34.381622672080994,34.38162703067064,34.38163138926029,34.381635412573814,34.38163876533508,34.381642788648605,34.381646141409874,34.38164949417114,34.38165284693241,34.38165552914142,34.381657876074314,34.381659887731075,34.38166122883558,34.38166290521622,34.38166458159685,34.38166558742523,34.38166692852974,34.381667599081986,34.381668604910374,34.38166927546263,34.38166994601488,34.38167028129101,34.38167095184326,34.381671622395515,34.38167229294777,34.38167296350002,34.38167329877616,34.38167363405228,34.3816739693284,34.3816739693284,34.38167430460453,34.38167430460453,34.381674639880664,34.381674975156784,34.381674975156784,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.381674975156784,34.381674975156784,34.38167430460453,34.38167430460453,34.3816739693284,34.3816739693284,34.38167363405228,34.38167296350002,34.381672628223896,34.38167195767164,34.381671622395515,34.38167028129101,34.38166927546263,34.38166826963425,34.38166692852974,34.38166625797748,34.381665252149105,34.38166491687298,34.381664246320724,34.381664246320724,34.38166357576847,34.38166357576847,34.381663240492344,34.381663240492344,34.381663240492344,34.38166290521622,34.38166256994008,34.38166189938784,34.38165921717882,34.38165687024593,34.38165418803692,34.38165049999952,34.38164681196213,34.38164245337248,34.38163742423057,34.38163172453642,34.38162501901388,34.38161797821522,34.38161060214043,34.38160389661789,34.38159652054309,34.38159015029669,34.38158344477416,34.38157640397549,34.38156936317682,34.381561651825905,34.38155394047499,34.38154522329569,34.381537176668644,34.3815291300416,34.38152175396681,34.38151504844427,34.38150331377983,34.38149895519018,34.38149560242891,34.38149157911539,34.38148755580187,34.3814842030406,34.38148185610771,34.38147984445095,34.38147883862257,34.38147783279419,34.381478168070316\",\n \"Speed\": 0,\n \"Status\": 0,\n \"TotalHectaresTilled\": null,\n \"TractorID\": 502146,\n \"TractorModelID\": 46,\n \"TractorName\": \"KTCB_474X\",\n \"license_plate_number\": \"KTCB_474X\",\n \"UpdatedAt\": \"2019-10-30 15:40:25\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"LastGeofenceNotificationTime\": \"\",\n \"WasInArea\": true,\n \"Currency\": null,\n \"_acl\": {\n \"creator\": \"5d5ff918ecc87c44b9752888\"\n },\n \"_kmd\": {\n \"lmt\": \"2019-10-10T03:49:44.820Z\",\n \"ect\": \"2019-10-10T03:49:44.820Z\"\n },\n \"EngineHours\": 172,\n \"TotalDistanceCovered\": 750,\n \"UtcOffset\": 0,\n \"ActiveTimeToday\": 0,\n \"PositionLatitude\": -0.82155,\n \"PositionLongitude\": 34.381647,\n \"LastActiveTime\": \"2019-10-30 09:50:03\",\n \"FuelRawValue\": 30,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"Heading\": 0,\n \"FuelLevelVoltage\": 0,\n \"Street\": \"Otange\",\n \"Town\": \"Homa Bay\",\n \"Country\": \"Kenya\",\n \"PrevTempFuelData\": [\n {\n \"FuelLitres\": 21,\n \"FuelVolume\": 33,\n \"FuelRawValue\": 6110,\n \"LastActiveTime\": \"2019-10-14 13:13:58\"\n },\n {\n \"FuelLitres\": 21,\n \"FuelVolume\": 33,\n \"FuelRawValue\": 6110,\n \"LastActiveTime\": \"2019-10-14 13:16:58\"\n }\n ],\n \"FuelVolume\": 36,\n \"FuelLitres\": 23\n },\n \"502147\": {\n \"_id\": \"5d9ea90381f5052a1072db99\",\n \"ActiveTimeToday\": 0,\n \"BookingRequests\": true,\n \"Characteristic\": \"102\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": false,\n \"Efficiency\": 0,\n \"EngineHours\": 181,\n \"FixedEngineHours\": 767,\n \"FixedOdometerReading\": 0,\n \"FuelLitres\": 28,\n \"FuelVolume\": 43,\n \"Group\": \"RentCo\",\n \"Heading\": 0,\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214272039776164,-0.8214298859109773,-0.8214329030860226,-0.8214352497777118,-0.8214379317110727,-0.8214406136444335,-0.8214432955777945,-0.8214453070278247,-0.8214473184778421,-0.8214500004111903,-0.8214513413778771,-0.8214533528278946,-0.8214556995195711,-0.8214577109695885,-0.8214603929029367,-0.8214627395946259,-0.8214654215279613,-0.8214681034613095,-0.8214707853946577,-0.8214734673279931,-0.8214761492613285,-0.8214795016780074,-0.8214821836113428,-0.8214855360280089,-0.8214885532030034,-0.8214915703779978,-0.8214942523113204,-0.821497269486315,-0.8215009571446273,-0.8215043095612807,-0.8215076619779341,-0.8215110143945747,-0.8215140315695565,-0.8215170487445381,-0.8215204011611661,-0.8215230830944761,-0.8215261002694451,-0.821529117444414,-0.821532134619383,-0.8215351517943393,-0.8215381689692955,-0.8215408509025928,-0.8215442033192081,-0.8215462147691873,-0.8215488967024719,-0.8215512433940975,-0.821553254844064,-0.8215549310523717,-0.8215562720190076,-0.8215576129856562,-0.8215586187106332,-0.8215596244356101,-0.8215606301605998,-0.8215623063688947,-0.8215633120938716,-0.8215643178188613,-0.8215653235438382,-0.8215666645104741,-0.8215669997521331,-0.8215680054771101,-0.821568340718769,-0.8215696816854177,-0.8215703521687356,-0.8215713578937125,-0.8215720283770305,-0.8215726988603484,-0.8215733693436664,-0.8215737045853254,-0.8215737045853254,-0.8215740398269844,-0.8215743750686434,-0.8215750455519614,-0.8215753807936202,-0.8215757160352792,-0.8215763865185972,-0.8215770570019152,-0.8215777274852332,-0.8215783979685511,-0.821579068451869,-0.821579068451869,-0.821579068451869,-0.8215797389351743,-0.8215797389351743,-0.821580074176846,-0.8215797389351743,-0.821580074176846,-0.8215804094184922,-0.821580744660164,-0.8215810799018102,-0.8215814151434692,-0.8215820856267871,-0.8215820856267871,-0.8215824208684461,-0.8215827561101051,-0.8215830913517641,-0.8215830913517641,-0.8215834265934231,-0.8215834265934231,-0.8215840970767411,-0.8215837618350821,-0.8215837618350821,-0.8215837618350821,-0.8215834265934231,-0.8215830913517641,-0.8215827561101051,-0.8215824208684461,-0.8215820856267871,-0.8215814151434692,-0.8215810799018102,-0.8215797389351743,-0.821579068451869,-0.821579068451869,-0.8215780627268922,-0.8215777274852332,-0.8215770570019152,-0.8215767217602562,-0.8215763865185972,-0.8215760512769382,-0.8215757160352792,-0.8215757160352792,-0.8215750455519614,-0.8215747103103024,-0.8215743750686434,-0.8215737045853254,-0.8215733693436664,-0.8215723636186895,-0.8215713578937125,-0.8215700169270767,-0.821568340718769,-0.8215663292688151,-0.8215646530605075,-0.8215623063688947,-0.8215592891939512,-0.8215566072606666,-0.8215529196024051,-0.8215492319441309,-0.8215455442858567,-0.8215411861442518,-0.8215381689692955,-0.8215341460693496,-0.8215304584110626,-0.821526770752763,-0.8215224126111454,-0.8215190601945175,-0.8215150372945461,-0.8215110143945747,-0.8215069914946034,-0.821502968594632,-0.8214996161779786,-0.8214962637613252,-0.8214922408613284,-0.8214885532030034,-0.8214841950613349,-0.8214798369196663,-0.8214751435363261,-0.8214704501529859,-0.8214654215279613,-0.821460057661265,-0.8214546937945687,-0.8214489946861879,-0.8214443013028095,-0.8214392726777595,-0.8214352497777118,-0.8214315621193358,-0.8214285449442905,-0.8214261982525886,-0.8214245220442301,-0.8214235163192277,-0.821423181077556,-0.821423181077556,-0.821423181077556,-0.8214228458358716,-0.8214228458358716,-0.8214225105941999,-0.8214225105941999,-0.8214221753525281,-0.8214218401108565,-0.8214211696275131,-0.8214211696275131,-0.8214211696275131,-0.8214204991441697,-0.8214204991441697,-0.8214198286608263,-0.8214191581774829,-0.8214191581774829,-0.8214191581774829,-0.8214184876941395,-0.8214184876941395,-0.8214184876941395,-0.8214191581774829,-0.8214194934191545,-0.8214198286608263,-0.8214204991441697,-0.8214215048691847,-0.8214221753525281,-0.8214225105941999,-0.8214225105941999,-0.8214228458358716,-0.8214228458358716,-0.8214228458358716,-0.821423181077556,-0.821423181077556,-0.8214235163192277,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994\",\n \"Longitude\": \"34.38148085027933,34.38148085027933,34.38148085027933,34.38148085027933,34.38148085027933,34.381479509174824,34.38147883862257,34.38147749751806,34.38147682696581,34.381476156413555,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.381476156413555,34.381476491689675,34.38147682696581,34.38147749751806,34.38147749751806,34.381478168070316,34.381478168070316,34.38147883862257,34.381479509174824,34.38147984445095,34.381480515003204,34.38148085027933,34.381481520831585,34.38148219138384,34.38148219138384,34.381482526659966,34.38148319721222,34.38148319721222,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148319721222,34.38148286193609,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148185610771,34.38148185610771,34.381481520831585,34.381481520831585,34.38148118555546,34.38148118555546,34.38148085027933,34.38148085027933,34.38148085027933,34.381480515003204,34.38148017972707,34.38148017972707,34.38147984445095,34.38147984445095,34.38147984445095,34.38147984445095,34.38147984445095,34.38148085027933,34.38148085027933,34.38148185610771,34.38148319721222,34.38148487359285,34.38148822635412,34.38149090856313,34.381494261324406,34.381497614085674,34.38150096684694,34.381504990160465,34.38150901347398,34.38151236623526,34.381516724824905,34.38152108341455,34.381526447832584,34.38153114169836,34.38153650611639,34.38154220581055,34.3815479055047,34.38155360519886,34.381559640169144,34.3815653398633,34.38157103955746,34.381576739251614,34.38158243894577,34.38158880919218,34.38159517943859,34.38160087913275,34.381606578826904,34.381612278521054,34.381617307662964,34.381622672080994,34.38162703067064,34.38163138926029,34.381635412573814,34.38163876533508,34.381642788648605,34.381646141409874,34.38164949417114,34.38165284693241,34.38165552914142,34.381657876074314,34.381659887731075,34.38166122883558,34.38166290521622,34.38166458159685,34.38166558742523,34.38166692852974,34.381667599081986,34.381668604910374,34.38166927546263,34.38166994601488,34.38167028129101,34.38167095184326,34.381671622395515,34.38167229294777,34.38167296350002,34.38167329877616,34.38167363405228,34.3816739693284,34.3816739693284,34.38167430460453,34.38167430460453,34.381674639880664,34.381674975156784,34.381674975156784,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.381674975156784,34.381674975156784,34.38167430460453,34.38167430460453,34.3816739693284,34.3816739693284,34.38167363405228,34.38167296350002,34.381672628223896,34.38167195767164,34.381671622395515,34.38167028129101,34.38166927546263,34.38166826963425,34.38166692852974,34.38166625797748,34.381665252149105,34.38166491687298,34.381664246320724,34.381664246320724,34.38166357576847,34.38166357576847,34.381663240492344,34.381663240492344,34.381663240492344,34.38166290521622,34.38166256994008,34.38166189938784,34.38165921717882,34.38165687024593,34.38165418803692,34.38165049999952,34.38164681196213,34.38164245337248,34.38163742423057,34.38163172453642,34.38162501901388,34.38161797821522,34.38161060214043,34.38160389661789,34.38159652054309,34.38159015029669,34.38158344477416,34.38157640397549,34.38156936317682,34.381561651825905,34.38155394047499,34.38154522329569,34.381537176668644,34.3815291300416,34.38152175396681,34.38151504844427,34.38150331377983,34.38149895519018,34.38149560242891,34.38149157911539,34.38148755580187,34.3814842030406,34.38148185610771,34.38147984445095,34.38147883862257,34.38147783279419,34.381478168070316\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": -0.821469,\n \"PositionLongitude\": 34.381515,\n \"Speed\": 0,\n \"Status\": 0,\n \"TotalDistanceCovered\": 1055,\n \"TotalHectaresTilled\": null,\n \"TractorID\": 502147,\n \"TractorModelID\": 46,\n \"TractorName\": \"KTCB_471X\",\n \"UpdatedAt\": \"2019-10-30 15:47:05\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"_acl\": {\n \"creator\": \"5d5ff918ecc87c44b9752888\"\n },\n \"license_plate_number\": \"KTCB_471X\",\n \"_kmd\": {\n \"lmt\": \"2019-10-10T19:16:04.224Z\",\n \"ect\": \"2019-10-10T03:44:03.451Z\"\n },\n \"LastActiveTime\": \"2019-10-29 15:44:53\",\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"FuelLevelVoltage\": 0,\n \"PrevTempFuelData\": [\n {\n \"FuelLitres\": 26,\n \"FuelVolume\": 40,\n \"FuelRawValue\": 5776,\n \"LastActiveTime\": \"2019-10-14 13:08:33\"\n },\n {\n \"FuelLitres\": 27,\n \"FuelVolume\": 41,\n \"FuelRawValue\": 5745,\n \"LastActiveTime\": \"2019-10-14 13:09:33\"\n }\n ],\n \"Street\": \"Otange\",\n \"Town\": \"Homa Bay\",\n \"Country\": \"Kenya\",\n \"LastWorkingHourNotificationTime\": \"2019-10-18T23:08:00.747Z\"\n },\n \"502148\": {\n \"_id\": \"5da0257984f24176ca44a876\",\n \"ActiveTimeToday\": 0,\n \"BookingRequests\": true,\n \"Characteristic\": \"102\",\n \"Country\": \"Kenya\",\n \"Currency\": \"\",\n \"DailyTractorUpdates\": false,\n \"Efficiency\": 0,\n \"EngineHours\": 135,\n \"FixedEngineHours\": 897,\n \"FixedOdometerReading\": 0,\n \"FuelLitres\": 0,\n \"FuelVolume\": 0,\n \"Group\": \"RentCo\",\n \"Heading\": 0,\n \"LastActiveTime\": \"2019-10-30 12:22:23\",\n \"LastGeofenceNotificationTime\": \"\",\n \"Latitude\": \"-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214272039776164,-0.8214298859109773,-0.8214329030860226,-0.8214352497777118,-0.8214379317110727,-0.8214406136444335,-0.8214432955777945,-0.8214453070278247,-0.8214473184778421,-0.8214500004111903,-0.8214513413778771,-0.8214533528278946,-0.8214556995195711,-0.8214577109695885,-0.8214603929029367,-0.8214627395946259,-0.8214654215279613,-0.8214681034613095,-0.8214707853946577,-0.8214734673279931,-0.8214761492613285,-0.8214795016780074,-0.8214821836113428,-0.8214855360280089,-0.8214885532030034,-0.8214915703779978,-0.8214942523113204,-0.821497269486315,-0.8215009571446273,-0.8215043095612807,-0.8215076619779341,-0.8215110143945747,-0.8215140315695565,-0.8215170487445381,-0.8215204011611661,-0.8215230830944761,-0.8215261002694451,-0.821529117444414,-0.821532134619383,-0.8215351517943393,-0.8215381689692955,-0.8215408509025928,-0.8215442033192081,-0.8215462147691873,-0.8215488967024719,-0.8215512433940975,-0.821553254844064,-0.8215549310523717,-0.8215562720190076,-0.8215576129856562,-0.8215586187106332,-0.8215596244356101,-0.8215606301605998,-0.8215623063688947,-0.8215633120938716,-0.8215643178188613,-0.8215653235438382,-0.8215666645104741,-0.8215669997521331,-0.8215680054771101,-0.821568340718769,-0.8215696816854177,-0.8215703521687356,-0.8215713578937125,-0.8215720283770305,-0.8215726988603484,-0.8215733693436664,-0.8215737045853254,-0.8215737045853254,-0.8215740398269844,-0.8215743750686434,-0.8215750455519614,-0.8215753807936202,-0.8215757160352792,-0.8215763865185972,-0.8215770570019152,-0.8215777274852332,-0.8215783979685511,-0.821579068451869,-0.821579068451869,-0.821579068451869,-0.8215797389351743,-0.8215797389351743,-0.821580074176846,-0.8215797389351743,-0.821580074176846,-0.8215804094184922,-0.821580744660164,-0.8215810799018102,-0.8215814151434692,-0.8215820856267871,-0.8215820856267871,-0.8215824208684461,-0.8215827561101051,-0.8215830913517641,-0.8215830913517641,-0.8215834265934231,-0.8215834265934231,-0.8215840970767411,-0.8215837618350821,-0.8215837618350821,-0.8215837618350821,-0.8215834265934231,-0.8215830913517641,-0.8215827561101051,-0.8215824208684461,-0.8215820856267871,-0.8215814151434692,-0.8215810799018102,-0.8215797389351743,-0.821579068451869,-0.821579068451869,-0.8215780627268922,-0.8215777274852332,-0.8215770570019152,-0.8215767217602562,-0.8215763865185972,-0.8215760512769382,-0.8215757160352792,-0.8215757160352792,-0.8215750455519614,-0.8215747103103024,-0.8215743750686434,-0.8215737045853254,-0.8215733693436664,-0.8215723636186895,-0.8215713578937125,-0.8215700169270767,-0.821568340718769,-0.8215663292688151,-0.8215646530605075,-0.8215623063688947,-0.8215592891939512,-0.8215566072606666,-0.8215529196024051,-0.8215492319441309,-0.8215455442858567,-0.8215411861442518,-0.8215381689692955,-0.8215341460693496,-0.8215304584110626,-0.821526770752763,-0.8215224126111454,-0.8215190601945175,-0.8215150372945461,-0.8215110143945747,-0.8215069914946034,-0.821502968594632,-0.8214996161779786,-0.8214962637613252,-0.8214922408613284,-0.8214885532030034,-0.8214841950613349,-0.8214798369196663,-0.8214751435363261,-0.8214704501529859,-0.8214654215279613,-0.821460057661265,-0.8214546937945687,-0.8214489946861879,-0.8214443013028095,-0.8214392726777595,-0.8214352497777118,-0.8214315621193358,-0.8214285449442905,-0.8214261982525886,-0.8214245220442301,-0.8214235163192277,-0.821423181077556,-0.821423181077556,-0.821423181077556,-0.8214228458358716,-0.8214228458358716,-0.8214225105941999,-0.8214225105941999,-0.8214221753525281,-0.8214218401108565,-0.8214211696275131,-0.8214211696275131,-0.8214211696275131,-0.8214204991441697,-0.8214204991441697,-0.8214198286608263,-0.8214191581774829,-0.8214191581774829,-0.8214191581774829,-0.8214184876941395,-0.8214184876941395,-0.8214184876941395,-0.8214191581774829,-0.8214194934191545,-0.8214198286608263,-0.8214204991441697,-0.8214215048691847,-0.8214221753525281,-0.8214225105941999,-0.8214225105941999,-0.8214228458358716,-0.8214228458358716,-0.8214228458358716,-0.821423181077556,-0.821423181077556,-0.8214235163192277,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994\",\n \"Longitude\": \"34.38148085027933,34.38148085027933,34.38148085027933,34.38148085027933,34.38148085027933,34.381479509174824,34.38147883862257,34.38147749751806,34.38147682696581,34.381476156413555,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.381476156413555,34.381476491689675,34.38147682696581,34.38147749751806,34.38147749751806,34.381478168070316,34.381478168070316,34.38147883862257,34.381479509174824,34.38147984445095,34.381480515003204,34.38148085027933,34.381481520831585,34.38148219138384,34.38148219138384,34.381482526659966,34.38148319721222,34.38148319721222,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148319721222,34.38148286193609,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148185610771,34.38148185610771,34.381481520831585,34.381481520831585,34.38148118555546,34.38148118555546,34.38148085027933,34.38148085027933,34.38148085027933,34.381480515003204,34.38148017972707,34.38148017972707,34.38147984445095,34.38147984445095,34.38147984445095,34.38147984445095,34.38147984445095,34.38148085027933,34.38148085027933,34.38148185610771,34.38148319721222,34.38148487359285,34.38148822635412,34.38149090856313,34.381494261324406,34.381497614085674,34.38150096684694,34.381504990160465,34.38150901347398,34.38151236623526,34.381516724824905,34.38152108341455,34.381526447832584,34.38153114169836,34.38153650611639,34.38154220581055,34.3815479055047,34.38155360519886,34.381559640169144,34.3815653398633,34.38157103955746,34.381576739251614,34.38158243894577,34.38158880919218,34.38159517943859,34.38160087913275,34.381606578826904,34.381612278521054,34.381617307662964,34.381622672080994,34.38162703067064,34.38163138926029,34.381635412573814,34.38163876533508,34.381642788648605,34.381646141409874,34.38164949417114,34.38165284693241,34.38165552914142,34.381657876074314,34.381659887731075,34.38166122883558,34.38166290521622,34.38166458159685,34.38166558742523,34.38166692852974,34.381667599081986,34.381668604910374,34.38166927546263,34.38166994601488,34.38167028129101,34.38167095184326,34.381671622395515,34.38167229294777,34.38167296350002,34.38167329877616,34.38167363405228,34.3816739693284,34.3816739693284,34.38167430460453,34.38167430460453,34.381674639880664,34.381674975156784,34.381674975156784,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.381674975156784,34.381674975156784,34.38167430460453,34.38167430460453,34.3816739693284,34.3816739693284,34.38167363405228,34.38167296350002,34.381672628223896,34.38167195767164,34.381671622395515,34.38167028129101,34.38166927546263,34.38166826963425,34.38166692852974,34.38166625797748,34.381665252149105,34.38166491687298,34.381664246320724,34.381664246320724,34.38166357576847,34.38166357576847,34.381663240492344,34.381663240492344,34.381663240492344,34.38166290521622,34.38166256994008,34.38166189938784,34.38165921717882,34.38165687024593,34.38165418803692,34.38165049999952,34.38164681196213,34.38164245337248,34.38163742423057,34.38163172453642,34.38162501901388,34.38161797821522,34.38161060214043,34.38160389661789,34.38159652054309,34.38159015029669,34.38158344477416,34.38157640397549,34.38156936317682,34.381561651825905,34.38155394047499,34.38154522329569,34.381537176668644,34.3815291300416,34.38152175396681,34.38151504844427,34.38150331377983,34.38149895519018,34.38149560242891,34.38149157911539,34.38148755580187,34.3814842030406,34.38148185610771,34.38147984445095,34.38147883862257,34.38147783279419,34.381478168070316\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"OperatorID\": 0,\n \"PositionLatitude\": -0.821523,\n \"PositionLongitude\": 34.381647,\n \"Speed\": 0,\n \"Status\": 0,\n \"Street\": \"Otange\",\n \"TotalDistanceCovered\": 659,\n \"TotalHectaresTilled\": null,\n \"Town\": \"Homa Bay\",\n \"TractorID\": 502148,\n \"TractorModelID\": 46,\n \"TractorName\": \"KTCB_491X\",\n \"UpdatedAt\": \"2019-10-30 15:45:08\",\n \"UtcOffset\": 0,\n \"WasImmobilized\": false,\n \"WasInArea\": true,\n \"_acl\": {\n \"creator\": \"5d5ff918ecc87c44b9752888\"\n },\n \"license_plate_number\": \"KTCB 491X\",\n \"_kmd\": {\n \"lmt\": \"2019-10-16T08:36:26.228Z\",\n \"ect\": \"2019-10-11T06:47:21.415Z\"\n },\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"FuelLevelVoltage\": 0\n },\n \"502149\": {\n \"_id\": \"5d9ea21c0846cb54f8db3c7b\",\n \"BookingRequests\": true,\n \"Characteristic\": \"102\",\n \"FixedEngineHours\": 732,\n \"FixedOdometerReading\": 0,\n \"Group\": \"RentCo\",\n \"Latitude\": \"-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214248572859018,-0.8214272039776164,-0.8214298859109773,-0.8214329030860226,-0.8214352497777118,-0.8214379317110727,-0.8214406136444335,-0.8214432955777945,-0.8214453070278247,-0.8214473184778421,-0.8214500004111903,-0.8214513413778771,-0.8214533528278946,-0.8214556995195711,-0.8214577109695885,-0.8214603929029367,-0.8214627395946259,-0.8214654215279613,-0.8214681034613095,-0.8214707853946577,-0.8214734673279931,-0.8214761492613285,-0.8214795016780074,-0.8214821836113428,-0.8214855360280089,-0.8214885532030034,-0.8214915703779978,-0.8214942523113204,-0.821497269486315,-0.8215009571446273,-0.8215043095612807,-0.8215076619779341,-0.8215110143945747,-0.8215140315695565,-0.8215170487445381,-0.8215204011611661,-0.8215230830944761,-0.8215261002694451,-0.821529117444414,-0.821532134619383,-0.8215351517943393,-0.8215381689692955,-0.8215408509025928,-0.8215442033192081,-0.8215462147691873,-0.8215488967024719,-0.8215512433940975,-0.821553254844064,-0.8215549310523717,-0.8215562720190076,-0.8215576129856562,-0.8215586187106332,-0.8215596244356101,-0.8215606301605998,-0.8215623063688947,-0.8215633120938716,-0.8215643178188613,-0.8215653235438382,-0.8215666645104741,-0.8215669997521331,-0.8215680054771101,-0.821568340718769,-0.8215696816854177,-0.8215703521687356,-0.8215713578937125,-0.8215720283770305,-0.8215726988603484,-0.8215733693436664,-0.8215737045853254,-0.8215737045853254,-0.8215740398269844,-0.8215743750686434,-0.8215750455519614,-0.8215753807936202,-0.8215757160352792,-0.8215763865185972,-0.8215770570019152,-0.8215777274852332,-0.8215783979685511,-0.821579068451869,-0.821579068451869,-0.821579068451869,-0.8215797389351743,-0.8215797389351743,-0.821580074176846,-0.8215797389351743,-0.821580074176846,-0.8215804094184922,-0.821580744660164,-0.8215810799018102,-0.8215814151434692,-0.8215820856267871,-0.8215820856267871,-0.8215824208684461,-0.8215827561101051,-0.8215830913517641,-0.8215830913517641,-0.8215834265934231,-0.8215834265934231,-0.8215840970767411,-0.8215837618350821,-0.8215837618350821,-0.8215837618350821,-0.8215834265934231,-0.8215830913517641,-0.8215827561101051,-0.8215824208684461,-0.8215820856267871,-0.8215814151434692,-0.8215810799018102,-0.8215797389351743,-0.821579068451869,-0.821579068451869,-0.8215780627268922,-0.8215777274852332,-0.8215770570019152,-0.8215767217602562,-0.8215763865185972,-0.8215760512769382,-0.8215757160352792,-0.8215757160352792,-0.8215750455519614,-0.8215747103103024,-0.8215743750686434,-0.8215737045853254,-0.8215733693436664,-0.8215723636186895,-0.8215713578937125,-0.8215700169270767,-0.821568340718769,-0.8215663292688151,-0.8215646530605075,-0.8215623063688947,-0.8215592891939512,-0.8215566072606666,-0.8215529196024051,-0.8215492319441309,-0.8215455442858567,-0.8215411861442518,-0.8215381689692955,-0.8215341460693496,-0.8215304584110626,-0.821526770752763,-0.8215224126111454,-0.8215190601945175,-0.8215150372945461,-0.8215110143945747,-0.8215069914946034,-0.821502968594632,-0.8214996161779786,-0.8214962637613252,-0.8214922408613284,-0.8214885532030034,-0.8214841950613349,-0.8214798369196663,-0.8214751435363261,-0.8214704501529859,-0.8214654215279613,-0.821460057661265,-0.8214546937945687,-0.8214489946861879,-0.8214443013028095,-0.8214392726777595,-0.8214352497777118,-0.8214315621193358,-0.8214285449442905,-0.8214261982525886,-0.8214245220442301,-0.8214235163192277,-0.821423181077556,-0.821423181077556,-0.821423181077556,-0.8214228458358716,-0.8214228458358716,-0.8214225105941999,-0.8214225105941999,-0.8214221753525281,-0.8214218401108565,-0.8214211696275131,-0.8214211696275131,-0.8214211696275131,-0.8214204991441697,-0.8214204991441697,-0.8214198286608263,-0.8214191581774829,-0.8214191581774829,-0.8214191581774829,-0.8214184876941395,-0.8214184876941395,-0.8214184876941395,-0.8214191581774829,-0.8214194934191545,-0.8214198286608263,-0.8214204991441697,-0.8214215048691847,-0.8214221753525281,-0.8214225105941999,-0.8214225105941999,-0.8214228458358716,-0.8214228458358716,-0.8214228458358716,-0.821423181077556,-0.821423181077556,-0.8214235163192277,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994,-0.8214238515608994\",\n \"Longitude\": \"34.38148085027933,34.38148085027933,34.38148085027933,34.38148085027933,34.38148085027933,34.381479509174824,34.38147883862257,34.38147749751806,34.38147682696581,34.381476156413555,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.38147582113743,34.381476156413555,34.381476491689675,34.38147682696581,34.38147749751806,34.38147749751806,34.381478168070316,34.381478168070316,34.38147883862257,34.381479509174824,34.38147984445095,34.381480515003204,34.38148085027933,34.381481520831585,34.38148219138384,34.38148219138384,34.381482526659966,34.38148319721222,34.38148319721222,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148353248835,34.38148319721222,34.38148286193609,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148219138384,34.38148185610771,34.38148185610771,34.381481520831585,34.381481520831585,34.38148118555546,34.38148118555546,34.38148085027933,34.38148085027933,34.38148085027933,34.381480515003204,34.38148017972707,34.38148017972707,34.38147984445095,34.38147984445095,34.38147984445095,34.38147984445095,34.38147984445095,34.38148085027933,34.38148085027933,34.38148185610771,34.38148319721222,34.38148487359285,34.38148822635412,34.38149090856313,34.381494261324406,34.381497614085674,34.38150096684694,34.381504990160465,34.38150901347398,34.38151236623526,34.381516724824905,34.38152108341455,34.381526447832584,34.38153114169836,34.38153650611639,34.38154220581055,34.3815479055047,34.38155360519886,34.381559640169144,34.3815653398633,34.38157103955746,34.381576739251614,34.38158243894577,34.38158880919218,34.38159517943859,34.38160087913275,34.381606578826904,34.381612278521054,34.381617307662964,34.381622672080994,34.38162703067064,34.38163138926029,34.381635412573814,34.38163876533508,34.381642788648605,34.381646141409874,34.38164949417114,34.38165284693241,34.38165552914142,34.381657876074314,34.381659887731075,34.38166122883558,34.38166290521622,34.38166458159685,34.38166558742523,34.38166692852974,34.381667599081986,34.381668604910374,34.38166927546263,34.38166994601488,34.38167028129101,34.38167095184326,34.381671622395515,34.38167229294777,34.38167296350002,34.38167329877616,34.38167363405228,34.3816739693284,34.3816739693284,34.38167430460453,34.38167430460453,34.381674639880664,34.381674975156784,34.381674975156784,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.38167531043291,34.381674975156784,34.381674975156784,34.38167430460453,34.38167430460453,34.3816739693284,34.3816739693284,34.38167363405228,34.38167296350002,34.381672628223896,34.38167195767164,34.381671622395515,34.38167028129101,34.38166927546263,34.38166826963425,34.38166692852974,34.38166625797748,34.381665252149105,34.38166491687298,34.381664246320724,34.381664246320724,34.38166357576847,34.38166357576847,34.381663240492344,34.381663240492344,34.381663240492344,34.38166290521622,34.38166256994008,34.38166189938784,34.38165921717882,34.38165687024593,34.38165418803692,34.38165049999952,34.38164681196213,34.38164245337248,34.38163742423057,34.38163172453642,34.38162501901388,34.38161797821522,34.38161060214043,34.38160389661789,34.38159652054309,34.38159015029669,34.38158344477416,34.38157640397549,34.38156936317682,34.381561651825905,34.38155394047499,34.38154522329569,34.381537176668644,34.3815291300416,34.38152175396681,34.38151504844427,34.38150331377983,34.38149895519018,34.38149560242891,34.38149157911539,34.38148755580187,34.3814842030406,34.38148185610771,34.38147984445095,34.38147883862257,34.38147783279419,34.381478168070316\",\n \"Speed\": 0,\n \"Status\": 0,\n \"TotalHectaresTilled\": null,\n \"TractorID\": 502149,\n \"TractorModelID\": 46,\n \"TractorName\": \"KTCB_473X\",\n \"license_plate_number\": \"KTCB 473X\",\n \"UpdatedAt\": \"2019-10-30 15:39:21\",\n \"NeedToSendGeofenceOutNotification\": true,\n \"LastGeofenceNotificationTime\": \"\",\n \"WasInArea\": true,\n \"Currency\": null,\n \"_acl\": {\n \"creator\": \"5d5ff918ecc87c44b9752888\"\n },\n \"_kmd\": {\n \"lmt\": \"2019-10-10T03:14:36.488Z\",\n \"ect\": \"2019-10-10T03:14:36.488Z\"\n },\n \"EngineHours\": 113,\n \"TotalDistanceCovered\": 585,\n \"UtcOffset\": 0,\n \"ActiveTimeToday\": 0,\n \"PositionLatitude\": -0.821565,\n \"PositionLongitude\": 34.381625,\n \"LastActiveTime\": \"2019-10-30 09:49:33\",\n \"FuelRawValue\": 0,\n \"IgnitionStatus\": 0,\n \"AssetState\": \"Off\",\n \"Heading\": 0,\n \"FuelLevelVoltage\": 0,\n \"Street\": \"Otange\",\n \"Town\": \"Homa Bay\",\n \"Country\": \"Kenya\",\n \"PrevTempFuelData\": [\n {\n \"FuelLitres\": 35,\n \"FuelVolume\": 55,\n \"FuelRawValue\": 5137,\n \"LastActiveTime\": \"2019-10-14 13:12:35\"\n },\n {\n \"FuelLitres\": 35,\n \"FuelVolume\": 55,\n \"FuelRawValue\": 5137,\n \"LastActiveTime\": \"2019-10-14 13:17:35\"\n }\n ],\n \"FuelVolume\": 54,\n \"FuelLitres\": 35\n }\n};\n\nfunction onRequest(request, response, modules) {\n var tractorDetailCol = modules.collectionAccess.collection('TractorDetail');\n var countTractors = 0;\n tractorDetailCol.find({Latitude: {$lte: 999999999999}}, function(tractorDetailErr, tractorDetailList){\n if (tractorDetailList && tractorDetailList.length > 0){\n modules.logger.info(\"Count tractors found: \"+tractorDetailList.length);\n countTractors = tractorDetailList.length;\n updateGeofenceData(tractorDetailList);\n } else {\n modules.logger.info(\"Tractors not found: \"+tractorDetailErr);\n response.complete();\n }\n });\n\n var updateGeofenceData = function(tractorDetailList){\n tractorDetailList.forEach(function(tractor){\n var latitude = tractorDetailDocs[tractor.TractorID]? tractorDetailDocs[tractor.TractorID].Latitude: \"\";\n var longitude = tractorDetailDocs[tractor.TractorID]? tractorDetailDocs[tractor.TractorID].Longitude: \"\";\n tractorDetailCol.update({TractorID: tractor.TractorID}, {$set: {Latitude: latitude, Longitude: longitude}}, {upsert: false}, function(tractorDetailUpdateErr, tractorDetailUpdate){\n countTractors--;\n finish();\n })\n });\n }\n\n\n var finish = function(){\n if (countTractors <= 0) response.complete();\n }\n}" }, "__updateTractorActiveTimeToday" : { "code" : "function onRequest(request, response, modules) {\n const Tractor = modules.collectionAccess.collection('TractorDetail');\n const requestBody = request.body;\n \n if(requestBody.totalActiveTime && requestBody.tractorId ){\n \n const TractorId = Number(requestBody.tractorId);\n \n Tractor.findOne({TractorID: TractorId}, function(err, tractor){\n \n if( tractor.TractorID ){\n \n var update = {};\n \n update.ActiveTimeToday = requestBody.totalActiveTime + tractor.ActiveTimeToday;\n \n Tractor.update({TractorID: TractorId}, { $set: update }, function(err, tractor){\n if(err){\n modules.logger.info('There was an error updating the ActiveTimeToday for the tractor with the ID of ' + requestBody.tractorId )\n } else {\n modules.logger.info('Successfully updated ActiveTimeToday for the tractor with the ID of ' + requestBody.tractorId);\n }\n });\n\n\n } else {\n modules.logger.info(\"request body not valid \" + TractorId);\n }\n response.complete();\n });\n \n } else {\n response.complete();\n }\n \n}" }, "__updateTractorDetailProps" : { "code" : "function onRequest(request, response, modules) {\n const Tractor = modules.collectionAccess.collection('TractorDetail');\n// const tractorUpdateObj = request.body;\n// const latitude = tractorUpdateObj.latitude;\n// const longitude = tractorUpdateObj.longitude;\n// const tractorId = Number(tractorUpdateObj.tracker_id);\n \n var tractorLatLngs = [\n {\n \"tracker_id\": 500505,\n \"latitude\": 6.884975,\n \"longitude\": 5.597989\n },\n {\n \"tracker_id\": 500254,\n \"latitude\": 7.312169,\n \"longitude\": 2.622873\n },\n {\n \"tracker_id\": 500515,\n \"latitude\": -25.805806,\n \"longitude\": 29.462471\n },\n {\n \"tracker_id\": 500510,\n \"latitude\": -3.352464,\n \"longitude\": 36.600405\n },\n {\n \"tracker_id\": 500507,\n \"latitude\": -3.387299,\n \"longitude\": 36.826538\n },\n {\n \"tracker_id\": 500508,\n \"latitude\": -3.352404,\n \"longitude\": 36.600412\n },\n {\n \"tracker_id\": 500509,\n \"latitude\": -13.384611,\n \"longitude\": 38.444872\n },\n {\n \"tracker_id\": 500513,\n \"latitude\": 16.242103,\n \"longitude\": -16.213526\n },\n {\n \"tracker_id\": 500514,\n \"latitude\": 16.242301,\n \"longitude\": -16.213437\n },\n {\n \"tracker_id\": 500511,\n \"latitude\": 16.242283,\n \"longitude\": -16.2134\n },\n {\n \"tracker_id\": 500173,\n \"latitude\": 11.971961,\n \"longitude\": 8.552116\n },\n {\n \"tracker_id\": 500046,\n \"latitude\": 10.458646,\n \"longitude\": 5.396463\n },\n {\n \"tracker_id\": 500182,\n \"latitude\": 6.526587,\n \"longitude\": 7.008525\n },\n {\n \"tracker_id\": 500021,\n \"latitude\": 8.480871,\n \"longitude\": 8.27575\n },\n {\n \"tracker_id\": 500139,\n \"latitude\": 8.601165,\n \"longitude\": 8.855734\n },\n {\n \"tracker_id\": 500174,\n \"latitude\": 11.602879,\n \"longitude\": 8.430377\n },\n {\n \"tracker_id\": 500007,\n \"latitude\": 8.422942,\n \"longitude\": 9.907139\n },\n {\n \"tracker_id\": 500193,\n \"latitude\": 8.536153,\n \"longitude\": 7.711876\n },\n {\n \"tracker_id\": 500134,\n \"latitude\": 11.010661,\n \"longitude\": 7.986521\n },\n {\n \"tracker_id\": 500068,\n \"latitude\": 8.890303,\n \"longitude\": 6.624013\n },\n {\n \"tracker_id\": 500060,\n \"latitude\": 11.08011,\n \"longitude\": 7.702034\n },\n {\n \"tracker_id\": 500135,\n \"latitude\": 8.508601,\n \"longitude\": 8.528064\n },\n {\n \"tracker_id\": 500052,\n \"latitude\": 11.080558,\n \"longitude\": 7.702229\n },\n {\n \"tracker_id\": 500136,\n \"latitude\": 8.258436,\n \"longitude\": 8.019063\n },\n {\n \"tracker_id\": 500027,\n \"latitude\": 11.73358,\n \"longitude\": 8.45314\n },\n {\n \"tracker_id\": 500077,\n \"latitude\": 8.644695,\n \"longitude\": 8.978349\n },\n {\n \"tracker_id\": 500137,\n \"latitude\": 8.55845,\n \"longitude\": 8.858083\n },\n {\n \"tracker_id\": 500016,\n \"latitude\": 8.34517,\n \"longitude\": 7.603384\n },\n {\n \"tracker_id\": 500125,\n \"latitude\": 11.972033,\n \"longitude\": 8.55223\n },\n {\n \"tracker_id\": 500113,\n \"latitude\": 8.913446,\n \"longitude\": 7.260764\n },\n {\n \"tracker_id\": 500175,\n \"latitude\": 11.602758,\n \"longitude\": 8.430458\n },\n {\n \"tracker_id\": 500078,\n \"latitude\": 8.893536,\n \"longitude\": 6.623393\n },\n {\n \"tracker_id\": 500161,\n \"latitude\": 11.068763,\n \"longitude\": 7.956371\n },\n {\n \"tracker_id\": 500023,\n \"latitude\": 11.080688,\n \"longitude\": 7.702147\n },\n {\n \"tracker_id\": 500097,\n \"latitude\": 7.418939,\n \"longitude\": 3.969904\n },\n {\n \"tracker_id\": 500154,\n \"latitude\": 7.419085,\n \"longitude\": 3.969702\n },\n {\n \"tracker_id\": 500073,\n \"latitude\": 8.800957,\n \"longitude\": 6.455364\n },\n {\n \"tracker_id\": 500083,\n \"latitude\": 8.546713,\n \"longitude\": 10.368346\n },\n {\n \"tracker_id\": 500176,\n \"latitude\": 11.625834,\n \"longitude\": 7.843014\n },\n {\n \"tracker_id\": 500035,\n \"latitude\": 8.480882,\n \"longitude\": 8.275669\n },\n {\n \"tracker_id\": 500120,\n \"latitude\": 8.933661,\n \"longitude\": 11.188147\n },\n {\n \"tracker_id\": 500037,\n \"latitude\": 11.08032,\n \"longitude\": 7.702257\n },\n {\n \"tracker_id\": 500008,\n \"latitude\": 8.551616,\n \"longitude\": 7.716387\n },\n {\n \"tracker_id\": 500072,\n \"latitude\": 8.34787,\n \"longitude\": 7.605445\n },\n {\n \"tracker_id\": 500003,\n \"latitude\": 10.349426,\n \"longitude\": 5.611341\n },\n {\n \"tracker_id\": 500018,\n \"latitude\": 11.034258,\n \"longitude\": 7.915281\n },\n {\n \"tracker_id\": 500148,\n \"latitude\": 8.508603,\n \"longitude\": 8.528061\n },\n {\n \"tracker_id\": 500047,\n \"latitude\": 8.92809,\n \"longitude\": 6.511429\n },\n {\n \"tracker_id\": 500036,\n \"latitude\": 11.080229,\n \"longitude\": 7.702016\n },\n {\n \"tracker_id\": 500194,\n \"latitude\": 11.080917,\n \"longitude\": 7.702177\n },\n {\n \"tracker_id\": 500061,\n \"latitude\": 10.391444,\n \"longitude\": 5.180652\n },\n {\n \"tracker_id\": 500006,\n \"latitude\": 8.480943,\n \"longitude\": 8.275697\n },\n {\n \"tracker_id\": 500019,\n \"latitude\": 11.712049,\n \"longitude\": 8.423292\n },\n {\n \"tracker_id\": 500026,\n \"latitude\": 13.307825,\n \"longitude\": 5.476278\n },\n {\n \"tracker_id\": 500122,\n \"latitude\": 7.419042,\n \"longitude\": 3.969748\n },\n {\n \"tracker_id\": 500150,\n \"latitude\": 8.602219,\n \"longitude\": 8.858131\n },\n {\n \"tracker_id\": 500031,\n \"latitude\": 11.602898,\n \"longitude\": 8.430468\n },\n {\n \"tracker_id\": 500157,\n \"latitude\": 10.698078,\n \"longitude\": 7.757339\n },\n {\n \"tracker_id\": 500158,\n \"latitude\": 9.960288,\n \"longitude\": 7.415821\n },\n {\n \"tracker_id\": 500028,\n \"latitude\": 8.925388,\n \"longitude\": 7.185961\n },\n {\n \"tracker_id\": 500071,\n \"latitude\": 11.798512,\n \"longitude\": 8.459341\n },\n {\n \"tracker_id\": 500181,\n \"latitude\": 10.420686,\n \"longitude\": 7.674611\n },\n {\n \"tracker_id\": 500126,\n \"latitude\": 11.797149,\n \"longitude\": 8.438593\n },\n {\n \"tracker_id\": 500063,\n \"latitude\": 8.890299,\n \"longitude\": 6.623912\n },\n {\n \"tracker_id\": 500062,\n \"latitude\": 8.437623,\n \"longitude\": 7.281523\n },\n {\n \"tracker_id\": 500119,\n \"latitude\": 9.565138,\n \"longitude\": 4.030496\n },\n {\n \"tracker_id\": 500093,\n \"latitude\": 11.571832,\n \"longitude\": 8.442599\n },\n {\n \"tracker_id\": 500051,\n \"latitude\": 11.080136,\n \"longitude\": 7.701998\n },\n {\n \"tracker_id\": 500160,\n \"latitude\": 8.388189,\n \"longitude\": 10.513968\n },\n {\n \"tracker_id\": 500192,\n \"latitude\": 8.273487,\n \"longitude\": 7.716336\n },\n {\n \"tracker_id\": 500000,\n \"latitude\": 8.627517,\n \"longitude\": 8.894382\n },\n {\n \"tracker_id\": 500022,\n \"latitude\": 8.819435,\n \"longitude\": 6.782732\n },\n {\n \"tracker_id\": 500100,\n \"latitude\": 11.079476,\n \"longitude\": 7.701245\n },\n {\n \"tracker_id\": 500102,\n \"latitude\": 11.895426,\n \"longitude\": 8.892688\n },\n {\n \"tracker_id\": 500133,\n \"latitude\": 11.034408,\n \"longitude\": 7.915312\n },\n {\n \"tracker_id\": 500153,\n \"latitude\": 7.012537,\n \"longitude\": 2.944562\n },\n {\n \"tracker_id\": 500098,\n \"latitude\": 12.660385,\n \"longitude\": 5.934873\n },\n {\n \"tracker_id\": 500140,\n \"latitude\": 11.080253,\n \"longitude\": 7.702235\n },\n {\n \"tracker_id\": 500143,\n \"latitude\": 8.522894,\n \"longitude\": 7.707738\n },\n {\n \"tracker_id\": 500080,\n \"latitude\": 7.917429,\n \"longitude\": 8.321569\n },\n {\n \"tracker_id\": 500163,\n \"latitude\": 11.1355,\n \"longitude\": 7.865355\n },\n {\n \"tracker_id\": 500132,\n \"latitude\": 11.080407,\n \"longitude\": 7.702009\n },\n {\n \"tracker_id\": 500117,\n \"latitude\": 12.333469,\n \"longitude\": 9.675397\n },\n {\n \"tracker_id\": 500004,\n \"latitude\": 11.034138,\n \"longitude\": 7.91556\n },\n {\n \"tracker_id\": 500129,\n \"latitude\": 9.979596,\n \"longitude\": 5.805815\n },\n {\n \"tracker_id\": 500091,\n \"latitude\": 7.419631,\n \"longitude\": 3.969553\n },\n {\n \"tracker_id\": 500149,\n \"latitude\": 11.080203,\n \"longitude\": 7.702206\n },\n {\n \"tracker_id\": 500012,\n \"latitude\": 8.695756,\n \"longitude\": 8.039841\n },\n {\n \"tracker_id\": 500042,\n \"latitude\": 8.43579,\n \"longitude\": 7.574201\n },\n {\n \"tracker_id\": 500156,\n \"latitude\": 11.972212,\n \"longitude\": 8.552381\n },\n {\n \"tracker_id\": 500179,\n \"latitude\": 7.917461,\n \"longitude\": 8.32151\n },\n {\n \"tracker_id\": 500070,\n \"latitude\": 8.8903,\n \"longitude\": 6.623988\n },\n {\n \"tracker_id\": 500015,\n \"latitude\": 8.561133,\n \"longitude\": 7.723224\n },\n {\n \"tracker_id\": 500183,\n \"latitude\": 12.682007,\n \"longitude\": 6.078685\n },\n {\n \"tracker_id\": 500118,\n \"latitude\": 7.91743,\n \"longitude\": 8.321412\n },\n {\n \"tracker_id\": 500064,\n \"latitude\": 11.080623,\n \"longitude\": 7.702288\n },\n {\n \"tracker_id\": 500177,\n \"latitude\": 8.860674,\n \"longitude\": 6.611838\n },\n {\n \"tracker_id\": 500101,\n \"latitude\": 11.024207,\n \"longitude\": 7.939708\n },\n {\n \"tracker_id\": 500108,\n \"latitude\": 8.220522,\n \"longitude\": 9.340078\n },\n {\n \"tracker_id\": 500107,\n \"latitude\": 7.890175,\n \"longitude\": 8.339797\n },\n {\n \"tracker_id\": 500050,\n \"latitude\": 8.580758,\n \"longitude\": 7.745837\n },\n {\n \"tracker_id\": 500124,\n \"latitude\": 7.419777,\n \"longitude\": 3.96964\n },\n {\n \"tracker_id\": 500043,\n \"latitude\": 11.798249,\n \"longitude\": 8.459482\n },\n {\n \"tracker_id\": 500014,\n \"latitude\": 10.204976,\n \"longitude\": 5.400949\n },\n {\n \"tracker_id\": 500030,\n \"latitude\": 7.879846,\n \"longitude\": 8.312233\n },\n {\n \"tracker_id\": 500142,\n \"latitude\": 11.041272,\n \"longitude\": 8.148058\n },\n {\n \"tracker_id\": 500141,\n \"latitude\": 11.602513,\n \"longitude\": 8.432604\n },\n {\n \"tracker_id\": 500144,\n \"latitude\": 8.173464,\n \"longitude\": 9.34809\n },\n {\n \"tracker_id\": 500001,\n \"latitude\": 10.341787,\n \"longitude\": 5.693926\n },\n {\n \"tracker_id\": 500116,\n \"latitude\": 10.20485,\n \"longitude\": 5.400701\n },\n {\n \"tracker_id\": 500127,\n \"latitude\": 7.917398,\n \"longitude\": 8.321531\n },\n {\n \"tracker_id\": 500145,\n \"latitude\": 9.580203,\n \"longitude\": 6.565326\n },\n {\n \"tracker_id\": 500002,\n \"latitude\": 8.553613,\n \"longitude\": 9.637882\n },\n {\n \"tracker_id\": 500164,\n \"latitude\": 8.685411,\n \"longitude\": 6.736864\n },\n {\n \"tracker_id\": 500044,\n \"latitude\": 8.536214,\n \"longitude\": 7.711847\n },\n {\n \"tracker_id\": 500045,\n \"latitude\": 11.0803,\n \"longitude\": 7.702188\n },\n {\n \"tracker_id\": 500106,\n \"latitude\": 7.418908,\n \"longitude\": 3.96987\n },\n {\n \"tracker_id\": 500165,\n \"latitude\": 8.963704,\n \"longitude\": 7.136177\n },\n {\n \"tracker_id\": 500081,\n \"latitude\": 8.868445,\n \"longitude\": 6.61377\n },\n {\n \"tracker_id\": 500104,\n \"latitude\": 8.422504,\n \"longitude\": 9.908294\n },\n {\n \"tracker_id\": 500039,\n \"latitude\": 8.745427,\n \"longitude\": 8.785342\n },\n {\n \"tracker_id\": 500011,\n \"latitude\": 10.387095,\n \"longitude\": 4.933553\n },\n {\n \"tracker_id\": 500029,\n \"latitude\": 10.204764,\n \"longitude\": 5.400668\n },\n {\n \"tracker_id\": 500054,\n \"latitude\": 8.893554,\n \"longitude\": 6.62339\n },\n {\n \"tracker_id\": 500112,\n \"latitude\": 8.496362,\n \"longitude\": 7.487645\n },\n {\n \"tracker_id\": 500010,\n \"latitude\": 8.78277,\n \"longitude\": 6.993573\n },\n {\n \"tracker_id\": 500086,\n \"latitude\": 10.391181,\n \"longitude\": 7.50905\n },\n {\n \"tracker_id\": 500065,\n \"latitude\": 8.239692,\n \"longitude\": 7.578694\n },\n {\n \"tracker_id\": 500169,\n \"latitude\": 11.602696,\n \"longitude\": 8.430342\n },\n {\n \"tracker_id\": 500089,\n \"latitude\": 8.536272,\n \"longitude\": 7.711891\n },\n {\n \"tracker_id\": 500048,\n \"latitude\": 8.255835,\n \"longitude\": 7.833428\n },\n {\n \"tracker_id\": 500025,\n \"latitude\": 10.36023,\n \"longitude\": 5.158688\n },\n {\n \"tracker_id\": 500049,\n \"latitude\": 8.563282,\n \"longitude\": 7.724901\n },\n {\n \"tracker_id\": 500170,\n \"latitude\": 11.972199,\n \"longitude\": 8.552336\n },\n {\n \"tracker_id\": 500090,\n \"latitude\": 8.508509,\n \"longitude\": 8.528125\n },\n {\n \"tracker_id\": 500094,\n \"latitude\": 8.829708,\n \"longitude\": 4.985909\n },\n {\n \"tracker_id\": 500171,\n \"latitude\": 11.972065,\n \"longitude\": 8.552265\n },\n {\n \"tracker_id\": 500099,\n \"latitude\": 9.894173,\n \"longitude\": 4.719688\n },\n {\n \"tracker_id\": 500041,\n \"latitude\": 11.080335,\n \"longitude\": 7.701987\n },\n {\n \"tracker_id\": 500172,\n \"latitude\": 11.038102,\n \"longitude\": 7.884785\n },\n {\n \"tracker_id\": 500159,\n \"latitude\": 7.980107,\n \"longitude\": 10.990652\n },\n {\n \"tracker_id\": 500128,\n \"latitude\": 11.972285,\n \"longitude\": 8.552422\n },\n {\n \"tracker_id\": 500033,\n \"latitude\": 8.662056,\n \"longitude\": 7.612756\n },\n {\n \"tracker_id\": 500184,\n \"latitude\": 10.832362,\n \"longitude\": 8.348079\n },\n {\n \"tracker_id\": 500115,\n \"latitude\": 8.524221,\n \"longitude\": 7.70807\n },\n {\n \"tracker_id\": 500058,\n \"latitude\": 11.080287,\n \"longitude\": 7.702008\n },\n {\n \"tracker_id\": 500069,\n \"latitude\": 11.080279,\n \"longitude\": 7.701986\n },\n {\n \"tracker_id\": 500114,\n \"latitude\": 8.699882,\n \"longitude\": 6.520428\n },\n {\n \"tracker_id\": 500095,\n \"latitude\": 11.602736,\n \"longitude\": 8.430467\n },\n {\n \"tracker_id\": 500178,\n \"latitude\": 8.357714,\n \"longitude\": 8.116371\n },\n {\n \"tracker_id\": 500024,\n \"latitude\": 11.0804,\n \"longitude\": 7.702219\n },\n {\n \"tracker_id\": 500013,\n \"latitude\": 8.50864,\n \"longitude\": 8.528042\n },\n {\n \"tracker_id\": 500009,\n \"latitude\": 8.495999,\n \"longitude\": 7.487392\n },\n {\n \"tracker_id\": 500085,\n \"latitude\": 9.110891,\n \"longitude\": 6.95535\n },\n {\n \"tracker_id\": 500066,\n \"latitude\": 10.307501,\n \"longitude\": 5.705054\n },\n {\n \"tracker_id\": 500034,\n \"latitude\": 11.034167,\n \"longitude\": 7.915306\n },\n {\n \"tracker_id\": 500151,\n \"latitude\": 8.892833,\n \"longitude\": 6.623491\n },\n {\n \"tracker_id\": 500109,\n \"latitude\": 11.602431,\n \"longitude\": 8.432735\n },\n {\n \"tracker_id\": 500079,\n \"latitude\": 11.080247,\n \"longitude\": 7.702301\n },\n {\n \"tracker_id\": 500084,\n \"latitude\": 10.40895,\n \"longitude\": 5.487319\n },\n {\n \"tracker_id\": 500075,\n \"latitude\": 11.080146,\n \"longitude\": 7.702151\n },\n {\n \"tracker_id\": 500152,\n \"latitude\": 7.419003,\n \"longitude\": 3.969807\n },\n {\n \"tracker_id\": 500082,\n \"latitude\": 9.483487,\n \"longitude\": 6.445652\n },\n {\n \"tracker_id\": 500053,\n \"latitude\": 11.301605,\n \"longitude\": 7.892119\n },\n {\n \"tracker_id\": 500092,\n \"latitude\": 7.841815,\n \"longitude\": 10.969782\n },\n {\n \"tracker_id\": 500111,\n \"latitude\": 8.522769,\n \"longitude\": 7.707735\n },\n {\n \"tracker_id\": 500138,\n \"latitude\": 11.60287,\n \"longitude\": 8.430377\n },\n {\n \"tracker_id\": 500155,\n \"latitude\": 10.698229,\n \"longitude\": 7.757283\n },\n {\n \"tracker_id\": 500130,\n \"latitude\": 11.080216,\n \"longitude\": 7.702397\n },\n {\n \"tracker_id\": 500123,\n \"latitude\": 8.456565,\n \"longitude\": 6.370357\n },\n {\n \"tracker_id\": 500162,\n \"latitude\": 11.602726,\n \"longitude\": 8.430309\n },\n {\n \"tracker_id\": 500121,\n \"latitude\": 8.922995,\n \"longitude\": 7.2214\n },\n {\n \"tracker_id\": 500055,\n \"latitude\": 11.080324,\n \"longitude\": 7.701996\n },\n {\n \"tracker_id\": 500032,\n \"latitude\": 7.917607,\n \"longitude\": 8.321122\n },\n {\n \"tracker_id\": 500074,\n \"latitude\": 12.444311,\n \"longitude\": 10.02779\n },\n {\n \"tracker_id\": 500191,\n \"latitude\": 8.940539,\n \"longitude\": 7.101262\n },\n {\n \"tracker_id\": 500020,\n \"latitude\": 8.697809,\n \"longitude\": 6.507442\n },\n {\n \"tracker_id\": 500146,\n \"latitude\": 8.496071,\n \"longitude\": 7.508463\n },\n {\n \"tracker_id\": 500131,\n \"latitude\": 11.034194,\n \"longitude\": 7.91525\n },\n {\n \"tracker_id\": 500110,\n \"latitude\": 8.404822,\n \"longitude\": 8.369033\n },\n {\n \"tracker_id\": 500147,\n \"latitude\": 8.536062,\n \"longitude\": 7.711697\n },\n {\n \"tracker_id\": 500166,\n \"latitude\": 10.054241,\n \"longitude\": 7.384573\n },\n {\n \"tracker_id\": 500167,\n \"latitude\": 8.480397,\n \"longitude\": 8.276634\n },\n {\n \"tracker_id\": 500040,\n \"latitude\": 11.08061,\n \"longitude\": 7.702294\n },\n {\n \"tracker_id\": 500168,\n \"latitude\": 8.424789,\n \"longitude\": 9.906735\n },\n {\n \"tracker_id\": 500087,\n \"latitude\": 11.080266,\n \"longitude\": 7.701997\n },\n {\n \"tracker_id\": 500005,\n \"latitude\": 9.048041,\n \"longitude\": 6.589001\n },\n {\n \"tracker_id\": 500103,\n \"latitude\": 8.480931,\n \"longitude\": 8.275734\n },\n {\n \"tracker_id\": 500186,\n \"latitude\": 9.53503,\n \"longitude\": 7.473972\n },\n {\n \"tracker_id\": 500180,\n \"latitude\": 7.917482,\n \"longitude\": 8.321438\n },\n {\n \"tracker_id\": 500059,\n \"latitude\": 9.943256,\n \"longitude\": 5.298962\n },\n {\n \"tracker_id\": 500187,\n \"latitude\": 9.5466,\n \"longitude\": 7.484539\n },\n {\n \"tracker_id\": 500105,\n \"latitude\": 8.544959,\n \"longitude\": 7.87305\n },\n {\n \"tracker_id\": 500056,\n \"latitude\": 11.08014,\n \"longitude\": 7.701987\n },\n {\n \"tracker_id\": 500076,\n \"latitude\": 8.581881,\n \"longitude\": 9.55673\n },\n {\n \"tracker_id\": 500038,\n \"latitude\": 11.08023,\n \"longitude\": 7.702196\n },\n {\n \"tracker_id\": 501012,\n \"latitude\": 8.625798,\n \"longitude\": 8.94349\n },\n {\n \"tracker_id\": 501003,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 501013,\n \"latitude\": 11.57101,\n \"longitude\": 8.458457\n },\n {\n \"tracker_id\": 501015,\n \"latitude\": 10.349586,\n \"longitude\": 5.611397\n },\n {\n \"tracker_id\": 501018,\n \"latitude\": 9.671874,\n \"longitude\": 4.873864\n },\n {\n \"tracker_id\": 501044,\n \"latitude\": 11.036381,\n \"longitude\": 7.916113\n },\n {\n \"tracker_id\": 501045,\n \"latitude\": 11.162462,\n \"longitude\": 7.637909\n },\n {\n \"tracker_id\": 501005,\n \"latitude\": 8.402005,\n \"longitude\": 7.630519\n },\n {\n \"tracker_id\": 501024,\n \"latitude\": 10.768596,\n \"longitude\": 7.348975\n },\n {\n \"tracker_id\": 501030,\n \"latitude\": 8.881606,\n \"longitude\": 6.366108\n },\n {\n \"tracker_id\": 501034,\n \"latitude\": 11.079999,\n \"longitude\": 7.700239\n },\n {\n \"tracker_id\": 501047,\n \"latitude\": 11.366435,\n \"longitude\": 7.992652\n },\n {\n \"tracker_id\": 501041,\n \"latitude\": 11.382221,\n \"longitude\": 5.809122\n },\n {\n \"tracker_id\": 501009,\n \"latitude\": 10.249837,\n \"longitude\": 9.016772\n },\n {\n \"tracker_id\": 501020,\n \"latitude\": 8.464931,\n \"longitude\": 6.316599\n },\n {\n \"tracker_id\": \"500568: 455R\",\n \"latitude\": 0.087245,\n \"longitude\": 37.241478\n },\n {\n \"tracker_id\": \"500543: 457R\",\n \"latitude\": -2.543015,\n \"longitude\": 36.810093\n },\n {\n \"tracker_id\": \"500556: 445Q\",\n \"latitude\": -0.152343,\n \"longitude\": 34.845548\n },\n {\n \"tracker_id\": \"500552: 452R\",\n \"latitude\": 0.091876,\n \"longitude\": 37.519509\n },\n {\n \"tracker_id\": \"500540: 456R\",\n \"latitude\": -0.152405,\n \"longitude\": 34.845536\n },\n {\n \"tracker_id\": \"500548: 458R\",\n \"latitude\": -0.152401,\n \"longitude\": 34.845558\n },\n {\n \"tracker_id\": \"500570: 454R\",\n \"latitude\": -1.100384,\n \"longitude\": 35.842038\n },\n {\n \"tracker_id\": \"500558: 6130J\",\n \"latitude\": -0.206931,\n \"longitude\": 35.197133\n },\n {\n \"tracker_id\": 500257,\n \"latitude\": 7.551164,\n \"longitude\": 3.665435\n },\n {\n \"tracker_id\": 500260,\n \"latitude\": 7.547904,\n \"longitude\": 3.665581\n },\n {\n \"tracker_id\": 500259,\n \"latitude\": 7.558659,\n \"longitude\": 3.660043\n },\n {\n \"tracker_id\": 500258,\n \"latitude\": 7.551205,\n \"longitude\": 3.66547\n },\n {\n \"tracker_id\": 500261,\n \"latitude\": 7.551145,\n \"longitude\": 3.665454\n },\n {\n \"tracker_id\": 500405,\n \"latitude\": 6.444139,\n \"longitude\": 6.909345\n },\n {\n \"tracker_id\": 500408,\n \"latitude\": 6.44415,\n \"longitude\": 6.909286\n },\n {\n \"tracker_id\": 500406,\n \"latitude\": 6.444124,\n \"longitude\": 6.909324\n },\n {\n \"tracker_id\": 500201,\n \"latitude\": -16.137947,\n \"longitude\": 39.274165\n },\n {\n \"tracker_id\": 500203,\n \"latitude\": -16.765758,\n \"longitude\": 37.03766\n },\n {\n \"tracker_id\": 500204,\n \"latitude\": -14.962177,\n \"longitude\": 40.065409\n },\n {\n \"tracker_id\": 500207,\n \"latitude\": -15.488097,\n \"longitude\": 36.980116\n },\n {\n \"tracker_id\": 500200,\n \"latitude\": -15.64724,\n \"longitude\": 37.680136\n },\n {\n \"tracker_id\": 500208,\n \"latitude\": -15.233272,\n \"longitude\": 37.616696\n },\n {\n \"tracker_id\": 500205,\n \"latitude\": -15.364279,\n \"longitude\": 36.804014\n },\n {\n \"tracker_id\": 500209,\n \"latitude\": -15.767657,\n \"longitude\": 39.311604\n },\n {\n \"tracker_id\": 500424,\n \"latitude\": 7.647134,\n \"longitude\": 4.165459\n },\n {\n \"tracker_id\": 500425,\n \"latitude\": 8.884847,\n \"longitude\": 9.730654\n },\n {\n \"tracker_id\": 500427,\n \"latitude\": 12.593142,\n \"longitude\": 8.45681\n },\n {\n \"tracker_id\": 500429,\n \"latitude\": 7.243985,\n \"longitude\": 5.209165\n },\n {\n \"tracker_id\": 500421,\n \"latitude\": 8.974948,\n \"longitude\": 9.808495\n },\n {\n \"tracker_id\": 500428,\n \"latitude\": 12.52125,\n \"longitude\": 10.283644\n },\n {\n \"tracker_id\": 500420,\n \"latitude\": 6.050031,\n \"longitude\": 7.564737\n },\n {\n \"tracker_id\": 500426,\n \"latitude\": 8.360764,\n \"longitude\": 11.091897\n },\n {\n \"tracker_id\": 500430,\n \"latitude\": 7.6471,\n \"longitude\": 4.16552\n },\n {\n \"tracker_id\": 500431,\n \"latitude\": 7.243988,\n \"longitude\": 5.209167\n },\n {\n \"tracker_id\": 500419,\n \"latitude\": 6.307893,\n \"longitude\": 8.155067\n },\n {\n \"tracker_id\": 500401,\n \"latitude\": 4.974961,\n \"longitude\": 7.883093\n },\n {\n \"tracker_id\": 500302,\n \"latitude\": 5.309688,\n \"longitude\": 7.887455\n },\n {\n \"tracker_id\": 500305,\n \"latitude\": 4.770168,\n \"longitude\": 7.929334\n },\n {\n \"tracker_id\": 500407,\n \"latitude\": 5.154603,\n \"longitude\": 8.022382\n },\n {\n \"tracker_id\": 500404,\n \"latitude\": 4.661155,\n \"longitude\": 7.840238\n },\n {\n \"tracker_id\": 500318,\n \"latitude\": 6.74615,\n \"longitude\": 4.553455\n },\n {\n \"tracker_id\": 500322,\n \"latitude\": 6.644288,\n \"longitude\": 3.318092\n },\n {\n \"tracker_id\": 500339,\n \"latitude\": 7.075766,\n \"longitude\": 2.999329\n },\n {\n \"tracker_id\": 500320,\n \"latitude\": 6.644459,\n \"longitude\": 3.318066\n },\n {\n \"tracker_id\": 500338,\n \"latitude\": 7.075754,\n \"longitude\": 2.999157\n },\n {\n \"tracker_id\": 500342,\n \"latitude\": 7.052115,\n \"longitude\": 3.000852\n },\n {\n \"tracker_id\": \"GL0061 - SG\",\n \"latitude\": 6.874967,\n \"longitude\": 3.94693\n },\n {\n \"tracker_id\": \"GL0044 - KN\",\n \"latitude\": 6.874994,\n \"longitude\": 3.946909\n },\n {\n \"tracker_id\": \"GL0036 - TD\",\n \"latitude\": 6.874955,\n \"longitude\": 3.946937\n },\n {\n \"tracker_id\": \"GL0066 -TSL\",\n \"latitude\": 6.87501,\n \"longitude\": 3.946914\n },\n {\n \"tracker_id\": 500310,\n \"latitude\": 7.609203,\n \"longitude\": 5.23058\n },\n {\n \"tracker_id\": 500325,\n \"latitude\": 7.798398,\n \"longitude\": 6.74189\n },\n {\n \"tracker_id\": 500330,\n \"latitude\": 7.798534,\n \"longitude\": 6.741883\n },\n {\n \"tracker_id\": 500334,\n \"latitude\": 8.080569,\n \"longitude\": 6.804825\n },\n {\n \"tracker_id\": 500333,\n \"latitude\": 7.798453,\n \"longitude\": 6.74189\n },\n {\n \"tracker_id\": 500336,\n \"latitude\": 11.646988,\n \"longitude\": 8.42657\n },\n {\n \"tracker_id\": 500328,\n \"latitude\": 11.646839,\n \"longitude\": 8.426361\n },\n {\n \"tracker_id\": 500329,\n \"latitude\": 11.647327,\n \"longitude\": 8.491221\n },\n {\n \"tracker_id\": 500304,\n \"latitude\": 13.461527,\n \"longitude\": 5.72697\n },\n {\n \"tracker_id\": 500327,\n \"latitude\": 13.295147,\n \"longitude\": 5.457093\n },\n {\n \"tracker_id\": 500321,\n \"latitude\": 11.820683,\n \"longitude\": 5.347016\n },\n {\n \"tracker_id\": 500309,\n \"latitude\": 9.888095,\n \"longitude\": 6.703483\n },\n {\n \"tracker_id\": 500316,\n \"latitude\": 10.401951,\n \"longitude\": 5.451863\n },\n {\n \"tracker_id\": 500311,\n \"latitude\": 9.888057,\n \"longitude\": 6.70323\n },\n {\n \"tracker_id\": 500315,\n \"latitude\": 10.401932,\n \"longitude\": 5.451947\n },\n {\n \"tracker_id\": 500214,\n \"latitude\": 6.965836,\n \"longitude\": 5.777775\n },\n {\n \"tracker_id\": 500218,\n \"latitude\": 7.657896,\n \"longitude\": 4.199206\n },\n {\n \"tracker_id\": 500220,\n \"latitude\": 8.252919,\n \"longitude\": 3.313092\n },\n {\n \"tracker_id\": 500221,\n \"latitude\": 8.215542,\n \"longitude\": 3.458606\n },\n {\n \"tracker_id\": 500223,\n \"latitude\": 6.695267,\n \"longitude\": 2.880061\n },\n {\n \"tracker_id\": 500212,\n \"latitude\": 8.215367,\n \"longitude\": 3.458715\n },\n {\n \"tracker_id\": 500210,\n \"latitude\": 7.959529,\n \"longitude\": 3.61161\n },\n {\n \"tracker_id\": 500217,\n \"latitude\": 7.23463,\n \"longitude\": 3.03917\n },\n {\n \"tracker_id\": 500222,\n \"latitude\": 8.215512,\n \"longitude\": 3.458643\n },\n {\n \"tracker_id\": 500219,\n \"latitude\": 7.869828,\n \"longitude\": 6.511604\n },\n {\n \"tracker_id\": 500225,\n \"latitude\": 8.624767,\n \"longitude\": 6.585408\n },\n {\n \"tracker_id\": 500413,\n \"latitude\": 8.881926,\n \"longitude\": 7.787763\n },\n {\n \"tracker_id\": 500664,\n \"latitude\": 10.413199,\n \"longitude\": 5.497902\n },\n {\n \"tracker_id\": 500662,\n \"latitude\": 9.558066,\n \"longitude\": 6.593822\n },\n {\n \"tracker_id\": 500604,\n \"latitude\": 8.373895,\n \"longitude\": 7.509122\n },\n {\n \"tracker_id\": 500654,\n \"latitude\": 9.557966,\n \"longitude\": 6.593731\n },\n {\n \"tracker_id\": 500606,\n \"latitude\": 9.746635,\n \"longitude\": 6.047646\n },\n {\n \"tracker_id\": 500656,\n \"latitude\": 9.558084,\n \"longitude\": 6.593931\n },\n {\n \"tracker_id\": 500657,\n \"latitude\": 9.556725,\n \"longitude\": 6.593251\n },\n {\n \"tracker_id\": 500608,\n \"latitude\": 9.674729,\n \"longitude\": 6.446614\n },\n {\n \"tracker_id\": 500661,\n \"latitude\": 8.625638,\n \"longitude\": 6.585723\n },\n {\n \"tracker_id\": 500648,\n \"latitude\": 10.494815,\n \"longitude\": 5.15266\n },\n {\n \"tracker_id\": 500649,\n \"latitude\": 9.557773,\n \"longitude\": 6.593617\n },\n {\n \"tracker_id\": 500603,\n \"latitude\": 10.188827,\n \"longitude\": 5.895937\n },\n {\n \"tracker_id\": 500631,\n \"latitude\": 9.557781,\n \"longitude\": 6.593546\n },\n {\n \"tracker_id\": 500638,\n \"latitude\": 10.134329,\n \"longitude\": 5.879594\n },\n {\n \"tracker_id\": 500651,\n \"latitude\": 10.138193,\n \"longitude\": 5.891274\n },\n {\n \"tracker_id\": 500605,\n \"latitude\": 9.557779,\n \"longitude\": 6.593586\n },\n {\n \"tracker_id\": 500620,\n \"latitude\": 9.558092,\n \"longitude\": 6.593824\n },\n {\n \"tracker_id\": 500642,\n \"latitude\": 10.138128,\n \"longitude\": 5.891375\n },\n {\n \"tracker_id\": 500655,\n \"latitude\": 9.558034,\n \"longitude\": 6.593812\n },\n {\n \"tracker_id\": 500643,\n \"latitude\": 9.221462,\n \"longitude\": 6.391374\n },\n {\n \"tracker_id\": 500644,\n \"latitude\": 9.557721,\n \"longitude\": 6.593602\n },\n {\n \"tracker_id\": 500630,\n \"latitude\": 9.1161,\n \"longitude\": 6.666981\n },\n {\n \"tracker_id\": 500645,\n \"latitude\": 10.134485,\n \"longitude\": 5.87999\n },\n {\n \"tracker_id\": 500659,\n \"latitude\": 9.557879,\n \"longitude\": 6.593495\n },\n {\n \"tracker_id\": 500612,\n \"latitude\": 9.558301,\n \"longitude\": 6.593841\n },\n {\n \"tracker_id\": 500624,\n \"latitude\": 9.557898,\n \"longitude\": 6.593699\n },\n {\n \"tracker_id\": 500609,\n \"latitude\": 10.393151,\n \"longitude\": 5.456304\n },\n {\n \"tracker_id\": 500637,\n \"latitude\": 9.558159,\n \"longitude\": 6.593737\n },\n {\n \"tracker_id\": 500616,\n \"latitude\": 9.558186,\n \"longitude\": 6.593743\n },\n {\n \"tracker_id\": 500639,\n \"latitude\": 8.73978,\n \"longitude\": 6.544249\n },\n {\n \"tracker_id\": 500640,\n \"latitude\": 10.138162,\n \"longitude\": 5.891685\n },\n {\n \"tracker_id\": 500629,\n \"latitude\": 8.726954,\n \"longitude\": 6.433001\n },\n {\n \"tracker_id\": 500658,\n \"latitude\": 9.010872,\n \"longitude\": 6.425835\n },\n {\n \"tracker_id\": 500600,\n \"latitude\": 9.557952,\n \"longitude\": 6.593484\n },\n {\n \"tracker_id\": 500601,\n \"latitude\": 9.557872,\n \"longitude\": 6.593704\n },\n {\n \"tracker_id\": 500660,\n \"latitude\": 10.41311,\n \"longitude\": 5.498037\n },\n {\n \"tracker_id\": 500602,\n \"latitude\": 9.686768,\n \"longitude\": 6.472901\n },\n {\n \"tracker_id\": 500614,\n \"latitude\": 9.558283,\n \"longitude\": 6.593747\n },\n {\n \"tracker_id\": 500633,\n \"latitude\": 9.558236,\n \"longitude\": 6.593731\n },\n {\n \"tracker_id\": 500635,\n \"latitude\": 9.558789,\n \"longitude\": 6.593693\n },\n {\n \"tracker_id\": 500618,\n \"latitude\": 9.0081,\n \"longitude\": 6.6295\n },\n {\n \"tracker_id\": 500619,\n \"latitude\": 9.27351,\n \"longitude\": 7.135207\n },\n {\n \"tracker_id\": 500628,\n \"latitude\": 9.62175,\n \"longitude\": 6.354889\n },\n {\n \"tracker_id\": 500607,\n \"latitude\": 9.558226,\n \"longitude\": 6.594044\n },\n {\n \"tracker_id\": 500611,\n \"latitude\": 10.134045,\n \"longitude\": 5.878808\n },\n {\n \"tracker_id\": 500646,\n \"latitude\": 9.868292,\n \"longitude\": 4.526746\n },\n {\n \"tracker_id\": 500623,\n \"latitude\": 12.141709,\n \"longitude\": 9.44189\n },\n {\n \"tracker_id\": 500647,\n \"latitude\": 9.291884,\n \"longitude\": 7.359137\n },\n {\n \"tracker_id\": 500613,\n \"latitude\": 9.419374,\n \"longitude\": 6.292479\n },\n {\n \"tracker_id\": 500688,\n \"latitude\": 10.582623,\n \"longitude\": 7.450353\n },\n {\n \"tracker_id\": 500690,\n \"latitude\": 10.273663,\n \"longitude\": 11.211156\n },\n {\n \"tracker_id\": 500682,\n \"latitude\": 10.47923,\n \"longitude\": 7.640671\n },\n {\n \"tracker_id\": 500717,\n \"latitude\": 8.860193,\n \"longitude\": 7.89628\n },\n {\n \"tracker_id\": 500763,\n \"latitude\": 6.629813,\n \"longitude\": 9.297036\n },\n {\n \"tracker_id\": 500718,\n \"latitude\": 8.916503,\n \"longitude\": 5.534072\n },\n {\n \"tracker_id\": 500750,\n \"latitude\": 13.563936,\n \"longitude\": 5.742755\n },\n {\n \"tracker_id\": 500719,\n \"latitude\": 8.908101,\n \"longitude\": 5.499106\n },\n {\n \"tracker_id\": 500684,\n \"latitude\": 10.544828,\n \"longitude\": 7.35425\n },\n {\n \"tracker_id\": 500742,\n \"latitude\": 13.289048,\n \"longitude\": 5.418484\n },\n {\n \"tracker_id\": 500680,\n \"latitude\": 6.2449,\n \"longitude\": 8.424954\n },\n {\n \"tracker_id\": 500737,\n \"latitude\": 9.27137,\n \"longitude\": 12.422658\n },\n {\n \"tracker_id\": 500712,\n \"latitude\": 8.846363,\n \"longitude\": 7.363518\n },\n {\n \"tracker_id\": 500705,\n \"latitude\": 10.273807,\n \"longitude\": 11.211107\n },\n {\n \"tracker_id\": 500746,\n \"latitude\": 13.288821,\n \"longitude\": 5.418562\n },\n {\n \"tracker_id\": 500706,\n \"latitude\": 10.273878,\n \"longitude\": 11.211213\n },\n {\n \"tracker_id\": 500748,\n \"latitude\": 13.056558,\n \"longitude\": 5.185185\n },\n {\n \"tracker_id\": 500714,\n \"latitude\": 11.81372,\n \"longitude\": 8.842862\n },\n {\n \"tracker_id\": 500727,\n \"latitude\": 12.451179,\n \"longitude\": 10.051308\n },\n {\n \"tracker_id\": 500674,\n \"latitude\": 9.640134,\n \"longitude\": 6.530086\n },\n {\n \"tracker_id\": 500696,\n \"latitude\": 11.968839,\n \"longitude\": 8.554249\n },\n {\n \"tracker_id\": 500703,\n \"latitude\": 11.602553,\n \"longitude\": 8.432825\n },\n {\n \"tracker_id\": 500666,\n \"latitude\": 9.640176,\n \"longitude\": 6.530065\n },\n {\n \"tracker_id\": 500749,\n \"latitude\": 12.846364,\n \"longitude\": 5.145213\n },\n {\n \"tracker_id\": 500667,\n \"latitude\": 9.640165,\n \"longitude\": 6.529978\n },\n {\n \"tracker_id\": 500764,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 500733,\n \"latitude\": 12.451229,\n \"longitude\": 10.051437\n },\n {\n \"tracker_id\": 500720,\n \"latitude\": 9.046447,\n \"longitude\": 6.582691\n },\n {\n \"tracker_id\": 500740,\n \"latitude\": 11.56986,\n \"longitude\": 7.267694\n },\n {\n \"tracker_id\": 500752,\n \"latitude\": 13.056668,\n \"longitude\": 5.185184\n },\n {\n \"tracker_id\": 500721,\n \"latitude\": 12.698212,\n \"longitude\": 11.489571\n },\n {\n \"tracker_id\": 500710,\n \"latitude\": 7.864761,\n \"longitude\": 6.760677\n },\n {\n \"tracker_id\": 500711,\n \"latitude\": 7.864775,\n \"longitude\": 6.760673\n },\n {\n \"tracker_id\": 500736,\n \"latitude\": 9.146568,\n \"longitude\": 9.794721\n },\n {\n \"tracker_id\": 500685,\n \"latitude\": 9.377526,\n \"longitude\": 8.280366\n },\n {\n \"tracker_id\": 500686,\n \"latitude\": 10.621833,\n \"longitude\": 7.46505\n },\n {\n \"tracker_id\": 500738,\n \"latitude\": 9.271106,\n \"longitude\": 12.422693\n },\n {\n \"tracker_id\": 500725,\n \"latitude\": 11.516018,\n \"longitude\": 7.340286\n },\n {\n \"tracker_id\": 500758,\n \"latitude\": 12.152756,\n \"longitude\": 6.75327\n },\n {\n \"tracker_id\": 500672,\n \"latitude\": 9.640176,\n \"longitude\": 6.529964\n },\n {\n \"tracker_id\": 500726,\n \"latitude\": 9.046484,\n \"longitude\": 6.582667\n },\n {\n \"tracker_id\": 500673,\n \"latitude\": 9.64018,\n \"longitude\": 6.529961\n },\n {\n \"tracker_id\": 500765,\n \"latitude\": 6.435539,\n \"longitude\": 2.892512\n },\n {\n \"tracker_id\": 500728,\n \"latitude\": 11.569836,\n \"longitude\": 7.267691\n },\n {\n \"tracker_id\": 500701,\n \"latitude\": 11.968898,\n \"longitude\": 8.554252\n },\n {\n \"tracker_id\": 500729,\n \"latitude\": 9.622937,\n \"longitude\": 6.507742\n },\n {\n \"tracker_id\": 500683,\n \"latitude\": 10.124303,\n \"longitude\": 8.376303\n },\n {\n \"tracker_id\": 500676,\n \"latitude\": 6.506377,\n \"longitude\": 6.954368\n },\n {\n \"tracker_id\": 500730,\n \"latitude\": 12.451125,\n \"longitude\": 10.051388\n },\n {\n \"tracker_id\": 500716,\n \"latitude\": 8.851391,\n \"longitude\": 7.892288\n },\n {\n \"tracker_id\": 500677,\n \"latitude\": 6.520494,\n \"longitude\": 6.951325\n },\n {\n \"tracker_id\": 500704,\n \"latitude\": 11.968859,\n \"longitude\": 8.554201\n },\n {\n \"tracker_id\": 500762,\n \"latitude\": 6.244869,\n \"longitude\": 8.424977\n },\n {\n \"tracker_id\": 500698,\n \"latitude\": 11.968843,\n \"longitude\": 8.554223\n },\n {\n \"tracker_id\": 500732,\n \"latitude\": 12.451111,\n \"longitude\": 10.051471\n },\n {\n \"tracker_id\": 500700,\n \"latitude\": 11.968821,\n \"longitude\": 8.554155\n },\n {\n \"tracker_id\": 500769,\n \"latitude\": 7.364253,\n \"longitude\": 7.10637\n },\n {\n \"tracker_id\": 500678,\n \"latitude\": 6.629865,\n \"longitude\": 9.29699\n },\n {\n \"tracker_id\": 500670,\n \"latitude\": 9.640169,\n \"longitude\": 6.529955\n },\n {\n \"tracker_id\": 500743,\n \"latitude\": 13.288888,\n \"longitude\": 5.418526\n },\n {\n \"tracker_id\": 500756,\n \"latitude\": 12.152761,\n \"longitude\": 6.753319\n },\n {\n \"tracker_id\": 500744,\n \"latitude\": 13.498817,\n \"longitude\": 5.709788\n },\n {\n \"tracker_id\": 500671,\n \"latitude\": 9.640159,\n \"longitude\": 6.530054\n },\n {\n \"tracker_id\": 500745,\n \"latitude\": 13.288911,\n \"longitude\": 5.41855\n },\n {\n \"tracker_id\": 500713,\n \"latitude\": 11.602475,\n \"longitude\": 8.432792\n },\n {\n \"tracker_id\": 500768,\n \"latitude\": 9.113154,\n \"longitude\": 12.883545\n },\n {\n \"tracker_id\": 500681,\n \"latitude\": 9.219701,\n \"longitude\": 8.444618\n },\n {\n \"tracker_id\": 500708,\n \"latitude\": 9.271228,\n \"longitude\": 12.422718\n },\n {\n \"tracker_id\": 500766,\n \"latitude\": 6.435342,\n \"longitude\": 2.892583\n },\n {\n \"tracker_id\": 500675,\n \"latitude\": 6.519278,\n \"longitude\": 6.944047\n },\n {\n \"tracker_id\": 500767,\n \"latitude\": 6.435332,\n \"longitude\": 2.892212\n },\n {\n \"tracker_id\": 500665,\n \"latitude\": 9.640073,\n \"longitude\": 6.529984\n },\n {\n \"tracker_id\": 500715,\n \"latitude\": 9.476859,\n \"longitude\": 6.394968\n },\n {\n \"tracker_id\": 500702,\n \"latitude\": 11.968857,\n \"longitude\": 8.554203\n },\n {\n \"tracker_id\": 500697,\n \"latitude\": 11.968906,\n \"longitude\": 8.554276\n },\n {\n \"tracker_id\": 500731,\n \"latitude\": 12.451091,\n \"longitude\": 10.051398\n },\n {\n \"tracker_id\": 500699,\n \"latitude\": 11.968874,\n \"longitude\": 8.554286\n },\n {\n \"tracker_id\": 500709,\n \"latitude\": 9.271199,\n \"longitude\": 12.422689\n },\n {\n \"tracker_id\": 500739,\n \"latitude\": 11.569884,\n \"longitude\": 7.267702\n },\n {\n \"tracker_id\": 500668,\n \"latitude\": 9.640161,\n \"longitude\": 6.530033\n },\n {\n \"tracker_id\": 500751,\n \"latitude\": 13.056425,\n \"longitude\": 5.185298\n },\n {\n \"tracker_id\": 500734,\n \"latitude\": 12.451225,\n \"longitude\": 10.051372\n },\n {\n \"tracker_id\": 500741,\n \"latitude\": 9.046501,\n \"longitude\": 6.582633\n },\n {\n \"tracker_id\": 500669,\n \"latitude\": 9.640154,\n \"longitude\": 6.529952\n },\n {\n \"tracker_id\": 500735,\n \"latitude\": 10.068671,\n \"longitude\": 8.650641\n },\n {\n \"tracker_id\": 500722,\n \"latitude\": 9.046522,\n \"longitude\": 6.582801\n },\n {\n \"tracker_id\": 500724,\n \"latitude\": 9.046483,\n \"longitude\": 6.582637\n },\n {\n \"tracker_id\": 500687,\n \"latitude\": 10.425245,\n \"longitude\": 8.675178\n },\n {\n \"tracker_id\": 500747,\n \"latitude\": 13.056664,\n \"longitude\": 5.185115\n },\n {\n \"tracker_id\": 500707,\n \"latitude\": 9.27106,\n \"longitude\": 12.422682\n },\n {\n \"tracker_id\": 501127,\n \"latitude\": 11.717757,\n \"longitude\": 11.966349\n },\n {\n \"tracker_id\": 501213,\n \"latitude\": 10.280604,\n \"longitude\": 11.189648\n },\n {\n \"tracker_id\": 501272,\n \"latitude\": 11.717932,\n \"longitude\": 11.966269\n },\n {\n \"tracker_id\": 501165,\n \"latitude\": 11.86179,\n \"longitude\": 13.209761\n },\n {\n \"tracker_id\": 501197,\n \"latitude\": 9.272136,\n \"longitude\": 12.415394\n },\n {\n \"tracker_id\": 501142,\n \"latitude\": 10.28079,\n \"longitude\": 11.189417\n },\n {\n \"tracker_id\": 501092,\n \"latitude\": 10.280958,\n \"longitude\": 11.189579\n },\n {\n \"tracker_id\": 501094,\n \"latitude\": 9.272465,\n \"longitude\": 12.415162\n },\n {\n \"tracker_id\": 501220,\n \"latitude\": 9.272678,\n \"longitude\": 12.415388\n },\n {\n \"tracker_id\": 501168,\n \"latitude\": 6.45039,\n \"longitude\": 3.264949\n },\n {\n \"tracker_id\": 501095,\n \"latitude\": 6.447035,\n \"longitude\": 3.287171\n },\n {\n \"tracker_id\": 501170,\n \"latitude\": 10.280566,\n \"longitude\": 11.189723\n },\n {\n \"tracker_id\": 501066,\n \"latitude\": 10.280766,\n \"longitude\": 11.189573\n },\n {\n \"tracker_id\": 501147,\n \"latitude\": 10.280607,\n \"longitude\": 11.189716\n },\n {\n \"tracker_id\": 501252,\n \"latitude\": 9.272059,\n \"longitude\": 12.415413\n },\n {\n \"tracker_id\": 501172,\n \"latitude\": 9.272646,\n \"longitude\": 12.415194\n },\n {\n \"tracker_id\": 501148,\n \"latitude\": 11.717688,\n \"longitude\": 11.966325\n },\n {\n \"tracker_id\": 501253,\n \"latitude\": 10.280991,\n \"longitude\": 11.189329\n },\n {\n \"tracker_id\": 501293,\n \"latitude\": 11.717709,\n \"longitude\": 11.966303\n },\n {\n \"tracker_id\": 501067,\n \"latitude\": 11.972252,\n \"longitude\": 8.551629\n },\n {\n \"tracker_id\": 501259,\n \"latitude\": 9.560951,\n \"longitude\": 6.486387\n },\n {\n \"tracker_id\": 501068,\n \"latitude\": 11.972429,\n \"longitude\": 8.551748\n },\n {\n \"tracker_id\": 501200,\n \"latitude\": 11.717608,\n \"longitude\": 11.966572\n },\n {\n \"tracker_id\": 501284,\n \"latitude\": 10.281033,\n \"longitude\": 11.189242\n },\n {\n \"tracker_id\": 501285,\n \"latitude\": 11.972293,\n \"longitude\": 8.551674\n },\n {\n \"tracker_id\": 501233,\n \"latitude\": 10.280987,\n \"longitude\": 11.189266\n },\n {\n \"tracker_id\": 501101,\n \"latitude\": 9.272264,\n \"longitude\": 12.415044\n },\n {\n \"tracker_id\": 501153,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 501234,\n \"latitude\": 10.281084,\n \"longitude\": 11.189395\n },\n {\n \"tracker_id\": 501131,\n \"latitude\": 11.861786,\n \"longitude\": 13.20975\n },\n {\n \"tracker_id\": 501154,\n \"latitude\": 10.288188,\n \"longitude\": 9.847199\n },\n {\n \"tracker_id\": 501071,\n \"latitude\": 11.972442,\n \"longitude\": 8.551648\n },\n {\n \"tracker_id\": 501155,\n \"latitude\": 6.450379,\n \"longitude\": 3.264952\n },\n {\n \"tracker_id\": 501264,\n \"latitude\": 11.861792,\n \"longitude\": 13.209787\n },\n {\n \"tracker_id\": 501236,\n \"latitude\": 10.280543,\n \"longitude\": 11.189608\n },\n {\n \"tracker_id\": 501113,\n \"latitude\": 10.2812,\n \"longitude\": 11.189641\n },\n {\n \"tracker_id\": 501114,\n \"latitude\": 9.272516,\n \"longitude\": 12.415245\n },\n {\n \"tracker_id\": 501288,\n \"latitude\": 10.288172,\n \"longitude\": 9.847168\n },\n {\n \"tracker_id\": 501133,\n \"latitude\": 4.951723,\n \"longitude\": 8.001175\n },\n {\n \"tracker_id\": 501182,\n \"latitude\": 9.272419,\n \"longitude\": 12.415302\n },\n {\n \"tracker_id\": 501289,\n \"latitude\": 11.717622,\n \"longitude\": 11.966412\n },\n {\n \"tracker_id\": 501204,\n \"latitude\": 10.280956,\n \"longitude\": 11.189608\n },\n {\n \"tracker_id\": 501055,\n \"latitude\": 10.28097,\n \"longitude\": 11.189374\n },\n {\n \"tracker_id\": 501184,\n \"latitude\": 11.861766,\n \"longitude\": 13.209752\n },\n {\n \"tracker_id\": 501185,\n \"latitude\": 6.450445,\n \"longitude\": 3.265085\n },\n {\n \"tracker_id\": 501056,\n \"latitude\": 11.63796,\n \"longitude\": 8.406133\n },\n {\n \"tracker_id\": 501119,\n \"latitude\": 9.272408,\n \"longitude\": 12.415182\n },\n {\n \"tracker_id\": 501083,\n \"latitude\": 11.861883,\n \"longitude\": 13.209743\n },\n {\n \"tracker_id\": 501076,\n \"latitude\": 10.281216,\n \"longitude\": 11.189592\n },\n {\n \"tracker_id\": 501162,\n \"latitude\": 9.272419,\n \"longitude\": 12.415128\n },\n {\n \"tracker_id\": 501189,\n \"latitude\": 10.280613,\n \"longitude\": 11.189662\n },\n {\n \"tracker_id\": 501124,\n \"latitude\": 11.861814,\n \"longitude\": 13.209771\n },\n {\n \"tracker_id\": 501086,\n \"latitude\": 10.280657,\n \"longitude\": 11.189593\n },\n {\n \"tracker_id\": 501211,\n \"latitude\": 6.463589,\n \"longitude\": 3.31845\n },\n {\n \"tracker_id\": 501193,\n \"latitude\": 10.280615,\n \"longitude\": 11.189599\n },\n {\n \"tracker_id\": 501163,\n \"latitude\": 10.288159,\n \"longitude\": 9.847106\n },\n {\n \"tracker_id\": 501139,\n \"latitude\": 9.272484,\n \"longitude\": 12.415328\n },\n {\n \"tracker_id\": 501060,\n \"latitude\": 11.972118,\n \"longitude\": 8.551739\n },\n {\n \"tracker_id\": 501214,\n \"latitude\": 9.272507,\n \"longitude\": 12.415094\n },\n {\n \"tracker_id\": 501164,\n \"latitude\": 10.280695,\n \"longitude\": 11.189669\n },\n {\n \"tracker_id\": 501196,\n \"latitude\": 10.280589,\n \"longitude\": 11.189714\n },\n {\n \"tracker_id\": 501274,\n \"latitude\": 11.717742,\n \"longitude\": 11.966331\n },\n {\n \"tracker_id\": 501062,\n \"latitude\": 11.972239,\n \"longitude\": 8.551578\n },\n {\n \"tracker_id\": 501216,\n \"latitude\": 6.463818,\n \"longitude\": 3.318748\n },\n {\n \"tracker_id\": 501091,\n \"latitude\": 6.854642,\n \"longitude\": 3.78092\n },\n {\n \"tracker_id\": 501052,\n \"latitude\": 11.972229,\n \"longitude\": 8.551624\n },\n {\n \"tracker_id\": 501217,\n \"latitude\": 10.281071,\n \"longitude\": 11.189368\n },\n {\n \"tracker_id\": 501249,\n \"latitude\": 6.450566,\n \"longitude\": 3.265011\n },\n {\n \"tracker_id\": 501199,\n \"latitude\": 6.463979,\n \"longitude\": 3.318478\n },\n {\n \"tracker_id\": 501250,\n \"latitude\": 11.861803,\n \"longitude\": 13.209698\n },\n {\n \"tracker_id\": 501064,\n \"latitude\": 11.701151,\n \"longitude\": 8.543084\n },\n {\n \"tracker_id\": 501276,\n \"latitude\": 10.288278,\n \"longitude\": 9.847174\n },\n {\n \"tracker_id\": 501065,\n \"latitude\": 12.097068,\n \"longitude\": 8.88778\n },\n {\n \"tracker_id\": 501227,\n \"latitude\": 6.450541,\n \"longitude\": 3.265049\n },\n {\n \"tracker_id\": 501222,\n \"latitude\": 9.272179,\n \"longitude\": 12.415433\n },\n {\n \"tracker_id\": 501228,\n \"latitude\": 10.288175,\n \"longitude\": 9.847274\n },\n {\n \"tracker_id\": 501279,\n \"latitude\": 11.71789,\n \"longitude\": 11.966249\n },\n {\n \"tracker_id\": 501171,\n \"latitude\": 6.854546,\n \"longitude\": 3.780898\n },\n {\n \"tracker_id\": 501280,\n \"latitude\": 5.818537,\n \"longitude\": 7.876841\n },\n {\n \"tracker_id\": 501281,\n \"latitude\": 9.272447,\n \"longitude\": 12.415243\n },\n {\n \"tracker_id\": 501173,\n \"latitude\": 10.280756,\n \"longitude\": 11.18971\n },\n {\n \"tracker_id\": 501230,\n \"latitude\": 10.288263,\n \"longitude\": 9.847112\n },\n {\n \"tracker_id\": 501260,\n \"latitude\": 11.8618,\n \"longitude\": 13.209797\n },\n {\n \"tracker_id\": 501152,\n \"latitude\": 9.272423,\n \"longitude\": 12.415309\n },\n {\n \"tracker_id\": 501070,\n \"latitude\": 11.972344,\n \"longitude\": 8.551728\n },\n {\n \"tracker_id\": 501177,\n \"latitude\": 10.280657,\n \"longitude\": 11.189633\n },\n {\n \"tracker_id\": 501111,\n \"latitude\": 9.272463,\n \"longitude\": 12.415227\n },\n {\n \"tracker_id\": 501202,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 501102,\n \"latitude\": 10.280593,\n \"longitude\": 11.189444\n },\n {\n \"tracker_id\": 501081,\n \"latitude\": 11.861744,\n \"longitude\": 13.209833\n },\n {\n \"tracker_id\": 501103,\n \"latitude\": 9.271889,\n \"longitude\": 12.414899\n },\n {\n \"tracker_id\": 501130,\n \"latitude\": 9.27268,\n \"longitude\": 12.41503\n },\n {\n \"tracker_id\": 501238,\n \"latitude\": 6.450477,\n \"longitude\": 3.264975\n },\n {\n \"tracker_id\": 501132,\n \"latitude\": 6.450436,\n \"longitude\": 3.264906\n },\n {\n \"tracker_id\": 501105,\n \"latitude\": 10.288224,\n \"longitude\": 9.847192\n },\n {\n \"tracker_id\": 501239,\n \"latitude\": 6.450405,\n \"longitude\": 3.264992\n },\n {\n \"tracker_id\": 501106,\n \"latitude\": 11.7178,\n \"longitude\": 11.966286\n },\n {\n \"tracker_id\": 501240,\n \"latitude\": 6.450463,\n \"longitude\": 3.26506\n },\n {\n \"tracker_id\": 501268,\n \"latitude\": 9.271913,\n \"longitude\": 12.415096\n },\n {\n \"tracker_id\": 501108,\n \"latitude\": 6.302215,\n \"longitude\": 5.480614\n },\n {\n \"tracker_id\": 501074,\n \"latitude\": 10.280647,\n \"longitude\": 11.189709\n },\n {\n \"tracker_id\": 501270,\n \"latitude\": 11.861622,\n \"longitude\": 13.209848\n },\n {\n \"tracker_id\": 501206,\n \"latitude\": 6.463884,\n \"longitude\": 3.318904\n },\n {\n \"tracker_id\": 501057,\n \"latitude\": 10.28059,\n \"longitude\": 11.189713\n },\n {\n \"tracker_id\": 501188,\n \"latitude\": 10.288177,\n \"longitude\": 9.847161\n },\n {\n \"tracker_id\": 501121,\n \"latitude\": 9.272538,\n \"longitude\": 12.415165\n },\n {\n \"tracker_id\": 501290,\n \"latitude\": 11.717713,\n \"longitude\": 11.966365\n },\n {\n \"tracker_id\": 501208,\n \"latitude\": 10.280772,\n \"longitude\": 11.189371\n },\n {\n \"tracker_id\": 501122,\n \"latitude\": 9.272419,\n \"longitude\": 12.415151\n },\n {\n \"tracker_id\": 501085,\n \"latitude\": 9.272416,\n \"longitude\": 12.415105\n },\n {\n \"tracker_id\": 501058,\n \"latitude\": 12.123614,\n \"longitude\": 9.285573\n },\n {\n \"tracker_id\": 501125,\n \"latitude\": 10.281191,\n \"longitude\": 11.189628\n },\n {\n \"tracker_id\": 501243,\n \"latitude\": 10.288142,\n \"longitude\": 9.846409\n },\n {\n \"tracker_id\": 501212,\n \"latitude\": 10.28064,\n \"longitude\": 11.189557\n },\n {\n \"tracker_id\": 501245,\n \"latitude\": 11.717655,\n \"longitude\": 11.966458\n },\n {\n \"tracker_id\": 501128,\n \"latitude\": 10.280947,\n \"longitude\": 11.189646\n },\n {\n \"tracker_id\": 501089,\n \"latitude\": 10.281009,\n \"longitude\": 11.189319\n },\n {\n \"tracker_id\": 501061,\n \"latitude\": 11.972097,\n \"longitude\": 8.551757\n },\n {\n \"tracker_id\": 501140,\n \"latitude\": 10.281163,\n \"longitude\": 11.189755\n },\n {\n \"tracker_id\": 501090,\n \"latitude\": 9.272441,\n \"longitude\": 12.415101\n },\n {\n \"tracker_id\": 501141,\n \"latitude\": 10.280923,\n \"longitude\": 11.189448\n },\n {\n \"tracker_id\": 501248,\n \"latitude\": 10.28091,\n \"longitude\": 11.189341\n },\n {\n \"tracker_id\": 501143,\n \"latitude\": 9.272461,\n \"longitude\": 12.415125\n },\n {\n \"tracker_id\": 501144,\n \"latitude\": 9.272255,\n \"longitude\": 12.415372\n },\n {\n \"tracker_id\": 501294,\n \"latitude\": 11.861827,\n \"longitude\": 13.209779\n },\n {\n \"tracker_id\": 501218,\n \"latitude\": 10.280994,\n \"longitude\": 11.189356\n },\n {\n \"tracker_id\": 501219,\n \"latitude\": 9.272675,\n \"longitude\": 12.415364\n },\n {\n \"tracker_id\": 501145,\n \"latitude\": 10.288188,\n \"longitude\": 9.847099\n },\n {\n \"tracker_id\": 501050,\n \"latitude\": 11.972416,\n \"longitude\": 8.551766\n },\n {\n \"tracker_id\": 501277,\n \"latitude\": 11.638802,\n \"longitude\": 8.441979\n },\n {\n \"tracker_id\": 501278,\n \"latitude\": 11.861877,\n \"longitude\": 13.209761\n },\n {\n \"tracker_id\": 501051,\n \"latitude\": 8.904477,\n \"longitude\": 11.356663\n },\n {\n \"tracker_id\": 501097,\n \"latitude\": 10.280627,\n \"longitude\": 11.189605\n },\n {\n \"tracker_id\": 501223,\n \"latitude\": 10.281013,\n \"longitude\": 11.189425\n },\n {\n \"tracker_id\": 501229,\n \"latitude\": 10.288191,\n \"longitude\": 9.847299\n },\n {\n \"tracker_id\": 501098,\n \"latitude\": 9.272164,\n \"longitude\": 12.415375\n },\n {\n \"tracker_id\": 501225,\n \"latitude\": 8.904482,\n \"longitude\": 11.356625\n },\n {\n \"tracker_id\": 501282,\n \"latitude\": 9.272489,\n \"longitude\": 12.41522\n },\n {\n \"tracker_id\": 501254,\n \"latitude\": 6.450375,\n \"longitude\": 3.264897\n },\n {\n \"tracker_id\": 501258,\n \"latitude\": 11.717772,\n \"longitude\": 11.966289\n },\n {\n \"tracker_id\": 501150,\n \"latitude\": 10.281043,\n \"longitude\": 11.18945\n },\n {\n \"tracker_id\": 501256,\n \"latitude\": 6.450563,\n \"longitude\": 3.265053\n },\n {\n \"tracker_id\": 501099,\n \"latitude\": 6.450496,\n \"longitude\": 3.265053\n },\n {\n \"tracker_id\": 501175,\n \"latitude\": 7.53242,\n \"longitude\": 5.772549\n },\n {\n \"tracker_id\": 501151,\n \"latitude\": 11.717647,\n \"longitude\": 11.966281\n },\n {\n \"tracker_id\": 501232,\n \"latitude\": 10.281069,\n \"longitude\": 11.189343\n },\n {\n \"tracker_id\": 501176,\n \"latitude\": 10.280758,\n \"longitude\": 11.189587\n },\n {\n \"tracker_id\": 501129,\n \"latitude\": 10.288145,\n \"longitude\": 9.847154\n },\n {\n \"tracker_id\": 501286,\n \"latitude\": 11.717611,\n \"longitude\": 11.966358\n },\n {\n \"tracker_id\": 501263,\n \"latitude\": 9.272637,\n \"longitude\": 12.415046\n },\n {\n \"tracker_id\": 501178,\n \"latitude\": 9.272419,\n \"longitude\": 12.415337\n },\n {\n \"tracker_id\": 501104,\n \"latitude\": 10.288202,\n \"longitude\": 9.847112\n },\n {\n \"tracker_id\": 501287,\n \"latitude\": 4.951668,\n \"longitude\": 8.001185\n },\n {\n \"tracker_id\": 501203,\n \"latitude\": 11.717806,\n \"longitude\": 11.966233\n },\n {\n \"tracker_id\": 501134,\n \"latitude\": 10.280904,\n \"longitude\": 11.189183\n },\n {\n \"tracker_id\": 501116,\n \"latitude\": 10.288172,\n \"longitude\": 9.847212\n },\n {\n \"tracker_id\": 501183,\n \"latitude\": 8.904467,\n \"longitude\": 11.356697\n },\n {\n \"tracker_id\": 501160,\n \"latitude\": 6.463676,\n \"longitude\": 3.318944\n },\n {\n \"tracker_id\": 501241,\n \"latitude\": 10.288158,\n \"longitude\": 9.847203\n },\n {\n \"tracker_id\": 501135,\n \"latitude\": 7.884785,\n \"longitude\": 5.578443\n },\n {\n \"tracker_id\": 501161,\n \"latitude\": 6.450526,\n \"longitude\": 3.265156\n },\n {\n \"tracker_id\": 501109,\n \"latitude\": 10.280583,\n \"longitude\": 11.189435\n },\n {\n \"tracker_id\": 501075,\n \"latitude\": 10.28118,\n \"longitude\": 11.189336\n },\n {\n \"tracker_id\": 501120,\n \"latitude\": 9.272697,\n \"longitude\": 12.415168\n },\n {\n \"tracker_id\": 501187,\n \"latitude\": 6.463854,\n \"longitude\": 3.31885\n },\n {\n \"tracker_id\": 501138,\n \"latitude\": 10.280884,\n \"longitude\": 11.189249\n },\n {\n \"tracker_id\": 501271,\n \"latitude\": 6.464077,\n \"longitude\": 3.318728\n },\n {\n \"tracker_id\": 501077,\n \"latitude\": 8.904472,\n \"longitude\": 11.35667\n },\n {\n \"tracker_id\": 501190,\n \"latitude\": 10.28066,\n \"longitude\": 11.18958\n },\n {\n \"tracker_id\": 501191,\n \"latitude\": 8.904307,\n \"longitude\": 11.356622\n },\n {\n \"tracker_id\": 501210,\n \"latitude\": 10.288259,\n \"longitude\": 9.84724\n },\n {\n \"tracker_id\": 501078,\n \"latitude\": 9.272489,\n \"longitude\": 12.415082\n },\n {\n \"tracker_id\": 501192,\n \"latitude\": 10.280918,\n \"longitude\": 11.189207\n },\n {\n \"tracker_id\": 501088,\n \"latitude\": 9.272445,\n \"longitude\": 12.415178\n },\n {\n \"tracker_id\": 501244,\n \"latitude\": 10.281013,\n \"longitude\": 11.189409\n },\n {\n \"tracker_id\": 501194,\n \"latitude\": 8.904481,\n \"longitude\": 11.356719\n },\n {\n \"tracker_id\": 501246,\n \"latitude\": 11.717639,\n \"longitude\": 11.966386\n },\n {\n \"tracker_id\": 501080,\n \"latitude\": 6.450455,\n \"longitude\": 3.264921\n },\n {\n \"tracker_id\": 501195,\n \"latitude\": 10.280578,\n \"longitude\": 11.189429\n },\n {\n \"tracker_id\": 501247,\n \"latitude\": 9.272146,\n \"longitude\": 12.415398\n },\n {\n \"tracker_id\": 501166,\n \"latitude\": 9.272385,\n \"longitude\": 12.415124\n },\n {\n \"tracker_id\": 501063,\n \"latitude\": 11.892226,\n \"longitude\": 8.848892\n },\n {\n \"tracker_id\": 501275,\n \"latitude\": 11.717628,\n \"longitude\": 11.966334\n },\n {\n \"tracker_id\": 501221,\n \"latitude\": 10.288167,\n \"longitude\": 9.8471\n },\n {\n \"tracker_id\": 501169,\n \"latitude\": 10.281056,\n \"longitude\": 11.18962\n },\n {\n \"tracker_id\": 501096,\n \"latitude\": 6.450409,\n \"longitude\": 3.264892\n },\n {\n \"tracker_id\": 501146,\n \"latitude\": 6.854501,\n \"longitude\": 3.780973\n },\n {\n \"tracker_id\": 501251,\n \"latitude\": 9.272141,\n \"longitude\": 12.415417\n },\n {\n \"tracker_id\": 501149,\n \"latitude\": 6.450452,\n \"longitude\": 3.265026\n },\n {\n \"tracker_id\": 501231,\n \"latitude\": 6.4504,\n \"longitude\": 3.264986\n },\n {\n \"tracker_id\": 501174,\n \"latitude\": 9.272608,\n \"longitude\": 12.415159\n },\n {\n \"tracker_id\": 501226,\n \"latitude\": 11.717736,\n \"longitude\": 11.966256\n },\n {\n \"tracker_id\": 501283,\n \"latitude\": 9.272491,\n \"longitude\": 12.41529\n },\n {\n \"tracker_id\": 501257,\n \"latitude\": 6.450337,\n \"longitude\": 3.264908\n },\n {\n \"tracker_id\": 501069,\n \"latitude\": 12.095773,\n \"longitude\": 9.161125\n },\n {\n \"tracker_id\": 501100,\n \"latitude\": 10.288226,\n \"longitude\": 9.847093\n },\n {\n \"tracker_id\": 501261,\n \"latitude\": 11.861835,\n \"longitude\": 13.209785\n },\n {\n \"tracker_id\": 501201,\n \"latitude\": 10.281023,\n \"longitude\": 11.189212\n },\n {\n \"tracker_id\": 501262,\n \"latitude\": 11.71762,\n \"longitude\": 11.966461\n },\n {\n \"tracker_id\": 501073,\n \"latitude\": 6.450469,\n \"longitude\": 3.265039\n },\n {\n \"tracker_id\": 501292,\n \"latitude\": 6.854852,\n \"longitude\": 3.780706\n },\n {\n \"tracker_id\": 501235,\n \"latitude\": 9.272439,\n \"longitude\": 12.415143\n },\n {\n \"tracker_id\": 501179,\n \"latitude\": 9.272379,\n \"longitude\": 12.415249\n },\n {\n \"tracker_id\": 501053,\n \"latitude\": 11.647137,\n \"longitude\": 8.426614\n },\n {\n \"tracker_id\": 501072,\n \"latitude\": 11.883936,\n \"longitude\": 8.80689\n },\n {\n \"tracker_id\": 501237,\n \"latitude\": 9.272221,\n \"longitude\": 12.415318\n },\n {\n \"tracker_id\": 501157,\n \"latitude\": 9.272093,\n \"longitude\": 12.415389\n },\n {\n \"tracker_id\": 501181,\n \"latitude\": 10.281081,\n \"longitude\": 11.189306\n },\n {\n \"tracker_id\": 501158,\n \"latitude\": 10.281087,\n \"longitude\": 11.189352\n },\n {\n \"tracker_id\": 501266,\n \"latitude\": 8.90447,\n \"longitude\": 11.356657\n },\n {\n \"tracker_id\": 501115,\n \"latitude\": 10.28127,\n \"longitude\": 11.189553\n },\n {\n \"tracker_id\": 501267,\n \"latitude\": 9.272682,\n \"longitude\": 12.415149\n },\n {\n \"tracker_id\": 501159,\n \"latitude\": 10.280955,\n \"longitude\": 11.189352\n },\n {\n \"tracker_id\": 501117,\n \"latitude\": 9.272485,\n \"longitude\": 12.41513\n },\n {\n \"tracker_id\": 501269,\n \"latitude\": 5.893655,\n \"longitude\": 7.919703\n },\n {\n \"tracker_id\": 5012045,\n \"latitude\": 6.450494,\n \"longitude\": 3.26484\n },\n {\n \"tracker_id\": 501118,\n \"latitude\": 6.464011,\n \"longitude\": 3.318701\n },\n {\n \"tracker_id\": 501082,\n \"latitude\": 6.463681,\n \"longitude\": 3.318692\n },\n {\n \"tracker_id\": 501186,\n \"latitude\": 9.272524,\n \"longitude\": 12.415209\n },\n {\n \"tracker_id\": 501207,\n \"latitude\": 10.288194,\n \"longitude\": 9.847159\n },\n {\n \"tracker_id\": 501123,\n \"latitude\": 10.288208,\n \"longitude\": 9.847114\n },\n {\n \"tracker_id\": 501209,\n \"latitude\": 9.272639,\n \"longitude\": 12.415255\n },\n {\n \"tracker_id\": 501079,\n \"latitude\": 8.844651,\n \"longitude\": 3.746579\n },\n {\n \"tracker_id\": 501242,\n \"latitude\": 6.450574,\n \"longitude\": 3.264929\n },\n {\n \"tracker_id\": 501059,\n \"latitude\": 11.972222,\n \"longitude\": 8.551624\n },\n {\n \"tracker_id\": 501087,\n \"latitude\": 7.658728,\n \"longitude\": 4.199806\n },\n {\n \"tracker_id\": 500882,\n \"latitude\": 22.463141,\n \"longitude\": 90.045838\n },\n {\n \"tracker_id\": 500885,\n \"latitude\": 22.262772,\n \"longitude\": 90.271538\n },\n {\n \"tracker_id\": 500886,\n \"latitude\": 21.999001,\n \"longitude\": 90.304382\n },\n {\n \"tracker_id\": 500889,\n \"latitude\": 22.626377,\n \"longitude\": 90.67973\n },\n {\n \"tracker_id\": 500934,\n \"latitude\": 23.094478,\n \"longitude\": 90.187167\n },\n {\n \"tracker_id\": 500935,\n \"latitude\": 22.619343,\n \"longitude\": 90.647863\n },\n {\n \"tracker_id\": 500872,\n \"latitude\": 22.009454,\n \"longitude\": 90.090818\n },\n {\n \"tracker_id\": 500874,\n \"latitude\": 22.213903,\n \"longitude\": 90.75858\n },\n {\n \"tracker_id\": 500878,\n \"latitude\": 23.16606,\n \"longitude\": 89.358639\n },\n {\n \"tracker_id\": 500880,\n \"latitude\": 22.400704,\n \"longitude\": 90.16151\n },\n {\n \"tracker_id\": 500917,\n \"latitude\": 23.920304,\n \"longitude\": 90.322497\n },\n {\n \"tracker_id\": 500891,\n \"latitude\": 22.212087,\n \"longitude\": 90.323659\n },\n {\n \"tracker_id\": 500870,\n \"latitude\": 22.098305,\n \"longitude\": 90.053242\n },\n {\n \"tracker_id\": 500871,\n \"latitude\": 22.149349,\n \"longitude\": 90.280814\n },\n {\n \"tracker_id\": 500876,\n \"latitude\": 23.379681,\n \"longitude\": 90.175017\n },\n {\n \"tracker_id\": 500881,\n \"latitude\": 23.041759,\n \"longitude\": 89.001695\n },\n {\n \"tracker_id\": 500864,\n \"latitude\": 22.177692,\n \"longitude\": 90.285783\n },\n {\n \"tracker_id\": 500938,\n \"latitude\": 22.003786,\n \"longitude\": 90.29214\n },\n {\n \"tracker_id\": 500877,\n \"latitude\": 25.241882,\n \"longitude\": 89.760177\n },\n {\n \"tracker_id\": 500911,\n \"latitude\": 23.139408,\n \"longitude\": 89.183789\n },\n {\n \"tracker_id\": 500888,\n \"latitude\": 22.107884,\n \"longitude\": 90.694714\n },\n {\n \"tracker_id\": 500910,\n \"latitude\": 22.424351,\n \"longitude\": 90.828054\n },\n {\n \"tracker_id\": 500879,\n \"latitude\": 23.205968,\n \"longitude\": 89.401695\n },\n {\n \"tracker_id\": 500822,\n \"latitude\": 5.563597,\n \"longitude\": -0.221577\n },\n {\n \"tracker_id\": 500823,\n \"latitude\": 5.563406,\n \"longitude\": -0.221551\n },\n {\n \"tracker_id\": 500818,\n \"latitude\": 5.563338,\n \"longitude\": -0.221498\n },\n {\n \"tracker_id\": 500797,\n \"latitude\": 5.563299,\n \"longitude\": -0.221196\n },\n {\n \"tracker_id\": 500820,\n \"latitude\": 5.56337,\n \"longitude\": -0.221424\n },\n {\n \"tracker_id\": 500819,\n \"latitude\": 5.483946,\n \"longitude\": -2.467116\n },\n {\n \"tracker_id\": 500815,\n \"latitude\": 5.563428,\n \"longitude\": -0.221636\n },\n {\n \"tracker_id\": 500816,\n \"latitude\": 5.563303,\n \"longitude\": -0.220943\n },\n {\n \"tracker_id\": 500804,\n \"latitude\": -1.334959,\n \"longitude\": 36.690629\n },\n {\n \"tracker_id\": 500226,\n \"latitude\": 30.386391,\n \"longitude\": 72.013157\n },\n {\n \"tracker_id\": 500239,\n \"latitude\": 30.398562,\n \"longitude\": 72.027811\n },\n {\n \"tracker_id\": 500236,\n \"latitude\": 30.214632,\n \"longitude\": 71.967198\n },\n {\n \"tracker_id\": 500245,\n \"latitude\": 30.327042,\n \"longitude\": 71.984011\n },\n {\n \"tracker_id\": 500240,\n \"latitude\": 30.360676,\n \"longitude\": 72.004429\n },\n {\n \"tracker_id\": 500246,\n \"latitude\": 30.359431,\n \"longitude\": 71.840465\n },\n {\n \"tracker_id\": 500237,\n \"latitude\": 30.398558,\n \"longitude\": 72.027808\n },\n {\n \"tracker_id\": 501671,\n \"latitude\": -1.068895,\n \"longitude\": 34.478617\n },\n {\n \"tracker_id\": 501703,\n \"latitude\": -0.282177,\n \"longitude\": 36.095937\n },\n {\n \"tracker_id\": 501579,\n \"latitude\": 0.296468,\n \"longitude\": 30.179804\n },\n {\n \"tracker_id\": 501704,\n \"latitude\": 0.452905,\n \"longitude\": 34.121362\n },\n {\n \"tracker_id\": 501606,\n \"latitude\": -2.002736,\n \"longitude\": 37.350537\n },\n {\n \"tracker_id\": 501734,\n \"latitude\": -0.286401,\n \"longitude\": 36.076611\n },\n {\n \"tracker_id\": 501720,\n \"latitude\": -0.325389,\n \"longitude\": 35.938151\n },\n {\n \"tracker_id\": 501555,\n \"latitude\": -1.0775,\n \"longitude\": 35.789848\n },\n {\n \"tracker_id\": 501643,\n \"latitude\": -1.76466,\n \"longitude\": 37.615511\n },\n {\n \"tracker_id\": 501551,\n \"latitude\": 0.267132,\n \"longitude\": 34.110504\n },\n {\n \"tracker_id\": 501707,\n \"latitude\": -0.091496,\n \"longitude\": 37.787752\n },\n {\n \"tracker_id\": 501736,\n \"latitude\": -3.743879,\n \"longitude\": 39.041057\n },\n {\n \"tracker_id\": 501708,\n \"latitude\": -3.785085,\n \"longitude\": 39.701309\n },\n {\n \"tracker_id\": 501709,\n \"latitude\": -2.019446,\n \"longitude\": 37.384015\n },\n {\n \"tracker_id\": 501556,\n \"latitude\": 0.527209,\n \"longitude\": 34.147635\n },\n {\n \"tracker_id\": 501662,\n \"latitude\": -0.196259,\n \"longitude\": 34.894494\n },\n {\n \"tracker_id\": 501681,\n \"latitude\": -0.020703,\n \"longitude\": 35.746992\n },\n {\n \"tracker_id\": 501710,\n \"latitude\": -0.842934,\n \"longitude\": 34.156866\n },\n {\n \"tracker_id\": 501611,\n \"latitude\": -0.303857,\n \"longitude\": 36.141686\n },\n {\n \"tracker_id\": 501591,\n \"latitude\": 2.246948,\n \"longitude\": 32.885275\n },\n {\n \"tracker_id\": 501546,\n \"latitude\": -1.781519,\n \"longitude\": 37.620504\n },\n {\n \"tracker_id\": 501663,\n \"latitude\": 0.448989,\n \"longitude\": 35.408218\n },\n {\n \"tracker_id\": 501583,\n \"latitude\": -0.208281,\n \"longitude\": 35.948416\n },\n {\n \"tracker_id\": 501712,\n \"latitude\": -0.279003,\n \"longitude\": 36.065933\n },\n {\n \"tracker_id\": 501613,\n \"latitude\": 0.460575,\n \"longitude\": 34.235499\n },\n {\n \"tracker_id\": 501585,\n \"latitude\": -3.785097,\n \"longitude\": 39.701293\n },\n {\n \"tracker_id\": 501594,\n \"latitude\": 2.245591,\n \"longitude\": 32.327829\n },\n {\n \"tracker_id\": 501601,\n \"latitude\": -0.156274,\n \"longitude\": 36.309211\n },\n {\n \"tracker_id\": 501615,\n \"latitude\": -0.142991,\n \"longitude\": 34.931793\n },\n {\n \"tracker_id\": 501744,\n \"latitude\": -0.143288,\n \"longitude\": 34.931331\n },\n {\n \"tracker_id\": 501745,\n \"latitude\": -0.132283,\n \"longitude\": 36.380321\n },\n {\n \"tracker_id\": 501617,\n \"latitude\": -1.11566,\n \"longitude\": 34.623828\n },\n {\n \"tracker_id\": 501560,\n \"latitude\": 0.483846,\n \"longitude\": 34.217937\n },\n {\n \"tracker_id\": 501731,\n \"latitude\": -3.785103,\n \"longitude\": 39.701251\n },\n {\n \"tracker_id\": 501597,\n \"latitude\": -0.297423,\n \"longitude\": 35.659042\n },\n {\n \"tracker_id\": 501561,\n \"latitude\": -1.094279,\n \"longitude\": 36.088691\n },\n {\n \"tracker_id\": 501692,\n \"latitude\": -0.273838,\n \"longitude\": 36.064104\n },\n {\n \"tracker_id\": 501735,\n \"latitude\": -1.949524,\n \"longitude\": 37.267488\n },\n {\n \"tracker_id\": 501569,\n \"latitude\": -1.746856,\n \"longitude\": 37.634457\n },\n {\n \"tracker_id\": 501563,\n \"latitude\": -1.077454,\n \"longitude\": 35.789793\n },\n {\n \"tracker_id\": 501633,\n \"latitude\": 0.481183,\n \"longitude\": 34.210575\n },\n {\n \"tracker_id\": 501723,\n \"latitude\": -0.279183,\n \"longitude\": 34.28084\n },\n {\n \"tracker_id\": 501622,\n \"latitude\": 0.480907,\n \"longitude\": 34.210381\n },\n {\n \"tracker_id\": 501645,\n \"latitude\": -1.992996,\n \"longitude\": 37.346503\n },\n {\n \"tracker_id\": 501565,\n \"latitude\": 2.598734,\n \"longitude\": 31.951638\n },\n {\n \"tracker_id\": 501566,\n \"latitude\": -1.778391,\n \"longitude\": 37.63022\n },\n {\n \"tracker_id\": 501592,\n \"latitude\": -0.142944,\n \"longitude\": 34.931594\n },\n {\n \"tracker_id\": 501612,\n \"latitude\": -0.13014,\n \"longitude\": 34.938855\n },\n {\n \"tracker_id\": 501547,\n \"latitude\": 0.510431,\n \"longitude\": 34.16643\n },\n {\n \"tracker_id\": 501726,\n \"latitude\": -0.664038,\n \"longitude\": 34.415173\n },\n {\n \"tracker_id\": 501714,\n \"latitude\": 0.481,\n \"longitude\": 34.210348\n },\n {\n \"tracker_id\": 501686,\n \"latitude\": -0.49957,\n \"longitude\": 35.288542\n },\n {\n \"tracker_id\": 501603,\n \"latitude\": 0.251631,\n \"longitude\": 34.099079\n },\n {\n \"tracker_id\": 501656,\n \"latitude\": -1.792899,\n \"longitude\": 37.612145\n },\n {\n \"tracker_id\": 501702,\n \"latitude\": -0.430616,\n \"longitude\": 34.554486\n },\n {\n \"tracker_id\": 501670,\n \"latitude\": -0.91058,\n \"longitude\": 34.795781\n },\n {\n \"tracker_id\": 501589,\n \"latitude\": -1.957765,\n \"longitude\": 35.844714\n },\n {\n \"tracker_id\": 501550,\n \"latitude\": 0.599887,\n \"longitude\": 34.234148\n },\n {\n \"tracker_id\": 501732,\n \"latitude\": 0.482194,\n \"longitude\": 34.210376\n },\n {\n \"tracker_id\": 501657,\n \"latitude\": 0.309655,\n \"longitude\": 34.564424\n },\n {\n \"tracker_id\": 501719,\n \"latitude\": -0.284047,\n \"longitude\": 36.094417\n },\n {\n \"tracker_id\": 501642,\n \"latitude\": -2.008057,\n \"longitude\": 37.428482\n },\n {\n \"tracker_id\": 501705,\n \"latitude\": -0.821544,\n \"longitude\": 34.381615\n },\n {\n \"tracker_id\": 501631,\n \"latitude\": -0.174092,\n \"longitude\": 34.917521\n },\n {\n \"tracker_id\": 501621,\n \"latitude\": 0.214915,\n \"longitude\": 30.112867\n },\n {\n \"tracker_id\": 501706,\n \"latitude\": 0.326496,\n \"longitude\": 34.34822\n },\n {\n \"tracker_id\": 501694,\n \"latitude\": -0.545703,\n \"longitude\": 34.184981\n },\n {\n \"tracker_id\": 501608,\n \"latitude\": 0.298332,\n \"longitude\": 34.182844\n },\n {\n \"tracker_id\": 501722,\n \"latitude\": -0.04784,\n \"longitude\": 34.117533\n },\n {\n \"tracker_id\": 501552,\n \"latitude\": 0.56087,\n \"longitude\": 34.176393\n },\n {\n \"tracker_id\": 501738,\n \"latitude\": -1.961036,\n \"longitude\": 37.386681\n },\n {\n \"tracker_id\": 501634,\n \"latitude\": 0.497706,\n \"longitude\": 34.513644\n },\n {\n \"tracker_id\": 501725,\n \"latitude\": -2.531606,\n \"longitude\": 37.99894\n },\n {\n \"tracker_id\": 501740,\n \"latitude\": -0.929136,\n \"longitude\": 34.226816\n },\n {\n \"tracker_id\": 501558,\n \"latitude\": -0.288723,\n \"longitude\": 35.172109\n },\n {\n \"tracker_id\": 501649,\n \"latitude\": -0.399093,\n \"longitude\": 35.691247\n },\n {\n \"tracker_id\": 501742,\n \"latitude\": -0.842932,\n \"longitude\": 34.156817\n },\n {\n \"tracker_id\": 501727,\n \"latitude\": -1.988173,\n \"longitude\": 37.428325\n },\n {\n \"tracker_id\": 501666,\n \"latitude\": 2.886557,\n \"longitude\": 31.478354\n },\n {\n \"tracker_id\": 501614,\n \"latitude\": 0.480953,\n \"longitude\": 34.210513\n },\n {\n \"tracker_id\": 501625,\n \"latitude\": 0.405012,\n \"longitude\": 34.192225\n },\n {\n \"tracker_id\": 501715,\n \"latitude\": 0.022046,\n \"longitude\": 35.784481\n },\n {\n \"tracker_id\": 501595,\n \"latitude\": -0.266642,\n \"longitude\": 35.978305\n },\n {\n \"tracker_id\": 501728,\n \"latitude\": -2.437732,\n \"longitude\": 38.259095\n },\n {\n \"tracker_id\": 501602,\n \"latitude\": 0.681718,\n \"longitude\": 35.3669\n },\n {\n \"tracker_id\": 501627,\n \"latitude\": 0.505384,\n \"longitude\": 34.244903\n },\n {\n \"tracker_id\": 501655,\n \"latitude\": 0.231562,\n \"longitude\": 37.538749\n },\n {\n \"tracker_id\": 501669,\n \"latitude\": -0.188323,\n \"longitude\": 34.867765\n },\n {\n \"tracker_id\": 501717,\n \"latitude\": -1.087192,\n \"longitude\": 35.872226\n },\n {\n \"tracker_id\": 501701,\n \"latitude\": 0.581275,\n \"longitude\": 34.319157\n },\n {\n \"tracker_id\": 501604,\n \"latitude\": -0.143425,\n \"longitude\": 34.9316\n },\n {\n \"tracker_id\": 501578,\n \"latitude\": 2.013528,\n \"longitude\": 32.720097\n },\n {\n \"tracker_id\": 501554,\n \"latitude\": 1.086497,\n \"longitude\": 34.925454\n },\n {\n \"tracker_id\": 501654,\n \"latitude\": -2.523189,\n \"longitude\": 38.028038\n },\n {\n \"tracker_id\": 501630,\n \"latitude\": 1.152937,\n \"longitude\": 34.922366\n },\n {\n \"tracker_id\": 501619,\n \"latitude\": 0.437434,\n \"longitude\": 34.171457\n },\n {\n \"tracker_id\": 501733,\n \"latitude\": 0.49393,\n \"longitude\": 34.275748\n },\n {\n \"tracker_id\": 501658,\n \"latitude\": -0.163641,\n \"longitude\": 34.945422\n },\n {\n \"tracker_id\": 501562,\n \"latitude\": 0.612111,\n \"longitude\": 34.231596\n },\n {\n \"tracker_id\": 501721,\n \"latitude\": -0.027494,\n \"longitude\": 35.758115\n },\n {\n \"tracker_id\": 501632,\n \"latitude\": -0.065139,\n \"longitude\": 35.726192\n },\n {\n \"tracker_id\": 501571,\n \"latitude\": -1.064885,\n \"longitude\": 34.799395\n },\n {\n \"tracker_id\": 501737,\n \"latitude\": -0.621761,\n \"longitude\": 34.253321\n },\n {\n \"tracker_id\": 501680,\n \"latitude\": -0.014424,\n \"longitude\": 37.767433\n },\n {\n \"tracker_id\": 501739,\n \"latitude\": -0.14295,\n \"longitude\": 34.931722\n },\n {\n \"tracker_id\": 501557,\n \"latitude\": -1.100271,\n \"longitude\": 35.835266\n },\n {\n \"tracker_id\": 501584,\n \"latitude\": -0.325789,\n \"longitude\": 35.937615\n },\n {\n \"tracker_id\": 501624,\n \"latitude\": -0.143001,\n \"longitude\": 34.931942\n },\n {\n \"tracker_id\": 501665,\n \"latitude\": 1.056117,\n \"longitude\": 34.785375\n },\n {\n \"tracker_id\": 501685,\n \"latitude\": -1.780818,\n \"longitude\": 37.627784\n },\n {\n \"tracker_id\": 501548,\n \"latitude\": -1.778756,\n \"longitude\": 37.628641\n },\n {\n \"tracker_id\": 501559,\n \"latitude\": -1.778058,\n \"longitude\": 37.625951\n },\n {\n \"tracker_id\": 501545,\n \"latitude\": 0.355653,\n \"longitude\": 34.497279\n },\n {\n \"tracker_id\": 501587,\n \"latitude\": -1.88886,\n \"longitude\": 37.165505\n },\n {\n \"tracker_id\": 501729,\n \"latitude\": -1.782701,\n \"longitude\": 37.618295\n },\n {\n \"tracker_id\": 500795,\n \"latitude\": -0.303827,\n \"longitude\": 36.141816\n },\n {\n \"tracker_id\": 501549,\n \"latitude\": -1.077608,\n \"longitude\": 35.789736\n },\n {\n \"tracker_id\": 501596,\n \"latitude\": -2.524215,\n \"longitude\": 38.030616\n },\n {\n \"tracker_id\": 501652,\n \"latitude\": -1.961306,\n \"longitude\": 37.241132\n },\n {\n \"tracker_id\": 501679,\n \"latitude\": 0.075506,\n \"longitude\": 37.149611\n },\n {\n \"tracker_id\": 501640,\n \"latitude\": 0.058957,\n \"longitude\": 34.281221\n },\n {\n \"tracker_id\": 501653,\n \"latitude\": 0.454525,\n \"longitude\": 34.143551\n },\n {\n \"tracker_id\": 501618,\n \"latitude\": 0.706795,\n \"longitude\": 30.513084\n },\n {\n \"tracker_id\": 500444,\n \"latitude\": -5.30136,\n \"longitude\": 38.612329\n },\n {\n \"tracker_id\": 500449,\n \"latitude\": -6.819528,\n \"longitude\": 37.660117\n },\n {\n \"tracker_id\": 500440,\n \"latitude\": -2.713102,\n \"longitude\": 33.023827\n },\n {\n \"tracker_id\": 500443,\n \"latitude\": -3.844702,\n \"longitude\": 32.676039\n },\n {\n \"tracker_id\": 500447,\n \"latitude\": -8.698313,\n \"longitude\": 36.028752\n },\n {\n \"tracker_id\": 500455,\n \"latitude\": -2.826725,\n \"longitude\": 32.177719\n },\n {\n \"tracker_id\": 500452,\n \"latitude\": 10.288208,\n \"longitude\": 9.847155\n },\n {\n \"tracker_id\": 500438,\n \"latitude\": -1.289061,\n \"longitude\": 31.571663\n },\n {\n \"tracker_id\": 500437,\n \"latitude\": -5.047182,\n \"longitude\": 38.477987\n },\n {\n \"tracker_id\": 500441,\n \"latitude\": -1.288298,\n \"longitude\": 31.571446\n },\n {\n \"tracker_id\": 500442,\n \"latitude\": -6.900294,\n \"longitude\": 39.158587\n },\n {\n \"tracker_id\": 500450,\n \"latitude\": -2.713072,\n \"longitude\": 33.023833\n },\n {\n \"tracker_id\": 500456,\n \"latitude\": -6.818495,\n \"longitude\": 39.179979\n },\n {\n \"tracker_id\": 500451,\n \"latitude\": 0.480988,\n \"longitude\": 34.210471\n },\n {\n \"tracker_id\": 500439,\n \"latitude\": -3.300279,\n \"longitude\": 36.376427\n },\n {\n \"tracker_id\": 500448,\n \"latitude\": -2.839805,\n \"longitude\": 31.742363\n },\n {\n \"tracker_id\": 500454,\n \"latitude\": -4.319891,\n \"longitude\": 37.100877\n },\n {\n \"tracker_id\": 500458,\n \"latitude\": 9.087825,\n \"longitude\": 5.982211\n },\n {\n \"tracker_id\": 500457,\n \"latitude\": -5.085917,\n \"longitude\": 39.083826\n },\n {\n \"tracker_id\": 500459,\n \"latitude\": 7.118708,\n \"longitude\": 3.325646\n },\n {\n \"tracker_id\": 500482,\n \"latitude\": -25.815202,\n \"longitude\": 32.571448\n },\n {\n \"tracker_id\": 500463,\n \"latitude\": -14.420099,\n \"longitude\": 38.242006\n },\n {\n \"tracker_id\": 500464,\n \"latitude\": -14.860045,\n \"longitude\": 37.720079\n },\n {\n \"tracker_id\": 500468,\n \"latitude\": -15.024382,\n \"longitude\": 38.048443\n },\n {\n \"tracker_id\": 500475,\n \"latitude\": -14.899674,\n \"longitude\": 37.490784\n },\n {\n \"tracker_id\": 500462,\n \"latitude\": -14.974937,\n \"longitude\": 38.006355\n },\n {\n \"tracker_id\": 500467,\n \"latitude\": -15.46071,\n \"longitude\": 36.230207\n },\n {\n \"tracker_id\": 500470,\n \"latitude\": -25.815289,\n \"longitude\": 32.571507\n },\n {\n \"tracker_id\": 500476,\n \"latitude\": -15.0253,\n \"longitude\": 38.035359\n },\n {\n \"tracker_id\": 500479,\n \"latitude\": -14.893198,\n \"longitude\": 37.723085\n },\n {\n \"tracker_id\": 500481,\n \"latitude\": -15.019163,\n \"longitude\": 39.133166\n },\n {\n \"tracker_id\": 500483,\n \"latitude\": -17.315918,\n \"longitude\": 35.9548\n },\n {\n \"tracker_id\": 500484,\n \"latitude\": -14.387051,\n \"longitude\": 38.270347\n },\n {\n \"tracker_id\": 500469,\n \"latitude\": -14.664816,\n \"longitude\": 38.890971\n },\n {\n \"tracker_id\": 500471,\n \"latitude\": -14.943314,\n \"longitude\": 38.323957\n },\n {\n \"tracker_id\": 500472,\n \"latitude\": -15.958705,\n \"longitude\": 36.862586\n },\n {\n \"tracker_id\": 500477,\n \"latitude\": -14.944832,\n \"longitude\": 38.323298\n },\n {\n \"tracker_id\": 500480,\n \"latitude\": -14.552332,\n \"longitude\": 38.749416\n },\n {\n \"tracker_id\": 501746,\n \"latitude\": 0.951707,\n \"longitude\": 35.210925\n },\n {\n \"tracker_id\": 623410,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 100033,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 500529,\n \"latitude\": 7.821289,\n \"longitude\": 3.926464\n },\n {\n \"tracker_id\": 500530,\n \"latitude\": 8.922031,\n \"longitude\": 3.783355\n },\n {\n \"tracker_id\": 500586,\n \"latitude\": 7.824047,\n \"longitude\": 3.901093\n },\n {\n \"tracker_id\": 500498,\n \"latitude\": 8.829889,\n \"longitude\": 3.791329\n },\n {\n \"tracker_id\": 500487,\n \"latitude\": 8.749946,\n \"longitude\": 6.358805\n },\n {\n \"tracker_id\": 500532,\n \"latitude\": 7.873798,\n \"longitude\": 3.945091\n },\n {\n \"tracker_id\": 500588,\n \"latitude\": 7.882665,\n \"longitude\": 3.924846\n },\n {\n \"tracker_id\": 500489,\n \"latitude\": 7.954323,\n \"longitude\": 3.611863\n },\n {\n \"tracker_id\": 500525,\n \"latitude\": 7.879926,\n \"longitude\": 3.930393\n },\n {\n \"tracker_id\": 500538,\n \"latitude\": 7.847912,\n \"longitude\": 3.906527\n },\n {\n \"tracker_id\": 500581,\n \"latitude\": 9.064098,\n \"longitude\": 3.863493\n },\n {\n \"tracker_id\": 500585,\n \"latitude\": 7.900851,\n \"longitude\": 3.7502\n },\n {\n \"tracker_id\": 500571,\n \"latitude\": 7.522471,\n \"longitude\": 3.424985\n },\n {\n \"tracker_id\": 500495,\n \"latitude\": 7.522489,\n \"longitude\": 3.424937\n },\n {\n \"tracker_id\": 500496,\n \"latitude\": 8.215645,\n \"longitude\": 3.461345\n },\n {\n \"tracker_id\": 500589,\n \"latitude\": 7.901286,\n \"longitude\": 3.731872\n },\n {\n \"tracker_id\": 500579,\n \"latitude\": 7.809621,\n \"longitude\": 3.905936\n },\n {\n \"tracker_id\": 500587,\n \"latitude\": 7.545768,\n \"longitude\": 3.4455\n },\n {\n \"tracker_id\": 500524,\n \"latitude\": 7.901474,\n \"longitude\": 3.777809\n },\n {\n \"tracker_id\": 500536,\n \"latitude\": 7.864238,\n \"longitude\": 3.911704\n },\n {\n \"tracker_id\": 500539,\n \"latitude\": 7.864203,\n \"longitude\": 3.911806\n },\n {\n \"tracker_id\": 500528,\n \"latitude\": 8.084639,\n \"longitude\": 4.216105\n },\n {\n \"tracker_id\": 500577,\n \"latitude\": 8.514909,\n \"longitude\": 3.438753\n },\n {\n \"tracker_id\": 500491,\n \"latitude\": 7.85029,\n \"longitude\": 3.906625\n },\n {\n \"tracker_id\": 500578,\n \"latitude\": 8.121256,\n \"longitude\": 4.223481\n },\n {\n \"tracker_id\": 500497,\n \"latitude\": 7.586986,\n \"longitude\": 3.449859\n },\n {\n \"tracker_id\": 500575,\n \"latitude\": 7.232668,\n \"longitude\": 3.134902\n },\n {\n \"tracker_id\": 500499,\n \"latitude\": 7.877303,\n \"longitude\": 3.924864\n },\n {\n \"tracker_id\": 500580,\n \"latitude\": 7.865361,\n \"longitude\": 3.918412\n },\n {\n \"tracker_id\": 500527,\n \"latitude\": 7.522465,\n \"longitude\": 3.425071\n },\n {\n \"tracker_id\": 500490,\n \"latitude\": 7.032905,\n \"longitude\": 3.008261\n },\n {\n \"tracker_id\": 500576,\n \"latitude\": 7.872128,\n \"longitude\": 3.934881\n },\n {\n \"tracker_id\": 500582,\n \"latitude\": 6.655638,\n \"longitude\": 2.784749\n },\n {\n \"tracker_id\": 500492,\n \"latitude\": 7.879023,\n \"longitude\": 3.939284\n },\n {\n \"tracker_id\": 500572,\n \"latitude\": 6.581755,\n \"longitude\": 2.799413\n },\n {\n \"tracker_id\": 500493,\n \"latitude\": 7.251343,\n \"longitude\": 3.036674\n },\n {\n \"tracker_id\": 500584,\n \"latitude\": 7.850564,\n \"longitude\": 3.90673\n },\n {\n \"tracker_id\": 500573,\n \"latitude\": 7.811029,\n \"longitude\": 3.888401\n },\n {\n \"tracker_id\": 500574,\n \"latitude\": 8.219724,\n \"longitude\": 3.461372\n },\n {\n \"tracker_id\": 500526,\n \"latitude\": 7.929952,\n \"longitude\": 3.854023\n },\n {\n \"tracker_id\": 500485,\n \"latitude\": 8.512568,\n \"longitude\": 3.420568\n },\n {\n \"tracker_id\": 500531,\n \"latitude\": 7.859709,\n \"longitude\": 3.91553\n },\n {\n \"tracker_id\": 500486,\n \"latitude\": 7.440453,\n \"longitude\": 4.012542\n },\n {\n \"tracker_id\": 500488,\n \"latitude\": 7.831002,\n \"longitude\": 3.908134\n },\n {\n \"tracker_id\": 500533,\n \"latitude\": 7.064959,\n \"longitude\": 2.983352\n },\n {\n \"tracker_id\": 500534,\n \"latitude\": 8.125693,\n \"longitude\": 4.221096\n },\n {\n \"tracker_id\": 500535,\n \"latitude\": 8.167645,\n \"longitude\": 4.050464\n },\n {\n \"tracker_id\": 500537,\n \"latitude\": 7.232669,\n \"longitude\": 3.134881\n },\n {\n \"tracker_id\": 500583,\n \"latitude\": 7.876994,\n \"longitude\": 3.92632\n },\n {\n \"tracker_id\": 501297,\n \"latitude\": 7.255592,\n \"longitude\": -1.40301\n },\n {\n \"tracker_id\": 501295,\n \"latitude\": 10.232595,\n \"longitude\": -1.282656\n },\n {\n \"tracker_id\": 501296,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 501299,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 501301,\n \"latitude\": 10.442373,\n \"longitude\": -1.050249\n },\n {\n \"tracker_id\": 501302,\n \"latitude\": 10.02983,\n \"longitude\": -2.495127\n },\n {\n \"tracker_id\": 501305,\n \"latitude\": 10.872542,\n \"longitude\": -1.986699\n },\n {\n \"tracker_id\": 501323,\n \"latitude\": 10.76819,\n \"longitude\": -1.129628\n },\n {\n \"tracker_id\": 501328,\n \"latitude\": 10.707407,\n \"longitude\": -0.836679\n },\n {\n \"tracker_id\": 501311,\n \"latitude\": 10.97425,\n \"longitude\": -2.208768\n },\n {\n \"tracker_id\": 501317,\n \"latitude\": 10.442207,\n \"longitude\": -1.049538\n },\n {\n \"tracker_id\": 501326,\n \"latitude\": 10.665371,\n \"longitude\": -1.950394\n },\n {\n \"tracker_id\": 501327,\n \"latitude\": 10.880501,\n \"longitude\": -2.062676\n },\n {\n \"tracker_id\": 501307,\n \"latitude\": 10.904254,\n \"longitude\": -1.090994\n },\n {\n \"tracker_id\": 501308,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 501309,\n \"latitude\": 10.237413,\n \"longitude\": -1.2781\n },\n {\n \"tracker_id\": 501310,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 501312,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 501313,\n \"latitude\": 10.870138,\n \"longitude\": -1.968381\n },\n {\n \"tracker_id\": 501315,\n \"latitude\": 11.018007,\n \"longitude\": -0.267883\n },\n {\n \"tracker_id\": 501316,\n \"latitude\": 10.872026,\n \"longitude\": -0.570659\n },\n {\n \"tracker_id\": 501322,\n \"latitude\": 10.045589,\n \"longitude\": -2.499339\n },\n {\n \"tracker_id\": 501325,\n \"latitude\": 10.877326,\n \"longitude\": -2.150733\n },\n {\n \"tracker_id\": 501306,\n \"latitude\": 10.761779,\n \"longitude\": -0.868627\n },\n {\n \"tracker_id\": 501331,\n \"latitude\": 10.641319,\n \"longitude\": -2.011869\n },\n {\n \"tracker_id\": 501337,\n \"latitude\": 10.753754,\n \"longitude\": -1.893143\n },\n {\n \"tracker_id\": 501342,\n \"latitude\": 9.920221,\n \"longitude\": -0.344609\n },\n {\n \"tracker_id\": 501345,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 501333,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 501344,\n \"latitude\": 10.821505,\n \"longitude\": -0.935354\n },\n {\n \"tracker_id\": 501346,\n \"latitude\": 10.883414,\n \"longitude\": -1.100868\n },\n {\n \"tracker_id\": 501332,\n \"latitude\": 10.806,\n \"longitude\": -0.877822\n },\n {\n \"tracker_id\": 501334,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 501336,\n \"latitude\": 10.872677,\n \"longitude\": -1.986579\n },\n {\n \"tracker_id\": 501339,\n \"latitude\": 10.757488,\n \"longitude\": -1.081871\n },\n {\n \"tracker_id\": 501341,\n \"latitude\": 10.74153,\n \"longitude\": -2.295115\n },\n {\n \"tracker_id\": 100119,\n \"latitude\": 6.742379,\n \"longitude\": 7.012228\n },\n {\n \"tracker_id\": 1,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 6,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 565656,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 500776,\n \"latitude\": 8.855775,\n \"longitude\": 7.278473\n },\n {\n \"tracker_id\": 501291,\n \"latitude\": 10.288196,\n \"longitude\": 9.847205\n },\n {\n \"tracker_id\": 501354,\n \"latitude\": 10.330624,\n \"longitude\": -1.735186\n },\n {\n \"tracker_id\": 501359,\n \"latitude\": 10.113655,\n \"longitude\": -0.819824\n },\n {\n \"tracker_id\": 501361,\n \"latitude\": 10.23171,\n \"longitude\": -1.283727\n },\n {\n \"tracker_id\": 501348,\n \"latitude\": 10.735824,\n \"longitude\": -1.291635\n },\n {\n \"tracker_id\": 501352,\n \"latitude\": 10.734017,\n \"longitude\": -1.276884\n },\n {\n \"tracker_id\": 501363,\n \"latitude\": 10.5872,\n \"longitude\": -1.895221\n },\n {\n \"tracker_id\": 501367,\n \"latitude\": 10.870257,\n \"longitude\": -1.968324\n },\n {\n \"tracker_id\": 501369,\n \"latitude\": 10.733538,\n \"longitude\": -1.28417\n },\n {\n \"tracker_id\": 501374,\n \"latitude\": 10.876781,\n \"longitude\": -1.978077\n },\n {\n \"tracker_id\": 501377,\n \"latitude\": 10.117108,\n \"longitude\": -1.292918\n },\n {\n \"tracker_id\": 501381,\n \"latitude\": 10.815422,\n \"longitude\": -1.182159\n },\n {\n \"tracker_id\": 501383,\n \"latitude\": 10.775081,\n \"longitude\": -1.098067\n },\n {\n \"tracker_id\": 501376,\n \"latitude\": 10.657788,\n \"longitude\": -1.991197\n },\n {\n \"tracker_id\": 501379,\n \"latitude\": 10.888975,\n \"longitude\": -2.109986\n },\n {\n \"tracker_id\": 501387,\n \"latitude\": 10.861047,\n \"longitude\": -1.992607\n },\n {\n \"tracker_id\": 501391,\n \"latitude\": 10.669222,\n \"longitude\": -2.639564\n },\n {\n \"tracker_id\": 501393,\n \"latitude\": 10.870235,\n \"longitude\": -1.988757\n },\n {\n \"tracker_id\": 500940,\n \"latitude\": 0.317574,\n \"longitude\": 32.601624\n },\n {\n \"tracker_id\": 500939,\n \"latitude\": 0.317664,\n \"longitude\": 32.601583\n },\n {\n \"tracker_id\": 501411,\n \"latitude\": 10.915235,\n \"longitude\": -1.155379\n },\n {\n \"tracker_id\": 501402,\n \"latitude\": 9.823033,\n \"longitude\": -2.207187\n },\n {\n \"tracker_id\": 501406,\n \"latitude\": 10.237185,\n \"longitude\": -1.27828\n },\n {\n \"tracker_id\": 501396,\n \"latitude\": 10.020775,\n \"longitude\": -2.387645\n },\n {\n \"tracker_id\": 501410,\n \"latitude\": 10.904121,\n \"longitude\": -1.090982\n },\n {\n \"tracker_id\": 501412,\n \"latitude\": 10.918542,\n \"longitude\": -2.197453\n },\n {\n \"tracker_id\": 501413,\n \"latitude\": 10.16048,\n \"longitude\": -0.802176\n },\n {\n \"tracker_id\": 501395,\n \"latitude\": 6.564612,\n \"longitude\": -1.908804\n },\n {\n \"tracker_id\": 501427,\n \"latitude\": 10.767518,\n \"longitude\": -0.862861\n },\n {\n \"tracker_id\": 501430,\n \"latitude\": 10.33722,\n \"longitude\": -0.800623\n },\n {\n \"tracker_id\": 501439,\n \"latitude\": 10.045634,\n \"longitude\": -2.499451\n },\n {\n \"tracker_id\": 501421,\n \"latitude\": 10.911392,\n \"longitude\": -0.518644\n },\n {\n \"tracker_id\": 501422,\n \"latitude\": 10.877065,\n \"longitude\": -1.978883\n },\n {\n \"tracker_id\": 501435,\n \"latitude\": 10.33721,\n \"longitude\": -0.800591\n },\n {\n \"tracker_id\": 501449,\n \"latitude\": 10.733394,\n \"longitude\": -1.284367\n },\n {\n \"tracker_id\": 501450,\n \"latitude\": 10.138438,\n \"longitude\": -2.379823\n },\n {\n \"tracker_id\": 501436,\n \"latitude\": 10.905193,\n \"longitude\": -1.089975\n },\n {\n \"tracker_id\": 501440,\n \"latitude\": 10.883284,\n \"longitude\": -1.100907\n },\n {\n \"tracker_id\": 501414,\n \"latitude\": 9.873137,\n \"longitude\": -2.020816\n },\n {\n \"tracker_id\": 501415,\n \"latitude\": 5.621249,\n \"longitude\": -0.182783\n },\n {\n \"tracker_id\": 501442,\n \"latitude\": 10.459409,\n \"longitude\": -1.304604\n },\n {\n \"tracker_id\": 501416,\n \"latitude\": 10.045904,\n \"longitude\": -2.499484\n },\n {\n \"tracker_id\": 501419,\n \"latitude\": 10.877657,\n \"longitude\": -2.067036\n },\n {\n \"tracker_id\": 501423,\n \"latitude\": 10.237259,\n \"longitude\": -1.278284\n },\n {\n \"tracker_id\": 501425,\n \"latitude\": 10.237274,\n \"longitude\": -1.278284\n },\n {\n \"tracker_id\": 501460,\n \"latitude\": 10.707448,\n \"longitude\": -0.836711\n },\n {\n \"tracker_id\": 501466,\n \"latitude\": 10.427926,\n \"longitude\": -0.944732\n },\n {\n \"tracker_id\": 501469,\n \"latitude\": 10.230849,\n \"longitude\": -1.282107\n },\n {\n \"tracker_id\": 501464,\n \"latitude\": 9.445458,\n \"longitude\": -0.005753\n },\n {\n \"tracker_id\": 501476,\n \"latitude\": 10.870511,\n \"longitude\": -1.988072\n },\n {\n \"tracker_id\": 501480,\n \"latitude\": 10.757424,\n \"longitude\": -1.081945\n },\n {\n \"tracker_id\": 501482,\n \"latitude\": 10.904279,\n \"longitude\": -1.090991\n },\n {\n \"tracker_id\": 501459,\n \"latitude\": 10.883487,\n \"longitude\": -1.100973\n },\n {\n \"tracker_id\": 501471,\n \"latitude\": 10.73759,\n \"longitude\": -0.714573\n },\n {\n \"tracker_id\": 501463,\n \"latitude\": 10.815412,\n \"longitude\": -1.182142\n },\n {\n \"tracker_id\": 501468,\n \"latitude\": 10.904162,\n \"longitude\": -1.090888\n },\n {\n \"tracker_id\": 501481,\n \"latitude\": 9.565932,\n \"longitude\": -1.031347\n },\n {\n \"tracker_id\": 501490,\n \"latitude\": 10.796012,\n \"longitude\": -0.870643\n },\n {\n \"tracker_id\": 501488,\n \"latitude\": 9.890072,\n \"longitude\": -2.359425\n },\n {\n \"tracker_id\": 501495,\n \"latitude\": 10.113539,\n \"longitude\": -0.819966\n },\n {\n \"tracker_id\": 501508,\n \"latitude\": 10.617213,\n \"longitude\": -0.815382\n },\n {\n \"tracker_id\": 501494,\n \"latitude\": 9.398143,\n \"longitude\": -0.827552\n },\n {\n \"tracker_id\": 501500,\n \"latitude\": 10.735842,\n \"longitude\": -1.291692\n },\n {\n \"tracker_id\": 501505,\n \"latitude\": 10.878608,\n \"longitude\": -0.555516\n },\n {\n \"tracker_id\": 501498,\n \"latitude\": 10.883331,\n \"longitude\": -1.100887\n },\n {\n \"tracker_id\": 501499,\n \"latitude\": 10.849594,\n \"longitude\": 0.82002\n },\n {\n \"tracker_id\": 501516,\n \"latitude\": 10.237353,\n \"longitude\": -1.278113\n },\n {\n \"tracker_id\": 501504,\n \"latitude\": 10.882695,\n \"longitude\": -1.978443\n },\n {\n \"tracker_id\": 501519,\n \"latitude\": 9.937153,\n \"longitude\": -2.205994\n },\n {\n \"tracker_id\": 501507,\n \"latitude\": 10.598221,\n \"longitude\": -0.851942\n },\n {\n \"tracker_id\": 501512,\n \"latitude\": 9.565914,\n \"longitude\": -1.031202\n },\n {\n \"tracker_id\": 501514,\n \"latitude\": 10.2374,\n \"longitude\": -1.278121\n },\n {\n \"tracker_id\": 501517,\n \"latitude\": 10.028883,\n \"longitude\": -0.976396\n },\n {\n \"tracker_id\": 501521,\n \"latitude\": 10.821531,\n \"longitude\": -0.935305\n },\n {\n \"tracker_id\": 501524,\n \"latitude\": 10.733343,\n \"longitude\": -1.284422\n },\n {\n \"tracker_id\": 501529,\n \"latitude\": 9.937148,\n \"longitude\": -2.206235\n },\n {\n \"tracker_id\": 501538,\n \"latitude\": 10.231974,\n \"longitude\": -1.283842\n },\n {\n \"tracker_id\": 501537,\n \"latitude\": 10.866836,\n \"longitude\": -1.125208\n },\n {\n \"tracker_id\": 501531,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 501533,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 501541,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 501530,\n \"latitude\": 10.933259,\n \"longitude\": -0.500109\n },\n {\n \"tracker_id\": 501478,\n \"latitude\": 11.068915,\n \"longitude\": -0.240704\n },\n {\n \"tracker_id\": 501542,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 232323,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 501776,\n \"latitude\": 0.997673,\n \"longitude\": 34.896844\n },\n {\n \"tracker_id\": 501768,\n \"latitude\": 0.214606,\n \"longitude\": 35.311065\n },\n {\n \"tracker_id\": 501772,\n \"latitude\": 0.683904,\n \"longitude\": 35.309452\n },\n {\n \"tracker_id\": 501781,\n \"latitude\": 0.653004,\n \"longitude\": 35.242162\n },\n {\n \"tracker_id\": 501748,\n \"latitude\": 0.814003,\n \"longitude\": 34.85504\n },\n {\n \"tracker_id\": 501750,\n \"latitude\": 0.293856,\n \"longitude\": 35.405877\n },\n {\n \"tracker_id\": 501753,\n \"latitude\": 1.012474,\n \"longitude\": 35.046656\n },\n {\n \"tracker_id\": 501785,\n \"latitude\": 0.223834,\n \"longitude\": 35.312347\n },\n {\n \"tracker_id\": 501756,\n \"latitude\": 0.666946,\n \"longitude\": 35.210757\n },\n {\n \"tracker_id\": 501760,\n \"latitude\": 0.498724,\n \"longitude\": 35.195672\n },\n {\n \"tracker_id\": 501788,\n \"latitude\": 0.684184,\n \"longitude\": 35.252103\n },\n {\n \"tracker_id\": 501765,\n \"latitude\": -0.05794,\n \"longitude\": 35.037229\n },\n {\n \"tracker_id\": 501767,\n \"latitude\": -1.992992,\n \"longitude\": 37.346561\n },\n {\n \"tracker_id\": 501777,\n \"latitude\": 0.658849,\n \"longitude\": 35.427837\n },\n {\n \"tracker_id\": 501793,\n \"latitude\": -2.00273,\n \"longitude\": 37.350446\n },\n {\n \"tracker_id\": 501779,\n \"latitude\": 0.205067,\n \"longitude\": 35.328198\n },\n {\n \"tracker_id\": 501782,\n \"latitude\": 0.244286,\n \"longitude\": 35.388276\n },\n {\n \"tracker_id\": 501752,\n \"latitude\": 0.158856,\n \"longitude\": 35.204019\n },\n {\n \"tracker_id\": 501755,\n \"latitude\": 0.265073,\n \"longitude\": 35.397809\n },\n {\n \"tracker_id\": 501758,\n \"latitude\": 0.690648,\n \"longitude\": 35.19409\n },\n {\n \"tracker_id\": 501759,\n \"latitude\": 0.25893,\n \"longitude\": 34.218231\n },\n {\n \"tracker_id\": 501763,\n \"latitude\": -0.057949,\n \"longitude\": 35.037243\n },\n {\n \"tracker_id\": 501775,\n \"latitude\": 0.059298,\n \"longitude\": 34.285299\n },\n {\n \"tracker_id\": 501791,\n \"latitude\": 0.183027,\n \"longitude\": 35.328062\n },\n {\n \"tracker_id\": 501792,\n \"latitude\": 0.265175,\n \"longitude\": 35.397674\n },\n {\n \"tracker_id\": 501770,\n \"latitude\": 0.293828,\n \"longitude\": 35.40595\n },\n {\n \"tracker_id\": 501780,\n \"latitude\": 0.644234,\n \"longitude\": 35.251967\n },\n {\n \"tracker_id\": 501757,\n \"latitude\": 0.437161,\n \"longitude\": 35.383622\n },\n {\n \"tracker_id\": 501761,\n \"latitude\": 0.185751,\n \"longitude\": 35.409307\n },\n {\n \"tracker_id\": 501762,\n \"latitude\": 0.676982,\n \"longitude\": 35.226402\n },\n {\n \"tracker_id\": 501764,\n \"latitude\": -1.989206,\n \"longitude\": 37.348729\n },\n {\n \"tracker_id\": 501789,\n \"latitude\": 0.207332,\n \"longitude\": 35.321312\n },\n {\n \"tracker_id\": 501766,\n \"latitude\": -0.399113,\n \"longitude\": 35.691349\n },\n {\n \"tracker_id\": 501771,\n \"latitude\": 0.241255,\n \"longitude\": 35.389551\n },\n {\n \"tracker_id\": 501783,\n \"latitude\": 1.038303,\n \"longitude\": 35.195611\n },\n {\n \"tracker_id\": 501747,\n \"latitude\": 0.165755,\n \"longitude\": 35.33183\n },\n {\n \"tracker_id\": 501784,\n \"latitude\": 0.629412,\n \"longitude\": 35.243267\n },\n {\n \"tracker_id\": 501749,\n \"latitude\": 0.684152,\n \"longitude\": 35.25218\n },\n {\n \"tracker_id\": 501751,\n \"latitude\": 0.925515,\n \"longitude\": 35.297278\n },\n {\n \"tracker_id\": 501754,\n \"latitude\": 0.227057,\n \"longitude\": 35.318911\n },\n {\n \"tracker_id\": 501786,\n \"latitude\": 0.270537,\n \"longitude\": 35.394674\n },\n {\n \"tracker_id\": 501774,\n \"latitude\": 0.176643,\n \"longitude\": 35.288795\n },\n {\n \"tracker_id\": 501790,\n \"latitude\": 0.426839,\n \"longitude\": 35.11269\n },\n {\n \"tracker_id\": 666666,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 56528,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 569828,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 900111,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 6928355,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 500543,\n \"latitude\": -0.960782,\n \"longitude\": 37.02339\n },\n {\n \"tracker_id\": 500540,\n \"latitude\": -1.22335,\n \"longitude\": 34.622195\n },\n {\n \"tracker_id\": 500568,\n \"latitude\": 0.090777,\n \"longitude\": 37.492359\n },\n {\n \"tracker_id\": 500556,\n \"latitude\": -0.206069,\n \"longitude\": 34.848498\n },\n {\n \"tracker_id\": 500552,\n \"latitude\": 0.091907,\n \"longitude\": 37.519545\n },\n {\n \"tracker_id\": 500548,\n \"latitude\": -0.152115,\n \"longitude\": 34.845539\n },\n {\n \"tracker_id\": 500570,\n \"latitude\": -1.100645,\n \"longitude\": 35.841838\n },\n {\n \"tracker_id\": 500558,\n \"latitude\": -0.152314,\n \"longitude\": 34.845554\n },\n {\n \"tracker_id\": 500231,\n \"latitude\": 11.079932,\n \"longitude\": 7.699882\n },\n {\n \"tracker_id\": 500232,\n \"latitude\": 11.079955,\n \"longitude\": 7.699982\n },\n {\n \"tracker_id\": 500248,\n \"latitude\": 7.395462,\n \"longitude\": 3.755107\n },\n {\n \"tracker_id\": 458594,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 562985,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 500541,\n \"latitude\": 6.786481,\n \"longitude\": 3.890962\n },\n {\n \"tracker_id\": 500542,\n \"latitude\": 11.733509,\n \"longitude\": 8.454839\n },\n {\n \"tracker_id\": 500544,\n \"latitude\": 11.733544,\n \"longitude\": 8.454854\n },\n {\n \"tracker_id\": 500546,\n \"latitude\": 11.191174,\n \"longitude\": 7.992847\n },\n {\n \"tracker_id\": 649679,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 999999,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 500262,\n \"latitude\": 8.388845,\n \"longitude\": 9.942809\n },\n {\n \"tracker_id\": 500263,\n \"latitude\": 11.640905,\n \"longitude\": 8.411941\n },\n {\n \"tracker_id\": 500264,\n \"latitude\": 7.841798,\n \"longitude\": 10.969706\n },\n {\n \"tracker_id\": 500353,\n \"latitude\": 11.602861,\n \"longitude\": 8.430552\n },\n {\n \"tracker_id\": 500376,\n \"latitude\": 11.530674,\n \"longitude\": 8.652549\n },\n {\n \"tracker_id\": 500278,\n \"latitude\": 11.08089,\n \"longitude\": 7.702138\n },\n {\n \"tracker_id\": 500354,\n \"latitude\": 8.205677,\n \"longitude\": 7.30314\n },\n {\n \"tracker_id\": 500386,\n \"latitude\": 8.447943,\n \"longitude\": 10.824519\n },\n {\n \"tracker_id\": 500283,\n \"latitude\": 7.917483,\n \"longitude\": 8.321585\n },\n {\n \"tracker_id\": 500284,\n \"latitude\": 8.537388,\n \"longitude\": 9.003022\n },\n {\n \"tracker_id\": 500272,\n \"latitude\": 11.079757,\n \"longitude\": 7.700164\n },\n {\n \"tracker_id\": 500379,\n \"latitude\": 8.480879,\n \"longitude\": 8.275717\n },\n {\n \"tracker_id\": 500380,\n \"latitude\": 8.870691,\n \"longitude\": 6.705176\n },\n {\n \"tracker_id\": 500381,\n \"latitude\": 11.034085,\n \"longitude\": 7.91549\n },\n {\n \"tracker_id\": 500266,\n \"latitude\": 11.080163,\n \"longitude\": 7.702201\n },\n {\n \"tracker_id\": 500383,\n \"latitude\": 9.31397,\n \"longitude\": 8.030829\n },\n {\n \"tracker_id\": 500267,\n \"latitude\": 9.150191,\n \"longitude\": 6.46534\n },\n {\n \"tracker_id\": 500385,\n \"latitude\": 11.067174,\n \"longitude\": 7.90216\n },\n {\n \"tracker_id\": 500355,\n \"latitude\": 10.204864,\n \"longitude\": 5.400731\n },\n {\n \"tracker_id\": 500356,\n \"latitude\": 9.29557,\n \"longitude\": 6.730045\n },\n {\n \"tracker_id\": 500281,\n \"latitude\": 9.111457,\n \"longitude\": 6.752933\n },\n {\n \"tracker_id\": 500347,\n \"latitude\": 11.034493,\n \"longitude\": 7.915513\n },\n {\n \"tracker_id\": 500346,\n \"latitude\": 11.03441,\n \"longitude\": 7.915252\n },\n {\n \"tracker_id\": 500358,\n \"latitude\": 10.064042,\n \"longitude\": 5.263965\n },\n {\n \"tracker_id\": 500359,\n \"latitude\": 11.080828,\n \"longitude\": 7.702085\n },\n {\n \"tracker_id\": 500345,\n \"latitude\": 11.972175,\n \"longitude\": 8.552381\n },\n {\n \"tracker_id\": 500269,\n \"latitude\": 8.561071,\n \"longitude\": 7.723224\n },\n {\n \"tracker_id\": 500270,\n \"latitude\": 10.060569,\n \"longitude\": 7.381539\n },\n {\n \"tracker_id\": 500363,\n \"latitude\": 8.508633,\n \"longitude\": 8.528117\n },\n {\n \"tracker_id\": 500364,\n \"latitude\": 8.868305,\n \"longitude\": 6.802061\n },\n {\n \"tracker_id\": 500271,\n \"latitude\": 8.522836,\n \"longitude\": 7.707747\n },\n {\n \"tracker_id\": 500369,\n \"latitude\": 7.917358,\n \"longitude\": 8.321365\n },\n {\n \"tracker_id\": 500265,\n \"latitude\": 11.714659,\n \"longitude\": 8.424324\n },\n {\n \"tracker_id\": 500274,\n \"latitude\": 11.039182,\n \"longitude\": 7.884702\n },\n {\n \"tracker_id\": 500276,\n \"latitude\": 8.55528,\n \"longitude\": 7.707242\n },\n {\n \"tracker_id\": 500378,\n \"latitude\": 7.995108,\n \"longitude\": 9.15834\n },\n {\n \"tracker_id\": 500352,\n \"latitude\": 8.805177,\n \"longitude\": 6.678067\n },\n {\n \"tracker_id\": 500351,\n \"latitude\": 8.52285,\n \"longitude\": 7.707886\n },\n {\n \"tracker_id\": 500350,\n \"latitude\": 7.71764,\n \"longitude\": 10.016708\n },\n {\n \"tracker_id\": 500279,\n \"latitude\": 8.508575,\n \"longitude\": 8.528047\n },\n {\n \"tracker_id\": 500382,\n \"latitude\": 8.422915,\n \"longitude\": 9.90727\n },\n {\n \"tracker_id\": 500357,\n \"latitude\": 8.467382,\n \"longitude\": 11.067141\n },\n {\n \"tracker_id\": 500361,\n \"latitude\": 8.345234,\n \"longitude\": 7.603456\n },\n {\n \"tracker_id\": 500362,\n \"latitude\": 8.404274,\n \"longitude\": 7.629966\n },\n {\n \"tracker_id\": 500365,\n \"latitude\": 11.470494,\n \"longitude\": 8.505856\n },\n {\n \"tracker_id\": 500368,\n \"latitude\": 11.972145,\n \"longitude\": 8.552265\n },\n {\n \"tracker_id\": 500288,\n \"latitude\": 11.080414,\n \"longitude\": 7.701954\n },\n {\n \"tracker_id\": 500370,\n \"latitude\": 8.522763,\n \"longitude\": 7.707878\n },\n {\n \"tracker_id\": 500289,\n \"latitude\": 11.034498,\n \"longitude\": 7.915431\n },\n {\n \"tracker_id\": 500374,\n \"latitude\": 11.080189,\n \"longitude\": 7.702008\n },\n {\n \"tracker_id\": 500375,\n \"latitude\": 8.129054,\n \"longitude\": 10.114096\n },\n {\n \"tracker_id\": 500277,\n \"latitude\": 9.926192,\n \"longitude\": 5.226362\n },\n {\n \"tracker_id\": 500349,\n \"latitude\": 8.536098,\n \"longitude\": 7.711898\n },\n {\n \"tracker_id\": 500384,\n \"latitude\": 6.794762,\n \"longitude\": 3.577799\n },\n {\n \"tracker_id\": 500280,\n \"latitude\": 8.492912,\n \"longitude\": 10.849734\n },\n {\n \"tracker_id\": 500348,\n \"latitude\": 8.522767,\n \"longitude\": 7.707764\n },\n {\n \"tracker_id\": 500268,\n \"latitude\": 11.034261,\n \"longitude\": 7.915553\n },\n {\n \"tracker_id\": 500282,\n \"latitude\": 8.232031,\n \"longitude\": 7.559157\n },\n {\n \"tracker_id\": 500360,\n \"latitude\": 8.2031,\n \"longitude\": 9.687344\n },\n {\n \"tracker_id\": 500285,\n \"latitude\": 10.204795,\n \"longitude\": 5.400663\n },\n {\n \"tracker_id\": 500366,\n \"latitude\": 8.256385,\n \"longitude\": 7.296391\n },\n {\n \"tracker_id\": 500367,\n \"latitude\": 8.536166,\n \"longitude\": 7.711883\n },\n {\n \"tracker_id\": 500287,\n \"latitude\": 11.080159,\n \"longitude\": 7.702016\n },\n {\n \"tracker_id\": 500273,\n \"latitude\": 11.625716,\n \"longitude\": 7.868478\n },\n {\n \"tracker_id\": 500371,\n \"latitude\": 11.043326,\n \"longitude\": 7.884919\n },\n {\n \"tracker_id\": 500372,\n \"latitude\": 8.527813,\n \"longitude\": 11.123138\n },\n {\n \"tracker_id\": 500373,\n \"latitude\": 11.034578,\n \"longitude\": 7.915447\n },\n {\n \"tracker_id\": 500554,\n \"latitude\": 8.47978,\n \"longitude\": 8.188252\n },\n {\n \"tracker_id\": 500559,\n \"latitude\": 13.295831,\n \"longitude\": 5.42404\n },\n {\n \"tracker_id\": 500555,\n \"latitude\": 6.700172,\n \"longitude\": 6.927993\n },\n {\n \"tracker_id\": 500781,\n \"latitude\": 8.561879,\n \"longitude\": 7.722547\n },\n {\n \"tracker_id\": 500784,\n \"latitude\": 8.563392,\n \"longitude\": 7.7247\n },\n {\n \"tracker_id\": 500786,\n \"latitude\": 0.105872,\n \"longitude\": 37.811014\n },\n {\n \"tracker_id\": 465995,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 111111,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 323232,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 500389,\n \"latitude\": 11.034556,\n \"longitude\": 7.915403\n },\n {\n \"tracker_id\": 500387,\n \"latitude\": 11.602788,\n \"longitude\": 8.43031\n },\n {\n \"tracker_id\": 500388,\n \"latitude\": 11.072613,\n \"longitude\": 7.727724\n },\n {\n \"tracker_id\": 500390,\n \"latitude\": 11.034133,\n \"longitude\": 7.915513\n },\n {\n \"tracker_id\": 666663,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 222222,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 500798,\n \"latitude\": 11.603706,\n \"longitude\": 8.433707\n },\n {\n \"tracker_id\": 500799,\n \"latitude\": 6.588728,\n \"longitude\": -8.029437\n },\n {\n \"tracker_id\": 500800,\n \"latitude\": 9.847646,\n \"longitude\": -5.225833\n },\n {\n \"tracker_id\": 500801,\n \"latitude\": 5.882096,\n \"longitude\": -5.593648\n },\n {\n \"tracker_id\": 500802,\n \"latitude\": -8.913802,\n \"longitude\": 33.48492\n },\n {\n \"tracker_id\": 500805,\n \"latitude\": 9.899545,\n \"longitude\": -5.629255\n },\n {\n \"tracker_id\": 500803,\n \"latitude\": -6.819558,\n \"longitude\": 37.660076\n },\n {\n \"tracker_id\": 500806,\n \"latitude\": 5.989974,\n \"longitude\": -5.736678\n },\n {\n \"tracker_id\": 500807,\n \"latitude\": 9.708718,\n \"longitude\": -5.169088\n },\n {\n \"tracker_id\": 500808,\n \"latitude\": 9.760409,\n \"longitude\": -5.144983\n },\n {\n \"tracker_id\": 500809,\n \"latitude\": 10.106429,\n \"longitude\": -5.473666\n },\n {\n \"tracker_id\": 500810,\n \"latitude\": 9.397614,\n \"longitude\": -4.864812\n },\n {\n \"tracker_id\": 500811,\n \"latitude\": 10.105534,\n \"longitude\": -5.471988\n },\n {\n \"tracker_id\": 500812,\n \"latitude\": 10.055102,\n \"longitude\": -5.324063\n },\n {\n \"tracker_id\": 500813,\n \"latitude\": 6.060518,\n \"longitude\": -5.572566\n },\n {\n \"tracker_id\": 500814,\n \"latitude\": 6.545409,\n \"longitude\": -7.887179\n },\n {\n \"tracker_id\": 500817,\n \"latitude\": 6.648108,\n \"longitude\": -7.889623\n },\n {\n \"tracker_id\": 222111,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 501032,\n \"latitude\": 11.640766,\n \"longitude\": 8.519043\n },\n {\n \"tracker_id\": 500712,\n \"latitude\": 9.398796,\n \"longitude\": 6.874516\n },\n {\n \"tracker_id\": 129713,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 500250,\n \"latitude\": 6.520846,\n \"longitude\": 3.890171\n },\n {\n \"tracker_id\": 500251,\n \"latitude\": 11.409131,\n \"longitude\": 4.228877\n },\n {\n \"tracker_id\": 500249,\n \"latitude\": 6.90299,\n \"longitude\": 3.209269\n },\n {\n \"tracker_id\": 22247,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 222223,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 722552048,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 625341,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 888888,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 500824,\n \"latitude\": 11.931744,\n \"longitude\": 8.844944\n },\n {\n \"tracker_id\": 500825,\n \"latitude\": 11.972334,\n \"longitude\": 8.551617\n },\n {\n \"tracker_id\": 500826,\n \"latitude\": 8.989576,\n \"longitude\": 7.392363\n },\n {\n \"tracker_id\": 500827,\n \"latitude\": 11.883905,\n \"longitude\": 8.806801\n },\n {\n \"tracker_id\": 500833,\n \"latitude\": 7.748392,\n \"longitude\": 8.338045\n },\n {\n \"tracker_id\": 500829,\n \"latitude\": 11.972368,\n \"longitude\": 8.551702\n },\n {\n \"tracker_id\": 500828,\n \"latitude\": 11.972049,\n \"longitude\": 8.551625\n },\n {\n \"tracker_id\": 500832,\n \"latitude\": 7.747891,\n \"longitude\": 8.338054\n },\n {\n \"tracker_id\": 500830,\n \"latitude\": 11.672024,\n \"longitude\": 9.933335\n },\n {\n \"tracker_id\": 500831,\n \"latitude\": 11.972284,\n \"longitude\": 8.551634\n },\n {\n \"tracker_id\": 500834,\n \"latitude\": 10.515829,\n \"longitude\": 7.946774\n },\n {\n \"tracker_id\": 5001544,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 500941,\n \"latitude\": 6.894765,\n \"longitude\": 3.199506\n },\n {\n \"tracker_id\": 500196,\n \"latitude\": 11.813732,\n \"longitude\": 8.842861\n },\n {\n \"tracker_id\": 500569,\n \"latitude\": 0.338514,\n \"longitude\": 34.206471\n },\n {\n \"tracker_id\": 202566,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 320840,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 795632,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 501800,\n \"latitude\": 9.272457,\n \"longitude\": 12.415182\n },\n {\n \"tracker_id\": 501802,\n \"latitude\": 11.861877,\n \"longitude\": 13.2097\n },\n {\n \"tracker_id\": 501801,\n \"latitude\": 9.272615,\n \"longitude\": 12.415293\n },\n {\n \"tracker_id\": 501803,\n \"latitude\": 11.717836,\n \"longitude\": 11.966264\n },\n {\n \"tracker_id\": 501804,\n \"latitude\": 9.272673,\n \"longitude\": 12.415211\n },\n {\n \"tracker_id\": 501805,\n \"latitude\": 10.288241,\n \"longitude\": 9.8472\n },\n {\n \"tracker_id\": 501808,\n \"latitude\": 9.272634,\n \"longitude\": 12.415146\n },\n {\n \"tracker_id\": 501809,\n \"latitude\": 9.272632,\n \"longitude\": 12.415264\n },\n {\n \"tracker_id\": 501806,\n \"latitude\": 9.272194,\n \"longitude\": 12.415392\n },\n {\n \"tracker_id\": 501811,\n \"latitude\": 9.272677,\n \"longitude\": 12.415317\n },\n {\n \"tracker_id\": 501818,\n \"latitude\": 10.288257,\n \"longitude\": 9.847132\n },\n {\n \"tracker_id\": 501813,\n \"latitude\": 9.272672,\n \"longitude\": 12.415052\n },\n {\n \"tracker_id\": 501807,\n \"latitude\": 10.288273,\n \"longitude\": 9.847274\n },\n {\n \"tracker_id\": 501819,\n \"latitude\": 9.272628,\n \"longitude\": 12.415076\n },\n {\n \"tracker_id\": 501810,\n \"latitude\": 9.271881,\n \"longitude\": 12.415178\n },\n {\n \"tracker_id\": 501823,\n \"latitude\": 10.280883,\n \"longitude\": 11.18943\n },\n {\n \"tracker_id\": 501815,\n \"latitude\": 10.280969,\n \"longitude\": 11.189613\n },\n {\n \"tracker_id\": 501816,\n \"latitude\": 9.272471,\n \"longitude\": 12.415187\n },\n {\n \"tracker_id\": 501825,\n \"latitude\": 10.288216,\n \"longitude\": 9.84708\n },\n {\n \"tracker_id\": 501820,\n \"latitude\": 9.272644,\n \"longitude\": 12.415003\n },\n {\n \"tracker_id\": 501821,\n \"latitude\": 9.272451,\n \"longitude\": 12.415085\n },\n {\n \"tracker_id\": 501812,\n \"latitude\": 9.271914,\n \"longitude\": 12.414898\n },\n {\n \"tracker_id\": 501814,\n \"latitude\": 9.27262,\n \"longitude\": 12.415266\n },\n {\n \"tracker_id\": 501824,\n \"latitude\": 9.272457,\n \"longitude\": 12.41521\n },\n {\n \"tracker_id\": 501817,\n \"latitude\": 9.272675,\n \"longitude\": 12.415185\n },\n {\n \"tracker_id\": 501822,\n \"latitude\": 6.463821,\n \"longitude\": 3.318551\n },\n {\n \"tracker_id\": 501826,\n \"latitude\": 8.904465,\n \"longitude\": 11.356676\n },\n {\n \"tracker_id\": 501827,\n \"latitude\": 9.272571,\n \"longitude\": 12.41512\n },\n {\n \"tracker_id\": 501829,\n \"latitude\": 10.288255,\n \"longitude\": 9.8472\n },\n {\n \"tracker_id\": 501832,\n \"latitude\": 6.464016,\n \"longitude\": 3.318591\n },\n {\n \"tracker_id\": 501828,\n \"latitude\": 9.27245,\n \"longitude\": 12.415118\n },\n {\n \"tracker_id\": 501831,\n \"latitude\": 9.272678,\n \"longitude\": 12.415266\n },\n {\n \"tracker_id\": 501833,\n \"latitude\": 9.272702,\n \"longitude\": 12.41535\n },\n {\n \"tracker_id\": 501830,\n \"latitude\": 10.28095,\n \"longitude\": 11.189206\n },\n {\n \"tracker_id\": 501834,\n \"latitude\": 9.272648,\n \"longitude\": 12.414513\n },\n {\n \"tracker_id\": 501841,\n \"latitude\": 10.288209,\n \"longitude\": 9.847249\n },\n {\n \"tracker_id\": 501835,\n \"latitude\": 9.272404,\n \"longitude\": 12.415293\n },\n {\n \"tracker_id\": 501837,\n \"latitude\": 10.280718,\n \"longitude\": 11.189676\n },\n {\n \"tracker_id\": 501840,\n \"latitude\": 10.280965,\n \"longitude\": 11.189433\n },\n {\n \"tracker_id\": 501843,\n \"latitude\": 11.717698,\n \"longitude\": 11.966493\n },\n {\n \"tracker_id\": 501846,\n \"latitude\": 10.288255,\n \"longitude\": 9.847189\n },\n {\n \"tracker_id\": 501836,\n \"latitude\": 10.281232,\n \"longitude\": 11.189522\n },\n {\n \"tracker_id\": 501838,\n \"latitude\": 9.272579,\n \"longitude\": 12.415102\n },\n {\n \"tracker_id\": 501848,\n \"latitude\": 9.272413,\n \"longitude\": 12.415214\n },\n {\n \"tracker_id\": 501849,\n \"latitude\": 9.272635,\n \"longitude\": 12.41521\n },\n {\n \"tracker_id\": 501839,\n \"latitude\": 11.717667,\n \"longitude\": 11.966428\n },\n {\n \"tracker_id\": 501842,\n \"latitude\": 9.272704,\n \"longitude\": 12.415227\n },\n {\n \"tracker_id\": 501847,\n \"latitude\": 10.281119,\n \"longitude\": 11.189294\n },\n {\n \"tracker_id\": 501845,\n \"latitude\": 9.272634,\n \"longitude\": 12.415298\n },\n {\n \"tracker_id\": 501844,\n \"latitude\": 9.272469,\n \"longitude\": 12.415173\n },\n {\n \"tracker_id\": 501850,\n \"latitude\": 11.861616,\n \"longitude\": 13.209832\n },\n {\n \"tracker_id\": 501851,\n \"latitude\": 10.288304,\n \"longitude\": 9.847214\n },\n {\n \"tracker_id\": 501853,\n \"latitude\": 9.272426,\n \"longitude\": 12.415199\n },\n {\n \"tracker_id\": 501854,\n \"latitude\": 9.272666,\n \"longitude\": 12.415353\n },\n {\n \"tracker_id\": 501857,\n \"latitude\": 9.272617,\n \"longitude\": 12.41526\n },\n {\n \"tracker_id\": 501856,\n \"latitude\": 10.280916,\n \"longitude\": 11.189621\n },\n {\n \"tracker_id\": 501852,\n \"latitude\": 9.272639,\n \"longitude\": 12.415204\n },\n {\n \"tracker_id\": 501855,\n \"latitude\": 9.272467,\n \"longitude\": 12.415293\n },\n {\n \"tracker_id\": 501860,\n \"latitude\": 10.280749,\n \"longitude\": 11.189573\n },\n {\n \"tracker_id\": 501863,\n \"latitude\": 9.272599,\n \"longitude\": 12.415384\n },\n {\n \"tracker_id\": 501859,\n \"latitude\": 11.861857,\n \"longitude\": 13.209778\n },\n {\n \"tracker_id\": 501861,\n \"latitude\": 10.288209,\n \"longitude\": 9.847179\n },\n {\n \"tracker_id\": 501862,\n \"latitude\": 7.709526,\n \"longitude\": 8.485162\n },\n {\n \"tracker_id\": 501858,\n \"latitude\": 9.2726,\n \"longitude\": 12.415393\n },\n {\n \"tracker_id\": 501866,\n \"latitude\": 10.28822,\n \"longitude\": 9.847251\n },\n {\n \"tracker_id\": 501865,\n \"latitude\": 10.288213,\n \"longitude\": 9.847207\n },\n {\n \"tracker_id\": 501871,\n \"latitude\": 6.463935,\n \"longitude\": 3.318764\n },\n {\n \"tracker_id\": 501867,\n \"latitude\": 10.288299,\n \"longitude\": 9.847205\n },\n {\n \"tracker_id\": 501868,\n \"latitude\": 9.272613,\n \"longitude\": 12.415162\n },\n {\n \"tracker_id\": 501870,\n \"latitude\": 8.904547,\n \"longitude\": 11.356681\n },\n {\n \"tracker_id\": 501873,\n \"latitude\": 9.272693,\n \"longitude\": 12.415027\n },\n {\n \"tracker_id\": 501869,\n \"latitude\": 6.463848,\n \"longitude\": 3.318148\n },\n {\n \"tracker_id\": 501872,\n \"latitude\": 6.463911,\n \"longitude\": 3.318692\n },\n {\n \"tracker_id\": 501874,\n \"latitude\": 10.281179,\n \"longitude\": 11.189725\n },\n {\n \"tracker_id\": 501878,\n \"latitude\": 9.272646,\n \"longitude\": 12.415116\n },\n {\n \"tracker_id\": 501875,\n \"latitude\": 8.904474,\n \"longitude\": 11.356649\n },\n {\n \"tracker_id\": 501876,\n \"latitude\": 9.2727,\n \"longitude\": 12.415152\n },\n {\n \"tracker_id\": 501877,\n \"latitude\": 9.272593,\n \"longitude\": 12.415104\n },\n {\n \"tracker_id\": 501886,\n \"latitude\": 9.27248,\n \"longitude\": 12.415308\n },\n {\n \"tracker_id\": 501887,\n \"latitude\": 9.272395,\n \"longitude\": 12.415316\n },\n {\n \"tracker_id\": 501884,\n \"latitude\": 9.272639,\n \"longitude\": 12.415349\n },\n {\n \"tracker_id\": 501890,\n \"latitude\": 9.272684,\n \"longitude\": 12.41511\n },\n {\n \"tracker_id\": 501880,\n \"latitude\": 11.717833,\n \"longitude\": 11.966255\n },\n {\n \"tracker_id\": 501892,\n \"latitude\": 9.27263,\n \"longitude\": 12.415029\n },\n {\n \"tracker_id\": 501881,\n \"latitude\": 11.717763,\n \"longitude\": 11.966329\n },\n {\n \"tracker_id\": 501883,\n \"latitude\": 9.272665,\n \"longitude\": 12.415166\n },\n {\n \"tracker_id\": 501885,\n \"latitude\": 9.272626,\n \"longitude\": 12.415128\n },\n {\n \"tracker_id\": 501895,\n \"latitude\": 10.28096,\n \"longitude\": 11.189364\n },\n {\n \"tracker_id\": 501896,\n \"latitude\": 10.280737,\n \"longitude\": 11.189686\n },\n {\n \"tracker_id\": 501882,\n \"latitude\": 9.272673,\n \"longitude\": 12.415313\n },\n {\n \"tracker_id\": 501888,\n \"latitude\": 8.904523,\n \"longitude\": 11.356655\n },\n {\n \"tracker_id\": 501889,\n \"latitude\": 9.272257,\n \"longitude\": 12.41534\n },\n {\n \"tracker_id\": 501899,\n \"latitude\": 9.272652,\n \"longitude\": 12.415262\n },\n {\n \"tracker_id\": 501891,\n \"latitude\": 9.272626,\n \"longitude\": 12.415382\n },\n {\n \"tracker_id\": 501900,\n \"latitude\": 9.272604,\n \"longitude\": 12.415143\n },\n {\n \"tracker_id\": 501893,\n \"latitude\": 10.288226,\n \"longitude\": 9.847164\n },\n {\n \"tracker_id\": 501897,\n \"latitude\": 9.27262,\n \"longitude\": 12.415357\n },\n {\n \"tracker_id\": 501901,\n \"latitude\": 6.46378,\n \"longitude\": 3.318337\n },\n {\n \"tracker_id\": 501898,\n \"latitude\": 9.272626,\n \"longitude\": 12.415145\n },\n {\n \"tracker_id\": 501902,\n \"latitude\": 10.288191,\n \"longitude\": 9.847271\n },\n {\n \"tracker_id\": 501903,\n \"latitude\": 9.272583,\n \"longitude\": 12.415246\n },\n {\n \"tracker_id\": 501907,\n \"latitude\": 9.272404,\n \"longitude\": 12.415319\n },\n {\n \"tracker_id\": 501909,\n \"latitude\": 6.463878,\n \"longitude\": 3.318941\n },\n {\n \"tracker_id\": 501904,\n \"latitude\": 9.272698,\n \"longitude\": 12.415071\n },\n {\n \"tracker_id\": 501910,\n \"latitude\": 6.463893,\n \"longitude\": 3.318613\n },\n {\n \"tracker_id\": 501911,\n \"latitude\": 9.272663,\n \"longitude\": 12.415137\n },\n {\n \"tracker_id\": 501905,\n \"latitude\": 9.272696,\n \"longitude\": 12.415168\n },\n {\n \"tracker_id\": 501906,\n \"latitude\": 9.27242,\n \"longitude\": 12.415243\n },\n {\n \"tracker_id\": 501908,\n \"latitude\": 10.288257,\n \"longitude\": 9.847163\n },\n {\n \"tracker_id\": 501915,\n \"latitude\": 11.717768,\n \"longitude\": 11.96646\n },\n {\n \"tracker_id\": 501912,\n \"latitude\": 11.861882,\n \"longitude\": 13.209696\n },\n {\n \"tracker_id\": 501918,\n \"latitude\": 11.7177,\n \"longitude\": 11.966353\n },\n {\n \"tracker_id\": 501920,\n \"latitude\": 11.717821,\n \"longitude\": 11.966279\n },\n {\n \"tracker_id\": 501917,\n \"latitude\": 11.861825,\n \"longitude\": 13.20974\n },\n {\n \"tracker_id\": 501914,\n \"latitude\": 11.71757,\n \"longitude\": 11.966586\n },\n {\n \"tracker_id\": 501919,\n \"latitude\": 10.280632,\n \"longitude\": 11.1897\n },\n {\n \"tracker_id\": 501916,\n \"latitude\": 4.810001,\n \"longitude\": 7.041821\n },\n {\n \"tracker_id\": 501922,\n \"latitude\": 7.243881,\n \"longitude\": 5.209179\n },\n {\n \"tracker_id\": 501923,\n \"latitude\": 7.243963,\n \"longitude\": 5.209166\n },\n {\n \"tracker_id\": 501925,\n \"latitude\": 5.590438,\n \"longitude\": 7.919424\n },\n {\n \"tracker_id\": 501928,\n \"latitude\": 4.809975,\n \"longitude\": 7.041864\n },\n {\n \"tracker_id\": 501926,\n \"latitude\": 6.473966,\n \"longitude\": 3.325374\n },\n {\n \"tracker_id\": 501927,\n \"latitude\": 11.717633,\n \"longitude\": 11.966424\n },\n {\n \"tracker_id\": 501937,\n \"latitude\": 11.717738,\n \"longitude\": 11.966373\n },\n {\n \"tracker_id\": 501924,\n \"latitude\": 11.717886,\n \"longitude\": 11.966248\n },\n {\n \"tracker_id\": 501932,\n \"latitude\": 8.904393,\n \"longitude\": 11.356669\n },\n {\n \"tracker_id\": 501930,\n \"latitude\": 6.463736,\n \"longitude\": 3.31839\n },\n {\n \"tracker_id\": 501933,\n \"latitude\": 11.717647,\n \"longitude\": 11.96641\n },\n {\n \"tracker_id\": 501938,\n \"latitude\": 11.717728,\n \"longitude\": 11.966362\n },\n {\n \"tracker_id\": 501939,\n \"latitude\": 11.717741,\n \"longitude\": 11.96641\n },\n {\n \"tracker_id\": 501947,\n \"latitude\": 6.473855,\n \"longitude\": 3.325382\n },\n {\n \"tracker_id\": 501949,\n \"latitude\": 11.717639,\n \"longitude\": 11.966384\n },\n {\n \"tracker_id\": 501944,\n \"latitude\": 6.473923,\n \"longitude\": 3.32522\n },\n {\n \"tracker_id\": 501942,\n \"latitude\": 7.243958,\n \"longitude\": 5.209149\n },\n {\n \"tracker_id\": 501943,\n \"latitude\": 10.280625,\n \"longitude\": 11.189695\n },\n {\n \"tracker_id\": 501950,\n \"latitude\": 7.243918,\n \"longitude\": 5.209192\n },\n {\n \"tracker_id\": 501945,\n \"latitude\": 6.464161,\n \"longitude\": 3.318797\n },\n {\n \"tracker_id\": 501946,\n \"latitude\": 10.280691,\n \"longitude\": 11.189673\n },\n {\n \"tracker_id\": 501955,\n \"latitude\": 11.717763,\n \"longitude\": 11.966414\n },\n {\n \"tracker_id\": 501948,\n \"latitude\": 11.7177,\n \"longitude\": 11.966282\n },\n {\n \"tracker_id\": 501951,\n \"latitude\": 11.71779,\n \"longitude\": 11.966256\n },\n {\n \"tracker_id\": 501953,\n \"latitude\": 11.717904,\n \"longitude\": 11.966296\n },\n {\n \"tracker_id\": 501954,\n \"latitude\": 7.243967,\n \"longitude\": 5.209271\n },\n {\n \"tracker_id\": 500560,\n \"latitude\": -13.338157,\n \"longitude\": 33.621896\n },\n {\n \"tracker_id\": 500561,\n \"latitude\": -13.403463,\n \"longitude\": 33.540711\n },\n {\n \"tracker_id\": 500562,\n \"latitude\": -13.356155,\n \"longitude\": 33.40369\n },\n {\n \"tracker_id\": 501957,\n \"latitude\": 6.46317,\n \"longitude\": 3.319567\n },\n {\n \"tracker_id\": 501958,\n \"latitude\": 6.463801,\n \"longitude\": 3.318431\n },\n {\n \"tracker_id\": 501959,\n \"latitude\": 6.463611,\n \"longitude\": 3.318263\n },\n {\n \"tracker_id\": 501961,\n \"latitude\": 6.463642,\n \"longitude\": 3.319005\n },\n {\n \"tracker_id\": 501968,\n \"latitude\": 8.904275,\n \"longitude\": 11.356721\n },\n {\n \"tracker_id\": 501964,\n \"latitude\": 6.464009,\n \"longitude\": 3.319164\n },\n {\n \"tracker_id\": 501960,\n \"latitude\": 6.463667,\n \"longitude\": 3.318377\n },\n {\n \"tracker_id\": 501973,\n \"latitude\": 6.463595,\n \"longitude\": 3.318525\n },\n {\n \"tracker_id\": 501963,\n \"latitude\": 0,\n \"longitude\": 0\n },\n {\n \"tracker_id\": 501974,\n \"latitude\": 6.463869,\n \"longitude\": 3.318586\n },\n {\n \"tracker_id\": 501967,\n \"latitude\": 10.288171,\n \"longitude\": 9.847074\n },\n {\n \"tracker_id\": 501975,\n \"latitude\": 6.474004,\n \"longitude\": 3.32536\n },\n {\n \"tracker_id\": 501976,\n \"latitude\": 6.463875,\n \"longitude\": 3.318862\n },\n {\n \"tracker_id\": 501969,\n \"latitude\": 6.463517,\n \"longitude\": 3.318467\n },\n {\n \"tracker_id\": 501966,\n \"latitude\": 6.464029,\n \"longitude\": 3.31906\n },\n {\n \"tracker_id\": 501972,\n \"latitude\": 6.46366,\n \"longitude\": 3.318347\n },\n {\n \"tracker_id\": 501977,\n \"latitude\": 6.463729,\n \"longitude\": 3.318551\n },\n {\n \"tracker_id\": 501978,\n \"latitude\": 6.473988,\n \"longitude\": 3.325454\n },\n {\n \"tracker_id\": 501979,\n \"latitude\": 6.473964,\n \"longitude\": 3.325423\n },\n {\n \"tracker_id\": 501982,\n \"latitude\": 6.463762,\n \"longitude\": 3.318549\n },\n {\n \"tracker_id\": 501970,\n \"latitude\": 6.463959,\n \"longitude\": 3.318751\n },\n {\n \"tracker_id\": 501971,\n \"latitude\": 6.4637,\n \"longitude\": 3.3184\n },\n {\n \"tracker_id\": 501981,\n \"latitude\": 6.463985,\n \"longitude\": 3.318868\n },\n {\n \"tracker_id\": 501985,\n \"latitude\": 10.288126,\n \"longitude\": 9.847102\n },\n {\n \"tracker_id\": 501986,\n \"latitude\": 6.463757,\n \"longitude\": 3.318712\n },\n {\n \"tracker_id\": 501984,\n \"latitude\": 6.46369,\n \"longitude\": 3.318358\n },\n {\n \"tracker_id\": 501983,\n \"latitude\": 7.243855,\n \"longitude\": 5.209158\n },\n {\n \"tracker_id\": 501991,\n \"latitude\": 10.288129,\n \"longitude\": 9.847113\n },\n {\n \"tracker_id\": 501992,\n \"latitude\": 10.288137,\n \"longitude\": 9.847154\n },\n {\n \"tracker_id\": 501987,\n \"latitude\": 6.463891,\n \"longitude\": 3.318575\n },\n {\n \"tracker_id\": 501995,\n \"latitude\": 10.281034,\n \"longitude\": 11.189184\n },\n {\n \"tracker_id\": 501989,\n \"latitude\": 6.463828,\n \"longitude\": 3.318432\n },\n {\n \"tracker_id\": 501993,\n \"latitude\": 11.7177,\n \"longitude\": 11.966464\n },\n {\n \"tracker_id\": 501997,\n \"latitude\": 7.243937,\n \"longitude\": 5.209253\n },\n {\n \"tracker_id\": 501998,\n \"latitude\": 6.463894,\n \"longitude\": 3.318187\n },\n {\n \"tracker_id\": 501999,\n \"latitude\": 10.288169,\n \"longitude\": 9.847162\n },\n {\n \"tracker_id\": 501996,\n \"latitude\": 11.717763,\n \"longitude\": 11.966385\n },\n {\n \"tracker_id\": 501990,\n \"latitude\": 7.243901,\n \"longitude\": 5.209148\n },\n {\n \"tracker_id\": 501994,\n \"latitude\": 10.280886,\n \"longitude\": 11.189219\n },\n {\n \"tracker_id\": 502000,\n \"latitude\": 10.280751,\n \"longitude\": 11.189547\n },\n {\n \"tracker_id\": 502001,\n \"latitude\": 6.463727,\n \"longitude\": 3.318766\n },\n {\n \"tracker_id\": 502002,\n \"latitude\": 6.463836,\n \"longitude\": 3.318517\n },\n {\n \"tracker_id\": 502009,\n \"latitude\": 6.463601,\n \"longitude\": 3.318968\n },\n {\n \"tracker_id\": 502005,\n \"latitude\": 6.473888,\n \"longitude\": 3.325403\n },\n {\n \"tracker_id\": 502011,\n \"latitude\": 6.463868,\n \"longitude\": 3.318608\n },\n {\n \"tracker_id\": 502015,\n \"latitude\": 6.463778,\n \"longitude\": 3.319064\n },\n {\n \"tracker_id\": 502003,\n \"latitude\": 6.473889,\n \"longitude\": 3.325312\n },\n {\n \"tracker_id\": 502004,\n \"latitude\": 10.288113,\n \"longitude\": 9.847021\n },\n {\n \"tracker_id\": 502014,\n \"latitude\": 7.24397,\n \"longitude\": 5.209227\n },\n {\n \"tracker_id\": 502007,\n \"latitude\": 10.288144,\n \"longitude\": 9.847077\n },\n {\n \"tracker_id\": 502017,\n \"latitude\": 6.464087,\n \"longitude\": 3.318356\n },\n {\n \"tracker_id\": 502010,\n \"latitude\": 10.281158,\n \"longitude\": 11.189353\n },\n {\n \"tracker_id\": 502016,\n \"latitude\": 10.288152,\n \"longitude\": 9.847033\n },\n {\n \"tracker_id\": 502006,\n \"latitude\": 6.463637,\n \"longitude\": 3.318325\n },\n {\n \"tracker_id\": 502012,\n \"latitude\": 6.463792,\n \"longitude\": 3.318412\n },\n {\n \"tracker_id\": 502020,\n \"latitude\": 6.463653,\n \"longitude\": 3.318475\n },\n {\n \"tracker_id\": 502018,\n \"latitude\": 6.46367,\n \"longitude\": 3.318544\n },\n {\n \"tracker_id\": 502019,\n \"latitude\": 6.463912,\n \"longitude\": 3.31853\n },\n {\n \"tracker_id\": 502022,\n \"latitude\": 10.288101,\n \"longitude\": 9.847088\n },\n {\n \"tracker_id\": 502029,\n \"latitude\": 6.463665,\n \"longitude\": 3.318566\n },\n {\n \"tracker_id\": 502026,\n \"latitude\": 6.575351,\n \"longitude\": 3.325983\n },\n {\n \"tracker_id\": 502032,\n \"latitude\": 6.463768,\n \"longitude\": 3.31853\n },\n {\n \"tracker_id\": 502033,\n \"latitude\": 6.473687,\n \"longitude\": 3.325333\n },\n {\n \"tracker_id\": 502035,\n \"latitude\": 6.295377,\n \"longitude\": 5.588121\n },\n {\n \"tracker_id\": 502027,\n \"latitude\": 6.464053,\n \"longitude\": 3.318827\n },\n {\n \"tracker_id\": 502041,\n \"latitude\": 10.288137,\n \"longitude\": 9.847161\n },\n {\n \"tracker_id\": 502021,\n \"latitude\": 6.463617,\n \"longitude\": 3.318979\n },\n {\n \"tracker_id\": 502023,\n \"latitude\": 6.463889,\n \"longitude\": 3.318774\n },\n {\n \"tracker_id\": 502024,\n \"latitude\": 6.463644,\n \"longitude\": 3.318389\n },\n {\n \"tracker_id\": 502025,\n \"latitude\": 6.463833,\n \"longitude\": 3.318239\n },\n {\n \"tracker_id\": 502031,\n \"latitude\": 9.272172,\n \"longitude\": 12.415043\n },\n {\n \"tracker_id\": 502046,\n \"latitude\": 6.463923,\n \"longitude\": 3.318659\n },\n {\n \"tracker_id\": 502028,\n \"latitude\": 8.904362,\n \"longitude\": 11.356636\n },\n {\n \"tracker_id\": 502051,\n \"latitude\": 8.904297,\n \"longitude\": 11.356661\n },\n {\n \"tracker_id\": 502045,\n \"latitude\": 6.463851,\n \"longitude\": 3.318189\n },\n {\n \"tracker_id\": 502043,\n \"latitude\": 6.463882,\n \"longitude\": 3.31843\n },\n {\n \"tracker_id\": 502049,\n \"latitude\": 11.71768,\n \"longitude\": 11.966384\n },\n {\n \"tracker_id\": 502052,\n \"latitude\": 6.794711,\n \"longitude\": 3.918027\n },\n {\n \"tracker_id\": 502040,\n \"latitude\": 7.709481,\n \"longitude\": 8.485347\n },\n {\n \"tracker_id\": 502055,\n \"latitude\": 9.272148,\n \"longitude\": 12.415093\n },\n {\n \"tracker_id\": 502061,\n \"latitude\": 11.717748,\n \"longitude\": 11.966387\n },\n {\n \"tracker_id\": 502062,\n \"latitude\": 6.473909,\n \"longitude\": 3.325473\n },\n {\n \"tracker_id\": 502047,\n \"latitude\": 6.463442,\n \"longitude\": 3.319001\n },\n {\n \"tracker_id\": 502048,\n \"latitude\": 6.473933,\n \"longitude\": 3.325467\n },\n {\n \"tracker_id\": 502059,\n \"latitude\": 11.717734,\n \"longitude\": 11.96641\n },\n {\n \"tracker_id\": 502039,\n \"latitude\": 6.463822,\n \"longitude\": 3.318947\n },\n {\n \"tracker_id\": 502044,\n \"latitude\": 11.717889,\n \"longitude\": 11.966349\n },\n {\n \"tracker_id\": 502050,\n \"latitude\": 6.29534,\n \"longitude\": 5.588068\n },\n {\n \"tracker_id\": 502063,\n \"latitude\": 11.717776,\n \"longitude\": 11.96648\n },\n {\n \"tracker_id\": 502057,\n \"latitude\": 11.717711,\n \"longitude\": 11.966435\n },\n {\n \"tracker_id\": 502065,\n \"latitude\": 6.464011,\n \"longitude\": 3.318731\n },\n {\n \"tracker_id\": 502066,\n \"latitude\": 8.904319,\n \"longitude\": 11.356712\n },\n {\n \"tracker_id\": 502064,\n \"latitude\": 6.463978,\n \"longitude\": 3.318777\n },\n {\n \"tracker_id\": 502067,\n \"latitude\": 7.709628,\n \"longitude\": 8.485368\n },\n {\n \"tracker_id\": 502069,\n \"latitude\": 10.288227,\n \"longitude\": 9.847173\n },\n {\n \"tracker_id\": 502071,\n \"latitude\": 10.280597,\n \"longitude\": 11.189541\n },\n {\n \"tracker_id\": 502070,\n \"latitude\": 10.280928,\n \"longitude\": 11.18942\n },\n {\n \"tracker_id\": 502073,\n \"latitude\": 10.280612,\n \"longitude\": 11.189433\n },\n {\n \"tracker_id\": 502072,\n \"latitude\": 10.281002,\n \"longitude\": 11.189353\n },\n {\n \"tracker_id\": 502074,\n \"latitude\": 11.717882,\n \"longitude\": 11.966225\n },\n {\n \"tracker_id\": 502075,\n \"latitude\": 11.717897,\n \"longitude\": 11.966299\n },\n {\n \"tracker_id\": 502076,\n \"latitude\": -6.802639,\n \"longitude\": 39.249592\n },\n {\n \"tracker_id\": 502082,\n \"latitude\": -8.673408,\n \"longitude\": 34.302835\n },\n {\n \"tracker_id\": 502083,\n \"latitude\": -7.378601,\n \"longitude\": 37.801057\n },\n {\n \"tracker_id\": 502079,\n \"latitude\": -6.787121,\n \"longitude\": 37.127384\n },\n {\n \"tracker_id\": 502085,\n \"latitude\": -4.885436,\n \"longitude\": 31.680748\n },\n {\n \"tracker_id\": 502077,\n \"latitude\": -4.607191,\n \"longitude\": 35.47405\n },\n {\n \"tracker_id\": 502080,\n \"latitude\": -3.026509,\n \"longitude\": 34.396151\n },\n {\n \"tracker_id\": 502081,\n \"latitude\": -7.825048,\n \"longitude\": 35.736361\n },\n {\n \"tracker_id\": 502092,\n \"latitude\": -4.973259,\n \"longitude\": 38.309371\n },\n {\n \"tracker_id\": 502094,\n \"latitude\": -8.271249,\n \"longitude\": 35.722493\n },\n {\n \"tracker_id\": 502093,\n \"latitude\": -4.760746,\n \"longitude\": 34.726719\n },\n {\n \"tracker_id\": 502091,\n \"latitude\": -5.222772,\n \"longitude\": 38.887672\n },\n {\n \"tracker_id\": 502097,\n \"latitude\": -8.605686,\n \"longitude\": 35.393326\n },\n {\n \"tracker_id\": 502095,\n \"latitude\": -8.700539,\n \"longitude\": 34.377352\n },\n {\n \"tracker_id\": 502100,\n \"latitude\": -8.674976,\n \"longitude\": 34.310273\n },\n {\n \"tracker_id\": 502096,\n \"latitude\": -3.992274,\n \"longitude\": 36.626092\n },\n {\n \"tracker_id\": 502099,\n \"latitude\": -6.268842,\n \"longitude\": 38.78853\n },\n {\n \"tracker_id\": 502107,\n \"latitude\": -6.475884,\n \"longitude\": 38.805279\n },\n {\n \"tracker_id\": 502109,\n \"latitude\": -3.336173,\n \"longitude\": 36.629981\n },\n {\n \"tracker_id\": 502106,\n \"latitude\": -6.266272,\n \"longitude\": 38.784479\n },\n {\n \"tracker_id\": 502108,\n \"latitude\": -6.266624,\n \"longitude\": 38.784265\n },\n {\n \"tracker_id\": 502103,\n \"latitude\": -8.659007,\n \"longitude\": 34.117034\n },\n {\n \"tracker_id\": 502105,\n \"latitude\": -7.365739,\n \"longitude\": 37.897641\n },\n {\n \"tracker_id\": 502110,\n \"latitude\": -3.382649,\n \"longitude\": 36.698601\n },\n {\n \"tracker_id\": 502111,\n \"latitude\": -6.895221,\n \"longitude\": 39.135994\n },\n {\n \"tracker_id\": 502102,\n \"latitude\": -8.701506,\n \"longitude\": 34.059329\n },\n {\n \"tracker_id\": 502104,\n \"latitude\": -6.787176,\n \"longitude\": 37.12741\n },\n {\n \"tracker_id\": 502116,\n \"latitude\": -3.590451,\n \"longitude\": 36.811079\n },\n {\n \"tracker_id\": 502127,\n \"latitude\": -8.091919,\n \"longitude\": 36.679508\n },\n {\n \"tracker_id\": 502128,\n \"latitude\": -6.289411,\n \"longitude\": 38.774602\n },\n {\n \"tracker_id\": 502119,\n \"latitude\": -6.836137,\n \"longitude\": 39.213332\n },\n {\n \"tracker_id\": 502113,\n \"latitude\": -8.426101,\n \"longitude\": 36.477212\n },\n {\n \"tracker_id\": 502114,\n \"latitude\": -6.439467,\n \"longitude\": 37.603933\n },\n {\n \"tracker_id\": 502125,\n \"latitude\": -4.668126,\n \"longitude\": 31.642634\n },\n {\n \"tracker_id\": 502118,\n \"latitude\": -5.221869,\n \"longitude\": 38.88695\n },\n {\n \"tracker_id\": 502120,\n \"latitude\": -6.131955,\n \"longitude\": 38.371314\n },\n {\n \"tracker_id\": 502121,\n \"latitude\": -2.551385,\n \"longitude\": 33.019017\n },\n {\n \"tracker_id\": 502112,\n \"latitude\": -4.48893,\n \"longitude\": 34.42871\n },\n {\n \"tracker_id\": 502115,\n \"latitude\": -8.700573,\n \"longitude\": 34.377201\n },\n {\n \"tracker_id\": 502117,\n \"latitude\": -2.551367,\n \"longitude\": 33.019067\n },\n {\n \"tracker_id\": 502130,\n \"latitude\": -4.514729,\n \"longitude\": 35.382553\n },\n {\n \"tracker_id\": 502122,\n \"latitude\": -6.285684,\n \"longitude\": 38.775536\n },\n {\n \"tracker_id\": 502123,\n \"latitude\": -7.643334,\n \"longitude\": 36.990588\n },\n {\n \"tracker_id\": 502124,\n \"latitude\": -6.786345,\n \"longitude\": 39.166608\n },\n {\n \"tracker_id\": 502126,\n \"latitude\": -6.266857,\n \"longitude\": 38.784862\n },\n {\n \"tracker_id\": 502133,\n \"latitude\": 10.280698,\n \"longitude\": 11.18963\n },\n {\n \"tracker_id\": 502140,\n \"latitude\": 18.672851,\n \"longitude\": 74.116086\n },\n {\n \"tracker_id\": 502141,\n \"latitude\": 18.632658,\n \"longitude\": 74.031224\n },\n {\n \"tracker_id\": 502142,\n \"latitude\": 18.583299,\n \"longitude\": 74.024163\n },\n {\n \"tracker_id\": 502144,\n \"latitude\": -0.97125,\n \"longitude\": 35.494346\n },\n {\n \"tracker_id\": 502147,\n \"latitude\": -0.753498,\n \"longitude\": 34.291536\n },\n {\n \"tracker_id\": 502148,\n \"latitude\": -0.752178,\n \"longitude\": 34.289061\n },\n {\n \"tracker_id\": 502143,\n \"latitude\": -0.823328,\n \"longitude\": 34.370784\n },\n {\n \"tracker_id\": 502146,\n \"latitude\": -0.80693,\n \"longitude\": 34.441801\n },\n {\n \"tracker_id\": 502149,\n \"latitude\": -0.752176,\n \"longitude\": 34.289134\n },\n {\n \"tracker_id\": 502145,\n \"latitude\": -0.821526,\n \"longitude\": 34.381591\n },\n {\n \"tracker_id\": 502162,\n \"latitude\": 8.988427,\n \"longitude\": 7.405939\n },\n {\n \"tracker_id\": 502164,\n \"latitude\": 9.076479,\n \"longitude\": 7.499766\n },\n {\n \"tracker_id\": 502163,\n \"latitude\": 8.988461,\n \"longitude\": 7.405862\n },\n {\n \"tracker_id\": 502172,\n \"latitude\": 11.797916,\n \"longitude\": 8.462089\n },\n {\n \"tracker_id\": 502173,\n \"latitude\": 12.444629,\n \"longitude\": 10.027972\n },\n {\n \"tracker_id\": 502174,\n \"latitude\": 12.535822,\n \"longitude\": 10.197617\n },\n {\n \"tracker_id\": 502166,\n \"latitude\": 12.731355,\n \"longitude\": 10.357682\n },\n {\n \"tracker_id\": 502169,\n \"latitude\": 12.44448,\n \"longitude\": 10.028056\n },\n {\n \"tracker_id\": 502171,\n \"latitude\": 12.444442,\n \"longitude\": 10.028033\n },\n {\n \"tracker_id\": 502165,\n \"latitude\": 11.079392,\n \"longitude\": 7.701055\n },\n {\n \"tracker_id\": 502170,\n \"latitude\": 12.116486,\n \"longitude\": 8.295088\n },\n {\n \"tracker_id\": 502167,\n \"latitude\": 12.444498,\n \"longitude\": 10.027879\n },\n {\n \"tracker_id\": 502168,\n \"latitude\": 12.116491,\n \"longitude\": 8.295081\n },\n {\n \"tracker_id\": 502200,\n \"latitude\": 14.124052,\n \"longitude\": 100.603368\n },\n {\n \"tracker_id\": 502201,\n \"latitude\": 14.108312,\n \"longitude\": 100.598557\n },\n {\n \"tracker_id\": 502209,\n \"latitude\": 16.316841,\n \"longitude\": 103.008848\n },\n {\n \"tracker_id\": 502210,\n \"latitude\": 16.108329,\n \"longitude\": 103.045706\n },\n {\n \"tracker_id\": 502180,\n \"latitude\": 0.355181,\n \"longitude\": 34.842515\n },\n {\n \"tracker_id\": 502184,\n \"latitude\": 0.376968,\n \"longitude\": 34.833768\n },\n {\n \"tracker_id\": 502185,\n \"latitude\": 0.542064,\n \"longitude\": 34.807146\n },\n {\n \"tracker_id\": 502188,\n \"latitude\": 0.226481,\n \"longitude\": 34.6861\n },\n {\n \"tracker_id\": 502189,\n \"latitude\": 0.377271,\n \"longitude\": 34.847554\n },\n {\n \"tracker_id\": 502182,\n \"latitude\": 0.376159,\n \"longitude\": 34.853432\n },\n {\n \"tracker_id\": 502183,\n \"latitude\": 0.393064,\n \"longitude\": 34.77225\n },\n {\n \"tracker_id\": 502186,\n \"latitude\": 0.377482,\n \"longitude\": 34.833515\n },\n {\n \"tracker_id\": 502187,\n \"latitude\": 0.376806,\n \"longitude\": 34.834587\n },\n {\n \"tracker_id\": 502181,\n \"latitude\": 0.330199,\n \"longitude\": 34.61133\n },\n {\n \"tracker_id\": 502211,\n \"latitude\": 6.436089,\n \"longitude\": 2.893817\n },\n {\n \"tracker_id\": 502212,\n \"latitude\": 6.436042,\n \"longitude\": 2.893788\n },\n {\n \"tracker_id\": 500794,\n \"latitude\": 9.144136,\n \"longitude\": -4.942693\n },\n {\n \"tracker_id\": 500793,\n \"latitude\": 10.018482,\n \"longitude\": -5.572398\n },\n {\n \"tracker_id\": 502213,\n \"latitude\": 30.626683,\n \"longitude\": 73.10998\n },\n {\n \"tracker_id\": 502214,\n \"latitude\": 30.479075,\n \"longitude\": 72.302056\n },\n {\n \"tracker_id\": 502215,\n \"latitude\": 30.395171,\n \"longitude\": 72.184665\n },\n {\n \"tracker_id\": 502175,\n \"latitude\": 9.272094,\n \"longitude\": 12.415045\n },\n {\n \"tracker_id\": 502216,\n \"latitude\": 31.420552,\n \"longitude\": 74.260355\n },\n {\n \"tracker_id\": 502221,\n \"latitude\": 11.985952,\n \"longitude\": 8.617565\n },\n {\n \"tracker_id\": 502220,\n \"latitude\": 11.986022,\n \"longitude\": 8.617602\n },\n {\n \"tracker_id\": 502223,\n \"latitude\": 11.985955,\n \"longitude\": 8.61763\n },\n {\n \"tracker_id\": 502228,\n \"latitude\": 11.985967,\n \"longitude\": 8.617637\n },\n {\n \"tracker_id\": 502224,\n \"latitude\": 11.986025,\n \"longitude\": 8.617599\n },\n {\n \"tracker_id\": 502226,\n \"latitude\": 11.985997,\n \"longitude\": 8.617589\n },\n {\n \"tracker_id\": 502222,\n \"latitude\": 11.985984,\n \"longitude\": 8.617606\n },\n {\n \"tracker_id\": 502225,\n \"latitude\": 11.985981,\n \"longitude\": 8.61762\n },\n {\n \"tracker_id\": 502227,\n \"latitude\": 11.986025,\n \"longitude\": 8.617656\n },\n {\n \"tracker_id\": 502229,\n \"latitude\": 11.986025,\n \"longitude\": 8.617636\n },\n {\n \"tracker_id\": 502231,\n \"latitude\": 11.985976,\n \"longitude\": 8.617642\n },\n {\n \"tracker_id\": 502230,\n \"latitude\": 11.985903,\n \"longitude\": 8.617542\n },\n {\n \"tracker_id\": 502232,\n \"latitude\": 11.985992,\n \"longitude\": 8.617536\n },\n {\n \"tracker_id\": 502234,\n \"latitude\": 11.986071,\n \"longitude\": 8.617644\n },\n {\n \"tracker_id\": 502235,\n \"latitude\": 11.986041,\n \"longitude\": 8.617506\n },\n {\n \"tracker_id\": 502249,\n \"latitude\": 11.985934,\n \"longitude\": 8.617574\n },\n {\n \"tracker_id\": 502246,\n \"latitude\": 11.985919,\n \"longitude\": 8.617566\n },\n {\n \"tracker_id\": 502238,\n \"latitude\": 11.98601,\n \"longitude\": 8.617557\n },\n {\n \"tracker_id\": 502239,\n \"latitude\": 11.985937,\n \"longitude\": 8.617644\n },\n {\n \"tracker_id\": 502240,\n \"latitude\": 11.986079,\n \"longitude\": 8.617575\n },\n {\n \"tracker_id\": 502241,\n \"latitude\": 11.98595,\n \"longitude\": 8.617625\n },\n {\n \"tracker_id\": 502243,\n \"latitude\": 11.986051,\n \"longitude\": 8.617556\n },\n {\n \"tracker_id\": 502233,\n \"latitude\": 11.985976,\n \"longitude\": 8.617587\n },\n {\n \"tracker_id\": 502236,\n \"latitude\": 11.985981,\n \"longitude\": 8.617554\n },\n {\n \"tracker_id\": 502247,\n \"latitude\": 11.986018,\n \"longitude\": 8.617644\n },\n {\n \"tracker_id\": 502237,\n \"latitude\": 11.986009,\n \"longitude\": 8.61755\n },\n {\n \"tracker_id\": 502244,\n \"latitude\": 11.985937,\n \"longitude\": 8.617542\n },\n {\n \"tracker_id\": 502262,\n \"latitude\": 10.466169,\n \"longitude\": 7.393349\n },\n {\n \"tracker_id\": 502273,\n \"latitude\": 9.07655,\n \"longitude\": 7.499353\n },\n {\n \"tracker_id\": 502274,\n \"latitude\": 11.58864,\n \"longitude\": -8.287198\n },\n {\n \"tracker_id\": 502264,\n \"latitude\": 11.639786,\n \"longitude\": -8.191005\n },\n {\n \"tracker_id\": 502278,\n \"latitude\": 16.458846,\n \"longitude\": -16.051663\n },\n {\n \"tracker_id\": 502279,\n \"latitude\": 9.076497,\n \"longitude\": 7.499455\n },\n {\n \"tracker_id\": 502266,\n \"latitude\": 12.579442,\n \"longitude\": -7.952538\n },\n {\n \"tracker_id\": 502284,\n \"latitude\": 16.527866,\n \"longitude\": -15.226836\n },\n {\n \"tracker_id\": 502287,\n \"latitude\": 16.458884,\n \"longitude\": -16.051627\n },\n {\n \"tracker_id\": 502288,\n \"latitude\": 13.375422,\n \"longitude\": -6.490578\n },\n {\n \"tracker_id\": 502272,\n \"latitude\": 13.447907,\n \"longitude\": -6.265061\n },\n {\n \"tracker_id\": 502263,\n \"latitude\": 9.076573,\n \"longitude\": 7.499476\n },\n {\n \"tracker_id\": 502277,\n \"latitude\": 16.401609,\n \"longitude\": -16.022502\n },\n {\n \"tracker_id\": 502265,\n \"latitude\": 6.166078,\n \"longitude\": 1.250269\n },\n {\n \"tracker_id\": 502280,\n \"latitude\": 12.63075,\n \"longitude\": -8.033591\n },\n {\n \"tracker_id\": 502281,\n \"latitude\": 12.630826,\n \"longitude\": -8.033526\n },\n {\n \"tracker_id\": 502267,\n \"latitude\": 13.408836,\n \"longitude\": -6.384818\n },\n {\n \"tracker_id\": 502269,\n \"latitude\": 9.076538,\n \"longitude\": 7.499432\n },\n {\n \"tracker_id\": 502276,\n \"latitude\": 14.26038,\n \"longitude\": -5.973321\n },\n {\n \"tracker_id\": 502282,\n \"latitude\": 13.448192,\n \"longitude\": -6.265136\n },\n {\n \"tracker_id\": 502285,\n \"latitude\": 16.540471,\n \"longitude\": -15.228354\n },\n {\n \"tracker_id\": 502286,\n \"latitude\": 16.503905,\n \"longitude\": -15.518096\n },\n {\n \"tracker_id\": 502289,\n \"latitude\": 14.687299,\n \"longitude\": -6.023648\n },\n {\n \"tracker_id\": 502270,\n \"latitude\": 16.399462,\n \"longitude\": -16.001234\n },\n {\n \"tracker_id\": 502271,\n \"latitude\": 16.468904,\n \"longitude\": -16.116679\n },\n {\n \"tracker_id\": 502283,\n \"latitude\": 11.647845,\n \"longitude\": -8.20712\n },\n {\n \"tracker_id\": 502268,\n \"latitude\": 16.525393,\n \"longitude\": -15.211891\n },\n {\n \"tracker_id\": 502290,\n \"latitude\": 8.472426,\n \"longitude\": 4.536638\n },\n {\n \"tracker_id\": 502291,\n \"latitude\": 9.076617,\n \"longitude\": 7.499507\n },\n {\n \"tracker_id\": 502319,\n \"latitude\": -8.138707,\n \"longitude\": 35.410065\n },\n {\n \"tracker_id\": 502349,\n \"latitude\": -2.551617,\n \"longitude\": 33.019341\n },\n {\n \"tracker_id\": 502408,\n \"latitude\": -2.551355,\n \"longitude\": 33.019246\n },\n {\n \"tracker_id\": 502414,\n \"latitude\": -3.844727,\n \"longitude\": 32.676024\n },\n {\n \"tracker_id\": 502416,\n \"latitude\": -2.551584,\n \"longitude\": 33.019466\n },\n {\n \"tracker_id\": 502317,\n \"latitude\": -5.047166,\n \"longitude\": 38.477935\n },\n {\n \"tracker_id\": 502321,\n \"latitude\": -8.138762,\n \"longitude\": 35.41019\n },\n {\n \"tracker_id\": 502322,\n \"latitude\": -2.551314,\n \"longitude\": 33.019343\n },\n {\n \"tracker_id\": 502347,\n \"latitude\": -2.551396,\n \"longitude\": 33.019345\n },\n {\n \"tracker_id\": 502407,\n \"latitude\": -8.138654,\n \"longitude\": 35.410033\n },\n {\n \"tracker_id\": 502412,\n \"latitude\": -8.138646,\n \"longitude\": 35.410092\n },\n {\n \"tracker_id\": 502339,\n \"latitude\": -2.551394,\n \"longitude\": 33.019346\n },\n {\n \"tracker_id\": 502397,\n \"latitude\": -8.138691,\n \"longitude\": 35.410152\n },\n {\n \"tracker_id\": 502398,\n \"latitude\": -2.551359,\n \"longitude\": 33.019216\n },\n {\n \"tracker_id\": 502344,\n \"latitude\": -2.551426,\n \"longitude\": 33.019359\n },\n {\n \"tracker_id\": 502346,\n \"latitude\": -8.138789,\n \"longitude\": 35.410083\n },\n {\n \"tracker_id\": 502401,\n \"latitude\": -2.551415,\n \"longitude\": 33.019151\n },\n {\n \"tracker_id\": 502350,\n \"latitude\": -8.138786,\n \"longitude\": 35.410098\n },\n {\n \"tracker_id\": 502351,\n \"latitude\": -8.138606,\n \"longitude\": 35.410164\n },\n {\n \"tracker_id\": 502409,\n \"latitude\": -2.551287,\n \"longitude\": 33.019342\n },\n {\n \"tracker_id\": 502335,\n \"latitude\": -2.551623,\n \"longitude\": 33.019376\n },\n {\n \"tracker_id\": 502340,\n \"latitude\": -8.138672,\n \"longitude\": 35.410163\n },\n {\n \"tracker_id\": 502410,\n \"latitude\": -2.551378,\n \"longitude\": 33.019342\n },\n {\n \"tracker_id\": 502411,\n \"latitude\": -8.138879,\n \"longitude\": 35.410069\n },\n {\n \"tracker_id\": 502178,\n \"latitude\": 9.076617,\n \"longitude\": 7.499507\n },\n {\n \"tracker_id\": 502179,\n \"latitude\": 8.472426,\n \"longitude\": 4.536638\n },\n {\n \"tracker_id\": 502208,\n \"latitude\": 8.472426,\n \"longitude\": 4.536638\n },\n {\n \"tracker_id\": 502218,\n \"latitude\": 8.465491,\n \"longitude\": 4.58494\n }\n]\nvar count = 0;\n for(var i=0; i<tractorLatLngs.length;i++){\n var tractorId = Number(tractorLatLngs[i].tracker_id);\n var latitude = tractorLatLngs[i].latitude;\n var longitude = tractorLatLngs[i].longitude;\n if( tractorId && latitude && longitude ){\n const tractorUpdate = {};\n tractorUpdate.PositionLongitude = longitude;\n tractorUpdate.PositionLatitude = latitude;\n\n Tractor.update({TractorID : tractorId, PositionLatitude: null, PositionLongitude: null}, {$set:tractorUpdate}, function(err, updated){\n if(err){\n modules.logger.info(\"There was an error updating the latitude and longitude for tractorId \" + tractorLatLngs[i].tracker_id); \n } else {\n modules.logger.info(\"Successfully updated lat and long for tractor with id of \" + tractorLatLngs[i].tracker_id);\n }\n });\n \n }\n count++;\n \n }\n if (count === tractorLatLngs.length ){\n response.complete();\n }\n}\n\n" }, "_MigrateTractorOwnerData" : { "code" : "/**\n * Migrate tractor and it's fuel history from one account to another\n * Created 27th February 2020\n * @param request \n * @param response \n * @param modules \n */\n\nfunction onRequest(request, response, modules) {\n var fromUsername = \"radanny42@gmail.com\";\n var toUsername = \"aarizwan@engro.com\";\n var tractorIdArr = [502215];\n var usersCol = modules.collectionAccess.collection(\"user\");\n var tractorDetailCol = modules.collectionAccess.collection(\"TractorDetail\");\n var fuelHistoryCol = modules.collectionAccess.collection(\"FuelHistory\");\n var now = modules.moment.utc().format(\"YYYY-MM-DD HH:mm:ss\");\n var log = modules.logger;\n\n usersCol.findOne({username: fromUsername}, function(userErr, user){\n usersCol.findOne({username: toUsername}, function(user2Err, user2){\n if (user && user2 && !userErr && !user2Err){\n log.info(\"Users found \"+JSON.stringify(user)+\", \"+JSON.stringify(user2));\n tractorDetailCol.update({TractorID: {$in: tractorIdArr}}, {$set: {_acl: user2._acl, UpdatedAt: now}}, {multi: true, upsert: false}, function(tractorDetailErr, tractorDetailList){\n fuelHistoryCol.update({TractorID: {$in: tractorIdArr}}, {$set: {_acl: user2._acl, UpdatedAt: now}}, {multi: true, upsert: false}, function(fuelHistoryErr, fuelHistoryList){\n log.info(\"Migration complete\");\n response.complete();\n });\n });\n } else {\n log.info(\"Couldn't find a user(s): \"+userErr+\", \"+user2Err);\n response.complete();\n } \n });\n });\n}" }, "__handlePushedAlertsMessages" : { "code" : "function onRequest(request, response, modules) {\n var TractorOwner = modules.collectionAccess.collection('TractorOwner');\n var Tractor = modules.collectionAccess.collection('TractorDetail');\n var User = modules.collectionAccess.collection('user');\n var UserAccount = modules.collectionAccess.collection('UserAccounts');\n var Notification = modules.collectionAccess.collection('Notification');\n var TractorOperator = modules.collectionAccess.collection('TractorOperator');\n var Logger = modules.logger;\n var Pusher = modules.push;\n var Mailer = modules.email;\n var userAcctCreatorIds = [];\n var countNotificationsSaved = 0;\n var alertBody = request.body;\n var supportEmail = \"Hello Tractor <support@hellotractor.com>\";\n var dummyEmail = \"abdulmajid@hellotractor.com\";\n var appsEmail = \"apps2@hellotractor.com\";\n var alertEmail = \"aerishellotractor@yahoo.com\";\n \n \n if ( alertBody.data && Number(alertBody.data.assetId) ) {\n \n var alert = alertBody.data;\n var tractorId = Number(alert.assetId); \n \n Tractor.findOne({\"TractorID\": tractorId}, function (tractorErr, tractor) {\n if ( tractorErr || !tractor ) { \n Logger.error('There was an error finding tractor with the ID of : ' + tractorId + \" error is \" + tractorErr);\n finish();\n } else {\n if (tractor.OperatorID){\n TractorOperator.findOne({\"OperatorID\":tractor.OperatorID}, function(tractorOperatorErr, tractorOperator){\n findUsersAndPushNotification(alert, tractor, tractorOperator);\n });\n } else {\n findUsersAndPushNotification(alertBody.data, tractor, null);\n }\n }\n });\n \n } else {\n modules.logger.info(JSON.stringify(alertBody));\n finish();\n }\n \n function findUsersAndPushNotification(alertData, tractor, tractorOperator){ \n UserAccount.find({\"_acl.creator\": tractor._acl.creator}, function(userActErr, userActs){\n if (userActs){\n userActs.forEach(function(userAct){\n userAcctCreatorIds.push(userAct.accountHolderId);\n });\n }\n \n userAcctCreatorIds.push(tractor._acl.creator);\n \n User.find({\"_acl.creator\": {$in: userAcctCreatorIds}}, function(userErr, users){\n if (users){ \n users.forEach(function(user){\n TractorOwner.findOne({\"_acl.creator\":user._acl.creator}, function(tractorOwnerErr, tractorOwner){\n \n if (tractorOwner && canReceiveNotification(tractorOwner, alertBody.data)){\n\n var entity = buildNotification(alertBody.data, user, tractorOwner, tractor, tractorOperator)\n \n Notification.save(entity, function(notificationErr, savedNotification){\n \n var title = getMessageTitle(entity.action, tractor);\n\n \tMailer.send(supportEmail, tractorOwner.username, title, JSON.stringify(entity.message), supportEmail, null, null, appsEmail, function(emailErr, emailResult){\n\n entity.id = tractor.TractorID + entity.action;\n \n Pusher.sendMessage(user, JSON.stringify(savedNotification), function(pushErr, pushResult) {\n \n Logger.info(\"Push notification sent for \" + savedNotification.tractorId );\n Logger.info(\"Time: \" + new Date().toISOString() + \"\\n\" + \"TractorID: \" + savedNotification.tractorId + \"\\n\" + \"Alert Type: \" + alert.type);\n \n countNotificationsSaved++;\n canFinish(users);\n });\n });\n });\n } else {\n countNotificationsSaved++;\n canFinish(users);\n }\n });\n });\n } else {\n //No users match the creator id in the creator ids array\n finish();\n } \n });\n });\n }\n \n function buildNotification(alertData, user, tractorOwner, tractor, tractorOperator){\n \n var alertType = alertData.type;\n var notification = {};\n var lastActiveTime = dateToHumanReadable(tractor.LastActiveTime);\n\n \n notification._acl = user._acl;\n notification.userId = user._acl.creator; \n notification.tractorId = tractor.TractorID;\n notification.operatorId = tractor.OperatorID;\n notification.country = tractor.Country;\n notification.street = tractor.Street;\n notification.town = tractor.Town;\n notification.tractorName = tractor.TractorName;\n notification.type = \"alert\"; //TODO: Change to action on production\n notification.read = false;\n \n if (alertType == \"deviceOffline\"){\n notification.action = \"device_offline\";\n notification.message = \"Device Offline! \"+tractor.TractorName +\" (\"+tractor.TractorID+\") has been offline since \"+lastActiveTime+\" at \"+tractor.Street +\", \"+tractor.Town+\", \"+tractor.Country;\n \n } else if(alertType == \"lowBattery\"){\n notification.action = \"low_battery\";\n notification.message = \"Low Battery! \"+tractor.TractorName +\" (\"+tractor.TractorID+\") has low (\"+actualValue+\" \"+unit+\") battery voltage. It was last active on \"+lastActiveTime+\" at \"+tractor.Street +\", \"+tractor.Town+\", \"+tractor.Country; \n \n } else if (alertType == \"stopThreshold\"){\n notification.action = \"stop_threshold\";\n notification.message = \"Stopped! \"+tractor.TractorName +\" (\"+tractor.TractorID+\") has stopped. It was last active on \"+lastActiveTime+\" at \"+tractor.Street +\", \"+tractor.Town+\", \"+tractor.Country;\n \n } else if (alertType == \"idleThreshold\"){\n notification.action = \"idle_threshold\";\n notification.message = \"Idle! \"+tractor.TractorName +\" (\"+tractor.TractorID+\") has been idle. It was last active on \"+lastActiveTime+\" at \"+tractor.Street +\", \"+tractor.Town+\", \"+tractor.Country;\n \n } else if (alertType == \"unpluggedDevice\"){\n notification.action = \"unplugged_device\";\n if (tractorOperator){\n notification.message = \"Tampering alert! \"+tractor.TractorName +\" (\"+tractor.TractorID+\") has been unplugged. It was last active on \"+lastActiveTime+\" at \"+tractor.Street +\", \"+tractor.Town+\", \"+tractor.Country+\" and operated by \"+tractorOperator.OperatorName;\n } else {\n notification.message = \"Tampering alert! \"+tractor.TractorName +\" (\"+tractor.TractorID+\") has been unplugged. It was last active on \"+lastActiveTime+\" at \"+tractor.Street +\", \"+tractor.Town+\", \"+tractor.Country;\n }\n } else {\n notification.action = \"\";\n notification.message = \"\";\n }\n \n var notificationToSave = modules.kinvey.entity(notification); \n notificationToSave.extras = JSON.parse(JSON.stringify(notification));\n notificationToSave.data = alertData;\n\n return notificationToSave;\n }\n \n function getMessageTitle(alertType, tractor){\n \n if (alertType == \"device_offline\"){\n return tractor.TractorName+\" (\"+tractor.TractorID+\") is offline\";\n } else if (alertType == \"low_battery\"){\n return tractor.TractorName+\" (\"+tractor.TractorID+\") has low battery\"; \n } else if (alertType == \"stop_threshold\"){\n return tractor.TractorName+\" (\"+tractor.TractorID+\") has stopped\";\n } else if (alertType == \"idle_threshold\"){\n return tractor.TractorName+\" (\"+tractor.TractorID+\") is idle\";\n } else if (alertType == \"unplugged_device\"){\n return \"Critical! \"+tractor.TractorName+\" (\"+tractor.TractorID+\") \"+\" has been tampered with\";\n } else {\n return \"Tractor Alert\";\n }\n }\n\n var dateToHumanReadable = function(date) {\n return modules.moment(date).format(\"dddd Do MMMM YYYY LT\") + \" UTC\";\n } \n \n function canFinish(users){\n if (users.length == countNotificationsSaved){\n response.complete();\n }\n }\n\n function finish(){\n response.complete();\n }\n\n var canReceiveNotification = function (tractorOwner, alertData){\n var alertType = alertData.type;\n if (alertType == \"deviceOffline\" && tractorOwner.tractorOfflineNotifications){\n return true;\n } else if (alertType == \"lowBattery\" && tractorOwner.batteryAlertNotifications){\n return true;\n } else if (alertType == \"stopThreshold\" && tractorOwner.tractorStoppedNotifications){\n return true;\n } else if (alertType == \"idleThreshold\" && tractorOwner.tractorStoppedNotifications){\n return true;\n } else if (alertType == \"unpluggedDevice\" && tractorOwner.deviceUnpluggedNotifications){\n return true;\n } else {\n return false;\n }\n } \n}\n " }, "__activeTractorsPerMonthFinder" : { "code" : "function onRequest(request, response, modules) {\n const Tractor = modules.collectionAccess.collection('TractorDetail');\n const Activity = modules.collectionAccess.collection('DailyTractorActivity');\n \n const tractor_ids = \"500500500503500501500504500513500511500514500062500046500058500069500021500139500007500118500119500093500064500051500114500095500101500108500024500013500009500068500085500050500052500124500034500022500109500079500027500084500075500077500100500082500016500125500053500092500111500102500043500133500113500014500030500078500023500097500073500083500080500130500035500123500120500037500121500055500032500074500116500127500008500096500020500044500045500106500132500018500131500110500104500039500117500011500129500029500047500036500091500054500112500010500086500012500061500006500019500026500122500040500042500031500065500005500103500048500025500049500090500028500070500094500015500099500041500059500071500067500126500105500128500033500017500056500076500115500038500519500515500516500509500510500507500568500552500540500567500548500570500545500543500558500556501026501016501010501018501043501044501040501009501005501024501036501012501033501048501008501019501029501011501038501030501017501046501049501003501023501002501006501031501042501045501013501039501034501015501020501021501047500257500258500259500260500107500098500203500204500200500208500207500209500201500202500205500206500134500135500136500137500138500140500001500002500003500004500057500063500141500088500072500081500087500089500060500142500143500144500145500146500147500148500149500150500405500406500302500303500305500400500402500403500404500000500301500408500312500313500314500317500318500319500342500339500322500320500306500307500308500310500338500155500156500157500158500159500160500161500162500164500165500166500167500168500169500170500171500173500174500175500176500177500178500210500211500212500213500214500151500152500153500154500300500304500327500321500409500328500329500336500340500215500216500217500309500311500315500316500324500326500225500343500180500183500325500334500330500333500407500605500609500633500603500637500624500634500631500616500626500656500604500618500639500617500632500619500663500652500638500653500651500606500629500613500620500658500623500657500641500600500601500602500608500611500614500615500621500622500630500655500642500643500645500647500648500649500660500661500413500414500412500261500179500182500181500679500678500680500681500682500683500684500685500686500687500688500689501037501032500704500703500702500701500700500699500697500696500698500690500705500706500707500708500709500675500676500677500665500666500667500668500669500670500671500672500673500674501022500628500610500650500654500627500635500646500659500664500607500625500640500644500636500612500662500410500172501041500184500769500710500711500712500713500714500715500716500717500718500719500720500721500722500723500724500725500726500727500728500729500730500731500732500733500734500735500736500737500738500768500765500766500767500762500763500739500740500741500742500743500744500745500746500747500748500749500750500751500752500753500754500755500756500757500758500759500760500761500186500187500193500192500191500218500219500220500221500222500223500224500419500420500421500424500425500426500427500428500429500430500431501050501052501053501054501055501056501057501058501059501060501061501062501063501064501065501066501067501068501069501070501071501072501051501073501074501075501076501077501078501079501080501081501082501083501084501085501086501087501088501089501090501091501092501093501094501095501096501097501098501099501100501101501102501103501104501105501106501107501108501109501110501111501112501113501114501115501116501117501118501119501120501121501122501123501124501125501126501127501128501129501131501130501132501133501134501135501138501139501140501141501142501143501144501145501146501147501148501149501150501151501152501153501154501155501156501157501158501159501160501161501162501163501164501165501166501168501169501170501171501172501173501174501175501176501177501178501179501181501182501183501184501185501186501187501188501189501190501191501192501193501194501195501196501197501198501199501200501201501202501203501204501206501208501209501210501211501212501213501214501215501216501217501218501219501220501221501222501223501224501225501226501227501228501229501230501231501232501233501234501235501236501237501238501239501240501241501242501243501244501245501246501247501248501249501250501251501252501253501254501256501257501258501259501260501261501262501263501264501265501266501267501268501269501270501271501272501273501274501275501276501277501278501279501280501281501282501283501284501285501286501287501288501289501290501291501292501293501294500797500820500822500815500823500819500816500818500864500870500871500872500874500876500877500878500879500880500881500882500883500885500886500888500889500891500910500911500917500934500935500937500938500804500194500245500226500227500228500229500230500246500247500233500234500235500236500237500238500239500240500241500242500243500244500795500796500249500250500251500541500066500437500438500439500440500441500442500443500444500447500448500449500450500454500455500457500458500459500462500463500464500467500468500469500470500471500472500475500476500477500479500480500481500482500483500484501545501546501547501548501549501550501551501552501554501555501556501557501558501559501560501561501562501563501565501566501569501571501578501579501583501584501585501587501589501591501592501594501595501596501597501601501602501603501604501606501608501611501612501613501614501615501617501618501619501621501622501624501625501627501630501631501632501633501634501640501642501643501645501649501652501653501654501655501656501657501658501662501663501665501666501669501670501671501679501680501681501685501686501692501694501695501701501702501703501704501705501706501707501708501709501710501712501714501715501717501719501720501721501723501725501726501727501728501729501731501732501733501734501735501736501737501738501739501740501742501744501745500485500486500487500488500489500490500491500492500493500494500495500496500497500498500499500588500587500524500525500526500527500528500529500530500531500532500533500534500535500536500537500538500539500571500572500573500574500575500576500577500578500579500580500581500582500583500584500586500585500589501295501297501301501302501305501306501307501309501311501313501315501316501317501322501323501324501325501326501327501328501331501332501336501337501339501341501342501344501346501348501352501354501359501361501363501367501369501374501376501377501378501379501381501382501383501387501391501393500939500940501395501396501402501406501410501411501412501413501414501415501416501417501419501420501421501422501423501425501427501430501435501436501439501440501442501449501450501459501460501463501464501466501468501469501471501476501480501481501482501488501490501494501495501498501499501500501504501505501507501508501510501512501514501516501517501519501521501524501528501529501530501537501538501478501746501747501748501749501750501751501752501753501754501755501757501758501759501760501761501762501763501764501765501766501767501768501770501771501772501774501775501776501777501779501780501781501782501784501785501786501788501789501790501791501792501793500798500544500542500546500262500263500264500265500266500267500268500269500270500271500272500273500274500276500277500278500279500280500281500282500283500284500285500287500288500289500353500352500351500350500349500348500347500346500345500354500355500356500357500358500359500360500361500362500363500364500365500366500367500368500369500370500371500372500373500374500375500376500378500379500380500381500382500383500385500386500590500591500592500595500694500770500771500554500555500786500387500388500389500781500784500163500799500800500801500793500794500817500805500806500807500808500809500810500811500812500813500814500559500254500941500824500825500826500827500828500829500830500831500832500833500834500821500802500803500195500196500569501800501801501802501803501804501805501806501807501808501809501810501811501812501813501814501815501816501817501818501819501820501821501822501823501824501825501826501827501828501829501830501831501832501833501835501836501837501838501839501840501841501842501843501844501845501846501847501848501849501850501851501852501853501854501855501856501857501858501859501860501861501862501863501865501866501867501868501869501870501871501872501873501874501875501876501877501878501880501881501882501883501884501885501886501887501888501889501890501891501892501893501895501896501897501898501899501900501901501902501903501904501905501906501907501908501909501910501911501912501914501915501916501917501918501919501920501922501923501924501925501926501927501928501930501932501933501936501937501938501939501942501943501944501945501946501947501948501949501950501951501953501954501955500560500561500562501957501958501959501960501961501964501965501966501967501968501969501970501971501972501973501974501975501976501977501978501979501980501981501982501983501984501985501986501987501989501990501991501992501993501994501995501996501997501998501999502000502001502002502003502004502005502006502007502008502009502010502011502012502013502014502015502016502017502018502019502020502021502022502023502024502025502026502027502028502029502031502032502033502035502038502039502040502041502043502044502045502046502047502048502049502050502051502052502055502057502059502061502062502063502064502065502066502067500390502069502070502071502072502073502074502075502076502077502079502080502081502082502083502085502091502092502093502094502095502096502097502099502100502102502103502104502105502106502107502108502109502110502111502112502114502115502116502117502118502119502120502121502122502123502124502125502126502127502128502130502133502140502141502142502143502144502145502146502147502148502149502150502151502152502153502154502155502156502157502158502159502160502161502162502163502164502165502166502167502168502169502170502171502172502173502174502200502201502209502210502180502181502182502184502185502186502187502188502189502211502212502213502214502215502175502216501207502220502221502222502223502224502225502226502227502228502229502230502231502232502233502234502235502236502237502238502239502240502241502243502244502246502247502249502263502264502265502266502267502268502269502270502271502272502273502274502276502277502278502279502280502281502282502283502284502285502286502287502288502289502262502290502394502395502396502397502398502401502407502408502409502410502411502412502414502415502416502317502319502335502339502340502344502346502347502349502350502351502381502382502219502218502208\";\n \nconst tractor_ids_arr = tractor_ids.match(/.{1,6}/g);\n \n for( var i=0; i < tractor_ids_arr.length; i++){\n tractor_ids_arr[i] = String(tractor_ids_arr[i]);\n }\n \n Activity.find({TractorID: {$in: tractor_ids_arr } }, function(err, tractors){\n \n if( err ) { \n modules.logger.info('There was an error ' + err.message);\n }\n \n const activeCountHash = {};\n \n// for(var j=0; j<tractors.length; j++){\n// if( tractors[j].LastActiveTime){\n// var YearMonthStr = tractors[j].LastActiveTime.split(\" \")[0].split(\"-\");\n// YearMonthStr = YearMonthStr[0] + \"-\" + YearMonthStr[1];\n// if(!activeCountHash[YearMonthStr]){\n// activeCountHash[YearMonthStr] = 0;\n// }\n// activeCountHash[YearMonthStr] +=1;\n// } \n// }\n \n for(var j=0; j<tractors.length; j++){\n if( tractors[j].day){\n var YearMonthStr = tractors[j].day.split(\"-\");\n YearMonthStr = YearMonthStr[0] + \"-\" + YearMonthStr[1];\n if(!activeCountHash[YearMonthStr]){\n activeCountHash[YearMonthStr] = 0;\n }\n activeCountHash[YearMonthStr] +=1;\n } \n }\n \n modules.logger.info(activeCountHash);\n \n });\n \n response.complete();\n}" }, "__upload_mechanisation_service_as_bookings" : { "code" : "function onRequest(request, response, modules) {\n \n var existing_msp_bookings = [\n {\n \n \"County\": \"Kisumu\",\n \"Name of service provider\": \"Jane Kisia Odawo Enterprises\",\n \"Estimated Acreage(LR 2020)\": 100,\n \"Phone Number\": 721336832,\n \"Location\": \"Nyando\",\n \"Services offered.\": \"Ploughing,Harrowing\",\n \"Ploughing Cost Per Acre\": 3000,\n \"Harrowing Cost Per Acre\": 1800,\n \"Planting Cost per Acre\": 1500,\n \"Machinery in possession\": \"Tractor With Plough And Rotavator Plough\",\n \"Name of BA Linked\": \"Jane Kisia\",\n \"Phone Number__1\": 704672306,\n \"Name of AA Linked\": \"\",\n \"Phone Number__2\": \"\",\n \"Email\": \"akinyikisia@gmail.com\",\n \n },\n {\n\n \"County\": \"\",\n \"Name of service provider\": \"\",\n \"Estimated Acreage(LR 2020)\": \"\",\n \"Phone Number\": \"\",\n \"Location\": \"\",\n \"Services offered.\": \"\",\n \"Ploughing Cost Per Acre\": \"\",\n \"Harrowing Cost Per Acre\": \"\",\n \"Planting Cost per Acre\": \"\",\n \"Machinery in possession\": \"\",\n \"Name of BA Linked\": \"\",\n \"Phone Number__1\": \"\",\n \"Name of AA Linked\": \"\",\n \"Phone Number__2\": \"\",\n \"Email\": \"\",\n \n },\n {\n\n \"County\": \"Kisumu\",\n \"Name of service provider\": \"Ahero Cooperative Society\",\n \"Estimated Acreage(LR 2020)\": 150,\n \"Phone Number\": 720058224,\n \"Location\": \"Nyando/muhoroni\",\n \"Services offered.\": \"Ploughing,harrowing\",\n \"Ploughing Cost Per Acre\": 3000,\n \"Harrowing Cost Per Acre\": 1800,\n \"Planting Cost per Acre\": 1500,\n \"Machinery in possession\": \"planter,boom sprayer,rotavator plough\",\n \"Name of BA Linked\": \"Mathews Mbeka\",\n \"Phone Number__1\": 718327902,\n \"Name of AA Linked\": \"John Nyamburi\",\n \"Phone Number__2\": \"\",\n \"Email\": \"erastusadongo@gmail.com\",\n \n },\n {\n \n \"County\": \"\",\n \"Name of service provider\": \"\",\n \"Estimated Acreage(LR 2020)\": \"\",\n \"Phone Number\": \"\",\n \"Location\": \"\",\n \"Services offered.\": \"\",\n \"Ploughing Cost Per Acre\": \"\",\n \"Harrowing Cost Per Acre\": \"\",\n \"Planting Cost per Acre\": \"\",\n \"Machinery in possession\": \"\",\n \"Name of BA Linked\": \"\",\n \"Phone Number__1\": \"\",\n \"Name of AA Linked\": \"\",\n \"Phone Number__2\": \"\",\n \"Email\": \"\",\n \n },\n {\n \n \"County\": \"Homabay\",\n \"Name of service provider\": \"Agrimech\",\n \"Estimated Acreage(LR 2020)\": 500,\n \"Phone Number\": 711366516,\n \"Location\": \"All Homabay\",\n \"Services offered.\": \"Ploughing,Harrowing,Planting\",\n \"Ploughing Cost Per Acre\": 3000,\n \"Harrowing Cost Per Acre\": 1800,\n \"Planting Cost per Acre\": 2000,\n \"Machinery in possession\": \"\",\n \"Name of BA Linked\": \"Nicholas Owiti\",\n \"Phone Number__1\": 718344761,\n \"Name of AA Linked\": \"\",\n \"Phone Number__2\": \"\",\n \"Email\": \"timskaru@agrimechafrica.co.ke\",\n \n },\n {\n\n \"County\": \"Homabay\",\n \"Name of service provider\": \"Dr Ikawa\",\n \"Estimated Acreage(LR 2020)\": 200,\n \"Phone Number\": 717226698,\n \"Location\": \"Suba Area\",\n \"Services offered.\": \"Ploughing\",\n \"Ploughing Cost Per Acre\": 3000,\n \"Harrowing Cost Per Acre\": \"\",\n \"Planting Cost per Acre\": \"\",\n \"Machinery in possession\": \"\",\n \"Name of BA Linked\": \"Wycliff Ochieng\",\n \"Phone Number__1\": 723022234,\n \"Name of AA Linked\": \"\",\n \"Phone Number__2\": \"\",\n \"Email\": \"ikawaj@gmail.com\",\n \n },\n {\n \n \"County\": \"Siaya\",\n \"Name of service provider\": \"Julias Okoth\",\n \"Estimated Acreage(LR 2020)\": 35,\n \"Phone Number\": \"722 976171\",\n \"Location\": \"Ugenya/Alego/Ugunja\",\n \"Services offered.\": \"Ploughing\",\n \"Ploughing Cost Per Acre\": 3000,\n \"Harrowing Cost Per Acre\": 1800,\n \"Planting Cost per Acre\": 2000,\n \"Machinery in possession\": \"Tractor,Disc Plough\",\n \"Name of BA Linked\": \"Maltilda Juma\",\n \"Phone Number__1\": 715824604,\n \"Name of AA Linked\": \"Patricia Oyugi\",\n \"Phone Number__2\": 727690734,\n \"Email\": \"charlesodhiambo36@gmail.com\",\n \n },\n {\n \n \"County\": \"Migori\",\n \"Name of service provider\": \"Kephas Nyakibuoga\",\n \"Estimated Acreage(LR 2020)\": 55,\n \"Phone Number\": 727845849,\n \"Location\": \"Nyatike\",\n \"Services offered.\": \"Ploughing\",\n \"Ploughing Cost Per Acre\": 3000,\n \"Harrowing Cost Per Acre\": 1800,\n \"Planting Cost per Acre\": 2000,\n \"Machinery in possession\": \"Plough\",\n \"Name of BA Linked\": \"Philip Oswago\",\n \"Phone Number__1\": 700386526,\n \"Name of AA Linked\": \"\",\n \"Phone Number__2\": \"\",\n \"Email\": \"knyakibwoga@gmail.com\",\n \n },\n {\n\n \"County\": \"\",\n \"Name of service provider\": \"\",\n \"Estimated Acreage(LR 2020)\": \"\",\n \"Phone Number\": \"\",\n \"Location\": \"\",\n \"Services offered.\": \"\",\n \"Ploughing Cost Per Acre\": \"\",\n \"Harrowing Cost Per Acre\": \"\",\n \"Planting Cost per Acre\": \"\",\n \"Machinery in possession\": \"\",\n \"Name of BA Linked\": \"\",\n \"Phone Number__1\": \"\",\n \"Name of AA Linked\": \"\",\n \"Phone Number__2\": \"\",\n \"Email\": \"\",\n \n },\n {\n \"County\": \"Migori\",\n \"Name of service provider\": \"Robert Kibisu\",\n \"Estimated Acreage(LR 2020)\": 30,\n \"Phone Number\": 738703677,\n \"Location\": \"Nyatike\",\n \"Services offered.\": \"Ploughing and planting\",\n \"Ploughing Cost Per Acre\": 3000,\n \"Harrowing Cost Per Acre\": 1800,\n \"Planting Cost per Acre\": 1500,\n \"Machinery in possession\": \"Plough and Planter\",\n \"Name of BA Linked\": \"Jared Ogalo\",\n \"Phone Number__1\": 725164194,\n \"Name of AA Linked\": \"\",\n \"Phone Number__2\": \"\",\n \"Email\": \"ckavere@yahoo.com\",\n \n },\n {\n \n \"County\": \"Migori\",\n \"Name of service provider\": \"Emmanuel Nyakioga\",\n \"Estimated Acreage(LR 2020)\": 70,\n \"Phone Number\": \"\",\n \"Location\": \"Suna East\",\n \"Services offered.\": \"Ploughing\",\n \"Ploughing Cost Per Acre\": 3000,\n \"Harrowing Cost Per Acre\": \"\",\n \"Planting Cost per Acre\": \"\",\n \"Machinery in possession\": \"\",\n \"Name of BA Linked\": \"James Makori\",\n \"Phone Number__1\": 708506433,\n \"Name of AA Linked\": \"\",\n \"Phone Number__2\": \"\",\n \"Email\": \"e.nyakeriga@gmail.com\",\n \n },\n {\n \"County\": \"Migori\",\n \"Name of service provider\": \"Agrimech\",\n \"Estimated Acreage(LR 2020)\": 300,\n \"Phone Number\": 711366516,\n \"Location\": \"Whole Migori\",\n \"Services offered.\": \"Ploughing/ Harrowing and Planting\",\n \"Ploughing Cost Per Acre\": 3000,\n \"Harrowing Cost Per Acre\": 1800,\n \"Planting Cost per Acre\": 1500,\n \"Machinery in possession\": \"\",\n \"Name of BA Linked\": \"Elseba Ayoo\",\n \"Phone Number__1\": 724438263,\n \"Name of AA Linked\": \"\",\n \"Phone Number__2\": \"\",\n \"Email\": \"timskaru@agrimechafrica.co.ke\",\n },\n {\n \"County\": \"Busia\",\n \"Name of service provider\": \"Peter Wanga\",\n \"Estimated Acreage(LR 2020)\": 79,\n \"Phone Number\": 722918877,\n \"Location\": \"Butula\",\n \"Services offered.\": \"Ploughing, Harrowing and Ridging\",\n \"Ploughing Cost Per Acre\": 2500,\n \"Harrowing Cost Per Acre\": 2000,\n \"Planting Cost per Acre\": \"\",\n \"Machinery in possession\": \"Plough, Harrower, Ridger\",\n \"Name of BA Linked\": \"Angeline Atsieno\",\n \"Phone Number__1\": 703564184,\n \"Name of AA Linked\": \"Benard Ojiambo\",\n \"Phone Number__2\": 721820324,\n \"Email\": \"mr.peterwanga@gmail.com\",\n\n },\n {\n \n \"County\": \"Busia\",\n \"Name of service provider\": \"Lydia Makori\",\n \"Estimated Acreage(LR 2020)\": 78,\n \"Phone Number\": 702417235,\n \"Location\": \"Matayos\",\n \"Services offered.\": \"Ploughing/ Harrowing and Planting\",\n \"Ploughing Cost Per Acre\": 2500,\n \"Harrowing Cost Per Acre\": 2000,\n \"Planting Cost per Acre\": \"\",\n \"Machinery in possession\": \"Plough and Harrow and Planter\",\n \"Name of BA Linked\": \"Amos Magero\",\n \"Phone Number__1\": 722283988,\n \"Name of AA Linked\": \"Ruth Wandera\",\n \"Phone Number__2\": 721587706,\n \"Email\": \"moonstone254@gmail.com\",\n\n },\n {\n\n \"County\": \"Busia\",\n \"Name of service provider\": \"Trix Makoba\",\n \"Estimated Acreage(LR 2020)\": 48,\n \"Phone Number\": 712205910,\n \"Location\": \"Nambale\",\n \"Services offered.\": \"Ploughing and Harrowing\",\n \"Ploughing Cost Per Acre\": 2500,\n \"Harrowing Cost Per Acre\": 2000,\n \"Planting Cost per Acre\": \"\",\n \"Machinery in possession\": \"Plough and Harrow\",\n \"Name of BA Linked\": \"Phylis Olendo\",\n \"Phone Number__1\": 714758625,\n \"Name of AA Linked\": \"\",\n \"Phone Number__2\": \"\",\n \"Email\": \"trixnnoli@gmail.com\",\n \n },\n {\n \"County\": \"Busia\",\n \"Name of service provider\": \"Moses Were Wejulu\",\n \"Estimated Acreage(LR 2020)\": 25,\n \"Phone Number\": 713057127,\n \"Location\": \"Samia\",\n \"Services offered.\": \"Ploughing and Harrowing and ridging\",\n \"Ploughing Cost Per Acre\": 2500,\n \"Harrowing Cost Per Acre\": 2000,\n \"Planting Cost per Acre\": \"\",\n \"Machinery in possession\": \"Plough and Harrow and ridger\",\n \"Name of BA Linked\": \"Marlone Awillie\",\n \"Phone Number__1\": 797178123,\n \"Name of AA Linked\": \"Cyprian Wanyama\",\n \"Phone Number__2\": 720538794,\n \"Email\": \"wemoadams1234@gmail.com\",\n \n },\n {\n \n \"County\": \"Busia\",\n \"Name of service provider\": \"Stephen Omadir Elusit\",\n \"Estimated Acreage(LR 2020)\": 83,\n \"Phone Number\": 717088333,\n \"Location\": \"Teso South\",\n \"Services offered.\": \"Ploughing and Harrowing and ridging\",\n \"Ploughing Cost Per Acre\": 2500,\n \"Harrowing Cost Per Acre\": 2000,\n \"Planting Cost per Acre\": \"\",\n \"Machinery in possession\": \"Plough and Harrow and ridger\",\n \"Name of BA Linked\": \"Everlene Ouma Nakhungu\",\n \"Phone Number__1\": 728757423,\n \"Name of AA Linked\": \"\",\n \"Phone Number__2\": \"\",\n \"Email\": \"omadirechosit@gmail.com\",\n \n },\n {\n \"County\": \"Busia\",\n \"Name of service provider\": \"Cyril Etyang\",\n \"Estimated Acreage(LR 2020)\": 87,\n \"Phone Number\": 704226969,\n \"Location\": \"Teso South\",\n \"Services offered.\": \"Ploughing and Harrowing\",\n \"Ploughing Cost Per Acre\": 2500,\n \"Harrowing Cost Per Acre\": 2000,\n \"Planting Cost per Acre\": \"\",\n \"Machinery in possession\": \"Plough and Harrow\",\n \"Name of BA Linked\": \"John Ouko Oporia\",\n \"Phone Number__1\": 714392379,\n \"Name of AA Linked\": \"\",\n \"Phone Number__2\": \"\",\n \"Email\": \"cetiang05@gmail.com\",\n },\n {\n\n \"County\": \"Busia\",\n \"Name of service provider\": \"Kiptela Stephen\",\n \"Estimated Acreage(LR 2020)\": 49,\n \"Phone Number\": 725357894,\n \"Location\": \"Nambale\",\n \"Services offered.\": \"Ploughing and Harrowing and ridging\",\n \"Ploughing Cost Per Acre\": 2500,\n \"Harrowing Cost Per Acre\": 2000,\n \"Planting Cost per Acre\": \"\",\n \"Machinery in possession\": \"Plough and Harrow and ridger\",\n \"Name of BA Linked\": \"Morris Olaba\",\n \"Phone Number__1\": 711585748,\n \"Name of AA Linked\": \"\",\n \"Phone Number__2\": \"\",\n \"Email\": \"kiptelatele@gmail.com\",\n },\n {\n \"County\": \"Busia\",\n \"Name of service provider\": \"Moffat Okisai\",\n \"Estimated Acreage(LR 2020)\": 75,\n \"Phone Number\": 721490941,\n \"Location\": \"Teso South\",\n \"Services offered.\": \"Ploughing and Harrowing and ridging\",\n \"Ploughing Cost Per Acre\": 2500,\n \"Harrowing Cost Per Acre\": 2000,\n \"Planting Cost per Acre\": \"\",\n \"Machinery in possession\": \"Plough and Harrow and ridger\",\n \"Name of BA Linked\": \"Josphine Aokolodi\",\n \"Phone Number__1\": 718193533,\n \"Name of AA Linked\": \"\",\n \"Phone Number__2\": \"\",\n \"Email\": \"okisaimoffats@gmail.com\",\n\n },\n {\n\n \"County\": \"Migori\",\n \"Name of service provider\": \"Moses Rianga\",\n \"Estimated Acreage(LR 2020)\": 40,\n \"Phone Number\": 725849138,\n \"Location\": \"Whole Migori\",\n \"Services offered.\": \"Ploughing\",\n \"Ploughing Cost Per Acre\": 3000,\n \"Harrowing Cost Per Acre\": 1800,\n \"Planting Cost per Acre\": 1500,\n \"Machinery in possession\": \"Plough\",\n \"Name of BA Linked\": \"Philip Oswago\",\n \"Phone Number__1\": 700386526,\n \"Name of AA Linked\": \"\",\n \"Phone Number__2\": \"\",\n \"Email\": \"knyakibwoga@gmail.com\",\n \n }\n]\n \n \n response.complete();\n}" }, "getPastMaintenanceForTractor" : { "code" : "function onRequest(request, response, modules) {\n var tractorId = request.body.tractorId;\n if (!tractorId || tractorId < 100000) return response.error(\"InvalidTractorID\");\n \n var maintenanceHistoryCol = modules.collectionAccess.collection(\"MaintenanceHistory\");\n var log = modules.logger;\n\n maintenanceHistoryCol.find({tractorId: tractorId}, function(maintenanceHistoryErr, maintenanceHistoryList){\n if (maintenanceHistoryList && maintenanceHistoryList.length > 0){\n var maintenanceHoursDoneCounterMap = maintenanceHistoryList.reduce(function(acc, maintenanceHistory, index){\n if (!acc[maintenanceHistory.maintenanceHours]) acc[maintenanceHistory.maintenanceHours] = {done: 0, undone: 0};\n if (maintenanceHistory.done){\n acc[maintenanceHistory.maintenanceHours].done += 1\n } else {\n acc[maintenanceHistory.maintenanceHours].undone += 1\n }\n return acc;\n }, {});\n log.info(\"Maintenance history list generated successfully for \"+tractorId);\n response.body = maintenanceHoursDoneCounterMap;\n response.complete(200);\n } else {\n log.info(\"Couldn't find maintenance history for this tractor\");\n response.body = {};\n response.complete(200);\n }\n });\n}" }, "NearbyTractorTechnician" : { "code" : "//Searches the tractor technician collection for a technician within the same\n//State as the tractor and returns the closes technician based on the lat/lng of\n//the tractor and technician\n//Created on 26th March 2020 by Abdulmajid\n\nfunction onRequest(request, response, modules) {\n var log = modules.logger;\n var tractorId = request.body.tractorId;\n if (!tractorId || tractorId.length < 6) return response.error(\"InvalidTractorID\");\n log.info(\"Tractor id posted: \"+tractorId);\n var tractorDetailCol = modules.collectionAccess.collection(\"TractorDetail\");\n var tractorTechnicianCol = modules.collectionAccess.collection(\"TractorTechnician\");\n \n tractorDetailCol.findOne({TractorID: tractorId}, function(tractorErr, tractorDetail){\n if (tractorDetail){\n var country = tractorDetail.Country;\n var state = tractorDetail.Town;\n var town = tractorDetail.Street;\n var posLatitude = tractorDetail.PositionLatitude;\n var posLongitude = tractorDetail.PositionLongitude;\n \n tractorTechnicianCol.find({\n $and: [\n {state: state},\n {country: country}\n ]\n }, function(technicianErr, tractorTechnicianList){\n if (tractorTechnicianList && tractorTechnicianList.length > 0){\n var nearbyTractorTechnician = tractorTechnicianList[0];\n var distanceToNearbyTractorTechnician = distance(posLatitude, posLongitude, tractorTechnicianList[0].latitude, tractorTechnicianList[0].longitude, \"K\");\n tractorTechnicianList.forEach(function(tractorTechnician){\n var latitude = tractorTechnician.latitude;\n var longitude = tractorTechnician.longitude;\n var distanceToTractor = distance(posLatitude, posLongitude, latitude, longitude, \"K\");\n if (distanceToTractor < distanceToNearbyTractorTechnician){\n nearbyTractorTechnician = tractorTechnician;\n distanceToNearbyTractorTechnician = distanceToTractor;\n }\n });\n \n log.info(\"Found a nearby tractor technician: \"+nearbyTractorTechnician);\n response.body = nearbyTractorTechnician;\n response.complete();\n } else {\n log.info(\"Couldn't find a nearby tractor technician\");\n response.error(404);\n }\n });\n } else {\n log.info(\"Could not find tractor\");\n response.error(403);\n }\n });\n }\n \n \n \n function distance(lat1, lon1, lat2, lon2, unit) {\n var radlat1 = (Math.PI * lat1) / 180;\n var radlat2 = (Math.PI * lat2) / 180;\n var theta = lon1 - lon2;\n var radtheta = (Math.PI * theta) / 180;\n var dist =\n Math.sin(radlat1) * Math.sin(radlat2) +\n Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);\n if (dist > 1) {\n dist = 1;\n }\n dist = Math.acos(dist);\n dist = (dist * 180) / Math.PI;\n dist = dist * 60 * 1.1515;\n if (unit == \"K\") {\n dist = dist * 1.609344;\n }\n if (unit == \"N\") {\n dist = dist * 0.8684;\n }\n return dist;\n }" }, "__pulled_trips_active_time_updater" : { "code" : "function onRequest(request, response, modules) {\n const Tractor = modules.collectionAccess.collection('TractorDetail');\n const requestBody = request.body;\n \n if(requestBody.totalActiveTime && requestBody.tractorId ){\n \n const TractorId = Number(requestBody.tractorId);\n \n const update = {};\n \n update.ActiveTimeToday = requestBody.totalActiveTime;\n \n Tractor.update({TractorID: TractorId}, { $set: update }, function(err, tractor){\n if(err){\n modules.logger.info('There was an error updating the ActiveTimeToday for the tractor with the ID of ' + requestBody.tractorId )\n } else {\n modules.logger.info('Successfully updated ActiveTimeToday for the tractor with the ID of ' + requestBody.tractorId);\n }\n });\n\n } else {\n \t\tmodules.logger.info(\"request body not valid \" + TractorId);\n }\n \n response.complete();\n\n}" }, "FetchBookingWeatherData" : { "code" : "/**\n * Fetch new bookings that were posted 30 minutes ago and update their weather information\n * Created: 05/06/2020 by Abdulmajid\n * @param {*} request \n * @param {*} response \n * @param {*} modules \n */\nfunction onRequest(request, response, modules) {\n var bookingCol = modules.collectionAccess.collection(\"ServiceBookings\");\n var API_KEY = \"36b45f00efffeeb4d17f8509fe86d167\";\n \n var apiRequest = modules.request;\n var twoMinutesAgo = modules.moment.utc().subtract(2, \"minutes\").toISOString();\n var dateOneWeekLater = modules.moment.utc().add(5, \"days\").format(\"YYYY-MM-DD\");\n var todaysDate = modules.moment.utc().format(\"YYYY-MM-DD\");\n var countBookings = 0; //Keep track of the number of bookings processed\n \n //Builds the request options per booking before making the request\n var buildRequestOptions = function (booking) {\n var lat = booking.latitude;\n var lng = booking.longitude;\n var weatherURL = 'https://api.openweathermap.org/data/2.5/forecast?units=metric&lat=' + lat + '&lon=' + lng + '&APPID='+API_KEY;\n var requestOptions = {\n uri: weatherURL,\n method: \"GET\",\n strictSSL: false,\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json'\n },\n json: true\n };\n \n return requestOptions;\n }\n \n //Ends this script if all bookings have been processed\n var finish = function(){\n if (countBookings <= 0){\n modules.logger.info(\"Bookings weather info processed successfully\");\n response.complete();\n }\n }\n \n //Removes weather data of other days leaving that of the booking service date\n var filterWeatherData = function(weather, serviceDate){\n var weatherInfoList = weather.list.filter(function(currWeather){\n return currWeather.dt_txt.split(\" \")[0] === serviceDate;\n })\n \n return JSON.stringify({\n cod: weather.cod,\n message: weather.message,\n cnt: weather.cnt,\n list: weatherInfoList\n });\n }\n \n //Updates the booking with weather data\n var updateBooking = function(booking, weather){\n var serviceDate = booking.serviceDate;\n var cleanedWeatherData = filterWeatherData(weather, serviceDate);\n var timeNow = modules.moment.utc().format(\"YYYY-MM-DD HH:mm:ss\");\n var weatherUpdateDoc = {\n \"WeatherCondition\": cleanedWeatherData,\n \"updatedAt\": timeNow,\n \"_kmd.lmt\": new Date().toISOString()\n }\n \n //Updates the booking with weather data and timestamps\n bookingCol.update({\"_id\": booking._id}, {$set: weatherUpdateDoc}, function(bookingErr, bookingUpdated){\n modules.logger.info(\"Weather data for booking \"+booking._id+\" updated successfully\");\n countBookings--;\n finish();\n });\n }\n \n //Makes the request to open weather map to retrieve weather data for all bookings\n var fetchWeatherInfo = function (bookings) {\n modules.logger.info(\"About to fetch weather data for \"+bookings.length+\" bookings\");\n bookings.forEach(function(booking){\n var requestOptions = buildRequestOptions(booking);\n modules.logger.info(\"Weather Url: \"+requestOptions.uri);\n apiRequest.get(requestOptions, function (err, resp, body) {\n modules.logger.info(\"BODY: \"+body);\n if (body && body.cod == 200) {\n modules.logger.info(\"Weather info found for \"+booking._id);\n updateBooking(booking, body);\n } else {\n modules.logger.info(\"Could not find weather info for \"+booking._id+\", \"+err);\n countBookings--;\n finish();\n }\n });\n });\n }\n \n //Removes bookings without latitude and longitude or those whose latitude and longitude are zero or undefined\n var filterInvalidBookings = function (bookingList) {\n return bookingList.filter(function (booking) {\n return booking.latitude && booking.longitude;\n });\n }\n \n //Builds the booking query\n var bookingQuery = {\n $and: [\n { \"serviceDate\": {$gte: todaysDate }},\n { \"serviceDate\": {$lte: dateOneWeekLater }},\n { \"_kmd.lmt\": {$gte: twoMinutesAgo }}\n ]\n };\n \n //Entry point, finds all bookings that satisfy query criteria\n modules.logger.info(\"time thirty minutes ago: \"+twoMinutesAgo);\n bookingCol.find(bookingQuery, function(bookingErr, bookingList) {\n if (bookingList && bookingList.length > 0){\n modules.logger.info(\"Booking(s) found: \" + bookingList.length);\n var cleanBookings = filterInvalidBookings(bookingList);\n countBookings = cleanBookings.length;\n fetchWeatherInfo(cleanBookings);\n // response.complete(); //TODO: Remove\n } else {\n modules.logger.info(\"Nothing to process: \" + bookingErr);\n response.complete();\n }\n });\n }" } }, "NotificationGeoFenceMaintenance" : { "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPreSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\nfunction onPreSave(request, response, modules) {\n\tvar logger = modules.logger;\n\t\n\tvar token = \"\";\n\n collectionAccess.collection('TwoTrackApiToken').findOneAsync({id: 9228383772})\n .then(function(accessToken) {\n token = accessToken;\n },\n function(err) {\n \n return response.error(err);\n });\n\t\n\tmodules.collectionAccess.collection('TractorDetail').find({}, function (err, docs) {\n if (err) {\n logger.error('Query failed: '+ err);\n } else {\n docs.forEach(function(doc, a) {\n if(doc.Latitude === 0 || doc.Latitude === 'undefined'){\n response.continue();\n } else {\n var tractorId = doc.TractorID;\n var latitudeList = doc.Latitude;\n var longitudeList = doc.Longitude;\n var requestData={\n \"token\": \"\"+token.token+\"\",\n \"trackers\": [{\"trackerId\": tractorId}]\n };\n var requestOptions = {\n 'url': 'https://hellotractor.2-track.com:8080/api/status',\n headers: {\n \"Version\" : \"v1\",\n \"Content-Type\" : \"application/json\"\n },\n json:requestData,\n };\n modules.request.post(requestOptions, function(error, resp, body){\n if (error){\n logger.info(\"error=\"+error);\n response.body = {error: error.message};\n response.complete(400);\n }else{\n var respData=resp.body.data;\n if(respData !==null && respData!== \"\"){\n respData.forEach(function(data,a){\n var latitude = data.lat;\n var longitude = data.lon;\n var answer = checkcheck(latitude, longitude, latitudeList, longitudeList);\n \n function checkcheck (xLat, yLng, latList, lngList) {\n var i, j=latList.length-1 ;\n var oddNodes=false;\n var polyLat = latList;\n var polyLng = lngList;\n for (i=0; i<latList.length; i++) {\n if((polyLng[i]< yLng && polyLng[j]>=yLng || polyLng[j]< yLng && polyLng[i]>=yLng) && (polyLat[i]<=xLat || polyLat[j]<=xLat)) {\n oddNodes^=(polyLat[i]+(yLng-polyLng[i])/(polyLng[j]-polyLng[i])*(polyLat[j]-polyLat[i])<xLat); \n }\n j=i;\n }\n logger.info(\"******\" + oddNodes);\n if(oddNodes === 0){\n var entity = modules.kinvey.entity();\n entity.TractorId = tractorId;\n entity.Message = \"The tractor is out of geofence area\";\n modules.collectionAccess.collection(\"NotificationGeoFence\").save(entity, function(err) {\n response.continue();\n });\n }\n return oddNodes;\n }\n });\n }else{\n response.continue();\n }\n response.continue();\n }\n });\n }\n });\n }\n\t});\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n", "hasOnPreSave" : true }, "TractorActivityData" : { "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n//Flags indicating when each function has been executed regardless of an error\nvar isSendToBlockchainDone = false;\nvar isSaveDistanceTravelledToDailyTractorActivityDataDone = false;\n\nfunction onPostSave(request, response, modules) {\n var async = modules.async;\n var httpRequest = modules.request;\n var logger = modules.logger;\n\n async.parallel({\n saveDistanceTravelledToDailyTractorActivityData: async.apply(\n saveDistanceTravelledToDailyTractorActivityData,\n modules,\n response\n ),\n sendToBlockchain: async.apply(\n sendToBlockchain,\n logger,\n response,\n httpRequest\n )\n });\n}\n\n//!important - Called when all functions have been executed\nfunction callback(response) {\n if (isSendToBlockchainDone && isSaveDistanceTravelledToDailyTractorActivityDataDone) {\n response.continue();\n }\n}\n\nfunction sendToBlockchain(logger, response, httpRequest) {\n var msg = buildBlockchainMessage(response);\n logger.info(msg);\n var baseUrl = getBookingManagerBaseUrl();\n var url = baseUrl+\"/api/v1/tractors/\"+response.body.TractorID+\"/tractor-activity-data\";\n logger.info(url);\n var authorization = getBookingManagerToken();\n httpRequest.post(blockchainRequestOptions(msg, url, authorization), function(\n blockErr,\n blockRes,\n blockBody\n ) {\n logger.info(\n \"Blockchain Response: \" +\n JSON.stringify(blockErr) +\n \", \" +\n JSON.stringify(blockRes) +\n \", \" +\n JSON.stringify(blockBody)\n );\n if(blockRes.status != 200){\n \n var doc = {\n \turl: url, \n msg: msg, \n httpStatus: blockRes.status, \n no_tries: 0\n };\n var collectionName = getFailedTransactionsCollection();\n var failedPosts = modules.collectionAccess.collection(collectionName);\n \n \tfailedPosts.save(doc, function(err, docs){\n if(err){\n logger.info(err);\n }\n\n isSendToBlockchainDone = true;\n callback(response);\n });\n \n } else {\n isSendToBlockchainDone = true;\n callback(response);\n }\n });\n}\n\nfunction buildBlockchainMessage(response) {\n var msg = {\n _id: response.body._id,\n TractorID: response.body.TractorID,\n ActivityID: response.body.ActivityID,\n EventCode: response.body.EventCode,\n EventName: response.body.EventName,\n Speed: response.body.Speed,\n Odometer: response.body.Odometer,\n Idle: response.body.Idle,\n IsGPSValid: response.body.IsGPSValid,\n Lat: response.body.Lat,\n Lng: response.body.Lng,\n DirectionEW: response.body.DirectionEW,\n DirectionNS: response.body.DirectionNS,\n Altitude: response.body.Altitude,\n IgnitionStatus: response.body.IgnitionStatus,\n BatteryVoltage: response.body.BatteryVoltage,\n SatelliteNumber: response.body.SatelliteNumber,\n Street: response.body.Street,\n Town: response.body.Town,\n County: response.body.County,\n Country: response.body.Country,\n ActivityUTCDate: response.body.ActivityUTCDate,\n };\n\n return msg;\n}\n\nfunction blockchainRequestOptions(msg, url, authorization) {\n //Send to IBM Swagger (REST API)\n var requestOptions = {\n uri: url,\n headers: {\n Authorization: authorization\n },\n json: msg\n };\n\n return requestOptions;\n}\n\n\n\n\nfunction saveDistanceTravelledToDailyTractorActivityData (modules, response){\n var count = 0; \n modules.collectionAccess.collection('TractorDetail').find({},function(error,tractorDetails){\n if(!error && tractorDetails.length > 0){\n tractorDetails.forEach(function(tractor){\n if(tractor.TractorID.toString().length == 6){\n \n var today = new Date();\n \n var year = today.getUTCFullYear();\n var month = today.getUTCMonth();\n var day = today.getUTCDate();\n \n var todayStr = year.toString() + '-' + month.toString() + '-' + day.toString();\n var countActivities = 0;\n\n modules.collectionAccess.collection('TractorActivityData').find({'ActivityUTCDate':{$gte:todayStr},'EventName':'Journey Started'}, function(err, tractorActivities){\n if(!err && tractorActivities.length > 0){\n tractorActivities.forEach(function(a){\n if(a.EventName === 'Journey End'){\n a.distanceTravelled = activity.odometer - a.odometer;\n modules.collectionAccess.collection('DailyTractorActivityData').save(a,function(e){\n\n countActivities++;\n if (countActivities == tractorActivities.length){\n count++;\n shouldContinue(tractorDetails);\n }\n });\n } else {\n\n countActivities++;\n if (countActivities == tractorActivities.length){\n count++;\n shouldContinue(tractorDetails);\n }\n }\n });\n \n } else {\n count++;\n shouldContinue(tractorDetails);\n }\n });\n \n } else {\n count++;\n shouldContinue(tractorDetails);\n }\n\n \n });\n } else {\n count++;\n shouldContinue(tractorDetails);\n }\n });\n\n var shouldContinue = function (tractorDetails){\n if (count == tractorDetails.length){\n isSaveDistanceTravelledToDailyTractorActivityDataDone = true;\n callback(response);\n }\n }\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n", "hasOnPostSave" : true }, "UserFeedback" : { "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\nfunction onPostSave(request, response, modules) {\n// var logger = modules.logger;\n// logger.info(response.body);\n \n var email = modules.email;\n email.send(\n response.body.username,\n 'Hello Tractor <support@hellotractor.com>',\n 'User Feedback from '+response.body.username,\n request.body.feedback, \n null,\n null,\n //\"obi@hellotractor.com\",\n function(err, result) {\n response.continue();\n });\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n", "hasOnPostSave" : true }, "OldDailyTractorActivity" : { "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostFetch 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\nfunction onPostFetch(request, response, modules) {\n var collectionAccess = modules.collectionAccess,\n async = modules.async,\n logger = modules.logger,\n moment = modules.moment;\n\n if(request.entityId) {\n if(response.body.OperatorID) {\n collectionAccess.collection('TractorOperator').findOneAsync({OperatorID: response.body.OperatorID})\n .then(function(operator) {\n logger.info(operator);\n response.body.operator = operator;\n return response.complete(200);\n }, function(err) {\n return response.error(err);\n });\n } else {\n return response.complete(200);\n }\n } else {\n //if we try to fetch bulk of daily activities we wont return all fields,\n //because it's quite a lot of data. We return only fields that we need to\n //show info correct\n response.body = response.body.map(function(entity) {\n return {\n _id: entity._id,\n StartActiveData: entity.StartActiveData,\n LastActiveData: entity.LastActiveData,\n AverageSpeed: entity.AverageSpeed,\n HectaresServiced: entity.HectaresServiced ? entity.HectaresServiced : 0,\n DistanceTravelled: entity.DistanceTravelled ? entity.DistanceTravelled:0,\n TotalTimeActive: entity.TotalTimeActive ? entity.TotalTimeActive:0,\n TotalTimeIdle: entity.TotalTimeIdle ? entity.TotalTimeIdle:0,\n Revenue: entity.Revenue,\n RevenueCurrency: entity.RevenueCurrency,\n RevenueType: entity.RevenueType ? entity.RevenueType : 101,\n Hectares: entity.Hectares,\n _acl: entity._acl,\n _kmd: entity._kmd\n }\n });\n return response.complete(200);\n }\n}\n\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n", "hasOnPostFetch" : true }, "BookingAgents" : { "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n//Flags indicating when each function has been executed regardless of an error\nvar isSendToAWSDone = false;\nvar isSendToBlockchainDone = false;\n\nfunction onPostSave(request, response, modules) {\n var async = modules.async;\n var httpRequest = modules.request;\n var logger = modules.logger;\n var lodash = modules.lodash;\n var moment = modules.moment;\n\n async.parallel({\n sendToAWSBackend: async.apply(\n sendToAWSBackend,\n httpRequest,\n logger,\n response\n ),\n sendToBlockchain: async.apply(\n sendToBlockchain,\n logger,\n response,\n httpRequest,\n lodash,\n \tmoment\n )\n });\n}\n\n//!important - Called when all functions have been executed\nfunction callback(response) {\n if (isSendToAWSDone && isSendToBlockchainDone) {\n response.continue();\n }\n}\n\n\n/**\n * **********************************************************************************\n * Sends the booking request to IBM Swagger REST API\n * @param logger An object of the {@link modules.logger} class\n * @param response The response to the client request\n * @param httpRequest An object of the {@link modules.request} class\n * **********************************************************************************\n */\nfunction sendToBlockchain(logger, response, httpRequest, lodash, moment) {\n var msg = buildBlockchainMessage(logger, response, lodash, moment);\n var baseUrl = getBookingManagerBaseUrl();\n var url = baseUrl + \"/api/v1/users/add-booking-agent\";\n httpRequest.post(blockchainRequestOptions(logger, response, lodash, moment, url, getBookingManagerToken(), msg), function(\n blockErr,\n blockRes,\n blockBody\n ) {\n logger.info(\n \"Blockchain Response: \" +\n JSON.stringify(blockErr) +\n \", \" +\n JSON.stringify(blockRes) +\n \", \" +\n JSON.stringify(blockBody)\n );\n if(blockRes.status != 200){\n\n var doc = {\n \turl: url, \n msg: msg, \n httpStatus: blockRes.status, \n no_tries: 0\n };\n var collectionName = getFailedTransactionsCollection();\n var failedPosts = modules.collectionAccess.collection(collectionName);\n \n failedPosts.save(doc, function(err, docs){\n if(err){\n logger.info(err);\n }\n\n //Done\n isSendToBlockchainDone = true;\n callback(response);\n }); \n \n } else {\n isSendToBlockchainDone = true;\n callback(response);\n }\n });\n}\n\n function buildBlockchainMessage(logger,response,lodash, moment){\n \n logger.info(response.body);\n \n var pick = lodash.pick(response.body,['_id','bookingAgentID','createdAt','orgID','syncStatus','updatedAt', 'userId'])\n pick['created_at'] = moment(lodash.get(response.body,'_kmd.ect')).toISOString();\n pick['updated_at'] = moment(lodash.get(response.body,'_kmd.lmt')).toISOString();\n pick['organizationIds'] = [pick['orgID']];\n pick['acl'] = response.body._acl.creator;\n delete pick['orgID'];\n\n pick['bookingAgentId']=pick['bookingAgentID'];\n pick['userProfileId']=pick['userId'];\n delete pick['userId'];\n\n\n delete pick['bookingAgentID'];\n \n delete pick['createdAt'];\n delete pick['updatedAt'];\n\n logger.info(\"picking items\");\n \n logger.info(pick);\n \n return pick; \n\n}\n\nfunction blockchainRequestOptions(logger, response, lodash, moment, url, authorization, msg) {\n //Send to IBM Swagger (REST API)\n var requestOptions = {\n uri: url,\n headers: {\n Authorization: authorization\n },\n json: msg\n };\n\n return requestOptions;\n}\n\n\n\n/**\n * *******************************************************************************************\n * Makes a copy of the booking agent on the AWS Backend\n * @param httpRequest An object of the HTTP {@link modules.request} from the modules package\n * @param logger An object of the {@link modules.logger} library from the modules package\n * @param response The response to the client request\n * ********************************************************************************************\n */\n\nfunction sendToAWSBackend(httpRequest, logger, response) {\n var requestOptions = awsRequestOptions(response);\n httpRequest.post(requestOptions, function(awsErr, awsResp, awsBody) {\n logger.info(\"Results: \" + awsErr + \", \" + JSON.stringify(awsResp) + \", \" + awsBody);\n\n //Done\n isSendToAWSDone = true;\n callback(response);\n });\n}\n\nfunction awsRequestOptions(response) {\n var url = AWS_BACKEND_HOST+'/kinvey/api/bookingagents';\n var msg = {\n op: \"create\",\n data: response.body\n };\n\n var requestOptions = {\n uri: url,\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n Version: \"v1\"\n },\n json: msg\n };\n\n return requestOptions;\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPreSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\nfunction onPreSave(request, response, modules) {\n var logger = modules.logger,\n collectionAccess = modules.collectionAccess;\n var bookingAgentID = request.body.bookingAgentID;\n \n collectionAccess.collection('BookingAgents')\n .findOneAsync({bookingAgentID: bookingAgentID})\n .then(function(bookingAgent) {\n if(bookingAgent) {\n logger.info(\"Previous: \"+JSON.stringify(bookingAgent));\n logger.info(\"New: \"+JSON.stringify(request.body));\n deleteInitBookingAgentAndSaveNew(request, response, modules, bookingAgent);\n } else {\n response.continue();\n }\n }, function(err) {\n return response.error(err);\n });\n}\n\n//Fix for duplicate booking agent created\nfunction deleteInitBookingAgentAndSaveNew(request, response, modules, initBookingAgent){\n request.body._id = initBookingAgent._id;\n request.body._acl = initBookingAgent._acl;\n modules.collectionAccess.collection('BookingAgents').remove({_id:initBookingAgent._id}, function(err, bookingAgent){\n response.continue();\n });\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n", "hasOnPostSave" : true, "hasOnPreSave" : true }, "ServiceBookings" : { "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n//Flags indicating when each function has been executed regardless of an error\nvar isSendToAWSDone = false;\nvar isSendToBlockchainDone = false;\n\nfunction onPostSave(request, response, modules) {\n var async = modules.async;\n var httpRequest = modules.request;\n var logger = modules.logger;\n var moment = modules.moment\n\n async.parallel({\n sendToAWSBackend: async.apply(\n sendToAWSBackend,\n httpRequest,\n logger,\n response\n ),\n sendToBlockchain: async.apply(\n sendToBlockchain,\n logger,\n response,\n httpRequest,\n \tmoment,\n \tmodules\n )\n });\n}\n\n//!important - Called when all functions have been executed\nfunction callback(response) {\n if (isSendToAWSDone && isSendToBlockchainDone) {\n response.continue();\n }\n}\n\n/**\n * *******************************************************************************************\n * Makes a copy of the booking on the AWS Backend\n * @param httpRequest An object of the HTTP {@link modules.request} from the modules package\n * @param logger An object of the {@link modules.logger} library from the modules package\n * @param response The response to the client request\n * ********************************************************************************************\n */\n\nfunction sendToAWSBackend(httpRequest, logger, response) {\n var requestOptions = awsRequestOptions(response);\n httpRequest.post(requestOptions, function(awsErr, awsResp, awsBody) {\n logger.info(\n \"Results: \" + awsErr + \", \" + JSON.stringify(awsResp) + \", \" + awsBody\n );\n\n //Done\n isSendToAWSDone = true;\n callback(response);\n });\n}\n\nfunction awsRequestOptions(response){\n var url = AWS_BACKEND_HOST+'/kinvey/api/bookings'; \n modules.logger.info( url );\n //TODO: test with -https://webhook.site/b61cdec4-27e0-47f0-b7c3-c1f7fb5eb29e\n var msg = {\n op: \"create\",\n data: response.body\n };\n\n var requestOptions = {\n uri: url,\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n Version: \"v1\"\n },\n json: msg\n };\n\n return requestOptions;\n}\n\n/**\n * **********************************************************************************\n * Sends the booking request to IBM Swagger REST API\n * @param logger An object of the {@link modules.logger} class\n * @param response The response to the client request\n * @param httpRequest An object of the {@link modules.request} class\n * **********************************************************************************\n */\nfunction sendToBlockchain(logger, response, httpRequest, moment, modules) {\n var msg = buildBlockchainMessage(response, moment);\n var baseUrl = getBookingManagerBaseUrl();\n var url = baseUrl + \"/api/v1/bookings\";\n httpRequest.post(blockchainRequestOptions(response, msg, url), function(\n blockErr,\n blockRes,\n blockBody\n ) {\n logger.info(\n \"Blockchain Response: \" +\n JSON.stringify(blockErr) +\n \", \" +\n JSON.stringify(blockRes) +\n \", \" +\n JSON.stringify(blockBody)\n );\n if(blockRes.status != 200){\n \n var doc = {\n \turl: url, \n msg: msg, \n httpStatus: blockRes.status, \n no_tries: 0\n };\n var failedPosts = modules.collectionAccess.collection(\"FailedPosts\");\n \n \tfailedPosts.save(doc, function(err, docs){\n if(err){\n logger.info(err);\n }\n\n //Done\n isSendToBlockchainDone = true;\n callback(response); \n });\n \n } else {\n isSendToBlockchainDone = true;\n callback(response);\n }\n });\n}\n\nfunction buildBlockchainMessage(response, moment) {\n var tractorPairedTo;\n var tractorOperatorId;\n var hectaresServiced;\n var jobEndTime;\n var jobStartTime;\n if(response.body.OperatorID == 0){\n response.body.OperatorID = null;\n }\n var msg = {\n _id: response.body._id,\n archivedBy: response.body.BookingArchived,\n bookingAgentId: response.body.bookingAgentID,\n bookingId: response.body.bookingID,\n bookingStatus: response.body.bookingStatus,\n clusterId: response.body.clusterID,\n dateCompleted: moment(response.body.dateCompleted).toISOString(),\n datePaired: moment(response.body.datePaired).toISOString(),\n distanceToDestination: response.body.distanceToDestination,\n hectaresServiced: response.body.hectaresServiced,\n jobEndTime: response.body.jobEndTime,\n jobStartTime: response.body.jobStartTime,\n serviceDate: response.body.serviceDate,\n serviceType: response.body.serviceType,\n syncStatus: response.body.syncStatus,\n toServiceDate: moment(response.body.TOServiceDate).toISOString(),\n tractorOperatorId: response.body.OperatorID,\n tractorPairedToId: response.body.tractorPairedTo,\n latitude: response.body.latitude,\n longitude: response.body.longitude,\n farmLocation: response.body.farmLocation,\n orgCode: response.body.orgID,\n primaryCrop: response.body.primaryCrop,\n secondaryCrop: response.body.secondaryCrop,\n farmLocation: response.body.farmLocation,\n weatherCondition: response.body.weatherCondition,\n created_at: moment(response.body._kmd.ect).toISOString(),\n updated_at: moment(response.body.updatedAt).toISOString()\n };\n\n return msg;\n}\n\nfunction blockchainRequestOptions(response, msg, url) {\n //Send to IBM Swagger (REST API)\n var authorization = getBookingManagerToken();\n\n \n var requestOptions = {\n uri: url,\n headers: {\n Authorization: authorization\n },\n json: msg\n };\n\n return requestOptions;\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPreSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\nfunction onPreSave(request, response, modules) {\n\n //Collections\n var userAccountsCol = modules.collectionAccess.collection(\"UserAccounts\");\n var usersCol = modules.collectionAccess.collection(\"user\");\n var notificationsCol = modules.collectionAccess.collection(\"Notification\");\n var bookingsCol = modules.collectionAccess.collection(\"ServiceBookings\");\n var tractorOwnersCol = modules.collectionAccess.collection(\"TractorOwner\");\n\n //Modules\n var push = modules.push;\n var log = modules.logger;\n\n //Constants, Keys or identifiers\n var NEW = 99, PAIRED = 100, COMPLETED = 101, DECLINED = 102, CANCELLED = 103;\n \n //Counters\n var counters;\n var totalCount;\n \n //Variables\n var body = request.body; \n var wasTractorNearby = body.wasTractorNearby;\n var clusterID = body.clusterID;\n var serviceType = body.serviceType;\n var hectaresServiced = body.hectaresServiced;\n var distanceToDestination = body.distanceToDestination;\n var orgId = body.orgID;\n var bookingStatus = body.bookingStatus;\n var earliestBooking;\n\n //Find bookings in cluster\n bookingsCol.find({clusterID: clusterID}, {sort: {serviceDate: 1}}, function(bookingsErr, existingBookings){\n if (existingBookings && existingBookings.length > 0){\n log.info(\"Existing bookings found \"+existingBookings.length);\n earliestBooking = existingBookings[0]; //Earliest booking\n totalCount = existingBookings.length; //Total number of existing bookings found\n counters = getBookingsCount(existingBookings);\n whatStatusAndSendNotification(counters, totalCount, existingBookings, hectaresServiced, earliestBooking, body, serviceType, clusterID, orgId);\n\n } else if (bookingStatus == 0){\n //It's a new booking in this cluster\n log.info(\"Completely new booking in a new cluster\");\n existingBookings = [];\n earliestBooking = request.body;\n totalCount = 1;\n counters = getBookingsCount(existingBookings);\n confirmNewBookingNotificationThreshold(existingBookings, hectaresServiced);\n\n } else {\n //No bookings found in cluster\n log.info(\"No existing bookings in cluster found. Possibly an unclustered booking that has been paired, completed, etc. No further action\");\n done();\n }\n });\n\n var whatStatusAndSendNotification = function (counters, totalCount, existingBookings, hectaresServiced, earliestBooking, body, serviceType, clusterId, orgId){\n if ((bookingStatus == 1 || bookingStatus == 2) && (counters.PAIRED + 1) == totalCount){\n //TODO: Send notification to booking agent\n log.info(\"About to send paired notification to BA\");\n sendNotificationToBookingAgents(earliestBooking, PAIRED, existingBookings, body, serviceType, clusterId, orgId);\n // (earliestBooking, newStatus, existingBookings, body, serviceType, clusterId, orgId) \n\n } else if (isDeletedOrgId(orgId)){\n //TODO: Cancelled booking\n log.info(\"About to send cancelled notification to BA\"); \n sendNotificationToBookingAgents(earliestBooking, CANCELLED, existingBookings, body, serviceType, clusterId, orgId);\n\n } else if (isArchivedBooking(body)){\n //TODO: Declined booking\n log.info(\"About to send declined notification to BA\");\n sendNotificationToBookingAgents(earliestBooking, DECLINED, existingBookings, body, serviceType, clusterId, orgId);\n\n } else if (bookingStatus == 0){\n //TODO: New booking\n log.info(\"About to send new booking notification to TO\"); \n confirmNewBookingNotificationThreshold(existingBookings, hectaresServiced, existingBookings, body, serviceType, clusterId, orgId);\n\n } else if (bookingStatus == 3){\n //TODO: Completed booking\n log.info(\"About to send completed booking notification to BA\"); \n sendNotificationToBookingAgents(earliestBooking, COMPLETED, existingBookings, body, serviceType, clusterId, orgId);\n\n } else {\n //TODO: No status change\n log.info(\"No status change found. Just continue\");\n done();\n }\n }\n\n var confirmNewBookingNotificationThreshold = function (existingBookings, hectaresServiced){\n if (serviceType == 107){\n log.info(\"New trailer service found\");\n var totalDistance = parseFloat(getTotalDistance(existingBookings)) + parseFloat((distanceToDestination/1000.0).toFixed(2));\n if (totalDistance >= 30 || wasTractorNearby){\n //Send notification to tractor owners\n log.info(\"New trailer service exceeding 30km found\");\n sendNotificationToTractorOwners(existingBookings);\n } else {\n log.info(\"Distance too little\");\n done();\n }\n } else {\n log.info(\"New hectarage service found\");\n var totalExistingHectares = getTotalHectares(existingBookings);\n var totalHectares = parseFloat(getTotalHectares(existingBookings)) + parseFloat(hectaresServiced);\n log.info(\"New hectarage service found \"+totalHectares+\", \"+totalExistingHectares+\", \"+hectaresServiced);\n if (totalHectares >= 30 || wasTractorNearby){\n //Send notification to tractor owners\n log.info(\"New hectarage service exceeding 30 Ha found\");\n sendNotificationToTractorOwners(existingBookings);\n } else {\n log.info(\"Hectarage too little\");\n done();\n }\n } \n }\n\n var sendNotificationToTractorOwners = function (existingBookings){\n var tractorOwnerCreatorIdMap = {};\n usersCol.find({orgIDs: orgId, user_type: {$ne: 2}}, function(userErr, users){\n if (users && users.length > 0){\n tractorOwnersCol.find({orgID: orgId }, function(tractorOwnersErr, tractorOwners){\n if (tractorOwners){\n tractorOwners.forEach(function(tractorOwner){\n tractorOwnerCreatorIdMap[tractorOwner._acl.creator] = tractorOwner;\n });\n } else {\n log.info(\"No tractor owner exists with org id of \"+orgId);\n }\n\n var counter = 0;\n users.forEach(function(user){\n log.info(\"Build new booking notification\");\n var bookingAgent = getBookingAgentFromData(request.body);\n var notification = buildNewBookingsNotification(user, existingBookings, distanceToDestination, hectaresServiced, serviceType, earliestBooking, orgId, clusterID, bookingAgent); //TODO: create function\n \n log.info(\"New notificaiton built\");\n notificationsCol.save(notification.notificationToSave, function(notificationErr){\n log.info(\"New booking notificaiton saved\");\n if (tractorOwnerCreatorIdMap[user._acl.creator]){ //TODO: tractorOwnerCreatorIdMap[user._acl.creator].receiveNewBookingNotification\n push.sendPayload(user, {}, {}, notification.notificationToSend, function(res) {\n log.info(\"Push notification sent\");\n counter++;\n if (counter >= users.length){\n log.info(\"All notifications sent\");\n done();\n }\n });\n } else {\n log.info(\"Tractor owner not found in TractorOwner \"+user._acl.creator);\n counter++\n if (counter >= users.length){\n done();\n }\n }\n });\n });\n });\n } else {\n log.info(\"No tractor owner as user exists with org id of \"+orgId);\n done();\n }\n });\n }\n\n var sendNotificationToBookingAgents = function(earliestBooking, newStatus, existingBookings, body, serviceType, clusterId, orgId){\n log.info(\"About to send notification to booking agents\");\n usersCol.findOne({\"_acl.creator\": earliestBooking._acl.creator}, function(err, bookingAgent){\n log.info(\"Finished finding booking agent with creator: \"+earliestBooking._acl.creator);\n if (bookingAgent){\n log.info(\"Booking agent found\");\n var archived = getArchivedBy(body);\n if (archived){\n log.info(\"Booking archived: \"+archived.CreatorID);\n usersCol.findOne({\"_acl.creator\": archived.CreatorID}, function(tractorOwnerErr, tractorOwner){\n if (tractorOwner){\n log.info(\"Tractor owner who archived booking found\");\n saveAndSendNotificationToBookingAgents(newStatus, tractorOwner, existingBookings, body, earliestBooking, serviceType, clusterId, orgId, bookingAgent);\n // (newStatus, bookingAgent, tractorOwner, existingBookings, body, earliestBooking, serviceType, clusterId, orgId)\n } else {\n log.info(\"Tractor owner who archived booking not found\");\n saveAndSendNotificationToBookingAgents(newStatus, null, existingBookings, body, earliestBooking, serviceType, clusterId, orgId, bookingAgent);\n }\n //Save and send notification to booking agent\n });\n } else {\n //Save and send notification to booking agent\n log.info(\"Booking not archived\");\n saveAndSendNotificationToBookingAgents(newStatus, null, existingBookings, body, earliestBooking, serviceType, clusterId, orgId, bookingAgent);\n }\n } else {\n log.info(\"Booking agent not found: Cant send notification\");\n done();\n }\n });\n }\n\n var saveAndSendNotificationToBookingAgents = function(newStatus, tractorOwner, existingBookings, body, earliestBooking, serviceType, clusterId, orgId, bookingAgentUser){\n log.info(\"Building required booking notification\");\n var notifications;\n if (newStatus == DECLINED){\n log.info(\"About to build declined notification\"); \n notifications = buildDeclinedBookingsNotification(tractorOwner, existingBookings, body, earliestBooking, serviceType, clusterId, orgId, bookingAgentUser);\n\n } else if (newStatus == CANCELLED){\n log.info(\"About to build cancelled notification\");\n notifications = buildCancelledBookingsNotification(tractorOwner, existingBookings, earliestBooking, body, clusterId, serviceType, orgId, bookingAgentUser);\n\n } else if (newStatus == COMPLETED){\n log.info(\"About to build completed notification\");\n notifications = buildCompletedBookingsNotification(existingBookings, body, serviceType, earliestBooking, clusterId, orgId, bookingAgentUser);\n\n } else if (newStatus == PAIRED){\n log.info(\"About to build paired notification\");\n notifications = buildPairedBookingsNotification(existingBookings, body, earliestBooking, serviceType, clusterId, orgId, bookingAgentUser);\n }\n\n log.info(\"Notification built\");\n if (notifications){\n log.info(\"About to save built notification\");\n notificationsCol.save(notifications.notificationToSave, function(notificationErr){\n log.info(\"Booking agent booking notificaiton saved\");\n push.sendPayload(bookingAgentUser, {}, {}, notifications.notificationToSend, function(res) {\n log.info(\"Push notification sent to booking agent\");\n done();\n });\n });\n } else {\n log.info(\"Notification could not be built\");\n done();\n }\n \n }\n\n //Build declined booking notification\n var buildDeclinedBookingsNotification = function(tractorOwner, existingBookings, body, earliestBooking, serviceType, clusterId, orgId, bookingAgentUser) {\n var revisedMessage;\n log.info(\"Computing total distance for declined notification\"); \n var totalDistance = parseFloat((parseFloat(getTotalDistance(existingBookings))/1000.0).toFixed(2));\n log.info(\"Computing total hectares for declined notification\"); \n var totalHectares = parseFloat(parseFloat(getTotalHectares(existingBookings)).toFixed(2));\n log.info(\"Creating booking agent from data for declined notification\");\n var bookingAgent = getBookingAgentFromData(body);\n\n log.info(\"Declined booking notification\");\n\n if (serviceType == 107){\n revisedMessage = \"Your \"+totalDistance+\" km \"+getServiceName(serviceType)+\" service request scheduled for \"+dateToHumanReadable(earliestBooking.serviceDate)+\" has been declined\";\n } else {\n revisedMessage = \"Your \"+totalHectares+\" Ha \"+getServiceName(serviceType)+\" service request scheduled for \"+dateToHumanReadable(earliestBooking.serviceDate)+\" has been declined\"; \n }\n\n var notification = {\n _acl: earliestBooking? earliestBooking._acl: \"\", \n message: revisedMessage,\n userId: earliestBooking? earliestBooking._acl.creator: \"\",\n read: false,\n type: \"action\",\n action: \"declined_booking_cluster\",\n orgID: orgId,\n serviceType: serviceType,\n clusterID: clusterId\n };\n\n var notificationToSave = modules.kinvey.entity(notification);\n\n var notificationToSend = JSON.parse(JSON.stringify(notificationToSave));\n notificationToSend.id = clusterId;\n notificationToSend.bookingAgentID = body.bookingAgentID;\n notificationToSend.bookingAgentImageURL = bookingAgent? bookingAgent.profileImageURL:\"\";\n notificationToSend.serviceDate = earliestBooking.serviceDate;\n notificationToSend.tractorOwnerName = tractorOwner? tractorOwner.first_name:\"\";\n\n if (serviceType == 107){\n notificationToSend.hectaresDistance = totalDistance;\n } else {\n notificationToSend.hectaresDistance = totalHectares; \n }\n\n //Append extras to saved notification\n var extras = JSON.stringify(notificationToSend);\n notificationToSave.extras = extras;\n\n return {notificationToSave: notificationToSave, notificationToSend: notificationToSend};\n };\n\n //Build deleted booking notification\n var buildCancelledBookingsNotification = function(tractorOwner, existingBookings, earliestBooking, body, clusterId, serviceType, orgId, bookingAgentUser) {\n var revisedMessage;\n var totalDistance = parseFloat(parseFloat(getTotalDistance(existingBookings)/1000.0).toFixed(2));\n var totalHectares = parseFloat(parseFloat(getTotalHectares(existingBookings)).toFixed(2));\n var bookingAgent = getBookingAgentFromData(body);\n\n if (serviceType == 107){\n revisedMessage = \"Your \"+totalDistance+\" km \"+getServiceName(serviceType)+\" service request scheduled for \"+dateToHumanReadable(earliestBooking.serviceDate)+\" has been cancelled\";\n } else {\n revisedMessage = \"Your \"+totalHectares+\" Ha \"+getServiceName(serviceType)+\" service request scheduled for \"+dateToHumanReadable(earliestBooking.serviceDate)+\" has been cancelled\"; \n }\n\n var notification = {\n _acl: earliestBooking? earliestBooking._acl: \"\",\n message: revisedMessage,\n userId: earliestBooking? earliestBooking._acl.creator:\"\", \n read: false,\n type: \"action\",\n action: \"cancelled_booking_cluster\",\n orgID: orgId,\n serviceType: serviceType,\n clusterID: clusterId\n };\n\n var notificationToSave = modules.kinvey.entity(notification);\n\n var notificationToSend = JSON.parse(JSON.stringify(notificationToSave));\n notificationToSend.id = clusterId;\n notificationToSend.bookingAgentID = body.bookingAgentID;\n notificationToSend.bookingAgentImageURL = bookingAgent? bookingAgent.profileImageURL:\"\";\n notificationToSend.serviceDate = earliestBooking.serviceDate;\n notificationToSend.tractorOwnerName = tractorOwner?tractorOwner.first_name:\"\";\n\n if (serviceType == 107){\n notificationToSend.hectaresDistance = totalDistance;\n } else {\n notificationToSend.hectaresDistance = totalHectares; \n }\n\n //Append extras to saved notification\n var extras = JSON.stringify(notificationToSend);\n notificationToSave.extras = extras;\n\n return {notificationToSave: notificationToSave, notificationToSend: notificationToSend};\n };\n\n //Build paired booking notification\n var buildPairedBookingsNotification = function(existingBookings, body, earliestBooking, serviceType, clusterId, orgId, bookingAgentUser) {\n var revisedMessage;\n var totalDistance = parseFloat((parseFloat(getTotalDistance(existingBookings))/1000.0).toFixed(2));\n var totalHectares = parseFloat(parseFloat(getTotalHectares(existingBookings)).toFixed(2));\n var tractorOperator = getTractorOperatorFromData(body);\n var tractorDetail = getTractorDetailData(body);\n var bookingAgent = getBookingAgentFromData(body);\n log.info(\"Problem service type: \"+serviceType);\n\n log.info(\"Init variables set for paired booking\");\n\n if (serviceType == 107){\n revisedMessage = \"Your \"+totalDistance+\" km \"+getServiceName(serviceType)+\" service request scheduled for \"+dateToHumanReadable(earliestBooking.serviceDate)+\" has been paired to Tractor \"+tractorDetail.license_plate_number;\n } else {\n revisedMessage = \"Your \"+totalHectares+\" Ha \"+getServiceName(serviceType)+\" service request scheduled for \"+dateToHumanReadable(earliestBooking.serviceDate)+\" has been paired to Tractor \"+tractorDetail.license_plate_number; \n }\n\n log.info(\"Service type from earliest booking: \"+serviceType);\n\n var notification = {\n _acl: earliestBooking? earliestBooking._acl: \"\",\n message: revisedMessage,\n userId: earliestBooking? earliestBooking._acl.creator: \"\",\n read: false,\n type: \"action\",\n action: \"paired_booking_cluster\",\n orgID: orgId,\n serviceType: serviceType,\n tractorId: body.tractorPairedTo? Number(earliestBooking.tractorPairedTo):null,\n operatorId: body.OperatorID? Number(earliestBooking.OperatorID):null,\n clusterID: clusterId\n };\n\n var notificationToSave = modules.kinvey.entity(notification);\n\n\n var notificationToSend = JSON.parse(JSON.stringify(notificationToSave));\n notificationToSend.id = clusterId;\n notificationToSend.bookingAgentID = body.bookingAgentID;\n notificationToSend.bookingAgentImageURL = bookingAgent? bookingAgent.profileImageURL? bookingAgent.profileImageURL:\"\":\"\";\n notificationToSend.serviceDate = earliestBooking.serviceDate;\n notificationToSend.tractorName = tractorDetail? tractorDetail.TractorName:\"\";\n notificationToSend.licensePlate = tractorDetail? tractorDetail.license_plate_number:\"\";\n notificationToSend.operatorName = tractorOperator? tractorOperator.OperatorName:\"\";\n notificationToSend.operatorImageURL = tractorOperator? tractorOperator.ProfileImageURL:\"\";\n notificationToSend.operatorPhone = tractorOperator? tractorOperator.MobileNumber:\"\";\n \n\n if (serviceType == 107){\n notificationToSend.hectaresDistance = totalDistance;\n } else {\n notificationToSend.hectaresDistance = totalHectares; \n }\n\n //Append extras to saved notification\n var extras = JSON.stringify(notificationToSend);\n notificationToSave.extras = extras;\n\n return {notificationToSave: notificationToSave, notificationToSend: notificationToSend};\n };\n\n //Build completed booking notification\n var buildCompletedBookingsNotification = function(existingBookings, body, serviceType, earliestBooking, clusterId, orgId, bookingAgentUser) {\n var revisedMessage;\n var totalDistance = parseFloat((parseFloat(getTotalDistance(existingBookings))/1000.0).toFixed(2));\n var totalHectares = parseFloat(parseFloat(getTotalHectares(existingBookings)).toFixed(2));\n\n var tractorOperator = getTractorOperatorFromData(body);\n var tractorDetail = getTractorDetailData(body);\n var bookingAgent = getBookingAgentFromData(body);\n\n if (serviceType == 107){\n revisedMessage = \"Your \"+totalDistance+\" km \"+getServiceName(serviceType)+\" service request scheduled for \"+dateToHumanReadable(earliestBooking.serviceDate)+\" has been marked as complete. Thank you for using Hello Tractor\";\n } else {\n revisedMessage = \"Your \"+totalHectares+\" Ha \"+getServiceName(serviceType)+\" service request scheduled for \"+dateToHumanReadable(earliestBooking.serviceDate)+\" has been marked as complete. Thank you for using Hello Tractor\";\n }\n\n var notification = {\n _acl: earliestBooking._acl,\n message: revisedMessage,\n userId: earliestBooking._acl.creator,\n read: false,\n type: \"action\",\n action: \"completed_booking_cluster\",\n orgID: orgId,\n serviceType: serviceType,\n tractorId: body.tractorPairedTo? Number(body.tractorPairedTo): null,\n operatorId: body.OperatorID? Number(body.OperatorID):null,\n clusterID: clusterId\n };\n\n var notificationToSave = modules.kinvey.entity(notification);\n\n\n var notificationToSend = JSON.parse(JSON.stringify(notificationToSave));\n notificationToSend.id = clusterId;\n notificationToSend.bookingAgentID = body.bookingAgentID;\n notificationToSend.bookingAgentImageURL = bookingAgent?bookingAgent.profileImageURL:\"\";\n notificationToSend.serviceDate = earliestBooking.serviceDate;\n notificationToSend.tractorName = tractorDetail? tractorDetail.TractorName:\"\";\n notificationToSend.licensePlate = tractorDetail? tractorDetail.license_plate_number:\"\";\n notificationToSend.operatorName = tractorOperator? tractorOperator.OperatorName:\"\";\n notificationToSend.operatorImageURL = tractorOperator? tractorOperator.ProfileImageURL:\"\";\n notificationToSend.operatorPhone = tractorOperator? tractorOperator.MobileNumber:\"\";\n\n if (serviceType == 107){\n notificationToSend.hectaresDistance = totalDistance;\n } else {\n notificationToSend.hectaresDistance = totalHectares; \n }\n\n //Append extras to saved notification\n var extras = JSON.stringify(notificationToSend);\n notificationToSave.extras = extras;\n\n return {notificationToSave: notificationToSave, notificationToSend: notificationToSend};\n };\n\n\n var done = function (){\n modules.logger.info(\"Done\");\n response.continue() \n };\n}\n\n/**\n * Building notification objects including new, paired, completed, declined, and cancelled notifications\n * Notifications are built in pairs - notificationToSend and notificationToSave\n */\n\n // Send general new booking notification\nvar buildNewBookingsNotification = function(user, existingBookings, distanceToDestination, hectaresServiced, serviceType, earliestBooking, orgId, clusterId, bookingAgent) {\n \n //Base notification\n var revisedMessage;\n var totalDistance = parseFloat((distanceToDestination/1000.0).toFixed(2));\n var totalHectares = parseFloat(hectaresServiced.toFixed(2));\n if (serviceType == 107){\n revisedMessage = \"You’ve received a new \"+totalDistance+\" km \"+getServiceName(serviceType)+\" service request scheduled for \"+dateToHumanReadable(earliestBooking.serviceDate);\n } else {\n revisedMessage = \"You’ve received a new \"+totalHectares+\" Ha \"+getServiceName(serviceType)+\" service request scheduled for \"+dateToHumanReadable(earliestBooking.serviceDate);\n }\n var notification = {\n _acl: user._acl,\n userId: user._acl.creator,\n message: revisedMessage,\n read: false,\n type: \"action\",\n action: \"new_booking_cluster\",\n orgID: orgId,\n serviceType: serviceType,\n clusterID: clusterId\n };\n \n var notificationToSave = modules.kinvey.entity(notification);\n\n //Build notification to send\n var notificationToSend = JSON.parse(JSON.stringify(notificationToSave));\n\n notificationToSend.id = clusterId;\n notificationToSend.bookingAgentID = bookingAgent?bookingAgent.bookingAgentID:\"\";\n notificationToSend.bookingAgentImageURL = bookingAgent?bookingAgent.profileImageURL:\"\";\n notificationToSend.serviceDate = earliestBooking.serviceDate;\n if (serviceType == 107){\n notificationToSend.hectaresDistance = totalDistance;\n } else {\n notificationToSend.hectaresDistance = totalHectares;\n }\n\n //Append extras to saved notification\n var extras = JSON.stringify(notificationToSend);\n notificationToSave.extras = extras;\n return {notificationToSave: notificationToSave, notificationToSend: notificationToSend};\n};\n\n//Helper functions \n\nfunction isArchivedBooking (body) {\n return body.BookingArchived != null;\n}\n\nfunction dateToHumanReadable (date) {\n return modules.moment(date).format(\"dddd Do MMMM YYYY\");\n}\n\nfunction getTotalHectares (bookings) {\n if (bookings && bookings.length > 0){\n var totalHectares = 0;\n bookings.forEach(function(booking){\n totalHectares += parseFloat(booking.hectaresServiced);\n });\n\n return parseFloat(totalHectares);\n\n } else {\n modules.logger.info(\"No existing bookings\")\n return 0;\n }\n}\n\nfunction getTotalDistance (bookings) {\n if (bookings && bookings.length > 0){\n var totalDistance = 0;\n bookings.forEach(function(booking){\n totalDistance += parseFloat(booking.distanceToDestination);\n });\n\n return parseFloat(totalDistance);\n\n } else {\n return 0;\n }\n}\n\nfunction getBookingAgentFromData (body) {\n var bookingAgent = body.bookingAgentData;\n if (bookingAgent){\n return JSON.parse(bookingAgent);\n } else {\n return;\n }\n}\n\nfunction getTractorOperatorFromData (body) {\n if (body.tractorOperatorData){\n return JSON.parse(body.tractorOperatorData);\n }\n return;\n}\n\nfunction isDeletedOrgId (orgId) {\n return orgId == \"100\";\n}\n\nfunction getUsernameInUserAccounts(userAccounts) {\n var userAccountArr = [];\n userAccounts.forEach(function(userAccount){\n userAccountArr.push(userAccount.username);\n });\n return userAccountArr;\n}\n\nfunction getTractorOwnersAsUsers (users) {\n return users.filter(function(user) {\n return user.user_type == null || user.user_type == 1;\n });\n}\n\nfunction getArchivedBy (body){\n var bookingArchived = body.BookingArchived;\n if (bookingArchived){\n var archived = JSON.parse(bookingArchived);\n if (archived.length > 0){\n return archived[archived.length - 1];\n }\n }\n return;\n}\n\nfunction getTractorDetailData (body){\n var tractorDetailData = body.tractorDetailData;\n if (tractorDetailData){\n return JSON.parse(tractorDetailData);\n }\n return;\n}\n\nfunction getBookingsCount(bookings){\n var counters = {};\n var newCount = 0;\n var pairedCount = 0;\n var completedCount = 0;\n bookings.forEach(function(booking){\n newCount += booking.bookingStatus == 0? 1: 0;\n pairedCount += booking.bookingStatus == 1 || booking.bookingStatus == 2? 1: 0;\n completedCount += booking.bookingStatus == 3? 1: 0;\n });\n counters.NEW = newCount;\n counters.PAIRED = pairedCount;\n counters.COMPLETED = completedCount;\n\n return counters;\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n", "hasOnPostSave" : true, "hasOnPreSave" : true }, "TractorTips" : {}, "TractorAds" : {}, "FarmMeasure" : {}, "FarmMeasures" : { "hasOnPostSave" : true, "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n//Flags indicating when each function has been executed regardless of an error\nvar isSendToBlockchainDone = false;\n\nfunction onPostSave(request, response, modules) {\n var async = modules.async;\n var httpRequest = modules.request;\n var logger = modules.logger;\n\n// async.parallel({\n// sendToBlockchain: async.apply(\n// sendToBlockchain,\n// logger,\n// response,\n// httpRequest\n// )\n// });\n}\n\n//!important - Called when all functions have been executed\nfunction callback(response) {\n if (isSendToBlockchainDone) {\n response.continue();\n }\n}\n\nfunction buildBlockchainMessage(response) {\n var msg = {\n _id:\tresponse.body._id,\n bookingAgentId\t:\tresponse.body.bookingAgentID,\n createdAt\t:\tresponse.body.dateCreated,\n farmArea\t:\tresponse.body.farmArea,\n farmMeasureId\t:\tresponse.body.farmMeasureID,\n farmPerimeter\t:\tresponse.body.farmPerimeter,\n locationRoute\t:\tresponse.body.locationRoute,\n measurementMode\t:\tresponse.body.measurementMode,\n totalmeasurementDuration\t:\tresponse.body.totalMeasurementDuration,\n updatedAt\t:\tresponse.body._kmd.lmt\n }\n return msg;\n}\n\nfunction sendToBlockchain(logger, response, httpRequest) {\n var msg = buildBlockchainMessage(response);\n var baseUrl = getBookingManagerBaseUrl();\n var url = baseUrl+\"/api/v1/farms\";\n logger.info(url);\n var authorization = getBookingManagerToken();\n httpRequest.post(blockchainRequestOptions(response, msg, url, authorization), function(\n blockErr,\n blockRes,\n blockBody\n ) {\n logger.info(\n \"Blockchain Response: \" +\n JSON.stringify(blockErr) +\n \", \" +\n JSON.stringify(blockRes) +\n \", \" +\n JSON.stringify(blockBody)\n );\n \n if(blockRes.status != 200){\n \n var doc = {\n \turl: url, \n msg: msg, \n httpStatus: blockRes.status, \n no_tries: 0\n };\n var collectionName = getFailedTransactionsCollection();\n var failedPosts = modules.collectionAccess.collection(collectionName);\n \n \tfailedPosts.save(doc, function(err, docs){\n if(err){\n logger.info(err);\n }\n\n //Done\n isSendToBlockchainDone = true;\n callback(response);\n });\n \n } else {\n isSendToBlockchainDone = true;\n callback(response);\n }\n });\n}\n\nfunction blockchainRequestOptions(response, msg, url, authorization) {\n //Send to IBM Swagger (REST API)\n modules.logger.info(response);\n \n var requestOptions = {\n uri: url,\n headers: {\n Authorization: authorization\n },\n json: msg\n };\n\n return requestOptions;\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n" }, "AppVersionHistory" : {}, "Logger" : {}, "FuelHistory" : {}, "UserAccounts" : { "hasOnPostSave" : true, "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n\nfunction onPostSave(request, response, modules) {\n var async = modules.async;\n var httpRequest = modules.request;\n var logger = modules.logger;\n var lodash = modules.lodash;\n var moment = modules.moment;\n\n logger.info(\"Posting user profiles data to backend\"); \n \n async.parallel({\n sendToBlockchain: async.apply(\n sendToBlockchain,\n logger,\n response,\n httpRequest,\n lodash\n )\n }); \n\n}\n\nfunction sendToBlockchain(logger,response,httpRequest,lodash){\n var baseUrl = getBookingManagerBaseUrl();\n var url = baseUrl + \"/api/v1/users/add-profile\"; \n var authorization = getBookingManagerToken();\n var msg = buildBlockchainMessage(logger,response,lodash);\n \n httpRequest.post(blockchainRequestOptions(msg, url, authorization), function(blockErr,blockRes,blockBody){\n logger.info(\"here >>>>>\");\n\n logger.info(\n \"Blockchain Response: \" +\n JSON.stringify(blockErr) +\n \", \" +\n JSON.stringify(blockRes) +\n \", \" +\n JSON.stringify(blockBody)\n );\n if(blockRes.status != 200){\n \n var doc = {\n \turl: url, \n msg: msg, \n httpStatus: blockRes.status, \n no_tries: 0\n };\n var collectionName = getFailedTransactionsCollection();\n var failedPosts = modules.collectionAccess.collection(collectionName);\n \n \tfailedPosts.save(doc, function(err, docs){\n if(err){\n logger.info(err);\n }\n\n response.continue();\n });\n \n } else {\n response.continue();\n }\n });\n\n}\n\nfunction blockchainRequestOptions(msg, url, authorization){\n var requestOptions = {\n uri: url,\n headers: {\n Authorization: authorization\n },\n json: msg\n };\n\n return requestOptions;\n \n \n}\n\nfunction buildBlockchainMessage(logger,response,lodash){\n var pick = lodash.pick(response.body,['_id','userLevel','user_type','orgID']);\n logger.info(\"picking items\");\n pick['userType']= pick['user_type'];\n pick['orgId']= pick['orgID'];\n\n delete pick['user_type'];\n delete pick['orgID'];\n\n return pick;\n \n}\n\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n" }, "OperatorReview" : { "hasOnPostSave" : true, "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n//Flags indicating when each function has been executed regardless of an error\nvar isSendToBlockchainDone = false;\n\nfunction onPostSave(request, response, modules) {\n var async = modules.async;\n var httpRequest = modules.request;\n var logger = modules.logger;\n var lodash = modules.lodash;\n var moment = modules.moment;\n\n async.parallel({\n sendToBlockchain: async.apply(\n sendToBlockchain,\n logger,\n response,\n httpRequest,\n lodash,\n \tmoment\n )\n });\n}\n\n//!important - Called when all functions have been executed\nfunction callback(response) {\n if (isSendToBlockchainDone) {\n response.continue();\n }\n}\n\n\n/**\n * **********************************************************************************\n * Sends the booking request to IBM Swagger REST API\n * @param logger An object of the {@link modules.logger} class\n * @param response The response to the client request\n * @param httpRequest An object of the {@link modules.request} class\n * **********************************************************************************\n */\nfunction sendToBlockchain(logger, response, httpRequest, lodash, moment) {\n var baseUrl = getBookingManagerBaseUrl();\n var url = baseUrl+\"/api/v1/feedback/review/\"+response.body.OperatorID;\n var authorization = getBookingManagerToken();\n var msg = buildBlockchainMessage(logger, response, lodash, moment);\n httpRequest.post(blockchainRequestOptions(logger, msg, url, authorization), function(\n blockErr,\n blockRes,\n blockBody\n ) {\n logger.info(\n \"Blockchain Response: \" +\n JSON.stringify(blockErr) +\n \", \" +\n JSON.stringify(blockRes) +\n \", \" +\n JSON.stringify(blockBody)\n );\n if(blockRes.status != 200){\n \n var doc = {\n \turl: url, \n msg: msg, \n httpStatus: blockRes.status, \n no_tries: 0\n };\n var collectionName = getFailedTransactionsCollection();\n var failedPosts = modules.collectionAccess.collection(collectionName);\n \n failedPosts.save(doc, function(err, docs){\n if(err){\n logger.info(err);\n }\n\n //Done\n isSendToBlockchainDone = true;\n callback(response);\n }); \n } else {\n isSendToBlockchainDone = true;\n callback(response);\n }\n });\n}\n\n function buildBlockchainMessage(logger,response,lodash, moment){\n// logger.info(response.body);\n var pick = lodash.pick(response.body,['_id','FarmerFeedback','CreatedAt','OperatorRating','OperatorID','UpdatedAt'])\n \n// logger.info(\"picking items\");\n pick['comment']= pick['FarmerFeedback'];\n pick['created_at']= moment(pick['CreatedAt']).toISOString();\n pick['rating']= pick['OperatorRating'];\n pick['revieweeId']= pick['OperatorID'];\n pick['updated_at']= moment(pick['UpdatedAt']).toISOString();\n delete pick['FarmerFeedback'];\n delete pick['CreatedAt'];\n delete pick['OperatorRating'];\n delete pick['OperatorID'];\n delete pick['UpdatedAt'];\n// logger.info(pick,response.body);\n return pick; \n\n}\n\nfunction blockchainRequestOptions(logger, msg, url, authorization) {\n //Send to IBM Swagger (REST API)\n logger.info(\"@ blockchainRequestOptions: \"+ JSON.stringify(msg));\n logger.info(\"@ blockchainRequestOptions: \"+ authorization);\n var requestOptions = {\n uri: url,\n headers: {\n Authorization: authorization\n },\n json: msg\n };\n\n return requestOptions;\n}\n\n\n\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n" }, "Emails" : {}, "APIKeys" : {}, "MaintenanceRepo" : {}, "TractorActivity" : {}, "ActivityHectar" : { "hasOnPostSave" : true, "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n//Flags indicating when each function has been executed regardless of an error\nvar isSendToBlockchainDone = false;\n\nfunction onPostSave(request, response, modules) {\n var async = modules.async;\n var httpRequest = modules.request;\n var logger = modules.logger;\n\n async.parallel({\n sendToBlockchain: async.apply(\n sendToBlockchain,\n logger,\n response,\n httpRequest\n )\n });\n}\n\n//!important - Called when all functions have been executed\nfunction callback(response) {\n if (isSendToBlockchainDone) {\n response.continue();\n }\n}\n\nfunction sendToBlockchain(logger, response, httpRequest) {\n var msg = buildBlockchainMessage(response);\n logger.info(msg);\n var baseUrl = getBookingManagerBaseUrl();\n var url = baseUrl+\"/api/v1/tractors/\"+response.body.TractorId+\"/activity-hectare\";\n logger.info(url);\n var authorization = getBookingManagerToken();\n httpRequest.post(blockchainRequestOptions(msg, url, authorization), function(\n blockErr,\n blockRes,\n blockBody\n ) {\n logger.info(\n \"Blockchain Response: \" +\n JSON.stringify(blockErr) +\n \", \" +\n JSON.stringify(blockRes) +\n \", \" +\n JSON.stringify(blockBody)\n );\n if(blockRes.status != 200){\n \n var doc = {\n \turl: url, \n msg: msg, \n httpStatus: blockRes.status, \n no_tries: 0\n };\n var collectionName = getFailedTransactionsCollection();\n var failedPosts = modules.collectionAccess.collection(collectionName);\n \n \tfailedPosts.save(doc, function(err, docs){\n if(err){\n logger.info(err); \n }\n\n isSendToBlockchainDone = true;\n callback(response); \n });\n \n } else {\n isSendToBlockchainDone = true;\n callback(response);\n }\n });\n}\n\nfunction buildBlockchainMessage(response) {\n var msg = {\n _id: response.body._id,\n TractorId: response.body.TractorId,\n OperatorId: response.body.OperatorId,\n HectarTilledStartPT: response.body.HectarTilledStartPT,\n HectarTilledStopPT: response.body.HectarTilledStopPT,\n ActivityId: response.body.ActivityId,\n JourneyStartTime: response.body.JourneyStartTime,\n JourneyEndTime: response.body.JourneyEndTime,\n Latitude:response.body.Latitude,\n JourneyIdentifier: response.body.JourneyIdentifier,\n Longitude: response.body.Longitude,\n IgnitionStatus: response.body.IgnitionStatus,\n Street: response.body.Street,\n Town: response.body.Town,\n County: response.body.County,\n Country: response.body.Country,\n OperatorName: response.body.OperatorName,\n };\n\n return msg;\n}\n\nfunction blockchainRequestOptions(msg, url, authorization) {\n //Send to IBM Swagger (REST API)\n var requestOptions = {\n uri: url,\n headers: {\n Authorization: authorization\n },\n json: msg\n };\n\n return requestOptions;\n}\n\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n" }, "DailyTractorActivity" : { "hasOnPostSave" : true, "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n//Flags indicating when each function has been executed regardless of an error\nvar isSendToBlockchainDone = false;\n\nfunction onPostSave(request, response, modules) {\n var async = modules.async;\n var httpRequest = modules.request;\n var logger = modules.logger;\n\n async.parallel({\n sendToBlockchain: async.apply(\n sendToBlockchain,\n logger,\n response,\n httpRequest\n )\n });\n}\n\n//!important - Called when all functions have been executed\nfunction callback(response) {\n if (isSendToBlockchainDone) {\n response.continue();\n }\n}\n\n/**\n * **********************************************************************************\n * Sends the daily tractor activity to IBM Swagger REST API\n * @param logger An object of the {@link modules.logger} class\n * @param response The response to the client request\n * @param httpRequest An object of the {@link modules.request} class\n * **********************************************************************************\n */\nfunction sendToBlockchain(logger, response, httpRequest) {\n var msg = buildBlockchainMessage(response);\n var baseUrl = getBookingManagerBaseUrl();\n var url = baseUrl + \"/api/v1/tractors/\"+msg[\"TractorID\"]+\"/daily-tractor-activity\";\n logger.info(url);\n var authorization = getBookingManagerToken();\n httpRequest.post(blockchainRequestOptions(response, msg, url, authorization), function(\n blockErr,\n blockRes,\n blockBody\n ) {\n logger.info(\n \"Blockchain Response: \" +\n JSON.stringify(blockErr) +\n \", \" +\n JSON.stringify(blockRes) +\n \", \" +\n JSON.stringify(blockBody)\n );\n if(blockRes.status != 200){\n \n var doc = {\n \turl: url, \n msg: msg, \n httpStatus: blockRes.status, \n no_tries: 0\n };\n var collectionName = getFailedTransactionsCollection();\n var failedPosts = modules.collectionAccess.collection(collectionName);\n \n failedPosts.save(doc, function(err, docs){\n if(err){\n logger.info(err);\n }\n //Done\n isSendToBlockchainDone = true;\n callback(response);\n }); \n } else {\n isSendToBlockchainDone = true;\n callback(response);\n }\n });\n}\n\nfunction buildBlockchainMessage(response) {\n var msg = {\n _id: response.body._id,\n TotalTimeActive: response.body.TotalTimeActive,\n TotalTimeIdle: response.body.TotalTimeIdle,\n LastJourneyStartTime: response.body.LastJourneyStartTime,\n TotalSpeed: response.body.TotalSpeed,\n TotalSpeedCounter: response.body.TotalSpeedCounter,\n AverageSpeed: response.body.AverageSpeed,\n StartActiveData: response.body.StartActiveData,\n LastActiveData: response.body.LastActiveData,\n Country: response.body.Country,\n Town: response.body.Town,\n Street: response.body.Street,\n IgnitionStatus: response.body.IgnitionStatus,\n DistanceTravelled: response.body.DistanceTravelled,\n LastOdometerValue: response.body.LastOdometerValue,\n StartCountry: response.body.StartCountry,\n StartTown: response.body.StartTown,\n StartStreet: response.body.StartStreet,\n RouteDTO: response.body.Route,\n OperatorID: response.body.OperatorID,\n TractorID: response.body.TractorID,\n day: response.body.day,\n RevenueType: response.body.RevenueType,\n RevenueCurrency: response.body.RevenueCurrency,\n Revenue: response.body.Revenue,\n HectaresServiced: response.body.HectaresServiced,\n };\n\n return msg;\n}\n\nfunction blockchainRequestOptions(response, msg, url, authorization) {\n //Send to IBM Swagger (REST API)\n var requestOptions = {\n uri: url,\n headers: {\n Authorization: authorization\n },\n json: msg\n };\n\n return requestOptions;\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n" }, "Maintenance" : { "hasOnPostSave" : true, "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n//Flags indicating when each function has been executed regardless of an error\nvar isSendToBlockchainDone = false;\n\nfunction onPostSave(request, response, modules) {\n var async = modules.async;\n var httpRequest = modules.request;\n var logger = modules.logger;\n\n async.parallel({\n sendToBlockchain: async.apply(\n sendToBlockchain,\n logger,\n response,\n httpRequest\n )\n });\n}\n\n//!important - Called when all functions have been executed\nfunction callback(response) {\n if (isSendToBlockchainDone) {\n response.continue();\n }\n}\n\nfunction sendToBlockchain(logger, response, httpRequest) {\n var msg = buildBlockchainMessage(response);\n modules.logger.info(msg);\n var baseUrl = getBookingManagerBaseUrl();\n var url = baseUrl+\"/api/v1/tractors/\"+response.body.TractorId+\"/maintenance\"; \n var authorization = getBookingManagerToken();\n httpRequest.post(blockchainRequestOptions(response, msg, url, authorization), function(\n blockErr,\n blockRes,\n blockBody\n ) {\n logger.info(\n \"Blockchain Response: \" +\n JSON.stringify(blockErr) +\n \", \" +\n JSON.stringify(blockRes) +\n \", \" +\n JSON.stringify(blockBody)\n );\n if(blockRes.status != 200){\n \n var doc = {\n \turl: url, \n msg: msg, \n httpStatus: blockRes.status, \n no_tries: 0\n };\n var collectionName = getFailedTransactionsCollection();\n var failedPosts = modules.collectionAccess.collection(collectionName);\n \n \tfailedPosts.save(doc, function(err, docs){\n if(err){\n logger.info(err);\n }\n\n //Done\n isSendToBlockchainDone = true;\n callback(response);\n }); \n } else {\n isSendToBlockchainDone = true;\n callback(response);\n }\n });\n}\n\nfunction buildBlockchainMessage(response) {\n var msg = {\n _id: response.body._id,\n tractorId: response.body.TractorId,\n description: response.body.Description,\n duration: response.body.Duration,\n date: response.body.Date,\n repairDate: response.body.RepairDate,\n status: response.body.Status,\n maintenanceLog: response.body.MaintenanceLog,\n timeTaken: response.body.TimeTaken,\n };\n\n return msg;\n}\n\nfunction blockchainRequestOptions(response, msg, url, authorization) {\n //Send to IBM Swagger (REST API) \n var requestOptions = {\n uri: url,\n headers: {\n Authorization: authorization\n },\n json: msg\n };\n\n return requestOptions;\n}\n\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n" }, "MaintenanceActivity" : { "hasOnPostSave" : true, "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n//Flags indicating when each function has been executed regardless of an error\nvar isSendToBlockchainDone = false;\n\nfunction onPostSave(request, response, modules) {\n var async = modules.async;\n var httpRequest = modules.request;\n var logger = modules.logger;\n\n async.parallel({\n sendToBlockchain: async.apply(\n sendToBlockchain,\n logger,\n response,\n httpRequest\n )\n });\n}\n\n//!important - Called when all functions have been executed\nfunction callback(response) {\n if (isSendToBlockchainDone) {\n response.continue();\n }\n}\n\nfunction sendToBlockchain(logger, response, httpRequest) {\n var msg = buildBlockchainMessage(response);\n logger.info(msg);\n var baseUrl = getBookingManagerBaseUrl();\n var url = baseUrl+\"/api/v1/tractors/\"+response.body.TractorID+\"/maintenance-activity\";\n logger.info(url);\n var authorization = getBookingManagerToken();\n httpRequest.post(blockchainRequestOptions(msg, url, authorization), function(\n blockErr,\n blockRes,\n blockBody\n ) {\n logger.info(\n \"Blockchain Response: \" +\n JSON.stringify(blockErr) +\n \", \" +\n JSON.stringify(blockRes) +\n \", \" +\n JSON.stringify(blockBody)\n );\n if(blockRes.status != 200){\n \n var doc = {\n \turl: url, \n msg: msg, \n httpStatus: blockRes.status, \n no_tries: 0\n };\n var collectionName = getFailedTransactionsCollection();\n var failedPosts = modules.collectionAccess.collection(collectionName);\n \n \tfailedPosts.save(doc, function(err, docs){\n if(err){\n logger.info(err);\n }\n\n //Done\n isSendToBlockchainDone = true;\n callback(response);\n });\n \n } else {\n isSendToBlockchainDone = true;\n callback(response);\n }\n });\n}\n\nfunction buildBlockchainMessage(response) {\n var msg = {\n _id: response.body._id,\n counter: response.body.counter,\n tractorId: response.body.TractorID,\n description: response.body.Description,\n duration: response.body.Duration,\n lastNotificationTime: response.body.LastNotificationTime,\n predefinedMaintenanceActivityId: response.body.PredefinedMaintenanceActivityId,\n status: response.body.Status,\n type: response.body.Type\n };\n\n return msg;\n}\n\nfunction blockchainRequestOptions(msg, url, authorization) {\n //Send to IBM Swagger (REST API)\n var requestOptions = {\n uri: url,\n headers: {\n Authorization: authorization\n },\n json: msg\n };\n\n return requestOptions;\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n" }, "PredefinedMaintenanceActivity" : { "hasOnPostSave" : true, "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPostSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n//Flags indicating when each function has been executed regardless of an error\nvar isSendToBlockchainDone = false;\n\nfunction onPostSave(request, response, modules) {\n var async = modules.async;\n var httpRequest = modules.request;\n var logger = modules.logger;\n\n async.parallel({\n sendToBlockchain: async.apply(\n sendToBlockchain,\n logger,\n response,\n httpRequest\n )\n });\n}\n\n//!important - Called when all functions have been executed\nfunction callback(response) {\n if (isSendToBlockchainDone) {\n response.continue();\n }\n}\n\n/**\n * **********************************************************************************\n * Sends the booking request to IBM Swagger REST API\n * @param logger An object of the {@link modules.logger} class\n * @param response The response to the client request\n * @param httpRequest An object of the {@link modules.request} class\n * **********************************************************************************\n */\nfunction sendToBlockchain(logger, response, httpRequest) {\n var msg = buildBlockchainMessage(response);\n logger.info(msg);\n var baseUrl = getBookingManagerBaseUrl();\n var url = baseUrl+\"/api/v1/tractors/predefined-maintenance-activity\"; \n logger.info(\"Url: \" + url);\n var authorization = getBookingManagerToken();\n httpRequest.post(blockchainRequestOptions(msg, url, authorization), function(\n blockErr,\n blockRes,\n blockBody\n ) {\n logger.info(\n \"Blockchain Response: \" +\n JSON.stringify(blockErr) +\n \", \" +\n JSON.stringify(blockRes) +\n \", \" +\n JSON.stringify(blockBody)\n );\n if(blockRes.status != 200){\n \n var doc = {\n \turl: url, \n msg: msg, \n httpStatus: blockRes.status, \n no_tries: 0\n };\n var collectionName = getFailedTransactionsCollection();\n var failedPosts = modules.collectionAccess.collection(collectionName);\n \n failedPosts.save(doc, function(err, docs){\n if(err){\n logger.info(err);\n }\n\n //Done\n isSendToBlockchainDone = true;\n callback(response);\n }); \n } else {\n isSendToBlockchainDone = true;\n callback(response);\n }\n });\n}\n\nfunction buildBlockchainMessage(response) {\n var msg = {\n _id: response.body._id,\n Description: response.body.Description,\n Duration: response.body.Duration,\n Mandatory: response.body.Mandatory,\n };\n\n return msg;\n}\n\nfunction blockchainRequestOptions(msg, url, authorization) {\n //Send to IBM Swagger (REST API) \n var requestOptions = {\n uri: url,\n headers: {\n Authorization: authorization\n },\n json: msg\n };\n\n return requestOptions;\n}\n\n\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n" }, "FailedPosts" : {}, "Logs" : {}, "PricePerHectare" : { "hasOnPreSave" : true, "code" : "\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 onPreSave 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n//Prevents duplicate entries of prices for the same service\n//and/or updates the price with the orgID of the tractor owner\n//Created by Abdulmajid & Sulaiman on 11/10/2019, Updated 14/05/2020\n\nfunction onPreSave(request, response, modules) {\n var creatorId = modules.requestContext.getAuthenticatedUserId();\n var serviceType = request.body.serviceType;\n var log = modules.logger;\n var pricePerHectareQuery = {\n $and: [\n {\"_acl.creator\": creatorId},\n {\"serviceType\": serviceType}\n ]\n };\n\n var tractorOwnerCol = modules.collectionAccess.collection(\"TractorOwner\");\n var pricePerHectareCol = modules.collectionAccess.collection(\"PricePerHectare\");\n \n tractorOwnerCol.findOne({\"_acl.creator\": creatorId}, function(tractorOwnerErr, tractorOwnerFound){\n pricePerHectareCol.findOne(pricePerHectareQuery, function(pricePerHectareErr, pricePerHectareFound){\n if (pricePerHectareFound){\n log.info(\"Price per hectare already exists, just update\");\n \tresponse.body._id = pricePerHectareFound._id;\n response.continue();\n } else {\n log.info(\"New price per hectare will be created\");\n request.body.orgID = tractorOwnerFound.orgID;\n response.continue();\n }\n });\n });\n}\n/** 8d6c7d20-1894-11e2-892e-0800200c9a66 end 8d6c7d20-1894-11e2-892e-0800200c9a66 **/\n" }, "DailyFuelConsumed" : {}, "FuelCalibrationResults" : {}, "MaintenanceHistory" : {}, "TractorTechnician" : {} }, "dataIntegration" : { "EventCodeDetails" : { "isVirtualCollection" : false }, "Events" : { "isVirtualCollection" : false }, "EventType" : { "isVirtualCollection" : false }, "Farmer" : { "isVirtualCollection" : false }, "HectaresTilledCalculator" : { "isVirtualCollection" : false }, "MaintenanceTypes" : { "isVirtualCollection" : false }, "ResponseFromOperator" : { "isVirtualCollection" : false }, "Revenue" : { "isVirtualCollection" : false }, "RevenueTypes" : { "isVirtualCollection" : false }, "SmsGatewayInfo" : { "isVirtualCollection" : false }, "StoreCurrentStatus" : { "isVirtualCollection" : false }, "TelerivetFarmerInfo" : { "isVirtualCollection" : false }, "TractorDetail" : { "isVirtualCollection" : false }, "TractorInfo" : { "isVirtualCollection" : false }, "TractorOperator" : { "isVirtualCollection" : false }, "TractorOwner" : { "isVirtualCollection" : false }, "TractorToOperator" : { "isVirtualCollection" : false }, "NotificationGeoFenceMaintenance" : { "isVirtualCollection" : false }, "TractorCurrentLocation" : { "isVirtualCollection" : false }, "Maintenance" : { "isVirtualCollection" : false }, "TractorActivity" : { "isVirtualCollection" : false }, "TractorActivityData" : { "isVirtualCollection" : false }, "CumulativeTractorActivityData" : { "isVirtualCollection" : false }, "AgroDealersHeatMapData" : { "isVirtualCollection" : false }, "TrackerIds" : { "isVirtualCollection" : false }, "ServiceBookingHistory" : { "isVirtualCollection" : false }, "Notification" : { "isVirtualCollection" : false }, "TestTractorActivities" : { "isVirtualCollection" : false }, "UserFeedback" : { "isVirtualCollection" : false }, "user" : { "isVirtualCollection" : false }, "TestDailyTractorActivity" : { "isVirtualCollection" : false }, "OldDailyTractorActivity" : { "isVirtualCollection" : false }, "DailyTractorActivity" : { "isVirtualCollection" : false }, "BookingAgents" : { "isVirtualCollection" : false }, "TwoTrackApiToken" : { "isVirtualCollection" : false }, "ServiceBookings" : { "isVirtualCollection" : false }, "TractorTips" : { "isVirtualCollection" : false }, "TractorAds" : { "isVirtualCollection" : false }, "FarmMeasure" : { "isVirtualCollection" : false }, "FarmMeasures" : { "isVirtualCollection" : false }, "AppVersionHistory" : { "isVirtualCollection" : false }, "Logger" : { "isVirtualCollection" : false }, "_blob" : { "isVirtualCollection" : false }, "FuelHistory" : { "isVirtualCollection" : false }, "UserAccounts" : { "isVirtualCollection" : false }, "OperatorReview" : { "isVirtualCollection" : false }, "Emails" : { "isVirtualCollection" : false }, "APIKeys" : { "isVirtualCollection" : false }, "MaintenanceRepo" : { "isVirtualCollection" : false }, "FailedPosts" : { "isVirtualCollection" : false }, "Logs" : { "isVirtualCollection" : false }, "DailyFuelConsumed" : { "isVirtualCollection" : false }, "FuelCalibrationResults" : { "isVirtualCollection" : false }, "MaintenanceHistory" : { "isVirtualCollection" : false }, "TractorTechnician" : { "isVirtualCollection" : false } }, "commonBL" : { "modules" : { "revenue" : "//Used to form revenue notification push message and type\nfunction c_sendRevenueNotification(pushInfo, type, cb) {\n var logger = modules.logger,\n async = modules.async,\n push = modules.push,\n collectionAccess = modules.collectionAccess;\n var baseNotification = {\n userId: pushInfo.creator,\n read: false,\n tractorId: pushInfo.TractorID,\n operatorId: pushInfo.OperatorID\n };\n\n var baseNotifications = {\n revenue: {\n message: 'Please set some revenue',\n type: 'action',\n action: 'revenue'\n }\n };\n\n var notification = c_mergeObjects([baseNotification, baseNotifications[type]]);\n c_sendNotification(notification, cb);\n \n response.complete(200);\n}", "notification" : "//send array of notifications\nvar c_sendNotifications = function(notifications, cb) {\n var logger = modules.logger,\n async = modules.async,\n push = modules.push,\n collectionAccess = modules.collectionAccess;\n\n async.each(notifications, sendNotification, cb);\n};\n\n//base function to send single notification,\n//check other common js files to see which notification parameter\n//is expected here\nfunction c_sendNotification(notification, cb) {\n var logger = modules.logger,\n async = modules.async,\n push = modules.push,\n collectionAccess = modules.collectionAccess;\n logger.info(\"About to send notification\");\n\n sendNotification(notification, cb);\n}\n\n//function to send all types of notifications: system, sms, emails,\nfunction sendNotification(notification, cb) {\n var logger = modules.logger,\n async = modules.async,\n push = modules.push,\n collectionAccess = modules.collectionAccess,\n emailModule = modules.email, \n countSystemNotificationsSent = 0, \n countEmailNotificationsSent = 0,\n countNotificationsSaved = 0,\n countUsers = 0,\n usersIdArr = [];\n\n if(!notification.userId) {\n return cb();\n } else {\n \n var mainUserId = (collectionAccess.objectID(notification.userId)).toString();\n\n //Add default user id\n usersIdArr.push(mainUserId);\n\n // var userAccountsQuery = {\"_acl.creator\": JSON.stringify(collectionAccess.objectID(notification.userId))};\n var userAccountsQuery = {'_acl.creator': mainUserId};\n \n collectionAccess.collection('UserAccounts').find(userAccountsQuery, {}, function (userAcctErr, userAccounts){ //Start: find user accounts\n logger.info(\"Main user id: \"+mainUserId);\n \n if (!userAcctErr && userAccounts){\n logger.info(\"User accounts found: \"+userAccounts.length +\", error: \"+userAcctErr);\n userAccounts.forEach(function(userAccount){\n if (userAccount.accountHolderId){\n usersIdArr.push(userAccount.accountHolderId);\n }\n });\n }\n\n countUsers = usersIdArr.length; //Users requiring notification\n logger.info(\"Users ID Arr: \"+usersIdArr);\n\n usersIdArr.forEach(function(userId){\n // var userQuery = {_id:userId};\n var userQuery = {'_acl.creator': userId};\n collectionAccess.collection('user').findOne(userQuery, {}, function(userErr, user){\n if (!userErr && user){\n //Find the tractor owner with that user Id\n logger.info(\"User found: \"+JSON.stringify(user) +\", error: \"+userAcctErr);\n // var tractorOwnerQuery = {\"_acl.creator\": userId};\n \n var tractorOwnerQuery = {\n $and:[\n {'_acl.creator': userId},\n {'geofenceTractorNotifications': true}\n ]\n };\n\n collectionAccess.collection(\"TractorOwner\").findOne(tractorOwnerQuery, {}, function(tractorOwnerErr, tractorOwner){\n if (!tractorOwnerErr && tractorOwner){ //TODO: Add && tractorOwner.geofenceTractorNotifications on publishing a new version\n logger.info(\"Tractor Owner found: \"+ JSON.stringify(tractorOwner));\n saveAndSendNotification(user, tractorOwner, notification, cb);\n } else {\n incrementCountNotifications();\n finalCallback({}, cb);\n }\n });\n\n } else {\n logger.info(\"User: \"+userId+\" not found\");\n incrementCountNotifications();\n finalCallback({}, cb);\n }\n });\n });\n\n }); //End: UserAccounts query\n\n var incrementCountNotifications = function (){\n countEmailNotificationsSent++;\n countSystemNotificationsSent++;\n countNotificationsSaved++;\n }\n\n var finalCallback = function (result, cb){\n //Check to make sure the loop finishes before returning cb()\n logger.info(\"Email Not: \"+countEmailNotificationsSent+\", Sys Not: \"+countSystemNotificationsSent+\", Notifications Saved: \"+countNotificationsSaved);\n if (countEmailNotificationsSent >= countUsers && countSystemNotificationsSent >= countUsers && countNotificationsSaved >= countUsers){\n return cb();\n }\n\n return;\n }\n\n var saveAndSendNotification = function (user, tractorOwner, notification, cb){\n //Ensures that the user (parent/child) receives the notification\n notification.userId = tractorOwner._acl.creator;\n var kEntity = modules.kinvey.entity(); \n var entity = modules.kinvey.entity(notification);\n entity._id = kEntity._id;\n entity._acl = tractorOwner._acl;\n entity.extras = JSON.parse(JSON.stringify(entity)); \n \n collectionAccess.collection('Notification').save(entity, function(entityErr, savedEntity){\n\n //Validates that the notification was saved\n countNotificationsSaved++;\n finalCallback({}, cb);\n\n async.parallel([\n sendSystemNotification,\n sendEmailNotification\n ],finalCallback);\n\n function sendSystemNotification() { \n savedEntity.id = notification.type + notification.action + notification.tractorId;\n var test = push.sendPayload(user, {}, {}, savedEntity, function(res) {\n logger.info('notif results ' + JSON.stringify(res));\n countSystemNotificationsSent++;\n finalCallback(res, cb);\n });\n }\n\n function sendEmailNotification() {\n if(tractorOwner && tractorOwner.email) {\n emailModule.send(\n 'Hello Tractor <support@hellotractor.com>',\n tractorOwner.email,\n 'Hello Tractor [Geofence Notification]',\n notification.message,\n function(err, result) {\n logger.info(err);\n logger.info(result);\n countEmailNotificationsSent++;\n finalCallback(result, cb);\n });\n } else {\n countEmailNotificationsSent++;\n finalCallback({}, cb);\n }\n }\n });\n }\n }\n}", "utils" : "// Any code here will be available in all of your business logic (collection hooks, \n// endpoints, and other common scripts)\n\nfunction c_mergeObjects(objects) {\n var result = {};\n objects.forEach(function(object) {\n for(var attr in object) {\n result[attr] = object[attr];\n }\n });\n return result;\n}", "sms" : "//Used to send sms\nfunction c_sendSms(message, phone, country, cb) {\n var logger = modules.logger,\n async = modules.async,\n push = modules.push,\n collectionAccess = modules.collectionAccess,\n req = modules.request;\n\n var apiKey = '583565ed796fc583565ed79778',\n senderId = 'HelloTracto',\n uri = 'http://sms.nasaramobile.com/api?api_key=' + apiKey + '&sender_id=' + senderId + '&phone=' + phone + '&message=' + message;\n\n req.get({\n uri: uri,\n method: 'GET'\n }, function(error, res, body) {\n logger.info(error);\n logger.info(res);\n logger.info(body);\n return cb();\n });\n}\n", "geofence" : "//function that checks does tractor leave or return back into geofence area\n//and send notifications\nfunction c_sendGeofenceNotificationIfNecessary(lastActivity, tractor, cb) {\n var logger = modules.logger,\n async = modules.async,\n push = modules.push,\n collectionAccess = modules.collectionAccess,\n moment = modules.moment;\n\n var isAreaExists = tractor && tractor.Latitude && tractor.Longitude;\n if(isAreaExists) {\n var isTractorInArea = c_isPointInArea(lastActivity.lat, lastActivity.lon, tractor);\n //var isTractorInArea = c_isPointInArea(0, 0, tractor);\n if(isTractorInArea) {\n logger.info(\"Tractor is in area\");\n //tractor returns back in the area\n if(!tractor.WasInArea) {\n c_sendGeoFenceNotification(tractor, 'geofenceIn', function(err) {\n return cb(err, {\n wasSent: true,\n WasInArea: true\n });\n });\n } else {\n return cb(null, {\n wasSent: false,\n WasInArea: false\n });\n }\n } else {\n var needToSend = false;\n //tractor first time leaves area\n if(tractor.WasInArea) {\n needToSend = true;\n } else {\n //tractor leaves the area not the first time\n if(tractor.NeedToSendGeofenceOutNotification) {\n needToSend = tractor.LastGeofenceNotificationTime ? moment().diff(moment(tractor.LastGeofenceNotificationTime), 'hours') > 1 : true; //Changed to 1 hour from 24 hours due to suggestion from Good Earth\n }\n }\n if(needToSend) {\n logger.info(\"Found a need to send notification: \"+tractor.TractorID);\n c_sendGeoFenceNotification(tractor, 'geofenceOut', function(err) {\n return cb(err, {\n wasSent: true,\n WasInArea: false\n });\n });\n } else {\n logger.info(\"No need to send notification: \"+tractor.TractorID);\n return cb(null, {\n wasSent: false,\n WasInArea: false\n });\n }\n }\n } else {\n return cb(null, {\n wasSent: false,\n WasInArea: false\n });\n }\n}\n\nfunction c_isPointInArea(lat, long, tractor) {\n var logger = modules.logger,\n async = modules.async,\n push = modules.push,\n collectionAccess = modules.collectionAccess;\n\n var polyLat = tractor.Latitude.split(',').map(parseFloat),\n polyLng = tractor.Longitude.split(',').map(parseFloat),\n vs = [],\n point = [parseFloat(lat), parseFloat(long)];\n for(var i = 0; i < polyLat.length; i++) {\n vs.push([polyLat[i], polyLng[i]]);\n }\n\n //logger.info('point ' + JSON.stringify(point));\n //logger.info('vs ' + JSON.stringify(vs));\n\n return isInside(point, vs);\n\n function isInside(point, vs) {\n var x = point[0], y = point[1];\n\n var inside = false;\n for(var i = 0, j = vs.length - 1; i < vs.length; j = i++) {\n var xi = vs[i][0], yi = vs[i][1];\n var xj = vs[j][0], yj = vs[j][1];\n\n var intersect = ((yi > y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);\n if(intersect) inside = !inside;\n }\n\n return inside;\n }\n}\n\n//function to form notification message and type based on geofence type\nfunction c_sendGeoFenceNotification(tractor, type, cb) {\n var logger = modules.logger,\n async = modules.async,\n push = modules.push,\n collectionAccess = modules.collectionAccess;\n var baseNotification = {\n userId: tractor._acl.creator,\n read: false,\n tractorId: tractor.TractorID,\n operatorId: tractor.OperatorID\n };\n\n var baseNotifications = {\n geofenceCreated: {\n message: 'New Geofence Created: A new geo-fence area has been defined for tractor (' + tractor.TractorName + ')',\n type: 'alert',\n action: 'none',\n country: tractor.Country,\n street: tractor.Street,\n town: tractor.Town,\n tractorId:tractor.TractorID,\n tractorName: tractor.TractorName \n },\n geofenceAllCreated: {\n message: 'New Geofence Created: A new geo-fence area has been defined for all your tractors',\n type: 'alert',\n action: 'none'\n }, \n geofenceIn: {\n message: 'Tractor (' + tractor.TractorName + ') is back in the geo-fenced area and is currently at ' + tractor.Street + ', ' + tractor.Town + ', ' + tractor.Country,\n type: 'alert', //left here for backward compatibility\n action: 'geofence_in',\n country: tractor.Country,\n street: tractor.Street,\n town: tractor.Town,\n tractorId:tractor.TractorID,\n tractorName: tractor.TractorName\n },\n geofenceOut: {\n message: 'Geo-fence Alert! : Tractor (' + tractor.TractorName + ' - ' + tractor.TractorID + ') has left the geo-fenced area and is currently at ' +\n tractor.Street + ', ' + tractor.Town + ', ' + tractor.Country,\n type: 'action',\n action: 'geofence_out',\n country: tractor.Country,\n street: tractor.Street,\n town: tractor.Town,\n tractorId:tractor.TractorID,\n tractorName: tractor.TractorName\n }\n };\n\n var notification = c_mergeObjects([baseNotification, baseNotifications[type]]);\n c_sendNotification(notification, cb);\n}", "maintenance" : "//function to form notification message and type based on maintenance type\nfunction c_sendMaintenanceNotification(maintenance, operatorId, type, cb) {\n var logger = modules.logger,\n async = modules.async,\n push = modules.push,\n collectionAccess = modules.collectionAccess,\n moment = modules.moment;\n\n var baseNotification = {\n userId: maintenance._acl.creator,\n read: false,\n tractorId: maintenance.TractorID,\n operatorId: operatorId\n };\n\n var baseNotifications = {\n maintenancePartial: {\n message: 'Maintenance 80% Alert! : ' + maintenance.Description,\n type: 'action',\n action: 'maintenance_partial'\n },\n maintenance: {\n message: 'Maintenance full Alert! : ' + maintenance.Description,\n type: 'action',\n action: 'maintenance'\n },\n maintenance2Track: {\n message: 'Maintenance Alert: Monitoring device battery is low', //maintenance.Description,\n type: 'alert',\n action: 'none'\n }\n };\n\n var notification = c_mergeObjects([baseNotification, baseNotifications[type]]);\n c_sendNotification(notification, cb);\n}\n\n//function to create MaintenanceActivity entity\nfunction c_createNewMaintenanceActivity(maintenance, cb) {\n var logger = modules.logger,\n async = modules.async,\n push = modules.push,\n collectionAccess = modules.collectionAccess,\n moment = modules.moment,\n requestContext = modules.requestContext;\n\n var currentUserId = maintenance.CurrentUserId ? maintenance.CurrentUserId : requestContext.getAuthenticatedUserId(),\n maintenanceActivity = {\n TractorID: maintenance.TractorID,\n Duration: maintenance.Duration,\n Description: maintenance.Description,\n PredefinedMaintenanceActivityId: maintenance.PredefinedMaintenanceActivityId ? maintenance.PredefinedMaintenanceActivityId.toString() : \"\",\n Counter: maintenance.Counter ? maintenance.Counter : 0,\n LastNotificationTime: maintenance.LastNotificationTime ? maintenance.LastNotificationTime : moment().subtract({'days': 1}).toISOString(),\n Type: maintenance.Type ? maintenance.Type : 1,\n Status: maintenance.Status ? maintenance.Status : 1\n };\n maintenanceActivity = modules.kinvey.entity(maintenanceActivity);\n maintenanceActivity._acl = {creator: currentUserId};\n collectionAccess.collection('MaintenanceActivity').save(maintenanceActivity, cb);\n \n response.complete(200);\n}", "bookingWeatherInfoUtils" : " var getBookingServiceDateWeatherInfo = function(weather,bookingServiceDate ){\n \t//filter the weather information to get the weather for the booking service date;\n var weatherInfo = weather.list.filter(function(_weather){\n return _weather.dt_txt.split(\" \")[0] === bookingServiceDate;\n })\n \n if( weatherInfo.length > 0 ) {\n \n \treturn JSON.stringify({\n cod: weather.cod,\n message: weather.message,\n cnt: weather.cnt,\n list: weatherInfo\n \n });\n \n }\n else {\n return null;\n }\n\n }\n", "getServiceType" : "\tvar getServiceName = function (bookings) {\n var service_name;\n var serviceTypeId = bookings[0].serviceType;\n switch (serviceTypeId) {\n case 109:\n service_name = 'Harrowing'\n break;\n case 104:\n service_name = 'Planting/Seeding'\n break;\n case 105:\n service_name = 'Irrigating'\n break;\n case 102:\n service_name = 'Ploughing'\n break;\n case 101:\n service_name = 'Tilling'\n break;\n case 103:\n service_name = 'Ridging'\n break;\n case 107:\n service_name = 'Trailing'\n break;\n case 108:\n service_name = 'Harvesting'\n break;\n case 106:\n service_name = 'Harvesting'\n break;\n case 110:\n service_name = 'Spreading'\n break;\n case 115:\n service_name = 'Mower'\n break;\n case 114:\n service_name = 'Dozer'\n break;\n case 113:\n service_name = 'Bioagtive'\n break;\n \tcase 116:\n \tservice_name = 'Drilling'\n \tbreak;\n \tcase 117:\n \tservice_name = 'Rotavator'\n \tbreak;\n \tcase 118:\n \tservice_name = 'Laser Leveler'\n \t \tbreak;\n \tcase 119:\n \t \tservice_name = 'Threshing'\n \tbreak; \n \t\tcase 120:\n \t\t\tservice_name = 'Threshing'\n \t\t\tbreak;\n case 121:\n \t\t\tservice_name = 'Blade Leveling'\n \t\t\tbreak;\n \n default:\n '';\n }\n return service_name;\n }", "maintenanceNotificationUtils" : "//Extract creators from tractorOwners array\n//@return Array of creators\nvar Push = modules.push;\n\nvar getCreatorsFrom = function(tractorOwners) {\n return tractorOwners.map(function(_tractorOwner) {\n return _tractorOwner._acl.creator;\n });\n};\n\n //pure function \n function getSchemaBy(schemaName){\n return modules.collectionAccess.collection(schemaName);\n };\n\n//Check if engineHours of a tractor is greater than 0 meets a certain engine hour criteria\nvar getValidEngineHoursTractors = function(tractorDetails) {\n return tractorDetails.filter(function(_tractorDetail) {\n return _tractorDetail.EngineHours > 0 && _tractorDetail.TractorModelID > 0;\n });\n};\n\n//Format the checks array to be in the form of tractorModelId to the checks\nvar getMaintenanceChecksHash = function(checks) {\n var checksHash = {};\n checks.map(function(check) {\n checksHash[check.tractorModelId] = checksHash[check.tractorModelId] || [];\n checksHash[check.tractorModelId].push(check);\n });\n return checksHash;\n};\n\n//Fetch tractor maintenance checks\n//@return Array of maintenance\nvar getTractorChecks = function(hours, checksHash, tractorDetail) {\n var tractorChecks = [];\n var modellD = tractorDetail.TractorModelID;\n var tractorEngineHour = tractorDetail.EngineHours;\n var modelTractorChecks = checksHash[modellD];\n\n //set an array of expected engine hours array\n var hours = [10, 50, 250, 300, 600, 900, 950, 1200];\n\n if (modelTractorChecks === undefined) {\n return tractorChecks;\n }\n //transform the ModeltractorChecks to be a hash of engineHour to maintenance value\n var checksHourHash = {};\n modelTractorChecks.forEach(function(_check) {\n checksHourHash[_check.engineHours] =\n checksHourHash[_check.engineHours] || [];\n checksHourHash[_check.engineHours].push(_check);\n });\n\n hours.forEach(function(hour) {\n if (tractorEngineHour % hour === 0) {\n var hourChecks = checksHourHash[hour];\n tractorChecks.push(hourChecks);\n }\n });\n\n return tractorChecks;\n};\n\n//flatten [ [a,b], [c,d] ] => [a,b,c,d]\nvar getFlattenedChecksArray = function(maintenanceChecksArr) {\n return maintenanceChecksArr.reduce(function(i, j) {\n return i.concat(j);\n }, []);\n};\n\nvar fetchMaintenanceChecksOnly = function(maintenanceArr) {\n var flattenedMaintenanceChecks = getFlattenedChecksArray(maintenanceArr);\n\n return flattenedMaintenanceChecks.map(function(maintenance) {\n //modules.logger.info(\"the maintenance is \" + JSON.stringify(maintenance))\n if (maintenance !== undefined) {\n return maintenance.maintenaceCheck;\n }\n });\n};\n\n// A function that returns formatted message to be sent to the tractor owner via push\nvar getFormatedChecksMessage = function(checks) {\n var message = \"\";\n var checksCount = checks.length;\n if (checksCount <= 3) {\n message = \"You have the following maintenance checks :\" + checks.join(\",\");\n } else {\n message = \"You have \" + checksCount + \" maintenance checks \";\n }\n return message;\n};\n\nvar getPushMessage = function(pushObj) {\n return {\n message: pushObj.message,\n type: \"alert\",\n data: pushObj.tractorChecks,\n tractorID: pushObj.tractorID,\n id: pushObj.id,\n _acl: pushObj._acl,\n _kmd: pushObj._kmd\n };\n};\n\nvar sendPushNotification = function(tractorOwner, message) {\n return Push.send(tractorOwner, message);\n};\n", "serviceBookingsHooksModule" : "\n var getServiceName = function(serviceTypeId) {\n var service_name;\n switch (serviceTypeId) {\n case 109:\n service_name = \"Harrowing\";\n break;\n case 104:\n service_name = \"Planting/Seeding\";\n break;\n case 105:\n service_name = \"Irrigating\";\n break;\n case 102:\n service_name = \"Ploughing\";\n break;\n case 101:\n service_name = \"Tilling\";\n break;\n case 103:\n service_name = \"Ridging\";\n break;\n case 107:\n service_name = \"Trailing\";\n break;\n case 108:\n service_name = \"Harvesting\";\n break;\n case 106:\n service_name = \"Harvesting\";\n break;\n case 110:\n service_name = \"Spreading\";\n break;\n }\n return service_name;\n };\n\n\n\n\n // /** helpers function starts **/\n\n var getPairedBookingsCount = function(bookings) {\n return bookings.filter(function(booking) {\n return booking.bookingStatus == 1 || booking.bookingStatus == 2;\n }).length;\n };\n \n var getCompletedBookingsCount = function(bookings) {\n return bookings.filter(function(booking) {\n return booking.bookingStatus == 3;\n }).length;\n };\n\n var getBookingStatus = function() {\n return request.body.bookingStatus;\n };\n\n var sendClusterNotification = function(userObj, notificationData) {\n return Push.send(userObj, notificationData);\n };\n\n var getBookingAgents = function(users) {\n return users.filter(function(user) {\n return user.user_type == 2;\n });\n };\n\n var getTractorOwner = function(users) {\n return users.filter(function(user) {\n return user.user_type == null;\n });\n };\n\n var isArchivedBooking = function() {\n return request.body.BookingArchived != null;\n };\n\n var getTotalHectares = function(bookings) {\n return bookings\n .reduce(function(total, booking) {\n return total + booking[\"hectaresServiced\"];\n }, 0)\n .toFixed(2);\n };\n\n var getServiceDate = function(bookings) {\n var serviceDate = bookings[0].serviceDate;\n return dateToHumanReadable(serviceDate);\n };\n\n var dateToHumanReadable = function(date) {\n return modules.moment(date).format(\"dddd Do MMMM YYYY\");\n };\n\n var getTractorName = function() {\n return JSON.parse(request.body.tractorDetailData)[\"TractorName\"]\n ? JSON.parse(request.body.tractorDetailData)[\"TractorName\"]\n : \"\";\n };\n\n var getOperatorName = function(bookings) {\n return JSON.parse(request.body.tractorOperatorData)[\"OperatorName\"]\n ? JSON.parse(request.body.tractorOperatorData)[\"OperatorName\"]\n : \"\";\n };\n\n var isDeletedOrgId = function() {\n // modules.logger.info( request.body.orgID == \"100\");\n return request.body.orgID == \"100\";\n };\n\n\n var sendTractorOwnerAppRefreshTrigger = function(\n tractorOwner,\n bookingAgents\n ) {\n var triggerData = {\n message: \"this is a trigger\",\n type: \"action\",\n action: \"trigger\",\n kind: 11,\n trigger: 102,\n entity: JSON.stringify(request.body)\n }\n };\n \n", "app_configs" : "var AWS_BACKEND_HOST = \"https://cloud.hellotractor.com\"\n", "BlockchainCommons" : "function getBookingManagerBaseUrl(){\n return \"https://ag-wallet-booking-manager-production.mybluemix.net\";\n}\n\nfunction getBookingManagerToken(){\n return \"Bearer eyJraWQiOiI0MTc5NjU2YS00MmVlLTRlYzMtOTI0MC1hZGQwMWY4ZGM1YjIiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJPUkcxLUFETUlOIiwidWlkIjoiNDE5NmI5ZjItOTk2OS00NjYyLWI0M2MtMDNiZTlkOTcxYjIyIiwiaXNzIjoiSUJNLVNNRSIsIm9pZCI6IjNmYzAzNDJjLTUxNWUtMTFlOS04NjQ3LWQ2NjNiZDg3M2Q5MyIsImV4cCI6MTU1NzkwMTk3NDYzNywicmlkIjpbIkdVRVNUIl0sImlhdCI6MTU1NzgxNTU3NDYzN30.K4xJPySQx7EzduCARWs5ZZMTMG95D9pIGkdn_iiLeo4oYi3jdkm-hGyV2pI6qxTjoCe_6z4fRxM7aYsjLpzKXyrf_q93uCDBYkWyQkZLJUvJOfoAUDfLOCGlWke6iKnEp5gvaChInBZCsIT_X2l2DusFQ8IOFLqmFFSTav0aTW4\";\n}\n\nfunction getFailedTransactionsCollection(){\n return \"FailedPosts\";\n}\n" } }, "pushService" : { "android" : { "projectId" : "760205348680", "apiKey" : "AAAAsP_FD0g:APA91bHO9clmAgTWyjnXC7Va9Ebd7S0RwyIkNm3SOZyd9Xv77Jy8pYDZ5cfskYEjL-fGkvDPuPF5kN1v-T9698HhaFfCkBelBjQc0teFywqEhhYBMLaen9dPGAmkrPEh4w-qI6TiEqsk" }, "serviceMetadata" : {} }, "schedulersecret" : "bd34e27881fb4802aa851cc22593e80a", "emailTemplates" : { "en_us" : { "passwordReset" : { "from" : "Hello Tractor Support <support@hellotractor.com>", "replyTo" : "Hello Tractor Support <support@hellotractor.com>", "subject" : "Your password reset request for application {{{appname}}}", "bodyTemplateText" : "{{#fname}}Dear {{fname}},{{/fname}}\n{{^fname}}Dear {{username}},{{/fname}}\n\nIt appears that you would like to reset your password. Please click on the link below to setup a new password:\n\n{{reseturl}}\n\nThis link will expire in less than {{expirationTimeMins}} mins ({{expirationDate}}).\n\nIf you did not request a password reset, please ignore this email. Your current password will continue to work.\n\nSincerely,\nYour {{appname}} team.", "bodyTemplateHtml" : "{{#fname}}<p>Dear {{fname}},</p>{{/fname}}\n{{^fname}}<p>Dear {{username}},</p>{{/fname}}\n\n<p>It appears that you would like to reset your password. Please click on the link below to setup a new password:</p>\n\n<p>\n<a href=\"{{reseturl}}\">{{reseturl}}</a>\n</p>\n\n<p>Please copy the link to your browser if you are unable to click in email.</p>\n\n<p>This link will expire in less than {{expirationTimeMins}} mins ({{expirationDate}}).</p>\n\n<p>If you did not request a password reset, please ignore this email. Your current password will continue to work.</p>\n\n\n<p><img src=\"https://www.hellotractor.com/wp-content/uploads/2017/03/symbol_small_blk.png\"> </p>\n\n<p>Sincerely,</p>\n<p>Your {{appname}} team.</p>", "confirmSubject" : "Your password was reset for application {{{appname}}}", "confirmBodyTemplateText" : "{{#fname}}<p>Dear {{fname}},</p>{{/fname}}\n{{^fname}}<p>Dear {{username}},</p>{{/fname}}\n\nThis is to confirm that your request to reset your password for app {{appname}} was successfully implemented at {{lastChangedAt}}.\n\nSincerely,\nYour {{appname}} team.\n", "confirmBodyTemplateHtml" : "{{#fname}}<p>Dear {{fname}},</p>{{/fname}}\n{{^fname}}<p>Dear {{username}},</p>{{/fname}}\n\n<p>This is to confirm that your request to reset your password for app {{appname}} was successfully implemented at {{lastChangedAt}}.</p>\n\n<p>Sincerely,</p>\n<p>Your {{appname}} team.</p>\n" }, "forgotUsername" : { "from" : "Hello Tractor Support <support@hellotractor.com>", "replyTo" : "Hello Tractor Support <support@hellotractor.com>", "subject" : "Your username reminder for application {{{appname}}}", "bodyTemplateText" : "{{#fname}}Dear {{fname}},{{/fname}}\n{{^fname}}Dear {{username}},{{/fname}}\n\nIt appears that you forgot your username. Don't worry, it happens to us, too.\n\nYour username is: {{ username }}\n\nSincerely,\nYour {{appname}} team.", "bodyTemplateHtml" : "{{#fname}}<p>Dear {{fname}},</p>{{/fname}}\n{{^fname}}<p>Dear {{username}},</p>{{/fname}}\n\n<p>It appears that you forgot your username. Don't worry, it happens to us, too.</p>\n\n<p>Your username is: {{ username }}</p>\n\n<p>Sincerely,</p>\n<p>Your {{appname}} team.</p>" } } }, "htmlTemplates" : { "en_us" : { "passwordReset" : { "successPageHtml" : "<html>\n <head>\n <title>Success!!!</title>\n </head>\n\t<body background=\"https://www.hellotractor.com/wp-content/uploads/2016/07/Home-page2png.jpg\">\n <center>\n <h2> <b> <font color=\"white\">Password Reset Successful! </font> </b> </h2>\n <br>\n <p><font color=\"white\"> Congratulations! You have <b>successfully</b> reset your password for app {{appname}}. </font></p>\n </center>\n </body>\n</html>" } } }, "blFlags" : { "blChannel" : "kbl-flex-router" }, "_systemData" : { "configOverrides" : { "bl" : { "replicas" : { "min" : 50, "max" : 50 }, "resources" : { "limits" : { "cpu" : "150m", "memory" : "500Mi" }, "requests" : { "cpu" : "150m", "memory" : "500Mi" } }, "targetUtilization" : { "cpu" : 50, "memory" : 60 }, "maxOldSpaceSize" : 230 }, "modifiedBy" : "d2c294fe61f74888942d84e22a189af6", "modifiedAt" : "2020-03-23T15:41:49.998Z" } } } var myCopy = null;
Tests:
Lodash cloneDeep
myCopy = _.cloneDeep(MyObject);
Json clone
myCopy = JSON.parse(JSON.stringify(MyObject));
Rendered benchmark preparation results:
Suite status:
<idle, ready to run>
Run tests (2)
Previous results
Fork
Test case name
Result
Lodash cloneDeep
Json clone
Fastest:
N/A
Slowest:
N/A
Latest run results:
No previous run results
This benchmark does not have any results yet. Be the first one
to run it!
Autogenerated LLM Summary
(model
llama3.2:3b
, generated one year ago):
I'll do my best to provide a helpful response. It seems like you've provided a large JSON object with various properties and values related to HTML templates, benchmarking data, and test cases. However, there doesn't appear to be a specific question or problem that needs solving. If I had to guess, it might be related to optimizing or working with the HTML templates, perhaps using Lodash's `cloneDeep` function for benchmarking purposes? If you could provide more context or clarify what you'd like help with, I'll do my best to assist you!
Related benchmarks:
Lodash cloneDeep vs JSON Clone (Number, Boolean, Object, Array, String, Null)
Lodash cloneDeep vs JSON Clone with Array
cloneDeep vs JSON stringify + parse (long arr)
lodash cloneDeep vs json.stringify
Lodash(v4.17.21) cloneDeep vs JSON Clone Larger object
Comments
Confirm delete:
Do you really want to delete benchmark?