Fleet Engine 시작하기

Fleet Engine 주문형 Rides and Deliveries API를 사용하면 이동 및 주문 진행 상황 애플리케이션의 이동과 차량 상태를 관리할 수 있습니다. gRPC 또는 REST 호출을 통해 Fleet Engine과 통신할 수 있는 드라이버 SDK, 소비자 SDK, 백엔드 서비스 간의 트랜잭션을 처리합니다.

기본 요건

개발 작업을 하려면 Cloud SDK를 설치 (gcloud)하고 프로젝트에 대한 인증을 받아야 합니다.

shell

gcloud auth login

다음과 같은 성공 메시지가 표시됩니다.

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

주문형 차량 공유 및 배송 솔루션 Fleet Engine API가 적절하게 구성되었는지 확인하세요.

shell

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

이 명령어에서 오류가 발생하면 프로젝트 관리자 및 Google 지원 담당자에게 문의하여 액세스 권한을 받으세요.

로깅

Fleet Engine은 수신한 API 호출에 대한 로그 메시지를 Google Cloud Platform 로그에 작성할 수 있습니다. 로그를 읽고 분석하는 방법에 대한 개요는 Cloud Logging 문서를 참조하세요.

2022년 2월 10일 이전에 생성된 프로젝트에는 Logging이 기본적으로 사용 설정되지 않을 수 있습니다. 자세한 내용은 로깅 문서를 참조하세요.

클라이언트 라이브러리

Google에서는 몇 가지 공통 프로그래밍 언어로 클라이언트 라이브러리를 게시합니다. 이러한 라이브러리는 원시 REST 또는 gRPC보다 더 나은 개발자 환경을 제공하는 데 도움이 됩니다. 서버 애플리케이션에 대한 클라이언트 라이브러리를 가져오는 방법은 클라이언트 라이브러리를 참조하세요.

이 문서의 Java 예시는 gRPC에 익숙하다고 가정합니다.

인증 및 승인

Google Cloud 콘솔을 통해 이동 및 주문 진행률에서 제공하는 기능을 구성할 수 있습니다. 이러한 API와 SDK를 사용하려면 Cloud Console에서 생성된 서비스 계정을 사용하여 서명된 JSON 웹 토큰을 사용해야 합니다.

Cloud 프로젝트 설정

클라우드 프로젝트를 설정하려면 먼저 프로젝트를 만든 후 서비스 계정을 만드세요.

Google Cloud 프로젝트를 만들려면 다음 안내를 따르세요.

  1. Google Cloud 콘솔을 사용하여 Google Cloud 프로젝트를 만듭니다.
  2. API 및 서비스 대시보드를 사용하여 Local Rides and Deliveries API를 사용 설정합니다.

서비스 계정은 하나 이상의 역할과 연결됩니다. 역할에 따라 서로 다른 권한 집합을 부여하는 JSON 웹 토큰을 만드는 데 사용됩니다. 일반적으로 악용 가능성을 줄이기 위해 각각 필요한 최소한의 역할 집합을 포함하는 여러 서비스 계정을 만들 수 있습니다.

이동 및 주문 진행률에서 사용하는 역할은 다음과 같습니다.

역할설명
Fleet Engine Consumer SDK 사용자

roles/fleetengine.consumerSdkUser
차량을 검색하고 차량 및 이동에 대한 정보를 가져올 수 있는 권한을 부여합니다. 이 역할을 가진 서비스 계정으로 만든 토큰은 일반적으로 차량 공유 또는 배달 소비자 앱 휴대기기에서 사용됩니다.
Fleet Engine Driver SDK 사용자

roles/fleetengine.driverSdkUser
차량 위치 및 경로를 업데이트하고 차량 및 이동에 대한 정보를 가져올 수 있는 권한을 부여합니다. 이 역할을 가진 서비스 계정으로 만든 토큰은 일반적으로 차량 공유 또는 배달 기사 앱 휴대기기에서 사용됩니다.
Fleet Engine 주문형 관리자

roles/fleetengine.ondemandAdmin
모든 차량 및 여행 리소스에 대한 읽기 및 쓰기 권한을 부여합니다. 이 역할이 있는 주 구성원은 JWT를 사용할 필요가 없으며 대신 애플리케이션 기본 사용자 인증 정보를 사용해야 합니다. 커스텀 JWT 클레임은 무시됩니다. 이 역할은 신뢰할 수 있는 환경 (고객 백엔드)으로 제한되어야 합니다.
FleetEngine 서비스 수퍼유저 **(지원 중단됨)**

roles/fleetengine.serviceSuperUser
모든 차량 및 여행 API에 대한 권한을 부여합니다. 이 역할을 가진 서비스 계정으로 발급된 토큰은 일반적으로 백엔드 서버에서 사용됩니다. 이 역할은 지원 중단되었습니다. 대신 roles/fleetengine.ondemandAdmin를 사용합니다.

예를 들어 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 웹 토큰 (JWT)을 사용하여 Fleet Engine API에 대한 액세스를 제한합니다. GitHub에서 제공되는 새로운 Fleet Engine 인증 라이브러리를 사용하면 Fleet Engine JWT의 구성을 간소화하고 안전하게 서명할 수 있습니다.

라이브러리는 다음과 같은 이점을 제공합니다.

  • Fleet 엔진 토큰 생성 프로세스가 간소화됩니다.
  • 사용자 인증 정보 파일 사용 이외의 토큰 서명 메커니즘 (예: 서비스 계정 가장)을 제공합니다.
  • gRPC 스텁 또는 GAIC 클라이언트에서 작성된 아웃바운드 요청에 서명된 토큰을 연결합니다.

승인을 위한 JSON 웹 토큰 (JWT) 만들기

Fleet Engine 인증 라이브러리를 사용하지 않는 경우 코드베이스에서 직접 JSON 웹 토큰 (JWT)을 만들어야 합니다. 이를 위해서는 JWT와 JWT가 Fleet Engine과 어떤 관련이 있는지에 대해 깊이 이해하고 있어야 합니다. 이러한 이유로 Fleet Engine 인증 라이브러리를 활용하는 것이 좋습니다.

Fleet Engine 내에서 JSON 웹 토큰 (JWT)은 단기 인증을 제공하며 기기가 승인된 차량, 이동, 작업만 수정할 수 있도록 합니다. JWT에는 헤더와 클레임 섹션이 포함됩니다. 헤더 섹션에는 사용할 비공개 키 (서비스 계정에서 가져옴) 및 암호화 알고리즘과 같은 정보가 포함됩니다. 클레임 섹션에는 토큰의 생성 시간, 토큰 TTL(수명), 액세스 권한을 요청하는 서비스, 액세스 범위를 줄이기 위한 기타 승인 정보(예: 차량 ID)가 포함됩니다.

JWT 헤더 섹션에는 다음 필드가 포함됩니다.

필드설명
alg 사용할 알고리즘입니다. `RS256`.
typ 토큰 유형입니다. `JWT`.
어린이 서비스 계정의 비공개 키 ID 이 값은 서비스 계정 JSON 파일의 `private_key_id` 필드에서 찾을 수 있습니다. 올바른 수준의 권한으로 서비스 계정의 키를 사용해야 합니다.

JWT 클레임 섹션에는 다음 필드가 포함되어 있습니다.

필드설명
iss 서비스 계정의 이메일 주소입니다.
Pub/Sub이 있습니다 서비스 계정의 이메일 주소입니다.
aud 서비스 계정의 SERVICE_NAME(이 경우 https://fleetengine.googleapis.com/)
iat 토큰이 생성된 타임스탬프로, 1970년 1월 1일 00:00:00 UTC 이후 경과된 초 단위로 지정됩니다. 편향이 발생할 수 있도록 10분간 기다립니다. 타임스탬프가 너무 먼 과거 또는 미래인 경우 서버에서 오류를 보고할 수 있습니다.
exp 토큰 만료 시점의 타임스탬프로, 1970년 1월 1일 00:00:00 UTC 이후 경과된 초로 지정됩니다. 타임스탬프가 1시간을 넘으면 요청이 실패합니다.
승인 사용 사례에 따라 `vehicleid` 또는 `tripid`를 포함할 수 있습니다.

JWT 토큰 만들기는 토큰 서명을 의미합니다. JWT를 만들고 서명하는 안내와 코드 샘플은 OAuth 없이 서비스 계정 승인을 참조하세요. 그런 다음 서명된 토큰을 gRPC 호출 또는 Fleet Engine에 액세스하는 데 사용되는 다른 메서드에 연결할 수 있습니다.

JWT 클레임

JWT 페이로드를 만들 때 vehicleid 또는 tripid 키를 호출이 이루어지는 차량 ID 또는 이동 ID 값으로 설정하여 승인 섹션에 추가 클레임을 추가합니다.

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

다음은 Driver app의 토큰 예시입니다.

{
  "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 필드에 서비스 계정의 비공개 키 ID를 지정합니다. 이 값은 서비스 계정 JSON 파일의 private_key_id 필드에서 찾을 수 있습니다.
  • isssub 필드에 서비스 계정의 이메일 주소를 지정합니다. 이 값은 서비스 계정 JSON 파일의 client_email 필드에서 찾을 수 있습니다.
  • aud 필드에 https://SERVICE_NAME/을 지정합니다.
  • iat 필드에는 1970년 1월 1일 00:00:00 UTC 이후 경과된 초로 지정된 토큰 생성 시점의 타임스탬프를 사용합니다. 편향이 발생할 수 있도록 10분간 기다립니다. 타임스탬프가 너무 먼 과거 또는 미래인 경우 서버에서 오류를 보고할 수 있습니다.
  • exp 필드의 경우 토큰이 만료될 때의 타임스탬프를 사용합니다. 이 타임스탬프는 1970년 1월 1일 00:00:00 UTC 이후의 초로 지정됩니다. 허용되는 최대값은 iat + 3,600입니다.

휴대기기로 전달할 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 속성은 에포크 후의 현재 시간(초)으로, 터미널에서 date +%s를 실행하여 가져올 수 있습니다. exp 속성은 에포크 후 만료 시간(초)이며 iat에 3600을 더하여 계산할 수 있습니다. 만료 시간은 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

이제 서명된 Base64로 인코딩된 JWT가 signed_token.jwt 파일 내에 저장됩니다. 토큰은 다음 시간 동안 유효합니다.

이제 차량 나열 REST 엔드포인트에 curl 명령어를 실행하여 토큰을 테스트할 수 있습니다.

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

차량 및 차량 수명 주기

Vehicle는 운전자와 차량 쌍을 나타내는 항목입니다. 현재 운전자와 차량은 별도로 추적할 수 없습니다. 차량 공유 또는 배달 제공업체는 제공업체 ID (Fleet Engine API를 호출하는 데 사용되는 서비스 계정이 포함된 Google Cloud 프로젝트의 프로젝트 ID와 동일해야 함) 및 차량 공유 또는 배달 업체가 소유한 차량 ID를 사용하여 차량을 만듭니다.

7일 후 UpdateVehicle를 통해 업데이트되지 않은 차량은 자동으로 삭제됩니다. 이미 존재하는 제공업체 ID/차량 ID 쌍으로 CreateVehicle를 호출하면 오류입니다. 자주 업데이트되지 않는 차량의 경우는 두 가지 방법으로 처리할 수 있습니다. 예상된 제공업체 ID/차량 ID 쌍으로 CreateVehicle를 자주 호출하고 차량이 이미 존재한다면 오류를 삭제하는 것입니다. 또는 UpdateVehicle가 반환된 후 CreateVehicle를 호출하면 NOT_FOUND 오류가 반환됩니다.

차량 위치 업데이트

Fleet Engine으로 최고의 성능을 얻으려면 차량 위치 업데이트 스트림을 제공하세요. 다음 방법 중 하나를 사용하여 이러한 업데이트를 제공하세요.

  1. Driver SDK(Android, iOS)를 사용합니다. 가장 간단한 옵션입니다.
  2. 커스텀 코드를 사용합니다. 백엔드를 통해 위치가 릴레이되거나 Android 또는 iOS 이외의 기기를 사용하는 경우에 유용합니다.

차량 유형

차량 항목에는 AUTO, TAXI, TRUCK, TWO_WHEELER, BICYCLE 또는 PEDESTRIAN로 지정할 수 있는 Category enum이 포함된 VehicleType의 필수 필드가 포함되어 있습니다. 차량 유형은 SearchVehiclesListVehicles에서 필터 기준으로 사용할 수 있습니다.

차량의 모든 라우팅은 카테고리가 AUTO, TWO_WHEELER, BICYCLE 또는 PEDESTRIAN로 설정된 경우 상응하는 RouteTravelMode를 사용합니다. 카테고리가 TAXI 또는 TRUCK로 설정된 경우 라우팅은 AUTO 모드와 동일하게 처리됩니다.

차량 속성

차량 항목에 반복되는 VehicleAttribute 필드가 포함되어 있습니다. 이러한 속성은 Fleet Engine에서 해석되지 않습니다. SearchVehicles API에는 일치하는 Vehicles에 지정된 값으로 설정된 모든 포함된 속성을 포함해야 하는 필드가 포함되어 있습니다.

속성 필드는 Vehicle 메시지에서 지원되는 다른 여러 필드(예: vehicle_type, supported_trip_types) 외에 추가됩니다.

차량 남은 경유지

차량 항목에 waypoints (RPC | REST)라는 반복되는 TripWaypoint 필드(RPC | REST)가 포함되어 있습니다. 이 필드에는 차량이 도착하는 순서대로 여정의 나머지 경유지가 포함됩니다. Fleet Engine은 이동이 차량에 할당될 때 이 필드를 계산하고 이동의 상태가 변경되면 이 필드를 업데이트합니다. 이러한 경유지는 TripId 필드와 WaypointType 필드로 식별할 수 있습니다.

차량의 경기 자격 요건 확대

일반적으로 차량 공유 또는 배달 제공업체의 서비스는 이동 요청을 차량과 일치시키는 일을 담당합니다. 서비스는 차량 속성을 사용하여 더 많은 검색에 차량을 포함할 수 있습니다. 예를 들어 제공업체는 차량이 제공하는 혜택 또는 기능의 수준에 상응하는 속성으로 설정된 속성을 구현할 수 있습니다. 예를 들어 3개 수준은 불리언 값 is_bronze_level, is_silver_level, is_gold_level를 갖는 속성 집합일 수 있습니다. 차량 한 대에서 세 가지를 모두 사용할 수 있습니다. Fleet Engine이 실버 수준의 기능이 필요한 이동에 대한 요청을 수신하면 해당 차량이 검색에 포함됩니다. 이러한 방식으로 속성을 사용하면 다양한 기능을 제공하는 차량이 포함됩니다.

차량 속성을 업데이트하는 방법에는 두 가지가 있습니다. 그 중 하나가 UpdateVehicle API입니다. 이 API를 사용하면 전체 차량 속성 집합이 값으로 설정됩니다. 하나의 속성만 업데이트할 수는 없습니다. 다른 메서드는 UpdateVehicleAttributes API입니다. 이 메서드는 업데이트할 속성만 사용합니다. 요청에 포함된 속성은 새 값으로 설정되거나 추가됩니다. 지정되지 않은 속성은 변경되지 않습니다.

방법: 차량 만들기

차량에서 추적할 차량마다 Vehicle 항목을 만들어야 합니다.

CreateVehicle 엔드포인트를 CreateVehicleRequest와 함께 사용하여 차량을 만듭니다.

Vehicleprovider_id는 Fleet Engine을 호출하는 데 사용될 서비스 계정이 포함된 Google Cloud 프로젝트의 프로젝트 ID(예: my-on-demand-project)여야 합니다. 여러 서비스 계정이 동일한 차량 공유 또는 배달 제공업체의 Fleet Engine에 액세스할 수 있지만 현재 Fleet Engine은 동일한 Vehicles에 액세스하는 여러 Google Cloud 프로젝트의 서비스 계정을 지원하지 않습니다.

VehicleOFFLINE 또는 ONLINE 상태로 만들 수 있습니다. ONLINE를 만든 경우 SearchVehicles 쿼리에 대한 응답으로 즉시 반환될 수 있습니다.

초기 last_locationCreateVehicle 호출에 포함될 수 있습니다. 허용되지만 Vehiclelast_location 없이 ONLINE 상태에서 생성되어서는 안 됩니다.

차량 유형 필드에 관한 자세한 내용은 차량 유형을 참고하세요.

속성 필드에 관한 자세한 내용은 Vehicle Attributes를 참고하세요.

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는 CreateVehicle 엔드포인트에 대한 호출이 수신되면 Google Cloud Platform 로그를 통해 로그 항목을 작성합니다. 로그 항목에는 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분에 한 번, 최대 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 이외의 속성을 업데이트하려면 Fleet 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는 UpdateVehicle 엔드포인트에 대한 호출이 수신되면 Google Cloud Platform 로그를 통해 로그 항목을 작성합니다. 로그 항목에는 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를 통해 알림을 게시합니다. 알림을 받으려면 여기의 안내를 따르세요.

방법: 차량 검색

Fleet Engine은 차량 검색을 지원합니다. SearchVehicles API를 사용하면 차량 서비스 제공이나 배달 요청과 같은 작업에 가장 적합한 주변 운전자를 찾을 수 있습니다. SearchVehicles API는 작업 속성과 Fleet의 차량 속성이 일치하는 드라이버의 순위 목록을 반환합니다. 자세한 내용은 근처 운전자 찾기를 참고하세요.

사용 가능한 차량을 검색할 때 Fleet 엔진은 기본적으로 활성 이동 중인 차량을 제외합니다. 차량 공유 또는 배달 제공업체의 서비스는 검색 요청에 이를 명시적으로 포함해야 합니다. 다음 예는 그랜드 인도네시아 이스트 몰에서 발라이 시당 자카르타 컨벤션 센터까지의 경로와 일치하는 차량 검색에 이러한 차량을 포함하는 방법을 보여줍니다.

shell

먼저 이전 단계에서 만든 차량의 위치를 업데이트하여 차량을 이용할 수 있도록 합니다. 실제로는 차량의 Android 또는 iOS 기기에서 실행되는 드라이버 SDK가 이 작업을 수행합니다.

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

차량 필터링 쿼리

SearchVehiclesListVehicles는 필터 쿼리를 사용하여 차량 속성에 관한 필터링을 지원합니다. 필터 쿼리 구문의 예는 AIP-160을 참고하세요.

필터 쿼리는 차량 속성에 대한 필터링만 지원하며 다른 필드에는 사용할 수 없습니다. 필터 쿼리는 SearchVehiclesRequestminimum_capacity 또는 vehicle_types와 같은 다른 제약 조건이 있는 AND 절로 작동합니다.

방법: 차량 등록

SearchVehicles는 순위가 지정된 소수의 차량을 매우 빠르게 찾는 데 최적화되어 있으며 주로 작업에 가장 적합한 근처 운전자를 찾는 데 사용됩니다. 그러나 결과를 페이징해야 하는 경우에도 특정 기준을 충족하는 모든 차량을 찾으려는 경우가 있습니다. ListVehicles는 이러한 사용 사례에 맞게 설계되었습니다.

ListVehicles API를 사용하면 특정 요청 옵션을 충족하는 모든 차량을 찾을 수 있습니다. ListVehicles API는 프로젝트에서 일부 요구사항과 일치하는 페이지로 나눈 차량 목록을 반환합니다.

차량 속성을 필터링하려면 차량 필터링 쿼리를 참고하세요.

이 예시에서는 filter 문자열을 사용하여 vehicle_type 및 속성을 필터링합니다.

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와 수명 주기는 Vehicle API 및 수명 주기와 비슷합니다. 차량 공유 제공업체는 Fleet Engine 인터페이스를 사용하여 이동을 만드는 일을 담당합니다. Fleet Engine은 RPC 서비스( TripService)와 REST 리소스(provider.trips)를 모두 제공합니다. 이러한 인터페이스를 통해 이동 항목 생성, 정보 요청, 검색 기능, 업데이트 기능을 사용할 수 있습니다.

Trip에는 수명 주기 동안 진행 상황을 추적하는 상태 필드가 있습니다. 값은 NEW에서 COMPLETE, CANCELEDUNKNOWN_TRIP_STATUS를 더한 값으로 이동합니다. RPC는 trip_status, REST의 경우 TripStatus를 참조하세요.

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

서비스에서 다음 상태 중 하나에서 CANCELED(으)로의 이동을 업데이트할 수 있습니다. 서비스가 이동을 만들면 엔진은 상태를 NEW로 설정합니다. vehicle_id은 선택사항입니다. 차량과 마찬가지로 서비스에서는 업데이트 없이 7일이 지나면 경로를 자동으로 삭제합니다. 서비스에서 이미 ID가 있는 이동을 만들려고 하면 오류가 반환됩니다. 상태가 COMPLETE 또는 CANCELED가 아닌 경우 '활성'으로 간주됩니다. 이러한 구분은 차량 항목의 active_trips 필드와 SearchTripsRequest에서 중요합니다.

이동이 활성화되어 있을 때만 서비스에서 이동에 할당된 vehicle_id을 변경할 수 있습니다. 예를 들어 운전자가 이동 중에 이동을 취소하고 해당 이동이 다른 차량에 재할당되는 경우 이를 처리할 수 있습니다.

상태는 연속 이동 지원을 구현할 때 중요합니다. 이 지원을 통해 제공자는 차량이 활성 이동 중인 동안 차량에 새 경로를 할당할 수 있습니다. 연달아 재생되는 경로를 만드는 코드는 단일 경로와 동일하며 동일한 차량 ID를 사용합니다. Fleet Engine이 새 경로의 출발지와 목적지를 차량의 경유지에 추가합니다. 연속으로 진행되는 경로에 대한 자세한 내용은 다중 경유지 경로 만들기를 참고하세요.

경로 남은 경유지

이동 항목에 remainingWaypoints (RPC | REST)라는 반복되는 TripWaypoint(RPC | REST) 필드가 포함되어 있습니다. 이 필드에는 차량이 이 경로의 최종 하차 지점에 도달하기 전에 순서대로 이동해야 하는 모든 경유지가 포함됩니다. 차량의 남은 경유지에서 계산합니다. 연달아 이용 및 카풀 사용 사례에서 이 목록에는 이번 이동 전에 횡단할 다른 경로의 경유지가 포함되지만 이 이동 이후의 경유지는 제외됩니다. 목록의 경유지는 TripIdWaypointType로 식별할 수 있습니다.

이동 상태와 차량 잔여 경유지 간의 관계

Fleet Engine이 이동 상태 변경 요청을 수신하면 차량의 남은 경유지 (RPC | REST)가 업데이트됩니다. 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 프로젝트를 만들 때 만든 제공업체 ID가 포함된 문자열입니다.
  • trip_id: 차량 공유 제공업체에서 만든 문자열입니다.
  • trip - 경로를 설명하는 기본 메타데이터가 있는 컨테이너입니다.
    • trip_type - 동일한 차량에 탑승한 다른 출발지와 목적지의 다른 탑승자가 이동에 있는지 (SHARED) 아니면 1인 탑승자만 (EXCLUSIVE) 있는지 여부를 나타내는 열거형입니다.
    • pickup_point - 여정의 출발지를 나타내는 TerminalLocation입니다. RPC 참조 또는 REST 참조를 확인하세요.

이동을 만들 때 number_of_passengers, dropoff_point, vehicle_id를 제공할 수 있습니다. 이러한 필드는 필수는 아니지만 제공하면 유지됩니다. 다른 모든 이동 필드는 무시됩니다. 예를 들어 모든 이동은 생성 요청에서 CANCELEDtrip_status를 전달하더라도 NEWtrip_status로 시작합니다.

다음 예에서는 그랜드 인도네시아 이스트 몰에 대한 여행을 만듭니다. 승객 2인 탑승객 전용 여행입니다. Tripprovider_id는 프로젝트 ID와 동일해야 합니다. 이 예에서는 차량 공유 제공업체가 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 로그

Fleet Engine API는 CreateTrip 엔드포인트에 대한 호출이 수신되면 Google Cloud Platform 로그를 사용하여 로그 항목을 작성합니다. 로그 항목에는 CreateTrip 요청의 값에 대한 정보가 포함됩니다. 호출이 성공하면 반환된 Trip에 관한 정보도 포함됩니다.

방법: 이동 업데이트

이동 항목에는 서비스에서 추적하고 Driver SDK 및 소비자 SDK를 통해 이동 진행 상황을 보고할 수 있는 필드가 포함됩니다. 속성을 업데이트하려면 UpdateTripRequest 메시지를 사용합니다. 이렇게 하면 요청의 field_mask에 따라 이동 필드가 업데이트됩니다. UpdateTripRequest를 참고하세요.

차량 공유 제공업체는 다음 속성을 업데이트해야 합니다.

  • 경로 상태를 탭합니다.
  • 차량 ID 생성 당시 또는 차량을 여정에 일치시킨 후
  • 승차, 하차 또는 경유지 변경

Fleet Engine은 Driver SDK 또는 Consumer SDK를 통해 여정 공유 기능을 사용할 때 다음 필드를 자동으로 업데이트합니다.

  • 경로
  • 도착예정시간
  • 남은 거리
  • 차량 위치
  • 남은 경유지

RPC의 Trip 또는 REST의 Resource.Trip를 참조하세요.

경로 업데이트를 위한 Google Cloud Platform 로그

Fleet Engine API는 UpdateTrip 엔드포인트에 대한 호출이 수신되면 Google Cloud Platform 로그를 사용하여 로그 항목을 작성합니다. 로그 항목에는 UpdateTrip 요청의 값에 대한 정보가 포함됩니다. 호출이 성공하면 반환된 Trip에 관한 정보도 포함됩니다.

방법: 여행 검색

Fleet Engine은 경로 검색을 지원합니다. 앞서 언급했듯이 이동은 7일 후에 자동으로 삭제되므로 SearchTrips는 모든 이동의 전체 기록을 노출하지 않습니다.

SearchTrips는 유연한 API이지만 아래 목록은 두 가지 사용 사례를 고려합니다.

  • 차량의 활성 경로 확인 -- 제공업체는 차량의 현재 활성 이동을 확인할 수 있습니다. SearchTripsRequest 내에서 vehicle_id는 고려 중인 차량으로 설정되고 active_trips_onlytrue로 설정되어야 합니다.

  • 제공업체와 Fleet 엔진 상태 조정 -- 제공업체는 SearchTrips를 사용하여 이동 상태와 Fleet Engine의 이동 상태가 일치하도록 보장할 수 있습니다. 이는 TripStatus에 특히 중요합니다. 차량에 할당된 이동의 상태가 COMPLETE 또는 CANCELED로 적절하게 설정되지 않은 경우 차량은 SearchVehicles에 포함되지 않습니다.

이런 방식으로 SearchTrips를 사용하려면 vehicle_id를 비워두고 active_trips_onlytrue로 설정하고 minimum_staleness을 대부분의 이동 시간보다 긴 시간으로 설정하세요. 예를 들어 1시간을 사용할 수 있습니다. 결과에는 COMPLETE 또는 CANCELED 상태가 아니며 1시간 넘게 업데이트되지 않은 이동이 포함됩니다. 제공업체는 이러한 이동을 검사하여 Fleet Engine에서 상태가 올바르게 업데이트되었는지 확인해야 합니다.

문제 해결

DEADLINE_EXCEEDED 오류가 발생하면 Fleet Engine의 상태를 알 수 없습니다. 제공자는 CreateTrip를 다시 호출해야 합니다. 그러면 201 (CREATED) 또는 409 (CONFLICT)가 반환됩니다. 후자의 경우 이전 요청이 DEADLINE_EXCEEDED 전에 성공했습니다. 이동 오류 처리에 관한 자세한 내용은 Consumer API 가이드(Android 또는 iOS)를 참고하세요.

카풀 탑승 지원

TripType.SHARED를 지원하는 차량에 여러 SHARED 이동을 할당할 수 있습니다. CreateTrip 또는 UpdateTrip 요청에서 공유 이동에 vehicle_id를 할당할 때 Trip.vehicle_waypoints를 통해 이 공유 탑승의 차량에 할당된 모든 이동에 대해 통과하지 않은 모든 경유지의 순서를 지정해야 합니다. RPC는 vehicle_waypoints, REST는 vehicleWaypoints를 참조하세요.

여러 대상 위치 지원

중간 대상 식별

이동의 intermediateDestinations 필드와 intermediateDestinationIndex 필드 (RPC | REST)가 결합되어 목적지를 나타냅니다.

중간 대상 업데이트

UpdateTrip를 통해 중간 대상을 업데이트할 수 있습니다. 중간 대상을 업데이트할 때는 새로 추가되거나 수정될 대상뿐만 아니라 방문한 대상을 포함하여 중간 대상의 전체 목록을 제공해야 합니다. intermediateDestinationIndex가 새로 추가/수정된 중간 대상의 위치 뒤에 있는 색인을 가리키면 새로 추가/업데이트된 중간 대상은 차량의 waypoints 또는 이동의 remainingWaypoints에 추가되지 않습니다. intermediateDestinationIndex 이전의 모든 중간 대상은 이미 방문한 것으로 취급되기 때문입니다.

이동 상태 변경사항

중간 목적지가 통과되었음을 나타내기 위해 Fleet Engine으로 전송되는 이동 상태 업데이트 요청에 (RPC | REST)의 intermediateDestinationsVersion 필드가 필요합니다. 타겟팅된 중간 대상은 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에서 알림 메시지 구독

Fleet Engine API는 Google Cloud Pub/Sub를 사용하여 소비자 Google Cloud 프로젝트에서 만든 주제에 대한 알림을 게시합니다. Pub/Sub는 Google Cloud 프로젝트의 Fleet Engine에 기본적으로 사용 설정되어 있지 않습니다. 지원 케이스를 제출하거나 고객 엔지니어에게 문의하여 Pub/Sub를 사용 설정하세요.

Cloud 프로젝트에서 주제를 만들려면 이 안내를 따르세요. 주제 ID는 'fleet_engine_notifications'여야 합니다.

Fleet Engine API를 호출하는 동일한 Cloud 프로젝트에서 주제를 만들어야 합니다.

주제가 생성되면 Fleet Engine API에 주제에 게시할 수 있는 권한을 부여해야 합니다. 이렇게 하려면 방금 만든 주제를 클릭하고 새 권한을 추가합니다. 권한 편집기를 열려면 정보 표시 패널을 클릭해야 할 수 있습니다. 주 구성원은 geo-fleet-engine@system.gserviceaccount.com이어야 하고 역할은 Pub/Sub publisher여야 합니다.

Cloud 프로젝트에서 알림을 구독하도록 설정하려면 다음 안내를 따르세요.

Fleet Engine API는 각 알림을 두 가지 데이터 형식(protobufjson)으로 게시합니다. 각 알림의 데이터 형식은 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"
    }
  }
}