Swarm Logistics PlanSim

REST API Examples
Version 1.1.4

 1        General notes

·         The examples apply to the Plansim API version 1.3.3.

·         In the following all routes are build specifying these placeholder tokens:

  servername gets replaced by some IP address or a domain like e. g. 23.88.111.210 or dev.swarmlogistics.org

  port gets replaced by some port value like e. g. 8091

  apiprefix gets replaced by some individual path like e. g. AutoDispatcher or AutoDispatcher/v1.3.0

·        This means that a generic URL like https://{servername}:{port}/{apiprefix}/ in practice must be something like e. g. https://dev.swarmlogistics.org:8091/AutoDispatcher/v1.3/

·        All body data is expected to be send as JSON, i. e. with the request header:
      Content-Type: “application/json”

·        Examples for error states are not given here. Generally error states get detected by the individual HTTP return codes.

·        When supplying coordinate values in data ensure that you do not mix up the longitude and latitude values. E. g. for geocoordinates in Germany the correctness can easily be asserted by checking that the latitude value is roughly between 47.5 and 54.7, and the longitude value is roughly between 6 and 14. If you are unsure you could check here: https://www.latlong.net/


 

 2        Authentication

Any call to the Plansim API needs to provide a valid bearer token. Such a token can get acquired by sending username / password credentials to the REST service.

Bearer tokens expire after some fixed time (e. g. after one hour). The expiry time is defined by the backend and cannot be changed by the client. If a token expired any request fails with a HTTP 401 error and body data like e. g.:
{
            "timestamp":"2022-03-09T14:02:22.237+00:00",
            "status":401,
            "error":"Unauthorized",
            "message":"Unauthorized",
            "path":"/AutoDispatcher/v1.3/address"
}

In the case of an expired token the client must resend the credentials as explained above to acquire a fresh valid bearer token.

 3        Creation of an address


 

 4        Creation of a transport

Any transport must consist of at least a driver id and a vehicle id. An id of a trailer can be supplied optionally. Therefore before a transport entry can be created entries for a driver and vehicle must be created – or preexist.

 4.1   Create a truck

A truck needs to have a home depot address as this location always gets used as starting point for route calculations. Therefore an address entry must be created first.

 4.1.1                First create a home depot address entry

Analogous to 3. Creation of an address

 4.1.2                Then create the truck entry itself

 4.2   Create a driver

Since a driver entry does not depend on other resources it can get created right away.

                        "id": "3gfil5hffg36mh7iflhjkhnoh5ojom47f34jgkkv5",

                        "description": "Driver A",

                        "pauseDurationMinutes": 60,

                        "pauseAfterWorkedMinutes": 240,

                        "workDurationMaxMinutes": 480,

                        "costsPerHour": 12.0

            }

Note that the value in “workDurationMaxMinutes” limits any possible tour to a duration defined by this value. E. g. if the value is 480 then this means that the driver is allowed to drive 8 hours at maximum (= 60 minutes x 8 = 480 minutes). If during the calculation of a tour a stop of a freight order would require the driver to exceed that maximum working time then that stop gets rejected - which results in the freight order to be rejected by the transport to which the driver belongs.
Thus obviously setting the maximum work duration to 0 will result in the transport rejecting any freight order because the driver is configured to not be allowed to work at all.

 4.3   Create the transport itself

The transport entry contains the IDs of the entries created before.

 5        Creation of a freight order entry

Similar to the truck resource a freight order entry depends on two entries of the address resource that get used as pickup address and delivery address. Therefore these entries must get create first before creating a freight order entry.

 5.1   Create a pickup address entry

Analogous to 3. Creation of an address

 5.2   Create a delivery address entry

Analogous to 3. Creation of an address

 5.3   Create a freight order entry

                        "id": "6pfm86g3njgffg76kj3j4m6nfngo583i5kfln866p",

                        "customId": "Grandpa's finest tomato soil",

                        "weight": 5.0,

                        "space": 0.25,

                        "idAddressPickup": "nshnjo8iijo86jkkjiln3il3jjolimjoffgfhihka",

                        "idAddressDelivery": "nshnlkm3h7o5klfjj7n338hl7i65g344ffg7n34ka",

                        "twPickup": [ 840, 1080 ],

                        "twDelivery": [ 960, 1200 ],

                        "handlingDurationPickup": 15,

                        "handlingDurationDelivery": 10

            }

 

 


 

 6        Creation of a task entry

A task is a blueprint of a scheduling problem to be solved by the Plansim / AutoDispatcher cloud system. It consists of (1) a set of freight orders which define freight to be transported or services that need to get performed at certain locations, (2) a set of transports that can carry out the given freight orders, an optional description and a value for “empirical stops per transport” which should default to zero if it is unknown.

                        "id": "uvfmf7ojk8gffg8nmokjhio3g368igoi3k7inlfn0",

                        "description": "Task A",

                        "transports": [

                                    "ufhjkjim3g4mh6lmjhfk3hg58nklffg8flk5hhmlu",

                                    "8mflgkk38gffghj3i75j8hg4h6mm7lg8n7kh8fmfb"

                        ],

                        "fos": [

                                    "hfggmil364jgk36ffgnjigk485nki6k67k7nli7wl",

                                    "lyggmn3i3fj5ihiffgkjhgk3ngn7mfn5gg585j8gb"

                        ],
                        “timeBegin” : 485,

                        "empStopsPerTransport": 2

            }


 

 7        Starting a calculation and polling its status

After a task is created a process can be started that tries to solve it. A POST to the calculation resource starts the calculation process.

                        "id": "6cfml3hl73kffgnm488j46nn4kgjkklnn773gi4fu",

                        "idTask": "uvfmf7ojk8gffg8nmokjhio3g368igoi3k7inlfn0",

                        "state": "RUNNING",

                        "idResult": ""

            }

Since the calculation is “long running” – maybe several seconds to even minutes – the client must poll its completion status. Sensible polling intervals can e. g. be every 30 seconds. Such queries are executed by GET requests to the calculation resource.

Or of the calculation got completed then the state will be “FINISHED” like e. g. this: {
            "id": "ymfl8m78mgffgmg48i3j4mi4486l8gnmfj7f84lkt",
            "idTask": "39hfi77k6ho6ggnfjg6f3jklffgih7jlm4jl7i6cz",
            "state": "FINISHED",
            "idResult": "7dgkfh5j3m5g863kji3ffg54fn38nol6oml7jk4r5"
}

 8        Fetching of a result entry

 8.1   Example of a successful result entry

For calculations that successfully completed – state “FINISHED” – the status contains the id of a result entry.

where “id” here must be the id of the result instance to be queried. The body must be empty.

 8.2   Example of a result containing unserviced freight orders

{
            "id": "u5fnfmgfmo4offgim6njigo4i47j43ooo76mf8on6",
            "idTask": "1lhlijmioig3fh53jn8jnhkm3hgn85ffg564holt4",
            "quality": 0.0,
            "schedules": [
                        {"idTransport": "qihh5i8kfm8khj6njg3f3j3og6ffg75mgf863lhdw",
                        "costsDistance": 0.0, "costsDuration": 0.0, "costsTotal": 0.0, ”totalDistance”: 0.0,
                        ”totalDuration”: 0.0, "timeStart": 0, "timeEnd": 0, "nodes": [{
                        "id": "fcffffgn5gfk7n45jo7jgijn434g4j45nm756lhgu", "idFo": "", "weightBefore":                     0.0, "weightAfter": 0.0, "spaceBefore": 0.0, "spaceAfter": 0.0,
                        "timeElapsedArrival": 0, "timeBeginService": 0, "timeElapsedDeparture": 0,
                        "distDetour": 0.0, "durationDetour": 0.0, "timePauseBegin": -1, "timePauseEnd":
                        -1, "pausePosition": 0, "distance": 0.0, "duration": 0.0, "ascend": 0.0, "descend":                0.0, "path": null, "instructions": null, "toll": null, "pickup": false },
                        { "id": "zwffffg38kof8jmhhg6jgm33imgkjg353jl73j8ps", "idFo": "", "weightBefore":                0.0, "weightAfter": 0.0, "spaceBefore": 0.0, "spaceAfter": 0.0,
                        "timeElapsedArrival": 0, "timeBeginService": 0, "timeElapsedDeparture": 0,                         "distDetour": 0.0, "durationDetour": 0.0, "timePauseBegin": -1, "timePauseEnd":                -1, "pausePosition": 0, "distance": 0.0, "duration": 0.0, "ascend": 0.0, "descend":                      0.0, "path": null, "instructions": null, "toll": null, "pickup": false }]}
            ],
            "unservicedFOs": ["ckfg7ffg3lj437kgnkojlj5n475gmg3588ljo8mct"]
}

Note that in this example there is a single transport (with id = qihh5i8kfm8khj6njg3f3j3og6ffg75mgf863lhdw) that rejected the only freight order (with id = ckfg7ffg3lj437kgnkojlj5n475gmg3588ljo8mct) specified in the task (with id = 1lhlijmioig3fh53jn8jnhkm3hgn85ffg564holt4). Thus the schedule is empty which means that it only consists of a start node (with id =  fcffffgn5gfk7n45jo7jgijn434g4j45nm756lhgu) and an end node (with id = zwffffg38kof8jmhhg6jgm33imgkjg353jl73j8ps).

In general the sequence of nodes in schedules can be determined by ordering them by the values of “timeElapsedArrival”. In the case of an empty schedule as shown above the start and end nodes are given “pro forma” and thus have the same value for the arrival time.

 9        Full example using the CSV import

In the following assume that the server name / port / apiprefix are this: https://dev.swarmlogistics.org:8091/AutoDispatcher/v1.3

 9.1   Import the freight orders

In the annex in 10.2 the CSV data is given that needs to be stored as a text file (here stored as ‘/home/someuser/SwarmLogistics/Data/FOs.csv’) which shall be send as a request.

 9.2   Import the Transports

In the annex in 10.3 the CSV data is given that needs to be stored as a text file (here stored as ‘/home/someuser/SwarmLogistics/Data/Transports.csv’) which shall be send as a request.

 9.3   Define the task

Assuming the freight orders imported in 9.1 were given the following ids.

Line id

Imported id

1

l9fh3lffgn55ll4g55hjojmn6g33gk8fj8kmkhog7

2

rkgn8j78h5h8ffo4j4kmn4ffgfj8m4m7h54n84fvw

3

4ahgkfif6453fj7mjmignj58kffgnojnmm44fl71a

4

apflflifnjffgjho5ijjomh4875jhog3o855477kh

5

86fjflmkffgfoln55g3jk5koi5364mh6ogoofjf6x

6

bofj8io4ffg8i5g7o7hj43injf5kgj7il4higl8gl

7

hofnm6i3ko8mffg4m33jkjnn453fmknnnlohoomsn

8

ffgnnglmkllffggijg5745ffgmk67o4o6jig4nf1w

9

h8gfoj4j835646ffg3ij87nnfnhj77khf75j4g763

 

And assuming the transports imported in 9.2 were given the following ids.

Line id

Imported id

1

n8fk3n4giffgnl564kkj655noj7oo7j37j68io3fc

2

uhhih77j3o47fkkhjo6f436oojoffgin5jiin5jwv

 

Then the following task can be created.

 9.4   Create a calculation

Assuming that the task created in 9.3 gets assigned the id tygljnl568o3465lj3l5ffgno3khhlkjlif5ojhx0

Then a calculation can be created which tries to generate a result consisting of transport schedules that carry the defined freights from the defined pickup locations to the defined
delivery locations.

                        "id": "orhn3kjnm7ii46ofjl77ohkkn4ng4k78ffgo345mm",

                        "idTask": "uvfmf7ojk8gffg8nmokjhio3g368igoi3k7inlfn0",

                        "state": "RUNNING",

                        "idResult": ""

            }

 9.5   Query the calculation state

In order to find out the end of the calculation started in 9.4 a GET request must be send.

 9.6   Query the result

The final step consists of requesting the calculated result.

The body must be empty, but the following request header has to be set to receive JSON data back: “Accept: application/json”

 10    Annex

 10.1                Version history

1.0.0 – initial version, examples for creation of entries for address, transport (incl. truck and driver entries) and freight order resources

1.1.0 – extended by examples for these resources: task, calculation

1.1.1 – extended by examples for these resources: result

1.1.2 – add how to fetch result in PDF format + fixed wrong coordinates in example for address creation

1.1.3 – add general comment on geocoordinates and notes comment for driver max work duration; add example of a result containing unserviced freightorders (8.2); add another full example using the CSV import (9, 10.2 and 10.3)

1.1.4 – added new parameters for API version 1.3.5; in detail “Task” → “timeBegin” (see e. g.   6) and for “Schedule” →”totalDistance”, “totalDuration” (see e.g. 9.6)

 10.2                CSV import freight order data

1,"A – Tour-de-City","A-Pickup","Germany",82110,"Germering","Tristanstraße",12,"A-Delivery","Germany",81379,"München","Seehauser Str.",12,1,1

2,"B – Tour-de-City","B-Pickup","Germany",81249,"München","Henschelstraße",15,"B-Delivery","Germany",82152,"Krailing","Margaretenstraße",25,1,1

3,"C – Tour-de-City","C-Pickup","Germany",85764,"Oberschleißheim","Effnerstraße",18,"C-Delivery","Germany",81243,"München","Stockacher Str.",5,1,1

4,"D – Tour-de-City","D-Pickup","Germany",85748,"Garching","Freisinger Landstraße",4,"D-Delivery","Germany",80993,"München","Hanauer Str.",75,1,1

5,"E – Tour-de-City","E-Pickup","Germany",85622,"Feldkirchen","Sonnenstraße",2,"E-Delivery","Germany",80939,"München","Lilienthalallee",35,1,1

6,"F – Tour-de-City","F-Pickup","Germany",85521,"Ottobrunn","Pommernstraße",89,"F-Delivery","Germany",81925,"München","Vollmannstraße","25D",1,1

7,"G – Tour-de-City","G-Pickup","Germany",81547,"München","Rotbuchenstraße",26,"G-Delivery","Germany",81825,"München","Solalindenstraße",50,1,1

8,"H – Tour-de-City","H-Pickup","Germany",82061,"Neuried","Planegger Str.",1,"H-Delivery","Germany",81539,"München","Perlacher Str.","122C",1,1

9,"I – Tour-de-City","I-Pickup","Germany",82166,"Gräfeling","Merowingerstraße",18,"I-Delivery","Germany",80638,"München","Menzinger Str.",37,1,1

 10.3                CSV import transport data

1,"Munich Express A","Germany",81543,"München","Tierparkstraße",14,"Germany",81543,"München","Alemannenstraße",8,25,35,"0.83","0.15",0,"18.5",240,60

2,"Munich Express B","Germany",82194,"Gröbenzell","Grasweg",2,"Germany",82194,"Gröbenzell","Eschenrieder Str.",22,25,35,"0.8","0.16",0,"18.5",240,60