주문형 차량 공유 및 배송 솔루션은 현재 일부 파트너만 이용할 수 있습니다.

Fleet Engine 시작하기

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

기본 요건

개발 시 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일 이전에 생성된 프로젝트에는 기본적으로 로깅이 사용 설정되지 않을 수 있습니다. 자세한 내용은 로깅 문서를 참조하세요.

클라이언트 라이브러리

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

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

인증 및 승인

Google Cloud Console을 통해 이동 및 주문 진행에서 제공하는 기능을 구성할 수 있습니다. 이러한 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 드라이버 SDK 사용자

roles/fleetengine.driverSdkUser
차량 위치 및 경로를 업데이트하고 차량 및 이동 정보를 검색할 수 있는 권한을 부여합니다. 이 역할이 있는 서비스 계정에서 만든 토큰은 일반적으로 차량 공유 또는 배달 드라이버 앱 휴대기기에서 사용됩니다.
Fleet Engine 서비스 수퍼유저

roles/fleetengine.serviceSuperUser
모든 차량 및 이동 API에 대한 권한을 부여합니다. 이 역할이 있는 서비스 계정에서 만든 토큰은 일반적으로 백엔드 서버에서 사용됩니다.

예를 들어 세 역할 각각에 대해 서비스 계정을 만들고 각각의 역할을 할당합니다.

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 Engine 토큰 생성 프로세스를 간소화합니다.
  • 사용자 인증 정보 파일 사용 이외의 토큰 서명 메커니즘 (예: 서비스 계정 가장)을 제공합니다.
  • gRPC 스텁 또는 GAPIC 클라이언트에서 생성된 아웃바운드 요청에 서명된 토큰을 연결합니다.

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

Fleet Engine 인증 라이브러리를 사용하지 않는 경우에는 코드베이스 내에서 JSON 웹 토큰 (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 서비스 계정의 이메일 주소입니다.
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의 값으로 설정하여 승인 섹션에 추가 클레임을 추가합니다.

운전자 SDK는 경로나 차량에서 운행하든 항상 vehicleid 클레임을 사용합니다. Fleet Engine 백엔드는 수정을 수행하기 전에 요청된 이동과 차량을 연결합니다.

소비자 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 + 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 속성은 에포크 후 초 단위의 시간으로, 터미널에서 date +%s를 실행하여 검색할 수 있습니다.

{
  "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,
  "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 파일 내에 저장됩니다. 토큰은 다음 1시간 동안 유효합니다.

이제 차량 나열 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 오류가 반환됩니다.

차량 속성

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

속성 필드는 Vehicle 메시지에서 지원되는 다른 여러 필드(예: vehicle_typesupported_trip_types)와 함께 추가됩니다.

남은 차량 경유지

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

차량 구매 자격 확대

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

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

방법: 차량 만들기

Fleet에서 추적할 차량별로 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 호출에 포함될 수 있습니다. 허용되지만 last_location 없이 ONLINE 상태에서 Vehicle를 만들면 안 됩니다.

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

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 참조를 확인하세요.

자바

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를 통해 알림을 게시합니다. 이러한 알림을 받으려면 여기의 안내를 따르세요.

방법: 차량 업데이트

UpdateVehicleVehicle의 상태를 업데이트하는 데 사용됩니다. 업데이트는 두 가지 카테고리로 나뉩니다.

차량 위치 업데이트 중

드라이버 SDK는 차량의 last_location를 자주 업데이트합니다. 이 업데이트는 Fleet Engine 드라이버 SDK 사용자 권한만 필요합니다. Fleet Engine은 차량 위치 업데이트를 최적화합니다.

다른 차량 상태 업데이트

차량 상태의 다른 속성 업데이트는 위치 업데이트보다 빈도가 더 낮습니다. 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 참조를 확인하세요.

자바

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 Engine은 기본적으로 활성 이동 중인 차량을 제외합니다. 차량 공유 또는 배송 제공업체의 서비스는 검색 요청에 이를 명시적으로 포함해야 합니다. 다음 예는 그랜드 인도네시아 이스트 몰에서 발라이 시당 자카르타 컨벤션 센터까지 이동과 일치하는 차량을 검색할 때 이러한 차량을 포함하는 방법을 보여줍니다.

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"}],
  "requiredAttributes": [{"key": "on_trip", "value": "false"}],
  "orderBy": "PICKUP_POINT_ETA",
  "includeBackToBack": true
}
EOM

providers.vehicles.search 참조를 확인하세요.

자바

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))
    .addRequiredAttributes(
        VehicleAttribute.newBuilder().setKey("on_trip").setValue("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는 해당 사용 사례에 맞게 설계되었습니다.

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

이 예시에서는 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"}],
}
EOM

providers.vehicles.list 참조를 확인하세요.

자바

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))
    .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, CANCELED, UNKNOWN_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에서 중요합니다.

서비스는 상태가 NEW 또는 CANCELED인 경우에만 경로에 할당된 vehicle_id를 변경할 수 있습니다. 이동 중에 운전자가 경로를 취소하면 vehicle_id가 변경되거나 삭제되기 전에 이동 상태를 NEW 또는 CANCELED로 설정해야 합니다.

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

남은 경로 경유지

Trip 항목에 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로 변경되면 이 이동에서 경유지가 차량의 남은 경유지 목록에 포함되지 않습니다.

방법: 여행 만들기

각 이동 요청을 추적하여 Fleet의 차량과 일치시키려면 Trip 항목을 만들어야 합니다. CreateTrip 엔드포인트를 CreateTripRequest와 함께 사용하여 경로를 만듭니다.

여행을 만들려면 다음 속성이 필요합니다.

  • parent - Google Cloud 프로젝트를 만들 때 생성된 제공업체 ID가 포함된 문자열입니다.
  • trip_id - 차량 공유 제공업체가 생성한 문자열입니다.
  • trip - 여정을 설명하는 기본 메타데이터가 있는 컨테이너
    • trip_type: 경로에 동일한 차량 (SHARED) 또는 단일 당사자 (EXCLUSIVE)의 다른 기수와 목적지의 다른 탑승자가 있는지 여부를 나타냅니다.
    • pickup_point - 이동의 출발지를 나타내는 TerminalLocation입니다. RPC 참조 또는 REST 참조를 확인하세요.

여행을 만들 때 number_of_passengers, dropoff_point, vehicle_id를 제공할 수 있습니다. 이러한 필드는 필수는 아니지만 제공하면 계속 유지됩니다. 다른 이동 필드를 제공하면 Fleet Engine은 이 필드를 사용하지 않습니다.

다음 예에서는 그랜드 인도네시아 이스트 몰을 여행합니다. 이 여행은 승객 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 참조를 확인하세요.

자바

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에 관한 정보도 포함됩니다.

방법: 경로 업데이트

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

차량 공유 제공업체는 다음 속성을 업데이트할 책임이 있습니다.

  • 이동 상태.
  • 차량 ID 생성 시 또는 차량과 이동 경로를 일치시킨 후
  • 승차, 하차 또는 경유지가 변경됩니다.

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

  • 경로
  • ETA
  • 남은 거리
  • 차량 위치
  • 남은 경유지

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 Engine 상태 조정 -- 제공업체는 SearchTrips를 사용하여 해당 이동 상태와 Fleet Engine의 이동 상태가 일치하도록 할 수 있습니다. 이는 TripStatus에서 특히 중요합니다. 차량에 할당된 이동 상태가 COMPLETE 또는 CANCELED로 제대로 설정되지 않으면 차량은 SearchVehicles에 포함되지 않습니다.

이러한 방식으로 SearchTrips를 사용하려면 vehicle_id를 비워두고 active_trips_onlytrue로 설정하고 minimum_staleness을 대부분의 이동 시간보다 긴 시간으로 설정합니다. 예를 들어 1시간을 사용할 수 있습니다. 결과에는 완료되지 않았거나 취소되지 않았으며 1시간 넘게 업데이트되지 않은 이동이 포함됩니다. 제공업체는 Fleet Engine의 상태가 적절하게 업데이트되도록 이러한 이동을 검토해야 합니다.

문제 해결

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

카풀 탑승 서비스

TripType.SHARED를 지원하는 차량에 SHARED 이동을 여러 개 할당할 수 있습니다. 공유 경로에 vehicle_id 또는 CreateTrip를 할당할 때 이 공유 차량에서 Trip.vehicle_waypoints에 차량에 할당된 모든 이동에 대해 전달되지 않은 모든 경유지의 순서를 지정해야 합니다.UpdateTrip 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] 사이의 숫자는 차량이 있는 중간 목적지를 나타냅니다.

다음 코드 예시에서는 다중 대상 이동을 만들고 이동이 승차 지점을 통과했다고 가정할 때 첫 번째 중간 대상으로 라우팅하도록 이동 상태를 업데이트하는 방법을 보여줍니다.

자바

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로 표시됩니다.

알림 스키마:

프로토부프

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