เริ่มต้นใช้งาน Fleet Engine

Fleet Engine On-demand Rides and Deliveries API ช่วยให้คุณจัดการการเดินทางและสถานะของพาหนะสำหรับแอปพลิเคชันการเดินทางและความคืบหน้าในการสั่งซื้อได้ โดยจะจัดการธุรกรรมระหว่าง Driver SDK, Consumer SDK และบริการแบ็กเอนด์ ซึ่งสื่อสารกับ Fleet Engine ได้ด้วยการเรียกใช้ gRPC หรือ REST

ข้อกำหนดเบื้องต้น

สำหรับการพัฒนา โปรดตรวจสอบว่าคุณติดตั้ง Cloud SDK (gcloud) และได้รับการตรวจสอบสิทธิ์ไปยังโปรเจ็กต์แล้ว

Shell

gcloud auth login

คุณควรเห็นข้อความแสดงความสำเร็จ เช่น

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

ตรวจสอบว่าได้รับการกำหนดค่า Rides แบบออนดีมานด์และ Deliveries Solution Fleet Engine API อย่างเหมาะสมแล้ว

Shell

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

หากคำสั่งนี้เกิดข้อผิดพลาด โปรดติดต่อผู้ดูแลระบบโปรเจ็กต์และตัวแทนทีมสนับสนุนของ Google เพื่อขอสิทธิ์เข้าถึง

Logging

Feet Engine จะเขียนข้อความบันทึกเกี่ยวกับการเรียก API ที่ได้รับลงใน บันทึกของ Google Cloud Platform ได้ ดูภาพรวมของวิธีอ่านและวิเคราะห์บันทึกได้ในเอกสารประกอบ Cloud Logging

ระบบอาจไม่ได้เปิดใช้การบันทึกโดยค่าเริ่มต้นสำหรับโปรเจ็กต์ที่สร้างขึ้นก่อนวันที่ 10 กุมภาพันธ์ 2022 ดูรายละเอียดเพิ่มเติมได้ในเอกสารการบันทึก

ไลบรารีไคลเอ็นต์

เราเผยแพร่ไลบรารีของไคลเอ็นต์ในภาษาโปรแกรมทั่วไปหลายภาษา ไลบรารีเหล่านี้จะช่วยให้นักพัฒนาแอปได้รับประสบการณ์ที่ดีกว่า REST หรือ gRPC ดิบ โปรดดูวิธีการรับไลบรารีไคลเอ็นต์สำหรับแอปพลิเคชันเซิร์ฟเวอร์ที่ไลบรารีไคลเอ็นต์

ตัวอย่าง Java ในเอกสารนี้จะถือว่าคุ้นเคยกับ gRPC

การตรวจสอบสิทธิ์และการให้สิทธิ์

คุณกำหนดค่าความสามารถของความคืบหน้าของการเดินทางและคำสั่งซื้อผ่าน Google Cloud Console ได้ API และ SDK เหล่านี้ต้องใช้โทเค็นเว็บ JSON ที่รับรองโดยใช้บัญชีบริการที่สร้างขึ้นจาก Cloud Console

การตั้งค่าโปรเจ็กต์ที่อยู่ในระบบคลาวด์

หากต้องการตั้งค่าโปรเจ็กต์ระบบคลาวด์ ให้สร้างโปรเจ็กต์ก่อนแล้วจึงสร้างบัญชีบริการ

วิธีสร้างโปรเจ็กต์ Google Cloud

  1. สร้างโปรเจ็กต์ Google Cloud โดยใช้คอนโซล Google Cloud
  2. การใช้ API และแดชบอร์ดบริการเปิดใช้งาน Local Rides and Deliveries API

บัญชีบริการเชื่อมโยงกับบทบาทอย่างน้อย 1 บทบาท โทเค็นเหล่านี้ใช้เพื่อสร้างโทเค็นเว็บ JSON ที่ให้สิทธิ์ชุดที่แตกต่างกันโดยขึ้นอยู่กับบทบาท โดยทั่วไปแล้ว คุณจะสร้างบัญชีบริการหลายบัญชีได้โดยให้มีชุดบทบาทขั้นต่ำที่กำหนด เพื่อลดโอกาสที่จะเกิดการละเมิด

การเดินทางและความคืบหน้าของคำสั่งซื้อใช้บทบาทต่อไปนี้

บทบาทคำอธิบาย
ผู้ใช้ Fleet Engine Consumer SDK

roles/fleetengine.consumerSdkUser
ให้สิทธิ์ค้นหารถยนต์และดึงข้อมูลเกี่ยวกับรถยนต์และการเดินทาง โดยทั่วไปโทเค็นที่สร้างโดยบัญชีบริการที่มีบทบาทนี้มักจะใช้จากอุปกรณ์เคลื่อนที่ที่เป็นแอปสำหรับใช้ร่วมกันหรือการนำส่งสำหรับผู้บริโภค
ผู้ใช้ Fleet Engine Driver SDK

roles/fleetengine.driverSdkUser
ให้สิทธิ์ในการอัปเดตตำแหน่งและเส้นทางของรถ รวมถึงเรียกข้อมูลเกี่ยวกับยานพาหนะและการเดินทาง โทเค็นที่สร้างโดยบัญชีบริการที่มีบทบาทนี้มักจะใช้จากอุปกรณ์เคลื่อนที่ของแอปบริการร่วมเดินทางหรือพนักงานขับรถส่งอาหาร
ผู้ใช้บริการ Fleet Engine ระดับสูง

roles/fleetengine.serviceSuperUser
ให้สิทธิ์ API ของยานพาหนะและการเดินทางทั้งหมด โทเค็นที่สร้างโดยบัญชีบริการที่มีบทบาทนี้มักจะใช้จากเซิร์ฟเวอร์แบ็กเอนด์

ตัวอย่างเช่น สร้างบัญชีบริการสำหรับแต่ละบทบาทจาก 3 บทบาท และมอบหมายบทบาทที่เกี่ยวข้อง

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 ไดรเวอร์และผู้บริโภคสร้างขึ้นโดยยึดตามบทบาทมาตรฐานเหล่านี้

หรือคุณจะสร้างบทบาทที่กำหนดเองเพื่อให้รวมชุดสิทธิ์ต่างๆ เข้าด้วยกันได้ตามต้องการ SDK ไดรเวอร์และผู้บริโภคจะแสดงข้อความแสดงข้อผิดพลาดเมื่อใดก็ตามที่สิทธิ์ที่จำเป็นหายไป ด้วยเหตุนี้ เราจึงขอแนะนำเป็นอย่างยิ่งให้ใช้ชุดบทบาทมาตรฐานที่แสดงข้างต้น และอย่าใช้บทบาทที่กำหนดเอง

หากคุณต้องการสร้างโทเค็น JWT สำหรับไคลเอ็นต์ที่ไม่น่าเชื่อถือ การเพิ่มผู้ใช้ลงในบทบาทผู้สร้างโทเค็นบัญชีบริการจะทําให้ผู้ใช้สร้างโทเค็นด้วยเครื่องมือบรรทัดคำสั่ง gcloud ได้

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

โดย my-user@example.com คืออีเมลที่ใช้ในการตรวจสอบสิทธิ์กับ gcloud (gcloud auth list --format='value(account)')

ไลบรารีการตรวจสอบสิทธิ์ Fleet Engine

Fleet Engine ใช้ JSON Web Token (JWT) เพื่อจำกัดการเข้าถึง API ของ Fleet Engine ไลบรารีการตรวจสอบสิทธิ์ Fleet Engine ใหม่พร้อมใช้งานใน GitHub ช่วยลดความซับซ้อนของการสร้าง Fleet Engine JWT และลงนามอย่างปลอดภัย

ไลบรารีมีประโยชน์ดังต่อไปนี้

  • ลดความซับซ้อนของกระบวนการสร้างโทเค็น Fleet Engine
  • มีกลไกการรับรองโทเค็นที่นอกเหนือจากการใช้ไฟล์ข้อมูลเข้าสู่ระบบ (เช่น การแอบอ้างบัญชีบริการ)
  • แนบโทเค็นที่ลงนามกับคำขอขาออกที่สร้างขึ้นจากต้นขั้ว gRPC หรือไคลเอ็นต์ GAPIC

การสร้าง JSON Web Token (JWT) สำหรับการให้สิทธิ์

เมื่อไม่ได้ใช้ไลบรารีการตรวจสอบสิทธิ์ Fleet Engine คุณจะต้องสร้างโทเค็นเว็บ JSON (JWT) ภายในฐานของโค้ดโดยตรง คุณจึงต้องมีความเข้าใจอย่างลึกซึ้งเกี่ยวกับ JWT และความเกี่ยวข้องกับ Fleet Engine นี่คือเหตุผลที่เราแนะนำอย่างยิ่ง ให้ใช้ประโยชน์จาก Fleet Engine Auth Library

ภายใน Fleet Engine นั้น JSON Web Token (JWT) ให้การตรวจสอบสิทธิ์เป็นระยะเวลาสั้นๆ และรับประกันว่าอุปกรณ์จะแก้ไขได้เฉพาะยานพาหนะ การเดินทาง หรืองานที่ได้รับอนุญาตเท่านั้น JWT มีส่วนหัวและส่วนการอ้างสิทธิ์ ส่วนหัวจะมีข้อมูลเช่นคีย์ส่วนตัวที่จะใช้ (ซึ่งได้มาจากบัญชีบริการ) และอัลกอริทึมการเข้ารหัส ส่วนการอ้างสิทธิ์มีข้อมูลอย่างเช่นเวลาที่สร้างของโทเค็น, Time to Live ของโทเค็น, บริการที่บริษัทอ้างว่ามีการเข้าถึง และข้อมูลการให้สิทธิ์อื่นๆ เพื่อกำหนดขอบเขตการเข้าถึง ตัวอย่างเช่น รหัสยานพาหนะ

ส่วนหัวของ JWT ประกอบด้วยช่องต่อไปนี้

ฟิลด์คำอธิบาย
alg อัลกอริทึมที่จะใช้ "RS256"
typ ประเภทของโทเค็น "JWT"
บุตรหลาน รหัสคีย์ส่วนตัวของบัญชีบริการ โดยคุณจะดูค่านี้ได้ในช่อง "private_key_id" ของไฟล์ JSON ของบัญชีบริการ ตรวจสอบว่าใช้คีย์จากบัญชีบริการที่มีระดับสิทธิ์ที่ถูกต้อง

ส่วนการอ้างสิทธิ์ JWT ประกอบด้วยช่องต่อไปนี้

ฟิลด์คำอธิบาย
IS อีเมลของบัญชีบริการ
สำรอง อีเมลของบัญชีบริการ
Aud SERVICE_NAME ของบัญชีบริการ ในกรณีนี้คือ https://fleetengine.googleapis.com/
IAt การประทับเวลาเมื่อสร้างโทเค็น ระบุเป็นวินาทีที่ผ่านไปตั้งแต่ 00:00:00 น. ตามเขตเวลา UTC วันที่ 1 มกราคม 1970 รอ 10 นาทีสำหรับการบิด หากการประทับเวลาอยู่ในอดีตหรือในอนาคตมากเกินไป เซิร์ฟเวอร์อาจรายงานข้อผิดพลาด
exp การประทับเวลาที่โทเค็นหมดอายุ ระบุเป็นวินาทีที่ผ่านไปตั้งแต่ 00:00:00 น. ตามเขตเวลา UTC วันที่ 1 มกราคม 1970 คำขอจะไม่สำเร็จหากการประทับเวลานานกว่า 1 ชั่วโมงในอนาคต
การให้สิทธิ์ อาจมี "vehicleid" หรือ "tripid" ทั้งนี้ขึ้นอยู่กับกรณีการใช้งาน

การสร้างโทเค็น JWT คือการลงนามโทเค็นนั้น สำหรับคำแนะนำและตัวอย่างโค้ดสำหรับการสร้างและลงชื่อ JWT โปรดดูการให้สิทธิ์บัญชีบริการที่ไม่มี OAuth จากนั้นคุณจะแนบโทเค็นที่ลงนามกับการเรียก gRPC หรือวิธีการอื่นๆ ที่ใช้เข้าถึง Fleet Engine ได้

การอ้างสิทธิ์ JWT

เมื่อสร้างเพย์โหลด JWT ให้เพิ่มการอ้างสิทธิ์เพิ่มเติมในส่วนการให้สิทธิ์ โดยตั้งค่าคีย์ vehicleid หรือ tripid เป็นค่าของรหัสยานพาหนะหรือรหัสการเดินทางที่กำลังทำการโทร

SDK ไดรเวอร์จะใช้การอ้างสิทธิ์ vehicleid เสมอ ไม่ว่าจะขับขี่ขณะเดินทางหรือยานพาหนะ แบ็กเอนด์ Fleet Engine จะยืนยันว่ารถเชื่อมโยงกับการเดินทางที่ขอก่อนทำการดัดแปลง

Consumer SDK จะใช้การอ้างสิทธิ์ tripid เสมอ

ผู้ให้บริการแชร์รถหรือจัดส่งควรใช้ vehicleid หรือ tripid ที่มีเครื่องหมาย "*" เพื่อจับคู่ยานพาหนะและการเดินทางทั้งหมด โปรดทราบว่า JWT จะมีโทเค็นทั้งสองได้ (แม้ว่าจะไม่จำเป็นก็ตาม) ซึ่งอาจทำให้การติดตั้งใช้งานการรับรองโทเค็นทำได้ง่ายขึ้น

กรณีการใช้งานของ JWT

ตัวอย่างต่อไปนี้แสดงโทเค็นตัวอย่างสำหรับเซิร์ฟเวอร์ผู้ให้บริการ

{
  "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": "*"
   }
}

ตัวอย่างต่อไปนี้แสดงโทเค็นตัวอย่างสำหรับแอปผู้บริโภค

{
  "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"
   }
}

ตัวอย่างต่อไปนี้แสดงโทเค็นตัวอย่างสำหรับแอปไดรเวอร์

{
  "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"
   }
}
  • สำหรับช่อง kid ในส่วนหัว ให้ระบุรหัสคีย์ส่วนตัวของบัญชีบริการ ค่านี้จะอยู่ในช่อง private_key_id ของไฟล์ JSON ของบัญชีบริการ
  • สำหรับช่อง iss และ sub ให้ระบุอีเมลของบัญชีบริการ คุณดูค่านี้ได้ในช่อง client_email ของไฟล์ JSON ของบัญชีบริการ
  • สำหรับช่อง aud ให้ระบุ https://SERVICE_NAME/
  • สำหรับช่อง iat ให้ใช้การประทับเวลาเมื่อสร้างโทเค็น โดยระบุเป็นวินาทีที่ผ่านไป 00:00:00 น. ตามเขตเวลา UTC ของวันที่ 1 มกราคม 1970 รอ 10 นาทีสำหรับการบิด หากการประทับเวลาย้อนหลังนานเกินไปหรือในอนาคต เซิร์ฟเวอร์อาจรายงานข้อผิดพลาด
  • สำหรับช่อง exp ให้ใช้การประทับเวลาเมื่อโทเค็นหมดอายุ โดยระบุเป็นวินาทีตั้งแต่ 00:00:00 น. ตามเขตเวลา UTC วันที่ 1 มกราคม 1970 ค่าสูงสุดที่อนุญาตคือ iat + 3600

เมื่อลงนาม JWT เพื่อให้ระบบส่งผ่านไปยังอุปกรณ์เคลื่อนที่ โปรดใช้บัญชีบริการสำหรับบทบาทไดรเวอร์หรือบทบาท SDK ผู้บริโภค ไม่เช่นนั้น อุปกรณ์เคลื่อนที่จะสามารถเปลี่ยนสถานะที่ไม่ควรจะมีได้

ในทำนองเดียวกัน เมื่อลงชื่อ JWT ที่จะใช้สำหรับการโทรที่ได้รับสิทธิ์ คุณต้องใช้บัญชีบริการที่มีบทบาทผู้ใช้ระดับสูง ไม่เช่นนั้นจะดำเนินการไม่สำเร็จ

สร้าง JWT สำหรับการทดสอบ

การสร้างโทเค็นจากเทอร์มินัลจะมีประโยชน์ในการทดสอบ

บัญชีผู้ใช้ของคุณต้องมีบทบาทผู้สร้างโทเค็นบัญชีบริการจึงจะทำตามขั้นตอนเหล่านี้ได้

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

สร้างไฟล์ใหม่ชื่อ unsigned_token.json โดยใช้เนื้อหาด้านล่าง พร็อพเพอร์ตี้ iat คือเวลาปัจจุบันในหน่วยวินาทีหลังจาก Epoch ซึ่งดึงขึ้นมาได้โดยการเรียกใช้ date +%s ในเทอร์มินัล พร็อพเพอร์ตี้ exp คือเวลาหมดอายุเป็นจํานวนวินาทีหลังจาก Epoch ซึ่งคํานวณได้โดยเพิ่ม 3600 ไปยัง iat เวลาหมดอายุต้องไม่เกิน 1 ชั่วโมงในอนาคต

{
  "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": "*"
   }
}

จากนั้นเรียกใช้คำสั่ง gcloud ต่อไปนี้เพื่อลงนามโทเค็นในนามของบัญชีบริการผู้ใช้ระดับสูง

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

ตอนนี้ JWT ที่เข้ารหัส Base64 ที่มีการลงชื่อควรจัดเก็บไว้ในไฟล์ signed_token.jwt โทเค็นนี้ใช้ได้อีก 1 ชั่วโมง

ตอนนี้คุณทดสอบโทเค็นโดยเรียกใช้คำสั่ง curl กับปลายทาง REST ของรายการยานพาหนะได้แล้ว ดังนี้

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

ยานพาหนะและวงจร

ยานพาหนะคือเอนทิตีที่เป็นตัวแทนของคู่คนขับและยานพาหนะ ปัจจุบันไม่สามารถติดตามคนขับและรถยนต์แยกกันได้ ผู้ให้บริการแชร์รถหรือการนำส่งจะสร้างรถโดยใช้รหัสผู้ให้บริการ (ซึ่งต้องเหมือนกันกับรหัสโปรเจ็กต์ของโปรเจ็กต์ Google Cloud ที่มีบัญชีบริการซึ่งใช้ในการเรียก Fleet Engine API) และรหัสรถของผู้ให้บริการเรียกรถหรือการนำส่ง

ระบบจะลบยานพาหนะที่ไม่ได้อัปเดตผ่าน UpdateVehicle หลังผ่านไป 7 วันโดยอัตโนมัติ เกิดข้อผิดพลาดในการเรียกใช้ CreateVehicle ด้วยคู่รหัสผู้ให้บริการ/รหัสยานพาหนะที่มีอยู่แล้ว กรณีของยานพาหนะที่ไม่ได้อัปเดตบ่อยครั้งสามารถจัดการได้ 2 วิธี ได้แก่ การเรียก CreateVehicle เป็นประจำพร้อมแจ้งรหัสผู้ให้บริการ/รหัสยานพาหนะคู่หนึ่งที่คาดไว้ และทิ้งข้อผิดพลาดหากมียานพาหนะนั้นอยู่แล้ว หรือการเรียก CreateVehicle หลังจาก UpdateVehicle กลับมาโดยมีข้อผิดพลาด NOT_FOUND

ข้อมูลอัปเดตเกี่ยวกับตำแหน่งของยานพาหนะ

เพื่อประสิทธิภาพที่ดีที่สุดกับ Fleet Engine ให้ส่งการอัปเดตตำแหน่งยานพาหนะ โดยใช้วิธีใดวิธีหนึ่งต่อไปนี้เพื่อส่งข้อมูลอัปเดต

  1. ใช้ Driver SDK - Android, iOS - ตัวเลือกที่ง่ายที่สุด
  2. ใช้โค้ดที่กำหนดเอง ซึ่งมีประโยชน์ในกรณีที่มีการส่งต่อสถานที่ผ่านแบ็กเอนด์หรือหากคุณใช้อุปกรณ์อื่นที่ไม่ใช่ Android หรือ iOS

ประเภทยานพาหนะ

เอนทิตียานพาหนะมีช่องที่ต้องกรอกของ VehicleType ซึ่งมี enum ของ Category ซึ่งระบุเป็น AUTO, TAXI, TRUCK, TWO_WHEELER, BICYCLE หรือ PEDESTRIAN ก็ได้ ประเภทยานพาหนะนั้นจะใช้เป็นเกณฑ์ตัวกรองใน SearchVehicles และ ListVehicles ได้

การกำหนดเส้นทางทั้งหมดสำหรับยานพาหนะจะใช้ RouteTravelMode ที่เกี่ยวข้อง หากตั้งค่าหมวดหมู่เป็น AUTO, TWO_WHEELER, BICYCLE หรือ PEDESTRIAN หากตั้งค่าหมวดหมู่เป็น TAXI หรือ TRUCK ระบบจะพิจารณาการกำหนดเส้นทางเหมือนกับโหมด AUTO

แอตทริบิวต์ของยานพาหนะ

เอนทิตียานพาหนะมีฟิลด์ VehicleAttribute ที่ซ้ำ Fleet Engine จะไม่ตีความแอตทริบิวต์เหล่านี้ SearchVehicles API มีช่องที่กำหนดให้ Vehicles ที่ตรงกันต้องมีแอตทริบิวต์ที่รวมอยู่ทั้งหมดที่ตั้งค่าเป็นค่าที่ระบุ

โปรดทราบว่าช่องแอตทริบิวต์เป็นช่องเพิ่มเติมจากช่องอื่นๆ ที่รองรับในข้อความ Vehicle เช่น vehicle_type และ supported_trip_types

จุดอ้างอิงที่เหลือของยานพาหนะ

เอนทิตียานพาหนะมีฟิลด์ที่ซ้ำของ TripWaypoint (RPC | REST) ซึ่งเรียกว่า waypoints(RPC | REST) ช่องนี้จะมีจุดอ้างอิงที่เหลืออยู่ในการเดินทางตามลำดับที่รถไปถึงได้ Fleet Engine จะคำนวณช่องนี้เมื่อมีการกำหนดการเดินทางให้กับรถ และอัปเดตเมื่อการเดินทางเปลี่ยนสถานะ จุดอ้างอิงเหล่านี้สามารถระบุด้วยฟิลด์ TripId และ WaypointType ฟิลด์

การขยายการมีสิทธิ์ของยานพาหนะสำหรับการจับคู่

โดยทั่วไป บริการของ Rideshare หรือ Delivery Provider จะรับผิดชอบการจับคู่คำขอการเดินทางกับยานพาหนะ บริการนี้สามารถใช้แอตทริบิวต์ยานพาหนะเพื่อรวมยานพาหนะในการค้นหาจำนวนมากขึ้น เช่น ผู้ให้บริการอาจใช้ชุดแอตทริบิวต์ที่สอดคล้องกับระดับของสิทธิพิเศษหรือความสามารถของยานพาหนะได้ ตัวอย่างเช่น 3 ระดับอาจเป็นชุดแอตทริบิวต์ที่มีค่าบูลีน ได้แก่ is_bronze_level, is_silver_level และ is_gold_level รถ 1 คัน ใช้ได้กับทั้ง 3 รุ่น เมื่อ Fleet Engine ได้รับคำขอเดินทางซึ่งต้องใช้ความสามารถระดับเงิน การค้นหาจะรวมยานพาหนะนั้นด้วย การใช้แอตทริบิวต์ในลักษณะนี้รวมถึงยานพาหนะที่มอบความสามารถที่หลากหลาย

คุณอัปเดตแอตทริบิวต์ยานพาหนะได้ 2 วิธี วิธีแรกคือ UpdateVehicle API เมื่อใช้ API นี้ ระบบจะตั้งค่าแอตทริบิวต์ยานพาหนะทั้งชุดเป็นค่า คุณไม่สามารถอัปเดตแอตทริบิวต์เพียงรายการเดียวได้ อีกวิธีหนึ่งคือใช้ UpdateVehicleAttributes API วิธีนี้ใช้เพียงแอตทริบิวต์ที่อัปเดต ระบบจะตั้งค่าแอตทริบิวต์ที่รวมอยู่ในคำขอเป็นค่าใหม่หรือมีการเพิ่ม แอตทริบิวต์ที่ไม่ได้ระบุจะไม่มีการเปลี่ยนแปลง

วิธีการ: สร้างยานพาหนะ

ต้องมีการสร้างเอนทิตี Vehicle เพื่อที่จะติดตามยานพาหนะแต่ละคันในกลุ่ม

ใช้ปลายทาง CreateVehicle กับ CreateVehicleRequest เพื่อสร้างยานพาหนะ

provider_id ของ Vehicle ต้องเป็นรหัสโปรเจ็กต์ (เช่น my-on-demand-project) ของโปรเจ็กต์ Google Cloud ที่มีบัญชีบริการที่จะใช้ในการเรียก Fleet Engine โปรดทราบว่าแม้บัญชีบริการหลายบัญชีอาจเข้าถึง Fleet Engine สำหรับผู้ให้บริการ Rideshare หรือผู้ให้บริการจัดส่งรายเดียวกันได้ แต่ในขณะนี้ Fleet Engine ยังไม่รองรับบัญชีบริการจากโปรเจ็กต์ Google Cloud หลายโปรเจ็กต์ที่เข้าถึง Vehicles เดียวกัน

คุณสามารถสร้าง Vehicle ได้ในสถานะ OFFLINE หรือ ONLINE หากสร้าง ONLINE ระบบอาจแสดงผล URL นั้นในการตอบกลับคำค้นหา SearchVehicles ทันที

last_location เริ่มต้นอาจรวมอยู่ในการโทร CreateVehicle แม้จะได้รับอนุญาต แต่ไม่ควรสร้าง Vehicle ในสถานะ ONLINE โดยไม่มี last_location

ดูประเภทยานพาหนะเพื่อดูรายละเอียดในช่องประเภทยานพาหนะ

ดูแอตทริบิวต์ยานพาหนะสำหรับรายละเอียด ในช่องแอตทริบิวต์

ค่าที่แสดงผลจาก CreateVehicle เป็นเอนทิตี Vehicle ที่สร้างขึ้น

ตัวอย่าง

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

ดูข้อมูลอ้างอิง 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.

บันทึก Google Cloud Platform สำหรับการสร้างยานพาหนะ

Fleet Engine API เขียนรายการบันทึกผ่านบันทึกของ Google Cloud Platform เมื่อได้รับการเรียกปลายทาง CreateVehicle รายการบันทึกจะมีข้อมูลเกี่ยวกับค่าในคำขอ CreateVehicle หากการโทรสำเร็จ จะมีข้อมูลเกี่ยวกับ Vehicle ที่ส่งคืนด้วย

Shell

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

ควรพิมพ์ระเบียนที่คล้ายกับตัวอย่างต่อไปนี้

---
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'

การแจ้งเตือน Cloud Pub/Sub สำหรับการสร้างยานพาหนะ

Fleet Engine API จะเผยแพร่การแจ้งเตือนผ่าน Cloud Pub/Sub เมื่อสร้างยานพาหนะใหม่ หากต้องการรับการแจ้งเตือนเหล่านี้ โปรดทำตามวิธีการที่นี่

วิธีการ: อัปเดตตำแหน่งของรถ

หากไม่ได้ใช้ Driver SDK เพื่ออัปเดตตำแหน่งของรถ คุณสามารถเรียกใช้ Fleet Engine โดยตรงเพื่อแจ้งตำแหน่งของรถได้ สำหรับรถที่มีการใช้งานอยู่ Fleet Engine จะคาดหวังการอัปเดตตำแหน่งอย่างน้อย 1 ครั้งทุกนาที และไม่เกิน 1 ครั้งทุก 5 วินาที การอัปเดตเหล่านี้ต้องการเฉพาะสิทธิ์ของผู้ใช้ Fleet Engine Driver SDK เท่านั้น

ตัวอย่าง

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

ดูข้อมูลอ้างอิง 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.

วิธีการ: อัปเดตช่องยานพาหนะอื่นๆ

การอัปเดตแอตทริบิวต์อื่นๆ ของสถานะของยานพาหนะเกิดขึ้นน้อยกว่าการอัปเดตตำแหน่ง การอัปเดตแอตทริบิวต์อื่นนอกเหนือจาก last_location จำเป็นต้องได้รับสิทธิ์ผู้ใช้ระดับสูงของ Flet Engine

UpdateVehicleRequest มี update_mask เพื่อระบุว่าต้องอัปเดตช่องใด ลักษณะการทำงานของฟิลด์จะเหมือนกับในเอกสารประกอบของ Protobuf สำหรับฟิลด์มาสก์

ตามที่ระบุไว้ในแอตทริบิวต์ยานพาหนะ การอัปเดตช่อง attributes กำหนดให้ต้องเขียนแอตทริบิวต์ทั้งหมดเพื่อเก็บรักษาไว้ คุณจะอัปเดตเฉพาะค่าของคู่คีย์-ค่าเดียวในการเรียกใช้ UpdateVehicle ไม่ได้ คุณใช้ UpdateVehicleAttributes API ได้เพื่ออัปเดตค่าของแอตทริบิวต์บางรายการ

ตัวอย่าง

ตัวอย่างนี้เปิดใช้ 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

ดูข้อมูลอ้างอิง 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.

บันทึก Google Cloud Platform สำหรับการอัปเดตยานพาหนะ

Fleet Engine API เขียนรายการบันทึกผ่านบันทึกของ Google Cloud Platform เมื่อได้รับการเรียกปลายทาง UpdateVehicle รายการบันทึกจะมีข้อมูลเกี่ยวกับค่าในคำขอ UpdateVehicle หากการโทรสำเร็จ จะมีข้อมูลเกี่ยวกับ Vehicle ที่ส่งคืนด้วย

Shell

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

การแจ้งเตือน Cloud Pub/Sub สำหรับการอัปเดตยานพาหนะ

Fleet Engine API จะเผยแพร่การแจ้งเตือนผ่าน Cloud Pub/Sub เมื่ออัปเดตยานพาหนะที่มีอยู่ หากต้องการรับการแจ้งเตือนเหล่านี้ โปรดทำตามวิธีการที่นี่

HOW-TO: ค้นหารถยนต์

Fleet Engine รองรับการค้นหายานพาหนะ SearchVehicles API จะช่วยให้คุณค้นหาคนขับรถที่อยู่ใกล้เคียงซึ่งเหมาะกับงานนั้นๆ มากที่สุด เช่น การให้บริการรถโดยสารหรือคำขอให้ส่งของ SearchVehicles API จะแสดงรายการผู้ขับขี่ตามอันดับที่ตรงกับแอตทริบิวต์ของงานกับแอตทริบิวต์ของยานพาหนะในกลุ่มอุปกรณ์ของคุณ ดูข้อมูลเพิ่มเติมได้ที่การค้นหาคนขับใกล้เคียง

ตัวอย่าง

เมื่อค้นหายานพาหนะที่พร้อมจำหน่าย Fleet Engine จะยกเว้นยานพาหนะในการเดินทางที่ใช้งานอยู่โดยค่าเริ่มต้น บริการของบริการร่วมเดินทางหรือบริการจัดส่งจะต้องรวมบริการเหล่านี้ไว้ในคำขอการค้นหาอย่างชัดแจ้ง ตัวอย่างต่อไปนี้แสดงวิธีรวมยานพาหนะเหล่านั้นในการค้นหายานพาหนะที่ตรงกับการเดินทางจาก Grand Indonesia East Mall ไปยังศูนย์ประชุม Balai Sidang Jakarta

Shell

ก่อนอื่นให้อัปเดตตำแหน่งของยานพาหนะที่เราสร้างในขั้นตอนก่อนหน้าให้มีสิทธิ์ ในความเป็นจริง จะเป็นไปได้ด้วย Driver SDK ที่ทำงานในอุปกรณ์ Android หรือ iOS ในรถ

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

การค้นหาควรจะปรากฏขึ้นอย่างน้อยยานพาหนะนั้น

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

ดูข้อมูลอ้างอิง 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;
}

การค้นหาเกี่ยวกับการกรองยานพาหนะ

SearchVehicles และ ListVehicles รองรับการกรองในแอตทริบิวต์ยานพาหนะโดยใช้คำค้นหาตัวกรอง ดูตัวอย่างไวยากรณ์การค้นหาตัวกรองได้ที่ AIP-160

โปรดทราบว่าตัวกรองการค้นหารองรับการกรองในแอตทริบิวต์ยานพาหนะเท่านั้น และจะใช้กับช่องอื่นๆ ไม่ได้ การค้นหาตัวกรองทำหน้าที่เป็นวลี AND ที่มีข้อจำกัดอื่นๆ เช่น minimum_capacity หรือ vehicle_types ใน SearchVehiclesRequest

วิธีการ: แสดงยานพาหนะ

SearchVehicles ได้รับการเพิ่มประสิทธิภาพสำหรับการค้นหายานพาหนะจำนวนน้อยที่จัดอันดับได้อย่างรวดเร็ว และจะใช้เพื่อค้นหาผู้ขับขี่ที่อยู่ใกล้เคียงซึ่งเหมาะกับงานที่สุดเป็นหลัก แต่บางครั้งคุณต้องการค้นหารถทุกคันที่ตรงตามเกณฑ์บางอย่าง แม้ว่าจำเป็นต้องเลื่อนดูผลการค้นหาก็ตาม ListVehicles ออกแบบมาสำหรับ Use Case นั้น

ListVehicles API ช่วยให้คุณค้นหารถยนต์ทุกคันที่ตรงกับตัวเลือกคำขอที่เจาะจงบางอย่างได้ ListVehicles API จะแสดงผลรายการยานพาหนะที่มีเลขหน้าในโปรเจ็กต์ซึ่งตรงกับข้อกำหนดบางอย่าง

หากต้องการกรองแอตทริบิวต์ของยานพาหนะ โปรดดูคำค้นหาการกรองยานพาหนะ

ตัวอย่าง

ตัวอย่างนี้ทำการกรองใน vehicle_type และแอตทริบิวต์โดยใช้สตริง 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

ดูข้อมูลอ้างอิง 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;
}

การเดินทางและวงจรชีวิต

Trip API และวงจรจะคล้ายกับวงจรและ API ของยานพาหนะ ผู้ให้บริการ Rideshare มีหน้าที่สร้างการเดินทางโดยใช้อินเทอร์เฟซ Fleet Engine Fleet Engine มีทั้งบริการ RPC, TripService และทรัพยากร REST, provider.trips อินเทอร์เฟซเหล่านี้ช่วยให้สร้างเอนทิตีการเดินทาง คำขอข้อมูล ฟังก์ชันการค้นหา และความสามารถในการอัปเดต

Trip มีช่องสถานะเพื่อติดตามความคืบหน้าผ่านวงจร ค่าจะย้ายจาก NEW ไปยัง COMPLETE บวก CANCELED และ UNKNOWN_TRIP_STATUS โปรดดู trip_status สำหรับ RPC หรือ TripStatus สำหรับ REST

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

บริการของคุณอัปเดตการเดินทางไปยัง CANCELED ได้จากสถานะเหล่านี้ เมื่อบริการสร้างการเดินทาง เครื่องมือจะตั้งสถานะเป็น NEW คุณจะใส่ vehicle_id หรือไม่ก็ได้ เช่นเดียวกับรถยนต์ บริการจะลบการเดินทางโดยอัตโนมัติ หลังจาก 7 วันโดยไม่มีการอัปเดต หากบริการพยายามสร้างการเดินทางด้วยรหัสที่มีอยู่แล้ว ระบบจะแสดงข้อผิดพลาด การเดินทางจะถือว่า "ใช้งานอยู่" หากอยู่ในสถานะอื่นนอกเหนือจาก COMPLETE หรือ CANCELED ความแตกต่างนี้สําคัญในช่อง active_trips ในเอนทิตียานพาหนะและ SearchTripsRequest

บริการนี้จะเปลี่ยน vehicle_id ที่กำหนดให้กับการเดินทางได้ก็ต่อเมื่อสถานะเป็น NEW หรือ CANCELED เท่านั้น หากคนขับยกเลิกการเดินทางขณะกำลังเดินทาง จะต้องตั้งค่าสถานะการเดินทางเป็น NEW หรือ CANCELED ก่อนที่จะเปลี่ยนหรือล้าง vehicle_id

สถานะมีความสำคัญเมื่อใช้การสนับสนุนการเดินทางอย่างต่อเนื่อง การสนับสนุนนี้จะช่วยให้ผู้ให้บริการกำหนดการเดินทางใหม่ให้กับยานพาหนะได้ในขณะที่ยานพาหนะดังกล่าวอยู่ระหว่างการเดินทาง รหัสสำหรับการสร้างการเดินทางแบบกลับไป-กลับนั้นเหมือนกันกับการเดินทางครั้งเดียวและใช้รหัสยานพาหนะเดียวกัน Fleet Engine จะเพิ่มต้นทางและปลายทางของการเดินทางใหม่ไปยังจุดอ้างอิงของยานพาหนะ ดูข้อมูลเพิ่มเติมเกี่ยวกับการเดินทางแบบขากลับได้ที่สร้างการเดินทางแบบหลายจุดทาง

จุดอ้างอิงที่เหลือของการเดินทาง

เอนทิตีการเดินทางมีช่องที่ซ้ำของ TripWaypoint (RPC | REST) ซึ่งมีชื่อว่า remainingWaypoints(RPC | REST) ช่องนี้รวมจุดอ้างอิงทั้งหมดที่ยานพาหนะจะต้องเดินทางตามลำดับก่อนจุดออกจากสุดท้ายของการเดินทางนี้ โดยจะคำนวณจากจุดอ้างอิงที่เหลือของยานพาหนะ ในกรณีการใช้งานแบบย้อนกลับและคาร์พูล รายการนี้ประกอบด้วยจุดอ้างอิงจากการเดินทางอื่นๆ ที่จะข้ามก่อนการเดินทางนี้ แต่ไม่รวมจุดอ้างอิงหลังการเดินทางนี้ จุดอ้างอิงในรายการสามารถระบุได้ด้วย TripId และ WaypointType

ความสัมพันธ์ระหว่างสถานะการเดินทางและจุดอ้างอิงที่เหลือของยานพาหนะ

ระบบจะอัปเดตจุดอ้างอิงที่เหลืออยู่ของยานพาหนะ (RPC | REST) เมื่อ Fleet Engine ได้รับคำขอเปลี่ยนสถานะการเดินทาง ระบบจะนำจุดอ้างอิงก่อนหน้านี้ออกจากรายการจุดอ้างอิงที่เหลืออยู่ของยานพาหนะเมื่อ tripStatus(RPC | REST) เปลี่ยนจากสถานะอื่นเป็น ENROUTE_TO_XXX กล่าวคือ เมื่อสถานะการเดินทางเปลี่ยนจาก ENROUTE_TO_PICKUP เป็น ARRIVED_AT_PICKUP จุดรับของการเดินทางจะยังคงอยู่ในรายการจุดอ้างอิงที่เหลืออยู่ของรถ แต่เมื่อสถานะการเดินทางเปลี่ยนเป็น ENROUTE_TO_INTERMEDIATE_DESTINATION หรือ ENROUTE_TO_DROPOFF จุดรับที่เหลือจะถูกนําออกจากจุดรับของรถ

โดยเป็นกรณีเดียวกันสำหรับ ARRIVED_AT_INTERMEDIATE_DESTINATION และ ENROUTE_TO_INTERMDEDIATE_DESTINATION เมื่อ ARRIVED_AT_INTERMEDIATE_DESTINATION ปลายทางระดับกลางในปัจจุบันจะไม่ถูกลบออกจากรายการจุดอ้างอิงที่เหลืออยู่ของยานพาหนะจนกว่ารถจะรายงานว่าอยู่ระหว่างการเปลี่ยนเส้นทางไปยังจุดอ้างอิงถัดไป

เมื่อสถานะการเดินทางเปลี่ยนเป็น COMPLETED จุดอ้างอิงจากการเดินทางนี้จะไม่ปรากฏในรายการจุดอ้างอิงที่เหลืออยู่ของพาหนะ

วิธีการ: สร้างการเดินทาง

คุณต้องสร้างเอนทิตี Trip เพื่อให้ระบบติดตามคำขอการเดินทางแต่ละรายการและจับคู่กับยานพาหนะในกองยาน ใช้ปลายทาง CreateTrip กับ CreateTripRequest เพื่อสร้างทริป

ต้องระบุแอตทริบิวต์ต่อไปนี้เพื่อสร้างการเดินทาง

  • parent - สตริงที่มีรหัสผู้ให้บริการซึ่งสร้างเมื่อสร้างโปรเจ็กต์ Google Cloud
  • trip_id - สตริงที่สร้างโดยผู้ให้บริการ Rideshare
  • trip - คอนเทนเนอร์ที่มีข้อมูลเมตาพื้นฐานที่อธิบายการเดินทาง
    • trip_type - ค่าแจกแจงว่าการเดินทางอาจมีผู้โดยสารรายอื่นจากต้นทางและจุดหมายอื่นในยานพาหนะเดียวกัน (SHARED) หรือมีผู้โดยสารคนเดียวเท่านั้น (EXCLUSIVE)
    • pickup_point - TerminalLocation แทนจุดเริ่มต้นของการเดินทาง โปรดดูข้อมูลอ้างอิงของ RC หรือข้อมูลอ้างอิง REST

เมื่อสร้างการเดินทาง คุณสามารถระบุnumber_of_passengers dropoff_point และvehicle_id แม้ว่าจะไม่จำเป็นต้องกรอกข้อมูลในช่องเหล่านี้ แต่หากระบุ ช่องเหล่านี้จะยังคงอยู่ ระบบจะไม่สนใจช่องการเดินทางอื่นๆ ทั้งหมด ตัวอย่างเช่น การเดินทางทั้งหมดเริ่มต้นด้วย trip_status จำนวน NEW แม้ว่าคุณจะผ่าน trip_status เป็น CANCELED ในคำขอสร้างก็ตาม

ตัวอย่าง

ตัวอย่างต่อไปนี้สร้างการเดินทางไปยังศูนย์การค้า Grand Indonesia East Mall ซึ่งเป็นการเดินทาง สำหรับผู้โดยสาร 2 คน เป็นเที่ยวบินพิเศษ provider_id ของ Trip ต้องเหมือนกับรหัสโปรเจ็กต์ ในตัวอย่างนี้ ผู้ให้บริการ Rideshare ได้สร้าง โปรเจ็กต์ Google Cloud ชื่อ project-id โปรเจ็กต์นี้ต้องมีบัญชีบริการที่ใช้ในการเรียก Fleet Engine สถานะของการเดินทางคือNEW

ภายหลัง หลังจากที่บริการจับคู่การเดินทางกับยานพาหนะแล้ว บริการจะโทรหา UpdateTrip และเปลี่ยน vehicle_id เมื่อมีการกําหนดการเดินทางไปยังยานพาหนะนั้น

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

ดูข้อมูลอ้างอิง 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;
}

บันทึก Google Cloud Platform สำหรับ Trip Creation

Fleet Engine API จะเขียนรายการบันทึกโดยใช้บันทึกของ Google Cloud Platform เมื่อได้รับการเรียกไปยังปลายทาง CreateTrip รายการบันทึกจะมีข้อมูลเกี่ยวกับค่าในคำขอ CreateTrip หากการโทรสำเร็จ จะมีข้อมูลเกี่ยวกับ Trip ที่ตอบกลับด้วย

วิธีการ: อัปเดตการเดินทาง

เอนทิตีการเดินทางมีช่องที่เปิดใช้การติดตามโดยบริการและรายงานความคืบหน้าของการเดินทางโดย Driver SDK และไปยัง Consumer SDK หากต้องการอัปเดตพร็อพเพอร์ตี้ ให้ใช้ข้อความ UpdateTripRequest การดำเนินการนี้จะอัปเดตช่องการเดินทางตามfield_maskของคำขอ โปรดดู UpdateTripRequest

ผู้ให้บริการ Rideshare มีหน้าที่อัปเดตแอตทริบิวต์ต่อไปนี้

  • สถานะการเดินทาง
  • รหัสยานพาหนะ ไม่ว่าจะเป็นในขณะที่สร้าง หรือหลังจากจับคู่ยานพาหนะกับการเดินทางแล้ว
  • การเปลี่ยนแปลงเกี่ยวกับการรับสินค้า จุดส่ง หรือจุดอ้างอิง

Fleet Engine จะอัปเดตช่องต่อไปนี้โดยอัตโนมัติเมื่อใช้ฟีเจอร์การแชร์เส้นทางผ่าน Driver SDK หรือ Consumer SDK

  • เส้นทาง
  • ETA
  • ระยะทางที่เหลือ
  • ตำแหน่งของยานพาหนะ
  • จุดอ้างอิงที่เหลืออยู่

โปรดดูTripใน RPC หรือ Resource.Trip ใน REST

บันทึก Google Cloud Platform สำหรับการอัปเดตการเดินทาง

Fleet Engine API จะเขียนรายการบันทึกโดยใช้บันทึกของ Google Cloud Platform เมื่อได้รับการเรียกไปยังปลายทาง UpdateTrip รายการบันทึกจะมีข้อมูลเกี่ยวกับค่าในคำขอ UpdateTrip หากการโทรสำเร็จ จะมีข้อมูลเกี่ยวกับ Trip ที่ถูกส่งกลับด้วย

วิธีการ: ค้นหาการเดินทาง

Fleet Engine รองรับการค้นหาการเดินทาง ตามที่ระบุไว้ก่อนหน้านี้ ระบบจะลบทริปโดยอัตโนมัติหลังจากผ่านไป 7 วัน ดังนั้น SearchTrips จะไม่แสดงประวัติการเดินทางทั้งหมด

แม้ว่า SearchTrips จะเป็น API แบบยืดหยุ่น แต่รายการด้านล่างจะพิจารณากรณีการใช้งาน 2 กรณี

  • การกำหนดการเดินทางของยานพาหนะ ผู้ให้บริการสามารถกำหนดการเดินทางที่ใช้งานอยู่ของยานพาหนะได้ ใน SearchTripsRequest vehicle_id ได้รับการตั้งค่าเป็นยานพาหนะที่อยู่ระหว่างการพิจารณา และควรตั้งค่า active_trips_only เป็น true

  • การปรับยอดผู้ให้บริการและสถานะของ Fleet Engine -- ผู้ให้บริการสามารถใช้ SearchTrips เพื่อให้มั่นใจว่าสถานะการเดินทางและสถานะของ Fleet Engine ตรงกัน การดำเนินการนี้สำคัญอย่างยิ่งสำหรับ "สถานะการเดินทาง" หากสถานะของการเดินทางที่กำหนดให้กับยานพาหนะไม่ได้ตั้งค่าเป็น COMPLETE หรือ CANCELED อย่างถูกต้อง SearchVehicles จะไม่รวมยานพาหนะดังกล่าว

หากต้องการใช้SearchTripsในลักษณะนี้ ให้ปล่อย vehicle_id ว่างไว้ ตั้งค่า active_trips_only เป็น true และตั้งค่า minimum_staleness เป็นเวลาที่สูงกว่าระยะเวลาการเดินทางส่วนใหญ่ ตัวอย่างเช่น คุณอาจใช้เวลา 1 ชั่วโมง ผลลัพธ์รวมถึงการเดินทางที่ไม่สมบูรณ์หรือถูกยกเลิก และไม่มีการอัปเดตเกินกว่า 1 ชั่วโมง ผู้ให้บริการควรตรวจสอบการเดินทางเหล่านี้เพื่อให้มั่นใจว่าสถานะใน Fleet Engine ได้รับการอัปเดตอย่างถูกต้อง

การแก้ปัญหา

ในกรณีที่เกิดข้อผิดพลาด DEADLINE_EXCEEDED ระบบจะไม่ทราบสถานะของ Fleet Engine ผู้ให้บริการควรเรียกใช้ CreateTrip อีกครั้ง ซึ่งจะแสดงผล 201 (CREATED) หรือ 409 (CONFLICT) ในกรณีหลัง คำขอก่อนหน้าจะสำเร็จก่อน DEADLINE_EXCEEDED ดูคำแนะนำ Consumer API สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการจัดการข้อผิดพลาดเกี่ยวกับการเดินทาง Android หรือ iOS

การสนับสนุนการโดยสารรถร่วมกัน

คุณกําหนดการเดินทาง SHARED หลายครั้งให้กับยานพาหนะที่รองรับ TripType.SHARED ได้ คุณต้องระบุลำดับจุดอ้างอิงที่ไม่ผ่านทั้งหมดสำหรับทุกการเดินทางที่กำหนดให้กับรถคันหนึ่งในการเดินทางที่แชร์นี้ผ่าน Trip.vehicle_waypoints เมื่อคุณกำหนด vehicle_id สำหรับการเดินทางที่แชร์ (ในคำขอ CreateTrip หรือ UpdateTrip) โปรดดู vehicle_waypoints สำหรับ RPC หรือ vehicleWaypoints สำหรับ REST

การรองรับปลายทางหลายแห่ง

ระบุปลายทางระดับกลาง

ช่อง intermediateDestinations และช่อง intermediateDestinationIndex ในการเดินทาง (RPC | REST) จะถูกรวมเข้าด้วยกันเพื่อใช้ระบุจุดหมาย

อัปเดตปลายทางระดับกลาง

คุณสามารถอัปเดตปลายทางระดับกลางผ่าน UpdateTrip เมื่ออัปเดตปลายทางระดับกลาง คุณต้องระบุรายการปลายทางระดับกลางทั้งหมด รวมถึงปลายทางที่เคยเยี่ยมชม ไม่ใช่แค่สถานที่ที่เพิ่มใหม่หรือที่ต้องแก้ไข เมื่อ intermediateDestinationIndex ชี้ไปยังดัชนีหลังจากตำแหน่งของปลายทางระดับกลางที่เพิ่มเข้ามา/แก้ไขใหม่ ระบบจะไม่เพิ่มปลายทางระดับกลางใหม่/ที่อัปเดตลงใน waypoints หรือ remainingWaypoints ของยานพาหนะ เนื่องจากจุดหมายระดับกลางก่อน intermediateDestinationIndex จะถือว่าเคยเข้าชมแล้ว

การเปลี่ยนแปลงสถานะการเดินทาง

ต้องระบุช่อง intermediateDestinationsVersion ใน (RPC | REST) ในคำขออัปเดตสถานะการเดินทางซึ่งส่งไปยัง Fleet Engine เพื่อบ่งชี้ว่าปลายทางระดับกลางได้ผ่านไปแล้ว จะมีการระบุปลายทางตัวกลางที่กำหนดเป้าหมายผ่านช่อง intermediateDestinationIndex เมื่อ tripStatus (RPC | REST) คือ ENROUTE_TO_INTERMEDIATE_Destination ตัวเลขระหว่าง [0..N-1] จะระบุปลายทางระดับกลางที่ยานพาหนะจะข้ามเป็นลำดับถัดไป เมื่อ tripStatus คือ ARRIVED_AT_INTERMEDIATE_DESTINATION ตัวเลขระหว่าง [0..N-1] จะแสดงถึงปลายทางระดับกลางที่ยานพาหนะอยู่

ตัวอย่าง

ตัวอย่างโค้ดต่อไปนี้แสดงวิธีอัปเดตสถานะการเดินทางเพื่อกำหนดเส้นทางไปยังปลายทางกลางแห่งแรก สมมติว่าคุณได้สร้างการเดินทางหลายจุดหมายไว้และการเดินทางนั้นผ่านจุดรับสินค้าแล้ว

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

วิธีการ: สมัครรับข้อความการแจ้งเตือนจาก Fleet Engine API

Feet Engine API ใช้ Google Cloud Pub/Sub เพื่อเผยแพร่การแจ้งเตือนในหัวข้อที่โปรเจ็กต์ Google Cloud สำหรับผู้บริโภคสร้างขึ้น โดยค่าเริ่มต้น จะไม่มีการเปิดใช้ Pub/Sub สำหรับ Fleet Engine บนโปรเจ็กต์ Google Cloud ของคุณ โปรดส่งเคสขอรับความช่วยเหลือหรือติดต่อวิศวกรลูกค้าเพื่อเปิดใช้ Pub/Sub

หากต้องการสร้างหัวข้อในโปรเจ็กต์ที่อยู่ในระบบคลาวด์ ให้ทำตามวิธีการเหล่านี้ รหัสหัวข้อต้องเป็น "fleet_engine_notifications"

โดยต้องสร้างหัวข้อในโปรเจ็กต์ Cloud เดียวกันกับที่เรียกใช้ Fleet Engine API

เมื่อสร้างหัวข้อแล้ว คุณจะต้องให้สิทธิ์ Fleet Engine API ในการเผยแพร่หัวข้อนั้น โดยคลิกหัวข้อที่คุณเพิ่งสร้าง แล้วเพิ่มสิทธิ์ใหม่ คุณอาจต้องคลิกแสดงแผงข้อมูลเพื่อเปิดเครื่องมือแก้ไขสิทธิ์ ผู้ใช้หลักควรเป็น geo-fleet-engine@system.gserviceaccount.com และบทบาทควรเป็น Pub/Sub publisher

หากต้องการตั้งค่าโปรเจ็กต์ที่อยู่ในระบบคลาวด์ให้สมัครรับการแจ้งเตือน ให้ทำตามวิธีการเหล่านี้

Fleet Engine API จะเผยแพร่การแจ้งเตือนแต่ละรายการในรูปแบบข้อมูล 2 รูปแบบ ได้แก่ protobuf และ json รูปแบบข้อมูลสำหรับการแจ้งเตือนแต่ละรายการจะแสดงไว้ในแอตทริบิวต์ PubsubMessage โดยมีคีย์เป็น data_format และค่าเป็น protobuf หรือ json

สคีมาการแจ้งเตือน:

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