NAV
shell python javascript

Introduction

Optimisation of assets including vehicles, goods, people and energy. Our powerful algorithms cut costs and emissions while improving productivity. Trakm8 Vortex is a suite of algorithms that solve Vehicle Routing Problems.

Trakm8 Vortex API supports both REST and WebSocket communication protocols. The request and response payload format uses JSON.

Vehicle routing problems can take a long time to solve as they are computationally intensive.

A key challenge that faces the logistics sector is the underlying complexity of managing mobile assets efficiently while meeting business objectives. Fleets are become larger, interacting with and adopting new technologies such as electric vehicles and eventually self-driving vehicles. The need for optimisation algorithms which produce realistic solutions, given ever more complex constraints, is growing exponentially.

The challenge is creating effective algorithms which scale. This is where Trakm8 Vortex excels. With our cloud based, highly scalable algorithms we are a recognised world leader in optimisation solutions.

The constrained vehicle routing problem (CVRP) is a combinatorial challenge that requires solving the following two problems together: 1. decide which vehicles will do which tasks 2. for each vehicle, decide the best sequence for the tasks assigned to it. The tasks can be deliveries, collections, transfers, engineering or maintenance visits, or any of a variety of other jobs to be done at some specific location; there maybe many constraints such as time-windows, tools, load and waiting times, capacity & weight, operator & driver skills, vehicle characteristics (e.g. lift or crane), battery charging time, battery capacity, vehicle range and many more constraints.

The routing uses a connected graph to mathematically model the segments of a road network and this has its own constraints such as speed limits, turn restrictions, truck restrictions (e.g. width, height, weight), legal restrictions, traffic patterns, weather and so on. Given all of these constraints the challenge is to quickly calculate good solutions for CVRPs that may have, typically, from 5 to 500 vehicles and from 10s to 10000s of jobs per day. Computationally this is a big challenge; however the use of cloud computing, parallel processing and centralised web-services has allowed significant computational capacity to be deployed. Even small vehicle fleets can access huge computational power which would otherwise be unaffordable.

Licence

The use of this application is subject to the Trakm8 End User License Agreement (EULA) and by accessing the application, you agree that any use you make of the application shall be in strict compliance with the EULA. The EULA is available on request. Contact information for Trakm8 Limited is available at www.trakm8.com. Software distributed under the EULA is distributed on an "AS IS" basis WITHOUT WARRANTY OF ANY KIND, either express or implied. Copyright © 1999-2019 Trakm8 Limited. All Rights Reserved. Use of this application is also subject to certain third party terms which are available at: https://legal.here.com/terms/b2bserviceterms/en

Background

The algorithms available are mainly ‘metaheuristic’ algorithms. This class of algorithm includes: genetic algorithms,evolutionary algorithms, tabu search and simulated annealing. Vortex also includes algorithms that are hybrids, combining aspects of more than one different algorithm.

Some examples in the Vortex algorithms suite include:

RESTful API

The API is based on the principles of a RESTFul web services. The payload is a JSON encoded format. The calculation of an optimised schedule can take several minutes. Large and complex requests with constraints and hundreds of vehicles will take longer to execute. For this reason the initial HTTP Post request returns immediately with a unique ID for this request. The client must use this ID to poll the server until a solution is available. Polling of the server with the ID will provide progress updates.

POST https://DOMAIN:PORT/RESOURCE?APIKEY=xxxxxx

The content payload is JSON

In summary the client process is:

  1. Client sends HTTPS POST Request with the JSON payload; the server returns with a request ID; the algorithm calculation starts.
  2. Client repeatedly sends HTTPS GET Request with the request ID appended in the URL; the sever replies with progress update.
  3. Finally, the client send a HTTPS GET Requests with the request ID; the server replies with the complete schedule.

The recommended poll rate is that the client should not send requests more frequently than 10 seconds. The server responds with HTTP status code 200. The final results is stored for a short time (~ 1 hour), so the client may make subsequent poll requests.

The payload format is defined later.

Convert JSON V1 to V2

For JSON v1 to v2 migration purposes, it is sometimes helpful to convert a Vortex JSON V1 request to V2. This can be done by the v1tov2 end-point. However, this way is not recommended to be used in production as this is only designed to help Vortex users to migrate to V2 JSON with less hassle.

Convert V1 to V2 example

import json
import requests

data = '{"ContinueWithoutImprovementTime":9,"PlanDate":"02/01/2019","TotalRunTime":1200,"Depots":[{"Latitude":51.5319517,"Longitude":0.1078958,"Tag":"2|DEPOT"}],"Drivers":[{"Tag":"250|DRIVER","MaximumDrivingDuration":"09:07:00"}],"Requests":[{"Latitude":51.6003284,"Longitude":0.3166651,"Tag":"268887|ORDER"}],"Vehicles":[{"Depot":"2|DEPOT","Driver":"250|DRIVER","Tag":"250|VEHICLE"}]}'


r = requests.post(url = "https://api-core01.trakm8.net:8443/bdservices/vortex/api/latest/v1tov2?apikey=APIKEY", data = data)

print(r.status_code, r.text)
var data = {"ContinueWithoutImprovementTime":9,"PlanDate":"02/01/2019","TotalRunTime":1200
,"Depots":[{"Latitude":51.5319517,"Longitude":0.1078958,"Tag":"2|DEPOT"}],"Drivers":[{"Tag":"250|DRIVER","MaximumDrivingDuration":"09:07:00"}],"Requests":[{"Latitude":51.6003284,"Longitude":0.3166651,"Tag":"2688
87|ORDER"}],"Vehicles":[{"Depot":"2|DEPOT","Driver":"250|DRIVER","Tag":"250|VEHICLE"}]};

var xmlhttp = new XMLHttpRequest();   // new HttpRequest instance 
xhttp.onreadystatechange = function() {
    if (this.readyState == 4) {
      if (this.status == 200)
        console.log(JSON.stringify(this))
    }
  };

xmlhttp.open("POST", "https://api-core01.trakm8.net:8443/bdservices/vortex/api/latest/v1tov2?apikey=APIKEY");
xmlhttp.setRequestHeader("Content-Type", "application/json");
xmlhttp.send(JSON.stringify(data));
curl -XPOST "https://api-core01.trakm8.net:8443/bdservices/vortex/api/latest/v1tov2?apikey=APIKEY" -d '{"ContinueWithoutImprovementTime":9,"PlanDate":"02/01/2019","TotalRunTime":1200
,"Depots":[{"Latitude":51.5319517,"Longitude":0.1078958,"Tag":"2|DEPOT"}],"Drivers":[{"Tag":"250|DRIVER","MaximumDrivingDuration":"09:07:00"}],"Requests":[{"Latitude":51.6003284,"Longitude":0.3166651,"Tag":"2688
87|ORDER"}],"Vehicles":[{"Depot":"2|DEPOT","Driver":"250|DRIVER","Tag":"250|VEHICLE"}]}'

Terminate a schedule

You can stop the scheduling request at any time of the execution as long as you know the RequestId. This can be done by sending a DELETE RESTFul request to the service.

DELETE https://DOMAIN:PORT/REQUEST_ID?APIKEY=xxxxxx

Please note that when there is no active process dealing with the targeted scheduling request, the service would return an error message with HTTP status code 404 Not Found.

Terminate Example

You can terminate a running V2 schedule request with RequestId = f06fa1bd248f5759ee86dc49fbe14c35b3cda3e41ce3fac0e04cb0b461bdd7c1.

Terminate a schedule as Follows:

import requests

r = requests.delete(url = "https://api-core01.trakm8.net:8443/bdservices/vortex/api/latest/f06fa1bd248f5759ee86dc49fbe14c35b3cda3e41ce3fac0e04cb0b461bdd7c1?apikey=APIKEY")

print(r.status_code)
print(r.text)
var xmlhttp = new XMLHttpRequest();   // new HttpRequest instance 
xhttp.onreadystatechange = function() {
    if (this.readyState == 4) {
      console.log(JSON.stringify(this))
    }
  };

xmlhttp.open("DELETE", "https://api-core01.trakm8.net:8443/bdservices/vortex/api/latest/f06fa1bd248f5759ee86dc49fbe14c35b3cda3e41ce3fac0e04cb0b461bdd7c1?apikey=APIKEY");
xmlhttp.setRequestHeader("Content-Type", "application/json");
xmlhttp.send(null);
 curl -XDELETE "https://api-core01.trakm8.net:8443/bdservices/vortex/api/latest/f06fa1bd248f5759ee86dc49fbe14c35b3cda3e41ce3fac0e04cb0b461bdd7c1?apikey=APIKEY"

V1 JSON Request

Supports RESTful only.

This API format and algorithm is identical to the Route Monkey quantum format and algorithm. The tm8rmscheduler service is a trakm8 service for solving the vehicle routing problems. Given a list of depots, vehicles, drivers and job requests, the service should be able to find a near optimal plan.

import requests
r = requests.get("http://[API_END_POINT]/")

if r.status_code == 200:
  print("alive")

 curl -I "http://[API_END_POINT]/"
var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4) {
      if (this.status == 200)
        alert("Alive");
      else 
        alert("dead");
    }
  };
  xhttp.open("GET", "http://[API_END_POINT]/", true);
  xhttp.send();

Make sure to replace http://[API_END_POINT]/ with the actual endpoint url.

This endpoint is an alive test, it can be used to check if the service is up and running

In order to use the scheduler API, one should first post the input problem to the endpoint: http://[API_END_POINT]/. If the request is valid and good to go, the scheduler then return with http status code 200 and a unique request id which can be used to retrieve the result later. The end user should keep polling the service for the result using the request id generated earlier.

In other words, there are two parts required to get a plan:

  1. Make a Schedule Request: POST the input request to the service
  2. Polling for Result: GET the response from the service by frequent polling attempts.

RESTFul V1 Example

  1. POST the JSON Request, which would return a request id.

Post JSON request example:

import json
import requests

data = {"ContinueWithoutImprovementTime":30,"Depots":[{"Characteristics":"","ClosingTime":"23:00:00","Latitude":54.3323,"LoadingTime":"00:00:30","LocationGeohash":"gcwj1dgu","Longitude":-2.7413,"MaximumVehiclesNumber":5,"OpeningTime":"05:00:00","Tag":"Depot_1"}],"Drivers":[{"BreakDuration":"00:45:00","BreifingTime":"00:15:00","CostPerDay":22,"CostPerHour":3.5,"DebreifingTime":"00:00:00","EarliestBreakTime":"04:30:00","MaxOvernights":2,"MaximumDrivingDuration":"10:00:00","MaximumOvertime":"01:30:00","MaximumWorkingTime":"11:00:00","MinOvernightDrivingDistanceKM":180,"OvernightCost":75,"OvertimeCostPerHour":7,"PossibleDays":"1","RequestCharacteristics":"driverskill_1","SecondManEffect":1,"SecondManFixedCost":0,"ShiftEarlyStart":"06:00:00","ShiftLateStart":"08:00:00","Tag":"Driver_1"}],"EnableIntermediateResults":true,"Locations":[{"Latitude":54.3323,"LocationGeohash":"gcwj1dgu","Longitude":-2.7413},{"Latitude":51.4904,"LocationGeohash":"gcnhzjd3","Longitude":-2.5016}],"RequestId":"257116863fc9c1e92f2456a13ae040857eb6dde36e971e20ddabf4f6756d7683","Requests":[{"CanSplitOverCompartment":false,"DepotCharacteristics":"","DriverCharacteristics":"","FixedVistDuration":"00:15:00","Id":1,"Latitude":51.4904,"LoadTimePerUnit":"00:00:00","LocationGeohash":"gcnhzjd3","Longitude":-2.5016,"MatchAllTractor":true,"MatchAllTrailer":false,"MatchAlldepot":false,"MatchAlldriver":false,"PossibleVistDays":"1","Quantity1":1,"Quantity2":40,"Quantity3":0,"Quantity4":0,"RevenueIncome":10000,"Service":0,"Tag":"Job_2","TimeWindows":"07:00:00,12:30:00,13:30:00,19:30:00","TractorCharacteristics":"","TrailerCharacteristics":"","TransportSeperately":false,"Weight":0}],"SpeedProfiles":[],"TotalRunTime":120,"Vehicles":[{"Backhaul":false,"Capacity1":12,"Capacity2":400,"Capacity3":0,"Capacity4":0,"CarryingWeightKg":1200,"CharacteristicsRequest":"resourceskill_1","CostPerKm":3.5,"Costperday":30,"CostperdayOfNonUse":20,"Depot":"Depot_1","DepotLoadingTime":"00:05:00","Driver":"Driver_1","EndLatitude":54.3323,"EndLocationGeohash":"gcwj1dgu","EndLongitude":-2.7413,"HandlingTimePerUnit":"00:00:00","LegalDrivingDuration":"04:30:00","LegalRestDuration":"00:30:00","MaximumLoadUnloadTime":"00:30:00","MaximumWorkingTime":"15:00:00","MinRestDuration":"00:15:00","OpenEnd":false,"OpenStart":false,"OperatingRadiusKM":1000000,"PossibleDays":"1","PreLoad":false,"StartLatitude":54.3323,"StartLocationGeohash":"gcwj1dgu","StartLongitude":-2.7413,"StartTime":"04:00:00","SurpressDepotReload":false,"Tag":"Resource_1","UnloadAfterShift":true}]}

r = requests.post(url = "https://api-core01.trakm8.net:8443/bdservices/vortex/api/latest/v2?apikey=APIKEY", data = json.dumps(data))

if r.status_code == 200:
  print(r.text)
var data = {"ContinueWithoutImprovementTime":30,"Depots":[{"Characteristics":"","ClosingTime":"23:00:00","Latitude":54.3323,"LoadingTime":"00:00:30","LocationGeohash":"gcwj1dgu","Longitude":-2.7413,"MaximumVehiclesNumber":5,"OpeningTime":"05:00:00","Tag":"Depot_1"}],"Drivers":[{"BreakDuration":"00:45:00","BreifingTime":"00:15:00","CostPerDay":22,"CostPerHour":3.5,"DebreifingTime":"00:00:00","EarliestBreakTime":"04:30:00","MaxOvernights":2,"MaximumDrivingDuration":"10:00:00","MaximumOvertime":"01:30:00","MaximumWorkingTime":"11:00:00","MinOvernightDrivingDistanceKM":180,"OvernightCost":75,"OvertimeCostPerHour":7,"PossibleDays":"1","RequestCharacteristics":"driverskill_1","SecondManEffect":1,"SecondManFixedCost":0,"ShiftEarlyStart":"06:00:00","ShiftLateStart":"08:00:00","Tag":"Driver_1"}],"EnableIntermediateResults":true,"Locations":[{"Latitude":54.3323,"LocationGeohash":"gcwj1dgu","Longitude":-2.7413},{"Latitude":51.4904,"LocationGeohash":"gcnhzjd3","Longitude":-2.5016}],"RequestId":"257116863fc9c1e92f2456a13ae040857eb6dde36e971e20ddabf4f6756d7683","Requests":[{"CanSplitOverCompartment":false,"DepotCharacteristics":"","DriverCharacteristics":"","FixedVistDuration":"00:15:00","Id":1,"Latitude":51.4904,"LoadTimePerUnit":"00:00:00","LocationGeohash":"gcnhzjd3","Longitude":-2.5016,"MatchAllTractor":true,"MatchAllTrailer":false,"MatchAlldepot":false,"MatchAlldriver":false,"PossibleVistDays":"1","Quantity1":1,"Quantity2":40,"Quantity3":0,"Quantity4":0,"RevenueIncome":10000,"Service":0,"Tag":"Job_2","TimeWindows":"07:00:00,12:30:00,13:30:00,19:30:00","TractorCharacteristics":"","TrailerCharacteristics":"","TransportSeperately":false,"Weight":0}],"SpeedProfiles":[],"TotalRunTime":120,"Vehicles":[{"Backhaul":false,"Capacity1":12,"Capacity2":400,"Capacity3":0,"Capacity4":0,"CarryingWeightKg":1200,"CharacteristicsRequest":"resourceskill_1","CostPerKm":3.5,"Costperday":30,"CostperdayOfNonUse":20,"Depot":"Depot_1","DepotLoadingTime":"00:05:00","Driver":"Driver_1","EndLatitude":54.3323,"EndLocationGeohash":"gcwj1dgu","EndLongitude":-2.7413,"HandlingTimePerUnit":"00:00:00","LegalDrivingDuration":"04:30:00","LegalRestDuration":"00:30:00","MaximumLoadUnloadTime":"00:30:00","MaximumWorkingTime":"15:00:00","MinRestDuration":"00:15:00","OpenEnd":false,"OpenStart":false,"OperatingRadiusKM":1000000,"PossibleDays":"1","PreLoad":false,"StartLatitude":54.3323,"StartLocationGeohash":"gcwj1dgu","StartLongitude":-2.7413,"StartTime":"04:00:00","SurpressDepotReload":false,"Tag":"Resource_1","UnloadAfterShift":true}]};

var xmlhttp = new XMLHttpRequest();   // new HttpRequest instance 
xhttp.onreadystatechange = function() {
    if (this.readyState == 4) {
      if (this.status == 200)
        console.log(JSON.stringify(this))
    }
  };

xmlhttp.open("POST", "https://api-core01.trakm8.net:8443/bdservices/vortex/api/latest/v2?apikey=APIKEY");
xmlhttp.setRequestHeader("Content-Type", "application/json");
xmlhttp.send(JSON.stringify(data));

 curl -XPOST "https://api-core01.trakm8.net:8443/bdservices/vortex/api/latest/v1?apikey=APIKEY" -d '{"ContinueWithoutImprovementTime":30,"Depots":[{"Characteristics":"","ClosingTime":"23:00:00","Latitude":54.3323,"LoadingTime":"00:00:30","LocationGeohash":"gcwj1dgu","Longitude":-2.7413,"MaximumVehiclesNumber":5,"OpeningTime":"05:00:00","Tag":"Depot_1"}],"Drivers":[{"BreakDuration":"00:45:00","BreifingTime":"00:15:00","CostPerDay":22,"CostPerHour":3.5,"DebreifingTime":"00:00:00","EarliestBreakTime":"04:30:00","MaxOvernights":2,"MaximumDrivingDuration":"10:00:00","MaximumOvertime":"01:30:00","MaximumWorkingTime":"11:00:00","MinOvernightDrivingDistanceKM":180,"OvernightCost":75,"OvertimeCostPerHour":7,"PossibleDays":"1","RequestCharacteristics":"driverskill_1","SecondManEffect":1,"SecondManFixedCost":0,"ShiftEarlyStart":"06:00:00","ShiftLateStart":"08:00:00","Tag":"Driver_1"}],"EnableIntermediateResults":true,"Locations":[{"Latitude":54.3323,"LocationGeohash":"gcwj1dgu","Longitude":-2.7413},{"Latitude":51.4904,"LocationGeohash":"gcnhzjd3","Longitude":-2.5016}],"RequestId":"257116863fc9c1e92f2456a13ae040857eb6dde36e971e20ddabf4f6756d7683","Requests":[{"CanSplitOverCompartment":false,"DepotCharacteristics":"","DriverCharacteristics":"","FixedVistDuration":"00:15:00","Id":1,"Latitude":51.4904,"LoadTimePerUnit":"00:00:00","LocationGeohash":"gcnhzjd3","Longitude":-2.5016,"MatchAllTractor":true,"MatchAllTrailer":false,"MatchAlldepot":false,"MatchAlldriver":false,"PossibleVistDays":"1","Quantity1":1,"Quantity2":40,"Quantity3":0,"Quantity4":0,"RevenueIncome":10000,"Service":0,"Tag":"Job_2","TimeWindows":"07:00:00,12:30:00,13:30:00,19:30:00","TractorCharacteristics":"","TrailerCharacteristics":"","TransportSeperately":false,"Weight":0}],"SpeedProfiles":[],"TotalRunTime":120,"Vehicles":[{"Backhaul":false,"Capacity1":12,"Capacity2":400,"Capacity3":0,"Capacity4":0,"CarryingWeightKg":1200,"CharacteristicsRequest":"resourceskill_1","CostPerKm":3.5,"Costperday":30,"CostperdayOfNonUse":20,"Depot":"Depot_1","DepotLoadingTime":"00:05:00","Driver":"Driver_1","EndLatitude":54.3323,"EndLocationGeohash":"gcwj1dgu","EndLongitude":-2.7413,"HandlingTimePerUnit":"00:00:00","LegalDrivingDuration":"04:30:00","LegalRestDuration":"00:30:00","MaximumLoadUnloadTime":"00:30:00","MaximumWorkingTime":"15:00:00","MinRestDuration":"00:15:00","OpenEnd":false,"OpenStart":false,"OperatingRadiusKM":1000000,"PossibleDays":"1","PreLoad":false,"StartLatitude":54.3323,"StartLocationGeohash":"gcwj1dgu","StartLongitude":-2.7413,"StartTime":"04:00:00","SurpressDepotReload":false,"Tag":"Resource_1","UnloadAfterShift":true}]}'

This returns with a request Id:

{
  "RequestId":"5ad316ecb44c597d180676010e32be72304540014f0d0bdffe22b845bc935e83"
}
  1. GET the response using previous request Id, which would return the result plan with status: HTTP/1.1 200 OK. If the results are not ready yet, the service response with status: HTTP/1.1 202 Accepted and may return any intermediate results if there are any.

Get JSON response using request Id:

import requests
r = requests.get("https://api-core01.trakm8.net:8443/bdservices/vortex/api/latest/v1/5ad316ecb44c597d180676010e32be72304540014f0d0bdffe22b845bc935e83?apikey=APIKEY")

if r.status_code == 200:
  print(r.text)

var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4) {
      if (this.status == 200)
        console.log(JSON.stringify(this));
    }
  };
  xhttp.open("GET", "https://api-core01.trakm8.net:8443/bdservices/vortex/api/latest/v1/5ad316ecb44c597d180676010e32be72304540014f0d0bdffe22b845bc935e83?apikey=APIKEY", true);
  xhttp.send();
curl -v -XGET "https://api-core01.trakm8.net:8443/bdservices/vortex/api/latest/v1/5ad316ecb44c597d180676010e32be72304540014f0d0bdffe22b845bc935e83?apikey=APIKEY"

JSON response:

{
  "RequestId": "5ad316ecb44c597d180676010e32be72304540014f0d0bdffe22b845bc935e83",
  "Cost": 2648.7859393439312,
  "Miles": 456.31693105407209,
  "UnPlanned": 0,
  "ExecutionTimeSecond": 0,
  "UnplannedRequests": [],
  "Data": [
    {
      "Tag": null,
      "RunOrder": 0,
      "RunNo": "0",
      "Day": 1,
      "Eta": 360.0,
      "Duration": 0.0,
      "Vehicle": "Resource_1",
      "Miles": 0.0,
      "Task": "TSKSHIFTSTART"
    },
    {
      "Tag": "Resource_1",
      "RunOrder": 1,
      "RunNo": "0",
      "Day": 1,
      "Eta": 360.0,
      "Duration": 15.0,
      "Vehicle": "Resource_1",
      "Miles": 0.0,
      "Task": "TSKBRIEFING"
    },
    {
      "Tag": null,
      "RunOrder": 2,
      "RunNo": "0",
      "Day": 1,
      "Eta": 375.0,
      "Duration": 189.63103519624377,
      "Vehicle": "Resource_1",
      "Miles": 228.09277804951685,
      "Task": "TSKTRAVEL"
    },
    {
      "Tag": "Job_2",
      "RunOrder": 3,
      "RunNo": "0",
      "Day": 1,
      "Eta": 564.63103519624383,
      "Duration": 15.0,
      "Vehicle": "Resource_1",
      "Miles": 228.09277804951685,
      "Task": "TSKSERVICE"
    },
    {
      "Tag": null,
      "RunOrder": 4,
      "RunNo": "0",
      "Day": 1,
      "Eta": 579.63103519624383,
      "Duration": 50.368964803756228,
      "Vehicle": "Resource_1",
      "Miles": 60.67942893695286,
      "Task": "TSKTRAVEL"
    },
    {
      "Tag": null,
      "RunOrder": 5,
      "RunNo": "0",
      "Day": 1,
      "Eta": 630.0,
      "Duration": 45.0,
      "Vehicle": "Resource_1",
      "Miles": 288.77220698646971,
      "Task": "TSKLUNCH"
    },
    {
      "Tag": null,
      "RunOrder": 6,
      "RunNo": "0",
      "Day": 1,
      "Eta": 675.0,
      "Duration": 30.0,
      "Vehicle": "Resource_1",
      "Miles": 36.140962499448307,
      "Task": "TSKTRAVEL"
    },
    {
      "Tag": null,
      "RunOrder": 7,
      "RunNo": "0",
      "Day": 1,
      "Eta": 705.0,
      "Duration": 109.07603379696371,
      "Vehicle": "Resource_1",
      "Miles": 131.40376156815404,
      "Task": "TSKTRAVEL"
    },
    {
      "Tag": "Resource_1",
      "RunOrder": 8,
      "RunNo": "0",
      "Day": 1,
      "Eta": 814.07603379696366,
      "Duration": 0.0,
      "Vehicle": "Resource_1",
      "Miles": 456.31693105407209,
      "Task": "TSKDEBRIEFING"
    },
    {
      "Tag": null,
      "RunOrder": 9,
      "RunNo": "0",
      "Day": 1,
      "Eta": 814.07603379696366,
      "Duration": 0.0,
      "Vehicle": "Resource_1",
      "Miles": 456.31693105407209,
      "Task": "TSKSHIFTEND"
    }
  ]
}

Part 1: Make a Schedule Request

This endpoint allow users to send input to the scheduler, the input should define a vehicle routing problem. This can be done by defining a list of Depots, Drivers, Vehicles, and Requests. As a result, the service respond with a unique request ID which can be used later to retrieve the plan. For more details please check Part 1 HTTP Response.

Input request has the following JSON format

{
  "ContinueWithoutImprovementTime": 5,
  "TotalRunTime": 1200,
  "Depots": [
    {
      "Latitude": 51.5319518,
      "Longitude": 0.1078958,
      "Tag": "2|DEPOT"
    }
  ],
  "Drivers": [
    {
      "BreakDuration": "00:30:00",
      "CostPerDay": 131.43,
      "CostPerHour": 16.43,
      "EarliestBreakTime": "04:00:00",
      "MaximumDrivingDuration": "09:00:00",
      "MaximumWorkingTime": "18:00:00",
      "PossibleDays": "1",
      "ShiftEarlyStart": "06:00:00",
      "Tag": "250|DRIVER"
    }
  ],
  "Requests": [
    {
      "AdditionalTag": "",
      "FixedVisitDuration": "00:04:00",
      "Latitude": 51.6003284,
      "Longitude": 0.3166651,
      "PossibleVisitDays": "1",
      "Quantity1": 49.38,
      "RevenueIncome": 1000,
      "Service": 1,
      "Tag": "268887|ORDER",
      "TimeWindows": "06:00:00,18:00:00",
      "TractorCharacteristics": ""
    }
  ],
  "SpeedProfile": {
    "Catergory1KPH": 80,
    "Catergory2KPH": 56,
    "Catergory3KPH": 48,
    "Catergory4KPH": 45,
    "Catergory5KPH": 35,
    "Catergory6KPH": 29
  },
  "SpeedProfiles": [
    {
      "Catergory1KPH": 101,
      "Catergory2KPH": 87,
      "Catergory3KPH": 72,
      "Catergory4KPH": 58,
      "Catergory5KPH": 43,
      "Catergory6KPH": 29,
      "Tag": "1|SPEED_PROFILE"
    }
  ],
  "Vehicles": [
    {
      "Capacity1": 1500,
      "CharacteristicsRequest": "250",
      "CostPerKm": 0.1,
      "CostPerDay": 4.8,
      "Depot": "2|DEPOT",
      "Driver": "250|DRIVER",
      "LegalDrivingDuration": "04:30:00",
      "MaximumLoadUnloadTime": "05:00:00",
      "PossibleDays": "1",
      "SpeedProfile": "1|SPEED_PROFILE",
      "Tag": "250|VEHICLE"
    }
  ]
}
import json
import requests

data = {"ContinueWithoutImprovementTime":5,"Depots":[{"Latitude":51.5319518,"Longitude":0.1078958,"Tag":"2|DEPOT"}],"Drivers":[{"BreakDuration":"00:30:00","CostPerDay":131.43,"CostPerHour":16.43,"EarliestBreakTime":"04:00:00","MaximumDrivingDuration":"09:00:00","MaximumWorkingTime":"18:00:00","PossibleDays":"1","ShiftEarlyStart":"06:00:00","Tag":"250|DRIVER"}],"Requests":[{"AdditionalTag":"","FixedVisitDuration":"00:04:00","Latitude":51.6003284,"Longitude":0.3166651,"PossibleVisitDays":"1","Quantity1":49.38,"RevenueIncome":1000,"Service":1,"Tag":"268887|ORDER","TimeWindows":"06:00:00,18:00:00","TractorCharacteristics":""}],"SpeedProfile":{"Catergory1KPH":80,"Catergory2KPH":56,"Catergory3KPH":48,"Catergory4KPH":45,"Catergory5KPH":35,"Catergory6KPH":29},"SpeedProfiles":[{"Catergory1KPH":101,"Catergory2KPH":87,"Catergory3KPH":72,"Catergory4KPH":58,"Catergory5KPH":43,"Catergory6KPH":29,"Tag":"1|SPEED_PROFILE"}],"TotalRunTime":1200,"Vehicles":[{"Capacity1":1500,"CharacteristicsRequest":"250","CostPerKm":0.1,"CostPerDay":4.8,"Depot":"2|DEPOT","Driver":"250|DRIVER","LegalDrivingDuration":"04:30:00","MaximumLoadUnloadTime":"05:00:00","PossibleDays":"1","SpeedProfile":"1|SPEED_PROFILE","Tag":"250|VEHICLE"}]}

r = requests.post(url = "http://[API_END_POINT]/", data = json.dumps(data))

if r.status_code == 200:
  print(r.text)

 curl -X POST \
  http://[API_END_POINT]/ \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/json' \
  -d '{"SpeedProfile": {"Catergory4KPH": 45, "Catergory5KPH": 35, "Catergory6KPH": 29, "Catergory1KPH": 80, "Catergory2KPH": 56, "Catergory3KPH": 48}, "SpeedProfiles": [{"Catergory4KPH": 58, "Catergory5KPH": 43, "Catergory6KPH": 29, "Tag": "1|SPEED_PROFILE", "Catergory1KPH": 101, "Catergory2KPH": 87, "Catergory3KPH": 72}], "Requests": [{"Service": 1, "TractorCharacteristics": "", "Longitude": 0.3166651, "AdditionalTag": "", "Latitude": 51.6003284, "FixedVisitDuration": "00:04:00", "TimeWindows": "06:00:00,18:00:00", "Tag": "268887|ORDER", "PossibleVisitDays": "1", "RevenueIncome": 1000, "Quantity1": 49.38}], "TotalRunTime": 1200, "Vehicles": [{"CostPerDay": 4.8, "MaximumLoadUnloadTime": "05:00:00", "SpeedProfile": "1|SPEED_PROFILE", "Depot": "2|DEPOT", "Capacity1": 1500, "CharacteristicsRequest": "250", "Driver": "250|DRIVER", "LegalDrivingDuration": "04:30:00", "Tag": "250|VEHICLE", "PossibleDays": "1", "CostPerKm": 0.1}], "ContinueWithoutImprovementTime": 5, "Drivers": [{"CostPerDay": 131.43, "Tag": "250|DRIVER", "BreakDuration": "00:30:00", "CostPerHour": 16.43, "MaximumWorkingTime": "18:00:00", "MaximumDrivingDuration": "09:00:00", "ShiftEarlyStart": "06:00:00", "EarliestBreakTime": "04:00:00", "PossibleDays": "1"}], "Depots": [{"Latitude": 51.5319518, "Tag": "2|DEPOT", "Longitude": 0.1078958}]}'

var data = {"ContinueWithoutImprovementTime":5,"Depots":[{"Latitude":51.5319518,"Longitude":0.1078958,"Tag":"2|DEPOT"}],"Drivers":[{"BreakDuration":"00:30:00","CostPerDay":131.43,"CostPerHour":16.43,"EarliestBreakTime":"04:00:00","MaximumDrivingDuration":"09:00:00","MaximumWorkingTime":"18:00:00","PossibleDays":"1","ShiftEarlyStart":"06:00:00","Tag":"250|DRIVER"}],"Requests":[{"AdditionalTag":"","FixedVisitDuration":"00:04:00","Latitude":51.6003284,"Longitude":0.3166651,"PossibleVisitDays":"1","Quantity1":49.38,"RevenueIncome":1000,"Service":1,"Tag":"268887|ORDER","TimeWindows":"06:00:00,18:00:00","TractorCharacteristics":""}],"SpeedProfile":{"Catergory1KPH":80,"Catergory2KPH":56,"Catergory3KPH":48,"Catergory4KPH":45,"Catergory5KPH":35,"Catergory6KPH":29},"SpeedProfiles":[{"Catergory1KPH":101,"Catergory2KPH":87,"Catergory3KPH":72,"Catergory4KPH":58,"Catergory5KPH":43,"Catergory6KPH":29,"Tag":"1|SPEED_PROFILE"}],"TotalRunTime":1200,"Vehicles":[{"Capacity1":1500,"CharacteristicsRequest":"250","CostPerKm":0.1,"CostPerDay":4.8,"Depot":"2|DEPOT","Driver":"250|DRIVER","LegalDrivingDuration":"04:30:00","MaximumLoadUnloadTime":"05:00:00","PossibleDays":"1","SpeedProfile":"1|SPEED_PROFILE","Tag":"250|VEHICLE"}]};

var xmlhttp = new XMLHttpRequest();   // new HttpRequest instance 
xhttp.onreadystatechange = function() {
    if (this.readyState == 4) {
      if (this.status == 200)
        console.log(JSON.stringify(this))
    }
  };

xmlhttp.open("POST", "http://[API_END_POINT]/");
xmlhttp.setRequestHeader("Content-Type", "application/json");
xmlhttp.send(JSON.stringify(data));

The above code return the following JSON structure:

{
    "RequestId": "a429a8e4-ecf9-4089-bdd6-f74fe7ad9808"
}

HTTP Request

POST http://[API_END_POINT]/ DATA

HTTP Response

As a result of sending a request, tm8rmscheduler service returns with a unique request ID.

Part 1 response has the following JSON format:

{
    "RequestId": "a802a998-e3c1-48f9-a8ca-619888f4adf0"
}
Key Value description
RequestId A unique request ID which can be used for polling the result plan from the service.

Key/Value Pairs in the POST DATA

Arguments which are required are marked as mandatory. Optional arguments are provided with their default values. It's recommended that you explicitly set all arguments as default arguments can change.

Key Default value Value Description
ContinueWithoutImprovementTime mandatory The run time of the second part of the algorithm since the last overall improvement was found.
TotalRunTime mandatory Specify the total time in seconds which is allowed for the algorithm to take before it terminates, thus execution time can be up to this value depending on the input problem.
LocationPrecisionMetre 1 This is a positive integer represents the precision vortex would use for input problem's locations. Less precision values mean that more adjacent locations might be considered as same location. Based on the LocationPrecisionMetre value, Vortex is clustering problem's locations into clusters each with maximum size of LocationPrecisionMetre in meters. When Vortex identify a group of geographic locations which can be located in a circle with diameter less than LocationPrecisionMetre value, all these geographic locations are represented by one of the group's locations; usually, the location in the centre is used to represent other group's locations.
EnableIntermediateResults false A boolean flag to determine whether the algorithm is sending intermediate results back during its execution. Intermediate results are returned with HTTP status: Accepted and status code: 202.
PriorRequestID null This can be optionally populated using the requestID of a previous (very similar), or slightly modified request. Consequently, when populated, Vortex would be able to reuse previous distance and time matrices.
CacheMatrices false This is a boolean value to determine whether or not to cache distance and time matrices. It is useful to turn this flag on when current request is likely to be modified in the future and run again; in this scenario, caching matrices on current request would help Vortex to calculate modified future requests' matrices faster.
Depots mandatory Specify a list of depots, for more info please check Depot Key/Value pairs. Note: there should always be at least one depot.
Drivers mandatory Specify a list of drivers, for more info please check Driver Key/Value pairs. Note: a 'driver' in this context will not normally refer to an individual person. Instead, it can be a profile which is inherited by resources. For example, there might be two drivers, one named "EarlyShift" and one named "LateShift", holding the respective operating constraints.
Vehicles mandatory Specify a list of vehicles. For example, if the client has 25 vehicles available today, then there will be 25 vehicles in this array. For more info please refer to Vehicle Key/Value pairs.
Requests Specify a list of job requests, each item has the format specified in Request Key/Value pairs.
SpeedProfile SpeedProfile Key/Value pairs Optionally specify the default speed profile which is used for all vehicles by default. The default values are defined by the SpeedProfile Key/Value pairs.
SpeedProfiles null Specify the list of speed profiles which are used for specific vehicles to override the default SpeedProfile. The speed profiles from this list when linked to vehicles override the default speed profile. For more info please refer to SpeedProfile Key/Value pairs.

Depots Key/Value pairs

The depot represents locations where resources are loaded/exchanged/unloaded and in most instances where vehicles start and end.

    "Depots": [{
        "Tag": "2|DEPOT",
        "OpeningTime": "00:00:00",
        "ClosingTime": "23:59:59",
        "Characteristics": null,
        "Latitude": 51.5319518,
        "Longitude": 0.1078958
      }
    ]
Key Default value Value Description
Tag mandatory A unique ID for the depot.
OpeningTime "00:00:00" A string represents the opening time of the depot in the format HH:mm:ss, e.g. 08:00:00 represents eight o'clock in the morning and 20:00:00 represents eight o'clock in the evening.
ClosingTime "23:59:59" A string represents the closing time of the depot in the format HH:mm:ss, e.g. 08:00:00 represents eight o'clock in the morning and 20:00:00 represents eight o'clock in the evening.
LoadingTime "00:00:00" Loading time (in string format HH:mm:ss) for this depot. This time will be added to other loading times for a resource and a job request. This is a single fixed cost to add when the algorithm loads or unloads a resource (NOT per item loaded/unloaded).
Characteristics null Characteristics which are matched against Tractor object to ensure it can operate from this site. Multiple characteristics need to be separated by a comma.
Latitude mandatory The geographical location latitude value of this depot. The format is degrees and decimal minutes e.g. 51.5319518.
Longitude mandatory The geographical location longitude value of this depot. . The format is degrees and decimal minutes e.g. 0.1078958.

Drivers Key/Value pairs

Drivers contain all the detail on when a driver is available , for how long and at what cost. You can set the system up so it uses a single generic driver, i.e. this is a driver of shift pattern 1 or you can set a profile up specific to a driver i.e. this relates specifically to John Smith.

    "Drivers": [{
      "Tag": "250-DRIVER",
      "BreakDuration": "00:30:00",
      "EarliestBreakTime": "04:00:00",
      "BriefingTime":"00:00:00",
      "DeBriefingTime":"00:00:00",
      "RequestCharacteristics":null,
      "CostPerDay": 131.43,
      "CostPerHour": 16.43,
      "MaximumWorkingTime": "18:00:00",
      "MaximumDrivingDuration": "09:00:00",
      "PossibleDays": "1",
      "ShiftEarlyStart": "06:00:00",
      "ShiftLateStart": "06:30:00"
    }, {
      "Tag": "251-DRIVER",
      "BreakDuration": "00:30:00",
      "EarliestBreakTime": "04:00:00",
      "BriefingTime":"00:00:00",
      "DeBriefingTime":"00:00:00", 
      "RequestCharacteristics":null,
      "CostPerDay": 80,
      "CostPerHour": 10,
      "MaximumWorkingTime": "18:00:00",
      "MaximumDrivingDuration": "09:00:00",
      "PossibleDays": "1",
      "ShiftEarlyStart": "06:00:00",
      "ShiftLateStart": "06:30:00"
    }
  ]
Key Default value Value Description
Tag mandatory A unique ID for the driver. This could be a driver's name, but normally it will indicate a type of driver - e.g. "MorningShift", "SubContractorCompany1", ...
BreakDuration "00:00:00" Drivers normally will often be required to have a break of length BreakDuration during their shift. This is a time interval in the string format HH:mm:ss.
EarliestBreakTime "04:00:00" Drivers must take a break of BreakDuration at the first opportunity after they have worked for at least this amount of time. (Work means driving + briefing + unloading/loading).
BriefingTime "00:00:00" Time interval string with format HH:mm:ss representing the briefing duration at the beginning of driver's shift in seconds.
DeBriefingTime "00:00:00" Time interval string format HH:mm:ss representing the debriefing time needed by the driver at the end of their shift.
RequestCharacteristics null Characteristics that are matched against the request to check this driver can complete this work, this is a comma separated string of skills.
CostPerDay 0 Daily cost of the driver, this is a fixed cost amount added in the days when the driver is hired.
CostPerHour 0 Hourly cost of the driver.
MaximumWorkingTime "11:00:00" Maximum duration of the driver's working shift in string time interval format HH:mm:ss.
MaximumDrivingDuration "10:00:00" Maximum time a driver can drive during their shift in string time interval format HH:mm:ss.
MaximumOvertime "00:00:00" String time interval represents maximum overtime duration (beyond MaximumWorkingTime) which the driver can do in one shift.
OvertimeCostPerHour 0 Hourly cost for overtime.
MaxOvernights 0 The maximum number of overnight stops that the driver can take during this scheduling run. The value zero indicates that overnight settings is turned off for this driver.
SecondManEffect 1.0 The percentage effect on the request duration that having a second man will have e.g. 0.7 a 30%reduction in time. if not second ma set to 1.0.
SecondManFixedCost 0 The increase in cost for have a second man, if no second man is used set to 0.0.
MinOvernightDrivingDistanceKM 0 If a driver is going to stay overnight at a location, this location must be at least MinOvernightDrivingDistanceKM from the driver's end location. The end location comes from the resource that this driver is assigned to; normally it will be the resource's depot, or it could refer to the nearest of the allowed depots.
OvernightCost 0 The cost associated with having to stay out between shifts, typically a hotel night.
PossibleDays "1" The days during the scheduling horizon which this driver is available. Multiple days should be separated by a comma, and the first day is set to a 1. Example: If today is Monday and we set a value of "1,2,4" the plan will be for Tues, Weds and Friday.
ShiftEarlyStart "00:00:00" The earliest time in string format HH:mm:ss for the driver to start their shift.
ShiftLateStart "00:00:00" The latest time in string format HH:mm:ss for the driver to start their shift.

Vehicles Key/Value pairs

Vehicles cover all moveable physical assets, a vehicle is made up of a tractor unit and a trailer. In turn the trailer is made up of one or more compartments.

  "Vehicles": [{
      "Capacity1": 1500,
      "CostPerDay": 4.8,
      "CostPerKm": 0.1,
      "Depot": "2|DEPOT",
      "SpeedProfile": "1|SPEED_PROFILE",
      "Driver": "250|DRIVER",
      "CharacteristicsRequest": "250",
      "LegalDrivingDuration": "04:30:00",
      "MaximumLoadUnloadTime": "05:00:00",
      "EndLatitude": null,
      "EndLongitude": null,
      "PossibleDays": "1",
      "Tag": "250|VEHICLE"
    }, {
      "Capacity1": 1500,
      "CostPerDay": 4.8,
      "CostPerKm": 0.1,
      "Depot": "2|DEPOT",
      "SpeedProfile": "1|SPEED_PROFILE",
      "Driver": "251|DRIVER",
      "CharacteristicsRequest": "251",
      "LegalDrivingDuration": "04:30:00",
      "MaximumLoadUnloadTime": "05:00:00",
      "EndLatitude": null,
      "EndLongitude": null,
      "PossibleDays": "1",
      "Tag": "251|VEHICLE"
    }
  ]
Key Default value Value description
Tag mandatory Unique name for this Vehicle/trailer/tractor within the run of the algorithm.
Driver mandatory The Tag of the driver that is allocated to drive this vehicle/Tractor.
Depot mandatory The Tag of the depot that this vehicle/tractor starts and finishes at.
Compartments null The list of compartments that make up this trailer.
StartLatitude null The start location latitude of the vehicle. If left empty, the vehicle starts from the associated depot. When OpenStart is on the vehicle starts from its first job request.
StartLongitude null The start location longitude of the vehicle. If left empty, the vehicle starts from the associated depot. When OpenStart is on the vehicle starts from its first job request.
EndLatitude null The end location longitude of the vehicle. If left empty, the vehicle finishes at the associated depot. When OpenEnd is on the vehicle finishes at its last job request.
EndLongitude null The end location longitude of the vehicle. If left empty, the vehicle finishes at the associated depot. When OpenEnd is on the vehicle finishes at its last job request.
CostPerKm 0 The cost per KM for running the Vehicle/Tractor.
CostPerDay 0 This is the cost incurred if the vehicle/tractor is used in a given day, even if it is only used for a single minute.
CostPerDayOfNonUse 0 This is the cost incurred if the vehicle/tractor is not used in a given day.
StartTime "00:00:00" The start time of the vehicle in a string format HH:mm:ss.
MaximumWorkingTime 23:59:59 A string time interval with the format HH:mm:ss which represents maximum time that the vehicle can work.
LegalDrivingDuration "04:30:00" Sets the legal maximum driving time allowed before a breaks must be taken.
LegalRestDuration "00:30:00" Sets the legal break required once the maximum driving time allowed before a breaks must be taken.
MinRestDuration "00:15:00" Sets the minimum length of time that a legal break can be so that waiting times lunch breaks can be included a breaks from driving.
PossibleDays "1" The days during the scheduling horizon which this Vehicle/tractor/trailer is available. Multiple days should be separated by a comma, and the first day is set a 1.
CharacteristicsRequest null Characteristics that need to be matched against the request characteristics to detect suitability for vehicle/Tractor/Trailer. This is a comma separated string, e.g. CAT1,CAT2.
HandlingTimePerUnit 00:00:00 This is used in conjunction with request service times and depot loading times.
UnloadAfterShift false indicates whether the unloading is done outside of the drivers working time.
PreLoad false indicates whether the loading is done outside of the drivers working time.
DepotLoadingTime 00:00:00 Set a fixed depot loading time for this vehicle, this is a time interval using the string format HH:mm:ss.
CarryingWeight null The maximum carrying weight over all the compartments in the trailer.
Backhaul false Indicates whether the vehicle/trailer needs to be empty of deliveries before any collections can be made.
SuppressDepotReload false Set to true it means the vehicle can not complete a depot reload during the shift.
MaximumLoadUnloadTime "10:00:00" The upper limit to depot time the time at depot is the minimum of this and the fixed loading/unloading times with the variable ones as well.
OpenStart false true or false to define whether the vehicle can start from the location of first job it is servicing.
OpenEnd false true or false to define whether the vehicle can finish at the location of the last job it is servicing.
Capacity1 0 Specify a capacity value for the vehicle, this can be width, weight, volume, etc.
Capacity2 0 Specify a capacity value for the vehicle, this can be weight, volume, etc.
Capacity3 0 Specify a capacity value for the vehicle, this can be weight, volume, etc.
Capacity4 0 Specify a capacity value for the vehicle, this can be weight, volume, etc.
SpeedProfile null Defines a speed profile associated with this vehicle, if not specified the default speed profile is used.

Compartments Key/Value pairs

The compartment is simply a separate section within the trailer, one open trailer simply has one compartment. A fuel distribution truck could have many different compartments. There is no limit to the number of compartments; it depends on the vehicle. Each compartment has capacity dimensions and the number of dimensions used is definable.

For example we may choose to map maximum (width 3.4m, length 15m, height 4.5m, weight 5000 kg) onto capacity1, capacity2, capacity3 and capacity4 respectively. Capacity1 being width, Capacity2 being length and so on.

    "Compartments": [{
        "Capacity1": 3.4,
        "Capacity2": 15,
        "Capacity3": 4.5,
        "Capacity4": 5000                
      }]

Equally we may simply map Capacity1 to volume (litres) and not use the other dimensions; this would be ideal for liquids such as fuels. This is an example of how to specify two compartments with 1000 litres of volume:

    "Compartments": [{
        "Capacity1": 1000
      }, {
        "Capacity1": 1000
      }
    ]

All constraints for each compartment will need to be satisfied. So for example if we map (width, length, height, weight) to capacity1..4, the requested (parcel) must satisy each capacity dimension to fit on the truck.

Key Default value Value Description
Capacity1 0 The capacity is used a limiting factor of Quantity1 in requests, e.g. 1000. If we have defined Compartments we must have at least 1 capacity defined.
Capacity2 0 The capacity is used a limiting factor of Quantity2 in requests, e.g. 1000.
Capacity3 0 The capacity is used a limiting factor of Quantity3 in requests, e.g. 1000.
Capacity4 0 The capacity is used a limiting factor of Quantity4 in requests, e.g. 1000.
PhohibitedType null This Request.StockType can not be placed in this compartment, e.g. "DIESEL".

Requests Key/Value pairs

In order to complete a plan a list of requests need to be added to the scheduler. There are many options that can be used within the process trying to replicate most of the scenarios where this could be required.

    "Requests": [{
        "Service": 1,
        "Longitude": 0.3166651,
        "Latitude": 51.6003284,
        "FixedVisitDuration": "00:04:00",
        "Tag": "268887-ORDER",
        "Quantity1": 49.38,
        "TimeWindows": "06:00:00,18:00:00",
        "PossibleVisitDays": "1",
        "TractorCharacteristics": "260",
        "AdditionalTag": "1,260659179_CM133RZ_THORNDONCOUNTRYPARK,1,,0",
        "RevenueIncome": 1000
      }, {
        "Service": 1,
        "Longitude": 0.2998903,
        "Latitude": 51.615578,
        "FixedVisitDuration": "00:04:00",
        "Tag": "269874-ORDER",
        "Quantity1": 3.3,
        "TimeWindows": "06:00:00,18:00:00",
        "PossibleVisitDays": "1",
        "TractorCharacteristics": "260",
        "AdditionalTag": "1,260805221_CM144LX_KINGSHOUSE,1,,0",
        "RevenueIncome": 1000
      }
    ]
Key Default value Value description
Tag mandatory The Unique reference for this item (unique amongst Depot, Request, Driver, Vehicle, Tractor and Trailer objects).
AdditionalTag null It has the following format {1/0},<TAG_ID>,<SEQ_NO>,<VEH_TAG>,{1/0}, where <TAG_ID> is a unique string which can be used to tag two or more job requests together, <SEQ_NO> is an integer represents the run order for these jobs requests, and <VEH_TAG> is preserved to specify the carrying vehicle (This is not implemeted yet, please leave it empty). Thus, AdditionalTag does many things: 1. links collections and deliveries together, 2. sequences a complete days work on the same vehicle, 3. links work to a specific vehicle e.g. #1,TEXT1,#2,TEXT2,#3 #1 (0,1) 0=other orders can be placed in between the linked ones 1=cannot. TEXT1= the linking text all orders with the same text are linked #2 (0, n) = sequences orders must be visited in. TEXT2 = this is not implemented yet and must be empty, this is preserved for future to specify vehicle Tag that must service the request, empty string means any vehicle can do the request. #3(0, 1) 0 = not the same product (collection and delivery order doesn't matter), 1 = same product (collection then delivery)
Latitude mandatory The Latitude of the job request location.
Longitude mandatory The Longitude of the job request location.
TractorCharacteristics null Characteristics which are matched against Tractor object to ensure it can service this request. Multiple characteristics need to be separated by a comma.
TrailerCharacteristics null Characteristics which are matched against Trailer object to ensure it can service this request. Multiple characteristics need to be separated by a comma.
DriverCharacteristics null Characteristics which are matched against Driver object to ensure it can service this request. Multiple characteristics need to be separated by a comma.
DepotCharacteristics null Characteristics which are matched against Depot object to ensure they can service this request. Multiple characteristics need to be separated by a comma.
MatchAllTractor false Set true to indicate that all characteristics of the request need to be matched by the tractor.
MatchAllTrailer false Set true to indicate that all characteristics of the request need to be matched by the trailer.
MatchAllDriver false Set true to indicate that all characteristics of the request need to be matched by the driver.
MatchAllDepot false Set true to indicate that all characteristics of the request need to be matched by the depot.
ProhibitedStock null Any products of type A cannot be planned on the same trip as this order.
Quantity1 0 A quantity that is measured against the Capacity1 of the vehicle.
Quantity2 0 A quantity that is measured against the Capacity2 of the vehicle.
Quantity3 0 A quantity that is measured against the Capacity3 of the vehicle.
Quantity4 0 A quantity that is measured against the Capacity4 of the vehicle.
FixedVisitDuration 00:00:00 This indicates how long the vehicle will remain on site at the request location, can be used alone or in conjunction with the loading time per unit, meaning you can have a paper work time and a physical loading time. Expected in the form of "hh:mm:ss" e.g. "00:05:00".
UnitQuantity 20 The amount of quantity used in conjunction with LoadTimePerUnit.
LoadTimePerUnit 00:00:00 Average amount of time required at the location to complete all or part f the service, used in conjunction with fixed visit duration.
PossibleVisitDays mandatory The days during the scheduling horizon which this request can be serviced on, if left as null all days are acceptable. Multiple days should be separated by a comma, and the first day is set a 1. e.g. "1,2,3".
RevenueIncome 0 A cost implication to not completing this request.
Service 0 indicates whether as request is a collection or a delivery. 0 means Collection, 1 is Delivery and 2 is visit.
TransportSeparately false This indicates with the stock for this request needs to travel in its own compartment in the trailer.
StockType null A type of product used for determining which compartments can do what.
TimeWindows null The time windows available on every day for this request to be serviced. Expected in the form 08:00,12:00,13:00,17:00 would represent two windows 8am-12pm and 1pm-5pm.
CanSplitOverCompartment false The goods do not need to transported in the same compartment and can be split over compartments in order to ensure good trailer utilisation. It indicates that this order is made up of small objects which can be spread over different compartments on the same trailer.
Weight 0 the weight of the order to determine that the carrying wait of the trailer is not broken.

Speed Profiles Key/Value pairs

The speed profile is used to apply various speeds to resources, each resource can have multiple speed profiles for different times of the day. This method applies a generic cross fleet speed profile.

There is a default speed profile - although this is likely to be faster than most fleets would require.

  "SpeedProfiles": [{
      "Catergory1KPH": 80,
      "Catergory2KPH": 56,
      "Catergory3KPH": 48,
      "Catergory4KPH": 45,
      "Catergory5KPH": 35,
      "Catergory6KPH": 29,
      "Catergory7KPH": 10,
      "Tag": "1|SPEED_PROFILE"
    }
  ]
Key Default value Value description
Tag The speed profile ID, this can be used to assign a customised speed profile for a vehicle.
Catergory1KPH 120 This property allows the value to be get or set for the speed in KMH, for the fastest type of roads. If a value less than 0 or greater than 200 is used it will not be accepted.
Catergory2KPH 95 This property allows the value to be get or set for the speed in KMH, for the next fastest type of roads2. If a value less than 0 or greater than 200 is used it will not be accepted.
Catergory3KPH 80 This property allows the value to be get or set for the speed in KMH, for the next fastest type of roads. If a value less than 0 or greater than 200 is used it will not be accepted.
Catergory4KPH 60 This property allows the value to be get or set for the speed in KMH, for the next fastest type of roads. If a value less than 0 or greater than 200 is used it will not be accepted.
Catergory5KPH 40 This property allows the value to be get or set for the speed in KMH, for the next fastest type of roads. If a value less than 0 or greater than 200 is used it will not be accepted.
Catergory6KPH 20 This property allows the value to be get or set for the speed in KMH, for the next fastest type of roads. If a value less than 0 or greater than 200 is used it will not be accepted.
Catergory7KPH 8 This property allows the value to be get or set for the speed in KMH, for the slowest type of roads. If a value less than 0 or greater than 200 is used it will not be accepted.

Part 2: Polling for Result

Given a request ID the end user need to keep polling the service until the result plan is computed. Depending on the size of the problem this might take hours.

HTTP Request

GET http://[API_END_POINT]/<RequestId>

URL Parameters

Parameter Description
RequestId The ID of request which is sent earlier. This is the tm8rmscheduler service response to the input request in part 1.
import requests
r = requests.get("http://[API_END_POINT]/a802a998-e3c1-48f9-a8ca-619888f4adf0")

if r.status_code == 200:
  print(r.text)

 curl "http://[API_END_POINT]/a802a998-e3c1-48f9-a8ca-619888f4adf0"
var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4) {
      if (this.status == 200)
        console.log(JSON.stringify(this));
    }
  };
  xhttp.open("GET", "http://[API_END_POINT]/a802a998-e3c1-48f9-a8ca-619888f4adf0", true);
  xhttp.send();

The response from the server is empty string if the result is not ready yet, and a full plan when the result is ready:

{
  "Cost": 154.75249428200416,
  "Miles": 36.112359750100978,
  "RequestId": "a802a998-e3c1-48f9-a8ca-619888f4adf0",
  "UnPlanned": 0,
  "UnplannedRequests": [],
  "Data": [
    {
      "Day": 1,
      "Duration": 0.0,
      "Eta": 360.0,
      "Miles": 0.0,
      "RunNo": "0",
      "RunOrder": 0,
      "Tag": null,
      "Task": "TSKSHIFTSTART",
      "Vehicle": "250|VEHICLE"
    },
    {
      "Day": 1,
      "Duration": 0.0,
      "Eta": 360.0,
      "Miles": 0.0,
      "RunNo": "0",
      "RunOrder": 1,
      "Tag": "2|DEPOT",
      "Task": "TSKBRIEFING",
      "Vehicle": "250|VEHICLE"
    },
    {
      "Day": 1,
      "Duration": 22.370801254603453,
      "Eta": 360.0,
      "Miles": 18.587216473612767,
      "RunNo": "0",
      "RunOrder": 2,
      "Tag": null,
      "Task": "TSKTRAVEL",
      "Vehicle": "250|VEHICLE"
    },
    {
      "Day": 1,
      "Duration": 4.0,
      "Eta": 382.37080125460346,
      "Miles": 18.587216473612767,
      "RunNo": "0",
      "RunOrder": 3,
      "Tag": "268887|ORDER",
      "Task": "TSKDELIVERY",
      "Vehicle": "250|VEHICLE"
    },
    {
      "Day": 1,
      "Duration": 20.0471174513327,
      "Eta": 386.37080125460346,
      "Miles": 17.525143276488208,
      "RunNo": "0",
      "RunOrder": 4,
      "Tag": null,
      "Task": "TSKTRAVEL",
      "Vehicle": "250|VEHICLE"
    },
    {
      "Day": 1,
      "Duration": 0.0,
      "Eta": 406.41791870593619,
      "Miles": 36.112359750100978,
      "RunNo": "0",
      "RunOrder": 5,
      "Tag": "2|DEPOT",
      "Task": "TSKDEBRIEFING",
      "Vehicle": "250|VEHICLE"
    },
    {
      "Day": 1,
      "Duration": 0.0,
      "Eta": 406.41791870593619,
      "Miles": 36.112359750100978,
      "RunNo": "0",
      "RunOrder": 6,
      "Tag": null,
      "Task": "TSKSHIFTEND",
      "Vehicle": "250|VEHICLE"
    }
  ]
}

V1 JSON Response

URL Parameters

The server shall response with empty string message if the plan result is not ready yet.

HTTP Response Key/Value pairs:

Key Value description
Cost The total cost of the plan.
Miles The total mileage of the plan.
RequestId The request ID generated when the input is posted to the server.
UnPlanned Total number of unplanned job requests
UnplannedRequests List of unplanned job requests Tags.
Data This is a list of items represents the actual itineraries of the plan. Please refer to Data Key/Value pairs for more info.

Data Key/Value pairs

Key Value description
Day The day of the action
Duration the duration of the action in minutes
Eta The expected time of the arrival of the action, this is represented as total number of minutes passed since the midnight of the Day.
Miles Accumulative mileage when this action takes place.
RunNo The number of itinerary, this is an integer representing the actual itineraries
RunOrder The order of the action inside the itinerary, this represents the order which itinerary actions should take place by.
Tag The ID of the object involved in the action. This can be a depot when action is Briefing or Loading and a job request Tag ID when the action is Collection or Delievery for example.
Task The action type which can be one of the following: TSKTRAVEL, TSKSERVICE, TSKDELIVERY, TSKCOLLECTION, TSKBRIEFING, TSKDEBRIEFING, TSKLUNCH, TSKDRIVINGBREAK, TSKDEPOTLOAD, TSKWAITING, TSKNIGHTOUTSTOP, TSKNIGHTOUTSTART, TSKSHIFTSTART, TSKSHIFTEND.
Vehicle Represents the vehicle which is doing the itinerary.