OTM5 Trips

Structure of the OTM trip

Within Simacan the trip is the most important entity and is the top-level entity in most of our OTM based APIs. It is used in the OTM5 planning intake, and planning/realisation/ETA push services. Though the use cases might be different, the trip always has the same general structure.

The general structure is as follows:

trip
  uuid (unique ID that is used for identifying the trip & future for updates)
  name (the display name)
  externalAttributes
  status (only there when cancelled, actions are then empty)
  actors (shipper, carrier, subcontractor, driver)
  vehicle
  actions
    stop
      location
        start and end times
      actions
        wait/break
        load/unload
          consignment
            goods
    move
      from (location reference)
      to (location reference)
      actions
        wait/break
        move (first/last mile)
    stop
    ...

Trip

As mentioned before, the trip is the top-level entity and ties together all information that is relevant for all visiting multiple locations and loading and unloading consignments on those locations.

A trip has the following properties:

  • The trip has a unique UUID that is used to identify this particular trip. This UUID is thus also used whenever the trip needs updates. Since not all planning systems work with UUIDs, it is optional. When not present the tripId in the external attributes will be used to deterministically generate a UUID.
  • A trip has an optional name (display name), which is to easily recognize it in the Control Tower. Note though that is doesn't have to be unique but usually is for a single day to differentiate trips on that day.
  • A trip optionally has externalAttributes , these are also known as customer data and do not serve a role on the Simacan platform, but can be used for grouping trips and shared with other parties where they might be essential. When receiving trips from the Simacan platform these external attributes also contain enriched data from the platform.
  • A trip at some point needs to be coupled to a vehicle for effective monitoring.
  • A trip is required to have actions : at least two stops are necessary. The one notably exception is when cancelling a trip. No actions are shared for cancelled trips.
  • A trip is required to have actors , usually a shipper and a carrier, but also a driver and subcontractor are possible.

Here is a basic example (that will be fleshed out):

Copy
Copied
{
  "id": "2a8af6c6-e4d5-5dfb-9532-e8b17c3ffd88",
  "name": "2021-32-2-ABC",
  "externalAttributes": {
    "shift": "morning shift",
    "tripId": "external-system-id"
  },
  "vehicle": {},
  "actors": [],
  "actions": []
}

Actors

Actors are organisations or individuals that have a role in the logistic operation. Within Simacan they can appear on the trip (shipper, carrier, subcontractor, driver), or on the consignment (consignee, consignor). The shipper and carrier are always expected on the trip level. The driver is optional, as are the consignor and consignee on the consignment.

Actors have the following properties:

  • An actor has a display name .
  • An actor has a unique Simacan identifier ( code ).
  • An actor has one or multiple roles .
Copy
Copied
  "actors": [
    {
      "entity": {
        "id": "9ade6709-d76a-5406-883a-85c7df10fded",
        "name": "Display name carrier",
        "externalAttributes": {
          "externalId": "unique_id_carrier"
        }
      },
      "roles": [ "carrier" ],
      "associationType": "inline"
    },
    {
      "entity": {
        "id": "9ade6709-d76a-5406-883a-85c7df10fded",
        "name": "Display name shipper",
        "externalAttributes": {
          "externalId": "unique_id_shipper"
        }
      },
      "roles": [ "shipper" ],
      "associationType": "inline"
    },
    ...
  ]

Vehicle/Sensor data

Ultimately a trip needs to be coupled to a vehicle to be able to be executed. However, for effective monitoring Simacan actually doesn't need the vehicle, since it also suffices to provide the device that is placed in the vehicle and emits the location updates. This device can be part of a vehicle (or the tracking unit attached to the vehicle), but it also could be the phone of the driver. Within OTM both these situations are modeled using the vehicle, possibly in the combination with a sensor.

Note that OTM distinguishes towing and towed 'vehicles' by modeling the latter as transportEquipment and not vehicles, so the vehicle field only contains information about the towing vehicle.

A vehicle contains the following properties:

  • A vehicle is a physical machine with cargo space able to transport goods.
  • Possibly a sensor is placed within that vehicle (OTM5 supports multiple sensors in a vehicle, but within Simacan we support only one).
  • The vehicle can contain properties such as fuel (type), licensePlate and vehicleType .
  • The vehicle might contain a unique identifier in the external attributes.
  • The vehicle does not contain any information about trailers. This information is added in the actions of the trip.
Copy
Copied
    "vehicle": {
      "entity": {
        "id": "3de444dd-81cf-4e69-b27b-82e92e0dbda3",
        "externalAttributes": {
          "vehicleId": "my-external-id"
        },
        "vehicleType": "truck",
        "fuel": "Euro95",
        "licensePlate": "AA-12-BB",
        "sensors": [{
           "associationType": "inline",
           "entity": {
               "id": "6827dac5-776e-4474-a927-0cf695b4d9d3",
               "externalAttributes": {
                   "sensorId": "id-of-the-device-in-the-vehicle",
                   "systemId": "system-of-the-fms-device"
               }
           }
        }]
      },
      "associationType": "inline"
    }

Actions

The most interesting information of the trip is present in the actions. These contain the locations that need to be visited, when, and what happens on those locations. Actions consists of stops and moves. Stops contain the information of visiting a location between certain time intervals and doing other actions on that locations such as loading and unloading consignments. Moves contain the information of moving between the locations of a stop. On these moves other actions can be done as well, such as having a break, or following a specific route (first/last miles). Naturally, the actions of a trip thus always start and end with a stop, with moves in between. However, depending on the use case, moves are left out since they do not contain any relevant information.

Stop

A stop indicates visiting a location within a time interval and doing actions on that location. It consists of the following properties:

  • A stop has a location , startTime and an endTime .
  • A stop can have multiple load and unload actions; these actions have a consignment .
  • A stop optionally has a display name , remark and sequenceNr .
  • A stop optionally has a stopId within an externalAttribute , this identifier can be used for updating this stop. If none is present the UUID of the stop will be used.
  • A stop can be cancelled . Unlike the trip the stop will simply not appear in future messages.
  • A stop can be marked administrative . This means the stop is only their for administrative purposes and is not actively monitored in the Control Tower. These stops do not have ETAs and are not actively visited. This information is provided in the externalAttributes of the stop by having a key-value pair "monitoring": "administrative" . Non-administrative stops will simply not have such an attribute.
  • A stop optionally has time constraints, wich in code looks like:
    Copy
    Copied
    {
      "id": "48c484f7-54ad-4209-b251-44abef26f6b0",
      "value": {
          "startTime": "2021-03-12T10:00:00Z",
          "endTime": "2021-03-12T11:00:00Z",
          "type": "timeWindowsConstraint"
      }
    }

A stop (with omitted location and consignment) could look like:

Copy
Copied
{
    "entity": {
        "id": "cd5be9b4-eb2e-50c1-bac9-d78d159c9d8e",
        "lifecycle": "planned",
        "externalAttributes": {
            "stopId": "stop123"
        },
        "location": {},
        "startTime": "2021-02-24T08:00:00Z",
        "endTime": "2021-02-24T08:20:00Z",
        "actions": [{
                "entity": {
                    "id": "85a48825-0d59-328b-b571-e3283a1f7fe7",
                    "lifecycle": "planned",
                    "consignment": {},
                    "startTime": "2021-02-24T08:00:00Z",
                    "endTime": "2021-02-24T08:15:00Z",
                    "actionType": "unload"
                },
                "associationType": "inline"
            },
            {
                "entity": {
                    "id": "b7a632a2-4f2b-4efb-b75c-17132436cf39",
                    "lifecycle": "planned",
                    "consignment": {},
                    "startTime": "2021-02-24T08:15:00Z",
                    "endTime": "2021-02-24T08:20:00Z",
                    "actionType": "load"
                },
                "associationType": "inline"
            }
        ],
        "sequenceNumber": 0,
        "constraint": {
            "entity": {
                "id": "10877d0c-ca94-459b-84aa-0cf10de35af6",
                "value": {
                    "startTime": "2021-02-24T07:30:00Z",
                    "endTime": "2021-02-24T09:30:00Z",
                    "type": "timeWindowConstraint"
                },
                "associationType": "inline"
            },
            "actionType": "stop"
        }
    }
}

Move

Moves model going from one location to another. Generally, this is usually not that interesting, because a list op stops implicitly model the same thing (the move is implied in between two stops). Therefore moves are only recommended whenever they contain additional information, such as having a planned break in between two stops, or whenever a very specific route must be used for a part of travelling between the two locations.

Moves have the following properties:

  • Moves have a from and to location, which are always references (locations are inlined on the stops).
  • Moves have optional actions. The actions within move s supported within the Simacan platform are the wait , break and move actions. Moves on move action imply first or last miles. Whether it is the former or the latter is implied in the name of the inner move. Next to (optional) from and to locations the inner move contains a route. The route is always represented using the GeoJson LineString .

An example move with last mile and break could look like this:

Copy
Copied
    {
      "entity": {
        "id": "0d5fde19-a436-3a69-8d7a-16217c55c410",
        "lifecycle": "planned",
        "from": {
          "uuid": "ab235853-dfdb-48f2-9240-a654fb781ea2",
          "entityType": "location",
          "associationType": "reference"
        },
        "to": {
          "uuid": "3c8829a8-4a82-48ca-a24b-5fe68a519d7f",
          "entityType": "location",
          "associationType": "reference"
        },
        "actions": [
          {
            "entity": {
              "id": "7e1fc454-57b2-39d0-b34f-eca8099327de",
              "startTime": "2021-06-14T12:40:00Z",
              "endTime": "2021-06-14T13:25:00Z",
              "actionType": "break"
            },
            "associationType": "inline"
          },
          {
            "entity": {
              "id": "0b949422-8b3a-3746-8896-fbeeeba06b0c",
              "name": "last-mile",
              "lifecycle": "planned",
              "to": {
                "uuid": "3c8829a8-4a82-48ca-a24b-5fe68a519d7f",
                "entityType": "location",
                "associationType": "reference"
              },
              "route": {
                "entity": {
                  "id": "1af201e4-f2d0-3181-b4a9-dfceb406a82b",
                  "geoReferences": {
                    "geometry": {
                      "coordinates": [
                        [
                          52.50052260516744,
                          6.130649215855866
                        ],
                        [
                          52.49654643979372,
                          6.133894958897176
                        ]
                      ],
                      "type": "LineString"
                    },
                    "type": "Feature"
                  }
                },
                "associationType": "inline"
              },
              "actionType": "move"
            },
            "associationType": "inline"
          }
        ],
        "actionType": "move"
      },
      "associationType": "inline"
    }

Location

Locations are the actual physical places visited during stops where actions - such as loading and unloading consignments - are being executed.

Within Simacan we deal with two types of locations:

  • managed locations, those that are reused for different trips repeatedly. Managed locations also are visible in Master Data, can have manual geofences, and first/last mile guidance.
  • unmanaged locations, those are only of interst in one planning and thus are not visible in Master Data. These locations do not have manual geofences, and no first or last mile guidance.

Both managed and unmanaged locations can be shared with and from Simacan using inline locations.

Inline locations have the following properties:

  • The location contains a name used for display purposes.
  • The location optionally contains a locationId in the externalAttributes that is used for identification in Master Data and repeated use after inlining.
  • The location optionally contains a coordinates.
  • The location contains address information such as the street , houseNumber , postalCode , city and country .
  • The location contains a type. The customer is used for one-off (unmanaged) locations and are treated as sensitive data. They also do not appear in Master Data. The types operationalBase and warehouse are used for managed locations and appear in Master Data.
  • The location has optional contact details.
Copy
Copied
   "location": {
       "entity": {
           "id": "a1463169-8e75-4c0c-8d4f-fbeb408f53aa",
           "externalAttributes": {
               "locationId": "simacan_123"
           },
           "name": "Simacan",
           "geoReference": {
               "lat": 52.370216,
               "lon": 4.895168,
               "type": "latLonPointGeoReference"
           },
           "administrativeReference": {
               "street": "Valutaboulevard",
               "houseNumber": "16",
               "postalCode": "1234AB",
               "city": "Amersfoort",
               "type": "addressGeoReference"
           },
           "contactDetails": [{
                   "value": "Simacan",
                   "type": "name"
               },
               {
                   "value": "0612345678",
                   "type": "phone"
               },
               {
                   "value": "sim@can.com",
                   "type": "email"
               }
           ],
           "type": "customer"
       },
       "associationType": "inline"
   }

Locations that have been shared before can be shared using an attribute restriction:

Copy
Copied
      "location": {
        "restriction": {
          "externalAttributes": {
            "locationId": "simacan_123"
          }
        },
        "entityType": "location",
        "associationType": "attributeRestriction"
      },

Consignment

A consignment is the administrative label put on a set of goods that are shipped together. A consigment does not physically exist and serves only to group goods together, provide some additional information like consignor and consignee and have somethign that be tracked during the lifetime of shpping the goods. The consignment is present in the trip by being the subject of the load, unload and handOver actions.

Within the Simacan platform the consignment has the following properties:

  • A consignment has a type (free text), this is what is known in the SCT as the goodsFlowType .
  • A consignment optionally has externalAttributes such as consignmentId , orderId , userId , trackTraceCode .
  • A consignment optionally has goods . Though goods are the meat of what is being transported, Simacan specializes in monitoring and thus is less concerned with what is actually shipped. A good has a quantity and optionally a productType, barCode and remark. Goods items and transportEquipment are both supported for the intake. The export will always use transportEquipment (even if the original used goods items).
  • Consignments can contain actors for the consignor and consignee. This can be the same actor.
Copy
Copied
{
  "id": "a556da93-46f3-4df5-8269-263bb337fde4",
  "actors": [
     {
       "associationType": "inline",
       "entity": { "name": "some consignor" },
       "roles": [ "consignor" ]
     },
          {
       "associationType": "inline",
       "entity": { "name": "some consignee" },
       "roles": [ "consignee" ]
     }
  ],
  "externalAttributes": {
    "orderId": "<order id>",
    "userId": "<user id>",
    "trackTraceCode": "<t&t code>"
  },
  "type": "Frozen goods",
  "goods": [
    {
      "entity": {
        "id": "b74d1b1a-905a-42dd-91be-1fe77f443467",
        "remark": "Be careful not to melt it!",
        "barCode": "123456789",
        "quantity": 3,
        "productType": "Ice cream",
        "type": "items"
      },
      "associationType": "inline"
    }
  ]
}