AI-based Scheduling



Intro

Attention: AI-based optimization and scheduling only works for internal technicians. Crowd is currently not supported.

Looking to optimize your field service according to your specific requirements? Want to minimize driving distances so that your technicians can hit more jobs per day?

SAP Field Service Management offers a flexible framework for automated planning and optimization that caters to the individual requirements and use cases of each customer.

The framework accepts plugins to contain individually tailored target functions that rate how well a technician is suitable for a job. The target functions can be written by the customers themselves.

This enables the customers to programmatically reflect all criteria that are relevant for planning and optimization of the field service activities, such as:

  • Distance between the current location of the technician and the planned job
  • the next available timeslot
  • if a technician is familiar with the customer and their equipment, etc.

It is up to the customer to consider multiple factors and weigh them out against each other (as soft vs. hard constraints) in the target function.

Not sure how to start and want to try an out-of-the-box solution? Use our standard plugins to optimize the following:

  • by distance to the job (nearest)
  • find the first available technician (fastest)
  • or the one with the most adequate skill set (best).

Note: As of today, plugins are deployed individually for every customer.


A Closer Look

Typically, there are three common cases addressed by automation:

  1. Scheduling of a job upon creation
  2. Periodic re-optimization of the entire board
  3. Rescheduling of overlapping jobs and reservations, e.g. urgent jobs, sick leaves, and so on.

Within SAP Field Service Management, automatic scheduling can be triggered by a business rule. It can also be triggered externally, for example by an external service or lambda function (additional provisioning resides with the customer).

To trigger scheduling and optimization externally, refer to Re-Optimization API.


Business Rules

Within a business rule, the following is specified:

Business Rule Component Description
Trigger Specifies when scheduling/optimization will be executed.
SQL statement Specifies which data (jobs and technicians) will be affected.
Partitioning strategy Specifies the parameters by which jobs and technicians are being divided into logical units to run scheduling and optimization for the unit. Learn more here.
Plugin to be used Specifies which of the available plugins will be used for scheduling.

The business rules will be configured per company.

You must configure the trigger of the business rule to schedule either periodic or event-based optimization.

Configure the following actions:

  • first, for receiving an authorization token
  • second, to define the list of activities to be reoptimized, the partitioning strategy, and the plugin to be used

For Action #0:

  • select Action Webhook
  • select Method POST
  • maintain URL according to the following pattern: https://<cluster>.coresystems.net/<api>/oauth2/<v>/token
  • maintain Content type:/x-www-form-urlencoded
  • maintain Body according to the following pattern: grant_type=client_credentials
  • maintain Response Variable Name: accessToken

For Action #1:

  • select Action Webhook
  • select Method POST
  • maintain URL: https://<cluster>.coresystems.net/dispatchservice/api/autoscheduler/v1/actions/re-optimize
  • maintain Content type: application/json
  • maintain Body according to the following pattern:

{ "activityIds": [<comma separated list of activity IDs, as strings>], "optimizationPlugin": "<name of the default plugin from the ones deployed for the company>", "start": "${moment().add(1, 'hour').toISOString()}", "end": "<end of the time span to be reoptimized - use the pattern for the start>", "partitioningStrategy": { "name": "<parameter for the partitioning strategy if needed>", "<parameter name>": [ "<instance 1 name>", "<instance 2 name>" ] } }

  • maintain Response Variable Name: reOptimizeResponse

Note: for multiple use cases (that is automated scheduling upon job creation, periodic rescheduling, rescheduling of overlapping jobs), multiple business rules will need to be configured.

To start with the optimizer and take a look at sample business rules, visit Business Rules for Optimization guide.


Plugins

Once there is a new event that triggers a business rule, scheduling and optimization is started according to the parameters specified in the selected plugin. There are standard plugins that can be utilized by the customers.

Rank by Earliest Start

The difference between a constant and the difference between proposed start and job earliest start is returned. A quotient could also be used, the difference being used for ease of interpretation. The assignments which start earlier will be returned on top of the list.

As a result, the plugin considers technicians’ availability and location to figure which technicians can be at the location of the job sooner. It calculates the difference between the earliest start date for the job the earliest possible start for each technician. Technicians’ assignments and current locations are therefore considered when each of them would be available and be able to arrive at the destination of the job.

The technician with the lowest difference between a job’s maintained earliest start date and the planned start date for the technician receives the highest score. Should multiple technicians have the same score, the assignment will be undefined since no other criteria is considered by the plugin.

**IMPORTANT NOTE: by default in Best Match UI, technicians’ scheduled jobs are not considered by the plugin. Thus, only the availability defined by the work time pattern and driving time is considered. In order to avoid assigning a job to a technician who is booked, ensure that “Include booked technicians” is not selected.

Name: Quickest

public Integer score(IResource resource, IJob job, IAssignment assignment, ILocation location) {
     return 1000 - (int)(
         (assignment.getStartDate().getTime() - job.getEarliestStartDate().getTime()) / (1000 * 60));
}

Rank by Distance to the Next Assignment

The difference between a constant and the distance is returned, as a measure of proximity. A quotient could also be used, the difference being used for readability.

As a result, the plugin considers the location of the job in question as a constant. The current location of the technician is considered to calculate the driving time for the technician. The technician with the shortest driving time to the job gets the highest score. Should multiple technicians have the same score, the assignment will be undefined since no other criteria is considered by the plugin.

The current location of the technician is determined by:

  • The address of the job that the technician is or will be performing prior to the job in question.
  • The default address of the technician. In case the job in question is considered as first job in the morning or in case the technician does not have any prior jobs.

The default address is usually the home address or office address if home address not available. Default address is set in the Master Data application for the Person DTO.

Name: Nearest

public Integer score(IResource resource, IJob job, IAssignment assignment, ILocation location) {
    return location != null && job.getLocation() != null ? (600 - OptimizerLibrary.travelTimeInMinutes(job.getLocation(), location)) : -1;
}

Rank by Overlapping Skills

This plugin counts the size of the set containing the skills both in the job and resource. The plugin ranks technicians in descending order based on their skillset. Both mandatory and optional skills are considered. Technicians whose skillsets overlap completely with the mandatory and optional requirement on the job get the highest score. Technicians that have none of the skills required for the job get the lowest score.

In case of automated planning, technician with the highest score gets assigned to the job. Should multiple technicians have the same score the assignment will be undefined since no other criteria is considered by the plugin. Optional skills are also considered by the formula, but with a lower order of relevance.

Name: Best

public Integer score(IResource resource, IJob job, IAssignment assignment, ILocation location) {
    double requiredSkillsOnActivity = job.getRequirements().size();
    double optionalSkillsOnActivity = job.getOptionalRequirements().size();
 
    if (requiredSkillsOnActivity + optionalSkillsOnActivity == 0) {
        return 100;
    }
 
    List<String> resourceSkills = resource.getSkills();
    List<String> matchingSkills = job.getRequirements().stream().filter(elem -> resourceSkills.contains(elem)).collect(Collectors.toList());
    List<String> matchingOptionalSkills =  job.getOptionalRequirements().stream().filter(elem -> resourceSkills.contains(elem)).collect(Collectors.toList());
 
    double requiredSkillsMatched = matchingSkills.size();
    double optionalSkillsMatched = matchingOptionalSkills.size();
 
    if (optionalSkillsOnActivity == 0) {
        return (int) Math.ceil((requiredSkillsMatched / requiredSkillsOnActivity) * 100);
    } else if (requiredSkillsOnActivity == 0) {
        return (int) Math.ceil((optionalSkillsMatched / optionalSkillsOnActivity) * 100);
    } else {
        return (int) Math.ceil((((requiredSkillsMatched / requiredSkillsOnActivity)
                + ((optionalSkillsMatched / optionalSkillsOnActivity) / (requiredSkillsMatched + 1)))
                * ((requiredSkillsMatched + 1) / (requiredSkillsOnActivity + 2))) * 100);
    }
}

Rank by Overlapping Skills and Distance

This plugin filters out technicians with missing skills or the ones that have refused the job (hence, are ineligible for the job). This plugin does not consider technicians or jobs which do not have a location, and sorts the remaining technicians by the shortest travel time.

The plugin first reduces the list of technicians to be considered for the job using the following prerequisites:

  • Possess all mandatory skills that are required for the job.
  • Have an address (either their default address - can be a home address or an office address - if the job is considered as first job in the morning, or the address of a previous job).
  • Have not rejected the job previously, which would make them ineligible for the job. (Works exclusively in a Crowd context. For non-crowd companies, a User Defined Field should be used to store IDs of ineligible technicians and a custom plugin must be built to interpret the blacklist values.)

The plugin also filters out the jobs that don’t have an address. Consequently, those will be left out of automated scheduling.

IMPORTANT NOTE: an address is considered valid by the autoscheduler if it has valid geocoordinates

Lastly, the plugin sorts technicians that fulfill the requirements listed above by the driving time to the job. The technician with the shortest driving time gets assigned to the job.

Name: SkillsAndDistance

public Integer score(IResource resource, IJob job, IAssignment assignment, ILocation location) {
    List<String> resourceSkills = resource.getSkills();
    List<String> jobRequirements = job.getRequirements();
    List<String> missingSkills = jobRequirements.stream().filter(elem -> !resourceSkills.contains(elem)).collect(Collectors.toList());
 
    if(missingSkills != null && missingSkills.size() > 0) {
      OptimizerLibrary.logScore(job, resource, -1, "Technician does not have the following mandatory skills: " + missingSkills);
      return -1;
    }
 
    else if (job.getResourceBlackList() != null && job.getResourceBlackList().contains(resource.getFSMId())) {
       OptimizerLibrary.logScore(job, resource, -1, "Technician is blacklisted for this job.");
       return -1;
    }
 
    else if(job.getLocation() == null) {
        OptimizerLibrary.logScore(job, resource, -1, "Job does not have location set.");
        return -1;
    }
 
    else if(location == null) {
        OptimizerLibrary.logScore(job, resource, -1, "Resource or previous job does not have location set.");
        return -1;
    }
 
    else {
        return (600 - OptimizerLibrary.travelTimeInMinutes(job.getLocation(), location));
    }
}

Customers are free to define their own plugins to address their specific use cases (multiple parameters can be considered within the plugin).

IMPORTANT NOTE: customers shall be guided through definition of their custom plugins. The plugins will be deployed for every customer individually.


Partitioning

For many businesses, field service activities are executed according to divisions within a company (for example: based on work centers, regions, etc.). Optimizing the planning board on a company level is, as a result, insufficient. To address those requirements, a partitioning strategy can be defined (for detailed instructions, please refer to the following guide.)

When a partitioning strategy is maintained, an optimization process is triggered per partition. That means jobs and technicians that belong to the same partition will be optimized together - hence, jobs from partition A can only be assigned to technicians that work in partition A. A job can only belong to one partition, while a technician can work for different partitions. Should that be the case, a technician can be assigned jobs from both partitions. In a custom plugin, customers can specify the specific criteria for handling different partitions (for example, a technician might have a primary partition and secondary partitions). Different partitions will be optimized in parallel (currently, only sequential optimization is supported).

Currently, partitioning can be done based on skills. In order for partitioning to work, relevant skills have to be maintained on jobs and technicians as well as specified in the body of the business rule in the partitioning strategy section:

{
	"activityIds": ["${var x=[]; activities.forEach(function(a) { x.push(a.id); }); x.join('\",\"')}"],
	"optimizationPlugin": "Nearest",
	"start": "${moment().add(1, 'hour').toISOString()}",
	"end":  "<end of the time span to be reoptimized - use the pattern for the start>",
	"partitioningStrategy": {
		"name": "Skill",
		"skills": [
			"skill name 2",
			"skill name 1"
		]
	}
}

IMPORTANT NOTE: in the context of optimization, skills are just a technical representation of partitions. The semantic meaning of partition-relevant skills can be anything. Thus, data can be partitioned based on: regions, work or service centers, teams, team leads, and so on. Often, companies use geographical criteria for their partitioning strategy, so partitioning would be region-based. For instance, for Germany, example partitions could be: Berlin, Hamburg, Stuttgart, Cologne, Munich. In that case, both jobs and technicians would have corresponding skills assigned (Berlin, Hamburg, Stuttgart, Cologne, Munich). Alternatively, the partitioning strategy can be based on service divisions. In the case of a household device manufacturer, partitions can be: washing machine specialists, dishwasher specialists, TV sets specialists, and so on. Here, partitioning relevant skills will be: Washing machines, Dishwasher, TV sets, etc.

Best practices suggest that the granularity level of individual teams is most appropriate for a partitioning strategy. For details on the recommended amount of data per partition, please refer to Constraints and Limitations


Equipment

In Business-to-Business line of work, field service technicians often deal with several machines that are located at the same geographical address. Thus, equipment data is relevant for scheduling of field service activities. Equipment data can now be exposed to custom plugins to be utilized for planning purposes. This way, if needed, jobs can be bundled together not only based on the geographical address, but also based on equipment located at this address. So that a technician would first perform all jobs on one piece of equipment before moving to the next one.

Certain types of jobs can be taken care of simultaneously. For instance, a major repair of the equipment that implies that the equipment has to be taken apart can be combined with an upcoming maintenance or inspection. To attend to this requirement, it is possible to schedule jobs in parallel. That means, several jobs will be assigned for the same time slot to the same technician. The duration of the longest job will determine the length of the time slot. The criteria based on which the optimizer determines which jobs are to be scheduled in parallel will be described in a custom plugin. For instance, all jobs for the same piece of equipment that are sent to the optimizer can be scheduled in parallel; alternatively, the customer can define that only sent jobs of certain type that belong to the same equipment would be scheduled in parallel.


Job Status and Due Date

Oftentimes, automated scheduling of jobs happens in bulk right after creation or replication of jobs into SAP Field Service Management. Only after having been scheduled, the jobs are released to the field technicians. However, sometimes, there are events - like receiving of an urgent job - that compromise the existing schedule and require rescheduling of already scheduled and released jobs. Now, autoscheduler can also reschedule jobs that already have a status “Released”.

Furthermore, after the autoscheduler has assigned jobs to technicians the assignments are automatically released so that there is no need for the dispatcher to manually release the jobs to field technicians. This configuration option can be switched off so that there is no automatic release of the jobs when autoscheduler has assigned technicians to all jobs. This can be done by passing this parameter in the business rule.

**IMPORTANT NOTE: for the name of the parameter, please refer to the Swagger Specification.

Additionally, the autoscheduler considers jobs that are due in the future as well as jobs on which the deadline has been missed. The due date no longer has to be in the future - jobs with the missed deadline are scheduled along with the ones that are due in the future. However, there is no special treatment of the jobs with a missed deadline. Special handling of the jobs that were due in the past should be considered in a custom plugin.


UDFs in plugins

When writing a custom plugin for optimization of the planning board, you can consider User Defined Fields introduced to your master data.

As of the 2002 release, User Defined Fields are supported for the following data transfer objects:

  • ServiceCall
  • Activity
  • Person
  • Skill
  • Equipment

Optimization can be run based on any parameter that is relevant for a specific use case. For example, to consider technicians’ ratings, a dedicated UDF will have to be added to the technician. The field would have to be addressed in the plugin, for example as follows:

import java.util.List;
import java.util.ArrayList;
import net.coresystems.autoscheduler.domain.interfaces.*;
import net.coresystems.autoscheduler.service.spatial.EuclideanDistanceService;
import java.util.stream.Collectors;
import net.coresystems.autoscheduler.service.optimize.OptimizerLibrary;

public class Plugin implements IOptimizationPlugin {
    public net.coresystems.autoscheduler.domain.Algorithm getAlgorithm() {
        return net.coresystems.autoscheduler.domain.Algorithm.GREEDY_RESOURCES_FIRST;
    }

    public List<IResource> filterResources(List<IResource> resources) {
        return new ArrayList();
    }

    public Integer score(IResource resource, IJob job, IAssignment assignment, ILocation location) {

        Integer resourceRating = resource.getUDFValue("RATING") != null ? Integer.valueOf(resource.getUDFValue("RATING")): null;
        if (resourceRating == null) {
           return 0;
        }

        return resourceRating;
    }
}

Live Location

While out in the field, technicians can share their live location. This can be utilized by the autoscheduler for route calculation. This is of high importance in cases when scheduling happens during the workday. For example, if a technician cannot tend to his jobs and his urgent work has to be assigned to other technicians to be performed as soon as possible.

To use live location for scheduling, the following criteria have to be fulfilled:

  • Live location tracking needs to be configured for technicians as described in the Auto-Location guide
  • Company Setting CoreSystems.Optimization.EnableRealTimeLocation set to TRUE
  • CoreSystems.Optimization.RealTimeLocationThresholdInMinutes set to a positive integer number.

If the settings are configured, the location is synchronized automatically when the technician is online. Threshold in minutes defines the maximum duration that optimizer will use the live location. If the technician is offline and location cannot be synchronised for a longer time than defined in the threshold, the autoscheduler falls back to the Dispatching Board as default. In the absence of a valid real time location, the location of the current/latest job that was assigned to the technician is taken. Should there be no assignment for the current moment and no previous job, the default address of the technician will be taken as a starting point for the route calculation.


Routing

Automated planning is trying to optimize technicians’ schedules, while complying with customer-specific planning criteria represented as a plugin. This means that technicians’ routes are optimized to the extent the plugins allow.

Travel time plays an important role in this. Travel time is calculated based on the distance to be driven and the recommended speed on each part of the road. That works as follows.

Within SAP Field Service Management, there is a dedicated service for calculation of the driving distance and travel time derived from that. As an input, geocoordinates of each individual address are taken (both technicians’ and jobs’ addresses). SAP Field Service Management uses Opens Street Maps, an open source, Google Maps-like software, to take snapshots of the world-wide road networks with recommended speed for each type of road. When optimization is triggered, the service receives geocoordinates of all available addresses, places it on the map and calculates the distance between all individual addresses and the corresponding driving time (derived from the distance between the addresses and the recommended speed for each type of road involved).

The driving time is computed using the road network considering the speed of the particular road. The following profile is used:

Road Speed KpH Speed MpH
Motorway 90 56
Secondary 55 34
Tertiary 45 28
Residential 25 16

The driving times are assigned to jobs as follows:

  • On first job of day, it is assumed the technician drives from home (or work address, if home not available)
  • From every subsequent job, the driving distance to the job (from the previous job) is assigned to the job itself. These jobs will have the value in the drive from field unchanged.

As an output, the service returns a matrix containing distances and driving times between all addresses. The driving time is considered by the autoscheduling framework when scoring possible job assignments.


Time Zone Handling

When scheduling jobs in multiple countries and time zones, autoscheduling framework automatically deals with the necessary conversion without any need for the user to adjust or configure the APIs. Determination of the time zone happens automatically and cannot be manually overwritten. Time zone of the job is automatically derived from the geospatial coordinates of the job’s address. In the case when the job does not have a valid address, a timezone can be given in some API endpoints. This is used as a fallback, for example, in the Best Match API, by the timezoneid field. In the Best Match form the UI, the timezone of user is sent as fallback. The autoscheduling framework assumes that the technician is going to work in the jobs time zone, which can be different from the technicians time zone. This means that for the automated planning the technicians time zone is not going be considered, which can lead to a distortion in the way how a job is displayed in the Dispatching Board. Let’s consider a rare scenario when technicians would cross national borders to perform a job and enter a time zone that is different from their own by one hour (e.g. -1h). In this case the autoscheduler would apply the technician’s work time pattern to the time zone of the job. However, in the Dispatching board, the time zone of the technician’s default address will be used, leading to the jobs being displayed with an one hour distortion. On the Board, it will look like the technician has one hour idle time at the beginning of the day and is ending the day one hour outside his working time. Such cases are usually rare. Most of the time technicians are scheduled for jobs within their own time zone.


Constraints and limitations

The Autoscheduling framework has a number of constraints and limitations imposed by the services used as well as the business scenarios served.

Constraints

The most important constraints are the ones relevant for geolocation:

  • Geocoding: all addresses (of jobs and technicians) have to have geocoding in place since the input provided to the service are geographical coordinates - not the addresses themselves. If geocoordinates of a job are missing or invalid the job is not considered by the optimizer. If a technician does not have an address with valid coordinates, travel time for the first job of the day shall not be calculcated for them. Instead, the default travel time is taken (currently, 0 minutes).
  • Accessibility: jobs have to be reachable for technicians by driving. Should driving time to a job exceed a day no technicians are assigned to the job
  • Earliest start date: the autoscheduler will only schedule jobs for dates starting after the maintained earliest start date, even if the scheduling takes place before this date
  • Work time pattern: by default, jobs will only be scheduled within the valid work time pattern of the technician. This means, jobs will only be scheduled within the configured working time. Lunch breaks will be respected. However, in a custom plugin, customers can have an option to break the constraint of the work time pattern and extend the duration of the job beyond working time. That means, a job can start within a work time pattern and end outside of it. The rules for planning behavior are to be established in a custom plugin.

    IMPORTANT NOTE: currently, the autoscheduling framework does not support splitting of jobs to accommodate interruptions, like reservations or lunch breaks. Thus, in order for a job to be scheduled it should fit into a technician’s working time without interruptions. That means, a job cannot start prior to lunch break and end after it. If the job is not fitting into the slot before the lunch break it will only be scheduled after lunch (assuming there is a sufficiently long slot to accommodate the job including driving time). The time before lunch will either be filled with a shorter job or remain idle time.


Limitations

Driving Time Calculation

Limitations of the autoscheduling framework are primarily originating from the driving time calculation.

Since snapshots of road networks are taken periodically:

  • The service only calculates driving times. There is no functionality to consider any other ways of travelling, such as using public transportation.
  • There is no consideration of historical traffic data (that is usual times and spots of traffic jams).
  • There is no consideration of live traffic data (that is current traffic jams, construction sites, and so on).

Technical Constraints

On the side of technical constraints, the following limits are applied to partition sizing:

  • 1500 jobs (Activities)
  • 15 technicians

This means for the optimization performed for each partition only the above mentioned amounts of data can be sent to the autoscheduler to be processed. Scheduling of partitions of larger sizes can lead to noticeable performance degradation.


Troubleshooting

Business Rule Execution isn’t Finished

The Business Rule execution log has forbidden or host not found:

  • When adapting the sample business rule, check that all variables are correctly replaced. In particular, the and the client indentifiers and secrets.
  • For debugging purposes we recommended to send the request to Optimize API in a message to your own email.

Jobs aren’t Scheduled

Oftentimes, the issues reside within the data. To make sure optimization runs check for data requirements:

  • All activities sent to the optimizer must have an address with valid geographical coordinates. If the activity does not have a geocoded address it will be excluded from the optimization.
  • All activities must be in a plannable state, they cannot be in cancelled state. For that, check the field Status on the Service Call or the field Stage on the Activity. If the Status is Cancelled, the assignment of the job to a technician is not going to be executed.

Jobs are scheduled for the non-working time

On rare occasions (mostly characteristic for demo scenarios) jobs can be scheduled automatically outside of the working time of technicians that is defined by their work time pattern. Should that occur, the time zones of technicians and jobs need to be compared. Since autoscheduler automatically determines the time zone based on the geocoding and takes jobs’ time zones as leading, a distorted depiction of technician’s assignments on the Dispatching Board can occur. The analysis will reveal that the difference in time zones can be attributed to that.


Additional Information

For additional information regarding the Re-Optimization API documentation. please refer to the following:

Re-Optimization API

To try optimization using sample business rules (not meant for productive usage) please refer to the following:

Sample Business Rules