Bắt đầu với Công cụ nhóm

API Chuyến đi và Giao hàng theo yêu cầu của Fleet Engine cho phép bạn quản lý các chuyến đi và trạng thái xe cho các ứng dụng Tiến trình đặt hàng và chuyến đi. Thư viện này xử lý các giao dịch giữa SDK trình điều khiển, SDK người dùng và dịch vụ phụ trợ – có thể giao tiếp với Fleet Engine bằng cách thực hiện lệnh gọi gRPC hoặc REST.

Điều kiện tiên quyết

Để phát triển ứng dụng, hãy đảm bảo bạn cài đặt Cloud SDK (gcloud) và được xác thực cho dự án của mình.

shell

gcloud auth login

Bạn sẽ thấy một thông báo thành công như:

You are now logged in as [my-user@example.com].
Your current project is [project-id].  You ...

Kiểm tra để đảm bảo rằng các API của nhóm giải pháp gọi xe và giao hàng theo yêu cầu đã được định cấu hình phù hợp.

shell

gcloud --project=project-id services enable fleetengine.googleapis.com

Nếu lệnh này dẫn đến lỗi, hãy kiểm tra với quản trị viên dự án của bạn và người đại diện hỗ trợ của Google để được cấp quyền truy cập.

Ghi nhật ký

Fleet Engine có thể viết thông điệp nhật ký về lệnh gọi API nhận được vào nhật ký nền tảng Google Cloud. Xem tài liệu về Cloud Logging để biết thông tin tổng quan về cách đọc và phân tích nhật ký.

Theo mặc định, tính năng ghi nhật ký có thể không bật cho các dự án được tạo trước ngày 10 tháng 2 năm 2022. Hãy xem tài liệu về cách ghi nhật ký để biết thêm thông tin chi tiết.

Thư viện ứng dụng

Chúng tôi xuất bản các thư viện ứng dụng bằng một số ngôn ngữ lập trình phổ biến. Các thư viện này sẽ giúp mang lại trải nghiệm tốt hơn cho nhà phát triển so với REST hoặc gRPC thô. Để biết hướng dẫn về cách lấy thư viện ứng dụng cho ứng dụng máy chủ của bạn, hãy xem phần Thư viện ứng dụng.

Các ví dụ Java trong tài liệu này giả định rằng bạn đã quen thuộc với gRPC.

Xác thực và uỷ quyền

Bạn có thể định cấu hình các chức năng do Chuyến đi và Tiến trình đặt hàng cung cấp thông qua Google Cloud Console. Các API và SDK này yêu cầu sử dụng Mã thông báo web JSON đã được ký bằng tài khoản dịch vụ tạo từ Cloud Console.

Thiết lập dự án Cloud

Để thiết lập dự án trên đám mây, trước tiên, hãy tạo dự án rồi tạo tài khoản dịch vụ.

Cách tạo dự án trên Google Cloud:

  1. Tạo một dự án trên Google Cloud bằng Bảng điều khiển Google Cloud.
  2. Trên Trang tổng quan về API và dịch vụ, hãy bật API Local Guides and Deliveries.

Tài khoản dịch vụ được liên kết với một hoặc nhiều vai trò. Các mã này được dùng để tạo Mã thông báo web JSON cấp các nhóm quyền khác nhau tuỳ thuộc vào vai trò. Thông thường, để giảm khả năng sử dụng sai mục đích, bạn có thể tạo nhiều tài khoản dịch vụ, trong đó mỗi tài khoản có số vai trò tối thiểu cần thiết.

Tiến trình chuyến đi và đơn đặt hàng sử dụng các vai trò sau:

RoleNội dung mô tả
Người dùng SDK người dùng Fleet Engine

roles/fleetengine.consumerSdkUser
Cấp quyền tìm kiếm xe và truy xuất thông tin về xe và chuyến đi. Mã thông báo do một tài khoản dịch vụ có vai trò này thường được dùng trên thiết bị di động có ứng dụng người dùng thông thường hoặc đi chung xe.
Người dùng SDK trình điều khiển Fleet Engine

roles/fleetengine.driverSdkUser
Cấp quyền cập nhật vị trí và tuyến đường của xe, cũng như truy xuất thông tin về các phương tiện và chuyến đi. Mã thông báo do tài khoản dịch vụ có vai trò này tạo thường được dùng trên thiết bị di động của ứng dụng đi chung xe hoặc giao hàng.
Người dùng cao cấp của Dịch vụ công cụ

roles/fleetengine.serviceSuperUser
Cấp quyền cho tất cả các API xe và chuyến đi. Mã thông báo do tài khoản dịch vụ có vai trò này tạo thường được dùng trên các máy chủ phụ trợ của bạn.

Ví dụ: tạo một tài khoản dịch vụ cho từng vai trò trong số 3 vai trò và chỉ định vai trò tương ứng cho từng vai trò đó.

gcloud --project=project-id iam service-accounts create fleet-engine-consumer-sdk
gcloud projects add-iam-policy-binding project-id \
       --member=serviceAccount:fleet-engine-consumer-sdk@project-id.iam.gserviceaccount.com \
       --role=roles/fleetengine.consumerSdkUser

gcloud --project=project-id iam service-accounts create fleet-engine-driver-sdk
gcloud projects add-iam-policy-binding project-id \
       --member=serviceAccount:fleet-engine-driver-sdk@project-id.iam.gserviceaccount.com \
       --role=roles/fleetengine.driverSdkUser

gcloud --project=project-id iam service-accounts create fleet-engine-su
gcloud projects add-iam-policy-binding project-id \
       --member=serviceAccount:fleet-engine-su@project-id.iam.gserviceaccount.com \
       --role=roles/fleetengine.serviceSuperUser

SDK của trình điều khiển và SDK người tiêu dùng được xây dựng dựa trên các vai trò tiêu chuẩn này.

Ngoài ra, bạn có thể tạo các vai trò tuỳ chỉnh cho phép nhóm các quyền tuỳ ý với nhau. Trình điều khiển và SDK người dùng sẽ hiển thị thông báo lỗi bất cứ khi nào bị thiếu quyền cần thiết. Do đó, bạn rất nên sử dụng bộ vai trò chuẩn đã trình bày ở trên và không sử dụng vai trò tuỳ chỉnh.

Để thuận tiện, nếu bạn cần tạo mã thông báo JWT cho các ứng dụng không tin cậy, thì việc thêm người dùng vào Vai trò người tạo mã thông báo tài khoản dịch vụ sẽ cho phép họ tạo mã thông báo bằng các công cụ dòng lệnh gcloud.

gcloud projects add-iam-policy-binding project-id \
       --member=user:my-user@example.com \
       --role=roles/iam.serviceAccountTokenCreator

Trong đó my-user@example.com là email dùng để xác thực bằng gcloud (gcloud auth list --format='value(account)').

Thư viện xác thực Fleet Engine

Fleet Engine sử dụng Mã thông báo web JSON (JWT) để hạn chế quyền truy cập vào các API của Fleet Engine. Thư viện xác thực Fleet Engine mới, có sẵn trên GitHub, sẽ đơn giản hóa việc xây dựng các JWT của Fleet Engine và ký các tệp đó một cách an toàn.

Thư viện mang lại các lợi ích sau:

  • Đơn giản hoá quy trình tạo Mã thông báo Fleet Engine.
  • Cung cấp các cơ chế ký mã thông báo ngoài việc sử dụng tệp thông tin xác thực (chẳng hạn như mạo danh tài khoản dịch vụ).
  • Đính kèm mã thông báo đã ký vào các yêu cầu gửi đi được thực hiện từ mã giả lập gRPC hoặc ứng dụng GAPIC.

Tạo mã thông báo web JSON (JWT) để uỷ quyền

Khi không sử dụng Thư viện xác thực Fleet Engine, bạn cần tạo mã thông báo web JSON (JWT) ngay trong cơ sở mã của mình. Để làm được như vậy, bạn phải hiểu rõ về JWT và mối liên hệ của chúng với Fleet Engine. Đây là lý do bạn nên tận dụng Thư viện xác thực Fleet Engine.

Trong Fleet Engine, Mã thông báo web JSON (JWT) cung cấp phương thức xác thực ngắn hạn và đảm bảo rằng các thiết bị chỉ có thể sửa đổi xe, chuyến đi hoặc nhiệm vụ mà chúng được uỷ quyền. JWT chứa tiêu đề và phần xác nhận quyền sở hữu. Phần tiêu đề chứa các thông tin như khoá riêng tư để sử dụng (lấy từ tài khoản dịch vụ) và thuật toán mã hoá. Phần thông báo xác nhận quyền sở hữu chứa các thông tin như thời gian tạo mã thông báo, thời gian tồn tại của mã thông báo, các dịch vụ mà mã thông báo đang xác nhận quyền truy cập và các thông tin uỷ quyền khác để giới hạn quyền truy cập; ví dụ: mã nhận dạng phương tiện.

Phần tiêu đề JWT chứa các trường sau:

TrườngNội dung mô tả
alg Thuật toán sử dụng. "RS256".
typ Loại mã thông báo. "JWT".
trẻ em Mã khoá riêng tư của tài khoản dịch vụ của bạn. Bạn có thể tìm thấy giá trị này trong trường "private_key_id" của tệp JSON tài khoản dịch vụ. Hãy nhớ sử dụng khoá từ một tài khoản dịch vụ có cấp quyền chính xác.

Phần xác nhận quyền sở hữu JWT chứa các trường sau:

TrườngNội dung mô tả
iss Địa chỉ email của tài khoản dịch vụ của bạn.
sub Địa chỉ email của tài khoản dịch vụ của bạn.
nghe DỊCH VỤ_NAME của tài khoản dịch vụ của bạn, trong trường hợp này là https://fleetengine.googleapis.com/
IAt Dấu thời gian khi mã được tạo, được chỉ định tính bằng giây kể từ 00:00:00 UTC, ngày 1 tháng 1 năm 1970. Chờ 10 phút để xiên. Nếu dấu thời gian quá lâu trong quá khứ hoặc trong tương lai, máy chủ có thể báo cáo lỗi.
exp Dấu thời gian khi mã thông báo hết hạn, được chỉ định bằng giây kể từ 00:00:00 UTC, ngày 1 tháng 1 năm 1970. Yêu cầu không thành công nếu dấu thời gian sau hơn 1 giờ trong tương lai.
khoản uỷ quyền Tuỳ thuộc vào trường hợp sử dụng, từ khoá này có thể chứa "vehicleid" hoặc "tripid".

Việc tạo mã thông báo JWT nghĩa là ký mã đó. Để biết hướng dẫn và mã mẫu dùng để tạo và ký JWT, hãy xem phần Uỷ quyền tài khoản dịch vụ mà không cần OAuth. Sau đó, bạn có thể đính kèm một mã thông báo đã ký vào các lệnh gọi gRPC hoặc các phương thức khác dùng để truy cập vào Fleet Engine.

Tuyên bố về JWT

Khi tạo tải trọng JWT, hãy thêm một thông báo xác nhận quyền sở hữu bổ sung trong phần uỷ quyền, trong đó khoá vehicleid hoặc tripid được đặt thành giá trị của mã xe hoặc mã chuyến đi mà lệnh gọi đang được thực hiện.

SDK trình điều khiển luôn sử dụng thông báo xác nhận quyền sở hữu vehicleid, bất kể hoạt động trong một chuyến đi hay trên xe. Phần phụ trợ Fleet Engine đảm bảo rằng xe được liên kết với chuyến đi được yêu cầu trước khi thực hiện việc sửa đổi.

SDK người tiêu dùng luôn sử dụng thông báo xác nhận quyền sở hữu tripid.

Đơn vị đi chung xe hoặc Nhà cung cấp dịch vụ phân phối phải sử dụng vehicleid hoặc tripid cùng với "*" để khớp với tất cả Phương tiện đi lại và Chuyến đi. Xin lưu ý rằng JWT có thể chứa cả hai mã thông báo (ngay cả khi không bắt buộc), điều này có thể giúp đơn giản hoá quá trình triển khai ký mã thông báo.

Trường hợp sử dụng JWT

Dưới đây là một mã thông báo mẫu cho máy chủ Nhà cung cấp:

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "private_key_id_of_provider_service_account"
}
.
{
  "iss": "provider@yourgcpproject.iam.gserviceaccount.com",
  "sub": "provider@yourgcpproject.iam.gserviceaccount.com",
  "aud": "https://fleetengine.googleapis.com/",
  "iat": 1511900000,
  "exp": 1511903600,
  "authorization": {
     "vehicleid": "*",
     "tripid": "*"
   }
}

Dưới đây là một mã thông báo mẫu cho Ứng dụng của người tiêu dùng:

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "private_key_id_of_consumer_service_account"
}
.
{
  "iss": "consumer@yourgcpproject.iam.gserviceaccount.com",
  "sub": "consumer@yourgcpproject.iam.gserviceaccount.com",
  "aud": "https://fleetengine.googleapis.com/",
  "iat": 1511900000,
  "exp": 1511903600,
  "authorization": {
     "tripid": "trip_54321"
   }
}

Dưới đây là một mã thông báo mẫu cho ứng dụng Driver:

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "private_key_id_of_driver_service_account"
}
.
{
  "iss": "driver@yourgcpproject.iam.gserviceaccount.com",
  "sub": "driver@yourgcpproject.iam.gserviceaccount.com",
  "aud": "https://fleetengine.googleapis.com/",
  "iat": 1511900000,
  "exp": 1511903600,
  "authorization": {
     "vehicleid": "driver_12345"
   }
}
  • Đối với trường kid trong tiêu đề, hãy chỉ định mã khoá riêng tư của tài khoản dịch vụ. Bạn có thể tìm thấy giá trị này trong trường private_key_id của tệp JSON cho tài khoản dịch vụ.
  • Đối với các trường isssub, hãy chỉ định địa chỉ email của tài khoản dịch vụ. Bạn có thể tìm thấy giá trị này trong trường client_email của tệp JSON tài khoản dịch vụ.
  • Đối với trường aud, hãy chỉ định https://SERVICE_NAME/.
  • Đối với trường iat, hãy sử dụng dấu thời gian khi mã được tạo, được chỉ định là giây đã trôi qua kể từ 00:00:00 UTC, ngày 1 tháng 1 năm 1970. Chờ 10 phút để xiên. Nếu dấu thời gian quá xa trong quá khứ hoặc trong tương lai, thì máy chủ có thể báo cáo lỗi.
  • Đối với trường exp, hãy sử dụng dấu thời gian khi mã thông báo hết hạn (được chỉ định là giây kể từ 00:00:00 UTC, ngày 1 tháng 1 năm 1970). Giá trị tối đa được phép là iat + 3600.

Khi ký JWT để truyền sang một thiết bị di động, hãy nhớ sử dụng tài khoản dịch vụ cho vai trò SDK của trình điều khiển hoặc SDK người dùng. Nếu không, thiết bị di động sẽ có khả năng thay đổi trạng thái mà nó không cần có.

Tương tự, khi ký JWT dùng cho các lệnh gọi đặc quyền, hãy nhớ sử dụng tài khoản dịch vụ với vai trò Người dùng cao cấp. Nếu không, thao tác sẽ không thành công.

Tạo JWT để kiểm thử

Việc tạo mã thông báo từ thiết bị đầu cuối có thể hữu ích khi kiểm thử.

Để làm theo những bước này, tài khoản người dùng của bạn phải có vai trò Người tạo mã thông báo của tài khoản dịch vụ:

gcloud projects add-iam-policy-binding project-id \
       --member=user:my-user@example.com \
       --role=roles/iam.serviceAccountTokenCreator

Tạo tệp mới có tên là unsigned_token.json với nội dung dưới đây. Thuộc tính iat là thời gian hiện tại tính bằng giây sau thời gian bắt đầu của hệ thống. Bạn có thể truy xuất thuộc tính này bằng cách chạy date +%s trong thiết bị đầu cuối của mình. Thuộc tính exp là thời gian hết hạn tính bằng giây sau thời gian bắt đầu của hệ thống, có thể được tính bằng cách thêm 3600 vào iat. Thời gian hết hạn không được lâu hơn một giờ trong tương lai.

{
  "aud": "https://fleetengine.googleapis.com/",
  "iss": "super-user-service-account@project-id.iam.gserviceaccount.com",
  "sub": "super-user-service-account@project-id.iam.gserviceaccount.com",
  "iat": iat,
  "exp": exp,
  "authorization": {
     "vehicleid": "*",
     "tripid": "*"
   }
}

Sau đó, chạy lệnh gcloud sau đây để ký mã thông báo thay mặt cho tài khoản dịch vụ Người dùng cao cấp của bạn:

gcloud beta iam service-accounts sign-jwt --iam-account=super-user-service-account@project-id.iam.gserviceaccount.com unsigned_token.json signed_token.jwt

Giờ đây, một JWT được mã hoá theo chuẩn Base64 đã ký sẽ được lưu trữ trong tệp signed_token.jwt. Mã thông báo có hiệu lực trong giờ tới.

Giờ đây, bạn có thể kiểm thử mã thông báo bằng cách chạy lệnh curl đối với điểm cuối REST trong danh sách xe:

curl -X GET "https://fleetengine.googleapis.com/v1/providers/project-id/vehicles" -H "Authorization: Bearer $(cat signed_token.jwt)"

Phương tiện di chuyển và vòng đời của chúng

Xe là thực thể đại diện cho một cặp xe kết hợp với người lái. Hiện tại, bạn không thể theo dõi riêng người lái xe và xe. Dịch vụ Chia sẻ chuyến đi hoặc Nhà cung cấp dịch vụ giao hàng sẽ tạo một Xe bằng Mã nhà cung cấp (phải giống với Mã dự án của Dự án Google Cloud có chứa tài khoản dịch vụ dùng để gọi các API Fleet Engine) và Mã xe của nhà cung cấp dịch vụ Chia sẻ chuyến đi hoặc Nhà cung cấp dịch vụ giao hàng.

Một chiếc xe không được cập nhật qua UpdateVehicle sau 7 ngày sẽ tự động bị xoá. Sẽ có lỗi khi gọi CreateVehicle bằng cặp Mã nhà cung cấp/Mã xe đã tồn tại. Chúng tôi có thể xử lý trường hợp các phương tiện không được cập nhật thường xuyên theo 2 cách: thường xuyên gọi CreateVehicle cùng với cặp Mã nhà cung cấp/Mã xe dự kiến và loại bỏ lỗi nếu Xe đã tồn tại; hoặc gọi CreateVehicle sau khi UpdateVehicle trả về lỗi NOT_FOUND.

Thông báo cập nhật về vị trí của xe

Để Fleet Engine đạt hiệu suất tốt nhất, hãy cung cấp cho dịch vụ một luồng thông tin cập nhật về vị trí của xe. Sử dụng một trong những cách sau để cung cấp các nội dung cập nhật này:

  1. Sử dụng SDK trình điều khiển – Android, iOS – lựa chọn đơn giản nhất.
  2. Sử dụng mã tuỳ chỉnh – hữu ích nếu vị trí được chuyển tiếp thông qua phần phụ trợ hoặc nếu bạn sử dụng các thiết bị không phải Android hoặc iOS.

Loại phương tiện

Thực thể xe chứa trường bắt buộc là VehicleType, trong đó có enum Category có thể được chỉ định thành AUTO, TAXI, TRUCK, TWO_WHEELER, BICYCLE hoặc PEDESTRIAN. Loại xe có thể đóng vai trò là tiêu chí lọc trong SearchVehiclesListVehicles.

Mọi tuyến đường cho xe sẽ sử dụng RouteTravelMode tương ứng nếu danh mục được đặt thành AUTO, TWO_WHEELER, BICYCLE hoặc PEDESTRIAN. Nếu bạn đặt danh mục thành TAXI hoặc TRUCK, thì việc định tuyến sẽ được xử lý giống như chế độ AUTO.

Thuộc tính xe

Thực thể Xe chứa trường lặp lại của VehicleAttribute. Fleet Engine không diễn giải các thuộc tính này. API SearchVehicles bao gồm một trường yêu cầu Vehicles trùng khớp phải chứa mọi thuộc tính đi kèm được đặt thành giá trị được chỉ định.

Lưu ý rằng trường thuộc tính bổ sung cho một số trường được hỗ trợ khác trong thông báo Vehicle, chẳng hạn như vehicle_typesupported_trip_types.

Điểm tham chiếu còn lại của xe

Thực thể Xe chứa trường lặp lại TripWaypoint (RPC | REST), có tên là waypoints(RPC | REST). Trường này bao gồm các điểm tham chiếu còn lại trong các chuyến đi, theo thứ tự mà xe đến các điểm đó. Fleet Engine tính toán trường này khi các chuyến đi được chỉ định cho xe và cập nhật trường này khi các chuyến đi thay đổi trạng thái. Bạn có thể xác định các điểm tham chiếu này bằng trường TripId và trường WaypointType.

Mở rộng khả năng xe đủ điều kiện so khớp

Thông thường, các dịch vụ của Dịch vụ đi chung xe hoặc Nhà cung cấp dịch vụ giao hàng sẽ chịu trách nhiệm so khớp các yêu cầu về chuyến đi với các phương tiện. Dịch vụ này có thể sử dụng các thuộc tính xe để đưa một chiếc xe vào số lượt tìm kiếm lớn hơn. Ví dụ: nhà cung cấp có thể triển khai một tập hợp các thuộc tính tương ứng với các cấp độ đặc quyền hoặc khả năng mà xe cung cấp. Ví dụ: 3 cấp có thể là một tập hợp các thuộc tính có giá trị boolean: is_bronze_level, is_silver_levelis_gold_level. Một chiếc xe có thể đủ điều kiện chạy cả 3 loại. Khi Fleet Engine nhận được yêu cầu về một chuyến đi yêu cầu tính năng cấp bạc, nội dung tìm kiếm sẽ bao gồm phương tiện đó. Việc sử dụng các thuộc tính theo cách này bao gồm cả những xe đang cung cấp nhiều tính năng.

Có hai cách để cập nhật các thuộc tính của xe. Một là API UpdateVehicle. Khi sử dụng API này, toàn bộ tập hợp Thuộc tính xe sẽ được đặt thành giá trị. Bạn không thể chỉ cập nhật một thuộc tính duy nhất. Phương thức còn lại là API UpdateVehicleAttributes. Phương thức này chỉ cần cập nhật các thuộc tính. Các thuộc tính có trong yêu cầu sẽ được đặt thành giá trị mới hoặc được thêm vào; các thuộc tính chưa xác định sẽ không bị thay đổi.

HƯỚNG DẪN: Tạo xe

Bạn phải tạo một thực thể Vehicle cho từng chiếc xe để theo dõi trong nhóm xe.

Sử dụng điểm cuối CreateVehicle với CreateVehicleRequest để tạo một Xe.

provider_id của Vehicle phải là Mã dự án (ví dụ: dự án theo yêu cầu của tôi) của dự án Google Cloud có chứa Tài khoản dịch vụ dùng để gọi Fleet Engine. Xin lưu ý rằng mặc dù nhiều tài khoản dịch vụ có thể truy cập vào Fleet Engine cho cùng một Dịch vụ đi chung xe hoặc Nhà cung cấp dịch vụ giao hàng, nhưng Fleet Engine hiện không hỗ trợ các tài khoản dịch vụ từ nhiều Dự án Google Cloud truy cập vào cùng một Vehicles.

Bạn có thể tạo Vehicle ở trạng thái OFFLINE hoặc ONLINE. Nếu được tạo ONLINE, hệ thống có thể trả về ngay lập tức để phản hồi các truy vấn SearchVehicles.

last_location ban đầu có thể được đưa vào lệnh gọi CreateVehicle. Mặc dù được phép, nhưng bạn không nên tạo Vehicle ở trạng thái ONLINE khi không có last_location.

Hãy xem phần Loại xe để biết thông tin chi tiết về trường loại xe.

Xem phần Thuộc tính xe để biết thông tin chi tiết về trường thuộc tính.

Giá trị được trả về từ CreateVehicle là thực thể Vehicle được tạo.

Ví dụ:

shell

curl -X POST \
  "https://fleetengine.googleapis.com/v1/providers/project-id/vehicles?vehicleId=vid-8241890" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  --data-binary @- << EOM
{
    "vehicleState": "OFFLINE",
    "supportedTripTypes": ["EXCLUSIVE"],
    "maximumCapacity": 4,
    "vehicleType": {"category": "AUTO"},
    "attributes": [{"key": "on_trip", "value": "false"}]
}
EOM

Hãy xem tài liệu tham khảo về providers.vehicles.create.

Java

static final String PROJECT_ID = "project-id";

VehicleServiceBlockingStub vehicleService =
    VehicleService.newBlockingStub(channel);

String parent = "providers/" + PROJECT_ID;
Vehicle vehicle = Vehicle.newBuilder()
    .setVehicleState(VehicleState.OFFLINE)  // Initial state
    .addSupportedTripTypes(TripType.EXCLUSIVE)
    .setMaximumCapacity(4)
    .setVehicleType(VehicleType.newBuilder().setCategory(VehicleType.Category.AUTO))
    .addAttributes(VehicleAttribute.newBuilder()
        .setKey("on_trip").setValue("false"))  // Opaque to the Fleet Engine
    // Add .setBackToBackEnabled(true) to make this vehicle eligible for trip
    // matching while even if it is on a trip.  By default this is disabled.
    .build();

CreateVehicleRequest createVehicleRequest =
    CreateVehicleRequest.newBuilder()  // no need for the header
        .setParent(parent)
        .setVehicleId("vid-8241890")  // Vehicle ID assigned by Rideshare or Delivery Provider
        .setVehicle(vehicle)  // Initial state
        .build();

// In this case, the Vehicle is being created in the OFFLINE state and
// no initial position is being provided.  When the Driver App checks
// in with the Rideshare or Delivery Provider, the state can be set to ONLINE and
// the Driver App will update the Vehicle Location.

try {
  Vehicle createdVehicle =
      vehicleService.createVehicle(createVehicleRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
    case ALREADY_EXISTS:
      break;
    case PERMISSION_DENIED:
      break;
  }
  return;
}
// If no Exception, Vehicle created successfully.

Nhật ký của Google Cloud Platform dùng để tạo xe

Fleet Engine API sẽ ghi một mục nhập nhật ký qua nhật ký của Google Cloud Platform khi nhận được lệnh gọi đến điểm cuối CreateVehicle. Mục nhập nhật ký bao gồm thông tin về các giá trị trong yêu cầu CreateVehicle. Nếu lệnh gọi thành công, lệnh gọi này cũng sẽ bao gồm thông tin về Vehicle đã được trả về.

shell

gcloud --project=project-id logging read --freshness=1h '
  jsonPayload.request.vehicleId="vid-8241890"
  jsonPayload.@type="type.googleapis.com/maps.fleetengine.v1.CreateVehicleLog"
'

Sẽ in một bản ghi tương tự như sau:

---
insertId: c2cf4d3a180251c1bdb892137c14f022
jsonPayload:
  '@type': type.googleapis.com/maps.fleetengine.v1.CreateVehicleLog
  request:
    vehicle:
      attributes:
      - key: on_trip
        value: 'false'
      maximumCapacity: 4
      state: VEHICLE_STATE_OFFLINE
      supportedTrips:
      - EXCLUSIVE_TRIP
      vehicleType:
        vehicleCategory: AUTO
    vehicleId: vid-8241890
  response:
    attributes:
    - key: on_trip
      value: 'false'
    availableCapacity: 4
    currentRouteSegmentHandle: AdSiwAwCO9gZ7Pw5UZZimOXOo41cJTjg/r3SuwVPQmuuaV0sU3+3UCY+z53Cl9i6mWHLoCKbBt9Vsj5PMRgOJ8zX
    maximumCapacity: 4
    name: providers/project-id/vehicles/vid-8241890
    state: VEHICLE_STATE_OFFLINE
    supportedTrips:
    - EXCLUSIVE_TRIP
    vehicleType:
      vehicleCategory: AUTO
labels:
  vehicle_id: vid-8241890
logName: projects/project-id/logs/fleetengine.googleapis.com%2Fcreate_vehicle
receiveTimestamp: '2021-09-22T03:25:16.361159871Z'
resource:
  labels:
    location: global
    resource_container: projects/project-id
  type: fleetengine.googleapis.com/Fleet
timestamp: '2021-09-22T03:25:15.724998Z'

Thông báo của Cloud Pub/Sub về việc tạo xe

Fleet Engine API sẽ phát hành một thông báo qua Cloud Pub/Sub khi một xe mới được tạo. Để nhận những thông báo này, vui lòng làm theo hướng dẫn tại đây.

CÁCH LÀM: Cập nhật vị trí của xe

Nếu không sử dụng SDK Trình điều khiển để cập nhật vị trí của xe, bạn có thể thực hiện lệnh gọi trực tiếp đến Fleet Engine kèm theo thông tin vị trí của xe. Đối với mọi xe đang hoạt động, Fleet Engine dự kiến sẽ cập nhật vị trí ít nhất một lần mỗi phút và tối đa là 5 giây một lần. Các bản cập nhật này chỉ yêu cầu các đặc quyền của người dùng đối với SDK trình điều khiển Fleet Engine.

Ví dụ:

shell

curl -X PUT \
  "https://fleetengine.googleapis.com/v1/providers/project-id/vehicles/vid-8241890?updateMask=last_location" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  --data-binary @- << EOM
{
    "supplementalLocation": {"latitude": 12.1, "longitude": 14.5},
    "supplementalLocationTime": "$(date -u --iso-8601=seconds)",
    "supplementalLocationSensor": "CUSTOMER_SUPPLIED_LOCATION",
    "supplementalLocationAccuracy": 15
}
EOM

Hãy xem tài liệu tham khảo về providers.vehicles.update.

Java

static final String PROJECT_ID = "project-id";
static final String VEHICLE_ID = "vid-8241890";

VehicleServiceBlockingStub vehicleService = VehicleService.newBlockingStub(channel);

String vehicleName = "providers/" + PROJECT_ID + "/vehicles/" + VEHICLE_ID;
Vehicle updatedVehicle = Vehicle.newBuilder()
    .setLastLocation(VehicleLocation.newBuilder()
        .setSupplementalLocation(LatLng.newBuilder()
            .setLatitude(37.3382)
            .setLongitude(121.8863))
        .setSupplementalLocationTime(now())
        .setSupplementalLocationSensor(LocationSensor.CUSTOMER_SUPPLIED_LOCATION)
        .setSupplementalLocationAccuracy(DoubleValue.of(15.0)))  // Optional)
    .build();

UpdateVehicleRequest updateVehicleRequest = UpdateVehicleRequest.newBuilder()
    .setName(vehicleName)
    .setVehicle(updatedVehicle)
    .setUpdateMask(FieldMask.newBuilder()
        .addPaths("last_location"))
    .build();

try {
  Vehicle updatedVehicle =
      vehicleService.updateVehicle(updateVehicleRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
    case NOT_FOUND:
      // Most implementations will call CreateVehicle in this case
      break;
    case PERMISSION_DENIED:
      break;
  }
  return;
}
// If no Exception, Vehicle updated successfully.

CÁCH: Cập nhật các trường khác về Xe

Tần suất cập nhật các thuộc tính khác của trạng thái Xe ít xảy ra hơn so với thông tin cập nhật vị trí. Để cập nhật các thuộc tính không phải last_location, bạn cần có đặc quyền của Người dùng cấp cao của Fleet Engine.

UpdateVehicleRequest bao gồm update_mask để cho biết những trường cần cập nhật. Hành vi của trường như trong tài liệu về Protobuf cho mặt nạ trường.

Như đã nêu trong phần Thuộc tính xe, việc cập nhật trường attributes yêu cầu bạn phải ghi tất cả các thuộc tính để được duy trì. Bạn không thể chỉ cập nhật giá trị của một cặp khoá-giá trị trong lệnh gọi UpdateVehicle. Để cập nhật giá trị của các thuộc tính cụ thể, bạn có thể sử dụng API UpdateVehicleAttributes.

Ví dụ:

Ví dụ này bật back_to_back.

shell

curl -X PUT \
  "https://fleetengine.googleapis.com/v1/providers/project-id/vehicles/vid-8241890?updateMask=vehicle_state,attributes,back_to_back_enabled" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  --data-binary @- << EOM
{
    "vehicleState": "ONLINE",
    "attributes": [
      {"key": "on_trip", "value": "true"},
      {"key": "cash_only", "value": "false"}
    ],
    "backToBackEnabled": true
}
EOM

Hãy xem tài liệu tham khảo về providers.vehicles.update.

Java

static final String PROJECT_ID = "project-id";
static final String VEHICLE_ID = "vid-8241890";

VehicleServiceBlockingStub vehicleService = VehicleService.newBlockingStub(channel);

String vehicleName = "providers/" + PROJECT_ID + "/vehicles/" + VEHICLE_ID;
Vehicle updatedVehicle = Vehicle.newBuilder()
    .setVehicleState(VehicleState.ONLINE)
    .addAllAttributes(ImmutableList.of(
        VehicleAttribute.newBuilder().setKey("on_trip").setValue("true").build(),
        VehicleAttribute.newBuilder().setKey("cash_only").setValue("false").build()))
    .setBackToBackEnabled(true)
    .build();

UpdateVehicleRequest updateVehicleRequest = UpdateVehicleRequest.newBuilder()
    .setName(vehicleName)
    .setVehicle(updatedVehicle)
    .setUpdateMask(FieldMask.newBuilder()
        .addPaths("vehicle_state")
        .addPaths("attributes")
        .addPaths("back_to_back_enabled"))
    .build();

// Attributes and vehicle state are being updated, so both are
// included in the field mask.  Note that of on_trip were
// not being updated, but rather cash_only was being changed,
// the desired value of "on_trip" would still need to be written
// as the attributes are completely replaced in an update operation.

try {
  Vehicle updatedVehicle =
      vehicleService.updateVehicle(updateVehicleRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
    case NOT_FOUND:
      // Most implementations will call CreateVehicle in this case
      break;
    case PERMISSION_DENIED:
      break;
  }
  return;
}
// If no Exception, Vehicle updated successfully.

Nhật ký của nền tảng Google Cloud dành cho các bản cập nhật xe

Fleet Engine API sẽ ghi một mục nhập nhật ký qua nhật ký của Google Cloud Platform khi nhận được lệnh gọi đến điểm cuối UpdateVehicle. Mục nhập nhật ký bao gồm thông tin về các giá trị trong yêu cầu UpdateVehicle. Nếu lệnh gọi thành công, lệnh gọi này cũng sẽ bao gồm thông tin về Vehicle đã được trả về.

shell

gcloud --project=project-id logging read --freshness=1h '
  jsonPayload.request.vehicleId="vid-8241890"
  jsonPayload.@type="type.googleapis.com/maps.fleetengine.v1.UpdateVehicleLog"
'

Thông báo của Cloud Pub/Sub về thông tin cập nhật về xe

Fleet Engine API sẽ phát hành một thông báo qua Cloud Pub/Sub khi một xe hiện có được cập nhật. Để nhận những thông báo này, vui lòng làm theo hướng dẫn tại đây.

HƯỚNG DẪN: Tìm kiếm xe

Fleet Engine hỗ trợ tính năng tìm kiếm xe. API SearchVehicles cho phép bạn tìm những tài xế ở gần và phù hợp nhất với một công việc như dịch vụ gọi xe hoặc yêu cầu giao hàng. API SearchVehicles trả về danh sách người lái xe theo thứ hạng khớp với thuộc tính nhiệm vụ với thuộc tính của xe trong đội xe của bạn. Để biết thêm thông tin, hãy xem phần Tìm tài xế ở gần.

Ví dụ:

Khi tìm kiếm các xe có sẵn, theo mặc định, Fleet Engine sẽ loại trừ các xe trong các chuyến đi đang hoạt động. Các dịch vụ của Dịch vụ đi chung xe hoặc Nhà cung cấp dịch vụ giao hàng cần phải đưa những dịch vụ này vào yêu cầu tìm kiếm một cách rõ ràng. Ví dụ sau cho thấy cách đưa những phương tiện đó vào nội dung tìm kiếm về những chiếc xe phù hợp với chuyến đi từ Trung tâm mua sắm Grand Indonesia East đến Trung tâm hội nghị Balay Sidang Jakarta.

shell

Trước tiên, hãy cập nhật vị trí của chiếc xe mà chúng ta đã tạo ở các bước trước để xe đủ điều kiện. Trong thực tế, việc này sẽ do SDK trình điều khiển chạy trên thiết bị Android hoặc iOS trong xe đó.

curl -X PUT \
  "https://fleetengine.googleapis.com/v1/providers/project-id/vehicles/vid-8241890?updateMask=last_location,attributes" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  --data-binary @- << EOM
{
  "lastLocation": {
    "updateTime": "$( date -u +"%Y-%m-%dT%H:%M:%SZ" )",
    "location": {
      "latitude": "-6.195139",
      "longitude": "106.820826"
    }
  },
  "attributes": [{"key": "on_trip", "value": "false"}]
}
EOM

Việc tìm kiếm sẽ ít nhất mang lại kết quả cho chiếc xe đó.

curl -X POST \
  "https://fleetengine.googleapis.com/v1/providers/project-id/vehicles:search" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  --data-binary @- << EOM
{
  "pickupPoint": {
    "point": {"latitude": "-6.195139", "longitude": "106.820826"}
  },
  "dropoffPoint": {
    "point": {"latitude": "-6.1275", "longitude": "106.6537"}
  },
  "pickupRadiusMeters": 2000,
  "count": 10,
  "minimumCapacity": 2,
  "tripTypes": ["EXCLUSIVE"],
  "vehicleTypes": [{"category": "AUTO"}],
  "filter": "attributes.on_trip=\"false\"",
  "orderBy": "PICKUP_POINT_ETA",
  "includeBackToBack": true
}
EOM

Hãy xem tài liệu tham khảo về providers.vehicles.search.

Java

static final String PROJECT_ID = "project-id";

VehicleServiceBlockingStub vehicleService = VehicleService.newBlockingStub(channel);

String parent = "providers/" + PROJECT_ID;
SearchVehiclesRequest searchVehiclesRequest = SearchVehiclesRequest.newBuilder()
    .setParent(parent)
    .setPickupPoint( // Grand Indonesia East Mall
        TerminalLocation.newBuilder().setPoint(
            LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
    .setDropoffPoint( // Balai Sidang Jakarta Convention Center
        TerminalLocation.newBuilder().setPoint(
            LatLng.newBuilder().setLatitude(-6.213796).setLongitude(106.807195)))
    .setPickupRadiusMeters(2000)
    .setCount(10)
    .setMinimumCapacity(2)
    .addTripTypes(TripType.EXCLUSIVE)
    .addVehicleTypes(VehicleType.newBuilder().setCategory(VehicleType.Category.AUTO))
    .setFilter("attributes.on_trip=\"false\"")
    .setOrderBy(VehicleMatchOrder.PICKUP_POINT_ETA)
    .setIncludeBackToBack(true) // Fleet Engine includes vehicles that are en route.
    .build();

// Error handling
// If matches are returned and the authentication passed, the request completed
// successfully

try {
  SearchVehiclesResponse searchVehiclesResponse =
      vehicleService.searchVehicles(searchVehiclesRequest);

  // Search results: Each vehicle match contains a vehicle entity and information
  // about the distance and ETA to the pickup point and dropoff point.
  List<VehicleMatch> vehicleMatches = searchVehiclesResponse.getMatchesList();
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
    case NOT_FOUND:
      break;
    case PERMISSION_DENIED:
      break;
  }
  return;
}

Cụm từ tìm kiếm về việc lọc xe

SearchVehiclesListVehicles hỗ trợ lọc theo thuộc tính xe bằng cách sử dụng truy vấn bộ lọc. Để biết cú pháp truy vấn bộ lọc, hãy xem AIP-160 để biết ví dụ.

Xin lưu ý rằng các truy vấn bộ lọc CHỈ hỗ trợ lọc theo thuộc tính của xe và không thể dùng cho các trường khác. Truy vấn bộ lọc hoạt động dưới dạng mệnh đề AND với các quy tắc ràng buộc khác, chẳng hạn như minimum_capacity hoặc vehicle_types trong SearchVehiclesRequest.

HƯỚNG DẪN: Liệt kê xe

SearchVehicles được tối ưu hoá để tìm một số ít xe theo thứ tự xếp hạng rất nhanh và chủ yếu dùng để tìm những người lái xe ở gần phù hợp nhất với một nhiệm vụ. Tuy nhiên, đôi khi bạn muốn tìm tất cả xe đáp ứng một số tiêu chí ngay cả khi cần phải phân trang thông qua kết quả. ListVehicles được thiết kế cho trường hợp sử dụng đó.

API ListVehicles cho phép bạn tìm tất cả xe đáp ứng một số tuỳ chọn yêu cầu cụ thể. API ListVehicles trả về danh sách xe được phân trang trong dự án phù hợp với một số yêu cầu.

Để lọc theo thuộc tính của xe, vui lòng tham khảo Cụm từ tìm kiếm lọc xe.

Ví dụ:

Ví dụ này thực hiện việc lọc theo vehicle_type và các thuộc tính bằng chuỗi filter.

shell

curl -X POST \
  "https://fleetengine.googleapis.com/v1/providers/project-id/vehicles:list" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  --data-binary @- << EOM
{
  "vehicleTypes": [{"category": "AUTO"}],
  "filter": "attributes.on_trip=\"false\"",
}
EOM

Hãy xem tài liệu tham khảo về providers.vehicles.list.

Java

static final String PROJECT_ID = "project-id";

VehicleServiceBlockingStub vehicleService = VehicleService.newBlockingStub(channel);

String parent = "providers/" + PROJECT_ID;
ListVehiclesRequest listVehiclesRequest = ListVehiclesRequest.newBuilder()
    .setParent(parent)
    .addTripTypes(TripType.EXCLUSIVE)
    .addVehicleTypes(VehicleType.newBuilder().setCategory(VehicleType.Category.AUTO))
    .setFilter("attributes.on_trip=\"false\"")
    .setIncludeBackToBack(true) // Fleet Engine includes vehicles that are en route.
    .build();

// Error handling
// If matches are returned and the authentication passed, the request completed
// successfully

try {
  ListVehiclesResponse listVehiclesResponse =
      vehicleService.listVehicles(listVehiclesRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
    case NOT_FOUND:
      break;
    case PERMISSION_DENIED:
      break;
  }
  return;
}

Các chuyến đi và vòng đời của chúng

API Chuyến đi và vòng đời tương tự như API và vòng đời của xe. Nhà cung cấp dịch vụ đi chung xe chịu trách nhiệm tạo các chuyến đi bằng giao diện Fleet Engine. Fleet Engine cung cấp cả dịch vụ RPC, TripService và tài nguyên REST, provider.trips . Các giao diện này cho phép tạo thực thể Chuyến đi, yêu cầu thông tin, chức năng tìm kiếm và cập nhật.

Trip có trường trạng thái để theo dõi tiến trình trong vòng đời. Các giá trị di chuyển từ NEW sang COMPLETE cùng với CANCELEDUNKNOWN_TRIP_STATUS. Tham khảo trip_status đối với RPC hoặc TripStatus cho REST.

  • NEW
  • ENROUTE_TO_PICKUP
  • ARRIVED_AT_PICKUP
  • ENROUTE_TO_INTERMEDIATE_DESTINATION
  • ARRIVED_AT_INTERMEDIATE_DESTINATION
  • ENROUTE_TO_DROPOFF
  • COMPLETE

Dịch vụ của bạn có thể cập nhật chuyến đi đến CANCELED từ bất kỳ trạng thái nào trong số này. Khi dịch vụ của bạn tạo một chuyến đi, công cụ sẽ đặt trạng thái là NEW. Bạn không bắt buộc phải sử dụng vehicle_id. Giống như phương tiện di chuyển, các dịch vụ sẽ tự động xoá các chuyến đi sau 7 ngày mà không cần cập nhật. Nếu dịch vụ của bạn cố gắng tạo một chuyến đi bằng mã nhận dạng đã tồn tại, thì hệ thống sẽ trả về lỗi. Một chuyến đi được coi là "đang hoạt động" nếu chuyến đi đó có trạng thái không phải là COMPLETE hoặc CANCELED. Sự khác biệt này rất quan trọng trong trường active_trips trong thực thể Xe và SearchTripsRequest.

Dịch vụ chỉ có thể thay đổi vehicle_id được gán cho một Chuyến đi khi trạng thái là NEW hoặc CANCELED. Nếu Người lái xe huỷ một Chuyến đi trong khi đang trên đường, trạng thái Chuyến đi phải được đặt thành NEW hoặc CANCELED trước khi vehicle_id bị thay đổi hoặc xoá.

Trạng thái là rất quan trọng khi triển khai tính năng hỗ trợ chuyến đi quay lại. Sự hỗ trợ này cho phép Nhà cung cấp chỉ định một chuyến đi mới cho một Xe trong khi Xe đó đang trên một Chuyến đi đang hoạt động. Mã để tạo Chuyến đi đường về giống như một chuyến đi và sử dụng cùng một mã phương tiện. Fleet Engine sẽ thêm điểm xuất phát và điểm đến của chuyến đi mới vào các điểm tham chiếu của xe. Để biết thêm thông tin về các chuyến đi hai chiều, hãy xem phần Tạo chuyến đi nhiều điểm.

Điểm tham chiếu còn lại của chuyến đi

Thực thể Trip chứa trường lặp lại của TripWaypoint (RPC | REST), được gọi là remainingWaypoints(RPC | REST). Trường này bao gồm tất cả các điểm mà phương tiện sẽ cần di chuyển theo thứ tự trước điểm trả cuối cùng của chuyến đi này. Giá trị này tính toán từ các điểm tham chiếu còn lại của xe. Trong các trường hợp sử dụng Đi ngược lại và Đi chung xe, danh sách này chứa các điểm tham chiếu từ các chuyến đi khác sẽ đi qua trước chuyến đi này, nhưng không bao gồm mọi điểm tham chiếu sau chuyến đi này. Bạn có thể xác định điểm tham chiếu trong danh sách bằng TripIdWaypointType.

Mối quan hệ giữa trạng thái chuyến đi và điểm tham chiếu còn lại của xe

Các điểm tham chiếu còn lại của xe (RPC | REST) sẽ được cập nhật khi Fleet Engine nhận được yêu cầu thay đổi trạng thái chuyến đi. Điểm tham chiếu trước đó sẽ bị xoá khỏi danh sách điểm tham chiếu còn lại của Xe khi tripStatus(RPC | REST) thay đổi từ trạng thái khác thành ENROUTE_TO_XXX. Tức là, khi trạng thái chuyến đi thay đổi từ ENROUTE_TO_CHOOSEUP thành thì điểm đón của chuyến đi sẽ vẫn nằm trong danh sách điểm tham chiếu còn lại của Xe, nhưng khi trạng thái chuyến đi thay đổi thành ENROUTE_TO_MEDIATE_ Hãy hoặc ENROUTE_TO_DROPOFF, điểm đón của chuyến đi sẽ bị xoá khỏi các điểm tham chiếu còn lại của xe.

Kết quả này là tương tự đối với Cách sánh lượt chuyển đổi ngoại tuyến và địa điểm Vui lòng tham khảo Khi AND_AT_InterMEDIATE_ nơi xuất hiện, điểm đến trung gian hiện tại sẽ không bị xoá khỏi danh sách điểm tham chiếu còn lại của Xe cho đến khi xe báo cáo rằng xe này đang đi đến điểm tham chiếu tiếp theo.

Khi trạng thái chuyến đi được thay đổi thành COMPLETED, sẽ không có điểm tham chiếu nào từ chuyến đi này nằm trong danh sách điểm tham chiếu còn lại của Xe.

HƯỚNG DẪN: Tạo chuyến đi

Bạn phải tạo thực thể Trip để theo dõi và so khớp mỗi yêu cầu về chuyến đi với các phương tiện trong nhóm xe. Sử dụng điểm cuối CreateTrip với CreateTripRequest để tạo một Chuyến đi.

Bạn phải có các thuộc tính sau để tạo chuyến đi:

  • parent – Một chuỗi chứa Mã nhận dạng nhà cung cấp được tạo khi dự án trên Google Cloud được tạo.
  • trip_id – Chuỗi do Nhà cung cấp dịch vụ đi chung xe tạo ra.
  • trip – Vùng chứa có siêu dữ liệu cơ bản mô tả chuyến đi.
    • trip_type – Enum cho biết liệu chuyến đi có thể có người khác đến từ một điểm khởi hành và điểm đến khác trong cùng một xe (SHARED) hay chỉ có một bên (EXCLUSIVE).
    • pickup_point – TerminalLocation biểu thị điểm khởi hành của chuyến đi. Tham khảo Tài liệu tham khảo RPC hoặc Tài liệu tham khảo REST

Khi tạo một chuyến đi, bạn có thể cung cấp number_of_passengers, dropoff_pointvehicle_id. Mặc dù các trường này là không bắt buộc, nhưng nếu bạn cung cấp, chúng sẽ được giữ lại. Tất cả các trường Chuyến đi khác đều bị bỏ qua. Ví dụ: tất cả các chuyến đi đều bắt đầu bằng trip_statusNEW ngay cả khi bạn truyền trip_statusCANCELED trong yêu cầu tạo.

Ví dụ:

Ví dụ sau đây tạo một chuyến đi đến Grand Indonesia East Mall. Chuyến đi chỉ dành cho 2 hành khách. provider_id của Trip phải giống với Mã dự án. Trong ví dụ này, Nhà cung cấp dịch vụ đi chung xe đã tạo Dự án Google Cloud, project-id. Dự án này phải có Tài khoản dịch vụ dùng để gọi Fleet Engine. Trạng thái của chuyến đi là NEW.

Sau đó, sau khi dịch vụ so khớp chuyến đi với một chiếc xe, dịch vụ có thể gọi UpdateTrip và thay đổi vehicle_id khi chuyến đi được chỉ định cho một xe.

shell

curl -X POST \
  "https://fleetengine.googleapis.com/v1/providers/project-id/trips?tripId=tid-1f97" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  --data-binary @- << EOM
{
  "tripType": "EXCLUSIVE",
  "numberOfPassengers": 2,
  "pickupPoint": {
    "point": {"latitude": "-6.195139", "longitude": "106.820826"}
  },
  "dropoffPoint": {
    "point": {"latitude": "-6.1275", "longitude": "106.6537"}
  }
}
EOM

Hãy xem tài liệu tham khảo providers.trips.create.

Java

static final String PROJECT_ID = "project-id";

TripServiceBlockingStub tripService = TripService.newBlockingStub(channel);

String parent = "providers/" + PROJECT_ID;
Trip trip = Trip.newBuilder()
    .setTripType(TripType.EXCLUSIVE) // Use TripType.SHARED for carpooling
    .setPickupPoint(                 // Grand Indonesia East Mall
        TerminalLocation.newBuilder().setPoint(
            LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
    // Provide the number of passengers if available.
    .setNumberOfPassengers(2)
    // Provide the drop-off point if available.
    .setDropoffPoint(
        TerminalLocation.newBuilder().setPoint(
            LatLng.newBuilder().setLatitude(-6.1275).setLongitude(106.6537)))
    .build();

CreateTripRequest createTripRequest =
    CreateTripRequest.newBuilder()  // no need for the header
        .setParent(parent)
        .setTripId("tid-1f97")  // Trip ID assigned by the Provider
        .setTrip(trip)              // Initial state
        .build();

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

try {
  Trip createdTrip =
      tripService.createTrip(createTripRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
    case ALREADY_EXISTS:
      break;
    case PERMISSION_DENIED:
      break;
  }
  return;
}

Nhật ký trên nền tảng Google Cloud cho quy trình Tạo chuyến đi

Fleet Engine API sẽ ghi một mục nhập nhật ký bằng cách sử dụng nhật ký của Google Cloud Platform khi nhận được lệnh gọi đến điểm cuối CreateTrip. Mục nhập nhật ký bao gồm thông tin về các giá trị trong yêu cầu CreateTrip. Nếu lệnh gọi thành công, lệnh gọi cũng sẽ bao gồm thông tin về Trip được trả về.

CÁCH LÀM: Cập nhật chuyến đi

Thực thể Trip chứa các trường cho phép dịch vụ theo dõi và báo cáo tiến trình của chuyến đi bằng SDK trình điều khiển và cho SDK người tiêu dùng. Để cập nhật các thuộc tính, hãy sử dụng thông báo UpdateTripRequest. Thao tác này sẽ cập nhật các trường Chuyến đi theo field_mask của yêu cầu. Tham khảo UpdateTripRequest.

Nhà cung cấp dịch vụ đi chung xe có trách nhiệm cập nhật các thuộc tính sau đây:

  • Trạng thái chuyến đi.
  • Mã xe. Tại thời điểm tạo hoặc sau khi so khớp xe với một chuyến đi.
  • Thay đổi đối với điểm đến lấy hàng, điểm trả xe hoặc điểm tham chiếu.

Fleet Engine sẽ tự động cập nhật các trường sau đây khi sử dụng tính năng Chia sẻ hành trình thông qua SDK trình điều khiển hoặc SDK người dùng:

  • Tuyến đường
  • Giờ đến dự kiến
  • Quãng đường còn lại
  • Vị trí xe
  • Điểm tham chiếu còn lại

Tham chiếu đến Trip trong RPC hoặc Resource.Trip trong REST.

Nhật ký trên nền tảng Google Cloud cho thông tin cập nhật về chuyến đi

Fleet Engine API sẽ ghi một mục nhập nhật ký bằng cách sử dụng nhật ký của Google Cloud Platform khi nhận được lệnh gọi đến điểm cuối UpdateTrip. Mục nhập nhật ký bao gồm thông tin về các giá trị trong yêu cầu UpdateTrip. Nếu lệnh gọi thành công, lệnh gọi này cũng sẽ bao gồm thông tin về Trip được trả về.

CÁCH: Tìm kiếm chuyến đi

Fleet Engine hỗ trợ tìm kiếm chuyến đi. Như đã lưu ý trước đó, một Chuyến đi sẽ tự động bị xoá sau 7 ngày, vì vậy, SearchTrips không hiển thị toàn bộ nhật ký của tất cả Chuyến đi.

Mặc dù SearchTrips là một API linh hoạt, nhưng danh sách dưới đây sẽ xem xét 2 trường hợp sử dụng.

  • Xác định các chuyến đi đang hoạt động của xe – Nhà cung cấp có thể xác định các chuyến đi hiện đang hoạt động của một chiếc xe. Trong SearchTripsRequest, vehicle_id được đặt thành xe đang được xem xét và active_trips_only phải được đặt thành true.

  • Đối chiếu trạng thái công cụ của Nhà cung cấp và Fleet Engine – Nhà cung cấp có thể sử dụng SearchTrips để đảm bảo trạng thái Chuyến đi của họ và trạng thái của Fleet Engine khớp với nhau. Điều này đặc biệt quan trọng đối với TripStatus. Nếu trạng thái của chuyến đi được chỉ định cho một Phương tiện không được đặt đúng cách thành COMPLETE hoặc CANCELED, thì SearchVehicles sẽ không bao gồm Phương tiện đó.

Để sử dụng SearchTrips theo cách này, hãy để trống vehicle_id, đặt active_trips_only thành true và đặt minimum_staleness thành thời gian dài hơn hầu hết thời lượng chuyến đi. Ví dụ: bạn có thể sử dụng một giờ. Kết quả bao gồm các Chuyến đi không HOÀN THÀNH hoặc BỊ HUỶ và chưa được cập nhật trong hơn một giờ. Nhà cung cấp nên kiểm tra các Chuyến đi này để đảm bảo rằng trạng thái của các Chuyến đi trong Fleet Engine được cập nhật đúng.

Khắc phục sự cố

Trong trường hợp xảy ra Lỗi DEADLINE_EXCEEDED, trạng thái của Fleet Engine là không xác định. Nhà cung cấp nên gọi lại CreateTrip và trả về 201 (TẠO) hoặc 409 (XUNG ĐỘT). Trong trường hợp sau, yêu cầu trước đó đã thành công trước DEADLINE_EXCEEDED. Hãy xem hướng dẫn về API Người tiêu dùng để biết thêm thông tin về cách xử lý lỗi chuyến đi: Android hoặc iOS.

Hỗ trợ đi chung xe

Bạn có thể chỉ định nhiều chuyến đi SHARED cho một xe hỗ trợ TripType.SHARED. Bạn cần chỉ định thứ tự của tất cả các điểm tham chiếu chưa được phép cho tất cả Chuyến đi được chỉ định cho Xe trong chuyến đi chung này thông qua Trip.vehicle_waypoints khi bạn chỉ định vehicle_id cho một chuyến đi chung (trong yêu cầu CreateTrip hoặc UpdateTrip). Tham khảo vehicle_waypoints đối với RPC hoặc vehicleWaypoints đối với REST.

Hỗ trợ nhiều đích đến

Xác định đích đến trung gian

Trường intermediateDestinations và trường intermediateDestinationIndex trong Chuyến đi (RPC | REST) được kết hợp để cho biết đích đến.

Cập nhật đích đến trung gian

Bạn có thể cập nhật các đích đến trung gian qua UpdateTrip. Khi cập nhật các đích đến trung gian, bạn phải cung cấp danh sách đầy đủ các đích đến trung gian, bao gồm các đích đến đã được truy cập, chứ không chỉ đích đến mới được thêm hoặc cần sửa đổi. Khi intermediateDestinationIndex trỏ đến một chỉ mục sau vị trí của đích đến trung gian mới được thêm/sửa đổi, đích đến trung gian mới/đã cập nhật sẽ không được thêm vào waypoints của Xe hoặc remainingWaypoints của Chuyến đi. Lý do là mọi đích đến trung gian trước intermediateDestinationIndex đều được coi là đã truy cập.

Các thay đổi về trạng thái chuyến đi

Trường intermediateDestinationsVersion trong (RPC | REST) là bắt buộc trong yêu cầu cập nhật trạng thái Chuyến đi được gửi tới Fleet Engine để cho biết một điểm đến trung gian đã qua. Đích trung gian nhắm mục tiêu được chỉ định thông qua trường intermediateDestinationIndex. Khi tripStatus (RPC | REST) là ENROUTE_TO_interMEDIATE_websearch, một số trong khoảng [0..N-1] cho biết xe sẽ đi qua điểm đến trung gian nào tiếp theo. Khi tripStatus là Cách sánh lượt chuyển đổi ngoại tuyến đến hôm nay là Tạo.

Ví dụ:

Ví dụ về mã sau đây minh hoạ cách cập nhật trạng thái của một chuyến đi để trên đường đến điểm đến trung gian đầu tiên, giả sử bạn đã tạo một chuyến đi nhiều điểm đến và chuyến đi đã vượt qua điểm đón của nó.

Java

static final String PROJECT_ID = "project-id";
static final String TRIP_ID = "multi-destination-trip-A";

String tripName = "providers/" + PROJECT_ID + "/trips/" + TRIP_ID;
Trip trip = …; // Fetch trip object from FleetEngine or your storage.

TripServiceBlockingStub tripService = TripService.newBlockingStub(channel);

// Trip settings to update.
Trip trip = Trip.newBuilder()
    // Trip status cannot go back to a previous status once it is passed
    .setTripStatus(TripStatus.ENROUTE_TO_INTERMEDIATE_DESTINATION)
    // Enrouting to the first intermediate destination.
    .setIntermediateDestinationIndex(0)
    // intermediate_destinations_version MUST be provided to ensure you
    // have the same picture on intermediate destinations list as FleetEngine has.
    .setIntermediateDestinationsVersion(
        trip.getIntermediateDestinationsVersion())
    .build();

// Trip update request
UpdateTripRequest updateTripRequest =
    UpdateTripRequest.newBuilder()
        .setName(tripName)
        .setTrip(trip)
        .setUpdateMask(
            FieldMask.newBuilder()
                .addPaths("trip_status")
                .addPaths("intermediate_destination_index")
                // intermediate_destinations_version must not be in the
                // update mask.
                .build())
        .build();

// Error handling
try {
  Trip updatedTrip = tripService.updateTrip(updateTripRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
    case NOT_FOUND:  // Trip does not exist.
      break;
    case FAILED_PRECONDITION:  // The given trip status is invalid, or the
                                // intermediate_destinations_version
                                // doesn’t match FleetEngine’s.
      break;
    case PERMISSION_DENIED:
      break;
  }
  return;
}

HƯỚNG DẪN: Đăng ký nhận thông báo từ Fleet Engine API

API Fleet Engine sử dụng Google Cloud Pub/Sub để phát hành thông báo về chủ đề này do Dự án Google Cloud dành cho người dùng thông thường tạo ra. Pub/Sub không được bật theo mặc định cho Fleet Engine trong dự án Google Cloud của bạn. Vui lòng gửi yêu cầu hỗ trợ hoặc liên hệ với Kỹ sư khách hàng của bạn để bật Pub/Sub.

Để tạo chủ đề cho dự án Cloud của bạn, hãy làm theo các hướng dẫn này. Mã chủ đề phải là 'fleet_engine_notification'.

Chủ đề phải được tạo trong cùng một dự án Cloud đang gọi các API Fleet Engine.

Sau khi tạo chủ đề, bạn sẽ cần cấp quyền cho Fleet Engine API để xuất bản chủ đề đó. Để làm như vậy, hãy nhấp vào chủ đề bạn vừa tạo và thêm quyền mới. Bạn có thể phải nhấp vào HIỂN THỊ BẢNG THÔNG TIN để mở trình chỉnh sửa quyền. Đối tượng chính phải là geo-fleet-engine@system.gserviceaccount.com và vai trò phải là Pub/Sub publisher.

Để thiết lập dự án Cloud nhằm đăng ký nhận thông báo, hãy làm theo các hướng dẫn này

Fleet Engine API sẽ phát hành mỗi thông báo ở hai định dạng dữ liệu khác nhau là protobufjson. Định dạng dữ liệu của mỗi thông báo được biểu thị trong các thuộc tính PubsubMessage với khoá là data_format và giá trị là protobuf hoặc json.

Giản đồ thông báo:

Protobuf

// A batch of notifications that is published by the Fleet Engine service using
// Cloud Pub/Sub in a single PubsubMessage.
message BatchNotification {
  // Required. At least one notification must exist.
  // List of notifications containing information related to changes in
  // Fleet Engine data.
  repeated Notification notifications = 1;
}

// A notification related to changes in Fleet Engine data.
// The data provides additional information specific to the type of the
// notification.
message Notification {
  // Required. At least one type must exist.
  // Type of notification.
  oneof type {
    // Notification related to changes in vehicle data.
    VehicleNotification vehicle_notification = 1;
  }
}

// Notification sent when a new vehicle was created.
message CreateVehicleNotification {
  // Required.
  // Vehicle must contain all fields that were set when it was created.
  Vehicle vehicle = 1;
}

// Notification sent when an existing vehicle is updated.
message UpdateVehicleNotification {
  // Required.
  // Vehicle must only contain name and fields that are present in the
  // field_mask field below.
  Vehicle vehicle = 1;

  // Required.
  // Contains vehicle field paths that were specifically requested
  // by the Provider.
  google.protobuf.FieldMask field_mask = 2;
}

// Notification related to changes in vehicle data.
message VehicleNotification {
  // Required. At least one type must be set.
  // Type of notification.
  oneof type {
    // Notification sent when a new vehicle was created.
    CreateVehicleNotification create_notification = 1;
    // Notification sent when an existing vehicle is updated.
    UpdateVehicleNotification update_notification = 2;
  }
}

JSON

BatchNotification: {
  "description": "A batch of notifications that is published by the Fleet Engine service using Cloud Pub/Sub in a single PubsubMessage.",
  "type": "object",
  "required": ["notifications"],
  "properties": {
    "notifications": {
      "description": "At least one notification must exist. List of notifications containing information related to changes in Fleet Engine data.",
      "type": "Notification[]"
    }
  }
}

Notification: {
  "description": "A notification related to changes in Fleet Engine data. The data provides additional information specific to the type of the notification.",
  "type": "object",
  "properties": {
    "vehicleNotification": {
      "description": "Notification related to changes in vehicle data.",
      "type": "VehicleNotification"
    }
  }
}

VehicleNotification: {
  "description": "Notification related to changes in vehicle data.",
  "type": "object",
  "properties": {
    "createNotification": {
      "description": "Notification sent when a new vehicle was created.",
      "type": "CreateVehicleNotification"
    },
    "updateNotification": {
      "description": "Notification sent when an existing vehicle is updated.",
      "type": "UpdateVehicleNotification"
    }
  }
}

CreateVehicleNotification: {
  "description": "Notification sent when a new vehicle was created.",
  "type": "object",
  "required": ["vehicle"],
  "properties": {
    "vehicle": {
      "description": "Vehicle must contain all fields that were set when it was created.",
      "type": "Vehicle"
    }
  }
}

UpdateVehicleNotification: {
  "description": "Notification sent when an existing vehicle is updated.",
  "type": "object",
  "required": ["vehicle", "fieldMask"],
  "properties": {
    "vehicle": {
      "description": "Vehicle must only contain name and fields that are present in the fieldMask field below.",
      "type": "Vehicle"
    },
    "fieldMask": {
      "description": "Contains vehicle field paths that were specifically requested by the Provider.",
      "type": "FieldMask"
    }
  }
}