NAV
javascript php

Introduction

Welcome to the adiutaByte API. The goal of the API is to provide an interface for generating plans for various fleet optimization problems. This API description is intended to help setting up your own code to access the adiutaByte API. Currently there are two API endpoints implemented. The first one is for submitting a problem description, for which an optimized plan is then calculated. The second endpoint is for retrieving this finalized plan.

The API uses token-based authentication to protect these endpoints; users are generated on demand. Feel free to contact us for such a personalized access.

The furthest right column of this page will provide examples to data structures, requests or responses. Additionally there will be a few code snippets for some languages. With the tabs in the upper right corner you can switch the example's programming language.

Currently the API solely supports JSON formatted data. For the JSON structures there is a schema that is used to validate the data. Non-valid requests are immediately rejected with an error message. The structure and meaning of the JSON data used is shown in the first part of the following description. In each section a downloadable corresponding JSON schema in the latest version is linked.

For the different requests you need to insert some entries in the header:

Currently we distinguish between users whose limits for how many tasks can be planned within a month are managed by us, and accounts which are used for clients, to which a special management account exists to register new clients. For such an account the limits are set per client. The account for submitting plans and the account for management use the same e-mail-address but need to identify against different cognitio pools. The configuration for the different account types can be found in Authentication. To identify the different clients you need to relay the client-ID to the backend in every request.

Features that are a Work In Progress or To Be Announced are marked WIP or TBA. The former signals beta features that may work but are subject to frequent and unannounced change. The latter signals features that are going to be implemented in a future update but do not work yet and may invalidate any submitted plan. Given examples will always exclude WIP or TBA features.

Definition of common types

GeoCoord

The GeoCoord JSON-body looks like this:

{
  "lat": 50.780241,
  "lng" : 7.184535
}

JSON-Schema

Parameter Type Required Domain Description
lat number $-90 \leq x \leq 90$ The latitude of the coordinate
lng number $-180 \leq x \leq 180$ The longitude of the coordinate

Date

Examples for valid date strings are :

"2018-01-10"
"2019-12-03"
"2020-05-23"

JSON-Schema

A string consisting of three parts following the pattern "YYYY-MM-DD":

Time

A string of either format "hh:mm" or "-hh:mm":

All times are interpreted in 24-hour notation and relative to midnight ("00:00") of a certain defined date. Those dates are:

This means that the following times applied to the respective date (in Date format) are equivalent:

Input data containing only identical dates and no time of format "-hh:mm" will not result in output data containing times of format "-hh:mm".

VehicleType

An integer in the range $0 \leq x \leq 4$.

VehicleTypeID Description
0 Car
1 Bicycle
2 Pedestrian
3 Truck
4 Public Transport Approximation

GenderType

An integer in the range $0 \leq x \leq 3$.

GenderTypeID Description
0 Not provided
1 Male
2 Female
3 Other

LanguageType

An integer in the range $0 \leq x \leq 1$.

LanguageTypeID Description
0 German
1 English

Parameter Preset

An integer in the range $0 \leq x \leq 4$. Depending on the type of plan (MixedPlanner/ ShiftPlanner) not all presets are valid for use. For more information please refer to the respective preset specification.

Preset ID Description
0 Eco orientied
1 Worker oriented
2 Customer oriented
3 Fleet oriented
4 Random

Location Site

The Location Site JSON-body looks like this:

{
  "locationSiteID": 200,
  "location": {
    "lat": 50.878847,
    "lng": 6.964728400000013
  }
}

JSON-Schema

A location site is a geocoordinate which can be referenced on various places:

Parameter Type Required Description
locationSiteID integer The unique id of the location site
location GeoCoord The geocoordinates of the location site

Shift

WIP

The minimum required shift JSON-body looks like this:

{
  "shiftDate": "2019-12-03",
  "shiftStart": "05:00",
  "shiftEnd": "12:00"
}

The full shift JSON-body looks like this:

{
  "shiftDate": "2019-12-03",
  "shiftStart": "05:00",
  "shiftEnd": "12:00",
  "shiftPriority": 2,
  "initassignedTask": 12
}

JSON-Schema (TODO)

A shift represents a worker's timeslot in which exactly one ShiftPlanner-Task can be carried out.

Parameter Required Type Description
shiftDate string (date) The date this timeslot is available on.
shiftStart string (time) The time this timeslot starts.
shiftEnd string (time) The time this timeslot ends.
shiftPriority integer The priority to keep the defined shift start/end times ranging from 0-3: irrelevant, neutral, important, very important. (Default: 1)
initassignedTask integer The taskID of a Task that will be assigned to this Shift in a first optimization step. This will increase the likelyhood that the task will also be assigned to this Shift in the final plan.

Construction Site

The Construction Site JSON-body looks like this:

{
  "constructionSiteID": 666,
  "startDate": "2020-07-23",
  "endDate": "2020-07-25",
  "startPoint": {
    "lat": 48.17083,
    "lng": 11.3292
  },
  "endPoint": {
    "lat": 48.16774,
    "lng": 11.33253
  },
  "info": "Waldstraße gesperrt 2020"
}

JSON-Schema

A construction site gets represented by a straight line between its startPoint and endPoint. These can be identical for small scale obstructions.

Parameter Required Type Description
constructionSiteID integer The unique ID of this construction site.
startPoint GeoCord Start point of the construction site.
endPoint GeoCoord End point of the construction site.
startDate string (date) The first day of construction work at this site.
endDate string (date) The last day of construction work at this site.
info string Misc. information.

Clientinformation

The client information JSON-body looks like this:

{
  "clientID": "{1234-5678-9123}"
}
Parameter Type Required Description
clientID string Identifies a specific client.

Obstacle

The minimum required obstacle looks like this:

{
  "type": "polyline",
  "factor": 2.5,
  "points": [
    {
      "lat": 51.46149994737996,
      "lng": 7.850463381293338
    },
    {
      "lat": 51.66914967977792,
      "lng": 9.753747625087499
    },
    ...
  ]
}

The full obstacle looks like this:

{
  "type": "polyline",
  "factor": 2.5,
  "description": "This is a line",
  "points": [
    {
      "lat": 51.46149994737996,
      "lng": 7.850463381293338
    },
    {
      "lat": 51.66914967977792,
      "lng": 9.753747625087499
    },
    ...
  ]
}

JSON-Schema

An obstacle represents a permanent traffic hindrance that increases travel times.

Parameter Type Required Description
type string Determines the type of obstacle. Currently available options are:
  • polygon - An area based obstacle
  • polyline - A line based obstacle
factor number The modifier to travel times through the obstacle. Can roughly be treated as an amplification factor on base travel time when driving short distances, but behaviour changes based on a multitude of other influences.
points Array<GeoCoord> The ordered set of coordinates that define the obstacle. For more information, see below.
description string A textual description of the obstacle.

Based on obstacle type, the shape of the obstacle is defined as follows:

Examples for obstacles

{
  "type": "polygon",
  "factor": 2.5,
  "description": "This is a square obstacle",
  "points": [
    {
      "lat": 0.0,
      "lng": 0.0
    },
    {
      "lat": 1.0,
      "lng": 0.0
    },
    {
      "lat": 1.0,
      "lng": 1.0
    },
    {
      "lat": 0.0,
      "lng": 1.0
    }
  ]
},
{
  "type": "polyline",
  "factor": 2.5,
  "description": "This is a W",
  "points": [
    {
      "lat": 0.0,
      "lng": 1.0
    },
    {
      "lat": 0.5,
      "lng": 0.0
    },
    {
      "lat": 1.0,
      "lng": 0.5
    },
    {
      "lat": 1.5,
      "lng": 0.0
    },
    {
      "lat": 2.0,
      "lng": 1.0
    }
  ]
}

Definition of MixedPlanner-Types

Mixedplanner-Metainformation

The minimum required meta information JSON-body looks like this:

{
  "dateFrom": "2019-12-03",
  "dateTo": "2019-12-03",
  "resCapacity": false,
  "resCategory": false,
  "resQualification": false,
  "postProcessing": false
}

The full meta information JSON-body looks like this:

{
  "dateFrom": "2019-12-03",
  "dateTo": "2019-12-03",
  "resCapacity": false,
  "resCategory": false,
  "resQualification": false,
  "postProcessing": false,
  "accuracyMode": 1.0,
  "outputLanguage": 1,
  "tightSchedule": false,
  "travelTimeMin": 5,
  "integrateDurationExtensions": true,
  "integrateGermanBreakRegulations": true
}

JSON-Schema

Parameter Type Required Description
dateFrom string (date) Planning horizont start (WIP).
dateTo string (date) Planning horizont end (WIP).
resCapacity boolean Activate/Deactivate whether capacities should be considered in the optimization.
resCategory boolean Activate/Deactivate whether category types should be considered in the optimization.
resQualification boolean Activate/Deactivate whether qualifications should be considered in the optimization.
postProcessing boolean Enable or disable additional traffic optimizations.
accuracyMode number Manages a solution refinement process. An accuracy > 0.0 can improve the solution significantly but will take longer to calculate, effects increase with higher accuracyMode. (Default: 1.0)
outputLanguage integer (LanguageType) Defines which language should be used in the output. (Default: German)
tightSchedule boolean Defines if buffer should be eliminated after optimization to increase profitability. Time windows with a priority lower than 3 can be exceeded. (Default: false)
travelTimeMin integer A global lower limit to travel time, travel times below this will be raised. (Default: 0)
integrateDurationExtensions boolean All travel time and task duration return values will already include their respective modifier, further information below. This does not change algorithm results. (Default: false)
integrateGermanBreakRegulations boolean Adds mandatory breaks to workers according to the German Working Time Act if set. (Default: false)

The options res* describe which fields from the dataset should be taken into account. More precisely those are:

The setting integrateDurationExtensions is an output-only setting, meaning both internal calculations and algorithm result are unaffected. Any values besides the ones listed below are unchanged:

Using the integrateDurationExtensions setting might provide some better readable data: Since internal calculations always apply the modifiers to durations and travel times, the internal values when calculating a plan are greater or equal to the ones that get output when not using integrateDurationExtensions. As a result, the output plan will feature gaps in time where for instance travel happens internally but would already be concluded if you used the output values. The integrateDurationExtensions setting outputs the internally used values to avoid this effect. However, the downside is inflated travel and work times in the output, since all buffers are now included in their respective work or travel time.

Mixedplanner-Optimization-Parameters

The minimum optimization parameters JSON-body is an empty body. The full body looks like this:

{
  "preset": 1,
  "fairDistribution": 4,
  "localityClustering": 2,
  "shortPaths": 7,
  "timeliness": 5,
  "travelTimeRelax": 0,
  "workerPrefs": 5,
  "workerReduction": 1,
  "workTimeRelax": 0,
  "genderPref": 2,
  "profitability": 3
}

JSON-Schema

All parameters are integer numbers $ 0 \leq x \leq 9 $. You only need to pass the ones you want to use, all others will be implicitly set to 0.

Parameter Type Required Description
preset integer (preset type) Sets the parameters to a predefined preset (details below). Additionally specified parameters will override the preset parameters.
fairDistribution integer Distribute the tasks fairly among the workers.
localityClustering integer Build local clusters for the workers to work within if possible.
shortPaths integer Optimize the plan towards short travel paths.
timeliness integer Optimize towards satisfying the time windows.
travelTimeRelax integer Increase the travel time by introducing travel time buffers.
workerPrefs integer Try to satisfy any tasks' worker preferences.
workerReduction integer Reduce the number of necessary workers.
workTimeRelax integer Increase the time needed for a task (duration) by introducing work time buffers.
genderPref integer Try to satisfy any tasks' gender preferences. Setting this parameter to 9 will upgrade the algorithm to consider prefGender a restriction rather than merely a preference.
profitability integer Optimize towards high single-tour profitability.

The following presets are currently available (parameters not listed are set to 0):

ID Name Parameter settings
0 Eco orientied
  • shortPaths: 9
  • timeliness: 5
  • genderPref: 4
  • profitability: 9
1 Worker oriented
  • fairDistribution: 9
  • shortPaths: 5
  • timeliness: 4
  • workerPref: 4
  • genderPref: 4
  • profitability: 4
2 Customer oriented
  • shortPaths: 2
  • timeliness: 9
  • workerPref: 7
  • genderPref: 9
  • profitability: 2
3 Fleet oriented
  • shortPaths: 5
  • timeliness: 2
  • workerReduction: 9
  • profitability: 2
4 Random The values shortPaths, timeliness are set to a random value 1 to 9. The values fairDistribution, workerPrefs, workerReduction, genderPref, profitability are set to a random value 0 to 9.

Unassigned MixedPlanner-Task

The minimum required unassigned task JSON-body looks like this:

{
  "taskID": 200,
  "date": "2019-12-03",
  "duration": 65,
  "timeEarliest": "10:00",
  "timeLatest": "12:00"
}

The full unassigned task JSON-body when using a GeoCoord location looks like this:

{
  "taskID": 200,
  "date": "2019-12-03",
  "duration": 65,
  "timeEarliest": "10:00",
  "timeLatest": "12:00",
  "timePriority": 2,
  "location": {
    "lat": 50.878847,
    "lng": 6.964728400000013
  },
  "prefWorkers": [
    1,2
  ],
  "forbWorkers": [
    3,4
  ],
  "capacity": 40,
  "weight": 40,
  "volume": 40,
  "qualification": 3,
  "categories": [
    1
  ],
  "antiCategories": [
    2
  ],
  "exchangeableCategories": [
    4,5,6
  ],
  "twinCategories": [
    3
  ],
  "desiredWorker": 1,
  "initassignedWorker": 1,
  "initassignedOrder": 1,
  "preassignedWorker": 2,
  "prefGender": 1,
  "precedingTasks": [ 
    1, 2
  ],
  "predecessorTasks": [
    3
  ],
  "revenue": 1.25,
  "travelTimeExtra": 2,
  "group": 2
}

The full unassigned task JSON-body when using a Location Site looks like this:

{
  "taskID": 200,
  "date": "2019-12-03",
  "duration": 65,
  "timeEarliest": "10:00",
  "timeLatest": "12:00",
  "timePriority": 2,
  "locationSiteID": 1,
  "prefWorkers": [
    1,2
  ],
  "forbWorkers": [
    3,4
  ],
  "capacity": 40,
  "weight": 40,
  "volume": 40,
  "qualification": 3,
  "categories": [
    1
  ],
  "antiCategories": [
    2
  ],
  "exchangeableCategories": [
    4,5,6
  ],
  "twinCategories": [
    3
  ],
  "desiredWorker": 1,
  "initassignedWorker": 1,
  "initassignedOrder": 1,
  "preassignedWorker": 2,
  "prefGender": 1,
  "precedingTasks": [ 
    1, 2
  ],
  "predecessorTasks": [
    3
  ],
  "revenue": 1.25,
  "travelTimeExtra": 2,
  "group": 2
}

The JSON-Schema of the unassigned task is an extension of the JSON-Schema of an abstract task.

The unassigned task is the incoming task description for the optimizer outlining the restrictions for the optimization.

Parameter Required Type Description
taskID integer The unqiue ID of this task.
date string (date) The date for the day to be planned.
duration integer The time in minutes it takes to complete this task.
timeEarliest string (time) The earliest possible start-time of this task.
timeLatest string (time) The latest time at which this task should be finished.
timePriority integer The priority of the time window ranging from 0-5. (Default: 1)
  • 0 - irrelevant
  • 1 - not important (automatically extended by 30 minutes)
  • 2 - more important (automatically extended by 15 minutes)
  • 3 - important (no extension)
  • 4 - very important (no extension)
  • 5 - fixed time (no extension)
Tasks with high time priority are more likely to get scheduled inside their given time window. Tasks with time priority 0 completely ignore their given time window.
location GeoCoord The geo-coordinates where the task has to be performed. Not defining a location will allow the task to be performed anywhere. Only one of location and locationSiteID may be set on each task.
locationSiteID integer (LocationSite) The ID of the location site which should be used as location for this task. Not defining a location will allow the task to be performed anywhere. Only one of location and locationSiteID may be set on each task.
description string DEPRECATED
prefWorkers Array<integer> The IDs of the preferred workers.
forbWorkers Array<integer> The IDs of the forbidden workers.
capacity number The capacity requirement of this task, which the assigned worker will need to provide.
weight number The weight requirement of this task, which the assigned worker will need to provide.
volume number The volume requirement of this task, which the assigned worker will need to provide.
qualification integer The minimum qualification of the employee required to perform the task (e.g. years of experience).
categories Array<integer> A suitable worker has to fulfill all of these categories.
antiCategories Array<integer> Categories of other tasks which exclude joint performance with this task.
exchangeableCategories Array<integer> A suitable worker has to fulfill at least one of these categories.
twinCategories Array<integer> The assigned worker will need to perform at least two tasks with each of these categories.
preassignedWorker integer The unique ID of the worker who has to take over this task. Restrictions such as qualifications, capacity, category still apply.
desiredWorker integer The unique ID of the worker who is desired (strong preference, not influenced to workerPrefs) to take over this task.
initassignedWorker integer The unique ID of the worker who will be initially assigned. This creates a higher likelyhood of the task being assigned to this worker in the solution, especially if the initial assignment stems from a previous solution.
initassignedOrder integer The order within the initially assigned worker's tour. Requires an initassignedWorker.
prefGender integer (gender) The preferred gender for the assigned worker.
precedingTasks Array<integer> Tasks in this list and this task will be performed by the same worker and all tasks in list will have to be finished before this task starts.
predecessorTasks Array<integer> The tasks of which one has to be performed right before this task by the same worker as this task.
revenue number The revenue which will be achieved with this task.
travelTimeExtra integer Fixed amount of time added to this task's travel time.
group integer A group ID. Tasks with the same group ID get assigned to the same worker.

categories, antiCategories and exchangeableCategories need to be disjoint sets on each task. This means that a category appearing in categories may not appear in antiCategories or exchangeableCategories and vice versa. twinCategories represent a different set and are not affected by this restriction.

Positive numbers for capacity, volume or weight represent loading tasks while negative numbers for capacity, volume or weight represent unloading tasks.

Assigned MixedPlanner-Task

The minimum required assigned task JSON-body looks like this:

{
  "taskID": 200,
  "date": "2019-12-03",
  "duration": 65,
  "timeEarliest": "10:00",
  "timeLatest": "12:00",
  "timeScheduled": "11:01",
  "travelTime": 3,
  "travelDistance": 2.83061,
  "assignedWorker": 2,
  "info": "This task assignment causes negative arrival slack: -6",
  "finalassignedOrder": 3
}

The full assigned task JSON-body when using a GeoCoord location looks like this:

{
  "taskID": 200,
  "date": "2019-12-03",
  "duration": 65,
  "timeEarliest": "10:00",
  "timeLatest": "12:00",
  "timePriority": 2,
  "location": {
    "lat": 50.878847,
    "lng": 6.964728400000013
  },
  "prefWorkers": [
    1,2
  ],
  "forbWorkers": [
    3,4
  ],
  "capacity": 40,
  "weight": 40,
  "volume": 40,
  "qualification": 3,
  "categories": [
    1
  ],
  "antiCategories": [
    2
  ],
  "exchangeableCategories": [
    4,5,6
  ],
  "twinCategories": [
    3
  ],
  "desiredWorker": 1,
  "initassignedWorker": 1,
  "initassignedOrder": 1,
  "preassignedWorker": 2,
  "prefGender": 1,
  "precedingTasks": [ 
    1,2
  ],
  "predecessorTasks": [
    3
  ],
  "revenue": 1.25,
  "travelTimeExtra": 2,
  "timeScheduled": "11:01",
  "travelTime": 3,
  "travelDistance": 2.83061,
  "assignedWorker": 2,
  "info": "This task assignment causes negative arrival slack: -6",
  "profit": 12.21,
  "performResetBeforeAtID": 2,
  "finalassignedOrder": 3,
  "group": 2,
}

The assigned task - after the performed optimization - extends the unassigned task with information about when the task is scheduled and by whom it will be completed. Additionally some predictive metrics about the distance and travel time to reach this task are added.

The JSON-Schema of the assigned task is an extension of the JSON-Schema of an abstract task.

Extension Parameter Required Type Description
taskID integer The unqiue ID of this task.
date string (date) The date for the day to be planned.
duration integer The time in minutes it takes to complete this task.
timeEarliest string (time) The earliest possible start-time of this task.
timeLatest string (time) The latest time at which this task should be finished.
timePriority integer The priority of the time window ranging from 0-5. (Default: 1)
  • 0 - irrelevant
  • 1 - not important (automatically extended by 30 minutes)
  • 2 - more important (automatically extended by 15 minutes)
  • 3 - important (no extension)
  • 4 - very important (no extension)
  • 5 - fixed time (no extension)
Tasks with high time priority are more likely to get scheduled inside their given time window. Tasks with time priority 0 completely ignore their given time window.
location GeoCoord The geo-coordinates where the task has to be performed. Not defining a location will allow the task to be performed anywhere. Only one of location and locationSiteID may be set on each task.
locationSiteID integer (LocationSite) The ID of the location site which should be used as location for this task. Not defining a location will allow the task to be performed anywhere. Only one of location and locationSiteID may be set on each task.
description string DEPRECATED
prefWorkers Array<integer> The IDs of the preferred workers.
forbWorkers Array<integer> The IDs of the forbidden workers.
capacity number The capacity requirement of this task, which the assigned worker will need to provide.
weight number The weight requirement of this task, which the assigned worker will need to provide.
volume number The volume requirement of this task, which the assigned worker will need to provide.
qualification integer The minimum qualification of the employee required to perform the task (e.g. years of experience).
categories Array<integer> A suitable worker has to fulfill all of these categories.
antiCategories Array<integer> Categories of other tasks which exclude joint performance with this task.
exchangeableCategories Array<integer> A suitable worker has to fulfill at least one of these categories.
twinCategories Array<integer> The assigned worker will need to perform at least two tasks with each of these categories.
preassignedWorker integer The unique ID of the worker who has to take over this task. Restrictions such as qualifications, capacity, category still apply.
desiredWorker integer The unique ID of the worker who is desired (strong preference, not influenced to workerPrefs) to take over this task.
initassignedWorker integer The unique ID of the worker who will be initially assigned. This creates a higher likelyhood of the task being assigned to this worker in the solution, especially if the initial assignment stems from a previous solution.
initassignedOrder integer The order within the initially assigned worker's tour.
prefGender integer (gender) The preferred gender for the assigned worker.
precedingTasks Array<integer> Tasks in this list and this task will be performed by the same worker and all tasks in list will have to be finished before this task starts.
predecessorTasks Array<integer> The tasks of which one has to be performed right before this task by the same worker as this task.
revenue number The revenue which will be achieved with this task.
travelTimeExtra integer Fixed amount of time added to this task's travel time.
group integer A group ID. Tasks with the same group ID get assigned to the same worker.=
timeScheduled string (time) The predicted/planned time to start this task by the assigned worker.
travelTime integer The time in minutes needed to travel from the previous task to this task. For a more detailed explanation see the table below.
travelDistance number The distance in km needed to travel from the previous task to this task.
assignedWorker integer The unique ID of the assigned worker who will perform this task.
info string Additional information about the task.
profit number The profit the task creates ($revenue - costs$).
performResetBeforeAtID integer The id of the location site which will be visited to reset capacity/weight/volume before this task starts.
finalassignedOrder integer The order number within the assigned tour.

The value travelTime also includes travel times to and from a capacity reset location, as well as the reset duration, if a reset is performed directly before this task. Depending on the integrateDurationExtensions settings, it may also include travelTimeExtra and the travel time multiplicator based on travelTimeRelax. The following table provides the calculations in each case:

meta settings no reset before this task reset before this task
integrateDurationExtensions set to false $travelTime = max( actualTravelTime,$ travelTimeMin $)$ $travelTime = max( travelTimeToResetLocation,$ travelTimeMin $) +$ capacityResetDuration $+ max( travelTimeFromResetLocation,$ travelTimeMin $)$
integrateDurationExtensions set to true $travelTime = max( actualTravelTime,$ travelTimeMin $) * travelTimeMultiplicator +$ travelTimeExtra $travelTime = max( travelTimeToResetLocation,$ travelTimeMin $) * travelTimeMultiplicator +$ capacityResetDuration $+ max( travelTimeFromResetLocation,$ travelTimeMin $) * travelTimeMultiplicator +$ travelTimeExtra

In case no actual travel happens (for instance identical locations of consecutive tasks, no location or no startLocation/ endLocation ) the values $max( actualTravelTime, travelTimeMin )$ and similar are zero.

Please note that the formula changes with integrateDurationExtensions set to true influence only output values, since the setting does not change internal calculations or the algorithm result (see MixedPlanner-Metainformation for more details).

Unassigned MixedPlanner-Worker

The minimum required JSON-body of an unassigned worker when using GeoCoord locations looks like this:

{
  "workerID": 1,
  "shiftStart": "06:00",
  "shiftEnd": "14:00",
  "shiftDate": "2019-12-03"
}

The full JSON-body of an unassigned worker when using GeoCoord locations looks like this:

{
  "workerID": 1,
  "shiftStart": "06:00",
  "shiftEnd": "14:00",
  "shiftDate": "2019-12-03",
  "startLocation":{
    "lat": 50.878847,
    "lng": 6.964728400000013
  },
  "endLocation":{
    "lat": 50.878847,
    "lng": 6.964728400000013
  },
  "shiftPriority": 2,
  "capacity": 20.5,
  "capacityInitial": 10.1,
  "capacityResetLocationSiteIDs": [
    1,2
  ],
  "capacityResetDuration": 10,
  "volume": 12.5,
  "volumeInitial": 5.5,
  "weight": 2.5,
  "weightInitial": 1.0,
  "finalCapacityResetThreshold": 12.1,
  "finalVolumeResetThreshold": 5.5,
  "finalWeightResetThreshold": 1.5,
  "qualification": 1,
  "categories": [
    4,5
  ],
  "prefCategories": [
    6
  ],
  "breakStartEarliest": "12:21",
  "breakEndLatest": "13:00",
  "breakDuration": 10,
  "vehicleType": 1,
  "gender": 1,
  "costsPerKM": 0.05,
  "costsPerMinute": 1.23,
  "costsInitial": 234.56,
  "maxDesiredTotalDistance": 100.0,
  "maxDesiredSingleDistance": 5.0
}

The full JSON-body of an unassigned worker when using Location Sites looks like this:

{
  "workerID": 1,
  "shiftStart": "06:00",
  "shiftEnd": "14:00",
  "shiftDate": "2019-12-03",
  "startLocationSiteID": 4,
  "endLocationSiteID": 5,
  "shiftPriority": 2,
  "capacity": 20.5,
  "capacityInitial": 10.1,
  "capacityResetLocationSiteIDs": [
    1,2
  ],
  "capacityResetDuration": 10,
  "volume": 12.5,
  "volumeInitial": 5.5,
  "weight": 2.5,
  "weightInitial": 1.0,
  "finalCapacityResetThreshold": 12.1,
  "finalVolumeResetThreshold": 5.5,
  "finalWeightResetThreshold": 1.5,
  "qualification": 1,
  "categories": [
    4,5
  ],
  "prefCategories": [
    6
  ],
  "breakStartEarliest": "12:21",
  "breakEndLatest": "13:00",
  "breakDuration": 10,
  "vehicleType": 1,
  "gender": 1,
  "costsPerKM": 0.05,
  "costsPerMinute": 1.23,
  "costsInitial": 234.56,
  "maxDesiredTotalDistance": 100.0,
  "maxDesiredSingleDistance": 5.0,
  "dontVary": true
}

The JSON-Schema of the unassigned worker is an extension of the JSON-Schema of an abstract worker.

The worker has both optional and required parameters as marked in the following table.

Parameter Required Type Description
workerID integer The unique ID of the worker. If a worker has multiple shifts this day, there can be multiple respective worker-objects with this (same) ID.
startLocation GeoCoord The location where the worker begins their working day. Only one of startLocation and startLocationSiteID may be set on any given worker.
startLocationSiteID integer (LocationSite) The id of the location where the worker begins their working day. Only one of startLocation and startLocationSiteID may be set on each worker.
endLocation GeoCoord The location where the worker finishes their working day. Only one of endLocation and endLocationSiteID may be set on any given worker.
endLocationSiteID integer (LocationSite) The id of the location where the worker finishes their working day. Only one of endLocation and endLocationSiteID may be set on each worker.
shiftDate string (date) The date of this shift (should match the date of the submitted tasks in general for daily plannings).
shiftStart string (time) The time this shift starts.
shiftEnd string (time) The time this shift ends.
shiftPriority integer The priority to keep the defined shift start and end times ranging from 0-3: irrelevant, neutral, important, very important. The default value is 1 (neutral).
hoursPerWeek integer DEPRECATED
capacity number The available capacity (positive value) of the worker or their vehicle.
capacityInitial number The initially occupied capacity (positive value) on shift start of this worker or their vehicle.
capacityResetLocationSiteIDs Array<integer> (LocationSite) The ids of location sites at which capacity/volume/weight can be reset.
capacityResetDuration integer The time in minutes needed for a capacity reset (Default: 0). Only allowed in combination with capacity reset locations.
volume number The available volume (positive value) of the worker or their vehicle.
volumeInitial number The initially loaded volume (positive value) on shift start of this worker or their vehicle.
weight number The weight (positive value) the worker or their vehicle is able to handle.
weightInitial number The initially loaded weight (positive value) on shift start of this worker or their vehicle.
finalCapacityResetThreshold number The used capacity threshold (positive value) above which a reset will be enforced before ending the shift.
finalVolumeResetThreshold number The used volume threshold (positive value) above which a reset will be enforced before ending the shift.
finalWeightResetThreshold number The used weight threshold (positive value) above which a reset will be enforced before ending the shift.
qualification integer The qualification of the worker. Workers can perform any task with equal or lower qualification requirement.
categories Array<integer> The categories the workers can take over.
prefCategories Array<integer> Tasks with any of these categories will be preferred by this worker.
breakStartEarliest string (time) The earliest start of the break a worker has to do.
breakEndLatest string (time) The latest end of the break a worker has to do.
breakDuration integer The duration in minutes of the break.
vehicleType integer (vehicle) The vehicle type used by this worker.
gender integer (gender) The gender type of the worker.
costsPerKM number The costs per km for this worker (e.g. fuel costs).
costsPerMinute number The costs per minute working time (carrying out tasks) for this worker (e.g. monthly salary converted to minutes).
costsInitial number Costs that occur if there is at least one task assigned to the worker.
maxDesiredTotalDistance number The maximum total travel distance per shift that a worker wants to perform (if possible).
maxDesiredSingleDistance number The maximum travel distance for each individual travel that a worker wants to perform (if possible).
dontVary boolean Lock existing task assignment, see below for details.

When no startLocation or startLocationSiteID is given, the shift of the worker will start at the first assigned task with no travel time or distance to it. This can be used in situations where workers start their day at home and any travel time to their first client does not count as working time. (By analogy: endLocation/endLocationSiteID)

A worker with dontVary set to true is "fixed" for the optimizer, meaning they get assigned all tasks (and only those tasks) that have this worker set as preassignedWorker or initassignedWorker in the order of initassignedOrder. That also means that initassignedOrder is required for these tasks. Travel times, resets, etc still get calculated on both worker and task and the worker and its tasks will be considered in MixedPlanner-Statistics and MixedPlanner-Info.

Assigned MixedPlanner-Worker

The assigned worker - after the performed optimization - extends the unassigned worker with information about when their break is scheduled (when one was given). Additionally some information about the worker can be added in the info field.

The minimum required JSON-body of an assigned MixedPlanner-Worker is identical to the minimum body of an unassigned MixedPlanner-Worker. The full JSON-body when using GeoCoord locations looks like this:

{
  "workerID": 1,
  "shiftStart": "06:00",
  "shiftEnd": "14:00",
  "shiftDate": "2019-12-03",
  "startLocationSiteID": 4,
  "endLocationSiteID": 5,
  "shiftPriority": 2,
  "capacity": 20.5,
  "capacityInitial": 10.1,
  "capacityResetLocationSiteIDs": [
    1,2
  ],
  "capacityResetDuration": 10,
  "volume": 12.5,
  "volumeInitial": 5.5,
  "weight": 2.5,
  "weightInitial": 1.0,
  "finalCapacityResetThreshold": 12.1,
  "finalVolumeResetThreshold": 5.5,
  "finalWeightResetThreshold": 1.5,
  "qualification": 1,
  "categories": [
    4,5
  ],
  "prefCategories": [
    6
  ],
  "breakStartEarliest": "12:21",
  "breakEndLatest": "13:00",
  "breakDuration": 10,
  "vehicleType": 1,
  "gender": 1,
  "costsPerKM": 0.05,
  "costsPerMinute": 1.23,
  "costsInitial": 234.56,
  "maxDesiredTotalDistance": 100.0,
  "maxDesiredSingleDistance": 5.0,
  "dontVary": true,
  "info": "",
  "breakScheduled": "12:30",
  "travelHomeTime": 2,
  "travelHomeDistance": 1.123,
  "performFinalResetAtID": 1
}

The JSON-Schema of the assigned worker is an extension of the JSON-Schema of an abstract worker.

Extension Parameter Required Type Description
workerID integer The unique ID of the worker. If a worker has multiple shifts this day, there can be multiple respective worker-objects with this (same) ID.
startLocation GeoCoord The location where the worker begins their working day. Only one of startLocation and startLocationSiteID may be set on any given worker.
startLocationSiteID integer (LocationSite) The id of the location where the worker begins their working day. Only one of startLocation and startLocationSiteID may be set on any given worker.
endLocation GeoCoord The location where the worker finishes their working day. Only one of endLocation and endLocationSiteID may be set on any given worker.
endLocationSiteID integer (LocationSite) The id of the location where the worker finishes their working day. Only one of endLocation and endLocationSiteID may be set on any given worker.
shiftDate string (date) The date of this shift (should match the date of the submitted tasks in general for daily plannings).
shiftStart string (time) The time this shift starts.
shiftEnd string (time) The time this shift ends.
shiftPriority integer The priority to keep the defined shift start and end times ranging from 0-3: irrelevant, neutral, important, very important. The default value is 1 (neutral).
hoursPerWeek integer DEPRECATED
capacity number The available capacity (positive value) of the worker or their vehicle.
capacityInitial number The initially occupied capacity (positive value) on shift start of this worker or their vehicle.
capacityResetLocationSiteIDs Array<integer> (LocationSite) The ids of location sites at which capacity/volume/weight can be reset.
capacityResetDuration integer The time in minutes needed for a capacity reset (Default: 0). Only allowed in combination with capacity reset locations.
volume number The available volume (positive value) of the worker or their vehicle.
volumeInitial number The initially loaded volume (positive value) on shift start of this worker or their vehicle.
weight number The weight (positive value) the worker or their vehicle is able to handle.
weightInitial number The initially loaded weight (positive value) on shift start of this worker or their vehicle.
finalCapacityResetThreshold number The used capacity threshold (positive value) above which a reset will be enforced before ending the shift.
finalVolumeResetThreshold number The used volume threshold (positive value) above which a reset will be enforced before ending the shift.
finalWeightResetThreshold number The used weight threshold (positive value) above which a reset will be enforced before ending the shift.
qualification integer The qualification of the worker. Workers can perform any task with equal or lower qualification requirement.
categories Array<integer> The categories the workers can take over.
prefCategories Array<integer> Tasks with any of these categories will be preferred by this worker.
breakStartEarliest string (time) The earliest start of the break a worker has to do.
breakEndLatest string (time) The latest end of the break a worker has to do.
breakDuration integer The duration in minutes of the break.
vehicleType integer (vehicle) The vehicle type used by this worker.
gender integer (gender) The gender type of the worker.
costsPerKM number The costs per km for this worker (e.g. fuel costs).
costsPerMinute number The costs per minute working time (carrying out tasks) for this worker (e.g. monthly salary converted to minutes).
costsInitial number Costs that occur if there is at least one task assigned to the worker.
maxDesiredTotalDistance number The maximum total travel distance per shift that a worker wants to perform (if possible).
maxDesiredSingleDistance number The maximum travel distance for each individual travel that a worker wants to perform (if possible).
dontVary boolean Lock existing task assignment.
breakScheduled string (time) When the break of the worker is scheduled, is just passed when a break was given.
info string Some textual information about the worker, e.g. for delays.
travelHomeTime integer Time in minutes needed to get to the endlocation from the last task. For a more edetailed explanation see the table to travelTime.
travelHomeDistance number Distance in km between last task and the endlocation.
performFinalResetAtID integer (LocationSite) The id of the location site at which a capacity/ weight/ volume reset was performed after the last task and before returning to a depot.

If an Unassigned MixedPlanner-Worker does not already contain the data breakStartEarliest, breakEndLatest or breakDuration, integrateGermanBreakRegulations is set to true and the worker has to take a break due to their shift length and German law, the automatically generated break data regarding these values will be added to the Assigned MixedPlanner-Worker as extension. If these values were already written in the Unassigned MixedPlanner-Worker, they do not get changed in the Assigned MixedPlanner-Worker. If the values were not written in the Unassigned MixedPlanner-Worker but integrateGermanBreakRegulations is set to false or German law does not require a break for this shift, no data will be added.

MixedPlanner-Statistics

The JSON-body of statistics for a calculated plan looks like this:

{
  "configuration": [
    {
      "label": "Short Path",
      "value": 0.777778
    },
    ...
  ],
  "workload": [
    {
      "workerID": 1,
      "values": [
        0,0,0,0,0,0,0.97,1,0.5,0.17,0.07,0.5,0,0,0,0,0,0,0,0,0,0,0
      ]
    },
    ...
  ],
  "travelTimes": [
    {
      "workerID": 1,
      "time": 51
    },
    ...
  ],
  "travelDistances": [
    {
      "workerID": 1,
      "distance": 32.1
    },
    ...
  ],
  "taskTimes": [
    {
      "workerID": 1,
      "time": 145
    },
    ...
],
  "taskBusyness": [
    {
      "workerID": 1, 
      "busyness": 0.3
    },
    ...
  ],
  "travelBusyness": [
    {
      "workerID": 1,
      "busyness": 0.4
    },
    ...
  ],
  "workTimeDistribution": [
    {
      "type": "Working Time",
      "time": 716
    },
    ...
  ],
  "preferredWorkers": [
    {
      "type": "matched",
      "count": 12
    },
    {
      "type": "unmatched",
      "count": 7
    }
  ],
  "preferredGender": [
    {
      "type": "matched",
      "count": 3
    },
    {
      "type": "unmatched",
      "count": 4
    }
  ],
  "desiredWorkers": [
    {
      "type": "matched",
      "count": 9
    },
    {
      "type": "unmatched",
      "count": 13
    }
  ],
  "routeLength": 146.841095,
  "onTime": 96,
  "planProfitability": 150.12
}

JSON-Schema

Parameter Type Description
configuration Array<Object<label: string, value: number>> The applied optimizer configurations mapped in ranges from $0.0$ to $1.0$.
workload Array<Object<workerID: integer, values: Array<number>>> The workload per worker for each hour of the day in ranges from $0.0$ to $1.0$ (worked 0 min to worked 60 min).
travelTimes Array<Object<workerID: integer, time: integer>> The total time in minutes each worker spends traveling. Capacity reset durations are exluded!
travelDistances Array<Object<workerID: integer, distance: number>> The distance in km each worker drives for this plan.
taskTimes Array<Object<workerID: integer, time: integer>> The time in minutes each worker spends on working on tasks (sum of durations). Previously called careTime.
taskBusyness Array<Object<workerID: integer, busyness: number>> Proportion of working time to shift time ($0.0$ to $1.0$).
travelBusyness Array<Object<workerID: integer, busyness: number>> Proportion of travel time to shift time ($0.0$ to $1.0$). Capacity reset durations are exluded!
workTimeDistribution Array<Object<type: string, time: integer>> The time in minutes spent on different actions summed up. Capacity reset durations are exluded!
preferredWorkers Array<Object<type: string, count: integer>> Sum of fulfilled (type: matched) as well as unfulfilled (type: unmatched) worker preferences.
preferredGender Array<Object<type: string, count: integer>> Sum of fulfilled (type: matched) as well as unfulfilled (type: unmatched) gender preferences.
desiredWorkers Array<Object<type: string, count: integer>> Sum of tasks assigned to desired workers (type: matched) and sum of tasks assigned to another worker (type: unmatched).
impact (TBA) Array<Object<label: string, value: number>> A number based summary of calculation results. See below for details.
routeLength number The driven distance in km summed up over all workers.
onTime integer Percentage for tasks scheduled perfectly inside the desired time windows ($0$ to $100$).
planProfitability number The profitability this plan archieves based on worker costs and task revenues.

All parameters are required.

The parameter configuration contains the following fields. They are translated based on the language setting and are all required:

German label English label
Kurze Wege Short Path
Arbeiterpräferenzen Worker Preferences
Faire Verteilung Fair Distribution
Clustering Clustering
Pünktlichkeit Timeliness
Weniger Arbeiter Worker Reduction
Reisezeit Travel Time
Arbeitszeit Working Time
Geschlechterpräferenzen Gender Preferences
Profitabilität Profitability

The parameter workTimeDistribution contains the following fields. They are translated based on the language setting and are all required:

German type English type
Arbeitszeit Working Time
Pausenzeit Break Time
Fahrzeit Travel Time
Schichtzeit Shift Time
Puffer Buffer

The array impact contains all restriction types and gives a percentage (0.0-1.0) evaluation of each restriction's final influence on the algorithmic optimization and plan result. This can be used to detect logical problems in the input data, i.e. too restrictive time windows, large travel times or a large amount of worker preferences that just cannot be fulfilled. However, please note that when a restriction is listed in impact with a value greater zero, it does not mean that there even is a way to erase its impact. For instance, travel values will always be featured unless the total amount of travel time is zero or the shortPaths option is set to zero.

The following fields are getting written in impact. They get translated based on the language setting and are all required:

German label English label
Anti-Kategorien Anticategories
Pausen Breaks
Wunschmitarbeiter Desired workers
Ausgeglichener Plan Fair distribution
Geschlechterpräferenz Gender preference
Gruppierung Groups
Initiale Kosten Initial costs
Maximale Fahrtstrecke Maximum travel distance
Multischicht Multishift
Ungültige Zuweisung Invalid assignment
Vorhergehende Aufgaben Preceding tasks
Unmittelbar vorhergehende Aufgaben Predecessor tasks
Kategoriepräferenz Preferred category
Mitarbeiterpräferenz Preferred worker
Arbeitszeitkosten Working time costs
Schichtzeitverletzungen Shift time violations
Zeitfensterverletzungen Task time window violations
Einzelfahrten Task to task travel
Fahrtkosten Travel costs
Twin-Kategorien Twin categories
Mitarbeiterreduzierung Worker reduction

MixedPlanner-Info

The JSON-body of info for a calculated plan with German language settings looks like this:

{
  "text": "Alle Aufgaben wurden valide den Mitarbeitern zugewiesen!",
  "balance": "4 Mitarbeiter sind eingeplant\n6,2 Aufgaben durchschnittlich (pro Mitarbeiter)\n1,2 Aufgaben Abweichung von der durchschnittlichen Aufgabenzahl (pro Mitarbeiter)\nAufgaben- und Reisezeiten in Summe: 886 Minuten\nSchichtzeiten in Summe: 1860 Minuten\nAuslastung (netto): 47,6%",
  "dist": "146,8 km auf der Straße",
  "pref": "12 Aufträge werden von einem gewünschten Mitarbeiter durchgeführt, bei 7 Aufträgen war dies leider nicht sinnvoll oder möglich",
  "relax": "Aufträge:\n\nPrognostizierte kurze Verspätungen [5-30 Minuten] (4%):\n200, \n\nPrognostizierte Verspätungen [über 30 Minuten] (0%):\n\n\nDie anderen 24 Aufgaben (96%) werden pünktlich erreicht!\n\nSchichten:\nAlle Mitarbeiterschichten können eingehalten werden.",
  "time": "170 Minuten auf der Straße\n42,5 Minuten auf der Straße durchschnittlich (pro Mitarbeiter)\n9,0 Minuten Reisezeitvarianz (pro Mitarbeiter)",
  "feasible": false,
  "constructionSites": [
    {
      "constructionSiteID": 666,
      "startDate": "2020-07-23",
      "endDate": "2020-07-25",
      "startPoint": {
        "lat": 48.17083,
        "lng": 11.3292
      },
      "endPoint": {
        "lat": 48.16774,
        "lng": 11.33253
      },
      "info": "Waldstraße gesperrt 2020"
    },
    ...
  ]
}

JSON-Schema

All parameters are strings.

Parameter Required Type Description
text string Some general information about the plan. Contains warnings if any "hard" constraints could not be kept.
balance string Statistics about the workload of the workers and the distribution of tasks among them.
dist string Distance in km driven by the workers.
pref string Information about preferred workers matches.
relax string Information about delayed tasks grouped by delay amount: 5-30 minutes, 30+ minutes. Information about exceeded worker shifts.
time string Total and average travel time. Capacity reset durations are exluded!
feasible boolean Set to false if certain input requirements (capacity, categories, qualifications, shifts, time windows with high timePriority, ...) could not be kept in the final solution.
constructionSites Array<Construction Site> A list of construction sites in close proximity to the calculated routes.

All text in text, balance, dist, pref, relax, time gets translated based on language setting.

Definition of ShiftPlanner-Types

ShiftPlanner-Metainformation

WIP

The minimum required JSON-body of metainformation looks like this:

{
  "dateFrom": "2019-12-03",
  "dateTo": "2019-12-03",
  "resCategory": false,
  "resQualification": false
}

The full JSON-body of metainformation looks like this:

{
  "dateFrom": "2019-12-03",
  "dateTo": "2019-12-03",
  "resCategory": false,
  "resQualification": false,
  "accuracyMode": 1.0,
  "outputLanguage": 1,
  "minQualificationOfTaskCoverage": 2,
  "omnipresentCategoriesOfTaskCoverage": [
    3,5,6
  ]
}

JSON-Schema (TODO)

Parameter Type Required Description
dateFrom string (date) Planning horizont start (WIP).
dateTo string (date) Planning horizont end (WIP).
resCategory boolean Activate/Deactivate whether category types should be considered in the optimization.
resQualification boolean Activate/Deactivate whether qualifications should be considered in the optimization.
accuracyMode number Manages a solution refinement process. An accuracy > 0.0 can improve the solution significantly but will take longer to calculate, effects increase with higher accuracyMode. Default: 1.0
outputLanguage integer (languagetype) Defines which language should be used in the output. Default: German
minQualificationOfTaskCoverage integer At each minute between the earliest shiftStart of any ShiftPlanner-Worker and latest shiftEnd of any ShiftPlanner-Worker there shall be least one ShiftPlanner-Worker of this qualification or higher performing a task.
omnipresentCategoriesOfTaskCoverage Array<integer> For each of these categories, at each minute between the earliest shiftStart of any ShiftPlanner-Worker and latest shiftEnd of any ShiftPlanner-Worker there shall be least one ShiftPlanner-Worker with the category performing a task.

The options res* describe which fields from the dataset should be taken into account. More precisely those are:

ShiftPlanner-Optimization-Parameters

WIP

The minimum optimization parameters JSON-body is an empty body. The full body looks like this:

{
  "preset": 1,
  "fairDistribution": 4,
  "timeliness": 5,
  "workerPrefs": 5,
  "teamPrefs": 5,
  "taskPrefs": 5,
  "worktimePrefs": 5,
  "workerReduction": 1,
  "genderPref": 2,
  "profitability": 3
}

JSON-Schema (TODO)

All parameters are integer numbers between 0 and 9 (inclusive). You only need to pass the ones you want to use, the other will be implicitly set to 0.

Parameter Type Required Description
preset integer (preset type) Sets the parameters to a predefined preset (details below). Parameters specified in the json-body will override the preset.
fairDistribution integer Distribute the tasks fairly among the workers.
timeliness integer Optimize towards satisfying the time windows.
workerPrefs integer Try to satisfy the workers' preferences.
teamPrefs integer Try to satisfy preferences in relations between workers.
taskPrefs integer Try to satisfy preferences set in tasks.
worktimePrefs integer Try to satisfy worktime related restrictions.
workerReduction integer Reduce the number of necessary workers.
genderPref integer Try to satisfy any tasks' gender preferences. Setting this parameter to 9 will upgrade the algorithm to consider prefGender a restriction rather than merely a preference.
profitability integer Optimize towards high single-worker profitability.

The following presets are currently available (parameters not listed are set to 0):

ID Name Parameter settings
TBA

Unassigned ShiftPlanner-Task

WIP

The minimum required JSON-body of an unassigned task looks like this:

{
  "taskID": 200,
  "date": "2019-12-03",
  "duration": 240,
  "timeEarliest": "06:00",
  "timeLatest": "12:00"
}

The full JSON-body of an unassigned task looks like this:

{
  "taskID": 200,
  "date": "2019-12-03",
  "duration": 240,
  "timeEarliest": "06:00",
  "timeLatest": "12:00",
  "timePriority": 2,
  "prefWorkers": [
    1,2
  ],
  "forbWorkers": [
    3,4
  ],
  "qualification": 3,
  "categories": [
    1
  ],
  "exchangeableCategories": [
    2,4
  ],
  "preassignedWorker": 2,
  "desiredWorker": 2,
  "prefGender": 1,
  "precedingTasks": [ 
    1,2
  ],
  "predecessorTasks": [ 
    1,2
  ],
  "group": 2,
  "revenue": 2.123
}

The JSON-Schema of the unassigned shiftplanner task (TODO) is an extension of the JSON-Schema of an abstract task.

The unassigned task is the incoming task description for the optimizer outlining the restrictions for the optimization.

Parameter Required Type Description
taskID integer The unqiue ID of this task.
date string (date) The date for the day to be planned.
duration integer The time in minutes it takes to complete this task.
timeEarliest string (time) The earliest possible start-time of this task.
timeLatest string (time) The latest time at which this task should be finished.
timePriority integer The priority of the time window ranging from 0-5. (Default: 1)
  • 0 - irrelevant
  • 1 - not important (automatically extended by 30 minutes)
  • 2 - more important (automatically extended by 15 minutes)
  • 3 - important (no extension)
  • 4 - very important (no extension)
  • 5 - fixed time (no extension)
Tasks with high time priority are more likely to get scheduled inside their given time window. Tasks with time priority 0 completely ignore their given time window.
prefWorkers Array<integer> The IDs of the preferred workers.
forbWorkers Array<integer> The IDs of the forbidden workers.
qualification integer The minimum qualification of the employee required to perform the task (e.g. years of experience).
categories Array<integer> A suitable worker has to fulfill all of these categories.
exchangeableCategories Array<integer> A suitable worker has to fulfill at least one of these categories.
preassignedWorker integer The unique ID of the worker who has to take over this task. Restrictions such as qualifications, capacity, category still apply.
desiredWorker integer The unique ID of the worker who is desired (strong preference, not influenced by workerPrefs) to take over this task.
prefGender integer (gender) The preferred gender for the assigned worker.
precedingTasks Array<integer> Tasks in this list and this task will be performed by the same worker and all tasks in list will have to be finished before this task starts.
predecessorTasks Array<integer> The tasks of which one has to be performed right before this task by the same worker as this task.
group integer A group ID. Tasks with the same group ID get assigned to the same worker.
groupOrder (TBA) integer The order within a group. For more details, see below.
revenue number The revenue which will be achieved with this task.

Tasks within the same group (identical groupID) will still need a Shift each where they will be assigned on seperately. (TBA) If the whole group or a subset of a group shall be assigned to a single Shift, each task in the set/ subset needs to have a unique groupOrder. The tasks will then be assigned to a single Shift in that order. Tasks without groupOrder within the same group will not get assigned to that Shift and need a seperate Shift each. Note that there can obviously be only one such subset per group.

If tasks are supposed to be on the same worker in a specified order but on seperate Shifts, set the groupID but use precedingTasks or predecessorTasks instead of groupOrder.

Assigned ShiftPlanner-Task

WIP

The assigned task - after the performed optimization - extends the unassigned tasks with information about when the task is scheduled and by whom it will be completed.

The minimum required JSON-body of an assigned task looks like this:

{
  "taskID": 200,
  "date": "2019-12-03",
  "duration": 240,
  "timeEarliest": "06:00",
  "timeLatest": "12:00",
  "timeScheduled": "13:45",
  "assignedWorker": 2,
  "info": "",
  "finalassignedOrder": 1, 
  "profit": 1.123
}

The full JSON-body of an assigned task looks like this:

{
  "taskID": 200,
  "date": "2019-12-03",
  "duration": 240,
  "timeEarliest": "06:00",
  "timeLatest": "12:00",
  "timePriority": 2,
  "prefWorkers": [
    1,2
  ],
  "forbWorkers": [
    3,4
  ],
  "qualification": 3,
  "categories": [
    1
  ],
  "exchangeableCategories": [
    2,4
  ],
  "preassignedWorker": 2,
  "desiredWorker": 2,
  "prefGender": 1,
  "precedingTasks": [ 
    1,2
  ],
  "predecessorTasks": [ 
    1,2
  ],
  "group": 2,
  "revenue": 2.123,
  "timeScheduled": "13:45",
  "assignedWorker": 2,
  "info": "",
  "finalassignedOrder": 1, 
  "profit": 1.123
}

The JSON-Schema of the assigned shiftplanner task (TODO) is an extension of the JSON-Schema of an abstract task.

Extension Parameter Required Type Description
taskID integer The unqiue ID of this task.
date string (date) The date for the day to be planned.
duration integer The time in minutes it takes to complete this task.
timeEarliest string (time) The earliest possible start-time of this task.
timeLatest string (time) The latest time at which this task should be finished.
timePriority integer The priority of the time window ranging from 0-5. (Default: 1)
  • 0 - irrelevant
  • 1 - not important (automatically extended by 30 minutes)
  • 2 - more important (automatically extended by 15 minutes)
  • 3 - important (no extension)
  • 4 - very important (no extension)
  • 5 - fixed time (no extension)
Tasks with high time priority are more likely to get scheduled inside their given time window. Tasks with time priority 0 completely ignore their given time window.
prefWorkers Array<integer> The IDs of the preferred workers.
forbWorkers Array<integer> The IDs of the forbidden workers.
qualification integer The minimum qualification of the employee required to perform the task (e.g. years of experience).
categories Array<integer> A suitable worker has to fulfill all of these categories.
exchangeableCategories Array<integer> A suitable worker has to fulfill at least one of these categories.
preassignedWorker integer The unique ID of the worker who has to take over this task. Restrictions such as qualifications, capacity, category still apply.
desiredWorker integer The unique ID of the worker who is desired (strong preference, not influenced by workerPrefs) to take over this task.
prefGender integer (gender) The preferred gender for the assigned worker.
precedingTasks Array<integer> Tasks in this list and this task will be performed by the same worker and all tasks in list will have to be finished before this task starts.
predecessorTasks Array<integer> The tasks of which one has to be performed right before this task by the same worker as this task.
group integer A group ID. Tasks with the same group ID get assigned to the same worker.
groupOrder (TBA) integer The order within a group.
revenue number The revenue which will be achieved with this task.
timeScheduled string (time) The predicted/planned time to start this task by the assigned worker.
assignedWorker integer The unique ID of the assigned worker who will take over this task.
info string may contain some information about the worker.
finalassignedOrder integer The order number on the assigned worker.
profit number The profit the task creates ($revenue - costs$).

Unassigned ShiftPlanner-Worker

WIP

The minimum required JSON-body of an unassigned worker looks like:

{
  "workerID": 1
}

The full JSON-body of an unassigned worker looks like:

{
  "workerID": 1,
  "shifts": [
    {
      "shiftStart": "05:00",
      "shiftEnd": "12:00",
      "shiftDate": "2019-12-03"
    }
  ],
  "qualification": 1,
  "prefConsecutiveWorkdays": 10,
  "prefConsecutiveOffdays": 15,
  "categories": [
    1,2
  ],
  "prefCategories": [
    3
  ],
  "prefWeekCategories": [
    2
  ],
  "prefWeekendCategories" : [
    3
  ],
  "prefWorkers": [
    5,43
  ],
  "antiWorkers": [
    5,43
  ],
  "gender": 1,
  "expectedWorkingMinutes": 9200,
  "minWorkingMinutes": 8000,
  "maxWorkingMinutes": 12000,
  "maxConsecutiveWorkdays": 6,
  "carryoverConsecutiveWorkdays": 0,
  "minConsecutiveOffdays": 2,
  "carryoverConsecutiveOffdays": 1,
  "minBreakMinutesBetweenTasks": 600,
  "maxDailyWorkingMinutes": 600,
  "minFreeSaturdays": 4,
  "minFreeSundays": 5,
  "maxWeeklyWorkingMinutes": 3000,
  "carryoverWorkingMinutesLastWeek": 50,
  "maxTwoWeekWorkingMinutes": 4800,
  "carryoverWorkingMinutesSecondLastWeek": 2100,
  "dontVary": true,
  "costsPerMinute": 1.123,
  "costsInitial": 100.12
}

The JSON-Schema of the unassigned shiftplanner worker is an extension of the JSON-Schema of an abstract worker.

The worker has both optional and required parameters as marked in the following table.

Parameter Required Type Description
workerID integer The unique ID of the worker.
qualification integer The qualification of the worker. He or she is able to take over tasks with the same or lower qualifications.
prefConsecutiveWorkdays integer The preferred number of working days in a row.
prefConsecutiveOffdays integer The preferred number of non-working days in a row.
categories Array<integer> The categories the workers can take over.
prefCategories Array<integer> The task-categories preferred by the worker.
prefWeekCategories Array<integer> The task-categories preferred by the worker on any week day (Mon-Fri).
prefWeekendCategories Array<integer> The task-categories preferred by the worker on any weekend day (Sat, Sun).
prefWorkers Array<integer> The workers that this worker prefers to have simultanious shifts with.
antiWorkers Array<integer> The workers that this worker prefers to not have simultanious shifts with.
shifts Array<Shift> The time slots at which a worker can perform exactly one task each.
gender integer (gender) The gender type of the worker.
expectedWorkingMinutes integer The preferred amount of working time minutes for this worker in the final plan, deviation in both directions will be kept as low as possible.
minWorkingMinutes integer The minimum amount of working time minutes for this worker in the final plan.
maxWorkingMinutes integer The maximum amount of working time minutes for this worker in the final plan.
maxConsecutiveWorkdays integer Maximum number of consecutive workdays. A day is a workday if any work is performed from 00:00 to 23:59. Default: no limit
carryoverConsecutiveWorkdays integer The current number of consecutive workdays at the start of the plan.
minConsecutiveOffdays integer Minimum number of consecutive offdays. A day is an offday if no work is performed from 00:00 to 23:59. Default: 0
carryoverConsecutiveOffdays integer The current number of consecutive offdays at the start of the plan.
minBreakMinutesBetweenTasks integer Minimum number of minutes break between two ShiftPlanner-Tasks. Default: 0
maxDailyWorkingMinutes integer Maximum number of working minutes per day. Default: no limit
minFreeSaturdays integer Minimum number of work-free Saturdays for this worker between the earliest shiftStart of any ShiftPlanner-Worker and latest shiftEnd of any ShiftPlanner-Worker.
minFreeSundays integer Minimum number of work-free Sundays for this worker between the earliest shiftStart of any ShiftPlanner-Worker and latest shiftEnd of any ShiftPlanner-Worker.
maxWeeklyWorkingMinutes integer Maximum minutes working time for this worker each calendar week (Monday to Sunday). Please note that the week cycle is independent from the planning horizon, use carryoverWorkingMinutesLastWeek in conflicting cases.
carryoverWorkingMinutesLastWeek integer Minutes of worktime already performed by this worker in the week of the earliest shiftStart of any ShiftPlanner-Worker in this plan. The value is factored in by maxWeeklyWorkingMinutes and maxTwoWeekWorkingMinutes but not expectedWorkingMinutes!
maxTwoWeekWorkingMinutes integer Maximum minutes working time for this worker for every two consecutive calendar weeks (Monday to Sunday). Please note that the week cycle is independent from the planning horizon, use carryoverWorkingMinutesLastWeek and carryoverWorkingMinutesSecondLastWeek in conflicting cases.
carryoverWorkingMinutesSecondLastWeek integer Minutes of worktime already performed by this worker in the week prior to the earliest shiftStart of any ShiftPlanner-Worker in this plan. The value is factored in by maxWeeklyWorkingMinutes and maxTwoWeekWorkingMinutes but not expectedWorkingMinutes!
dontVary boolean Lock existing task assignment, see below for details.
costsPerMinute number The costs per minute working time (carrying out tasks) for this worker (e.g. monthly salary converted to minutes).
costsInitial number Costs that occur if there is at least one task assigned to the worker.

A worker with dontVary set to true is "fixed" for the optimizer, meaning they get assigned all tasks (and only those tasks) that are the initassignedTask to any of the worker's Shifts. To each of these tasks there has to be exactly one Shift on the worker that has the task set as initassignedTask, this Shift will be the one where the task is assigned to in the final plan. The worker and its tasks will be considered in ShiftPlanner-Statistics and ShiftPlanner-Info.

Only one of carryoverConsecutiveWorkdays and carryoverConsecutiveOffdays may be set for each worker.

Assigned ShiftPlanner-Worker

WIP

The assigned worker - after the performed optimization - extends the unassigned workers with information in the info field.

The minimum required JSON-body of an assigned worker is identical to the minimum required JSON-body of an unassigned worker. The full JSON-body looks like this:

{
  "workerID": 1,
  "shifts": [
    {
      "shiftStart": "05:00",
      "shiftEnd": "12:00",
      "shiftDate": "2019-12-03"
    }
  ],
  "qualification": 1,
  "prefConsecutiveWorkdays": 10,
  "prefConsecutiveOffdays": 15,
  "categories": [
    1,2
  ],
  "prefCategories": [
    3
  ],
  "prefWeekCategories": [
    2
  ],
  "prefWeekendCategories" : [
    3
  ],
  "prefWorkers": [
    5,43
  ],
  "antiWorkers": [
    5,43
  ],
  "gender": 1,
  "expectedWorkingMinutes": 9200,
  "minWorkingMinutes": 8000,
  "maxWorkingMinutes": 12000,
  "maxConsecutiveWorkdays": 6,
  "carryoverConsecutiveWorkdays": 0,
  "minConsecutiveOffdays": 2,
  "carryoverConsecutiveOffdays": 1,
  "minBreakMinutesBetweenTasks": 600,
  "maxDailyWorkingMinutes": 600,
  "minFreeSaturdays": 4,
  "minFreeSundays": 5,
  "maxWeeklyWorkingMinutes": 3000,
  "carryoverWorkingMinutesLastWeek": 50,
  "maxTwoWeekWorkingMinutes": 4800,
  "carryoverWorkingMinutesSecondLastWeek": 2100,
  "dontVary": true,
  "costsPerMinute": 1.123,
  "costsInitial": 100.12,
  "info": ""
}

The JSON-Schema of the assigned shiftplanner worker is an extension of the JSON-Schema of an abstract worker.

Extension Parameter Required Type Description
workerID integer The unique ID of the worker.
qualification integer The qualification of the worker. He or she is able to take over tasks with the same or lower qualifications.
prefConsecutiveWorkdays integer The preferred number of working days in a row.
prefConsecutiveOffdays integer The preferred number of non-working days in a row.
categories Array<integer> The categories the workers can take over.
prefCategories Array<integer> The task-categories preferred by the worker.
prefWeekCategories Array<integer> The task-categories preferred by the worker on any week day (Mon-Fri).
prefWeekendCategories Array<integer> The task-categories preferred by the worker on any weekend day (Sat, Sun).
prefWorkers Array<integer> The workers that this worker prefers to have simultanious shifts with.
antiWorkers Array<integer> The workers that this worker prefers to not have simultanious shifts with.
shifts Array<Shift> The timeslots at which this worker can perform exactly one task each.
gender integer (gender) The gender type of the worker.
expectedWorkingMinutes integer The preferred amount of working time minutes for this worker in the final plan, deviation in both directions will be kept as low as possible.
minWorkingMinutes integer The minimum amount of working time minutes for this worker in the final plan.
maxWorkingMinutes integer The maximum amount of working time minutes for this worker in the final plan.
maxConsecutiveWorkdays integer Maximum number of consecutive workdays. A day is a workday if any work is performed from 00:00 to 23:59. Default: no limit
carryoverConsecutiveWorkdays integer The current number of consecutive workdays at the start of the plan.
minConsecutiveOffdays integer Minimum number of consecutive offdays. A day is an offday if no work is performed from 00:00 to 23:59. Default: 0
carryoverConsecutiveOffdays integer The current number of consecutive offdays at the start of the plan.
minBreakMinutesBetweenTasks integer Minimum number of minutes break between two ShiftPlanner-Tasks. Default: 0
maxDailyWorkingMinutes integer Maximum number of working minutes per day. Default: no limit
minFreeSaturdays integer Minimum number of work-free Saturdays for this worker between the earliest shiftStart of any ShiftPlanner-Worker and latest shiftEnd of any ShiftPlanner-Worker.
minFreeSundays integer Minimum number of work-free Sundays for this worker between the earliest shiftStart of any ShiftPlanner-Worker and latest shiftEnd of any ShiftPlanner-Worker.
maxWeeklyWorkingMinutes integer Maximum minutes working time for this worker each calendar week (Monday to Sunday). Please note that the week cycle is independent from the planning horizon, use carryoverWorkingMinutesLastWeek in conflicting cases.
carryoverWorkingMinutesLastWeek integer Minutes of worktime already performed by this worker in the week of the earliest shiftStart of any ShiftPlanner-Worker in this plan. The value is factored in by maxWeeklyWorkingMinutes and maxTwoWeekWorkingMinutes but not expectedWorkingMinutes!
maxTwoWeekWorkingMinutes integer Maximum minutes working time for this worker for every two consecutive calendar weeks (Monday to Sunday). Please note that the week cycle is independent from the planning horizon, use carryoverWorkingMinutesLastWeek and carryoverWorkingMinutesSecondLastWeek in conflicting cases.
carryoverWorkingMinutesSecondLastWeek integer Minutes of worktime already performed by this worker in the week prior to the earliest shiftStart of any ShiftPlanner-Worker in this plan. The value is factored in by maxWeeklyWorkingMinutes and maxTwoWeekWorkingMinutes but not expectedWorkingMinutes!
dontVary boolean Lock existing task assignment.
costsPerMinute number The costs per minute working time (carrying out tasks) for this worker (e.g. monthly salary converted to minutes).
costsInitial number Costs that occur if there is at least one task assigned to the worker.
info string Some textual information about the worker.

ShiftPlanner-Statistics

WIP

The JSON-body of statistics for a calculated plan looks like this:

{
  "impact": [
    {
      "label": "Minimum consecutive offdays",
      "value": 0.777778
    },
    ...
  ]
}

JSON-Schema

Parameter Type Description
impact Array<Object<label: string, value: number>> A number based summary of calculation results. See below for details.

All parameters are required.

The array impact contains all restriction types and gives a percentage (0.0-1.0) evaluation of each restriction's final influence on the algorithmic optimization and plan result. This can be used to detect logical problems in the input data, i.e. too restrictive time windows, an unrealisic amount of free Saturday/ Sunday preferences or a large amount of worker preferences that just cannot be fulfilled. However, please note that when a restriction is listed in impact with a value greater zero, it does not mean that there even is a way to erase its impact. For instance, if costsPerMinute are set, worktime costs will always be featured unless the total amount of working time is zero or the profitability option is set to zero.

The following fields are getting written in impact. They get translated based on the language setting and are all required:

German label English label
Minimum freie Tage Minimum consecutive offdays
Präferierte freie Tage Preferred consecutive offdays
Ungültige Zuweisung Invalid assignment
Vorhergehende Aufgaben Preceding Tasks
Unmittelbar vorhergehende Aufgaben Predecessor Tasks
Mitarbeiterpräferenz Worker preference
Wunschmitarbeiter Desired worker
Geschlechterpräferenz Gender preference
Zeitfensterverletzung Task time window violation
Schichtverletzung Shift time window violation
Arbeitszeitkosten Worktime costs
Initiale Kosten Initial costs
Erwartete Gesamtarbeitszeit Expected total worktime
Minimale Gesamtarbeitszeit Minimum total worktime
Maximale Gesamtarbeitszeit Maximum total worktime
Freie Samstage Free Saturdays
Freie Sonntage Free Sundays
Gruppierung Groups
Kategoriepräferenz Preferred categories
Maximale Arbeitszeiten Maximum worktimes
Ausgeglichener Plan Fair distribution
Mitarbeiterreduzierung Worker reduction
Maximale Arbeitstage Maximum workdays
Präferierte Arbeitstage Preferred workdays
Präferenzen zwischen Mitarbeitern Preferences between workers
Anti-Präferenzen zwischen Mitarbeitern Anti-preferences between workers
Qualifikationsabdeckung Qualification coverage
Kategorieabdeckung Category coverage

ShiftPlanner-Info

TBA

Authentication

To authorize, use this code:

const AmazonCognitoIdentity = require('amazon-cognito-identity-js');
const CognitoUserPool = AmazonCognitoIdentity.CognitoUserPool;
const poolData = {
  UserPoolId: "eu-central-1_0nXRn1JFH", // Your user pool ID here
  ClientId: "5n75tqsegshum2i9o0bgavmmuf " // Your client ID here
};
const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
const authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails({
  Username : 'abc@xyz.de', // Your username here
  Password : '*****', // Your password here
});

const userData = {
  Username : 'abc@xyz.de', // Your username again here
  Pool : userPool
};

const cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
  onSuccess: function (result) {
  ...
  },
  onFailure: function(err) {
  console.log(err);
  },
});

Make sure to replace with your authentication data.

We are using personlized accounts to provide access to the API. You can request an account by contacting us.

Through the authentication you get three tokens: the access-token, the ID-token and the refresh-token. The tokens are jwt-tokens (JSON Web Tokens). The access-token is currently not used in the API. The ID-token has to be proposed in every request in the header as follows:

Authorization: 'ID-token'

The ID-token contains a timestamp when the token has been authorized (auth_time) and when it will expire (exp). Currently an ID-token expires after one hour. With these parameters you are able to check if the token is still valid. If a request with an expired token is sent, it will be rejected with status code 401. If so, you can easily get a new ID-token by using the refresh-token without having to re-enter your credentials.

Currently the method SRP (Secure Remote Password protocol) is used for authentication. This method does not need to pass the password to the backend. Instead, a multiway handshake is used to proof the authentication. Implementations of this procedure can be found on the Wikipedia-Page.

The authentication is performed via AWS Cognito (Developer-Guide). AWS provides SDKs for some languages which simplifies the authentication process. For example, when you are using JavaScript you can use the amazon-cognito-identity-js to easily integrate the authentication. However, not all SDKs provide full support for this method.

Easily supported languages by AWS are:

If you are using a language that is not directly supported, feel free to contact us. Even if an AWS-SDK exists for your language, often the SRP-methods have to be implemented by yourself. Here you can try one of the implementations linked on Wikipedia.

Configurations

Basing on your id-token you are able to determine wheter you have just a single user and no access to your limits or you have two users one for submitting plans and one for managing your clients.

In the first case the field cognito:groups in the id-token is not set. In the second case the field cognito:groups is set. For the submitting-account the entry hasMgmtUser is set and for the management-account the entry isMgmtUser is set.

The user and the management account are mapped to the same e-mail-address but have different passwords.

User-Authentication

You authenticate yourself against this user pool with your account details to do calculations. When you have a managed account you have to provide an client id.

UserPoolId: "eu-central-1_0nXRn1JFH",
ClientId: "5n75tqsegshum2i9o0bgavmmuf"

Management-User-Authentication

You authenticate yourself against this user pool with you account details to alter limitation for your clients.

UserPoolId: "eu-central-1_esw8SOukA",
ClientId: "7vqnjalt4k4op5ffhqf8uramvi"

Plans

Post a new plan

This endpoint is used to post a new problem description for obtaining an optimized plan based on it.

HTTP-Endpoint

Type Endpoint
MixedPlanner POST https://jadnzfxwb3.execute-api.eu-central-1.amazonaws.com/dev/description
ShiftPlanner POST https://jadnzfxwb3.execute-api.eu-central-1.amazonaws.com/dev/shift-description

MixedPlanner-Request

An example for a MixedPlanner request

{
  "meta": {
    "accuracyMode": 1,
    "dateFrom": "2019-12-03",
    "dateTo": "2019-12-03",
    "postProcessing": true,
    "resCapacity": false,
    "resCategory": false,
    "resQualification": false
  },
  "parameters": {
    "fairDistribution": 4,
    "localityClustering": 2,
    "shortPaths": 7,
    "timeliness": 5,
    "travelTimeRelax": 0,
    "workerPrefs": 5,
    "workerReduction": 1,
    "workTimeRelax": 0
  },
  "tasks": [
    {
      "date": "2019-12-03",
      "duration": 65,
      "location": {
        "lat": 50.878847,
        "lng": 6.964728400000013
        },
      "taskID": 200,
      "timeEarliest": "10:00",
      "timeLatest": "12:00"
    },
    {
      "date": "2019-12-03",
      "duration": 25,
      "location": {
        "lat": 50.9333412,
        "lng": 6.972426400000018
      },
      "taskID": 201,
      "timeEarliest": "16:00",
      "timeLatest": "17:00"
    },
    ...
  ],
  "workers": [
    {
      "workerID": 1,
      "endLocation": {
        "lat":50.9357092,
        "lng":6.974585599999955
      },
      "shiftDate": "2019-12-03",
      "shiftEnd": "14:00",
      "shiftStart": "06:00",
      "startLocation": {
        "lat": 50.9357092,
        "lng": 6.974585599999955
      }
    },
    ...
  ], 
  "locationSites": [
    {
      "locationSiteID": 1,
      "location": {
        "lat": 50.878847,
        "lng": 6.964728400000013
      }
    },
    {
      "locationSiteID": 2,
      "location": {
        "lat": 12.878847,
        "lng": -13.964728400000013
      }
    },
    ...
  ],
  "obstacles": [
    {
      "type": "polyline",
      "factor": 2.5,
      "description": "This is a line",
      "points": [
        {
          "lat": 51.46149994737996,
          "lng": 7.850463381293338
        },
        {
          "lat": 51.66914967977792,
          "lng": 9.753747625087499
        },
        ...
      ]
    },
    {
      "type": "polygon",
      "factor": 2.5,
      "points": [
        {
          "lat": 51.46149994737996,
          "lng": 7.850463381293338
        },
        {
          "lat": 51.66914967977792,
          "lng": 9.753747625087499
        },
        ...
      ]
    },
    ...
  ],
  "client": {
    "clientID": "{1234-5678-9123}"
  }
}

The JSON-schema is named unassigned plan

Parameter Required Type Description
client client Contains information about the client, which sends this request.
meta meta Meta-information about what to consider in the optimization.
parameters parameters Parameters for the optimizer.
tasks Array<task> Array of MixedPlanner-Tasks that have to be planned.
workers Array<unassigned worker> Array of available MixedPlanner-Workers.
locationSites Array<LocationSite> Array of available location sites.
obstacles Array<Obstacle> Array of additional obstacles.

The client field is required when you have a separate management account. It is used to determine the different client and their specific limits.

Every request gets calculated using a pre-selected list of obstacles from various sources. However, if you want to add custom ones, you can add them in the obstacles array. Please use this feature with caution, as obstacles can change algorithm behaviour in unintended ways.

ShiftPlanner-Request

WIP

An example for a ShiftPlanner request

{
  "meta": {
    "accuracyMode": 1,
    "dateFrom": "2019-12-03",
    "dateTo": "2019-12-03",
    "postProcessing": true,
    "resCategory": false,
    "resQualification": false
  },
  "parameters": {
    "fairDistribution": 4,
    "timeliness": 5,
    "workerPrefs": 5,
    "workerReduction": 1,
    "workTimeRelax": 0
  },
  "tasks": [
    {
      "date": "2019-12-03",
      "duration": 65,
      "taskID": 200,
      "timeEarliest": "10:00",
      "timeLatest": "12:00"
    },
    {
      "date": "2019-12-03",
      "duration": 25,
      "taskID": 201,
      "timeEarliest": "16:00",
      "timeLatest": "17:00"
    },
    ...
  ],
  "workers": [
    {
      "workerID": 1,
      "shifts": [
        {
          "shiftStart": "08:00",
          "shiftEnd": "20:00",
          "shiftDate": "2019-12-03"
        },
        ...
      ]
    },
    ...
  ],
  "client": {
    "clientID": "{1234-5678-9123}"
  }
}

The JSON-schema is named unassigned plan.

Parameter Required Type Description
client client Contains information about the client, which sends this request.
meta meta Meta-information about what to consider in the optimization.
parameters parameters Parameters for the optimizer.
tasks Array<task> Array of ShiftPlanner-Tasks that have to be planned.
workers Array<unassigned worker> Array of available ShiftPlanner-Workers.

The client field is required when you have a separate management account. It is used to determine the different client and their specific limits.

Result

As a result an ID will be given which can be used to check the result of the computation

AAAAAAAAABBBBBBBBBBBBBBBEEEEEEEEEEEEEEEEEDDDDDDDDDD

As result an ID will be returned which identifies the planning. You can use the function Retrieve a plan/status to check the planning status or whether the plan result exists.

Status-Codes

Number Code Description
200 OK The plan has already been submitted, everything is fine!
201 CREATED The plan was accepted and is currently processed by the optimization procedures.
403 FORBIDDEN Your account is setup to use different clients. The clientID was not given or the clientID was not registered yet.
409 CONFLICT The limit for the user or client has been exceeded.
422 UNPROCESSABLE ENTITY The plan generated by the backend does not match the JSON-schema. Please contact us to correct this failure.
500 INTERNAL SERVER ERROR The given data produces a failure in the backend. This can e.g. happen if IDs are referenced which not actually exists, like an workerID in prefWorkers is referenced which does not exist as worker. Please check your given data for consistency. Otherwise feel free to contact us.

Check status/retrieve a Plan

This endpoint is used to get the status of a plan or retrieve the plan, when the calculation already is finished.

HTTP-Endpoint

The HTTP-Endpoint to check status or receive the plan is identical for MixedPlanner and ShiftPlanner.

GET https://jadnzfxwb3.execute-api.eu-central-1.amazonaws.com/dev/plan/<ID>

Request

In the header of the request the field Accept must be set to application/json. The <ID> which was delivered as a result of the post request needs to be given in the URL.

MixedPlanner-Result

The result contains a plan where each task is assigned to a worker. Additionally for every tasks there are more information given like the time when the task is scheduled to be done.

When the calculation is finished you get a calculated plan, which can look like this:

{
  "requestID": "id2103",
  "meta": {
    "dateFrom": "2019-12-03",
    "dateTo": "2019-12-03",
    "resCapacity": false,
    "resQualification": false,
    "resCategory": false,
    "accuracyMode": 1,
    "postProcessing": false
  },
  "parameters": {
    "shortPaths": 7,
    "workerPrefs": 5,
    "fairDistribution": 4,
    "localityClustering": 2,
    "timeliness": 5,
    "workerReduction": 1,
    "travelTimeRelax": 0,
    "workTimeRelax": 0
  },
  "locationSites": [
    {
      "locationSiteID": 3,
      "location": {
        "lat": 50.3232323,
        "lng": 7.23122212
      }
    }
  ],
  "workers": [
    {
      "workerID": 1,
      "startLocation": {
        "lat": 50.9357092,
        "lng": 6.974585599999955
      },
      "endLocation": {
        "lat": 50.9357092,
        "lng": 6.974585599999955
      },
      "shiftStart": "06:00",
      "shiftEnd": "14:00",
      "info": "",
      "shiftDate": "2019-12-03"
    },
    {
      "workerID": 2,
      "startLocationSiteID": 3,
      "shiftStart": "05:00",
      "shiftEnd": "16:00",
      "shiftDate": "2019-12-03"
    }
  ],
  "tasks": [
    {
      "taskID": 200,
      "date": "2019-12-03",
      "duration": 65,
      "timeEarliest": "10:00",
      "timeLatest": "12:00",
      "location": {
        "lat": 50.878847,
        "lng": 6.964728400000013
      },
      "description": "",
      "timeScheduled": "11:01",
      "travelTime": 3,
      "travelDistance": 2.83061,
      "assignedWorker": 2,
      "info": "This task assignment causes negative arrival slack: -6"
    },
    ...
  ],
  "info": {
    "text": "Alle Aufgaben wurden valide den Mitarbeitern zugewiesen!",
    "balance": "4 Mitarbeiter sind eingeplant\n6,2 Aufgaben durchschnittlich (pro Mitarbeiter)\n1,2 Aufgaben Abweichung von der durchschnittlichen Aufgabenzahl (pro Mitarbeiter)\nAufgaben- und Reisezeiten in Summe: 886 Minuten\nSchichtzeiten in Summe: 1860 Minuten\nAuslastung (netto): 47,6%",
    "dist": "146,8 km auf der Straße",
    "pref": "12 Aufträge werden von einem gewünschten Mitarbeiter durchgeführt, bei 7 Aufträgen war dies leider nicht sinnvoll oder möglich",
    "relax": "Aufträge:\n\nPrognostizierte kurze Verspätungen [5-30 Minuten] (4%):\n200, \n\nPrognostizierte Verspätungen [über 30 Minuten] (0%):\n\n\nDie anderen 24 Aufgaben (96%) werden pünktlich erreicht!\n\nSchichten:\nAlle Mitarbeiterschichten können eingehalten werden.",
    "time": "170 Minuten auf der Straße\n42,5 Minuten auf der Straße durchschnittlich (pro Mitarbeiter)\n9,0 Minuten Reisezeitvarianz (pro Mitarbeiter)"
  },
  "statistics": {
    "configuration": [
      ...
    ],
    "workload": [
      {
        "workerID": 1,
        "values": [
          0,0,0,0,0,0,0.97,1,0.5,0.17,0.07,0.5,0,0,0,0,0,0,0,0,0,0,0
        ]
      },
      ...
    ],
    "travelTimes": [
      {
        "workerID": 1,
        "time": 51
      },
      ...
    ],
    "travelDistances": [
      {
        "workerID": 1,
        "distance": 13.1
      },
      ...
    ],
    "taskTimes": [
      {
        "workerID": 1,
        "time": 145
      },
      ...
    ],
    "taskBusyness": [
      {
        "workerID": 1,
        "busyness": 0.3
      },
      ...
    ],
    "travelBusyness": [
      {
        "workerID": 1,
        "busyness": 0.5
      },
      ...
    ],
    "workTimeDistribution": [
      {
        "type": "Arbeitszeit",
        "time": 716
      },
      {
        "type": "Fahrzeit",
        "time": 170
      },
      {
        "type": "Pausenzeit",
        "time": 0
      },
      {
        "type": "Puffer",
        "time": 974
      }
    ],
    "preferredWorkers": [
      {
        "type": "matched",
        "count": 12
      },
      {
        "type": "unmatched",
        "count": 7
      }
    ],
    "preferredGender": [
      {
        "type": "matched",
        "count": 12
      },
      {
        "type": "unmatched",
        "count": 7
      }
    ],
    "desiredWorkers": [
      {
        "type": "matched",
        "count": 12
      },
      {
        "type": "unmatched",
        "count": 7
      }
    ],
    "routeLength": 146.841095,
    "onTime": 96,
    "planProfitability": 150.12
  }
}

The JSON-schema is called assigned plan

Parameter Required Type Description
requestID string A unique id to identify the plan.
client client Contains information about the client, which sent this request.
meta meta Meta-information about what to consider in the optimization.
parameters parameters Parameters for the optimization.
tasks Array<task> Array of assigned tasks.
workers Array<assigned worker> Array of available workers.
locationSites Array<LocationSite> Array of available location sites.
obstacles Array<Obstacle> Array of additional obstacles.
statistics statistics Some statistics about the plan.
info info Some textual information about the plan.

ShiftPlanner-Result

WIP

Parameter Required Type Description
requestID string A unique id to identify the plan.
client client Contains information about the client, which sent this request.
meta meta Meta-information about what to consider in the optimization.
parameters parameters Parameters for the optimization.
tasks Array<task> Array of assigned tasks.
workers Array<assigned worker> Array of available workers.
statistics statistics Some statistics about the plan.
info (TBA) info Some textual information about the plan.

Error-result

If your request contains errors which leads to unsatisfiable plans, you will receive a error response instead of a plan.

If your request contains error you get a response, which can look like this:

{
  "requestID": "id32013",
  "error_msg": " |-| ERROR: Task #12 has itself assigned as preceding task. (129) |-| contact email: support@adiutabyte.de",
  "version": "1.0.0",
  "type": "error",
  "errorID": 129,
  "taskID": 12
}

The JSON-schema is named error plan

Parameter Required Type Description
requestID string A unique id to identify the plan request.
error_msg string Contains a textual description of the error.
version string Currently always set to "1.0.0".
type string Currently always set to "error".
errorID integer A unique id for identifying the error cause.
taskID integer If the error occurred by a specific task, its ID will be referenced.
workerID integer If the error occurred by a specific worker, their ID will be referenced.

The error_msg gets translated based on language settings.

Error Codes

Error message and id depend on what caused the problem. In some cases a notify-devs suffix gets added to the message, the English one being "Please contact the developers!". Both error message and dev-notification suffix get translated based on language settings specified.

For an error solution to be created the algorithm has to be able to

Should the program fail without being able to perform these steps, it will exit without an error solution being created.

Below are the currently used error ids and a short description as to what is the problem. Internal errors are most likely caused by bugs and can in general only be solved with a developer on our side (Error Code >249), the in the following listed errors are mainly caused by errors in the input processing and may also be solved by users directly correcting their input sent.

Error Code Range Error Category
0 – 99 Server side error
100 – 109 Miscellaneous errors
110 – 119 Invalid object in input data
120 – 199 Input data validation fail
200 – 249 Error while priming input data
250 – 999 Errors internal for the developers
Error Code Description Error name (internal) notify devs? internal? additional output additional properties
98 Project file could not be retrieved from S3
99 Process crashed
100 invalid error code InvalidError
101 error was not caught via manual checks or exception was thrown by c++ or external code UncaughtException text
110 invalid worker in input (missing required data) InvalidWorker workerID
111 invalid task in input (missing required data) InvalidTask taskID
112 invalid LocationSite in input (missing required data) InvalidLocationSite locationSiteID
113 invalid Shift in input (missing required data) InvalidShift
114 missing corner points on polygon InvalidPolygon
115 missing corner points on polyline InvalidPolyLine
116 invalid obstacle in input (missing required data) InvalidObstacle
117 input file contains no worker field NoWorkersInInput
118 input file contains no tasks field NoTasksInInput
120 sum of task capacity exceeds sum of worker capacity but no resets TaskCapacityExceedsWorkerCapacity
121 sum of task weights exceeds sum of worker weight limits but no resets TaskWeightExceedsWorkerWeight
122 sum of task volume exceeds sum of worker volume limits but no resets TaskVolumeExceedsWorkerVolume
123 sum of task minutes exceeds sum of shift minutes TaskTimeGTShiftTime
124 a worker set as initassignedWorker to a task does not exist in the input data InitWorkerDoesNotExist taskID workerID
125 initassignedOrder is set but neither initassignedWorker not preassignedWorker are set InitOrderButNotInitWorker taskID
126 two tasks have the same initial order on same worker ConflictingInitialOrder taskID 1&2
127 isAllowedToTakeOver fails for this task on every worker in plan (MixedPlanner version) NoSuitableWorkerAvailable_MP taskID task earliest, latest, duration, coordinates
128 isAllowedToTakeOver fails for this task on every worker in plan (ShiftPlanner version) NoSuitableWorkerAvailable_SP taskID task earliest, latest, duration
129 Tasks precedes itself directly SelfPrecedingTask taskID
130 one of the given preceding tasks does not exist in plan PrecedingTaskDoesNotExist taskID preceding taskID
131 The task and one of its preceding tasks have no common worker that is isAllowedToTakeOver NoSuitableWorkerPreceding taskID preceding taskID
132 task has itself as predecessor SelfPredecessorTask taskID
133 The task and every of its predecessor tasks have no common worker that is isAllowedToTakeOver NoSuitableWorkerPredecessor taskID
134 two tasks have the same id DuplicateTaskID taskID
135 two workers have the same id DuplicateWorkerID workerID
136 the time between task earliest and latest is not enough for the whole task duration TaskTimeWindowTooSmall taskID task duration, earliest, latest
137 initial capacity is greater than worker capacity WorkerInitiallyOverfilledCap workerID
138 initial weight is greater than worker weight limit WorkerInitiallyOverfilledWeight workerID
139 initial volume is greater than worker volume limit WorkerInitiallyOverfilledVol workerID
140 reset duration is set but reset locations are missing CapacityResetInformationInvalid workerID
141 shift end is before shift start NegativeLengthShift workerID
142 more tasks than total shifts in plan MoreTasksThanShifts
143 break start earliest is missing when other break values are set MissingBreakEarliest workerID
144 break end latest is missing when other break values are set MissingBreakLatest workerID
145 break duration is missing when other break values are set MissingBreakDuration workerID
146 break duration is greater than time between break earliest start and break latest end BreakTimeSlotTooSmall workerID
147 break end latest is before break start earliest NegativeBreakTimeWindow workerID
148 break is not inside worker shift BreakOutsideWorkerShift workerID
149 two multishifts on worker overlap OverlappingMultishifts workerID
150 both startLocation and startLocationSiteID on worker RedundantStartLocationSiteID workerID
151 both endLocation and endLocationSiteID on worker RedundantEndLocationSiteID workerID
152 locationSite set in startLocationSiteID does not exist InvalidStartLocationID workerID
153 locationSite set in endLocationSiteID does not exist InvalidEndLocationID workerID
154 one of the locationSites for resets does not exist InvalidCapacityResetLocationID workerID
155 both location and locationSiteID on task RedundantLocationSiteID taskID
156 locationSite set in location (task) does not exist InvalidLocationSiteID taskID
157 circle in preceding tasks PrecedingCircle
158 tasks in a preceding tree have different preassigned workers PrecedingTasksWithDifferentPreassigned preceding taskID preceded taskID
159 Qualification coverage is expected but no worker has enough qual QualificationCoverageNotPossible
160 Category coverage is expected but no worker has this category CategoryCoverageNotPossible category
161 a worker with multishifts has tasks that have it as initassigned worker. This is not allowed InvalidMultishift workerID
162 a worker with multishifts is set as dontVary worker. This is not allowed InvalidDontVary workerID
163 sum of negative capacities is greater than sum of positive capacities MoreNegCapacitiesThanPos
164 sum of negative weights is greater than sum of positive weights MoreNegWeightThanPos
165 sum of negative volumes is greater than sum of positive volumes MoreNegVolumeThanPos
166 two tasks have the same task as required (single) predecessor NotUniquePredecessorTask taskID 1&2
167 task has different preassigned and initassignedWorker when one of those is dontVary InconsistentDontVaryTask taskID
168 task is assigned to dontVary worker but has no initassigned order NoInitAssignedOrderDontVary taskID
169 task is assigned to dontVary worker but has same initassignedOrder as another task on same worker DontVaryInitassignedOrderNotUnique workerID
170 task is initassigned task to multiple shifts InitialAssignmentNotUnique taskID
171 initially assigned task on shift does not exist InitiallyAssignedTaskDoesNotExist the shift’s workerID taskID
172 task has dontVary worker as preassigned but no shift has it as initassigned NoDontVaryTaskShiftCorrelation taskID
173 a set of tasks that have to be performed by the same worker don't have any worker that can do so InvalidRelationGroup taskIDs of group
174 Input parameter out of range InvalidParameter
175 Two tasks have same group and groupOrder GroupOrderNotUnique taskID 1, taskID 2
176 groupOrder is set but group is not MissingGroupData taskID
200 time window is too small for duration even after reducing work time multiplicator TimeSlotTooSmallAfterCheck
201 Unique predecessor task does not exist in data NonexistantUniquePredecessor taskID
202 Task is linked directly to multiple tasks InvalidTaskLink taskID
203 Linked tasks form a circle TaskLinkCircle
204 Task replaces the task itself InvalidLinkList
205 Task replacement creates task duplicates in replacement lists InvalidTaskReplacement

Status-Codes

Number Code Description
200 OK The plan will be delivered.
404 NOT FOUND The requested ID does not exist.
406 NOT ACCEPTABLE The given Accept parameter in the header could not be used.
422 UNPROCESSABLE ENTITY The plan generated by the backend does not match the JSON-schema. Please contact us to correct this failure.
423 LOCKED The plan is currently optimized. Try again later to check if the calculation has finished.
500 INTERNAL SERVER ERROR An error occured in the backend. Please contact us to check why this has happened.

Client-Limits

If your account is set up to support different clients you have to submit the clientID in every request. Before you are able to use a new client you have to specify a limit of tasks a client is able to plan every month.

For these kind of request you have to use the management user. So you have to authenticate against the cognito pool mentioned in Management-User-Authentication

Set default client-limit

HTTP-Endpoint

POST https://jadnzfxwb3.execute-api.eu-central-1.amazonaws.com/dev/client-limit

Request

The JSON-body for setting the a default client limit looks like this:

{
  "clientID": "{12345-678-90}",
  "limit": 3000
}
Parameter Required Type Description
clientID string The identifier which identifies a client.
limit number The number of tasks a client is allowed to plan within a month.

Result

Parameter Type Description
message string Text: 'default limit successfully set'.

Status-Codes

Number Code Description
200 OK The limit was successfully set.
401 UNAUTHORIZED No credentials given in the header or they are not valid.
403 FORBIDDEN The access was not allowed for this user.

Get the default client-limit

HTTP-Endpoint

GET https://jadnzfxwb3.execute-api.eu-central-1.amazonaws.com/dev/client-limit/<client-id>

Result

The result JSON-body for getting the default client limit looks like this:

{
  "task_limit": 3000
}
Parameter Type Description
task_limit number The default task monthly limit.

Status-Codes

Number Code Description
200 OK The default task limit.
204 NO CONTENT No default task limit is set.

Set client-limit for a specific month

HTTP-Endpoint

POST https://jadnzfxwb3.execute-api.eu-central-1.amazonaws.com/dev/client-limit

Request

The JSON-body for setting the a specific client limit looks like this:

{
  "clientID": "{12345-678-90}",
  "limit": 3000,
  "year": 2020, 
  "month": 1
}
Parameter Required Type Description
clientID string The identifier which identifies a client.
year number The year for the limit.
month number The corresponding month for the limit.
limit number The number of tasks a client is allowed to plan within a month.

Result

Parameter Type Description
message string Text for which month the limit was set.

Status-Codes

Number Code Description
200 OK The limit was successfully set.
401 UNAUTHORIZED No credentials given in the header or they are not valid.
403 FORBIDDEN The access was not allowed for this user.
409 CONFLICT The client was not registered yet.

Get the client-limit for a specific month

HTTP-Endpoint

GET https://jadnzfxwb3.execute-api.eu-central-1.amazonaws.com/dev/client-limit/<client-id>/<year>/<month>

Result

The result JSON-body for getting the default client limit looks like this:

{
  "used_tasks": 2019,
  "task_limit": 3000
}
Parameter Type Description
used_tasks number The number of used tasks for this month.
task_limit number The monthly limit for tasks.

Status-Codes

Number Code Description
200 OK Everything fine, the limit and usage of tasks.
204 NO CONTENT No task limit is set for this month.

Changelog

2021-11-22

2021-11-12

2021-11-04

2021-10-18

2021-10-11

2021-10-07

2021-09-28

2021-09-25

2021-09-23

2021-08-26

2021-07-09

2021-06-25

2021-06-18

2021-05-28

2021-05-25

2021-05-18

2021-05-10

2021-04-29

2021-04-23

2021-04-08

2021-04-06

2021-03-23

2021-03-18

2021-03-17