NAV

# 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:

• Authorization (your ID-token, see Authentication)
• Accepts ("application/json")
• Content-Type ("application/json")

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.

• WIP
• In Input: Beta feature, use at own risk. Might not work as documented.
• In Output: Might not work as documented.
• TBA
• In Input: Not yet implemented feature. Do not use!
• In Output: No output as of yet.

# Definition of common types

## GeoCoord

The JSON-body of a GeoCoord 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

## Time

Valid time strings could be:

"00:15"
"11:45"
"23:59"


JSON-Schema

A string consisting of two parts following the pattern "HH:mm":

• "HH": the hour part with $0 \leq x \lt 9999$
• "mm": the minute part with $0 \leq x \lt 60$

With this approach it is possible to plan for multiple days. For any following days the time stamps needs to be relative to the first day. The second day at 15:13 would be 39:13.

## Date

Valid date strings could be:

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


JSON-Schema

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

• "YYYY": the year part with $2010 \leq x \lt 2100$
• "MM": the month part with $1 \leq x \leq 12$
• "DD": the day part with $1 \leq x \leq 31$

## VehicleType

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

VehicleTypeID Description
0 Car (default value)
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 (default value)
1 Male
2 Female
3 Other

## LanguageType

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

LanguageTypeID Description
0 German (default value)
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 JSON-body of a location site 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, which will be used for references
location GeoCoord The geocoordiantes of the location site

## Shift

WIP

The minimum required JSON-body of a shift looks like this:

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


The full JSON-body of a shift looks like this:

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


JSON-Schema

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.
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. The default value is 1 (neutral).

## Construction Site

The JSON-body of a construction site looks like this:

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


JSON-Schema

A constructionSite gets represented by a straight line between its startPoint and endPoint which can be identical.

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 JSON-body of a clientinformation looks like this:

{
"clientID": "{1234-5678-9123}"
}

Parameter Type Required Description
clientID string Identifies a specific client.

# Definition of MixedPlanner-Types

## Mixedplanner-Metainformation

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

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


The full JSON-body of metainformation looks like this:

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


JSON-Schema

Parameter Type Required Description
dateFrom string (date) Planning horizont start (WIP, for common single day-plannings use $dateFrom = dateTo$).
dateTo string (date) Planning horizont end (WIP, for common single day-plannings use $dateFrom = dateTo$).
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.
accuracyMode number Generally set it to 1. Experimental feature: a value of 0 would bypass many optimization steps to deliver a fast but rough solution.
postProcessing boolean Enable or disable additional traffic optimizations.
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 (Default: false). Time windows with a priority lower than 3 can be exceeded.
travelTimeMin integer A global lower limit to travel time (Default: 0, Minimum: 0). Travel times below this will be raised.
integrateDurationExtensions boolean Defines if relaxation of worktime/traveltime should be used in the output, otherwise they will be handled as buffers (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:

• resCapacity
• capacity restrictions
• weight restrictions
• volume restrictions
• resCategories
• categories
• preferred categories
• anticategories
• exchangeable categories
• twin categories
• resQualification
• qualification

## 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 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). Additionally specified parameters will override the preset.
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.
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.

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

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


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

{
"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,
1, 2
],
3
],
"revenue": 1.25,
"travelTimeExtra": 2,
"group": 2
}


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

{
"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,
1, 2
],
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
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 when this task should be finished.
timePriority integer The priority of the time window ranging from 0-5. The default value is 1. Meanings: 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 any given 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 any given task.
description string DEPRECATED
prefWorkers Array<integer> The IDs of the preferred workers.
forbWorkers Array<integer> The IDs of the forbidden workers.
capacity double The capacity requirement of this task, which the assigned worker will need to provide.
weight double The weight requirement of this task, which the assigned worker will need to provide.
volume double 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.
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 any one 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 does not share anything with the other three categories. To consider any category type, the option resCategory needs to be set true.

To consider capacity, volume or weight, the option resCapacity needs to be set true.

To consider qualification, the option resQualification needs to be set true.

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

{
"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 JSON-body of an assigned task when using a GeoCoord location looks like this:

{
"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,
1,2
],
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",
"performResetBeforeAtID": 2,
"finalassignedOrder": 3,
"group": 2,
}


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

Extension Parameter Required Type Description
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 when this task should be finished.
timePriority integer The priority of the time window ranging from 0-5. The default value is 1. Meanings: 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 any given 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 any given task.
description string DEPRECATED
prefWorkers Array<integer> The IDs of the preferred workers.
forbWorkers Array<integer> The IDs of the forbidden workers.
capacity double The capacity requirement of this task, which the assigned worker will need to provide.
weight double The weight requirement of this task, which the assigned worker will need to provide.
volume double 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.
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. Capacity reset durations are included!
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.
profit number The profit the task creates. WILL BE CHANGED TO NON-REQUIRED IN FUTURE UPDATE (TBA)
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.

categories, antiCategories and exchangeableCategories need to be disjoint sets. This means that a category appearing in categories may not appear in antiCategories or exchangeableCategories and vice versa. twinCategories represent a different set and does not share anything with the other three categories. The twinCategories are used to symbolize relations between tasks. To consider any category type, the option resCategory needs to be set true.

To consider capacity, volume or weight, the option resCapacity needs to be set true.

To consider qualification, the option resQualification needs to be set true.

## 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
}


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
}


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 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.
hoursPerWeek integer DEPRECATED
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).
capacity double The available capacity of the worker or their vehicle.
capacityInitial double The initially occupied capacity 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 double The available volume of the worker or their vehicle.
volumeInitial double The initially loaded volume on shift start of this worker or their vehicle.
weight double The weight the worker or their vehicle is able to handle.
weightInitial double The initially loaded weight on shift start of this worker or their vehicle.
finalCapacityResetThreshold double The capacity threshold at which a reset will be enforced before ending the shift.
finalVolumeResetThreshold double The volume threshold at which a reset will be enforced before ending the shift.
finalWeightResetThreshold double The weight threshold at 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> The task-categories preferred by the 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 salaray converted to minutes).

To consider any category type, the option resCategory needs to be set true.

To consider capacity, volume, weight, any *Initial or capacity resets, the option resCapacity needs to be set true.

To consider qualification, the option resQualification needs to be set true.

When no startLocation or endLocation 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.

## 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,
"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.
hoursPerWeek integer DEPRECATED
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).
capacity double The available capacity of the worker or their vehicle.
capacityInitial double The initially occupied capacity 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 double The available volume of the worker or their vehicle.
volumeInitial double The initially loaded volume on shift start of this worker or their vehicle.
weight double The weight the worker or their vehicle is able to handle.
weightInitial double The initially loaded weight on shift start of this worker or their vehicle.
finalCapacityResetThreshold double The capacity threshold at which a reset will be enforced before ending the shift.
finalVolumeResetThreshold double The volume threshold at which a reset will be enforced before ending the shift.
finalWeightResetThreshold double The weight threshold at 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> The task-categories preferred by the 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 salaray converted to minutes).
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. Capacity reset durations are included!
travelHomeDistance double 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.

## MixedPlanner-Statistics

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

{
"configuration": [
{
"label": "Kurze Wege",
"value": 0.777778
},
{
"label": "Arbeiterpräferenzen",
"value": 0.555556
},
{
"label": "Faire Verteilung",
"value": 0.444444
},
{
"label": "Clustering",
"value": 0.222222
},
{
"label": "Pünktlichkeit",
"value": 0.555556
},
{
"label": "Weniger Arbeiter",
"value": 0.111111
},
{
"label": "Reisezeit",
"value": 0
},
{
"label": "Arbeitszeit",
"value": 0
},
{
"label": "Geschlechterpräferenzen",
"value": 0
}
,
{
"label": "Profitabilität",
"value": 0
}
],
{
"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
},
...
],
{
"workerID": 1,
"time": 145
},
...
],
{
"workerID": 1,
"busyness": 0.3
},
...
],
"travelBusyness": [
{
"workerID": 1,
"busyness": 0.4
},
...
],
"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": 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).
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.

The parameter configuration contains the following fields which are translated based on the language setting:

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

The parameter workTimeDistribution contains the following fields which are translated based on the language setting:

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

## 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
}


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.
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.

Any 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,
"accuracyMode":1
}


The full JSON-body of metainformation looks like this:

{
"dateFrom":"2019-12-03",
"dateTo":"2019-12-03",
"resCategory": false,
"resQualification": false,
"accuracyMode":1,
"outputLanguage": 1,
"maxConsecutiveWorkdays": 6,
"minConsecutiveOffdays": 1,
"maxDailyWorkingMinutes": 1080
}


JSON-Schema

Parameter Type Required Description
dateFrom string (date) Planning horizont start (WIP, for common single day-plannings use $dateFrom = dateTo$).
dateTo string (date) Planning horizont end (WIP, for common single day-plannings use $dateFrom = dateTo$).
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 Generally set it to 1. Experimental feature: a value of 0 would bypass many optimization steps to deliver a fast but rough solution.
outputLanguage integer (languagetype) Defines which language should be used in the output (Default: German).
maxConsecutiveWorkdays integer Maximum number of consecutive work days.
minConsecutiveOffdays integer Minimum number of consecutive off days.
maxDailyWorkingMinutes integer Maximum number of working minutes per day.

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

• resCategories
• categories
• preferred categories
• preferred week categories
• preferred weekend categories
• resQualification
• qualification

## 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,
"workerReduction": 1,
"workTimeRelax": 0,
"genderPref": 2,
"profitability": 3
}


JSON-Schema

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 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.
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
0 Eco orientied
• genderPref: 4
• profitability: 9
1 Worker oriented
• fairDistribution: 9
• timeliness: 4
• workerPref: 4
• genderPref: 4
• profitability: 4
2 Customer oriented
• timeliness: 9
• workerPref: 7
• genderPref: 9
• profitability: 2
3 not used
4 Random The value timeliness is set to a random value 1 to 9. The values fairDistribution, workerPrefs, workerReduction, genderPref, profitability are set to a random value 0 to 9.

WIP

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

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


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

{
"date": "2019-12-03",
"duration": 240,
"timeEarliest": "06:00",
"timeLatest": "12:00",
"timePriority": 2,
"prefWorkers": [
1,2
],
"forbWorkers": [
3,4
],
"qualification": 3,
"categories": [
1
],
"preassignedWorker": 2,
"desiredWorker": 2,
"prefGender": 1,
"initassignedWorker": 1,
"initassignedOrder": 2,
1,2
],
1,2
],
"group": 2
}


The JSON-Schema of the unassigned shiftplanner 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
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 when this task should be finished.
timePriority integer The priority of the time window ranging from 0-5. The default value is 1. Meanings: 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.
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.
initassignedWorker integer The unique ID of the worker who will be initially assigned.
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.
group integer A group ID. Tasks with the same group ID get assigned to the same worker.

To consider categories, the option resCategory needs to be set true.

To consider qualification, the option resQualification needs to be set true.

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:

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


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

{
"date": "2019-12-03",
"duration": 240,
"timeEarliest": "06:00",
"timeLatest": "12:00",
"timePriority": 2,
"prefWorkers": [
1,2
],
"forbWorkers": [
3,4
],
"qualification": 3,
"categories": [
1
],
"preassignedWorker": 2,
"desiredWorker": 2,
"prefGender": 1,
"initassignedWorker": 1,
"initassignedOrder": 2,
1,2
],
1,2
],
"group": 2
}


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

Extension Parameter Required Type Description
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 when this task should be finished.
timePriority integer The priority of the time window ranging from 0-5. The default value is 1. Meanings: 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.
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.
initassignedWorker integer The unique ID of the worker who will be initially assigned.
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.
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.
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 within the assigned tour.

To consider any category type, the option resCategory needs to be set true.

To consider qualification, the option resQualification needs to be set true.

## 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"
}
],
"hoursExpected": 120,
"qualification": 1,
"prefConsecutiveWorkdays": 10,
"prefConsecutiveOffdays": 15,
"categories": [
1,2
],
"prefCategories": [
3
],
"prefWeekCategories": [
2
],
"prefWeekendCategories" : [
3
],
"prefWorkers": [
5,43
],
"gender": 1
}


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.
hoursExpected integer The number of expected worktime hours for this plan.
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.
shifts Array<Shift> The time slots at which a worker perform exactly one task.
gender integer (gender) The gender type of the 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"
}
],
"hoursExpected": 120,
"qualification": 1,
"prefConsecutiveWorkdays": 10,
"prefConsecutiveOffdays": 15,
"categories": [
1,2
],
"prefCategories": [
3
],
"prefWeekCategories": [
2
],
"prefWeekendCategories" : [
3
],
"prefWorkers": [
5,43
],
"gender": 1,
"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.
hoursExpected integer The number of expected worktime hours for this plan.
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.
shifts Array<Shift> The timeslots at which this worker can perform exactly one task each.
gender integer (gender) The gender type of the worker.
info string Some textual information about the worker.

## ShiftPlanner-Statistics

WIP

The JSON-body of statistics for a calculated plan

{
"configuration": [
{
"label": "Arbeiterpräferenzen",
"value": 0.555556
},
{
"label": "Faire Verteilung",
"value": 0.444444
},
{
"label": "Pünktlichkeit",
"value": 0.555556
},
{
"label": "Weniger Arbeiter",
"value": 0.111111
},
{
"label": "Arbeitszeit",
"value": 0
},
{
"label": "Geschlechterpräferenzen",
"value": 0
}
],
{
"workerID": 1,
"time": 145
},
...
],
{
"workerID": 1,
"busyness": 0.3
},
...
],
"workTimeDistribution": [
{
"type": "Arbeitszeit",
"time": 716
},
{
"type": "Puffer",
"time": 974
},
{
"type": "Schichtzeit",
"time": 1200
}
],
"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
}
],
"onTime": 96
}


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).
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$).
workTimeDistribution Array<Object<type: string, time: integer>> The time in minutes spent on different actions summed up.
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).
onTime integer Percentage for tasks scheduled perfectly inside the desired time windows ($0$ to $100$).

The parameter configuration contains the following fields which are translated based on the language setting:

German label English label Type Required
Arbeiterpräferenzen Worker Preferences number
Faire Verteilung Fair Distribution number
Pünktlichkeit Timeliness number
Weniger Arbeiter Worker Reduction number
Arbeitszeit Working Time number
Geschlechterpräferenzen Gender Preferences number

The parameter workTimeDistribution contains the following fields which are translated based on the language setting:

German type English type Type Required
Arbeitszeit Working Time integer
Schichtzeit Shift Time integer
Puffer Buffer integer

WIP

# 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({
});

const userData = {
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 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
},
{
"date": "2019-12-03",
"duration": 65,
"location": {
"lat": 50.878847,
"lng": 6.964728400000013
},
"timeEarliest": "10:00",
"timeLatest": "12:00"
},
{
"date": "2019-12-03",
"duration": 25,
"location": {
"lat": 50.9333412,
"lng": 6.972426400000018
},
"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
}
},
...
]
}


The JSON-schema is named unassigned plan

Parameter Required Type Description
request_id integer An id to identify the plan.
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/weights 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.

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

### ShiftPlanner-Request

WIP

An example for a request

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


The JSON-schema is named unassigned plan.

Parameter Required Type Description
request_id integer An id to identify the plan.
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/weights 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.
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

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

{
"request_id": "1",
"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"
}
],
{
"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": [
{
"label": "Kurze Wege",
"value": 0.777778
},
{
"label": "Arbeiterpräferenzen",
"value": 0.555556
},
{
"label": "Faire Verteilung",
"value": 0.444444
},
{
"label": "Clustering",
"value": 0.222222
},
{
"label": "Pünktlichkeit",
"value": 0.555556
},
{
"label": "Weniger Arbeiter",
"value": 0.111111
},
{
"label": "Reisezeit",
"value": 0
},
{
"label": "Arbeitszeit",
"value": 0
},
{
"label": "Geschlechterpräferenzen",
"value": 0
},
{
"label": "Profitabilität",
"value": 0
}
],
{
"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
},
...
],
{
"workerID": 1,
"time": 145
},
...
],
{
"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 named assigned plan

Parameter Required Type Description
request_id integer An 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/weights 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.
statistics statistics Some statistics about the plan.
info info Some textual information about the plan.

WIP

### Error-result

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

{
"request_id": "1",
"error_msg": " |-| ERROR: In den Eingabedaten fehlt ein geeigneter Mitarbeiter für Aufgabe #100 unter den gestatteten Mitarbeitern. Bitte entsprechenden Mitarbeiter bereitstellen oder Anforderungen in der Aufgabe anpassen. |-| contact email: support@adiutabyte.de",
"version": "1.0.0",
"type": "error",
"workerID": 3
}


The JSON-schema is named error plan

Parameter Required Type Description
request_id string Currently always set to "1".
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".
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 the language setting.

### Status-Codes

Number Code Description
200 OK The plan will be delivered.
406 NOT ACCEPTABLE The given Accept parameter in the header could not be used.
423 LOCKED The plan is currently optimized. Try again later to check if the calculation has finished.

# 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:

{
}

Parameter Type Description

### 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:

{
}

Parameter Type Description

### 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.