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

API Giao hàng và gọi xe theo yêu cầu của Fleet Engine giúp bạn quản lý các chuyến đi và trạng thái xe cho các ứng dụng Chuyến đi và Tiến trình đặt hàng của bạn. Thư viện này xử lý các giao dịch giữa SDK trình điều khiển, SDK người tiêu 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 các lệnh gọi gRPC hoặc REST.

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

Để phát triển, hãy nhớ cài đặt Cloud SDK (gcloud) và xác thực dự án của bạn.

shell

gcloud auth login

Bạn sẽ thấy thông báo thành công, chẳng hạn 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 Fleet Engine của 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 gây ra lỗi, hãy liên hệ với quản trị viên dự án và người đại diện Nhóm hỗ trợ Google để được cấp quyền truy cập.

Ghi nhật ký

Fleet Engine có thể ghi thông điệp nhật ký về các lệnh gọi API mà nó nhận được vào nhật ký của Google Cloud Platform. Xem tài liệu về Cloud Logging (Ghi nhật ký trên đám mây) để 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 được 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 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 tải thư viện ứng dụng cho ứng dụng máy chủ, 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 Tiến trình đặt hàng và chuyến đi 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ụ được tạo từ Cloud Console.

Thiết lập dự án trên đám mây

Để 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 Google Cloud Console.
  2. Sử dụng Trang tổng quan các API và dịch vụ, bật API Dịch vụ gọi xe và giao hàng địa phương.

Tài khoản dịch vụ được liên kết với một hoặc nhiều vai trò. Các thư viện này dùng để tạo Mã thông báo web JSON nhằm cấp các nhóm quyền khác nhau tuỳ theo 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ụ, mỗi tài khoản có số lượng vai trò tối thiểu cần thiết.

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

RoleNội dung mô tả
Người dùng SDK tiêu dùng của Fleet Engine

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

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ề xe và chuyến đi. Những mã thông báo do tài khoản dịch vụ tạo ra có vai trò này thường được dùng trên các thiết bị di động của ứng dụng đi chung xe hoặc giao hàng dành cho tài xế.
Quản trị viên theo yêu cầu của Fleet Engine

roles/fleetengine.ondemandAdmin
Cấp quyền đọc và ghi mọi tài nguyên về xe cộ và chuyến đi. Những người dùng có vai trò này không cần phải dùng JWT và thay vào đó, họ nên dùng Thông tin xác thực mặc định của ứng dụng. Các thông báo xác nhận quyền sở hữu JWT tuỳ chỉnh sẽ bị bỏ qua. Vai trò này chỉ được dành cho các môi trường đáng tin cậy (phần phụ trợ của khách hàng).
Siêu người dùng dịch vụ FleetEngine **(KHÔNG DÙNG NỮA)**

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

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 các 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 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ò 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. SDK Trình điều khiển và SDK Người tiêu dùng sẽ hiển thị thông báo lỗi bất cứ khi nào thiếu quyền cần thiết. Do đó, bạn rất nên sử dụng nhóm vai trò chuẩn nêu trên và không 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 những khách hàng không đá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 của tài khoản dịch vụ sẽ giúp họ tạo mã thông báo bằng 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 Fleet Engine. Thư viện xác thực công cụ Fleet Engine mới, có trên GitHub, giúp đơn giản hoá quá trình xây dựng JWT Fleet Engine và ký tên một cách an toàn.

Thư viện mang lại những lợi ích sau:

  • Đơn giản hoá quy trình tạo Mã thông báo Fleet Engine.
  • Cung cấp 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 công cụ Fleet, bạn cần tạo Mã thông báo web JSON (JWT) trực tiếp trong cơ sở mã của mình. Để làm được như vậy, bạn phải hiểu rõ về JWT cũng như 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ụ được cho phép. 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 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, những 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ảm phạm vi truy cập; ví dụ: mã xe.

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

Kỹ thuậtNội dung mô tả
alg Thuật toán cầ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 trong tài khoản dịch vụ. Hãy nhớ sử dụng khoá trong một tài khoản dịch vụ có cấp độ quyền phù hợp.

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

Kỹ thuậtNội dung mô tả
Đị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.
aud SERVICE_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/
kiến thức Dấu thời gian khi mã thông báo được tạo, được chỉ định bằng giây đã trôi qua kể từ 00:00:00 giờ 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ì có thể máy chủ sẽ 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 đã trôi qua kể từ 00:00:00 giờ 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 là hơn một giờ trong tương lai.
khoản uỷ quyền Tuỳ thuộc vào trường hợp sử dụng, có thể chứa "vehicleid" hoặc "tripid".

Việc tạo mã thông báo JWT tức là ký mã đó. Để biết hướng dẫn và mã mẫu để tạo và ký JWT, hãy xem phần Uỷ quyền tài khoản dịch vụ 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.

Thông báo xác nhận quyền sở hữu 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 bằng cách khoá vehicleid hoặc tripid được đặt thành giá trị của mã nhận dạng 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, cho dù hoạt động trên phương tiện di chuyển hay phương tiện di chuyển. Phần phụ trợ của Fleet Engine đảm bảo rằng xe được liên kết với chuyến đi mà bạn yêu cầu trước khi 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.

Nhà cung cấp dịch vụ đi chung xe hoặc giao hàng phải sử dụng vehicleid hoặc tripid có "*" để khớp với tất cả Xe 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 hoạt động ký mã thông báo.

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

Sau đây là một mã thông báo mẫu cho máy chủ của 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": "*"
   }
}

Sau đây là ví dụ về mã thông báo cho Ứng dụng người 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"
   }
}

Sau đây là ví dụ về mã thông báo cho ứng dụng Trình điều khiển:

{
  "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 trong 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ụ của bạn. Bạn có thể tìm thấy giá trị này trong trường client_email của tệp JSON trong 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ã thông báo được tạo, được chỉ định là số giây đã trôi qua kể từ 00:00:00 giờ 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ì có thể máy chủ sẽ 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 giờ 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ò Trình điều khiển hoặc SDK Người tiêu dùng. Nếu không, thiết bị di động sẽ có khả năng thay đổi trạng thái lẽ ra không nê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ụ có vai trò Người dùng cao cấp. Nếu không, thao tác này 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 các 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 cho 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 một tệp mới có tên là unsigned_token.json chứa nội dung ở bên dưới. 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. 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 vượt quá 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 cho tài khoản dịch vụ Super User 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á Base64 đã ký sẽ được lưu trữ trong tệp signed_token.jwt. Mã thông báo này sẽ có hiệu lực trong giờ tiếp theo.

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 của Danh sách phương tiện di chuyển:

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

Xe cộ và vòng đời của chúng

Xe là thực thể đại diện cho một cặp xe. Hiện tại, bạn không thể theo dõi riêng Người lái xe và Xe. Nhà cung cấp dịch vụ đi chung xe hoặc phân phối tạo xe bằng Mã nhà cung cấp (mã này phải giống với Mã dự án của dự án trên Google Cloud chứa tài khoản dịch vụ dùng để gọi các API Fleet Engine) và Mã xe thuộc quyền sở hữu của Nhà cung cấp dịch vụ đi chung xe hoặc nhà cung cấp dịch vụ giao hàng.

Một chiếc xe chưa được cập nhật qua UpdateVehicle sau 7 ngày sẽ tự động bị xoá. Lỗi khi gọi CreateVehicle bằng một cặp Mã nhà cung cấp/Mã xe đã tồn tại. Có thể xử lý trường hợp xe không được cập nhật thường xuyên theo 2 cách: thường xuyên gọi CreateVehicle bằng 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ị trí xe

Để Fleet Engine đạt được hiệu suất tốt nhất, hãy cung cấp cho công cụ này một luồng thông tin cập nhật vị trí của xe. Bạn có thể sử dụng một trong các cách sau để cung cấp các thông tin 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 các 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 VehicleType, trong đó chứa enum Category có thể được chỉ định là AUTO, TAXI, TRUCK, TWO_WHEELER, BICYCLE hoặc PEDESTRIAN. Loại xe có thể đóng vai trò là tiêu chí bộ lọc trong SearchVehiclesListVehicles.

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

Thuộc tính xe

Thực thể Xe chứa một trường lặp lại là 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 tất cả các thuộc tính đi kèm được đặt thành giá trị đã 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 của 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 vì các chuyến đi được chỉ định cho xe và cập nhật trường này khi trạng thái của các chuyến đi thay đổ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.

Tăng khả năng xe đủ điều kiện tham gia các trận đấu

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 xe. Dịch vụ này có thể sử dụng các thuộc tính của xe để thêm một chiếc xe vào nhiều cụm từ tìm kiếm hơn. Ví dụ: nhà cung cấp có thể triển khai một tập hợp thành các thuộc tính tương ứng với cấp đặc quyền hoặc khả năng do 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ó các giá trị boolean: is_bronze_level, is_silver_levelis_gold_level. Một chiếc xe có thể đủ điều kiện cho cả ba loại. Khi Fleet Engine nhận được một yêu cầu về một chuyến đi yêu cầu khả năng ở cấp độ Bạc, nội dung tìm kiếm sẽ bao gồm chiếc xe đó. Việc sử dụng các thuộc tính theo cách này áp dụng cho cả những chiếc xe 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. Một phương thức khác 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 được chỉ định sẽ không được thay đổi.

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

Bạn phải tạo một thực thể Vehicle cho mỗi Chiếc xe để theo dõi trong hệ thống thiết bị.

Sử dụng điểm cuối CreateVehicle với CreateVehicleRequest để tạo 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 trên Google Cloud có chứa Tài khoản dịch vụ sẽ được 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 Nhà cung cấp dịch vụ đi chung xe hoặc giao hàng, nhưng Fleet Engine hiện không hỗ trợ các tài khoản dịch vụ của nhiều dự án trê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, kết quả này có thể được trả về ngay lập tức theo 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, bạn không nên tạo Vehicle ở trạng thái ONLINE nếu 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.

Vui lòng xem phần Thuộc tính của xe để biết thông tin chi tiết về trường thuộc tính.

Giá trị được CreateVehicle trả về là thực thể Vehicle đã 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ệp tham chiếu 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 cho việc tạo xe

API Fleet Engine 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"
'

Phải in một bản ghi tương tự như bản ghi 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 phát hành một thông báo qua Cloud Pub/Sub khi tạo một xe mới. Để 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 THỰC HIỆN: Cập nhật vị trí của xe

Nếu không dùng SDK trình điều khiển để cập nhật vị trí của xe, bạn có thể gọi trực tiếp đến Fleet Engine để cung cấp thông tin về vị trí của xe. Đối với mọi xe đang hoạt động, Fleet Engine sẽ cập nhật vị trí tối thiểu 1 lần/phút và tối đa 5 giây/lần. Những bản cập nhật này chỉ yêu cầu các đặc quyền của người dùng SDK Fleet Engine Driver.

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 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 THỰC HIỆN: Cập nhật các trường khác về Xe

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

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

Như đã lưu ý trong mục Thuộc tính xe, việc cập nhật trường attributes yêu cầu bạn ghi tất cả các thuộc tính cần được giữ nguyên. 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 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 Google Cloud Platform dành cho xe cập nhật

API Fleet Engine 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ề việc cập nhật xe

Fleet Engine API 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.

CÁCH THỰC HIỆN: Tìm xe

Fleet Engine hỗ trợ tìm kiếm xe. API SearchVehicles cho phép bạn tìm các tài xế ở gần phù hợp nhất với một nhiệm vụ như phục vụ gọi xe hoặc yêu cầu giao hàng. API SearchVehicles trả về một danh sách xếp hạng gồm những người lái xe khớp với các thuộc tính nhiệm vụ khớp với các thuộc tính của xe trong nhóm 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ụ:

Theo mặc định, khi tìm kiếm xe hiện có, Fleet Engine sẽ loại trừ những phương tiện trong các chuyến đi đang hoạt động. Các dịch vụ của Nhà cung cấp dịch vụ đi chung xe hoặc giao hàng cần phải đưa những thông tin này vào yêu cầu tìm kiếm một cách rõ ràng. Ví dụ sau đây cho thấy cách đưa những phương tiện đó vào kết quả tìm kiếm cá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ị Balai Sidang Jakarta.

shell

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

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 ít nhất phải mang lại cho bạn 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 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ề bộ lọc xe

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

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

CÁCH THỰC HIỆN: Đăng thông tin về xe

SearchVehicles được tối ưu hoá để nhanh chóng tìm kiếm một số lượng nhỏ xe trong thứ tự được xếp hạng và chủ yếu được dùng để tìm những người lái xe ở gần phù hợp nhất cho 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â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 thấy tất cả các xe đáp ứng một số lựa chọn yêu cầu cụ thể. API ListVehicles trả về một 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 các thuộc tính xe, vui lòng tham khảo Cụm từ tìm kiếm về tính năng lọc xe.

Ví dụ:

Ví dụ này thực hiện việc lọc trên vehicle_type và các thuộc tính bằng cách sử dụ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 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;
}

Chuyến đi và vòng đời của chuyến đi

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à khả năng cập nhật.

Trip có một trường trạng thái để theo dõi tiến trình của nó trong suốt vòng đời. Các giá trị chuyển từ NEW sang COMPLETE cùng với CANCELEDUNKNOWN_TRIP_STATUS. Hãy 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 sau đây. Khi dịch vụ của bạn tạo ra một chuyến đi, công cụ sẽ đặt trạng thái là NEW. vehicle_id là không bắt buộc. Tương tự như với phương tiện di chuyển, các dịch vụ này 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 chuyến đi với 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 ở 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ụ của bạn chỉ có thể thay đổi vehicle_id được chỉ định cho một chuyến đi khi chuyến đi đó đang hoạt động. Ví dụ: bạn sẽ thực hiện việc này khi người lái xe huỷ một chuyến đi trong khi đang trên đường và chuyến đi được chỉ định lại cho một chiếc xe khác.

Trạng thái này rất quan trọng khi triển khai tính năng hỗ trợ đi lại. Dịch vụ 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 trong một Chuyến đi đang hoạt động. Mã để tạo Chuyến đi khứ hồi cũng giống như một chuyến đi duy nhất và sử dụng cùng một mã xe. Fleet Engine thêm điểm khởi hành 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 khứ hồi, hãy xem phần Tạo các chuyến đi nhiều chặng.

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

Thực thể Chuyến đi chứa một trường lặp lại là TripWaypoint (RPC | REST), có tên là remainingWaypoints(RPC | REST). Trường này bao gồm tất cả các điểm tham chiếu mà xe cần di chuyển theo thứ tự trước điểm trả khách cuối cùng của chuyến đi này. Giá trị này tính 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 tính năng Quay lại và đi chung xe, danh sách này chứa các điểm tham chiếu của các chuyến đi khác sẽ được di chuyển 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 của chuyến đi và số đ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 các đ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_PICKUP thành ARRIVED_AT_PICKUP, điểm đón của chuyến đi vẫn sẽ 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 được thay đổi thành ENROUTE_TO_INTERMEDIATE_PLACE hoặc ENROUTE_TO_DROPOFF, thì điểm đón của điểm đó sẽ bị xoá khỏi điểm đón còn lại của xe.

Điều này tương tự với ARRIVED_AT_INTERMEDIATE_URL và ENROUTE_TO_INTERMDEDIATE_Destination. Khi ARRIVED_AT_INTERMEDIATE_URL, đích đế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 mình đ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 của chuyến đi này 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 một thực thể Trip để theo dõi và so khớp mỗi yêu cầu chuyến đi với các phương tiện trong nhóm phương tiện. Sử dụng điểm cuối CreateTrip với CreateTripRequest để tạo một Chuyến đi.

Các thuộc tính sau đây là bắt buộc để tạo chuyến đi:

  • parent – Một chuỗi bao gồm Mã nhà cung cấp được tạo khi tạo Dự án Google Cloud.
  • trip_id – Chuỗi do Nhà cung cấp dịch vụ đi chung xe tạo.
  • trip – Vùng chứa có siêu dữ liệu cơ bản mô tả chuyến đi.

Khi tạo 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 thì các trường này sẽ được giữ lại. Tất cả các trường Chuyến đi khác sẽ bị bỏ qua. Ví dụ: mọi chuyến đi đều bắt đầu bằng trip_statusNEW ngay cả khi bạn truyền một trip_status của CANCELED vào yêu cầu tạo.

Ví dụ:

Ví dụ sau đây tạo ra một chuyến đi đến Trung tâm mua sắm Grand Indonesia East. Đây là chuyến đi dành riêng 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 là 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 khớp với chuyến đi đến 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 chiếc 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ệp tham chiếu 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ý của Google Cloud Platform dành cho tính năng Tạo chuyến đi

API Fleet Engine ghi 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 này cũng sẽ bao gồm thông tin về Trip đã được trả về.

HƯỚNG DẪN: Cập nhật chuyến đi

Thực thể Chuyến đi 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à SDK cho 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. Hãy tham khảo UpdateTripRequest.

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

  • 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, trả khách hoặc điểm tham chiếu.

Fleet Engine 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 tiêu 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 khảo Triptrong RPC hoặc Resource.Trip trong REST.

Nhật ký của Google Cloud Platform cho thông tin cập nhật về chuyến đi

API Fleet Engine ghi 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ề.

HƯỚNG DẪN: Tìm kiếm chuyến đi

Fleet Engine hỗ trợ tìm kiếm các 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à API linh hoạt, nhưng danh sách dưới đây xem xét 2 trường hợp sử dụng.

  • Xác định 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 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ủ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ọ khớp với trạng thái của Fleet Engine. Đ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 Xe không được đặt đúng cách thành COMPLETE hoặc CANCELED, thì Xe đó sẽ không được SearchVehicles bao gồm.

Để 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 lớn 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 những Chuyến đi không HOÀN THÀNH hoặc ĐÃ HUỶ, và chưa được cập nhật trong hơn một giờ. Nhà cung cấp phải kiểm tra các Chuyến đi này để đảm bảo rằng trạng thái của chúng trong Fleet Engine được cập nhật đúng cách.

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 sẽ gọi lại CreateTrip để trả về lỗi 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. 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ự tất cả các điểm tham chiếu chưa được vượt qua 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 một đích đến trung gian

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

Cập nhật vị trí xuất hiện trung gian

Bạn có thể cập nhật các đích đến trung gian thông qua UpdateTrip. Khi cập nhật đí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ả những đích đến đã được truy cập, chứ không chỉ là đích đến mới 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à đã được 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 đã vượt qua. Đích đến trung gian được nhắm đến được chỉ định thông qua trường intermediateDestinationIndex. Khi tripStatus (RPC | REST) là ENROUTE_TO_INTERMEDIATE_Destination, một số giữa [0..N-1] cho biết điểm đến trung gian mà xe sẽ đi qua tiếp theo. Khi tripStatus là ARRIVED_AT_INTERMEDIATE_destination, một số giữa [0..N-1] cho biết xe đang ở điểm đến trung gian nà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 để đến đích 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.

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;
}

CÁCH THỰC HIỆN: Đăng ký nhận thông báo từ API Fleet Engine

API Fleet Engine sử dụng Google Cloud Pub/Sub để phát hành thông báo về chủ đề do Dự án Google Cloud dành cho người dùng tạo ra. Theo mặc định, Pub/Sub không được bật 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 một chủ đề trong dự án trên Google Cloud, hãy làm theo hướng dẫn tại đâ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 API Fleet Engine.

Sau khi tạo chủ đề, bạn sẽ cần cấp quyền API Fleet Engine để xuất bản về chủ đề đó. Để làm việc này, hãy nhấp vào chủ đề bạn vừa tạo rồi thêm quyền mới. Bạn có thể phải nhấp vào HIỂN THỊ BẢNG ĐIỀU KHIỂN 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ò này phải là Pub/Sub publisher.

Để thiết lập dự án trên đám mây của bạn cho việc đă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 từng thông báo ở hai định dạng dữ liệu khác nhau là protobufjson. Định dạng dữ liệu cho mỗi thông báo được biểu thị trong 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"
    }
  }
}