Suggest: times to schedule a job

Optimize resources, schedule, and dispatch a job using the optimize/resource_suggestions endpoint and GraphQL

The Suggest scheduling optimization feature proposes time/s to schedule a single job with a set of resources during a specified time range. This can be particularly useful for jobs that have specified time constraints (see Job time constraints for more information).

The /planr/optimize/suggest REST API endpoint requires the following fields in the request body:

Field Description Type
suggestForNode The UID of the job to be scheduled. String
resourceIds The UID/s of the available resources. You can include multiple resources in the Suggest query, with the UID for each resource separated with a comma. Array of IDs
scheduleStart Can be either ISO8601 date time string or Unix timestamp number ( in milliseconds ). Indicates the start of the time range to consider for job scheduling. String
scheduleEnd Can be either ISO8601 date time string or Unix timestamp number ( in milliseconds ). Indicates the end time of the job scheduling window. String

You can also specify schedulingOptions to add further constraints to your query. The following schedulingOptions are available:

Field Description Type Default
balanceWorkload Equalize total allocated duration including travel time for each resource. Boolean false
minimizeResources Attempt to allocate to the fewest number of resources in a scheduling window. Boolean false
jobTimeAsTimeConstraint When a job has a time set, consider it to be a time constraint and never reschedule to another time slot. Boolean true
preferJobTimeOverTimeConstraint When a job with a JobTimeConstraint also has a time set, consider the job time as the authoritative constraint and ignore the JobTimeConstraint. Boolean true
respectSchedule For a job that is allocated and in “Pending Dispatch” status, do not move the job to a different time. Boolean true
ignoreTravelTimes Ignore all travel times between resources and jobs. Boolean false
ignoreTravelTimeFirstJob Ignore travel time from a resource’ home location to the first job. Boolean false
ignoreTravelTimeLastJob Ignore travel time to the resource’ home location from the last job. Boolean false
padding A fixed interval of time between consecutive jobs. Integer 0
snapUnit Divide the given time frame into parts described by this value and allocate all jobs to the nearest part in seconds. Integer 0 (>=0)

Example: Suggest a time for a job, assign, and dispatch using REST and GraphQL

In the following example, we will use GraphQL and the /optimize/suggest REST API to find the best time to schedule a job. We will then update the job using GraphQL and dispatch it to the resource using the /notifications/dispatch endpoint.

The job we want to schedule has a 60 minute duration, it must be completed on Wednesday, we have three resources, and they already have jobs scheduled throughout that day:

Jobs already scheduled with three resources.

  1. Run a GraphQL query to obtain the UID for each of your resources:
query fetchResources {
  resources {
    edges {
      node {
        UID
        Name
      }
    }
  }
}

 2. Send a POST request to the /planr/optimize/suggest endpoint to find what times your resources are available to complete the job during the required scheduling window.

The example request body includes the following information:

  • The resourceIds of our three resources.
  • The scheduleStart and scheduleEnd of the scheduling window in ISO 8601 format.
  • The balanceWorkload option is enabled.
  • We’ve allowed 5 minutes of padding between jobs.
query fetchResources {
  resources {
    edges {
      node {
        UID
        Name
      }
    }
  }
}

The response returns the following result:

{
  "result": {
    "routes": {
      "0005a7e9-b1aa-44da-937f-310b921b75cc": {
        "resourceId": "0005a7e9-b1aa-44da-937f-310b921b75cc",
        "score": {
          "hard": 0,
          "medium": 0,
          "soft": -153
        },
        "route": {
          "jobId": "0014b2b8-6543-4d3a-b39f-91d9ccadb12f",
          "jobName": "JOB-0023",
          "start": "2019-07-17T06:10:00.000Z",
          "duration": 60,
          "travelTime": 7,
          "type": "job"
        },
        "gapList": [
          {
            "fromPrev": {
              "travelTime": 7
            },
            "interval": {
              "start": "2019-07-17T06:10:00.000Z",
              "end": "2019-07-17T07:10:00.000Z"
            },
            "toNext": {
              "travelTime": 0
            }
          }
        ],
        "isAllocated": false
      },
      "000520bd-63a1-47a0-9c80-9a343cb35ec6": {
        "resourceId": "000520bd-63a1-47a0-9c80-9a343cb35ec6",
        "score": {
          "hard": 0,
          "medium": 0,
          "soft": -180
        },
        "route": {
          "jobId": "0014b2b8-6543-4d3a-b39f-91d9ccadb12f",
          "jobName": "JOB-0023",
          "start": "2019-07-17T04:37:00.000Z",
          "duration": 60,
          "travelTime": 18,
          "type": "job"
        },
        "gapList": [
          {
            "fromPrev": {
              "travelTime": 18
            },
            "interval": {
              "start": "2019-07-17T04:37:00.000Z",
              "end": "2019-07-17T05:37:00.000Z"
            },
            "toNext": {
              "travelTime": 0
            }
          }
        ],
        "isAllocated": false
      }
    }
  }
}

From the result, we can see that there are two resources available on Wednesday that can complete the job. The results are shown in order of who can complete the job first.

 
3. Allocate one of the resources to the job update the start and end times using a GraphQL query.

In this example, we are going to assign the job to the first resource returned in the /optimize/suggest query, schedule, and dispatch it using GraphQL:

mutation saveSuggestResult {
  schema {
    updateJobs(input: {
      UID: "0014b2b8-6543-4d3a-b39f-91d9ccadb12f"
      Start:"2019-07-17T06:10:00.000Z"
      End: "2019-07-17T07:10:00.000Z"
      Duration: 60
    })
    insertJobAllocations(input: {
      JobId: "0014b2b8-6543-4d3a-b39f-91d9ccadb12f"
      ResourceId: "0005a7e9-b1aa-44da-937f-310b921b75cc"
      Status: "Dispatched"
    })
  }
}

The result indicates that the updateJobs request to schedule the job and the insertJobAllocations request to assign the job to a resource and dispatch it were both successful:

{
  "data": {
    "schema": {
      "updateJobs": "0014b2b8-6543-4d3a-b39f-91d9ccadb12f",
      "insertJobAllocations": "0018e28b-88a4-4687-8c5c-6ad5e5f2f1b4"
    }
  }
}

4. Open the job in the Skedulo web application Scheduling page to see that it has been scheduled and dispatched:

Suggest job scheduled and dispatched.