Fleet Engine Deliveries API を使用すると、配達の起点と終点のフリート アクティビティをモデル化できます。Deliveries API は、Android および iOS 用の Driver SDK で公開され、HTTP REST または gRPC 呼び出しを介して直接使用することもできます。
初期設定を行う
Fleet Engine Deliveries API は、Google Cloud コンソールで構成します。コンソール内で行う手順と、認可用の JSON Web Token を作成する方法については、認証と認可をご覧ください。コンソールの使用方法については、Google Cloud コンソールのドキュメントをご覧ください。
設定を確認する
サービス アカウントを作成したら、設定が完了し、配送車両を作成できることを確認します。ワークフローのこの段階で検証を行うことで、プロジェクトの設定時に発生する可能性がある一般的な承認の問題に対処できます。設定の確認のガイドの手順を行います。
このガイドでは、gcloud
コマンドライン ユーティリティを使用して、認証トークンの署名とトライアル配信車両の作成という、設定の 2 つの重要な部分をテストする方法について詳しく説明します。
また、Fleet Engine Auth のサンプル スクリプトを使用して設定をテストすることもできます。
クライアント ライブラリ
クライアント ライブラリは、いくつかの一般的なプログラミング言語で公開されています。これらのライブラリにより、未加工の REST や gRPC よりもデベロッパー エクスペリエンスが向上します。サーバー アプリケーション用のクライアント ライブラリを取得する手順については、クライアント ライブラリをご覧ください。
このドキュメントの Java の例は、gRPC に精通していることを前提としています。
データ構造
Deliveries API は、次の 2 つのデータ構造を使用して、荷物の集配をモデル化します。
- 荷物の輸送に使用された配送車両。
- 荷物の集荷と配達のタスク。
また、タスクを使用して、1 日を通してドライバーの休憩やスケジュールされた停車地をモデル化することもできます。
配達用車両
配達車両は、荷物をデポから配達場所へ、およびピックアップ場所からデポに輸送します。場合によっては、集荷場所から配達場所に直接荷物を輸送することもできます。
Driver SDK を使用して Fleet Engine に DeliveryVehicle
オブジェクトを作成し、配送とフリート追跡のために位置情報の更新を送信できます。
タスク
各車両にはタスクが割り当てられています。たとえば、集荷や配達のタスク、ドライバーの必要な休憩、ドロップ ボックスや顧客のいる場所での停車地などです。各タスクには一意のタスク ID が必要ですが、同じトラッキング ID を共有できます。タスクとそのスケジュール順序に基づいて、各タスクの ETA ウィンドウが計算されます。
Driver SDK タスク マネージャーを使用して Fleet Engine でタスクを作成する。
配送タスク
配送タスクは、荷物の集荷または持ち込みに関連するものです。 配送タスクを作成するときに、荷物追跡番号または ID を指定する必要があります。また、タスクの完了、駐車場を探す、引き継ぎ場所まで徒歩で移動するための追加の時間を考慮するため、滞在時間を指定する必要があります。
- 集荷場所と荷物追跡番号または ID を指定して、荷物を受け取る集荷タスクを作成します。
- 配送場所と荷物追跡番号または ID を指定して、荷物を配達する配送タスクを作成します。
利用不可のタスク
車両の集荷や配達を利用できない期間に「利用不可」タスクを作成する。たとえば、車両に給油する休憩でも、ドライバーの休憩休憩でもかまいません。タスクの作成時に挿入点の長さを指定します。特定の場所で休憩を取る必要はありませんが、場所を指定することで 1 日の到着予定時刻(ETA)がより正確になります。
利用不能タスクの間、位置情報はエンドユーザーと共有されません。たとえば、フリート トラッキング ライブラリを使用して、配達車両の場所はフリート管理者に対して非表示になります。
スケジュール設定された停止タスク
配達車両が停車する停車地をモデル化するには、スケジュールされた停車タスクを作成します。たとえば、同じ場所での他の配達や集荷とは関係なく、特定の場所での日次スケジュールに基づく収集停留所に対するスケジュールされた停止タスクを作成できます。また、ドロップ ボックスからの撮影や、フィーダーと車両の間の乗り換えや、サービス センターやサービス ポイントでの停車地をモデル化するために、スケジュールされた停車タスクを作成することもできます。
各データ構造に含まれる特定のフィールドについては、DeliveryVehicle
(gRPC、REST)と Task
(gRPC、REST)の API リファレンス ドキュメントをご覧ください。
タスク ID のガイドライン
タスク ID は一意である必要があり、個人を特定できる情報(PII)やクリアテキストデータを公開してはなりません。タスク ID は、次の形式の要件も遵守する必要があります。
- ID は有効な Unicode 文字列にする必要があります。
- ID は 64 文字以下にしてください。
- ID は Unicode Normalization Form C に従って正規化されます。
- ID に ASCII 文字「/」、「:」、「\」、「?」、「#」を含めることはできません。
適切なタスク ID の例を次に示します。
- 566c33d9-2a31-4b6a-9cd4-80ba1a0c643b
- e4708eabcfa39bf2767c9546c9273f747b4626e8cc44e9630d50f6d129013d38
- NTA1YTliYWNkYmViMTI0ZmMzMWFmOWY2NzNkM2Jk
次の表に、不適切なタスク ID の例を示します。
不適切なタスク ID | 理由 |
---|---|
2019 年 8 月 31 日-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
オブジェクトは、配達車両(ファースト ワンマイルまたはラスト ワンマイル)を表します。次のコマンドを使用して DeliveryVehicle
オブジェクトを作成します。
- Fleet Engine API の呼び出しに使用されるサービス アカウントを含む Google Cloud プロジェクトのプロジェクト ID。
- お客様が所有する車両 ID。
車両 ID は車両ごとに一意である必要があります。車両にアクティブなタスクがない場合を除き、別の車両に再利用しないでください。
UpdateDeliveryVehicle
を呼び出すときは NOT_FOUND エラーを確認してから、必要に応じて CreateDeliveryVehicle
を呼び出して新しい車両を作成します。UpdateDeliveryVehicle
を使用して更新されていない DeliveryVehicle
オブジェクトは、7 日後に自動的に削除されます。すでに存在するプロジェクト ID/車両 ID のペアで CreateDeliveryVehicle
を呼び出すと、エラーが発生します。
車両属性
DeliveryVehicle
エンティティには DeliveryVehicleAttribute
の繰り返しフィールドが含まれています。ListDeliveryVehicles
API には、返される DeliveryVehicle
エンティティを、指定された属性を持つエンティティに制限できる filter
フィールドが含まれています。DeliveryVehicleAttribute
は、Fleet Engine のルーティング動作に影響しません。
属性には個人情報や機密情報を含めないでください。この項目はユーザーに表示される可能性があります。
タスクのライフサイクル
Fleet Engine のタスクは、Deliveries API gRPC または REST インターフェースを使用して作成、更新、照会できます。
Task
オブジェクトには、ライフサイクル全体の進捗状況を追跡する状態フィールドがあります。値が OPEN から CLOSED に変化します。新しいタスクは OPEN 状態で作成されます。これは次のいずれかを意味します。
- タスクはまだ配達車両に割り当てられていません。
- 配達車両は、タスクに割り当てられた車両停留所をまだ通過していません。
車両にタスクを割り当てることができるのは、車両が OPEN 状態の場合のみです。
タスクをキャンセルするには、そのタスクを車両停留所のリストから削除します。 ステータスは自動的に CLOSED に設定されます。
タスクの車両がタスクの車両の停止を完了したら、タスクの結果フィールドを [SUCCEEDED] または [FAILED] に更新し、イベントのタイムスタンプを指定します。タスクの結果は、タスクの完了前後にいつでも設定できますが、設定できるのは 1 回だけです。
JavaScript Fleet Tracking ライブラリは、タスクの結果を表示できます。タスクのステータスは自動的に CLOSED に設定されます。詳細については、JavaScript Fleet Tracking Library を使用したフリートのトラッキングをご覧ください。
車両と同様に、7 日後に更新されていないタスクは削除され、既存の ID でタスクを作成しようとするとエラーが返されます。
注: Fleet Engine では、タスクの明示的な削除はサポートされていません。更新がないまま 7 日が経過すると、タスクは自動的に削除されます。タスクデータを 7 日間以上保持する場合は、ご自身でその機能を実装する必要があります。
タスクの属性
Task
エンティティには TaskAttribute
の繰り返しフィールドがあり、このフィールドには文字列、数値、ブール値の 3 つのタイプのいずれかの値を指定できます。ListTasks
API には、返される Task
エンティティを、指定された属性を持つエンティティに制限できる filter
フィールドがあります。TaskAttribute
は、Fleet Engine のルーティング動作に影響しません。
属性には個人情報や機密情報を含めないでください。この項目はユーザーに表示される可能性があります。
車両とタスクのライフサイクルの管理
システムで車両とタスクのライフサイクルを管理するには、Fleet Engine Deliveries API を使用して、車両とそれに関連するタスクを作成、更新、追跡します。内部システムは、Fleet Engine Deliveries API がユーザーに代わって拡張するデータの信頼できるソースとして機能します。
同時に、ドライバ アプリケーションは、デバイスの位置情報とルート情報を更新するために、Fleet Engine と直接通信します。このモデルにより、Fleet Engine はリアルタイムの位置情報を効率的に管理し、追跡ライブラリに直接送信できます。これにより、注文のステータスの更新が必要な利用者がこれを使用できます。
たとえば、次のシナリオがあるとします。
- ドライバーが配達所の近くに来ると、Fleet Engine がデバイスの位置情報を追跡ライブラリに送信します。ユーザー アプリケーションは、この位置情報を使用して消費者に荷物が近くにあることを警告します。
- ドライバーは配送を完了したら、ドライバー アプリで [配送済み] ボタンをクリックします。
- これにより情報がバックエンド システムに送信され、必要なビジネス検証と検証ステップが実行されます。
- システムはタスクを「SUCCEEDED」と確認し、Deliveries API を使用して Fleet Engine を更新します。
次の図は、これらのプロセスを一般的なレベルで示しています。また、システム、クライアント、Fleet Engine の間の標準的な関係も表示されます。
クライアント トークンの管理
ドライバー アプリケーションから Fleet Engine に直接送信される位置情報の更新には、認証トークンが必要です。クライアントから Fleet Engine への更新を処理する場合は、ドライバ アプリケーションにスコープを限定したトークンを提供し、Fleet Engine でデバイスの位置情報のみを更新できるようにすることをおすすめします。このタイプのトークンでは、Fleet Engine Delivery の信頼されていないドライバ ユーザーと呼ばれるサービス アカウント ロールを使用します。これにより、低信頼環境とみなされるモバイル デバイスからの呼び出しが最小権限の原則に従うようになります。
他のサービス アカウントのロール
特定のタスクの更新など、信頼できないドライバのロールに制限されない Fleet Engine の直接更新をドライバ アプリケーションに許可する場合は、信頼できるドライバのロールを使用します。信頼できるドライバのロールを使用するモデルの詳細については、信頼できるドライバモデルをご覧ください。
信頼できない信頼できるドライバーのロールの使用方法について詳しくは、Cloud プロジェクトのセットアップをご覧ください。
勤務日のモデリング
次の表に、配送および物流会社のファースト ワンマイルまたはラスト ワンマイルのドライバーの勤務時間を示します。会社によって詳細が異なる場合もありますが、勤務日をモデル化する方法を確認できます。
時間 | アクティビティ | モデリング |
---|---|---|
日が始まってから 24 時間以内 | コーディネーターは、配送車両またはルートに荷物を割り当てます。 | 出荷、集荷、休憩などのタスクは、Fleet Engine で事前に作成できます。たとえば、集荷タスク、配送タスク、配達不能の日時の指定、停車のスケジュールを作成できます。 配達パッケージのセットと配達順序が確定したら、タスクを車両に割り当てる必要があります。 |
1 日の始まり | Driver はドライバー アプリにログインして、デポでその日をスタートします。 | Delivery Driver API を初期化します。必要に応じて、Fleet Engine で配達車両を作成します。 |
ドライバーが荷物を配達車両に積み込み、荷物をスキャンする。 | 配送タスクが事前に作成されていない場合は、スキャン時に配送タスクを作成します。 | |
ドライバが、実行するタスクの順序を確認します。 | 前もって作成されていない場合は、配送集荷タスク、予約不可の時間帯、停車地のスケジュールを作成します。 | |
ドライバーはデポを離れ、次の数のタスクの競合にコミットします。 | 完了順序をコミットして、すべてのタスクまたはタスクのサブセットを車両に割り当てます。 | |
荷物を配達するドライバー。 | 配送の停車地に到着したら、停車地に到着する車両に関連する操作を行います。配送後に、配送タスクを終了します。また、必要に応じて配送ステータスなどのメタ情報を格納します。停車地ですべてのタスクを完了し、次の停車地への走行を開始する前に、車両による停車地の完了や次の停車地までの車両に関連する操作を行います。 | |
ドライバーはフィーダー車両に乗って、追加の荷物を配達車両に積み込む。 | フィーダー車両と配達車両間の乗り換えの待ち合わせ場所は、停車地としてモデル化する必要があります。 配送を転送してスキャンした後、配送タスクを作成します(まだ作成していない場合)。次に、タスクを車両に割り当て、タスクの順序を更新して、タスクの完了順序を更新します。 |
|
ドライバーが集荷リクエストの通知を受け取ります。 | 集荷リクエストを承認したら、荷物の受け取りタスクを作成します。次に、タスクを車両に割り当て、タスクの順序を更新して、タスクの実行順序を更新します。 | |
正午 | 昼食をとるドライバー。 | ビジネスが利用不能タスクに関連付けられている場合は、他のタスクと同様に扱います。車両に関連するアクションの実行、停車地への到着、車両の停車停止、次の停車場所への経路の車両など。 それ以外の場合は、広告ブレークの終了までこれ以上のアクションは不要です。 次のタスクと残りのタスクを確認し、タスクの順序を更新することで、タスクを削除します。 |
ドライバーが荷物を受け取る。 | この場所は、配達の停車地と同じようにモデル化されています。車両の停車地への到着とタスクの終了に関連するアクションを実行し、必要に応じて配送ステータスやその他のメタ情報を保存します。 停車地ですべてのタスクを完了し、次の停車地への運転を開始する前に、車両による停車地の完了および次の停車地までの車両に関連する操作を実行します。 注: 請求が正しく行われるように、すべての集荷に対応する配達タスクを設定する必要があります。その日にドライバーの同じ経路上の別の場所に集荷を配達する場合は、その配達タスクを、経路上の他の配達タスクとしてモデル化することをおすすめします。ドライバーがピックアップを車両基地に戻す場合は、車両基地の目的地で配達タスクを作成することをおすすめします。 | |
ドライバーが、配達先を配達する停車場所を設定して、ドロップ ボックスから荷物を受け取る。 | 他の乗車地点と同じようにモデル化されます。車両の停車地への到着やタスクの終了に関連するアクションを実行する。停車地ですべてのタスクを完了し、次の停車地への運転を開始したら、車両による停車と次の停車地までの車両に関連する操作を行います。 | |
ドライバーが、荷物が別の場所に配送されるという通知を受け取った。 | 元の配送タスクのステータスを「COMPLETED」に設定し、新しい配送場所に新しい配送タスクを作成します。詳しくは、配送ルートの変更をご覧ください。 | |
ドライバーが荷物を配達しようとしましたが、できませんでした。 | これは配信が正常に停止する場合と同様にモデル化され、配信タスクを完了としてマークします。停車地に到着する車両に関連するアクションを実行します。配送に失敗した場合は、タスクを閉じ、必要に応じて配送ステータスとその他のメタ情報を保存します。停車地ですべてのタスクを完了し、次の停車地への運転を開始する前に、車両による停車地の完了および次の停車地までの車両に関連する操作を実行します。 | |
ドライバーに荷物を留め置く(配送しない)よう通知されました。 | 通知を受信して確認したら、タスクのステータスを COMPLETED に設定します。 | |
ドライバーは、次の荷物を配達するように通知され、コミットされた配達注文が変更されました。 | タスクの順序を更新します。 | |
ドライバーが品切れの配送を選択しました。 | タスクの順序を更新してから、通常どおり処理を続行します。 | |
ドライバーが複数の荷物を 1 か所に配達している。 | これは、単一の配送の配達先と同じようにモデル化されます。停車地に到着したら、停車地に到着する車両に関連する操作を行います。配送を配送したら、各タスクをクローズします。また、必要に応じて店舗の配送ステータスなどのメタ情報も保存します。停車地ですべてのタスクを完了し、次の停車地への運転を開始する前に、車両による停車地の完了および次の停車地までの車両に関連する操作を実行します。 | |
1 日の終わり | ドライバーがデポに戻ります。 | 配車中に集荷された荷物をドライバーが持ち帰った場合、正しい請求が行われるように、配達タスクとして各パッケージを作成して閉じる必要もあります。これを行うには、他の配達停車地と同様に車両基地をモデル化します。 車両基地を配達の停車地として使用しない場合でも、必要に応じてその車両基地をスケジュールされた停車地としてモデル化できます。これにより、ドライバーは車両基地に戻るルートを確認し、到着予定時刻を可視化できます。 |
位置情報の更新について
配達車両が停車地を含む停車地から配送中になると、次の停車地に到着するまで、位置情報の更新内容が Fleet Engine に送信されます。これらのイベントは自動的に検出されないため、プログラムでマークを付ける必要があります。交通手段の変更を検出するライブラリを使用して、Fleet Engine への必要な通知の送信をトリガーします。
ドライバーが運転していないときは、位置情報の更新を停止する必要があります。これは、誰かが建物内にいると位置情報信号の品質が大幅に低下するためです。
位置情報の更新頻度は Driver SDK 内で設定できます。デフォルトでは、10 秒ごとに更新が送信されます。
車両の停車地と配達場所
車両停車とは、配達車両が配達タスクなどのタスクを完了することです。それは、集荷場などのアクセス ポイントや、道路に挟まれた場所のいずれかです。
配達場所とは、荷物が配達または集荷される場所です。配達場所との移動には、車両の停留所から歩いていくことが必要になる場合があります。
たとえば、ショッピング モール内の店舗に荷物を配達する場合、配達車両は店舗に最も近い入り口近くの駐車場に停車します。これは車両の停車地です。その後、ドライバーは車両の停車地から歩いて、店舗があるショッピング モール内の場所まで移動します。これは配達場所です。
ユーザーが荷物追跡を快適に行うには、配送タスクが車両停留所にどのように割り当てられるかを考慮してください。また、配送タスクの残りの車両停留所の数は、配送の進行状況を確認できるようにユーザーに報告されることに注意してください。
たとえば、ドライバーが 1 つのオフィスビルに多数の配達を行っている場合は、すべての配達タスクを 1 つの車両停留所に割り当てることを検討してください。各配送タスクが独自の車両停留所に割り当てられると、ユーザーにとっての配送追跡エクスペリエンスはあまり役に立ちません。車両が目的地の前にある停車地の数を制限内に収めると、追跡が利用可能になります。車両の停車地が短時間に多数あると、ユーザーが配達の進捗状況を追跡するのに十分な時間が得られません。
モバイル SDK の使用
Driver SDK を呼び出す前に、初期化してください。
Delivery Driver API の初期化
Driver 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)が含まれていないことを確認してください。
車両を作成する
車両は、Driver SDK またはサーバー環境から作成できます。
gRPC
新しい車両を作成するには、Fleet Engine に対して CreateDeliveryVehicle
呼び出しを行います。CreateDeliveryVehicleRequest
オブジェクトを使用して、新しい配達車両の属性を定義します。Name
フィールドに指定された値は、ユーザー指定の ID に関する API ガイダンスに従って無視されます。車両の ID を設定するには、DeliveryVehicleId
フィールドを使用する必要があります。
DeliveryVehicle
を作成するときに、必要に応じて次の 2 つのフィールドを指定できます。
- 属性
- LastLocation
その他のフィールドはすべて設定しないでください。設定しない場合、これらのフィールドは読み取り専用であるか、UpdateDeliveryVehicle
呼び出しによってのみ更新できるため、Fleet Engine はエラーを返します。
オプション フィールドを設定せずに車両を作成するには、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> は、フリート内の配送車両の一意の識別子です。
リクエスト ヘッダーには、値 Bearer <token> を持つフィールド Authorization が含まれている必要があります。ここで、<token> はFleet Engine トークン ファクトリによって作成されたトークンです。
POST 本文は、作成する DeliveryVehicle
エンティティを表します。次のオプション フィールドを指定できます。
- 属性
- 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
Fleet Engine は、ユーザー指定の ID の API ガイダンスに従い、DeliveryVehicle
エンティティの name
フィールドを無視します。その他のフィールドは設定しないでください。設定しない場合、これらのフィールドは読み取り専用であるか、UpdateDeliveryVehicle
呼び出しを介してのみ更新できるため、Fleet Engine はエラーを返します。
フィールドを設定せずに車両を作成するには、POST リクエストの本文を空のままにします。新しく作成された車両には、POST URL の 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}"
集荷タスクを作成する
出荷集荷タスクは、Driver SDK またはサーバー環境から作成できます。
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 がない場合は、Universally Unique Identifier(UUID)を生成することができます。
リクエスト ヘッダーには、値 Bearer <token> を持つフィールド Authorization が含まれている必要があります。ここで、<token> はFleet Engine トークン ファクトリによって作成されたトークンです。
リクエストの本文には Task
エンティティを含める必要があります。
必須項目:
項目 値 type Type.PICKUP 使って State.OPEN trackingId 配送の追跡に使用している番号または ID。 planLocation タスクが完了する場所(この場合は配送の集荷場所)。 taskDuration 受け取り場所での集荷にかかると予想される時間(秒単位)。 省略可能項目:
項目 値 targetTimeWindow タスクが完了するまでの時間枠。現時点では、これはルーティングの動作には影響しません。 属性 カスタムのタスク属性のリスト。各属性には一意のキーが必要です。
エンティティ内の他のフィールドはすべて、作成で無視されます。割り当てられた DeliveryVehicleId がリクエストに含まれている場合、Fleet Engine は例外をスローします。タスクの割り当てには UpdateDeliveryVehicleRequests
を使用します。詳しくは、車両にタスクを割り当てるをご覧ください。
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
配送タスクを作成する
出荷タスクは、Driver SDK またはサーバー環境から作成できます。
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
サーバー環境から出荷配送タスクを作成するには、「CreateTask」に対して HTTP REST 呼び出しを行います。
POST https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks?taskId=<id>
<id> は、タスクの一意の識別子です。荷物追跡番号は使用できません。システムにタスク ID がない場合は、Universally Unique Identifier(UUID)を生成することができます。
リクエスト ヘッダーには、値 Bearer <token> を持つフィールド Authorization が含まれている必要があります。ここで、<token> はFleet Engine トークン ファクトリによって作成されたトークンです。
リクエストの本文には Task
エンティティを含める必要があります。
必須項目:
項目 値 type Type.DELIVERY 使って State.OPEN trackingId 配送の追跡に使用している番号または ID。 planLocation タスクを完了する場所。この場合は、この配送の配達先です。 taskDuration 配達場所で荷物を発送するまでの予想時間(秒単位)。 省略可能項目:
項目 値 targetTimeWindow タスクが完了するまでの時間枠。現時点では、これはルーティングの動作には影響しません。 属性 カスタムのタスク属性のリスト。各属性には一意のキーが必要です。
エンティティ内の他のフィールドはすべて、作成で無視されます。割り当てられた DeliveryVehicleId がリクエストに含まれている場合、Fleet Engine は例外をスローします。タスクの割り当てには UpdateDeliveryVehicleRequests
を使用します。詳しくは、車両にタスクを割り当てるをご覧ください。
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
次の例は、Java gRPC ライブラリを使用して 2 つのタスク(1 つは配達用、もう 1 つは同じ場所での集荷用)を作成する方法を示しています。
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
>省略可能フィールド:
項目 値 header 「DeliveryRequestHeader」
requests
内の各 CreateTasksRequest
要素は、CreateTask
リクエストと同じ検証ルールに合格する必要がありますが、parent
フィールドと header
フィールドはオプションです。設定する場合は、トップレベル BatchCreateTasksRequest
の対応するフィールドと同じにする必要があります。それぞれの特定の検証ルールについては、発送タスクの作成と配送タスクの作成をご覧ください。
詳細については、BatchCreateTasks
の API リファレンス ドキュメント(gRPC、REST)をご覧ください。
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
スケジュール設定された利用不可
利用不可を示すタスク(ドライバーの休憩や車両の給油など)は、Driver SDK またはサーバー環境から作成できます。スケジュール設定された利用不可のタスクにトラッキング 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 がない場合は、Universally Unique Identifier(UUID)を生成することができます。
リクエスト ヘッダーには、値 Bearer <token> を持つフィールド Authorization が含まれている必要があります。ここで、<token> はFleet Engine トークン ファクトリによって作成されたトークンです。
リクエストの本文には Task
エンティティを含める必要があります。
必須項目:
項目 値 type タイプ.UNAVAILABLE 使って State.OPEN taskDuration 休憩の長さ(秒)。 省略可能項目:
項目 値 planLocation 特定の場所で休憩を取る必要がある場合、休憩の場所。
エンティティ内の他のフィールドはすべて、作成で無視されます。割り当てられた DeliveryVehicleId がリクエストに含まれている場合、Fleet Engine は例外をスローします。タスクの割り当てには UpdateDeliveryVehicleRequests
を使用します。詳しくは、車両にタスクを割り当てるをご覧ください。
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
予定された停車地
スケジュールされた停止タスクは、Driver SDK またはサーバー環境から作成できます。スケジュールされた停止タスクにトラッキング 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 がない場合は、Universally Unique Identifier(UUID)を生成することができます。
リクエスト ヘッダーには、値 Bearer <token> を持つフィールド Authorization が含まれている必要があります。ここで、<token> はFleet Engine トークン ファクトリによって作成されたトークンです。
リクエストの本文には Task
エンティティを含める必要があります。
必須項目:
項目 値 type タイプ.SCHEDULED_STOP 使って State.OPEN planLocation 停車地の場所。 taskDuration 想定される停車地の長さ(秒)。 省略可能フィールド:
- なし
エンティティ内の他のフィールドはすべて、作成で無視されます。割り当てられた DeliveryVehicleId がリクエストに含まれている場合、Fleet Engine は例外をスローします。タスクの割り当てには UpdateDeliveryVehicleRequests
を使用します。詳しくは、車両にタスクを割り当てるをご覧ください。
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> は、タスクの一意の識別子です。
リクエスト ヘッダーには、値 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
タスク トラッキングの公開設定を設定する
Shipment Tracking ライブラリ内のデータと、GetTaskTrackingInfo
の呼び出しから返されるデータの表示は、タスクに TaskTrackingViewConfig
を設定することで、タスクごとに制御できます。詳しくは、アクティブな車両タスクをご覧ください。これは、タスクの作成時または更新時に行うことができます。次に、この構成でタスクを更新する例を示します。
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> は、タスクの一意の識別子です。
リクエスト ヘッダーには、値 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
車両にタスクを割り当てる
タスクは、配送車両のタスク順序を更新することで、配達車両に割り当てられます。車両のタスクの順序は、配達車両の車両停留所のリストによって決まります。各停車場所には、1 つ以上のタスクを割り当てることができます。
以前に別の車両に割り当てられていたタスクのタスクの順序を更新すると、エラーが発生します。
車両から別の車両に配送を変更するには、元のタスクを閉じて再作成してから、新しい車両に割り当てます。
タスクの順序を更新する
車両に割り当てられたタスクの実行順序は、Driver SDK またはサーバー環境から更新できます。競合状態を避けるため、2 つのメソッドを混在させないでください。
タスクの順序を更新すると、以前に車両に割り当てられていなかったタスクも車両に割り当てられ、以前に車両に割り当てられ、更新後の順序から除外されたタスクが閉じられます。以前に別の車両に割り当てられていたタスクを別の車両に割り当てると、エラーが発生します。まず既存のタスクを閉じ、新しいタスクを作成してから新しい車両に割り当てます。
タスクの順序はいつでも変更できます。
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 です。
リクエスト ヘッダーには、値 Bearer <token> を持つフィールド Authorization が含まれている必要があります。ここで、<token> はFleet Engine トークン ファクトリによって作成されたトークンです。
リクエストの本文には DeliveryVehicle
エンティティを含める必要があります。
必須項目:
項目 値 restrictedVehicleJourneySegments 実行すべきタスクの工程セグメントのリスト。リストの最初のタスクが最初に実行されます。 emptyVehicleJourneySegments[i].stop リスト内のタスク i の停車地。 restrictedVehicleJourneySegments[i].stop.plannedLocation 停車地について予定されている場所。 beyondVehicleJourneySegments[i].stop.tasks この車両停留所で行われるタスクのリスト。 restrictedVehicleJourneySegments[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 に通知する必要があります。Fleet Engine への通知は、 Driver SDK またはサーバー環境から行えます。競合状態を回避し、信頼できる唯一の情報源を維持するために、2 つのメソッドを混在させないでください。
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 に通知するには、HTTP REST 呼び出しで UpdateDeliveryVehicle を呼び出します。
PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<id>?updateMask=remainingVehicleJourneySegments
<id> は、タスクの順序を更新するフリート内の配送車両の一意の識別子です。これは、車両の作成時に指定した ID です。
リクエスト ヘッダーには、値 Bearer <token> を持つフィールド Authorization が含まれている必要があります。ここで、<token> はFleet Engine トークン ファクトリによって作成されたトークンです。
リクエストの本文には DeliveryVehicle
エンティティを含める必要があります。
必須項目:
項目 値 restrictedVehicleJourneySegments 残っている車両停留所のリスト。ステータスが 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
車両が停車地に到着
車両が停車地に到着したときに、Fleet Engine に通知する必要があります。Fleet Engine への通知は、 Driver SDK またはサーバー環境から行えます。競合状態を回避し、信頼できる唯一の情報源を維持するために、2 つのメソッドを混在させないでください。
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 に通知するには、HTTP REST 呼び出しで「UpdateDeliveryVehicle」を呼び出します。
PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<id>?updateMask=remainingVehicleJourneySegments
<id> は、タスクの順序を更新するフリート内の配送車両の一意の識別子です。これは、車両の作成時に指定した ID です。
リクエスト ヘッダーには、値 Bearer <token> を持つフィールド Authorization が含まれている必要があります。ここで、<token> はFleet Engine トークン ファクトリによって作成されたトークンです。
リクエストの本文には DeliveryVehicle
エンティティを含める必要があります。
必須項目:
項目 値 restrictedVehicleJourneySegments 到着した停車地の状態が 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 は、車両が停止を完了したときに通知される必要があります。これにより、停車地に関連付けられているすべてのタスクが CLOSED 状態に設定されます。Fleet Engine への通知は、 Driver SDK またはサーバー環境から行えます。競合状態を回避し、信頼できる唯一の情報源を維持するために、2 つのメソッドを混在させないでください。
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 に通知するには、HTTP REST 呼び出しで UpdateDeliveryVehicle を呼び出します。
PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<id>?updateMask=remaining_vehicle_journey_segments
<id> は、タスクの順序を更新するフリート内の配送車両の一意の識別子です。これは、車両の作成時に指定した ID です。
リクエスト ヘッダーには、値 Bearer <token> を持つフィールド Authorization が含まれている必要があります。ここで、<token> はFleet Engine トークン ファクトリによって作成されたトークンです。
リクエストの本文には DeliveryVehicle
エンティティを含める必要があります。
必須項目:
項目 値 beyond_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}",
"taskDuration": "120s"
}
]
}
}
]
}
EOM
タスクを更新する
ほとんどのタスク フィールドは不変です。ただし、タスク エンティティを直接更新することで、状態、タスク結果、タスク結果時間、タスク結果の場所、属性を変更できます。たとえば、タスクが車両に割り当てられていない場合は、状態を直接更新してタスクを終了できます。
gRPC
REST
タスクを終了する
車両に割り当てられたタスクを終了するには、 車両がタスクが行われる停車地を完了したことを Fleet Engine に通知するか、車両の停車地のリストから削除します。そのためには、車両のタスクの順序を更新する場合と同様に、残りの車両停車場所のリストを設定します。
車両がまだ割り当てられておらず、タスクを終了する必要がある場合は、タスクを CLOSED 状態に更新します。ただし、終了したタスクを再度開くことはできません。
タスクが終了しても、成功や失敗を示すものではありません。これは、タスクが進行中とみなされなくなったことを示します。フリート トラッキングでは、デリバリーの結果を表示できるように、タスクの実際の結果を示すことが重要です。
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) // It's only possible to directly CLOSE a
.build(); // task which 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
リクエスト ヘッダーには、値 Bearer <token> を持つフィールド Authorization が含まれている必要があります。ここで、<token> はFleet Engine トークン ファクトリによって作成されたトークンです。
リクエストの本文には Task
エンティティを含める必要があります。
必須項目:
項目 値 使って State.CLOSED 省略可能項目:
項目 値 タスクの結果 Outcome.SUCCEEDED または Outcome.FAILED 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
タスクの結果と結果の場所を設定する
タスクの終了は、成功や失敗を示すものではなく、タスクが進行中とみなされなくなったことを示します。フリート トラッキングでは、デリバリー結果を表示して、サービスに対する適切な課金を行うために、タスクの実際の結果を示すことが重要です。一度設定したタスクの結果は変更できません。タスク結果時間とタスク結果の場所は、設定後に変更できます。
CLOSED 状態のタスクは、結果を 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
リクエスト ヘッダーには、値 Bearer <token> を持つフィールド Authorization が含まれている必要があります。ここで、<token> はFleet Engine トークン ファクトリによって作成されたトークンです。
リクエストの本文には Task
エンティティを含める必要があります。
必須項目:
項目 値 タスクの結果 Outcome.SUCCEEDED または Outcome.FAILED 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=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 を外部テーブルのキーとして使用します。
詳細については、タスクのライフサイクルをご覧ください。
車両を検索
車両の検索は、Driver SDK またはサーバー環境から行えます。
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> は、タスクの一意の識別子です。
<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}"
タスクを検索する
サーバー環境からタスクを検索できます。Driver 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> は、タスクの一意の識別子です。
<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 によって提供される配送情報が、トラッキング対象の位置情報の表示を管理するに記載されている公開設定ルールに準拠している。
Fleet Engine を使用して、荷物追跡 ID で配送情報を検索する。Driver SDK は、トラッキング ID による情報検索をサポートしていません。Fleet Engine でこれを行うには、サーバー環境またはブラウザ環境を使用します。
セキュリティ リスクを抑えるために、可能な限り狭いトークンを使用する。たとえば、Delivery Consumer トークンを使用する場合、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}"
タスクの一覧表示
サーバー環境またはブラウザ環境からタスクを一覧表示できます。Driver SDK はタスクの一覧表示をサポートしていません。
タスクの一覧表示は、タスクへの幅広いアクセス権をリクエストします。タスクの一覧表示は、信頼できるユーザーのみを対象としています。リストタスクのリクエストを行う場合は、Delivery フリート リーダーまたは Delivery スーパー ユーザー認証トークンを使用します。
リストに記載されているタスクでは、次のフィールドが削除されます。
- VehicleStop.planned_location
- VehicleStop.state
- VehicleStop.TaskInfo.taskId
リストされたタスクは、ほとんどのタスク プロパティでフィルタできます。フィルタクエリ構文については、AIP-160 をご覧ください。フィルタリングに使用できる有効なタスク プロパティを次のリストに示します。
- 属性
- Delivery_vehicle_id [配達車両 ID]
- 使って
- plan_location
- task_duration
- #task_outcome
- #task_outcome_location
- #task_outcome_location_source
- task_outcome_time
- トラッキング ID
- type
Google API の改善提案に基づいて、次のフィールド形式を使用します。
フィールド タイプ | 形式 | 例 |
---|---|---|
タイムスタンプ | RFC-3339 | task_outcome_time = 2022-03-01T11:30:00-08:00 |
所要時間 | 「s」が続く秒数 | task_duration = 120s |
列挙型 | 文字列 | state = CLOSED AND type = PICKUP |
場所 | point.latitude 、point.longitude |
planned_location.point.latitude > 36.1 AND planned_location.point.longitude < -122.0 |
フィルタクエリ演算子の一覧については、AIP-160 をご覧ください。
フィルタクエリが指定されていない場合は、すべてのタスクが一覧表示されます。
タスクリストはページ分けされます。ページサイズは、リストタスク リクエストで指定できます。ページサイズが指定されている場合、返されるタスクの数は指定されたページサイズ以下になります。ページサイズが存在しない場合は、妥当なデフォルトが使用されます。リクエストされたページサイズが内部の最大値を超えている場合は、内部の最大値が使用されます。
タスクリストには、結果の次のページを読み取るためのトークンを含めることができます。前のリクエストと同一であるリクエストでページトークンを使用して、タスクの次のページを取得します。返されたページトークンが空の場合、これ以上取得できるタスクはありません。
gRPC
次の例は、Java gRPC ライブラリを使用して、deliveryVehicleId と task 属性のタスクを一覧表示する方法を示しています。成功のレスポンスは空のままでもかまいません。空のレスポンスは、指定された deliveryVehicleId に関連付けられたタスクがないことを示します。
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
リストにあるタスクにフィルタを適用するには、URL パラメータとして「filter」を指定し、URL エスケープされたフィルタクエリを値として指定します。
リクエスト ヘッダーには、値 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}"
配送車両を一覧表示する
サーバー環境またはブラウザ環境から配送車両を一覧表示できます。Driver SDK は配達車両の一覧表示をサポートしていません。
配達車両の一覧表示は、配達車両への幅広いアクセス権をリクエストし、信頼できるユーザーのみを対象としています。リスト配送車両リクエストを行う場合は、Delivery フリート リーダーまたは Delivery スーパー ユーザー認証トークンを使用します。
リストに記載されている配送車両では、レスポンス サイズへの影響により、次のフィールドが削除されます。
- CurrentRouteSegment
- RemainingVehicleJourneySegments
リスト配送車両は、attributes
プロパティでフィルタできます。たとえば、キー my_key
と値 my_value
を持つ属性をクエリするには、attributes.my_key = my_value
を使用します。複数の属性をクエリするには、attributes.key1 = value1 AND
attributes.key2 = value2
のように論理 AND
および OR
演算子を使用してクエリを結合します。フィルタクエリ構文の詳細については、AIP-160 をご覧ください。
viewport
リクエスト パラメータを使用すると、リストされた配送車両をロケーションでフィルタできます。viewport
リクエスト パラメータは、high
(北東)と low
(南西)の 2 つの境界座標(緯度/経度)を使用してビューポートを定義します。低い緯度よりも地理的に低い高い緯度が含まれる場合、リクエストは拒否されます。
配送車両リストはデフォルトで、適切なページサイズを使用してページ分けされます。ページサイズを指定した場合、リクエストは制限で指定された数以下の車両のみを返します。リクエストされたページサイズが内部の最大値を超えている場合は、内部の最大値が使用されます。デフォルトと最大のページサイズはどちらも 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
リストにあるタスクにフィルタを適用するには、URL エスケープされたフィルタクエリを値として「filter」URL パラメータを含めます。
リクエスト ヘッダーには、値 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 を使用してフリートのトラッキングを有効にするには、次の 2 つの方法があります。
推奨: JavaScript フリート トラッキング ライブラリを使用する。このライブラリを使用すると、Fleet Engine で追跡した車両の位置情報と関心のある場所を可視化できます。この API には、標準の google.maps.Map オブジェクトを置き換える JavaScript マップ コンポーネントと、Fleet Engine に接続するためのデータ コンポーネントが含まれています。これにより、ウェブアプリやモバイルアプリから、カスタマイズ可能なアニメーション付きのフリート トラッキング エクスペリエンスを提供できます。
Fleet Engine Deliveries API の上に独自のフリート トラッキングを実装します。
ロギング
Fleet Engine が RPC ログを Cloud Logging に送信できるようにオプションを有効にできます。詳細については、ロギングをご覧ください。
認可ロールとトークン
Deliveries API の統合と個々のユースケースの承認メモで説明されているように、Fleet Engine を呼び出すには、サービス アカウントの認証情報を使用して署名された JSON Web Token による認証が必要です。これらのトークンの作成に使用されるサービス アカウントには 1 つ以上のロールがあり、各ロールで異なる権限セットを付与できます。
詳細については、認証と認可をご覧ください。
トラブルシューティング
復元性
Fleet Engine は信頼できる情報源とはみなされません。Fleet Engine に依存せずに、必要に応じてシステムの状態を復元する必要があります。
Fleet Engine における状態の消失
Fleet Engine を使用する場合は、障害発生時にシステムが自己修復するようにクライアントを実装します。たとえば、Fleet Engine が車両を更新しようとすると、車両が存在しないことを示すエラーを返すことがあります。その後、クライアントは新しい状態で車両を再作成する必要があります。この状況はめったに発生しません。発生した場合、システムの復元力を確保する必要があります。
Fleet Engine の致命的な障害というまれなケースでは、ほとんどまたはすべての車両とタスクの再作成が必要になる可能性があります。作成頻度が高すぎると、割り当ての問題によって一部のリクエストが再び失敗することがあります。これは、サービス拒否(DoS)攻撃を回避するために割り当てのチェックが行われるためです。この場合は、再試行のバックオフ戦略を使用して再作成率を遅くします。
ドライバー アプリ内の状態の消失
ドライバアプリがクラッシュした場合、アプリは Driver SDK 内に現在の状態を再作成する必要があります。アプリはタスクを再作成して、タスクが存在することを確認し、現在の状態を復元する必要があります。また、Driver SDK の停車地のリストを再作成して明示的に設定する必要があります。
これらの復元は、エンティティがデータベースにすでに存在するかどうか、いつ存在するかを示すエラーを除き、Fleet Engine からの情報に依存せずに自律的に実行する必要があります。エンティティがすでに存在する場合、そのエラーを吸収し、その ID を使用してエンティティを更新できます。
よくある質問
もし、運転手が順不同のタスクのために停車した場合はどうなるでしょうか。
この場合は、まずタスクの順序を更新してから通常どおりに進み、停車地への到着やタスクの完了をマークする必要があります。そうしないと、システムの一貫性が失われる可能性があります。ETA が不正確になったり、予期しないエラーが報告されたりする可能性があります。