開始使用 Fleet Engine 進行運送追蹤

使用 Fleet Engine Deliveries API 為運送的第一英里和最後里程建立機群活動模型。您可以使用 Android 和 iOS 適用的驅動程式 SDK,或直接透過 HTTP REST 或 gRPC 呼叫來使用這個 API。

初始設定

您可以在 Google Cloud 控制台中設定 Fleet Engine Deliveries API。

確認設定正確無誤

建立服務帳戶後,請確認您的設定已完成,然後可以建立運送車輛。立即驗證設定,確保您已解決設定專案時可能發生的常見授權問題。驗證設定的方法有兩種:

用戶端程式庫

比起原始 gRPC 或 REST,開發人員能使用多種常見程式設計語言的用戶端程式庫來獲得更優質的開發人員體驗。如需如何為伺服器應用程式取得用戶端程式庫的操作說明,請參閱用戶端程式庫

本說明文件中的 Java 範例假設您已熟悉 gRPC。

資料結構

Fleet Engine Deliveries API 使用以下兩種資料結構來模擬運送的取貨和送貨服務:

  • 用來運送貨品的運送車輛。
  • 運送自取和外送工作。

工作也能用來模擬駕駛人整天的故障情形和排定的停靠站。

交車

貨運車輛會將貨物從倉庫轉移至送貨地點,以及從取貨地點到倉庫。在某些情況下,他們也可以直接將貨物從取貨地點傳輸至送貨地點。

使用驅動程式 SDK 在 Fleet Engine 中建立 DeliveryVehicle 物件,並傳送位置更新資訊,以便追蹤運送和車隊。

工作

對於車輛在當天採取的動作,您可以根據動作類型指派工作:

  • 如為自取和外送服務,請指派出貨工作
  • 對於駕駛人無法使用的時間 (例如所需休息時間),請指派無法使用的工作
  • 如為放置箱或客戶地點的非駕駛工作,請指派已排定的停止工作

您指派的每項工作都必須有不重複的工作 ID,但工作可以共用相同的追蹤 ID。Fleet Engine 計算每項工作的預計到達時間時,會使用所有任務和排定時間進行預估的順序。如要進一步瞭解工作 ID,請參閱「工作 ID 指南」。

如要在 Fleet Engine 中建立工作,請使用驅動程式 SDK 工作管理工具。

運送工作

建立出貨和送貨的出貨工作,並提供下列資訊:

  • 自取或外送服務的地點。
  • 追蹤號碼或 ID。
  • 完成工作、尋找停車或走到交接地點的停留時間。
  • 不重複的工作 ID。請參閱「工作 ID 指南」。

詳情請參閱下列主題:

Android

iOS

無法使用的工作

不可用工作涵蓋無法上車或交車的時段,例如為補充車輛或駕駛休息時間而休息的時間。

建立無法使用下列資訊的工作:

  • 廣告插播的時間長度。
  • (選用) 廣告插播位置。您不必提供特定地點,但這麼做可以提供整天的預計到達時間。

詳情請參閱下列主題:

Android

iOS

已排定的停止工作

建立排定的停靠點工作,模擬貨運車輛需要行駛的停靠站。舉例來說,您可以為特定地點的每日定時停靠站建立排定的停止工作,而不必在同一地點執行其他配送或取貨工作。您也可以為從投遞箱的集合、到模型饋送車轉乘或於服務中心和服務點停止,建立排定的停靠工作。

詳情請參閱下列主題:

Android

iOS

工作 ID 指南

建立工作 ID 時,請遵守下列內容和格式規範:

  • 建立專屬工作 ID
  • 請勿提供任何個人識別資訊 (PII) 或明文資料。
  • 請使用有效的 Unicode 字串。
  • 最多只能使用 64 個半形字元。
  • 請勿加入下列任何 ASCII 字元:"/"、":"、"\"、?" 或 "#"。
  • 根據 Unicode 正規化表單 C 正規化。

以下是一些良好工作 ID 的範例:

  • 566c33d9-2a31-4b6a-9cd4-80ba1a0c643b
  • e4708eabcfa39bf2767c9546c9273f747b4626e8cc44e9630d50f6d129013d38
  • NTA1YTliYWNkYmViMTI0ZmMzMWFmOWY2NzNkM2Jk

下表列出不支援的工作 ID:

不支援的工作 ID 原因
8/31/2019-20:48-46.70746,-130.10807,-85.17909,61.33680 違反 PII 和字元規定:逗號、句號、冒號和斜線。
JohnDoe-577b484da26f-Cupertino-SantaCruz 違反 PII 規定。
4R0oXLToF"112 Summer Dr. East Hartford, CT06118"577b484da26f8a, 違反 PII 和字元規定:空格、逗號和引號。超過 64 個半形字元。

其他資源

如要查看每個資料結構中包含的特定欄位,請參閱 DeliveryVehicle (gRPCREST) 和 Task (gRPCREST) 的 API 參考說明文件。

車輛的生命週期

DeliveryVehicle 物件代表第一英里或最後一英里送貨車。您可以使用下列指令建立 DeliveryVehicle 物件:

  • Google Cloud 專案的專案 ID,含有用於呼叫 Fleet Engine API 的服務帳戶。
  • 客戶擁有的車輛 ID。

請使用每輛車的專屬 ID。除非原始車輛沒有執行中的工作,否則請勿重複使用車輛 ID。

Fleet Engine 會自動刪除七天後,沒有使用 UpdateDeliveryVehicle 更新的 DeliveryVehicle 物件。如何查看車輛是否存在:

  1. 呼叫 UpdateDeliveryVehicle
  2. 如果發生 NOT_FOUND 錯誤,請呼叫 CreateDeliveryVehicle 來重新建立車輛。如果呼叫傳回車輛,表示該呼叫仍可更新。

交通工具類型

VehicleType 實體包含 VehicleType 的選用欄位,其中包含 Category 列舉,可指定為 AUTOTWO_WHEELERBICYCLEPEDESTRIAN。如果不設定這個欄位,系統會預設為 AUTO

所有車輛路線都會針對交通工具類型使用對應的 RouteTravelMode

車輛屬性

DeliveryVehicle 實體包含 DeliveryVehicleAttribute 的重複欄位。ListDeliveryVehicles API 包含 filter 欄位,可以將傳回的 DeliveryVehicle 實體限制為具有指定屬性的實體。DeliveryVehicleAttribute 不會影響 Fleet Engine 轉送行為。

由於使用者可能會看到這個欄位,因此請勿在屬性中加入個人識別資訊 (PII) 或機密資訊。

工作的生命週期

您可以透過 Deliveries API gRPC 或 REST 介面在 Fleet Engine 中建立、更新及查詢工作。

Task 物件具有狀態欄位,可在其生命週期追蹤進度。值會從「OPEN」移至「CLOSED」。新工作會以 OPEN 狀態建立,表示:

  • 這項工作尚未指派給送貨車輛。
  • 車輛尚未經過指派的車輛停靠站。

工作指南

你只能將處於「開啟」狀態的車輛指派給車輛。

如要取消工作,請從車輛停靠站清單中移除工作,讓工作狀態自動設為「已關閉」。

工作車輛完成工作的車輛停靠站時:

  1. 將工作的結果欄位更新為「SUCCEEDED」或「FAILED」。

  2. 指定事件的時間戳記。

    接著,JavaScript shipment Tracking 程式庫會指出工作結果, 並將工作狀態設為「已關閉」。詳情請參閱使用 JavaScript 運送追蹤程式庫追蹤運送狀態

與車輛一樣,Fleet Engine 會刪除七天未更新的工作,如果您嘗試建立已有 ID 的工作,這個工作會傳回錯誤。

注意:Fleet Engine 不支援明確刪除工作。服務會在七天後自動刪除工作,且不會更新。如果希望工作資料保留超過七天,您必須自行實作該功能。

工作屬性

Task 實體包含 TaskAttribute 的重複欄位,可以採用以下 3 種類型之一的值:字串、數字和布林值。ListTasks API 包含 filter 欄位,可限制傳回 Task 實體,只傳回具有指定屬性的實體。工作屬性不會影響 Fleet Engine 的轉送行為。

請勿在屬性中加入個人識別資訊 (PII) 或其他機密資訊,因為使用者可能會看到這些屬性。

管理車輛和工作生命週期

提醒:Fleet Engine Deliveries API 代表您擴增資料,將內部系統視為可靠的資料來源。

如要管理系統中的車輛和工作生命週期,請使用 Fleet Engine Deliveries API 建立、更新及追蹤車輛及其相關工作。

同時,駕駛應用程式會直接與 Fleet Engine 通訊,以更新裝置位置和路線資訊。這個模型可讓 Fleet Engine 有效率地管理即時位置資訊。然後將位置直接傳送至追蹤程式庫,讓您用來更新消費者的訂單狀態。

舉例來說,假設您遇到以下情境:

  • 司機靠近送貨站。驅動程式應用程式將其位置傳送至 Fleet Engine。
  • Fleet Engine 將裝置位置資訊傳送至追蹤程式庫,而消費者應用程式會使用該程式庫,通知取用者瞭解套件的距離。
  • 駕駛人完成出貨後,他們只要在駕駛應用程式上點選「已送達」按鈕。
  • 「已出貨」動作會將資訊傳送到後端系統,以執行必要的業務驗證和驗證步驟。
  • 您的系統確認任務為 SUCCEEDED,並使用 Deliveries API 更新 Fleet Engine。

下圖說明這些程序的一般層級。也會顯示系統、用戶端和 Fleet Engine 之間的標準關係。

使用 Deliveries API

管理用戶端權杖

由驅動程式應用程式發出並直接傳送至 Fleet Engine 的位置更新需要授權權杖。以下是處理用戶端傳送至 Fleet Engine 的更新建議的方法:

  1. 使用 Fleet Engine Delivery Untrusted Driver User 服務帳戶角色產生權杖。

  2. 為驅動程式應用程式提供有限範圍的憑證。這個範圍僅允許更新 Fleet Engine 中的裝置位置。

這個方法可確保來自行動裝置 (視為低信任環境) 的呼叫,遵循最低權限原則

其他服務帳戶角色

如要改為授權驅動程式應用程式直接更新 Fleet Engine,而不進行僅限受信任驅動程式角色的限制 (例如進行特定工作更新),可以使用「信任的驅動程式」角色。如要進一步瞭解使用「信任的驅動程式」角色的模型,請參閱「信任的驅動程式模型」。

如要進一步瞭解不受信任和信任的驅動程式角色的使用,請參閱 Cloud 專案設定

建立工作日模型

下表說明第一英里或最後一里的司機在送貨和物流公司的工作日可能呈現的樣貌。公司細節可能會有差異,但您可以瞭解如何為工作日建立模型。

時間活動模擬
當日開始後的 24 小時內 調度員負責指派貨運給運輸車輛或路線。 您可以事先透過 Fleet Engine 建立運送、取貨、休息時間和其他事宜的任務。舉例來說,您可以建立出貨取貨工作出貨服務交付工作排定不開放預約排定停靠站

在運送包裹組及預計交付訂單完成之後,將工作指派給車輛。
當天開始時間 司機登入駕駛應用程式,在總庫當日開始導航。 初始化 Delivery Driver API。視需要在 Fleet Engine 中建立運送車輛
駕駛人將貨物裝運到貨車上,再掃描貨物。 如果配送工作並未預先建立運送工作,請在掃描時建立運送運送工作
驅動程式可確認工作執行的順序。 如果未提前建立,請建立出貨自取工作排定不開放預約,以及排定停靠站
駕駛人會留在庫房,修訂下一個要完成的工作數量。 透過提交完成順序,將所有工作指派給車輛。
司機送貨, 抵達貨運站後,執行與抵達停靠站車輛相關的動作。提交出貨後,請關閉運送工作,並視需要關閉商店運送狀態和其他中繼資訊。於停靠站完成所有工作後,在行駛到下一個停靠站前,請執行與車輛完成停靠站車輛行駛至下一個停靠站相關的動作。
駕駛與送貨員會面,將其他貨物轉到貨運車輛上。 轉乘至餵食器和運輸車輛之間的轉乘點應模擬為預定停靠點

如果尚未建立運送工作,請在轉移及掃描完成後建立運送工作。接著,將工作指派給車輛更新工作順序,藉此更新工作完成順序。
駕駛會收到取件要求的通知。 接受取貨要求後,請建立出貨取貨工作。接著,請將工作指派給車輛更新工作順序,藉此更新工作執行順序。
中午 駕駛人吃午餐休息一下。 如果位置與無法使用的工作相關聯,請將其視為任何其他工作。執行與車輛抵達停靠站車輛完成停靠站車輛行駛至下一個停靠站的相關動作。

否則,在廣告插播結束之前,您無須採取進一步行動。 如要移除工作,請確認後續和其餘的工作,並更新工作順序
司機上車。 這種模型就像放送停靠站一樣。執行與抵達停靠站的車輛關閉工作相關的動作,並視需要一併儲存運送狀態和其他中繼資訊。在停靠站完成所有工作,且開始行駛至下一個停靠點前,請執行與車輛完成停靠站車輛行駛至下一個停靠站相關的動作。注意事項:為確保收費方式正確無誤,所有取貨服務都必須有對應的提交工作。如果取件服務會運送至駕駛當天同一條路線上的其他地點,建議您以路線上的任何其他運送工作為地點建立模型。如果司機將取件送回庫房,建議您在庫房目的地建立運送工作。
駕駛人會安排停靠站,從集貨箱取件。 這種模型與任何其他上車停靠站相同。執行與停靠站抵達的車輛關閉工作相關的動作。在停靠站完成所有工作並開始行駛至下一個停靠點後,請執行與車輛完成停靠站車輛行駛至下一個停靠站相關的動作。
司機收到貨物轉至其他地點的通知。 將原始運送工作狀態設為「已完成」,並為新的送貨地點建立新的運送運送工作。詳情請參閱重新安排運送包裹一節。
駕駛人嘗試提交包裹,但未能送達。 這個模型與成功停止提交作業的模式類似,也就是將推送工作標示為已完成。執行與抵達停靠站車輛相關的動作。未能交付貨品後,請關閉工作,並視需要關閉商店運送狀態和其他中繼資訊。在停靠站完成所有工作,且開始行駛至下一個停靠點前,請執行與車輛完成停靠站車輛行駛至下一個停靠站相關的動作。
司機收到保留 (未出貨) 的通知。 收到並確認通知後,請將工作狀態設為「已完成」。
司機收到後續運送特定貨品的通知,變更承諾的貨品交付訂單。 更新工作排序
司機選擇送貨到府。 更新工作排序,然後照常繼續操作。
司機能將多個貨物運送至單一地點。 這個模型與單一運送停靠站類似。抵達停靠站後,執行與抵達停靠站車輛相關的動作。每次出貨後,請關閉每項工作,並視情況關閉商店運送狀態和其他中繼資訊。在停靠站完成所有工作,且開始行駛至下一個停靠點前,請執行與車輛完成停靠站車輛行駛至下一個停靠站相關的動作。
當天結束時間 駕駛員返回庫房。 如果司機返回庫房,且安排運送途中取貨,您也必須為運送任務建立並結案,以確保帳單正確。您可以比照其他運送停靠站建立模型,建立模型。如果該 Depot 並未用作供應停靠站,您仍可選擇將庫房建為排定的停靠站。建立停靠站模型,可讓駕駛人查看返回庫房的路線,並掌握預計抵達時間。

位置資訊更新的運作方式

為獲得最佳的 Fleet Engine 效能,請提供一連串的車輛位置更新。請使用下列其中一種方式提供這些更新:

  1. 使用驅動程式 SDK - AndroidiOS -- 最簡單的選項。
  2. 使用自訂程式碼 -- 如果位置是透過後端轉送,或者您使用 Android 或 iOS 以外的裝置,就很適合使用。

無論您提供車輛位置更新的方式為何,在貨運車輛轉送至停靠站 (包括庫房) 和抵達停靠站時,後端都必須負責更新 Fleet Engine。Fleet Engine 不會自動偵測這些事件。

車輛停靠站和送貨地點

車輛停靠站是指貨運車輛完成運送工作或其他工作的位置。它是存取點 (例如載入座架或道路封閉位置)。

交貨地點是運送或取貨地點。往返送貨地點可能需要步行距離車輛停靠站。

舉例來說,如果司機送貨至購物中心裡的某間商店,則送貨車會在購物中心附近靠近商店的入口處。這是車輛停靠站。然後,司機從車輛停靠站前往商店所在的購物中心位置。這是送貨地點。

為了帶給使用者最佳運送追蹤體驗,請思考如何將運送工作指派給車輛停靠站。請記住,系統會回報運送工作的剩餘車輛數量,讓使用者查看運送進度。

舉例來說,如果司機要為一棟辦公大樓進行多次配送,不妨將所有運送工作指派給單一車輛停靠站。如果每項運送工作都指派給自己的車輛停靠站,運送追蹤體驗對使用者而言比較實用,因為只有在車輛抵達目的地的有限停靠站內,系統才能進行追蹤。即使有許多車輛在短時間內完成許多停靠站,使用者並沒有足夠時間追蹤貨品交付進度。

使用行動 SDK

呼叫 Driver SDK 之前,請務必先初始化。

初始化 Delivery Driver API

在驅動程式 SDK 中初始化 Delivery Driver API 之前,請務必先初始化 Navigation SDK。接著初始化 Delivery Driver API,如以下範例所示:

static final String PROVIDER_ID = "provider-1234";
static final String VEHICLE_ID = "vehicle-8241890";

NavigationApi.getNavigator(
   this, // Activity.
   new NavigatorListener() {
     @Override
     public void onNavigatorReady(Navigator navigator) {
       DeliveryDriverApi.createInstance(DriverContext.builder(getApplication())
         .setNavigator(navigator)
         .setProviderId(PROVIDER_ID)
         .setVehicleId(VEHICLE_ID)
         .setAuthTokenFactory((context) -> "JWT") // AuthTokenFactory returns JWT for call context.
         .setRoadSnappedLocationProvider(NavigationApi.getRoadSnappedLocationProvider(getApplication()))
         .setNavigationTransactionRecorder(NavigationApi.getNavigationTransactionRecorder(getApplication()))
         .setStatusListener((statusLevel,statusCode,statusMsg) -> // Optional, surfaces polling errors.
             Log.d("TAG", String.format("New status update. %s, %s, %s", statusLevel, statusCode, statusMsg)))
         .build));
     }
     @Override
     public void onError(int errorCode) {
       Log.e("TAG", String.format("Error loading Navigator instance: %s", errorCode));
     }
   });

用途

本節說明如何使用 Deliveries API 建立常見用途模型。

專屬實體 ID

REST 呼叫中專屬實體 ID 的格式和值不對 Fleet Engine 顯示。請避免使用自動遞增的 ID,並確認該 ID 不含任何個人識別資訊 (PII),例如駕照的電話號碼。

建立車輛

您可以透過驅動程式 SDK,或是使用 gRPC 或 REST 從伺服器環境建立車輛。

gRPC

如要建立新車輛,請向 Fleet Engine 發出 CreateDeliveryVehicle 呼叫。使用 CreateDeliveryVehicleRequest 物件定義新交車的屬性。請注意,根據使用者指定 ID 的 API 指南,系統會忽略 Name 欄位指定的所有值。應使用 DeliveryVehicleId 欄位設定車輛 ID。

建立 DeliveryVehicle 時,您可以選擇指定下列欄位:

  • 屬性
  • LastLocation
  • 類型

請勿設定任何其他欄位。如果採取這項動作,Fleet Engine 會傳回錯誤,因為這些欄位處於唯讀狀態,或只能透過 UpdateDeliveryVehicle 呼叫更新。

如要建立車輛而不設定任何選用欄位,可以取消設定 CreateDeliveryVehicleRequest 中的 DeliveryVehicle 欄位。

以下範例說明如何使用 Java gRPC 程式庫建立車輛:

    static final String PROJECT_ID = "my-delivery-co-gcp-project";
    static final String VEHICLE_ID = "vehicle-8241890"; // Avoid auto-incrementing IDs.

    DeliveryServiceBlockingStub deliveryService =
      DeliveryServiceGrpc.newBlockingStub(channel);

    // Vehicle settings
    String parent = "providers/" + PROJECT_ID;
    DeliveryVehicle vehicle = DeliveryVehicle.newBuilder()
      .addAttributes(DeliveryVehicleAttribute.newBuilder()
        .setKey("route_number").setValue("1"))  // Opaque to the Fleet Engine
      .build();

    // Vehicle request
    CreateDeliveryVehicleRequest createVehicleRequest =
      CreateDeliveryVehicleRequest.newBuilder()  // No need for the header
          .setParent(parent)
          .setDeliveryVehicleId(VEHICLE_ID)     // Vehicle ID assigned by the Provider
          .setDeliveryVehicle(vehicle)
          .build();

    // Error handling
    // If Fleet Engine does not have vehicle with that ID and the credentials of the
    // requestor pass, the service creates the vehicle successfully.

    try {
      DeliveryVehicle createdVehicle =
        deliveryService.createDeliveryVehicle(createVehicleRequest);
    } catch (StatusRuntimeException e) {
      Status s = e.getStatus();
      switch (s.getCode()) {
         case ALREADY_EXISTS:
           break;
         case PERMISSION_DENIED:
           break;
      }
      return;
    }

REST

如要從伺服器環境建立車輛,請向 CreateDeliveryVehicle 發出 HTTP REST 呼叫:

POST https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles?deliveryVehicleId=<id>

<id> 是車隊中運輸車輛的專屬 ID

要求標頭必須包含一個值為 Bearer <token>Authorization 欄位,其中 <token>Fleet Engine 符記工廠所核發的憑證

POST 主體代表要建立的 DeliveryVehicle 實體。您可以指定下列選用欄位:

  • attributes
  • lastLocation
  • 類型

curl 指令範例:

# Set $JWT, $PROJECT_ID, and $VEHICLE_ID in the local
# environment
curl -X POST "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles?deliveryVehicleId=${VEHICLE_ID}" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
--data-binary @- << EOM
{
  "attributes": [{"key": "model", "value": "sedan"}],
  "lastLocation": {"location": {"latitude": 12.1, "longitude": 14.5}}
}
EOM

針對使用者指定 ID,Fleet Engine 會根據 API 指南,忽略 DeliveryVehicle 實體的 name 欄位。請勿設定任何其他欄位。如果這樣做,Fleet Engine 會傳回錯誤,因為這些欄位處於唯讀狀態,或只能透過呼叫 UpdateDeliveryVehicle 來更新。

如要建立車輛而不設定任何欄位,請將 POST 要求的主體留空。接著,新建立的車輛會從 POST 網址的 deliveryVehicleId 參數中擷取車輛 ID。

curl 指令範例:

# Set $JWT, $PROJECT_ID, and $VEHICLE_ID in the local
# environment
curl -X POST "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles?deliveryVehicleId=${VEHICLE_ID}" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}"

建立運送自取工作

您可以透過驅動程式 SDK,或在伺服器環境中使用 gRPC 或 REST 建立運送取貨工作。

gRPC

以下範例說明如何使用 Java gRPC 程式庫建立運送取貨工作:

static final String PROJECT_ID = "my-delivery-co-gcp-project";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Task settings
String parent = "providers/" + PROJECT_ID;
Task task = Task.newBuilder()
  .setType(Task.Type.PICKUP)
  .setState(Task.State.OPEN)
  .setTrackingId("my-tracking-id")
  .setPlannedLocation(               // Grand Indonesia East Mall
    LocationInfo.newBuilder().setPoint(
      LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
  .setTaskDuration(
    Duration.newBuilder().setSeconds(2 * 60))
  .setTargetTimeWindow(
    TimeWindow.newBuilder()
      .setStartTime(Timestamp.newBuilder().setSeconds(1680123600))
      .setEndTime(Timestamp.newBuilder().setSeconds(1680130800)))
  .addAttributes(TaskAttribute.newBuilder().setKey("foo").setStringValue("value"))
  .addAttributes(TaskAttribute.newBuilder().setKey("bar").setNumberValue(10))
  .addAttributes(TaskAttribute.newBuilder().setKey("baz").setBoolValue(false))
  .build();

// Task request
CreateTaskRequest createTaskRequest =
  CreateTaskRequest.newBuilder()  // No need for the header
      .setParent(parent)          // Avoid using auto-incrementing IDs for the taskId
      .setTaskId("task-8241890")  // Task ID assigned by the Provider
      .setTask(task)              // Initial state
      .build();

// Error handling
// If Fleet Engine does not have a task with that ID and the credentials of the
// requestor pass, the service creates the task successfully.

try {
  Task createdTask = deliveryService.createTask(createTaskRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case ALREADY_EXISTS:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

如要從伺服器環境建立運送取貨工作,請向 CreateTask 發出 HTTP REST 呼叫:

`POST https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks?taskId=<id>`

<id> 是工作的專屬 ID。不可以是貨品的追蹤號碼。如果系統中沒有工作 ID,可以產生通用唯一 ID (UUID)。

要求標頭必須包含一個值為 Bearer <token>Authorization 欄位,其中 <token>Fleet Engine 符記工廠所核發的憑證

要求主體必須包含 Task 實體:

  • 必填欄位:

    欄位價值
    類型 Type.PICKUP
    state State.OPEN
    trackingId 您用來追蹤運送狀態的號碼或 ID。
    plannedLocation 工作完成的位置,本例中為運送取貨地點。
    taskDuration 到取貨地點取貨的預計時間 (以秒為單位)。

  • 選填欄位:

    欄位價值
    targetTimeWindow 完成工作的時間範圍。這不會影響轉送行為。
    attributes 自訂工作屬性的清單。每個屬性都必須有專屬索引鍵。

系統會在建立實體時忽略實體中的所有其他欄位。如果要求包含指派的 deliveryVehicleId,Fleet Engine 會擲回例外狀況。您可以使用 UpdateDeliveryVehicleRequest 指派工作。詳情請參閱「將工作指派給車輛」和「UpdateDeliveryVehicleRequest」一文。

curl 指令範例:

# Set $JWT, $PROJECT_ID, $TRACKING_ID, and $TASK_ID in the local
# environment
curl -X POST "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks?taskId=${TASK_ID}" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "type": "PICKUP",
  "state": "OPEN",
  "trackingId": "${TRACKING_ID}",
  "plannedLocation": {
     "point": {
        "latitude": -6.195139,
        "longitude": 106.820826
     }
  },
  "taskDuration": "90s",
  "targetTimeWindow": {
    "startTime": "2023-03-29T21:00:00Z",
    "endTime": "2023-03-29T23:00:00Z"
  }
}
EOM

建立運送運送工作

透過驅動程式 SDK,或是使用 gRPC 或 REST 從伺服器環境建立運送傳遞工作。

gRPC

以下範例說明如何使用 Java gRPC 程式庫建立運送運送工作:

static final String PROJECT_ID = "my-delivery-co-gcp-project";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Task settings
String parent = "providers/" + PROJECT_ID;
Task task = Task.newBuilder()
  .setType(Task.Type.DELIVERY)
  .setState(Task.State.OPEN)
  .setTrackingId("my-tracking-id")
  .setPlannedLocation(               // Grand Indonesia East Mall
    LocationInfo.newBuilder().setPoint(
      LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
  .setTaskDuration(
    Duration.newBuilder().setSeconds(2 * 60))
  .setTargetTimeWindow(
    TimeWindow.newBuilder()
      .setStartTime(Timestamp.newBuilder().setSeconds(1680123600))
      .setEndTime(Timestamp.newBuilder().setSeconds(1680130800)))
  .addAttributes(TaskAttribute.newBuilder().setKey("foo").setStringValue("value"))
  .addAttributes(TaskAttribute.newBuilder().setKey("bar").setNumberValue(10))
  .addAttributes(TaskAttribute.newBuilder().setKey("baz").setBoolValue(false))
  .build();

// Task request
CreateTaskRequest createTaskRequest =
  CreateTaskRequest.newBuilder()  // No need for the header
      .setParent(parent)          // Avoid using auto-incrementing IDs for the taskId
      .setTaskId("task-8241890")  // Task ID assigned by the Provider
      .setTask(task)              // Initial state
      .build();

// Error handling
// If Fleet Engine does not have task with that ID and the credentials of the
// requestor pass, the service creates the task successfully.

try {
  Task createdTask = deliveryService.createTask(createTaskRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case ALREADY_EXISTS:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

如要使用 gRPC 或 REST 從伺服器環境建立運送傳遞工作,請對 CreateTask 發出 HTTP REST 呼叫:

`POST https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks?taskId=<id>`

<id> 是工作的專屬 ID。不可以是貨品的追蹤號碼。如果系統中沒有工作 ID,可以產生通用唯一 ID (UUID)。

要求標頭必須包含一個值為 Bearer <token>Authorization 欄位,其中 <token>Fleet Engine 符記工廠所核發的憑證

要求主體必須包含 Task 實體:

  • 必填欄位:

    欄位價值
    類型 Type.DELIVERY
    state State.OPEN
    trackingId 您用來追蹤運送狀態的號碼或 ID。
    plannedLocation 工作完成的位置,本例中的運送地點。
    taskDuration 出貨地點送達的預計時間 (以秒為單位)。

  • 選填欄位:

    欄位價值
    targetTimeWindow 完成工作的時間範圍。這不會影響轉送行為。
    attributes 自訂工作屬性的清單。每個屬性都必須有專屬索引鍵。

系統會在建立實體時忽略實體中的所有其他欄位。如果要求包含指派的 DeliveryVehicleId,Fleet Engine 會擲回例外狀況。您可以使用 UpdateDeliveryVehicleRequest 指派工作。詳情請參閱「將工作指派給車輛」和「UpdateDeliveryVehicleRequest」一文。

curl 指令範例:

# Set $JWT, $PROJECT_ID, $TRACKING_ID, and $TASK_ID in the local
# environment
curl -X POST "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks?taskId=${TASK_ID}" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "type": "DELIVERY",
  "state": "OPEN",
  "trackingId": "${TRACKING_ID}",
  "plannedLocation": {
     "point": {
        "latitude": -6.195139,
        "longitude": 106.820826
     }
  },
  "taskDuration": "90s",
  "targetTimeWindow": {
    "startTime": "2023-03-29T21:00:00Z",
    "endTime": "2023-03-29T23:00:00Z"
  }
}
EOM

批次建立工作

您可以使用 gRPC 或 REST,從伺服器環境建立一批工作。

gRPC

以下範例說明如何使用 Java gRPC 程式庫建立兩項工作:一項用於傳輸,另一個用於在同一位置取貨:

static final String PROJECT_ID = "my-delivery-co-gcp-project";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Delivery Task settings
Task deliveryTask = Task.newBuilder()
  .setType(Task.Type.DELIVERY)
  .setState(Task.State.OPEN)
  .setTrackingId("delivery-tracking-id")
  .setPlannedLocation(               // Grand Indonesia East Mall
    LocationInfo.newBuilder().setPoint(
      LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
  .setTaskDuration(
    Duration.newBuilder().setSeconds(2 * 60))
  .build();

// Delivery Task request
CreateTaskRequest createDeliveryTaskRequest =
  CreateTaskRequest.newBuilder()  // No need for the header or parent fields
      .setTaskId("task-8312508")  // Task ID assigned by the Provider
      .setTask(deliveryTask)      // Initial state
      .build();

// Pickup Task settings
Task pickupTask = Task.newBuilder()
  .setType(Task.Type.PICKUP)
  .setState(Task.State.OPEN)
  .setTrackingId("pickup-tracking-id")
  .setPlannedLocation(               // Grand Indonesia East Mall
    LocationInfo.newBuilder().setPoint(
      LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
  .setTaskDuration(
    Duration.newBuilder().setSeconds(2 * 60))
  .build();

// Pickup Task request
CreateTaskRequest createPickupTaskRequest =
  CreateTaskRequest.newBuilder()  // No need for the header or parent fields
      .setTaskId("task-8241890")  // Task ID assigned by the Provider
      .setTask(pickupTask)        // Initial state
      .build();

// Batch Create Tasks settings
String parent = "providers/" + PROJECT_ID;

// Batch Create Tasks request
BatchCreateTasksRequest batchCreateTasksRequest =
  BatchCreateTasksRequest.newBuilder()
      .setParent(parent)
      .addRequests(createDeliveryTaskRequest)
      .addRequests(createPickupTaskRequest)
      .build();

// Error handling
// If Fleet Engine does not have any task(s) with these task ID(s) and the
// credentials of the requestor pass, the service creates the task(s)
// successfully.

try {
  BatchCreateTasksResponse createdTasks = deliveryService.batchCreateTasks(
    batchCreateTasksRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case ALREADY_EXISTS:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

如要從伺服器環境建立傳送與取貨工作,請向 BatchCreateTasks 發出 HTTP REST 呼叫:

POST https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks:batchCreate

要求標頭必須包含一個值為 Bearer <token>Authorization 欄位,其中 <token>由 Fleet Engine 符記工廠所核發的憑證

要求主體必須包含 BatchCreateTasksRequest 實體:

  • 必填欄位:

    欄位價值
    項要求 陣列<CreateTasksRequest>

  • 選填欄位:

    欄位價值
    標頭 「DeliveryRequestHeader」

requests 中的每個 CreateTasksRequest 元素都必須與 CreateTask 要求傳遞相同的驗證規則,但 parentheader 欄位為選用欄位。如果設定,這些變數必須與頂層 BatchCreateTasksRequest 中的對應欄位相同。請參閱「建立運送取貨工作」,並針對每個各規則的特定驗證規則建立運送運送工作

詳情請參閱 BatchCreateTasks 的 API 參考說明文件 (gRPCREST)。

curl 指令範例:

# Set $JWT, $PROJECT_ID, $DELIVERY_TRACKING_ID, $DELIVERY_TASK_ID,
# $PICKUP_TRACKING_ID, and $PICKUP_TASK_ID in the local environment
curl -X POST "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks:batchCreate" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "requests" : [
    {
      "taskId": "${DELIVERY_TASK_ID}",
      "task" : {
        "type": "DELIVERY",
        "state": "OPEN",
        "trackingId": "${DELIVERY_TRACKING_ID}",
        "plannedLocation": {
          "point": {
              "latitude": -6.195139,
              "longitude": 106.820826
          }
        },
        "taskDuration": "90s"
      }
    },
    {
      "taskId": "${PICKUP_TASK_ID}",
      "task" : {
        "type": "PICKUP",
        "state": "OPEN",
        "trackingId": "${PICKUP_TRACKING_ID}",
        "plannedLocation": {
          "point": {
              "latitude": -6.195139,
              "longitude": 106.820826
          }
        },
        "taskDuration": "90s"
      }
    }
  ]
}
EOM

已排定時間無法使用

您可以透過驅動程式 SDK 建立指出無法使用的任務 (例如駕駛中斷或回車),或是在伺服器環境中使用 gRPC 或 REST 建立任務。已排定無法使用的工作不得包含追蹤 ID。您可以選擇提供位置。

gRPC

以下範例說明如何使用 Java gRPC 程式庫建立無法使用的工作:

    static final String PROJECT_ID = "my-delivery-co-gcp-project";

    DeliveryServiceBlockingStub deliveryService =
      DeliveryServiceGrpc.newBlockingStub(channel);

    // Task settings
    String parent = "providers/" + PROJECT_ID;
    Task task = Task.newBuilder()
      .setType(Task.Type.UNAVAILABLE)
      .setState(Task.State.OPEN)
      .setTaskDuration(
        Duration.newBuilder().setSeconds(60 * 60))  // 1hr break
      .build();

    // Task request
    CreateTaskRequest createTaskRequest =
      CreateTaskRequest.newBuilder()  // No need for the header
          .setParent(parent)          // Avoid using auto-incrementing IDs for the taskId
          .setTaskId("task-8241890")  // Task ID assigned by the Provider
          .setTask(task)              // Initial state
          .build();

    // Error handling
    // If Fleet Engine does not have task with that ID and the credentials of the
    // requestor pass, the service creates the task successfully.

    try {
      Task createdTask = deliveryService.createTask(createTaskRequest);
    } catch (StatusRuntimeException e) {
      Status s = e.getStatus();
      switch (s.getCode()) {
         case ALREADY_EXISTS:
           break;
         case PERMISSION_DENIED:
           break;
      }
      return;
    }

REST

如要從伺服器環境建立無法使用的工作,請向 CreateTask 發出 HTTP REST 呼叫:

`POST https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks?taskId=<id>`

<id> 是工作的專屬 ID。如果系統中沒有工作 ID,可以產生通用唯一 ID (UUID)。

要求標頭必須包含一個值為 Bearer <token>Authorization 欄位,其中 <token>Fleet Engine 符記工廠所核發的憑證

要求主體必須包含 Task 實體:

  • 必填欄位:

    欄位價值
    類型 Type.UNAVAILABLE
    state State.OPEN
    taskDuration 廣告插播的時間長度 (以秒為單位)。

  • 選填欄位:

    欄位價值
    plannedLocation 休息地點 (如果必須在特定位置拍攝)

系統會在建立實體時忽略實體中的所有其他欄位。如果要求包含指派的 DeliveryVehicleId,Fleet Engine 會擲回例外狀況。您可以使用 UpdateDeliveryVehicleRequest 指派工作。詳情請參閱「將工作指派給車輛」和「UpdateDeliveryVehicleRequest」一文。

curl 指令範例:

    # Set $JWT, $PROJECT_ID, and $TASK_ID in the local environment
    curl -X POST "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks?taskId=${TASK_ID}" \
      -H "Content-type: application/json" \
      -H "Authorization: Bearer ${JWT}" \
      --data-binary @- << EOM
    {
      "type": "UNAVAILABLE",
      "state": "OPEN",
      "plannedLocation": {
         "point": {
            "latitude": -6.195139,
            "longitude": 106.820826
         }
      },
      "taskDuration": "300s"
    }
    EOM

已排定的停靠站

您可以透過驅動程式 SDK,或是在伺服器環境中使用 gRPC 或 REST 建立已排定的停止工作。已排定的停止工作可能不得包含追蹤 ID。

gRPC

以下範例說明如何使用 Java gRPC 程式庫建立排定的停止工作:

static final String PROJECT_ID = "my-delivery-co-gcp-project";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Task settings
String parent = "providers/" + PROJECT_ID;
Task task = Task.newBuilder()
  .setType(Task.Type.SCHEDULED_STOP)
  .setState(Task.State.OPEN)
  .setPlannedLocation(               // Grand Indonesia East Mall
    LocationInfo.newBuilder().setPoint(
      LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
  .setTaskDuration(
    Duration.newBuilder().setSeconds(2 * 60))
  .build();

// Task request
CreateTaskRequest createTaskRequest =
  CreateTaskRequest.newBuilder()  // No need for the header
      .setParent(parent)
      .setTaskId("task-8241890")  // Task ID assigned by the Provider
      .setTrip(task)              // Initial state
      .build();

// Error handling
// If Fleet Engine does not have task with that ID and the credentials of the
// requestor pass, the service creates the task successfully.

try {
  Task createdTask = deliveryService.createTask(createTaskRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case ALREADY_EXISTS:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

如要從伺服器環境建立已排定的停止工作,請向 CreateTask 發出 HTTP REST 呼叫:

`POST https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks?taskId=<id>`

<id> 是工作的專屬 ID。如果系統中沒有工作 ID,可以產生通用唯一識別碼 (UUID)。

要求標頭必須包含一個值為 Bearer <token>Authorization 欄位,其中 <token>Fleet Engine 符記工廠所核發的憑證

要求主體必須包含 Task 實體:

  • 必填欄位:

    欄位價值
    類型 Type.SCHEDULED_STOP
    state State.OPEN
    plannedLocation 停靠站的位置。
    taskDuration 預測停靠站長度 (以秒為單位)。

  • 選填欄位:

系統會在建立實體時忽略實體中的所有其他欄位。如果要求包含指派的 DeliveryVehicleId,Fleet Engine 會擲回例外狀況。您可以使用 UpdateDeliveryVehicleRequest 指派工作。詳情請參閱「將工作指派給車輛」和「UpdateDeliveryVehicleRequest」一文。

curl 指令範例:

    # Set $JWT, $PROJECT_ID, and $TASK_ID in the local environment
    curl -X POST "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks?taskId=${TASK_ID}" \
      -H "Content-type: application/json" \
      -H "Authorization: Bearer ${JWT}" \
      --data-binary @- << EOM
    {
      "type": "SCHEDULED_STOP",
      "state": "OPEN",
      "plannedLocation": {
         "point": {
            "latitude": -6.195139,
            "longitude": 106.820826
         }
      },
      "taskDuration": "600s"
    }
    EOM

設定目標時間範圍

目標時間範圍是應完成工作的 TimeWindow。例如,如果您向貨運接收者傳達運送時間,可以使用工作目標時間範圍擷取這個時間範圍,並使用該欄位產生快訊或分析行程後成效。

目標時間範圍包含開始時間和結束時間,且可針對任何工作類型設定。目標時間範圍不會影響轉送行為。

gRPC

以下範例說明如何使用 Java gRPC 程式庫設定工作時間範圍:

    static final String PROJECT_ID = "my-delivery-co-gcp-project";
    static final String TASK_ID = "task-8241890";

    DeliveryServiceBlockingStub deliveryService =
      DeliveryServiceGrpc.newBlockingStub(channel);

    // Task settings
    String taskName = "providers/" + PROJECT_ID + "/tasks/" + TASK_ID;
    Task task = Task.newBuilder()
      .setName(taskName)
      .setTargetTimeWindow(
        TimeWindow.newBuilder()
          .setStartTime(Timestamp.newBuilder().setSeconds(1680123600))
          .setEndTime(Timestamp.newBuilder().setSeconds(1680130800)))
      .build();

    // Task request
    UpdateTaskRequest updateTaskRequest =
      UpdateTaskRequest.newBuilder()  // No need for the header
          .setTask(task)
          .setUpdateMask(FieldMask.newBuilder().addPaths("targetTimeWindow"))
          .build();

    try {
      Task updatedTask = deliveryService.updateTask(updateTaskRequest);
    } catch (StatusRuntimeException e) {
      Status s = e.getStatus();
      switch (s.getCode()) {
         case NOT_FOUND:
           break;
         case PERMISSION_DENIED:
           break;
      }
      return;
    }

REST

如要使用 HTTP 設定工作時間範圍,請呼叫 UpdateTask

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks/<id>?updateMask=targetTimeWindow`

<id> 是工作的專屬 ID

要求標頭必須包含一個值為 Bearer <token>Authorization 欄位,其中 <token>Fleet Engine 符記工廠所核發的憑證

要求主體必須包含 Task 實體:

  • 必填欄位:

    欄位價值
    targetTimeWindow 完成工作的時間範圍。這項設定不會影響轉送行為

  • 選填欄位:

系統會忽略實體中的所有其他欄位,以便執行這項更新作業。

curl 指令範例:

# Set JWT, PROJECT_ID, and TASK_ID in the local environment
curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks/${TASK_ID}?updateMask=targetTimeWindow" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "targetTimeWindow": {
    "startTime": "2023-03-29T21:00:00Z",
    "endTime": "2023-03-29T23:00:00Z"
  }
}
EOM

設定工作追蹤瀏覽權限設定

個別工作可以設定任務的 TaskTrackingViewConfig,藉此控制運送追蹤程式庫中資料和從呼叫 GetTaskTrackingInfo 傳回的資料瀏覽權限。詳情請參閱「進行中的車輛工作」一文。您在建立或更新工作時即可執行這項操作。以下範例說明如何透過此設定更新工作:

gRPC

以下範例說明如何使用 Java gRPC 程式庫設定工作追蹤檢視設定:

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String TASK_ID = "task-8241890";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Task settings
String taskName = "providers/" + PROJECT_ID + "/tasks/" + TASK_ID;
Task task = Task.newBuilder()
  .setName(taskName)
  .setTaskTrackingViewConfig(
    TaskTrackingViewConfig.newBuilder()
      .setRoutePolylinePointsVisibility(
        VisibilityOption.newBuilder().setRemainingStopCountThreshold(3))
      .setEstimatedArrivalTimeVisibility(
        VisibilityOption.newBuilder().remainingDrivingDistanceMetersThreshold(5000))
      .setRemainingStopCountVisibility(
        VisibilityOption.newBuilder().setNever(true)))
  .build();

// Task request
UpdateTaskRequest updateTaskRequest =
  UpdateTaskRequest.newBuilder()  // No need for the header
      .setTask(task)
      .setUpdateMask(FieldMask.newBuilder().addPaths("taskTrackingViewConfig"))
      .build();

try {
  Task updatedTask = deliveryService.updateTask(updateTaskRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
      case NOT_FOUND:
        break;
      case PERMISSION_DENIED:
        break;
  }
  return;
}

REST

如要使用 HTTP 設定工作追蹤檢視設定視窗,請呼叫 UpdateTask

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks/<id>?updateMask=taskTrackingViewConfig`

<id> 是工作的專屬 ID

要求標頭必須包含一個值為 Bearer <token>Authorization 欄位,其中 <token>Fleet Engine 符記工廠所核發的憑證

要求主體必須包含 Task 實體:

  • 必填欄位:

    欄位價值
    taskTrackingViewConfig 設定工作追蹤,用於指定在何種情況下向使用者顯示的資料元素。

  • 選填欄位:

系統會忽略實體中的所有其他欄位,以便執行這項更新作業。

curl 指令範例:

# Set JWT, PROJECT_ID, and TASK_ID in the local environment
curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks/${TASK_ID}?updateMask=taskTrackingViewConfig" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "taskTrackingViewConfig": {
    "routePolylinePointsVisibility": {
      "remainingStopCountThreshold": 3
    },
    "estimatedArrivalTimeVisibility": {
      "remainingDrivingDistanceMetersThreshold": 5000
    },
    "remainingStopCountVisibility": {
      "never": true
    }
  }
}
EOM

將工作指派給車輛

您可以透過更新車輛的工作順序,將工作指派給運輸車輛。車輛的任務順序取決於運輸車輛的車輛停靠站清單,您可以為每個車輛停靠站指派一或多項工作。詳情請參閱「更新工作排序」。

如要將運送方式從一輛車變更為另一輛車,請關閉原始工作並重新建立,再指派新車。如果您更新已指派給其他車輛的任務順序,就會收到錯誤訊息。

更新工作排序

您可以透過驅動程式 SDK 或伺服器環境更新指派給車輛的訂單工作。請勿使用這兩種方法避免競爭狀況,並維護單一可靠資料來源。

更新車輛的工作順序時,也會執行以下操作:

  • 指派新的工作到車輛。
  • 關閉先前指派給車輛,但順序未更新的所有工作。

如要將運送方式從一輛車變更為另一輛車,請關閉原始工作並重新建立,再指派新車。如果您更新已指派給其他車輛的任務順序,就會收到錯誤訊息。

您隨時都可更新工作排序。

gRPC

以下範例說明如何使用 Java gRPC 程式庫更新車輛的工作順序:

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String VEHICLE_ID = "vehicle-8241890";
static final String TASK1_ID = "task-756390";
static final String TASK2_ID = "task-849263";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Vehicle settings
String vehicleName = "providers/" + PROJECT_ID + "/deliveryVehicles/" + VEHICLE_ID;
DeliveryVehicle deliveryVehicle = DeliveryVehicle.newBuilder()
    .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()  // 1st stop
       .setStop(VehicleStop.newBuilder()
           .setPlannedLocation(LocationInfo.newBuilder()
               .setPoint(LatLng.newBuilder()
                   .setLatitude(37.7749)
                   .setLongitude(122.4194)))
           .addTasks(TaskInfo.newBuilder().setTaskId(TASK1_ID))
           .setState(VehicleStop.State.NEW)))
    .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()  // 2nd stop
       .setStop(VehicleStop.newBuilder()
           .setPlannedLocation(LocationInfo.newBuilder()
               .setPoint(LatLng.newBuilder()
                   .setLatitude(37.3382)
                   .setLongitude(121.8863)))
           .addTasks(TaskInfo.newBuilder().setTaskId(TASK2_ID))
           .setState(VehicleStop.State.NEW)))
    .build();

// DeliveryVehicle request
UpdateDeliveryVehicleRequest updateDeliveryRequest =
  UpdateDeliveryVehicleRequest.newBuilder()  // No need for the header
      .setName(vehicleName)
      .setDeliveryVehicle(deliveryVehicle)
      .setUpdateMask(FieldMask.newBuilder().addPaths("remaining_vehicle_journey_segments"))
      .build();

try {
  DeliveryVehicle updatedDeliveryVehicle =
      deliveryService.updateDeliveryVehicle(updateDeliveryVehicleRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case NOT_FOUND:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

如要從伺服器環境更新車輛的工作順序,請對 UpdateDeliveryVehicle 發出 HTTP REST 呼叫:

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<id>?updateMask=remainingVehicleJourneySegments`

<id> 是車輛中運輸車輛的專屬 ID,可用來更新任務順序。這是您建立車輛時指定的 ID。

要求標頭必須包含一個值為 Bearer <token>Authorization 欄位,其中 <token>Fleet Engine 符記工廠所核發的憑證

要求主體必須包含 DeliveryVehicle 實體:

  • 必填欄位:

    欄位價值
    remainingVehicleJourneySegments 按照工作執行順序列出的工作歷程區隔清單。 系統會先執行清單中的第一個工作。
    剩餘的 VehicleJourneySegments[i].stop 清單中工作 i 的停止。
    剩餘的 VehicleJourneySegments[i].stop.plannedLocation 停靠站的預定位置。
    剩餘的 VehicleJourneySegments[i].stop.tasks 此車輛停靠站要執行的工作清單。
    remainingVehicleJourneySegments[i].stop.state State.NEW

  • 選填欄位:

系統會忽略實體中的所有其他欄位,以便執行這項更新作業。

curl 指令範例:

# Set JWT, PROJECT_ID, VEHICLE_ID, TASK1_ID, and TASK2_ID in the local
# environment
curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles/${VEHICLE_ID}?updateMask=remainingVehicleJourneySegments" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "remainingVehicleJourneySegments": [
    {
      "stop": {
        "state": "NEW",
        "plannedLocation": {
          "point": {
            "latitude": 37.7749,
            "longitude": -122.084061
          }
        },
        "tasks": [
          {
            "taskId": "${TASK1_ID}"
          }
        ]
      }
    },
    {
      "stop": {
        "state": "NEW",
        "plannedLocation": {
          "point": {
            "latitude": 37.3382,
            "longitude": 121.8863
          }
        },
        "tasks": [
          {
            "taskId": "${TASK2_ID}"
          }
        ]
      }
    }
  ]
}
EOM

車輛正在前往下一個停靠站

從停靠站出發或開始導航時,Fleet Engine 必須收到通知。您可以透過 Driver SDK,或從伺服器環境使用 gRPC 或 REST 通知 Fleet Engine。請勿使用這兩種方法避免競爭狀況,並維護單一可靠資料來源。

gRPC

以下範例說明如何使用 Java gRPC 程式庫,通知 Fleet Engine 車輛正在傳送到下一個停靠站。

    static final String PROJECT_ID = "my-delivery-co-gcp-project";
    static final String VEHICLE_ID = "vehicle-8241890";

    DeliveryServiceBlockingStub deliveryService =
      DeliveryServiceGrpc.newBlockingStub(channel);

    // Vehicle settings
    DeliveryVehicle deliveryVehicle = DeliveryVehicle.newBuilder()
        // Next stop marked as ENROUTE
        .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()  // 1st stop
           .setStop(VehicleStop.newBuilder()
               .setPlannedLocation(LocationInfo.newBuilder()
                   .setPoint(LatLng.newBuilder()
                       .setLatitude(37.7749)
                       .setLongitude(122.4194)))
               .addTasks(TaskInfo.newBuilder().setTaskId(TASK1_ID))
               .setState(VehicleStop.State.ENROUTE)))
        // All other stops marked as NEW
        .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()  // 2nd stop
           .setStop(VehicleStop.newBuilder()
               .setPlannedLocation(LocationInfo.newBuilder()
                   .setPoint(LatLng.newBuilder()
                       .setLatitude(37.3382)
                       .setLongitude(121.8863)))
               .addTasks(TaskInfo.newBuilder().setTaskId(TASK2_ID))
               .setState(VehicleStop.State.NEW)))
        .build();

    // DeliveryVehicle request
    UpdateDeliveryVehicleRequest updateDeliveryVehicleRequest =
      UpdateDeliveryVehicleRequest.newBuilder()  // No need for the header
          .setName(vehicleName)
          .setDeliveryVehicle(deliveryVehicle)
          .setUpdateMask(FieldMask.newBuilder().addPaths("remaining_vehicle_journey_segments"))
          .build();

    try {
      DeliveryVehicle updatedDeliveryVehicle =
          deliveryService.updateDeliveryVehicle(updateDeliveryVehicleRequest);
    } catch (StatusRuntimeException e) {
      Status s = e.getStatus();
      switch (s.getCode()) {
         case NOT_FOUND:
           break;
         case PERMISSION_DENIED:
           break;
      }
      return;
    }

REST

如要通知 Fleet Engine 通知車輛正在從伺服器環境傳送到下一個停靠站,請對 UpdateDeliveryVehicle 發出 HTTP REST 呼叫:

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<id>?updateMask=remainingVehicleJourneySegments`

<id> 是車輛中運輸車輛的專屬 ID,可用來更新任務順序。這是您建立車輛時指定的 ID。

要求標頭必須包含一個值為 Bearer <token>Authorization 欄位,其中 <token>Fleet Engine 符記工廠所核發的憑證

要求主體必須包含 DeliveryVehicle 實體:

  • 必填欄位:

    欄位價值
    remainingVehicleJourneySegments 其餘車輛停靠站清單,狀態會標示為 State.NEW。清單上第一個停靠站的狀態必須標示為 State.ENROUTE。

  • 選填欄位:

系統會忽略實體中的所有其他欄位。

curl 指令範例:

# Set JWT, PROJECT_ID, VEHICLE_ID, TASK1_ID, and TASK2_ID in the local
# environment
curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles/${VEHICLE_ID}?updateMask=remainingVehicleJourneySegments" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "remainingVehicleJourneySegments": [
    {
      "stop": {
        "state": "ENROUTE",
        "plannedLocation": {
          "point": {
            "latitude": 37.7749,
            "longitude": -122.084061
          }
        },
        "tasks": [
          {
            "taskId": "${TASK1_ID}"
          }
        ]
      }
    },
    {
      "stop": {
        "state": "NEW",
        "plannedLocation": {
          "point": {
            "latitude": 37.3382,
            "longitude": 121.8863
          }
        },
        "tasks": [
          {
            "taskId": "${TASK2_ID}"
          }
        ]
      }
    }
  ]
}
EOM

更新車輛位置資訊

如未使用 Driver SDK 更新車輛位置,可以直接呼叫 Fleet Engine 和車輛位置資訊。針對正在運作的車輛,Fleet Engine 預期每分鐘至少更新一次位置,最多每 5 秒更新一次位置。

gRPC

以下範例說明如何使用 Java gRPC 程式庫在 Fleet Engine 中更新車輛位置:

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String VEHICLE_ID = "vehicle-8241890";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Vehicle settings
String vehicleName = "providers/" + PROJECT_ID + "/deliveryVehicles/" + VEHICLE_ID;
DeliveryVehicle myDeliveryVehicle = DeliveryVehicle.newBuilder()
    .setLastLocation(DeliveryVehicleLocation.newBuilder()
        .setSupplementalLocation(LatLng.newBuilder()
            .setLatitude(37.3382)
            .setLongitude(121.8863))
        .setSupplementalLocationTime(now())
        .setSupplementalLocationSensor(DeliveryVehicleLocationSensor.CUSTOMER_SUPPLIED_LOCATION)
        .setSupplementalLocationAccuracy(DoubleValue.of(15.0)))  // Optional
    .build();

// DeliveryVehicle request
UpdateDeliveryVehicleRequest updateDeliveryVehicleRequest =
  UpdateDeliveryVehicleRequest.newBuilder()  // No need for the header
      .setName(vehicleName)
      .setDeliveryVehicle(myDeliveryVehicle)
      .setUpdateMask(FieldMask.newBuilder()
          .addPaths("last_location"))
      .build();

try {
  DeliveryVehicle updatedDeliveryVehicle =
      deliveryService.updateDeliveryVehicle(updateDeliveryVehicleRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case NOT_FOUND:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

如要使用 HTTP REST 更新 Fleet Engine 中的車輛位置,請呼叫 UpdateDeliveryVehicle

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<id>?updateMask=last_location`

<id> 是車輛中運送車輛或您想更新位置的專屬 ID。這是您建立車輛時指定的 ID。

要求標頭必須包含一個值為 Bearer <token>Authorization 欄位,其中 <token>Fleet Engine 符記工廠所核發的憑證

要求主體必須包含 DeliveryVehicle 實體:

  • 必填欄位:

    欄位價值
    lastLocation.supplementalLocation 車輛的位置。
    lastLocation.supplementalLocationTime 車輛在這個位置的最後已知時間戳記。
    lastLocation.supplementalLocationSensor 應填入 CUSTOMER_SUPPLIED_LOCATION。

  • 選填欄位:

    欄位價值
    lastLocation.supplementalLocationAccuracy 提供位置的精確度 (以公尺為單位)。

curl 指令範例:

# Set JWT, PROJECT_ID, VEHICLE_ID, TASK1_ID, and TASK2_ID in the local
# environment
curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles/${VEHICLE_ID}?updateMask=remainingVehicleJourneySegments" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "lastLocation": {
    "supplementalLocation": {"latitude": 12.1, "longitude": 14.5},
    "supplementalLocationTime": "$(date -u --iso-8601=seconds)",
    "supplementalLocationSensor": "CUSTOMER_SUPPLIED_LOCATION",
    "supplementalLocationAccuracy": 15
  }
}
EOM

車輛抵達停靠站

車輛抵達停靠站時,Fleet Engine 必須收到通知。您可以透過 Driver SDK 通知 Fleet Engine,從伺服器環境使用 gRPC 或 REST。請勿使用這兩種方法避免競爭狀況,並維護單一可靠資料來源。

gRPC

以下範例說明如何使用 Java gRPC 程式庫,通知 Fleet Engine 車輛抵達停靠站:

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String VEHICLE_ID = "vehicle-8241890";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Vehicle settings
String vehicleName = "providers/" + PROJECT_ID + "/deliveryVehicles/" + VEHICLE_ID;
DeliveryVehicle deliveryVehicle = DeliveryVehicle.newBuilder()
    // Marking the arrival at stop.
    .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()
       .setStop(VehicleStop.newBuilder()
           .setPlannedLocation(LocationInfo.newBuilder()
               .setPoint(LatLng.newBuilder()
                   .setLatitude(37.7749)
                   .setLongitude(122.4194)))
           .addTasks(TaskInfo.newBuilder().setTaskId(TASK1_ID))
           .setState(VehicleStop.State.ARRIVED)))
    // All other remaining stops marked as NEW.
    .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()  // 2nd stop
       .setStop(VehicleStop.newBuilder()
           .setPlannedLocation(LocationInfo.newBuilder()
               .setPoint(LatLng.newBuilder()
                   .setLatitude(37.3382)
                   .setLongitude(121.8863)))
           .addTasks(TaskInfo.newBuilder().setTaskId(TASK2_ID))
           .setState(VehicleStop.State.NEW))) // Remaining stops must be NEW.
    .build();

// DeliveryVehicle request
UpdateDeliveryVehicleRequest updateDeliveryVehicleRequest =
  UpdateDeliveryVehicleRequest.newBuilder()  // No need for the header
      .setName(vehicleName)
      .setDeliveryVehicle(deliveryVehicle)
      .setUpdateMask(FieldMask.newBuilder()
          .addPaths("remaining_vehicle_journey_segments"))
      .build();

try {
  DeliveryVehicle updatedDeliveryVehicle =
      deliveryService.updateDeliveryVehicle(updateDeliveryVehicleRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case NOT_FOUND:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

如要在伺服器環境的停靠站車輛抵達時通知 Fleet Engine,請對 UpdateDeliveryVehicle 發出 HTTP REST 呼叫:

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<id>?updateMask=remainingVehicleJourneySegments`

<id> 是車輛中運輸車輛的專屬 ID,可用來更新任務順序。這是您建立車輛時指定的 ID。

要求標頭必須包含一個值為 Bearer <token>Authorization 欄位,其中 <token>Fleet Engine 符記工廠所核發的憑證

要求主體必須包含 DeliveryVehicle 實體:

  • 必填欄位:

    欄位價值
    remainingVehicleJourneySegments 你抵達的停靠站狀態應設為 State.ARRIVED,接著是其他車輛停靠站清單,且狀態會標示為 State.NEW。

  • 選填欄位:

系統會忽略實體中的所有其他欄位,以便執行這項更新作業。

curl 指令範例:

# Set JWT, PROJECT_ID, VEHICLE_ID, TASK1_ID, and TASK2_ID in the local
# environment
curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles/${VEHICLE_ID}?updateMask=remainingVehicleJourneySegments" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "remainingVehicleJourneySegments": [
    {
      "stop": {
        "state": "ARRIVED",
        "plannedLocation": {
          "point": {
            "latitude": 37.7749,
            "longitude": -122.084061
          }
        },
        "tasks": [
          {
            "taskId": "${TASK1_ID}"
          }
        ]
      }
    },
    {
      "stop": {
        "state": "NEW",
        "plannedLocation": {
          "point": {
            "latitude": 37.3382,
            "longitude": 121.8863
          }
        },
        "tasks": [
          {
            "taskId": "${TASK2_ID}"
          }
        ]
      }
    }
  ]
}
EOM

車輛完成一個停靠站

車輛完成停靠點時,Fleet Engine 必須收到通知。因此,所有與停靠站相關的工作都會設為「已關閉」狀態。您可以透過驅動程式 SDK,或在伺服器環境中使用 gRPC 或 REST 通知 Fleet Engine。請勿使用這兩種方法避免競爭狀況,並維護單一可靠資料來源。

gRPC

以下範例說明如何使用 Java gRPC 程式庫,通知 Fleet Engine 車輛已完成停靠站。

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String VEHICLE_ID = "vehicle-8241890";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Vehicle settings
String vehicleName = "providers/" + PROJECT_ID + "/deliveryVehicles/" + VEHICLE_ID;
DeliveryVehicle deliveryVehicle = DeliveryVehicle.newBuilder()
    // This stop has been completed and is commented out to indicate it
    // should be removed from the list of vehicle journey segments.
    // .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()
    //    .setStop(VehicleStop.newBuilder()
    //        .setPlannedLocation(LocationInfo.newBuilder()
    //            .setPoint(LatLng.newBuilder()
    //                .setLatitude(37.7749)
    //                .setLongitude(122.4194)))
    //        .addTasks(TaskInfo.newBuilder().setTaskId(TASK1_ID))
    //        .setState(VehicleStop.State.ARRIVED)))
    // All other remaining stops marked as NEW.
    // The next stop could be marked as ENROUTE if the vehicle has begun
    // its journey to the next stop.
    .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()  // Next stop
       .setStop(VehicleStop.newBuilder()
           .setPlannedLocation(LocationInfo.newBuilder()
               .setPoint(LatLng.newBuilder()
                   .setLatitude(37.3382)
                   .setLongitude(121.8863)))
           .addTasks(TaskInfo.newBuilder().setTaskId(TASK2_ID))
           .setState(VehicleStop.State.NEW)))
    .build();

// DeliveryVehicle request
UpdateDeliveryVehicleRequest updateDeliveryVehicleRequest =
  UpdateDeliveryVehicleRequest.newBuilder()  // no need for the header
      .setName(vehicleName)
      .setDeliveryVehicle(deliveryVehicle)
      .setUpdateMask(FieldMask.newBuilder()
          .addPaths("remaining_vehicle_journey_segments"))
      .build();

try {
  DeliveryVehicle updatedDeliveryVehicle =
      deliveryService.updateDeliveryVehicle(updateDeliveryVehicleRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case NOT_FOUND:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

如要通知 Fleet Engine 關於伺服器環境的停靠站完成,請對 UpdateDeliveryVehicle 發出 HTTP REST 呼叫:

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<id>?updateMask=remaining_vehicle_journey_segments`

<id> 是車輛中運輸車輛的專屬 ID,可用來更新任務順序。這是您建立車輛時指定的 ID。

要求標頭必須包含一個值為 Bearer <token>Authorization 欄位,其中 <token>Fleet Engine 符記工廠所核發的憑證

要求主體必須包含 DeliveryVehicle 實體:

  • 必填欄位:

    欄位價值
    remaining_vehicle_journey_segments 你完成的停靠站應該就不再位於其餘車輛停靠站清單中。

  • 選填欄位:

系統會忽略實體中的所有其他欄位,以便執行這項更新作業。

curl 指令範例:

    # Set JWT, PROJECT_ID, VEHICLE_ID, TASK1_ID, and TASK2_ID in the local
    # environment
    curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles/${VEHICLE_ID}?updateMask=remainingVehicleJourneySegments" \
      -H "Content-type: application/json" \
      -H "Authorization: Bearer ${JWT}" \
      --data-binary @- << EOM
    {
      "remainingVehicleJourneySegments": [
        {
          "stop": {
            "state": "NEW",
            "plannedLocation": {
              "point": {
                "latitude": 37.3382,
                "longitude": 121.8863
              }
            },
            "tasks": [
              {
                "taskId": "${TASK2_ID}"
              }
            ]
          }
        }
      ]
    }
    EOM

更新工作

大部分的工作欄位都無法變更。不過,您可以直接更新工作實體,修改狀態、工作結果、工作結果時間、工作結果位置和屬性。舉例來說,如果任務尚未指派至車輛,您可以直接更新狀態來關閉工作。

gRPC

這是透過 gRPC 更新工作的例子。

REST

這個範例說明如何透過 REST 更新任務

關閉工作

如要關閉已指派給車輛的任務,請通知 Fleet Engine 通知車輛已完成工作發生停靠站,或從車輛停靠站清單中移除工作。為此,您可以設定其餘車輛停靠站清單,就像更新車輛的工作順序一樣。

如果工作尚未分配到需要關閉車輛,請將工作更新為已關閉狀態。不過,您無法重新開啟「已關閉」的工作。

關閉工作並不代表成功或失敗。表示不再將工作視為進行中。為追蹤運送資訊,請務必指出工作的實際結果,以便顯示貨品交付結果。

gRPC

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String TASK_ID = "task-8241890";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Task settings
String taskName = "providers/" + PROJECT_ID + "/tasks/" + TASK_ID;
Task task = Task.newBuilder()
  .setName(taskName)
  .setState(Task.State.CLOSED) // You can only directly CLOSE a
  .build();                    // task that is NOT assigned to a vehicle.

// Task request
UpdateTaskRequest updateTaskRequest =
  UpdateTaskRequest.newBuilder()  // No need for the header
      .setTask(task)
      .setUpdateMask(FieldMask.newBuilder().addPaths("state"))
      .build();

try {
  Task updatedTask = deliveryService.updateTask(updateTaskRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case NOT_FOUND:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

如要從伺服器環境將工作標示為結束,請向 UpdateTask 發出 HTTP REST 呼叫:

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks/<id>?updateMask=state`

<id> 是工作的專屬 ID

要求標頭必須包含一個值為 Bearer <token> 的「Authorization」欄位,其中 <token>由 Fleet Engine 權杖工廠核發的權杖

您必須在要求主體中加入 Task 實體:

  • 必填欄位:

    欄位價值
    state State.CLOSED

  • 選填欄位:

    欄位價值
    taskOutcome 結果:成功或結果失敗
    taskOutcomeTime 工作完成的時間。
    taskOutcomeLocation 工作完成的位置。除非供應商手動覆寫,否則 Fleet Engine 預設為最後的車輛位置。

系統會忽略實體中的所有其他欄位,以便執行這項更新作業。

curl 指令範例:

    # Set JWT, PROJECT_ID, and TASK_ID in the local environment
    curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks/${TASK_ID}?updateMask=state,taskOutcome,taskOutcomeTime" \
      -H "Content-type: application/json" \
      -H "Authorization: Bearer ${JWT}" \
      --data-binary @- << EOM
    {
      "state": "CLOSED",
      "taskOutcome": "SUCCEEDED",
      "taskOutcomeTime": "$(date -u --iso-8601=seconds)"
    }
    EOM

設定工作結果和結果位置

關閉工作並不代表工作成功或失敗,則表示工作不再處於進行中。為追蹤運送資訊,請務必指出工作的實際結果,以便顯示交付結果,並讓系統針對服務提供適當的帳單。設定後即無法變更工作結果。不過,您可以設定工作結果時間和工作結果位置。

處於「已關閉」狀態的工作,可以將其結果設定為「SUCCEEDED」(成功) 或「FAILED」(失敗)。Fleet Engine 只會針對狀態為「SUCCEEDED」的提交工作收費。

標記工作結果時,Fleet Engine 會自動在工作結果位置填入最後已知車輛位置。您可以覆寫這個行為。

gRPC

您可以選擇在設定結果時設定工作結果位置。設定位置可防止 Fleet Engine 將其設為上次車輛位置的預設位置。您也可以在日後覆寫設定的 Fleet Engine 工作結果位置。Fleet Engine 絕不會覆寫您提供的工作結果位置。無法為沒有設定工作結果的工作設定工作結果位置。您可以在同一項要求中,同時設定工作結果和工作結果位置。

以下範例說明如何使用 Java gRPC 程式庫將工作結果設為 SUCCEEDED,並設定工作完成的位置:

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String TASK_ID = "task-8241890";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Task settings
String taskName = "providers/" + PROJECT_ID + "/tasks/" + TASK_ID;
Task task = Task.newBuilder()
  .setName(taskName)
  .setTaskOutcome(TaskOutcome.SUCCEEDED)
  .setTaskOutcomeTime(now())
  .setTaskOutcomeLocation(               // Grand Indonesia East Mall
    LocationInfo.newBuilder().setPoint(
      LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
  .build();

// Task request
UpdateTaskRequest updateTaskRequest =
  UpdateTaskRequest.newBuilder()  // No need for the header
      .setTask(task)
      .setUpdateMask(FieldMask.newBuilder().addPaths("task_outcome", "task_outcome_time", "task_outcome_location"))
      .build();

try {
  Task updatedTask = deliveryService.updateTask(updateTaskRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case NOT_FOUND:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

如要從伺服器環境將工作標示為完成,請向 UpdateTask 發出 HTTP REST 呼叫:

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks/<id>?updateMask=taskOutcome,taskOutcomeTime,taskOutcomeLocation`

<id> 是工作的專屬 ID

要求標頭必須包含一個值為 Bearer <token>Authorization 欄位,其中 <token>Fleet Engine 符記工廠所核發的憑證

要求主體必須包含 Task 實體:

  • 必填欄位:

    欄位價值
    taskOutcome 結果:成功或結果失敗

  • 選填欄位:

    欄位價值
    taskOutcomeLocation 工作完成的位置。如未設定,Fleet Engine 會預設為最後的車輛位置。
    taskOutcomeTime 工作完成時的時間戳記。

系統會忽略實體中的所有其他欄位,以便執行這項更新作業。

curl 指令範例:

# Set JWT, PROJECT_ID, and TASK_ID in the local environment
curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks/${TASK_ID}?updateMask=taskOutcome,taskOutcomeTime,taskOutcomeLocation" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "taskOutcome": "SUCCEEDED",
  "taskOutcomeTime": "$(date -u --iso-8601=seconds)",
  "taskOutcomeLocation": {
    "point": {
      "latitude": -6.195139,
      "longitude": 106.820826
    }
  }
}
EOM

重新安排配送訂單

建立運送工作後,就無法變更預定位置。如要重新規劃路線,請關閉運送工作而不設定結果,然後使用更新後的預定位置建立新工作。 建立新工作後,請將工作指派給同一輛車。詳情請參閱關閉運送工作指派工作

使用餵食器和運輸車輛

如果您使用饋送車輛全天運送貨物至貨車,請將貨運轉運作業視為已排定的貨運車輛預定停靠工作模型。為確保位置追蹤功能準確詳情請參閱預定停靠站一文。

儲存運送狀態和其他中繼資訊

運送工作完成後,工作狀態和結果就會記錄在工作中。不過,您可能會想更新運送專屬的其他中繼資訊。如要儲存可在 Fleet Engine 服務外參照的其他中繼資訊,請使用與任務相關聯的 tracking_id 做為外部資料表中的鍵。

詳情請參閱「工作的生命週期」。

查詢車輛

您可以透過驅動程式 SDK 查詢車輛,也可以使用 gRPC 或 REST 從伺服器環境查詢。

gRPC

以下範例說明如何使用 Java gRPC 程式庫查詢車輛:

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String VEHICLE_ID = "vehicle-8241890";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Vehicle request
String name = "providers/" + PROJECT_ID + "/deliveryVehicles/" + VEHICLE_ID;
GetDeliveryVehicleRequest getVehicleRequest = GetDeliveryVehicleRequest.newBuilder()  // No need for the header
    .setName(name)
    .build();

try {
  DeliveryVehicle vehicle = deliveryService.getDeliveryVehicle(getVehicleRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case NOT_FOUND:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

如要從伺服器環境查詢車輛,請對 GetVehicle 發出 HTTP REST 呼叫:

`GET https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<vehicleId>`

<id> 是工作的專屬 ID

<vehicleId> 是要查詢的車輛 ID。

要求標頭必須包含一個值為 Bearer <token>Authorization 欄位,其中 <token>Fleet Engine 符記工廠所核發的憑證

要求主體必須為空白。

如果查詢成功,回應主體會包含車輛實體。

curl 指令範例:

# Set JWT, PROJECT_ID, and VEHICLE_ID in the local environment
curl -H "Authorization: Bearer ${JWT}" \
  "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles/${VEHICLE_ID}"

查詢工作

您可以使用 gRPC 或 REST 在伺服器環境中查詢工作。驅動程式 SDK 不支援查詢工作。

gRPC

以下範例說明如何使用 Java gRPC 程式庫查詢工作:

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String TASK_ID = "task-8597549";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Task request
String taskName = "providers/" + PROJECT_ID + "/tasks/" + TASK_ID;
GetTaskRequest getTaskRequest = GetTaskRequest.newBuilder()  // No need for the header
    .setName(taskName)
    .build();

try {
  Task task = deliveryService.getTask(getTaskRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case NOT_FOUND:
       break;

     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

如要從伺服器環境查詢工作,請向 GetTask 發出 HTTP REST 呼叫:

`GET https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks/<taskId>`

<id> 是工作的專屬 ID

<taskId> 是要查詢的工作 ID。

要求標頭必須包含一個值為 Bearer <token>Authorization 欄位,其中 <token>Fleet Engine 符記工廠所核發的憑證

要求主體必須為空白。

如果查詢成功,回應主體會包含工作實體。

curl 指令範例:

    # Set JWT, PROJECT_ID, and TASK_ID in the local environment
    curl -H "Authorization: Bearer ${JWT}" \
      "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks/${TASK_ID}"

根據追蹤 ID 查詢運送工作資訊

您可以透過下列方式查詢運送工作資訊,每個資訊都有各自的用途:

  • 由工作 ID 管理:使用者 (例如機群運算子) 可存取工作資料完整檢視畫面的使用者。
  • 透過追蹤 ID:用戶端軟體使用追蹤 ID,向使用者提供有限資訊,例如他們應該要在家裡有包裹。

本節說明如何透過追蹤 ID 查詢工作資訊。如果您想按照工作 ID 查詢工作,請參閱查詢工作

若要按追蹤 ID 查詢資訊,您可以使用下列其中一種方式:

查詢規定

  • 追蹤 ID 提供的運送資訊必須遵循「控管追蹤位置顯示設定」一文所述的瀏覽權限規則。

  • 使用 Fleet Engine 根據追蹤 ID 查詢運送資訊。驅動程式 SDK 不支援透過追蹤 ID 查詢資訊。如要使用 Fleet Engine 執行這項作業,請使用伺服器或瀏覽器環境。

  • 盡可能使用最小的符記來降低安全性風險。舉例來說,如果您使用 Delivery Consumer Token,所有 Fleet Engine Deliveries API 呼叫只會傳回與使用者相關的資訊,例如貨運公司或運送接收端。系統會遮蓋回應中的所有其他資訊。如要進一步瞭解憑證,請參閱建立授權的 JSON Web Token (JWT)

使用 gRPC 以 Java 進行查詢

以下範例說明如何使用 Java gRPC 程式庫,依據追蹤 ID 查詢運送工作的相關資訊。

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String TRACKING_ID = "TID-7449w087464x5";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Tasks request
String parent = "providers/" + PROJECT_ID;
GetTaskTrackingInfoRequest getTaskTrackingInfoRequest = GetTaskTrackingInfoRequest.newBuilder()  // No need for the header
    .setParent(parent)
    .setTrackingId(TRACKING_ID)
    .build();

try {
  TaskTrackingInfo taskTrackingInfo = deliveryService.getTaskTrackingInfo(getTaskTrackingInfoRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case NOT_FOUND:
       break;

     case PERMISSION_DENIED:
       break;
  }
  return;
}

使用 HTTP 查詢

如要從瀏覽器查詢運送工作,請對 GetTaskTrackingInfo 發出 HTTP REST 呼叫:

`GET https://fleetengine.googleapis.com/v1/providers/<project_id>/taskTrackingInfo/<tracking_id>`

<tracking_id> 是與工作相關聯的追蹤 ID。

要求標頭必須包含值為 Bearer <token> 的「Authorization」欄位,其中 <token>由 Fleet Engine 權杖工廠核發的憑證

如果查詢成功,回應主體會包含 taskTrackingInfo 實體。

curl 指令範例:

# Set JWT, PROJECT_ID, and TRACKING_ID in the local environment
curl -H "Authorization: Bearer ${JWT}" \
  "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/taskTrackingInfo/${TRACKING_ID}"

列出工作

您可以在伺服器或瀏覽器環境中列出工作。驅動程式 SDK 不支援清單工作。

列出工作會要求廣泛的工作存取權。列出工作僅適用於信任的使用者。提出清單工作要求時,請使用推送機群讀取器或推送超級使用者驗證權杖。

列出的工作包含下列欄位:

  • VehicleStop.planned_location
  • VehicleStop.state
  • VehicleStop.TaskInfo.taskId

大部分的工作屬性都可以篩選已列出的工作。如需篩選查詢語法,請參閱 AIP-160。下列清單列出可用於篩選的有效工作屬性:

  • attributes
  • delivery_vehicle_id
  • state
  • planned_location
  • task_duration
  • task_outcome
  • task_outcome_location
  • task_outcome_location_source
  • task_outcome_time
  • tracking_id
  • 類型

根據 Google API 改善提案,使用下列欄位格式:

欄位類型 格式 範例
時間戳記 RFC-3339 task_outcome_time = 2022-03-01T11:30:00-08:00
課程時長 後面加上 s 的秒數 task_duration = 120s
列舉 字串 state = CLOSED AND type = PICKUP
位置 point.latitudepoint.longitude planned_location.point.latitude > 36.1 AND planned_location.point.longitude < -122.0

如需篩選查詢運算子的完整清單,請參閱 AIP-160

如未指定篩選器查詢,則會列出所有工作。

工作清單會分頁。您可以在清單工作要求中指定頁面大小。如果指定頁面大小,傳回的工作數量就不會大於指定頁面大小。如果沒有頁面大小,則會使用合理的預設值。如果要求的頁面大小超過內部最大值,則會使用內部最大值。

工作清單可包含符記,用於讀取下一頁的結果。透過與上一個要求相同的要求使用頁面符記,以擷取下一頁的工作。如果傳回的頁面符記為空白,則沒有可擷取的工作。

gRPC

以下範例說明如何使用 Java gRPC 程式庫列出 deliveryVehicleId 和工作屬性的工作。成功的回應仍是空白的。空白回應表示提供的交付車輛 ID 沒有任何 Tasks。

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String TRACKING_ID = "TID-7449w087464x5";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Tasks request
String parent = "providers/" + PROJECT_ID;
ListTasksRequest listTasksRequest = ListTasksRequest.newBuilder()  // No need for the header
    .setParent(parent)
    .setFilter("delivery_vehicle_id = 123 AND attributes.foo = true")
    .build();

try {
  ListTasksResponse listTasksResponse = deliveryService.listTasks(listTasksRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case NOT_FOUND:
       break;

     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

如要從瀏覽器列出工作,請對 ListTasks 發出 HTTP REST 呼叫:

`GET https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks`

如要將篩選器套用到所列工作,請納入「filter」網址參數,並使用網址逸出的篩選器查詢做為值。

要求標頭必須包含一個值為 Bearer <token>Authorization 欄位,其中 <token>Fleet Engine 符記工廠所核發的憑證

如果查詢成功,回應主體會包含結構如下的資料:

    // JSON representation
    {
      "tasks": [
        {
          object (Task)
        }
      ],
      "nextPageToken": string,
      "totalSize": integer
    }

成功的回應也可以留空。如果回應空白,代表找不到符合指定篩選條件的工作。

curl 指令範例:

    # Set JWT, PROJECT_ID, and VEHICLE_ID in the local environment
    curl -H "Authorization: Bearer ${JWT}" \
      "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks?filter=state%20%3D%20OPEN%20AND%20delivery_vehicle_id%20%3D%20${VEHICLE_ID}"

列出送貨車

您可以透過伺服器或瀏覽器環境列出運輸車輛。驅動程式 SDK 不支援列出運輸車輛。

清單運送車輛會要求廣泛存取貨運車輛,因此僅適用於信任的使用者。提出清單傳遞車輛要求時,請使用推送機群讀取器或 Delivery 超級使用者驗證權杖。

列出的運送車輛會因回應大小的影響而遮蓋下列欄位:

  • CurrentRouteSegment
  • RemainingVehicleJourneySegments

您可以按照 attributes 屬性篩選運送車輛清單。舉例來說,如要查詢具有 my_key 鍵和 my_value 值的屬性,請使用 attributes.my_key = my_value。如要查詢多個屬性,請使用邏輯 ANDOR 運算子 (如同 attributes.key1 = value1 AND attributes.key2 = value2) 彙整查詢。如需篩選器查詢語法的完整說明,請參閱 AIP-160

您可以使用 viewport 要求參數,依地點篩選列出的運輸車輛。viewport 要求參數會使用兩個邊界座標來定義可視區域:high (東北部) 和 low (西南) 經緯度座標組合。如果要求包含的高緯度低於低緯度,要求就會遭到拒絕。

根據預設,配送車輛清單的頁面大小會以適當的頁面大小進行分頁。如果您指定頁面大小,要求只會傳回限制指定的車輛數量,或更少。如果要求的頁面大小超過內部最大值,則會使用內部最大值。預設與最大頁面大小皆為 100 輛車。

運輸車輛清單可包含符記,用於讀取下一頁的結果。只有在可供擷取的貨品更多頁時,回應中才會出現網頁符記。如要擷取下一頁的工作,請使用頁面符記搭配與上一個要求相同的要求。

gRPC

以下範例說明如何使用 Java gRPC 程式庫,列出含有特定屬性的特定區域運輸車輛。成功的回應仍是空白的。發生這種情況時,表示指定屬性中沒有任何具指定屬性的車輛已位於指定的可視區域中。

static final String PROJECT_ID = "my-delivery-co-gcp-project";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Tasks request
String parent = "providers/" + PROJECT_ID;
ListDeliveryVehiclesRequest listDeliveryVehiclesRequest =
  ListDeliveryVehiclesRequest.newBuilder()  // No need for the header
      .setParent(parent)
      .setViewport(
            Viewport.newBuilder()
              .setHigh(LatLng.newBuilder()
                  .setLatitude(37.45)
                  .setLongitude(-122.06)
                  .build())
              .setLow(LatLng.newBuilder()
                  .setLatitude(37.41)
                  .setLongitude(-122.11)
                  .build())
      .setFilter("attributes.my_key = my_value")
      .build();

try {
  ListDeliveryVehiclesResponse listDeliveryVehiclesResponse =
      deliveryService.listDeliveryVehicles(listDeliveryVehiclesRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
      case NOT_FOUND:
          break;

      case PERMISSION_DENIED:
          break;
  }
  return;
}

REST

如要從瀏覽器列出工作,請對 ListDeliveryVehicles 發出 HTTP REST 呼叫:

`GET https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles`

如要將篩選器套用到所列工作,請納入「filter」網址參數,並使用網址逸出篩選器查詢做為值。

要求標頭必須包含一個值為 Bearer <token>Authorization 欄位,其中 <token>Fleet Engine 符記工廠所核發的憑證

如果查詢成功,回應主體會包含結構如下的資料:

// JSON representation
{
  "deliveryVehicles": [
    {
      object (DeliveryVehicle)
    }
  ],
  "nextPageToken": string,
  "totalSize": integer
}

成功的回應也可以留空。發生這種情況時,代表找不到符合指定篩選查詢和可視區域的運送車輛。

curl 指令範例:

# Set JWT, PROJECT_ID, and VEHICLE_ID in the local environment
curl -H "Authorization: Bearer ${JWT}" \
  "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles?filter=attributes.my_key%20%3D%20my_value%20&viewport.high.latitude=37.45&viewport.high.longitude=-122.06&viewport.low.latitude=37.41&viewport.low.longitude=-122.11"

運送追蹤

您可透過以下兩種方式使用 Fleet Engine Deliveries API 啟用運送追蹤:

  • 建議使用:使用 JavaScript Shipment Tracking Library。這個程式庫能以視覺化方式呈現 Fleet Engine 追蹤的車輛位置和感興趣的地點。其中包含 JavaScript 地圖元件,可直接取代標準 google.maps.Map 物件,以及用來與 Fleet Engine 連線的資料元件。這個元件可讓您透過網頁或行動應用程式,提供可自訂的動畫運送追蹤體驗。

  • 在 Fleet Engine Deliveries API 上導入自己的運送追蹤功能。

關鍵是根據追蹤 ID 來查詢運送工作

如果使用 Delivery Consumer Role,所有 Fleet Engine Deliveries API 呼叫只會傳回與貨運公司或接收器相關的資訊。系統會遮蓋回應中的所有其他資訊。您有責任驗證使用者。此外,系統會根據已完成的工作篩選位置資訊。在無法使用的任務期間,不會與使用者分享任何位置資訊。

Logging

您可以設定 Fleet Engine,將遠端程序呼叫 (RPC) 記錄傳送至 Cloud Logging。詳情請參閱「記錄」一文。

授權角色和權杖

如「管理車輛和工作生命週期」和個別用途的說明說明,如要呼叫 Fleet Engine,就必須使用以服務帳戶憑證簽署的 JSON Web Token 進行驗證。用來核發憑證的服務帳戶可能會有一或多個角色,每個角色分別授予不同的權限集。

詳情請參閱驗證與授權

排解常見問題

如果遇到任何問題,請參考以下各節的說明。

彈性

我們不會使用 Fleet Engine 做為資料來源。您應負責在必要時還原系統狀態,而不依賴 Fleet Engine。

Fleet Engine 中的遺失狀態

使用 Fleet Engine 時,請實作用戶端,讓系統在發生故障時自行修復。舉例來說,Fleet Engine 嘗試更新車輛時,可能會回應錯誤,指出車輛不存在。接著,用戶端應以新的狀態重新建立車輛。雖然這個問題極少發生,但請確保系統具有足夠的彈性來處理問題。

在極少數或 Fleet Engine 發生災難性故障的情況下,您可能需要重新建立大部分或所有車輛和工作。如果建立頻率過高,可能會因配額檢查而再次導致部分要求失敗,因為這項檢查是為了避免阻斷服務 (DOS) 攻擊。在本案例中,使用輪詢策略減緩重建率。

駕駛應用程式中的遺失狀態

如果驅動程式應用程式當機,應用程式必須在驅動程式 SDK 中重新建立目前狀態。應用程式應嘗試重新建立工作,確保工作存在,並還原目前狀態。應用程式也應重新建立並明確設定 Driver SDK 的停靠站清單。

常見問題

如果駕駛人停止任務順序,該怎麼辦?

在這種情況下,請先更新工作順序,然後照常執行,以標示停靠站、工作完成和其他詳細資料。否則系統可能會不一致、預計到達時間有誤,並回報非預期的錯誤。