Primeiros passos com o Fleet Engine

A API de viagens e entregas sob demanda do Fleet Engine permite gerenciar viagens e o estado do veículo para seus aplicativos de progresso de viagem e pedido. Ele processa transações entre o SDK do Driver, o SDK do consumidor e o serviço de back-end, que pode se comunicar com o Fleet Engine fazendo chamadas gRPC ou REST.

Pré-requisitos

Para desenvolvimento, verifique se você instala o SDK do Cloud (gcloud) e está autenticado no seu projeto.

shell

gcloud auth login

Uma mensagem de sucesso como esta será exibida:

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

Verifique se as APIs do Fleet Engine de viagens sob demanda e entregas estão configuradas corretamente.

shell

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

Se esse comando resultar em um erro, verifique com o administrador do projeto e o representante do Suporte do Google para ter acesso.

Geração de registros

O Fleet Engine pode gravar mensagens de registro sobre as chamadas de API que recebe nos registros do Google Cloud Platform. Consulte a documentação do Cloud Logging para ter uma visão geral de como ler e analisar registros.

O Logging pode não estar ativado por padrão para projetos criados antes de 10 de fevereiro de 2022. Consulte a documentação da geração de registros para mais detalhes.

Bibliotecas de cliente

Publicamos bibliotecas de clientes em diversas linguagens de programação comuns. Essas bibliotecas ajudarão a fornecer uma melhor experiência de desenvolvedor em relação a REST ou gRPC brutos. Para instruções sobre como conseguir bibliotecas de cliente para seu aplicativo de servidor, consulte Bibliotecas de cliente.

Os exemplos em Java nesta documentação pressupõem familiaridade com o gRPC.

Autenticação e autorização

É possível configurar os recursos fornecidos pelo andamento da viagem e do pedido no console do Google Cloud. Essas APIs e SDKs exigem o uso de JSON Web Tokens que foi assinado usando contas de serviço criadas no Console do Cloud.

Configuração do projeto do Google Cloud

Para configurar o projeto na nuvem, primeiro crie o projeto e, em seguida, crie contas de serviço.

Para criar seu projeto do Google Cloud:

  1. Crie um projeto do Google Cloud usando o console do Google Cloud.
  2. Usando o painel de APIs e serviços, ative a API Local Rides and Deliveries.

As contas de serviço estão associadas a um ou mais papéis. Eles são usados para criar JSON Web Tokens que concedem diferentes conjuntos de permissões, dependendo dos papéis. Normalmente, para reduzir a possibilidade de abuso, é possível criar várias contas de serviço, cada uma com o conjunto mínimo de papéis necessários.

O andamento da viagem e do pedido usa os seguintes papéis:

PapelDescrição
Usuário do SDK do consumidor do Fleet Engine

roles/fleetengine.consumerSdkUser
Concede permissão para pesquisar veículos e recuperar informações sobre veículos e viagens. Os tokens criados por uma conta de serviço com esse papel geralmente são usados nos dispositivos móveis do app para consumidor de serviço de transporte por aplicativo ou de entrega.
Usuário do SDK do driver Fleet Engine

roles/fleetengine.driverSdkUser
Concede permissão para atualizar locais e trajetos de veículos e recuperar informações sobre veículos e viagens. Os tokens criados por uma conta de serviço com esse papel geralmente são usados nos dispositivos móveis do app de transporte por aplicativo ou aplicativo de entrega.
Superusuário de serviço do Fleet Engine

roles/fleetengine.serviceSuperUser
Concede permissão a todas as APIs de veículos e viagens. Os tokens criados por uma conta de serviço com esse papel são usados normalmente nos servidores de back-end.

Por exemplo, crie uma conta de serviço para cada um dos três papéis e atribua os respectivos papéis.

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

Os SDKs do driver e do consumidor são criados com base nesses papéis padrão.

Como alternativa, é possível criar papéis personalizados que permitam o agrupamento de um conjunto arbitrário de permissões. Os SDKs de driver e consumidor vão mostrar mensagens de erro sempre que uma permissão necessária estiver ausente. Por isso, é altamente recomendável usar o conjunto padrão de papéis apresentado acima e não usar os papéis personalizados.

Por conveniência, se você precisar criar tokens JWT para clientes não confiáveis, adicionar usuários ao papel de Criador de token de conta de serviço permite que eles criem tokens com ferramentas de linha de comando gcloud.

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

Em que my-user@example.com é o e-mail usado para autenticação com gcloud (gcloud auth list --format='value(account)').

Biblioteca de autenticação do Fleet Engine

O Fleet Engine usa JSON Web Tokens (JWTs) para restringir o acesso às APIs do Fleet Engine. A nova biblioteca de autenticação do Fleet Engine, disponível no GitHub, simplifica a criação de JWTs do Fleet Engine e os assina com segurança.

A biblioteca oferece os seguintes benefícios:

  • Simplifica o processo de criação de tokens do Fleet Engine.
  • Oferece mecanismos de assinatura de token além do uso de arquivos de credenciais (como a representação de uma conta de serviço).
  • Anexa tokens assinados às solicitações de saída feitas de um stub gRPC ou de um cliente GAPIC.

Como criar um JSON Web Token (JWT) para autorização

Quando você não usa a biblioteca de autenticação do Fleet Engine, os JSON Web Tokens (JWTs) precisam ser criados diretamente na base de código. Isso exige um entendimento profundo sobre os JWTs e a relação deles com o Fleet Engine. É por isso que recomendamos que você use a biblioteca de autenticação do Fleet Engine.

No Fleet Engine, os JSON Web Tokens (JWTs) fornecem autenticação de curta duração e garantem que os dispositivos só possam modificar veículos, viagens ou tarefas para as quais forem autorizados. Os JWTs contêm um cabeçalho e uma seção de declaração. A seção de cabeçalho contém informações como a chave privada a ser usada (recebida das contas de serviço) e o algoritmo de criptografia. A seção de declaração contém informações como o horário de criação do token, a vida útil dos tokens, os serviços a que ele está reivindicando acesso e outras informações de autorização para reduzir o escopo de acesso, por exemplo, o ID do veículo.

A seção de cabeçalho JWT contém os seguintes campos:

CampoDescrição
alg O algoritmo a ser usado. "RS256".
typ O tipo de token. "JWT".
criança O ID da chave privada da sua conta de serviço. Esse valor está no campo "private_key_id" do arquivo JSON da conta de serviço. Use uma chave de uma conta de serviço com o nível de permissões correto.

A seção de declarações do JWT contém os seguintes campos:

CampoDescrição
iss O endereço de e-mail da sua conta de serviço.
sub O endereço de e-mail da sua conta de serviço.
aud O SERVICE_NAME da sua conta de serviço, neste caso https://fleetengine.googleapis.com/
iat O carimbo de data/hora em que o token foi criado, especificado em segundos desde 1o de janeiro de 1970, às 00:00:00 UTC. Aguarde 10 minutos para o desvio. Se o carimbo de data/hora estiver muito distante no passado ou no futuro, o servidor pode relatar um erro.
exp O carimbo de data/hora da expiração do token, especificado em segundos desde 1o de janeiro de 1970, às 00:00:00 UTC. A solicitação falhará se o carimbo de data/hora for mais de uma hora no futuro.
autorização Dependendo do caso de uso, pode conter "vehicleid" ou "tripid".

A criação de um token JWT é referente a assiná-lo. Para instruções e exemplos de código para criar e assinar o JWT, consulte Autorização da conta de serviço sem OAuth. Em seguida, é possível anexar um token assinado a chamadas gRPC ou outros métodos usados para acessar o Fleet Engine.

Declarações JWT

Ao criar o payload do JWT, inclua uma declaração adicional na seção de autorização com a chave vehicleid ou tripid definida como o valor do ID do veículo ou da viagem para o qual a chamada está sendo feita.

O SDK do Driver sempre usa a declaração vehicleid, seja ao operar em uma viagem ou um veículo. O back-end do Fleet Engine garante que o veículo esteja associado à viagem solicitada antes de fazer a modificação.

O SDK do consumidor sempre usa a declaração tripid.

O provedor de serviço de transporte por aplicativo ou transporte precisa usar o vehicleid ou o tripid com um "*" para corresponder a todos os Veículos e Viagens. O JWT pode conter os dois tokens, mesmo que não sejam obrigatórios, o que pode simplificar a implementação da assinatura do token.

Casos de uso do JWT

Veja a seguir um token de exemplo para o servidor do provedor:

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

Veja a seguir um token de exemplo para o app do consumidor:

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

Veja a seguir um exemplo de token para o app do motorista:

{
  "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"
   }
}
  • No campo kid no cabeçalho, especifique o ID da chave privada da conta de serviço. Esse valor está no campo private_key_id do arquivo JSON da sua conta de serviço.
  • Nos campos iss e sub, especifique o endereço de e-mail da conta de serviço. Esse valor está no campo client_email do arquivo JSON da conta de serviço.
  • No campo aud, especifique https://SERVICE_NAME/.
  • No campo iat, use o carimbo de data/hora da criação do token, especificado como segundos decorridos desde 1o de janeiro de 1970, às 00:00:00 UTC. Aguarde 10 minutos para o desvio. Se o carimbo de data/hora estiver muito distante no passado ou no futuro, o servidor pode relatar um erro.
  • No campo exp, use o carimbo de data/hora da expiração do token, especificado em segundos desde 1o de janeiro de 1970, às 00:00:00 UTC. O valor máximo permitido é iat + 3.600.

Ao assinar o JWT que será transmitido para um dispositivo móvel, use a conta de serviço para o papel de SDK do motorista ou do consumidor. Caso contrário, o dispositivo móvel poderá alterar o estado que não deveria ter.

Da mesma forma, ao assinar o JWT que será usado para chamadas privilegiadas, use a conta de serviço com o papel de superusuário. Caso contrário, a operação falhará.

Como gerar um JWT para teste

Gerar tokens do terminal pode ser útil durante os testes.

Para seguir essas etapas, sua conta de usuário precisa ter o papel Criador de token da conta de serviço:

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

Crie um novo arquivo chamado unsigned_token.json com o conteúdo abaixo. A propriedade iat é o horário atual em segundos após a época, que pode ser recuperado executando date +%s no terminal. A propriedade exp é o tempo de expiração em número de segundos após a época, que pode ser calculado adicionando 3.600 a iat. O prazo de validade não pode ser mais de uma hora no futuro.

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

Em seguida, execute o seguinte comando gcloud para assinar o token em nome da sua conta de serviço de superusuário:

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

Um JWT assinado codificado em Base64 agora deve ser armazenado no arquivo signed_token.jwt. O token é válido para a próxima hora.

Agora é possível testar o token executando um comando curl no endpoint REST "Listar veículos":

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

Veículos e o ciclo de vida deles

O veículo é a entidade que representa um par de veículo e motorista. Atualmente, não é possível rastrear um motorista e um veículo separadamente. O provedor de serviço de transporte por aplicativo cria um Veículo usando um ID de provedor (que precisa ser igual ao ID do projeto do Google Cloud que contém a conta de serviço usada para chamar as APIs do Fleet Engine) e um ID do veículo do provedor de entrega.

Um Veículo que não tiver sido atualizado pelo UpdateVehicle após sete dias será excluído automaticamente. É um erro chamar CreateVehicle com um par de ID do provedor/ID do veículo que já existe. O caso de veículos que não são atualizados com frequência pode ser tratado de duas maneiras: chamando CreateVehicle com um par esperado de ID do provedor/ID do veículo e descartando o erro se ele já existir; ou chamando CreateVehicle depois que um UpdateVehicle retorna com um erro NOT_FOUND.

Atualizações de localização de veículos

Para ter o melhor desempenho com o Fleet Engine, forneça um fluxo de atualizações de localização do veículo. Use uma das seguintes maneiras para fazer isso:

  1. A opção mais simples é usar o SDK do Driver, Android ou iOS.
  2. Use código personalizado. Isso é útil se os locais forem realçados pelo seu back-end ou se você usa dispositivos que não são Android ou iOS.

Tipos de veículo

A entidade do veículo tem um campo obrigatório de VehicleType, com um tipo enumerado Category que pode ser especificado como AUTO, TAXI, TRUCK, TWO_WHEELER, BICYCLE ou PEDESTRIAN. O tipo de veículo pode servir como um critério de filtro em SearchVehicles e ListVehicles.

Todos os trajetos para veículos usarão o RouteTravelMode correspondente se a categoria estiver definida como AUTO, TWO_WHEELER, BICYCLE ou PEDESTRIAN. Se a categoria for definida como TAXI ou TRUCK, o roteamento será tratado da mesma forma que o modo AUTO.

Atributos do veículo

A entidade "Veículo" contém um campo repetido de VehicleAttribute. Esses atributos não são interpretados pelo Fleet Engine. A API SearchVehicles inclui um campo para exigir que o Vehicles correspondente contenha todos os atributos incluídos definidos como o valor especificado.

Observe que o campo de atributo é adicionado a vários outros campos compatíveis na mensagem Vehicle, como vehicle_type e supported_trip_types.

Pontos de referência restantes do veículo

A entidade do veículo contém um campo repetido de TripWaypoint (RPC | REST), chamado waypoints(RPC | REST). Esse campo inclui os waypoints restantes nas viagens, na ordem em que o veículo os alcança. O Fleet Engine calcula esse campo à medida que as viagens são atribuídas ao veículo e o atualiza à medida que o status delas muda. Esses waypoints podem ser identificados pelos campos TripId e WaypointType.

Ampliar a qualificação de um veículo para correspondências

Normalmente, os serviços do serviço de transporte por aplicativo compartilhado ou do provedor de entrega são responsáveis por fazer a correspondência entre as solicitações de viagem e os veículos. O serviço pode usar os atributos do veículo para incluir um veículo em um número maior de pesquisas. Por exemplo, o provedor pode implementar um conjunto de atributos correspondentes aos níveis de benefícios ou recursos fornecidos por um veículo. Por exemplo, três níveis podem ser um conjunto de atributos com valores booleanos: is_bronze_level, is_silver_level e is_gold_level. Um veículo pode estar qualificado para os três. Quando o Fleet Engine recebe uma solicitação para uma viagem que exija recursos no nível Prata, a pesquisa inclui esse veículo. O uso de atributos dessa maneira inclui veículos que oferecem uma variedade de recursos.

Há duas maneiras de atualizar os atributos do veículo. Uma é a API UpdateVehicle. Ao usar essa API, todo o conjunto de atributos do veículo é definido como o valor. Não é possível atualizar apenas um único atributo. O outro método é a API UpdateVehicleAttributes. Esse método usa apenas os atributos a serem atualizados. Os atributos incluídos na solicitação serão definidos com o novo valor ou adicionados. Atributos não especificados não serão alterados.

Instruções: criar um veículo

Uma entidade Vehicle precisa ser criada para cada Veículo a ser rastreado na frota.

Use o endpoint CreateVehicle com o CreateVehicleRequest para criar um Veículo.

O provider_id do Vehicle precisa ser o ID do projeto (por exemplo, my-on-demand-project) do projeto do Google Cloud que contém as contas de serviço que serão usadas para chamar o Fleet Engine. Embora várias contas de serviço possam acessar o Fleet Engine para o mesmo provedor de transporte por aplicativo ou de entrega, no momento o Fleet Engine não oferece suporte a contas de serviço de vários projetos do Google Cloud que acessam o mesmo Vehicles.

A Vehicle pode ser criada no estado OFFLINE ou ONLINE. Se criado ONLINE, ele poderá ser imediatamente retornado em resposta a consultas SearchVehicles.

Um last_location inicial pode ser incluído na chamada CreateVehicle. Embora permitido, um Vehicle não pode ser criado no estado ONLINE sem um last_location.

Consulte a página Tipos de Veículo para conferir detalhes sobre o campo de tipo de veículo.

Consulte Atributos do veículo para ver detalhes sobre o campo de atributos.

O valor retornado de CreateVehicle é a entidade Vehicle criada.

Exemplo

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

Consulte a referência de 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.

Registros do Google Cloud Platform para criação de veículos

A API Fleet Engine grava uma entrada de registro usando os registros do Google Cloud Platform quando uma chamada para o endpoint CreateVehicle é recebida. A entrada de registro inclui informações sobre os valores na solicitação CreateVehicle. Se a chamada for bem-sucedida, ela também vai incluir informações sobre o Vehicle que foi retornado.

shell

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

Deve gerar um registro semelhante ao seguinte:

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

Notificações do Cloud Pub/Sub para criação de veículos

A API Fleet Engine publica uma notificação pelo Cloud Pub/Sub quando um novo veículo é criado. Para receber essas notificações, siga as instruções aqui.

Instruções: atualizar o local de um veículo

Se você não estiver usando o SDK do Driver para atualizar a localização do veículo, poderá fazer uma chamada direta para o Fleet Engine com a localização do veículo. Para qualquer veículo ativo, o Fleet Engine espera uma atualização de localização pelo menos uma vez por minuto e no máximo uma vez a cada 5 segundos. Essas atualizações exigem apenas privilégios de usuário do SDK do driver do Fleet Engine.

Exemplo

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

Consulte a referência de 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.

Instruções: atualizar outros campos "Veículo"

As atualizações de outros atributos do estado do veículo ocorrem com menos frequência do que as atualizações de posição. As atualizações de atributos diferentes de last_location exigem privilégios de superusuário do Fleet Engine.

O UpdateVehicleRequest inclui um update_mask para indicar quais campos precisam ser atualizados. O comportamento do campo é igual ao da documentação do Protobuf para máscaras de campo.

Conforme observado em Atributos do veículo, a atualização do campo attributes exige que todos os atributos sejam preservados. Não é possível apenas atualizar o valor de um par de chave-valor em uma chamada UpdateVehicle. Para atualizar os valores de atributos específicos, a API UpdateVehicleAttributes pode ser usada.

Exemplo

Este exemplo ativa 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

Consulte a referência de 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.

Registros do Google Cloud Platform para atualizações de veículos

A API Fleet Engine grava uma entrada de registro usando os registros do Google Cloud Platform quando uma chamada para o endpoint UpdateVehicle é recebida. A entrada de registro inclui informações sobre os valores na solicitação UpdateVehicle. Se a chamada for bem-sucedida, ela também vai incluir informações sobre o Vehicle que foi retornado.

shell

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

Notificações do Cloud Pub/Sub para atualizações de veículos

A API Fleet Engine publica uma notificação pelo Cloud Pub/Sub quando um veículo atual é atualizado. Para receber essas notificações, siga as instruções aqui.

Instruções: pesquisar veículos

O Fleet Engine permite a pesquisa de veículos. A API SearchVehicles permite encontrar motoristas próximos disponíveis e mais adequados para uma tarefa, como atender a uma viagem ou pedir uma entrega. A API SearchVehicles retorna uma lista classificada de motoristas que correspondem aos atributos da tarefa com atributos de veículos da sua frota. Para mais informações, consulte Encontrar motoristas por perto.

Exemplo

Por padrão, ao pesquisar veículos disponíveis, o Fleet Engine exclui aqueles em viagens ativas. Os serviços do provedor de serviço de transporte por aplicativo compartilhado ou entrega precisam incluí-los explicitamente nas solicitações de pesquisa. O exemplo a seguir mostra como incluir esses veículos em uma pesquisa que corresponde a uma viagem do Grand Indonesia East Mall até o Balai Sidang Jakarta Convention Center.

shell

Primeiro, atualize o local do veículo que criamos nas etapas anteriores para que ele esteja qualificado. No mundo real, isso seria feito pelo SDK do driver em execução em um dispositivo Android ou iOS no veículo.

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

A realização da pesquisa deve mostrar pelo menos esse veículo.

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

Consulte a referência de 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;
}

Consulta de filtragem de veículos

SearchVehicles e ListVehicles são compatíveis com a filtragem em atributos do veículo usando uma consulta de filtro. Para conferir a sintaxe da consulta de filtro, consulte AIP-160 para exemplos.

As consultas com filtro aceitam APENAS a filtragem de atributos do veículo e não podem ser usadas para outros campos. A consulta de filtro funciona como uma cláusula AND com outras restrições, como minimum_capacity ou vehicle_types em SearchVehiclesRequest.

Instruções: listar veículos

O SearchVehicles é otimizado para encontrar um pequeno número de veículos na ordem classificada com muita rapidez e é usado principalmente para encontrar motoristas próximos mais adequados para uma tarefa. No entanto, às vezes você quer encontrar todos os veículos que atendam a alguns critérios, mesmo que seja necessário percorrer os resultados. ListVehicles foi projetado para esse caso de uso.

A API ListVehicles permite encontrar todos os veículos que atendem a algumas opções específicas de solicitação. A API ListVehicles retorna uma lista paginada de veículos no projeto que corresponde a alguns requisitos.

Para filtrar os atributos do veículo, confira Consulta de filtragem de veículos.

Exemplo

Neste exemplo, realizamos a filtragem em vehicle_type e em atributos usando a string 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

Consulte a referência de 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;
}

Viagens e o ciclo de vida delas

A API Trip e o ciclo de vida são semelhantes aos da API e do ciclo de vida do veículo. O provedor de serviço de transporte por aplicativo é responsável por criar viagens usando as interfaces do Fleet Engine. O Fleet Engine fornece um serviço RPC, TripService, e recursos REST, provider.trips . Essas interfaces permitem a criação de entidades "Viagem", as solicitações de informações, a funcionalidade de pesquisa e o recurso de atualização.

Um Trip tem um campo de status para acompanhar a progressão ao longo do ciclo de vida. Os valores mudam de NEW para COMPLETE, mais CANCELED e UNKNOWN_TRIP_STATUS. Consulte trip_status para RPC ou TripStatus para REST.

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

Seu serviço pode atualizar a viagem para CANCELED usando qualquer um desses status. Quando o serviço cria uma viagem, o mecanismo define o status como NEW. Um vehicle_id é opcional. Assim como os veículos, os serviços excluem viagens automaticamente após sete dias sem atualização. Se o serviço tentar criar uma viagem com um ID que já existe, será retornado um erro. Uma viagem é considerada "ativa" quando está em um status diferente de COMPLETE ou CANCELED. Essa distinção é importante no campo active_trips na entidade do veículo e SearchTripsRequest.

O serviço só pode alterar o vehicle_id atribuído a uma viagem quando o status é NEW ou CANCELED. Se um motorista cancelar uma viagem durante o trajeto, o status dela precisará ser definido como NEW ou CANCELED antes que vehicle_id seja modificado ou apagado.

O status é importante ao implementar o suporte à viagem consecutiva. Esse suporte permite que o Provedor atribua uma nova viagem a um Veículo enquanto ele está em uma viagem ativa. O código para criar uma viagem consecutiva é o mesmo de uma única viagem e usa o mesmo ID do veículo. O Fleet Engine adiciona a origem e o destino da nova viagem aos waypoints do veículo. Para mais informações sobre viagens recuadas, consulte Criar viagens com vários waypoints.

Pontos de referência restantes da viagem

A entidade "Trip" contém um campo repetido de TripWaypoint (RPC | REST), chamado remainingWaypoints(RPC | REST). Esse campo inclui todos os waypoints que o veículo precisará percorrer em ordem antes do último ponto de desembarque da viagem. O cálculo é feito com base nos waypoints restantes do veículo. Nos casos de uso "Voltar para trás" e "Waze Carpool", essa lista contém waypoints de outras viagens que serão percorridos antes dessa viagem, mas exclui os waypoints depois dela. O waypoint na lista pode ser identificado por TripId e WaypointType.

A relação entre o status da viagem e os waypoints restantes do Veículo

Os waypoints restantes do veículo (RPC | REST) serão atualizados quando o Fleet Engine receber uma solicitação de mudança do status da viagem. O waypoint anterior será removido da lista de waypoints restantes do Veículo quando tripStatus(RPC | REST) for alterado de outro status para ENROUTE_TO_XXX. Ou seja, quando o status da viagem é alterado de ENROUTE_TO_PICKUP para ARRIVED_AT_PICKUP, o ponto de embarque da viagem continua na lista de waypoints restantes do Veículo. No entanto, quando o status da viagem é alterado para ENROUTE_TO_INTERMEDIATE_DESTINATION ou ENROUTE_TO_DROPOFF, o ponto de embarque restante é removido do waypoint.

Isso é o mesmo para ARRIVED_AT_INTERMEDIATE_DESTINATION e ENROUTE_TO_INTERMDEDIATE_DESTINATION. Quando ARRIVED_AT_INTERMEDIATE_DESTINATION, o destino intermediário atual não será removido da lista de waypoints restantes do Veículo até que o veículo informe que está indo para o próximo waypoint.

Quando o status da viagem mudar para COMPLETED, nenhum waypoint dessa viagem vai aparecer na lista de waypoints restantes do veículo.

Instruções: criar uma viagem

Uma entidade Trip precisa ser criada para que cada solicitação de viagem seja rastreada e correspondida aos veículos na frota. Use o endpoint CreateTrip com CreateTripRequest para criar uma viagem.

Os seguintes atributos são necessários para criar uma viagem:

  • parent: uma string que inclui o ID do provedor criado quando o projeto do Google Cloud foi criado.
  • trip_id: uma string criada pelo provedor de serviço de transporte por aplicativo.
  • trip: contêiner com metadados básicos que descrevem a viagem.
    • trip_type: tipo enumerado que representa se a viagem pode ter outros passageiros de uma origem e um destino diferentes no mesmo veículo (SHARED) ou somente uma parte (EXCLUSIVE).
    • pickup_point: TerminalLocation que representa o ponto de origem da viagem. Consulte a referência da RPC ou a referência da REST.

Ao criar uma viagem, você pode fornecer o number_of_passengers, o dropoff_point e o vehicle_id. Embora esses campos não sejam obrigatórios, eles serão mantidos se você os informar. Todos os outros campos "Viagem" serão ignorados. Por exemplo, todas as viagens começam com um trip_status de NEW, mesmo que você transmita um trip_status de CANCELED na solicitação de criação.

Exemplo

O exemplo a seguir cria uma viagem para o Grand Indonesia East Mall. A viagem é para dois passageiros e é exclusiva. O provider_id do Trip precisa ser igual ao ID do projeto. No exemplo, o provedor de serviço de transporte por aplicativo criou o projeto do Google Cloud, project-id. Esse projeto precisa ter as contas de serviço usadas para chamar o Fleet Engine. O status da viagem é NEW.

Depois, depois que o serviço faz a correspondência da viagem com um veículo, ele pode chamar UpdateTrip e mudar o vehicle_id quando a viagem é atribuída a um veículo.

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

Consulte a referência de 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;
}

Registros do Google Cloud Platform para o Trip Creation

A API Fleet Engine grava uma entrada de registro usando os registros do Google Cloud Platform quando uma chamada para o endpoint CreateTrip é recebida. A entrada de registro inclui informações sobre os valores na solicitação CreateTrip. Se a chamada for bem-sucedida, ela também vai incluir informações sobre o Trip retornado.

Instruções: atualizar uma viagem

A entidade "Trip" contém campos que permitem o rastreamento pelo serviço e para informar a progressão da viagem pelo SDK do motorista e ao SDK do consumidor. Para atualizar as propriedades, use a mensagem UpdateTripRequest. Isso atualiza os campos "Viagem" de acordo com as field_mask da solicitação. Consulte UpdateTripRequest.

O provedor de serviço de transporte por aplicativo é responsável por atualizar os seguintes atributos:

  • Status da viagem.
  • ID do veículo No momento da criação ou depois de corresponder o veículo a uma viagem.
  • Mudanças no embarque, desembarque ou nos waypoints.

O Fleet Engine atualiza automaticamente os seguintes campos ao usar o recurso de compartilhamento de jornada com o SDK do Driver ou o SDK do consumidor:

  • Rotas
  • HEC
  • Distância restante
  • Local do veículo
  • Pontos de referência restantes

Consulte Trip em RPC ou Resource.Trip em REST.

Registros do Google Cloud Platform para atualizações de viagens

A API Fleet Engine grava uma entrada de registro usando os registros do Google Cloud Platform quando uma chamada para o endpoint UpdateTrip é recebida. A entrada de registro inclui informações sobre os valores na solicitação UpdateTrip. Se a chamada for bem-sucedida, ela também vai incluir informações sobre o Trip retornado.

Instruções: pesquisar viagens

O Fleet Engine oferece suporte à pesquisa de viagens. Conforme mencionado anteriormente, uma viagem é excluída automaticamente após sete dias. Portanto, SearchTrips não expõe um histórico completo de todas as viagens.

Embora a SearchTrips seja uma API flexível, a lista abaixo considera dois casos de uso.

  • Determinar as viagens ativas de um veículo: o provedor pode determinar as viagens ativas no momento. No SearchTripsRequest, o vehicle_id é definido como o veículo em questão, e active_trips_only precisa ser definido como true.

  • Reconciliação do estado do provedor e do mecanismo da frota: o provedor pode usar SearchTrips para garantir que o estado da viagem corresponda ao do mecanismo da frota. Isso é especialmente importante para o TripStatus. Se o estado de uma viagem atribuída a um Veículo não estiver definido corretamente como COMPLETE ou CANCELED, o Veículo não será incluído no SearchVehicles.

Para usar SearchTrips dessa maneira, deixe vehicle_id vazio, defina active_trips_only como true e defina minimum_staleness como um horário maior do que a maioria das durações das viagens. Por exemplo, você pode usar uma hora. Os resultados incluem viagens que não estão CONCLUÍDAS nem CANCELADAS e não são atualizadas há mais de uma hora. O provedor precisa examinar essas viagens para garantir que o status delas no Fleet Engine seja atualizado corretamente.

Solução de problemas

No caso de um erro DEADLINE_EXCEEDED, o estado do Fleet Engine é desconhecido. O provedor precisa chamar CreateTrip novamente, que retorna um 201 (CREATED) ou 409 (CONFLICT). No último caso, a solicitação anterior é bem-sucedida antes de DEADLINE_EXCEEDED. Consulte os guias da API Consumer para mais informações sobre como lidar com erros de viagem: Android ou iOS.

Suporte para viagens do Waze Carpool

Você pode atribuir várias viagens de SHARED a um veículo compatível com TripType.SHARED. Você precisa especificar a ordem de todos os waypoints não transmitidos em todas as viagens atribuídas ao Veículo nessa viagem compartilhada usando Trip.vehicle_waypoints ao atribuir o vehicle_id para uma viagem compartilhada (em uma solicitação CreateTrip ou UpdateTrip). Consulte vehicle_waypoints para RPC ou vehicleWaypoints para REST.

Suporte a vários destinos

Identificar um destino intermediário

Os campos intermediateDestinations e intermediateDestinationIndex em Trip (RPC | REST) são combinados para indicar o destino.

Atualizar destino intermediário

Você pode atualizar os destinos intermediários via UpdateTrip. Ao atualizar destinos intermediários, você precisa fornecer uma lista completa de destinos intermediários, incluindo aqueles que foram visitados, e não apenas aqueles recém-adicionados ou a serem modificados. Quando o intermediateDestinationIndex apontar para um índice depois da posição do destino intermediário recém-adicionado/modificado, o destino intermediário novo/atualizado não vai ser adicionado ao waypoints do Veículo ou ao remainingWaypoints da viagem. O motivo é que todos os destinos intermediários antes de intermediateDestinationIndex são tratados como já visitados.

Alterações no status da viagem

O campo intermediateDestinationsVersion em (RPC | REST) é obrigatório na solicitação de atualização do status da viagem enviada ao Fleet Engine para indicar que um destino intermediário foi passado. O destino intermediário desejado é especificado pelo campo intermediateDestinationIndex. Quando tripStatus (RPC | REST) é ENROUTE_TO_INTERMEDIATE_DESTINATION, um número entre [0..N-1] indica qual destino intermediário o veículo vai atravessar em seguida. Quando tripStatus é ARRIVED_AT_INTERMEDIATE_DESTINATION, um número entre [0..N-1] indica em qual destino intermediário o veículo está.

Exemplo

O exemplo de código a seguir demonstra como atualizar o status de uma viagem para chegar ao primeiro destino intermediário, supondo que você tenha criado uma viagem com vários destinos e ela tenha passado pelo ponto de partida.

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

Instruções: inscrever-se para receber mensagens de notificação da API Fleet Engine

A API Fleet Engine usa o Google Cloud Pub/Sub para publicar notificações sobre o tópico criado pelo projeto do Google Cloud do consumidor. O Pub/Sub não está ativado por padrão para o Fleet Engine no seu projeto do Google Cloud. Registre um caso de suporte ou entre em contato com seu Engenheiro de clientes para ativar o Pub/Sub.

Para criar um tópico no seu projeto do Cloud, siga estas instruções. O ID do tópico precisa ser "fleet_engine_notifications".

O tópico precisa ser criado no mesmo projeto do Cloud que está chamando as APIs do Fleet Engine.

Depois que o tópico for criado, será necessário conceder permissão à API Fleet Engine para publicar nele. Para fazer isso, clique no tópico que você acabou de criar e adicione uma nova permissão. Talvez seja necessário clicar em SHOW INFO PANEL para abrir o editor de permissões. O principal precisa ser geo-fleet-engine@system.gserviceaccount.com e o papel precisa ser Pub/Sub publisher.

Para configurar seu projeto do Cloud para receber notificações, siga estas instruções.

A API Fleet Engine vai publicar cada notificação em dois formatos de dados diferentes, protobuf e json. O formato de dados de cada notificação é indicado nos atributos do PubsubMessage com a chave como data_format e o valor como protobuf ou json.

Esquema de notificação:

Protobuf

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

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

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

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

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

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

JSON

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

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

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

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

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