Comienza a usar Fleet Engine

La API de On-demand Rides & Deliveries de Fleet Engine te permite administrar los viajes y el estado de los vehículos para tus aplicaciones de progreso de viaje y pedido. Controla las transacciones entre el SDK de Driver, el SDK del consumidor y tu servicio de backend, que se puede comunicar con Fleet Engine mediante llamadas gRPC o REST.

Requisitos previos

Para desarrollo, asegúrate de instalar el SDK de Cloud (gcloud) y de tener la autenticación en tu proyecto.

shell

gcloud auth login

Deberías ver un mensaje de éxito como el siguiente:

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

Comprobar que las API de On-demand Rides & Deliveries Solution Fleet Engine estén configuradas correctamente

shell

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

Si este comando genera un error, consulta al administrador del proyecto y a tu representante de Atención al cliente de Google para obtener acceso.

Logging

Fleet Engine puede escribir mensajes de registro sobre las llamadas a la API que recibe en registros de Google Cloud Platform. Consulta la documentación de Cloud Logging para obtener una descripción general de cómo leer y analizar los registros.

Es posible que Logging no esté habilitado de forma predeterminada para los proyectos creados antes del 10 de febrero de 2022. Consulta la documentación de registro para obtener más detalles.

Bibliotecas cliente

Publicamos bibliotecas cliente en varios lenguajes de programación comunes. Estas bibliotecas ayudarán a proporcionar una mejor experiencia a los desarrolladores sobre REST o gRPC sin procesar. Si quieres obtener instrucciones para obtener bibliotecas cliente para la aplicación de servidor, consulta Bibliotecas cliente.

En los ejemplos de Java que se incluyen en esta documentación, se supone que el usuario tiene conocimientos previos sobre gRPC.

Autenticación y autorización

Puedes configurar las funciones que proporciona el progreso del viaje y del pedido a través de la consola de Google Cloud. Estas APIs y SDKs requieren el uso de tokens web JSON que se firmaron con cuentas de servicio creadas desde la consola de Cloud.

Configuración del proyecto de Cloud

Para configurar tu proyecto de la nube, primero crea tu proyecto y, luego, crea cuentas de servicio.

Para crear tu proyecto de Google Cloud, sigue estos pasos:

  1. Crea un proyecto de Google Cloud con la consola de Google Cloud.
  2. En el panel de APIs y servicios, habilita la API de Local Rides and Deliveries.

Las cuentas de servicio están asociadas con uno o más roles. Se usan para crear tokens web JSON que otorgan diferentes conjuntos de permisos según las funciones. Por lo general, para reducir la posibilidad de abusos, puedes crear varias cuentas de servicio, cada una con el conjunto mínimo de funciones requeridas.

El progreso del viaje y el pedido usa los siguientes roles:

RolDescripción
Usuario de SDK del consumidor de Fleet Engine

roles/fleetengine.consumerSdkUser
Otorga permiso para buscar vehículos y recuperar información sobre vehículos y viajes. Los tokens creados por una cuenta de servicio con este rol se suelen usar desde tus dispositivos móviles de transporte compartido o entrega para consumidores.
Usuario de SDK del controlador de Fleet Engine

roles/fleetengine.driverSdkUser
Otorga permiso para actualizar las ubicaciones y rutas de los vehículos, y recuperar información sobre los vehículos y los viajes. Los tokens creados por una cuenta de servicio con esta función se suelen usar desde tus dispositivos móviles de transporte compartido o de la app del conductor de entregas.
Superusuario del servicio de Fleet Engine

roles/fleetengine.serviceSuperUser
Otorga permisos a todas las APIs de vehículos y viajes. Los tokens creados por una cuenta de servicio con esta función suelen usarse desde tus servidores de backend.

Por ejemplo, crea una cuenta de servicio para cada una de las tres funciones y asígnales sus respectivas funciones.

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

Los SDK de Driver y Consumer se basan en estos roles estándar.

De manera alternativa, es posible crear funciones personalizadas que permitan agrupar un conjunto arbitrario de permisos. Los SDK de Drive y Consumer mostrarán mensajes de error cuando falte un permiso obligatorio. Por lo tanto, recomendamos enfáticamente usar el conjunto de funciones estándar que se presentó anteriormente y no usar las funciones personalizadas.

Para mayor comodidad, si necesitas crear tokens JWT para clientes que no sean de confianza, agregar usuarios a la función de creador de tokens de la cuenta de servicio les permite crear tokens con las herramientas de línea de comandos de gcloud.

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

En el ejemplo anterior, my-user@example.com es el correo electrónico que se usa para autenticarse con gcloud (gcloud auth list --format='value(account)').

Biblioteca de autenticación de Fleet Engine

Fleet Engine usa tokens web JSON (JWT) para restringir el acceso a las APIs de Fleet Engine. La nueva biblioteca de autenticación de Fleet Engine, disponible en GitHub, simplifica la construcción de los JWT de Fleet Engine y los firma de forma segura.

La biblioteca proporciona los siguientes beneficios:

  • Simplifica el proceso de creación de tokens de Fleet Engine.
  • Proporciona mecanismos de firma de tokens distintos del uso de archivos de credenciales (como suplantar la identidad de una cuenta de servicio).
  • Adjunta tokens firmados a las solicitudes salientes realizadas desde un stub de gRPC o un cliente de GAPIC.

Crea un token web JSON (JWT) para la autorización

Cuando no se usa la biblioteca de autenticación de Fleet Engine, los tokens web JSON (JWT) deben crearse directamente en tu base de código. Esto requiere que tengas un conocimiento profundo de los JWT y de cómo se relacionan con Fleet Engine. Es por eso que recomendamos EN gran medida que aproveches la biblioteca de autenticación de Fleet Engine.

En Fleet Engine, los tokens web JSON (JWT) proporcionan autenticación de corta duración y garantizan que los dispositivos solo puedan modificar vehículos, viajes o tareas para los que están autorizados. Los JWT contienen un encabezado y una sección de reclamación. La sección del encabezado contiene información como la clave privada que se usará (obtenida de las cuentas de servicio) y el algoritmo de encriptación. La sección de reclamos contiene información como la hora de creación del token, el tiempo de actividad de los tokens, los servicios a los que reclama el acceso y otra información de autorización para determinar el acceso descendente, por ejemplo, el ID del vehículo.

La sección de un encabezado JWT contiene los siguientes campos:

CampoDescripción
alg El algoritmo que se usará. `RS256`.
typ Es el tipo de token. “JWT”.
niño El ID de la clave privada de tu cuenta de servicio Puedes encontrar este valor en el campo “private_key_id” del archivo JSON de tu cuenta de servicio. Asegúrate de usar la clave de una cuenta de servicio con el nivel correcto de permisos.

Una sección de reclamaciones de JWT contiene los siguientes campos:

CampoDescripción
iss La dirección de correo electrónico de tu cuenta de servicio.
sub La dirección de correo electrónico de tu cuenta de servicio.
aud El SERVICE_NAME de su cuenta de servicio, en este caso https://fleetengine.googleapis.com/
iat La marca de tiempo de cuando se creó el token, especificada en segundos transcurridos desde las 00:00:00 UTC, del 1 de enero de 1970. Espera 10 minutos para el sesgo. Si la marca de tiempo es demasiado lejana en el pasado o en el futuro, es posible que el servidor informe un error.
exp La marca de tiempo de cuándo vence el token, especificada en segundos transcurridos desde las 00:00:00 UTC, del 1 de enero de 1970. La solicitud falla si la marca de tiempo es de más de una hora después.
autorización Según el caso de uso, puede contener "vehicleid" o "tripid".

Crear un token JWT implica firmarlo. Si deseas obtener instrucciones y muestras de código para crear y firmar el JWT, consulta Autorización de cuenta de servicio sin OAuth. Luego, puedes adjuntar un token firmado a las llamadas de gRPC o a otros métodos que se usen para acceder a Fleet Engine.

Reclamaciones de JWT

Cuando crees la carga útil de JWT, agrega una reclamación adicional en la sección de autorización con la clave vehicleid o tripid configurada con el valor del ID de vehículo o ID de viaje para el cual se realiza la llamada.

El SDK de Driver siempre usa la reclamación vehicleid, ya sea que opere en un viaje o un vehículo. El backend de Fleet Engine garantiza que el vehículo esté asociado con el viaje solicitado antes de realizar la modificación.

El SDK para consumidores siempre usa un reclamo tripid.

El proveedor de transporte compartido o proveedor de entregas debe usar vehicleid o tripid con un "*" para que coincida con todos los vehículos y viajes. Ten en cuenta que el JWT puede contener ambos tokens, incluso si no es obligatorio, lo que puede simplificar la implementación de la firma de tokens.

Casos de uso de JWT

A continuación, se muestra un ejemplo de un token para el servidor del proveedor:

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

A continuación, se muestra un token de ejemplo para Consumer app:

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

A continuación, se muestra un token de ejemplo para la app del conductor:

{
  "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"
   }
}
  • En el campo kid del encabezado, especifica el ID de la clave privada de tu cuenta de servicio. Puedes encontrar este valor en el campo private_key_id del archivo JSON de tu cuenta de servicio.
  • En los campos iss y sub, especifica la dirección de correo electrónico de tu cuenta de servicio. Puedes encontrar este valor en el campo client_email del archivo JSON de tu cuenta de servicio.
  • En el campo aud, especifica https://SERVICE_NAME/.
  • Para el campo iat, usa la marca de tiempo de cuando se creó el token, especificada como los segundos transcurridos desde las 00:00:00 UTC del 1 de enero de 1970. Espera 10 minutos para el sesgo. Si la marca de tiempo es demasiado lejana en el pasado o en el futuro, es posible que el servidor informe un error.
  • Para el campo exp, usa la marca de tiempo de cuándo vence el token, especificada como segundos desde las 00:00:00 UTC del 1 de enero de 1970. El valor máximo permitido es iat + 3,600.

Cuando firmes el JWT que se pasará a un dispositivo móvil, asegúrate de usar la cuenta de servicio para la función de SDK de controlador o consumidor. De lo contrario, el dispositivo móvil podrá alterar el estado que no debería tener.

Del mismo modo, cuando firmes el JWT que se usará para llamadas con privilegios, asegúrate de usar la cuenta de servicio con el rol de superusuario. De lo contrario, la operación fallará.

Genera un JWT para realizar pruebas

Generar tokens desde la terminal puede ser útil durante las pruebas.

Para seguir estos pasos, tu cuenta de usuario debe tener la función de creador de tokens de cuenta de servicio:

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

Crea un archivo nuevo llamado unsigned_token.json con el siguiente contenido. La propiedad iat es la hora actual en segundos después del ciclo de entrenamiento, que se puede recuperar ejecutando date +%s en tu terminal. La propiedad exp es la hora de vencimiento en segundos después de la época, que se puede calcular agregando 3,600 a iat. La fecha de vencimiento no puede ser más de una hora en el 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": "*"
   }
}

Luego, ejecuta el comando siguiente de gcloud para firmar el token en nombre de tu cuenta de servicio de superusuario:

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

Ahora, se debe almacenar un JWT codificado en Base64 firmado dentro del archivo signed_token.jwt. El token es válido durante la próxima hora.

Ahora puedes probar el token ejecutando un comando curl en el extremo de REST para enumerar vehículos:

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

Los vehículos y su ciclo de vida

El vehículo es la entidad que representa un par de vehículo y conductor. Actualmente, no se puede hacer un seguimiento de un conductor y un vehículo por separado. El proveedor de transporte compartido o de entregas crea un vehículo con un ID de proveedor (que debe ser el mismo que el del proyecto de Google Cloud que contiene la cuenta de servicio que se usa para llamar a las APIs de Fleet Engine) y un ID de vehículo propiedad del proveedor de transportes compartidos o de entregas.

Los vehículos que no se hayan actualizado mediante UpdateVehicle después de siete días se borrarán automáticamente. Se produjo un error cuando se llama a CreateVehicle con un par de ID de proveedor/ID de vehículo que ya existe. El caso de vehículos que no se actualizan con frecuencia se puede abordar de dos maneras: llamar con frecuencia a CreateVehicle con un par de ID de proveedor/ID de vehículo previsto y descartar el error si el vehículo ya existe o llamar a CreateVehicle después de que una UpdateVehicle devuelve un error NOT_FOUND.

Actualizaciones sobre la ubicación del vehículo

Para obtener el mejor rendimiento con Fleet Engine, proporciónale un flujo de actualizaciones de la ubicación de los vehículos. Utiliza cualquiera de los siguientes métodos para proporcionar estas actualizaciones:

  1. Usa el SDK de Driver para iOS o Android. Es la opción más simple.
  2. Usa un código personalizado, que es útil si las ubicaciones se retransmiten mediante tu backend o si usas dispositivos que no son Android o iOS.

Tipos de vehículos

La entidad Vehículo incluye un campo obligatorio de VehicleType, que incluye una enumeración Category que se puede especificar como AUTO, TAXI, TRUCK, TWO_WHEELER, BICYCLE o PEDESTRIAN. El tipo de vehículo puede servir como criterios de filtro en SearchVehicles y ListVehicles.

Todas las rutas para vehículos usarán el RouteTravelMode correspondiente si la categoría está configurada como AUTO, TWO_WHEELER, BICYCLE o PEDESTRIAN. Si la categoría se establece en TAXI o TRUCK, el enrutamiento se trata de la misma manera que el modo AUTO.

Atributos del vehículo

La entidad Vehículo contiene un campo repetido de VehicleAttribute. Fleet Engine no interpreta estos atributos. La API de SearchVehicles incluye un campo para requerir que los Vehicles coincidentes contengan todos los atributos incluidos establecidos en el valor especificado.

Ten en cuenta que el campo de atributo es además de varios otros campos admitidos en el mensaje Vehicle, como vehicle_type y supported_trip_types.

Puntos de referencia restantes del vehículo

La entidad vehículo contiene un campo repetido de TripWaypoint (RPC | REST), llamado waypoints(RPC | REST). Este campo incluye los puntos de referencia restantes en los viajes, en el orden en que el vehículo llega a ellos. Fleet Engine calcula este campo a medida que se asignan viajes al vehículo y lo actualiza a medida que los viajes cambian su estado. Estos puntos de referencia se pueden identificar con los campos TripId y WaypointType.

Ampliación de la elegibilidad de un vehículo para las coincidencias

Por lo general, los servicios de transporte compartido o proveedor de entregas son responsables de hacer coincidir las solicitudes de viaje con los vehículos. El servicio puede usar los atributos del vehículo para incluir un vehículo en una mayor cantidad de búsquedas. Por ejemplo, el proveedor puede implementar un conjunto de atributos que correspondan a los niveles de beneficios o capacidades que proporciona un vehículo. Por ejemplo, tres niveles podrían ser un conjunto de atributos con valores booleanos: is_bronze_level, is_silver_level y is_gold_level. Un vehículo puede ser apto para los tres. Cuando Fleet Engine recibe una solicitud para un viaje que requiere capacidades de nivel plata, la búsqueda incluye ese vehículo. El uso de atributos de esta forma incluye vehículos que ofrecen una variedad de capacidades.

Existen dos formas de actualizar los atributos de un vehículo. Una es la API de UpdateVehicle. Cuando se usa esta API, se establece el conjunto completo de atributos de vehículos en función del valor establecido. No se puede actualizar un solo atributo. El otro método es la API de UpdateVehicleAttributes. Este método solo toma los atributos que se actualizarán. Los atributos incluidos en la solicitud se configurarán con el valor nuevo o se agregarán. Los atributos no especificados no se modificarán.

INSTRUCTIVO: Cómo crear un vehículo

Se debe crear una entidad Vehicle para cada vehículo al que se pueda hacer un seguimiento de la flota.

Usa el extremo CreateVehicle con CreateVehicleRequest para crear un vehículo.

El provider_id de Vehicle debe ser el ID del proyecto (p.ej., mi proyecto a pedido) del proyecto de Google Cloud que contiene las cuentas de servicio que se usarán para llamar a Fleet Engine. Ten en cuenta que, si bien varias cuentas de servicio pueden acceder a Fleet Engine para el mismo proveedor de transporte compartido o de entrega, por el momento, Fleet Engine no admite cuentas de servicio de varios proyectos de Google Cloud que accedan al mismo Vehicles.

Vehicle se puede crear en el estado OFFLINE o ONLINE. Si se crea ONLINE, puede mostrarse de inmediato en respuesta a las consultas SearchVehicles.

Se puede incluir un last_location inicial en la llamada a CreateVehicle. Si bien se permite, no se debe crear un Vehicle en el estado ONLINE sin un last_location.

Consulta Tipos de vehículos para obtener detalles sobre el campo de tipos de vehículo.

Consulta Atributos de vehículo para obtener detalles sobre el campo de atributos.

El valor que muestra CreateVehicle es la entidad Vehicle creada.

Ejemplo

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

Consulta la referencia 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 de Google Cloud Platform para la creación de vehículos

La API de Fleet Engine escribe una entrada de registro a través de los registros de Google Cloud Platform cuando se recibe una llamada al extremo CreateVehicle. La entrada de registro incluye información sobre los valores de la solicitud CreateVehicle. Si la llamada se realiza correctamente, también se incluirá información sobre el objeto Vehicle que se mostró.

shell

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

Deberías imprimir un registro similar al siguiente:

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

Notificaciones de Cloud Pub/Sub para la creación de vehículos

La API de Fleet Engine publica una notificación a través de Cloud Pub/Sub cuando se crea un vehículo nuevo. Para recibir estas notificaciones, sigue las instrucciones que aparecen aquí.

INSTRUCTIVO: Cómo actualizar la ubicación de un vehículo

Si no usas el SDK de Driver para actualizar la ubicación del vehículo, puedes realizar una llamada directa a Fleet Engine con esa ubicación. Para cualquier vehículo activo, Fleet Engine espera una actualización de ubicación al menos una vez por minuto y como máximo una vez cada 5 segundos. Estas actualizaciones solo requieren privilegios de usuario del SDK del controlador de Fleet Engine.

Ejemplo

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

Consulta la referencia 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.

Instructivo: Actualiza otros campos de vehículos

Las actualizaciones de otros atributos del estado del vehículo se producen con menos frecuencia que las actualizaciones de posición. Las actualizaciones de los atributos que no sean last_location requieren privilegios de superusuario de Fleet Engine.

UpdateVehicleRequest incluye un update_mask para indicar qué campos actualizar. El comportamiento del campo es como en la documentación de Protobuf para máscaras de campo.

Como se indica en Atributos de vehículo, para actualizar el campo attributes, es necesario escribir todos los atributos a fin de preservarlos. No es posible actualizar solo el valor de un par clave-valor en una llamada a UpdateVehicle. Para actualizar los valores de atributos específicos, se puede usar la API de UpdateVehicleAttributes.

Ejemplo

En este ejemplo, se habilita 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

Consulta la referencia 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 de plataforma de Google Cloud para actualizaciones de vehículos

La API de Fleet Engine escribe una entrada de registro a través de los registros de Google Cloud Platform cuando se recibe una llamada al extremo UpdateVehicle. La entrada de registro incluye información sobre los valores de la solicitud UpdateVehicle. Si la llamada se realiza correctamente, también se incluirá información sobre el objeto Vehicle que se mostró.

shell

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

Notificaciones de Cloud Pub/Sub para actualizaciones de vehículos

La API de Fleet Engine publica una notificación a través de Cloud Pub/Sub cuando se actualiza un vehículo existente. Para recibir estas notificaciones, sigue las instrucciones que aparecen aquí.

INSTRUCTIVO: Buscar vehículos

Fleet Engine admite la búsqueda de vehículos. La API de SearchVehicles te permite encontrar los conductores cercanos disponibles más adecuados para realizar una tarea, como brindar un viaje o solicitar una entrega. La API de SearchVehicles muestra una lista clasificada de conductores que coinciden con los atributos de las tareas de los vehículos de tu flota. Para obtener más información, consulta Cómo encontrar conductores cercanos.

Ejemplo

Cuando se buscan vehículos disponibles, Fleet Engine excluye los vehículos en viajes activos de forma predeterminada. Los servicios de un proveedor de transporte compartido o proveedor de servicios de entrega deben incluirlos explícitamente en las solicitudes de búsqueda. En el siguiente ejemplo, se muestra cómo incluir esos vehículos en una búsqueda de vehículos que coincidan con un viaje desde el Grand Indonesia East Mall hasta el centro de convenciones Balai Sidang Yakarta.

shell

Primero, actualiza la ubicación del vehículo que creamos en los pasos anteriores para que sea apto. En el mundo real, esto lo haría el SDK de Driver que se ejecuta en un dispositivo Android o iOS en el vehí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

La búsqueda debería rendir al menos en ese vehí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

Consulta la referencia 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 filtrado de vehículos

SearchVehicles y ListVehicles admiten el filtrado en atributos de vehículos mediante una consulta de filtro. Para ver la sintaxis de las consultas de filtros, consulta AIP-160 para ver ejemplos.

Ten en cuenta que las consultas de filtro SOLO admiten el filtrado por atributos del vehículo y no se pueden usar para otros campos. La consulta de filtro funciona como una cláusula AND con otras restricciones, como minimum_capacity o vehicle_types en SearchVehiclesRequest.

INSTRUCTIVO: Enumerar vehículos

SearchVehicles está optimizado para encontrar con rapidez una pequeña cantidad de vehículos en orden de clasificación y se usa principalmente para encontrar a los conductores cercanos que son más adecuados para una tarea. Sin embargo, en ocasiones, es posible que desees encontrar todos los vehículos que cumplan con algunos criterios, incluso si es necesario desplazarse por los resultados. ListVehicles está diseñado para ese caso de uso.

La API de ListVehicles te permite encontrar todos los vehículos que satisfacen algunas opciones de solicitud específicas. La API de ListVehicles muestra una lista paginada de vehículos del proyecto que coincide con algunos requisitos.

Para filtrar los atributos de vehículos, consulta la Consulta de filtrado de vehículos.

Ejemplo

En este ejemplo, se filtra en vehicle_type y en atributos con la cadena 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

Consulta la referencia 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;
}

Viajes y su ciclo de vida

La API de Trip y su ciclo de vida son similares a la API y su ciclo de vida de vehículos. El proveedor de transporte compartido es responsable de crear viajes con las interfaces de Fleet Engine. Fleet Engine proporciona un servicio de RPC, TripService, y recursos de REST, provider.trips. Estas interfaces habilitan la creación de entidades de viaje, las solicitudes de información y la funcionalidad de búsqueda y de actualización.

Un Trip tiene un campo de estado para realizar un seguimiento de su progreso a lo largo del ciclo de vida. Los valores pasan de NEW a COMPLETE más CANCELED y UNKNOWN_TRIP_STATUS. Consulta trip_status para RPC o TripStatus para REST.

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

Tu servicio puede actualizar el viaje a CANCELED desde cualquiera de estos estados. Cuando el servicio crea un viaje, el motor establece el estado como NEW. Un vehicle_id es opcional. Al igual que con los vehículos, los servicios borran viajes automáticamente después de siete días sin una actualización. Si tu servicio intenta crear un viaje con un ID que ya existe, se mostrará un error. Un viaje se considera "activo" si se encuentra en un estado que no sea COMPLETE ni CANCELED. Esta distinción es importante en el campo active_trips de la entidad Vehicle y SearchTripsRequest.

El servicio solo puede modificar el objeto vehicle_id asignado a un viaje cuando el estado es NEW o CANCELED. Si un Conductor cancela un Viaje mientras está en la ruta, el estado del Viaje debe establecerse en NEW o CANCELED antes de que se cambie o borre el vehicle_id.

El estado es importante cuando se implementa la compatibilidad con viajes seguidos. Esta compatibilidad permite al Proveedor asignar un viaje nuevo a un Vehículo mientras este se encuentra en un Viaje activo. El código para crear un viaje uno tras otro es el mismo que el de un solo viaje y usa el mismo ID de vehículo. Fleet Engine agrega el origen y el destino del viaje nuevo a los puntos de referencia del vehículo. Para obtener más información sobre los viajes seguidos, consulta Cómo crear viajes con varios puntos de referencia.

Puntos de referencia restantes del viaje

La entidad de viaje contiene un campo repetido de TripWaypoint (RPC | REST), llamado remainingWaypoints(RPC | REST). Este campo incluye todos los puntos de referencia que el vehículo deberá recorrer en orden antes del punto de llegada final del viaje. Calcula a partir de los puntos de referencia restantes del vehículo. En los casos de uso de viajes consecutivos y de Carpool, esta lista contiene puntos de referencia de otros viajes que se recorrerán antes de este viaje, pero excluye los puntos de referencia posteriores a este. El punto de referencia de la lista se puede identificar por su TripId y WaypointType.

La relación entre el estado del viaje y los puntos de referencia restantes del vehículo

Los puntos de referencia restantes del vehículo (RPC | REST) se actualizarán cuando Fleet Engine reciba una solicitud de cambio de estado de viaje. El punto de referencia anterior se quitará de la lista de puntos de referencia restantes del vehículo cuando tripStatus(RPC | REST) se cambie de otro estado a ENROUTE_TO_XXX. Es decir, cuando el estado del viaje cambia de ENROUTE_TO_PICKUP a ARRIVED_AT_PICKUP, el punto de partida del viaje seguirá estando en la lista de puntos de referencia restantes del vehículo, pero cuando el estado del viaje cambie a ENROUTE_TO_INTERMEDIATE_DESTINATION o ENROUTE_TO_DROPOFF, el punto de partida se quitará del vehículo.

Es lo mismo para ARRIVED_AT_INTERMEDIATE_DESTINATION y ENROUTE_TO_INTERMDEDIATE_DESTINATION. Cuando llegue ARRIVED_AT_INTERMEDIATE_DESTINATION, el destino intermedio actual no se quitará de la lista de puntos de referencia restantes del vehículo hasta que el vehículo informe que se dirige al siguiente punto de referencia.

Cuando el estado del viaje se cambie a COMPLETED, no habrá puntos de referencia de este viaje en la lista de puntos de referencia restantes del vehículo.

INSTRUCTIVO: Cómo crear un viaje

Se debe crear una entidad Trip para que cada solicitud de viaje se rastree y coincida con los vehículos de la flota. Usa el extremo CreateTrip con CreateTripRequest para crear un viaje.

Para crear un viaje, se requieren los siguientes atributos:

  • parent: Es una cadena que incluye el ID de proveedor creado cuando se creó el proyecto de Google Cloud.
  • trip_id: Es una cadena creada por el proveedor de transporte compartido.
  • trip: Contenedor con metadatos básicos que describen el viaje.
    • trip_type: Es una enumeración que representa si el viaje podría tener otros pasajeros de un origen y un destino diferentes en el mismo vehículo (SHARED) o solo de una parte (EXCLUSIVE).
    • pickup_point: Es el campo TerminalLocation que representa el punto de origen del viaje. Consulta la referencia de RPC o la referencia de REST.

Cuando creas un viaje, puedes proporcionar el number_of_passengers, el dropoff_point y el vehicle_id. Aunque estos campos no son obligatorios, se conservarán si los proporcionas. Se ignorarán todos los demás campos de Viaje. Por ejemplo, todos los viajes comienzan con un trip_status de NEW, incluso si pasas un trip_status de CANCELED en la solicitud de creación.

Ejemplo

En el siguiente ejemplo, se crea un viaje al centro comercial Grand Indonesia East. El viaje es de dos pasajeros y es exclusivo. El provider_id de Trip debe ser el mismo que el ID del proyecto. En el ejemplo, el proveedor de transporte compartido creó el proyecto de Google Cloud, project-id. Este proyecto debe tener las cuentas de servicio que se usan para llamar a Fleet Engine. El estado del viaje es NEW.

Más adelante, después de que el servicio asocia el viaje con un vehículo, puede llamar a UpdateTrip y cambiar las vehicle_id cuando el viaje se asigna a un vehí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

Consulta la referencia 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 de plataforma de Google Cloud para la creación de viajes

La API de Fleet Engine escribe una entrada de registro con los registros de la plataforma de Google Cloud cuando se recibe una llamada al extremo CreateTrip. La entrada de registro incluye información sobre los valores de la solicitud CreateTrip. Si la llamada se ejecuta correctamente, también se incluirá información sobre el objeto Trip que se mostró.

Instructivo: Cómo actualizar un viaje

La entidad Trip contiene campos que permiten el seguimiento por parte del servicio y para informar el progreso del viaje a través del SDK de Driver y del SDK de Consumidor. Para actualizar las propiedades, usa el mensaje UpdateTripRequest. Esto actualizará los campos de viaje según el field_mask de la solicitud. Consulta UpdateTripRequest.

El Proveedor de transporte compartido es responsable de actualizar los siguientes atributos:

  • Estado del viaje.
  • ID del vehículo. ya sea en el momento de la creación o después de hacer coincidir el vehículo con un viaje.
  • Cambios en el punto de partida, el destino o los puntos de referencia.

Fleet Engine actualiza automáticamente los siguientes campos cuando usa la función de viaje compartido mediante el SDK de Driver o el SDK de consumidor:

  • Routes
  • ETA
  • Distancia restante
  • Ubicación del vehículo
  • Puntos de referencia restantes

Consulta Trip en RPC o Resource.Trip en REST.

Registros de plataforma de Google Cloud para Actualizaciones de viaje

La API de Fleet Engine escribe una entrada de registro con los registros de la plataforma de Google Cloud cuando se recibe una llamada al extremo UpdateTrip. La entrada de registro incluye información sobre los valores de la solicitud UpdateTrip. Si la llamada se ejecuta correctamente, también se incluirá información sobre el objeto Trip que se mostró.

INSTRUCTIVOS: Buscar viajes

Fleet Engine admite la búsqueda de viajes. Como se indicó anteriormente, los Viajes se borran automáticamente después de siete días, por lo que SearchTrips no expone un historial completo de todos los Viajes.

Si bien SearchTrips es una API flexible, la siguiente lista considera dos casos de uso.

  • Determinación de los viajes activos de un vehículo: El proveedor puede determinar los viajes activos de un vehículo en ese momento. Dentro de SearchTripsRequest, vehicle_id se establece en el vehículo en cuestión y active_trips_only debe establecerse en true.

  • Conciliar el proveedor y el estado de Fleet Engine: El proveedor puede usar SearchTrips para garantizar que su estado del Viaje y el de Fleet Engine coincidan. Esto es muy importante para el estado TripStatus. Si el estado de un viaje asignado a un vehículo no se establece correctamente en COMPLETE o CANCELED, el vehículo no se incluirá en SearchVehicles.

Para usar SearchTrips de esta manera, deja vehicle_id vacío, establece active_trips_only en true y establece minimum_staleness en un horario mayor que la mayoría de las duraciones de los viajes. Por ejemplo, puedes usar una hora. Los resultados incluyen Viajes que no son COMPLETO ni CANCELADO y que no se actualizaron en más de una hora. El proveedor debe examinar estos viajes para asegurarse de que su estado en Fleet Engine se actualice de forma correcta.

Solución de problemas

En el caso de un error DEADLINE_EXCEEDED, se desconoce el estado de Fleet Engine. El proveedor debe volver a llamar a CreateTrip, que muestra un 201 (CREATED) o 409 (CONFLICT). En el último caso, la solicitud anterior se realizó correctamente antes del DEADLINE_EXCEEDED. Consulta las guías de la API del consumidor para obtener más información sobre cómo manejar los errores de viaje: Android o iOS.

Asistencia para viajes de Carpool

Puedes asignar varios viajes con SHARED a un vehículo que admite TripType.SHARED. Debes especificar el orden de todos los puntos de referencia sin pasar para todos los Viajes asignados al Vehículo en este viaje compartido a través de Trip.vehicle_waypoints cuando asignas el vehicle_id para un viaje compartido (en una solicitud CreateTrip o UpdateTrip). Consulta vehicle_waypoints para RPC o vehicleWaypoints para REST.

Compatibilidad con varios destinos

Cómo identificar un destino intermedio

Los campos intermediateDestinations y intermediateDestinationIndex en Trip (RPC | REST) se combinan para indicar el destino.

Actualizar el destino intermedio

Puedes actualizar los destinos intermedios mediante UpdateTrip. Cuando actualizas destinos intermedios, debes proporcionar una lista completa de estos, incluidos los que ya se visitaron, no solo los que se agregaron recientemente o deben modificarse. Cuando intermediateDestinationIndex apunta a un índice después de la posición del destino intermedio agregado o modificado recientemente, este último no se agregará al waypoints del vehículo o al remainingWaypoints del viaje. Esto se debe a que cualquier destino intermedio anterior a intermediateDestinationIndex se trata como ya visitado.

Cambios en el estado del viaje

El campo intermediateDestinationsVersion en (RPC | REST) es obligatorio en la solicitud de actualización de estado del viaje enviada a Fleet Engine para indicar que un destino intermedio pasó. El destino intermedio objetivo se especifica a través del campo intermediateDestinationIndex. Cuando tripStatus (RPC | REST) es ENROUTE_TO_INTERMEDIATE_DESTINATION, un número entre [0..N-1] indica con qué destino intermedio cruzará el vehículo a continuación. Cuando tripStatus es ARRIVED_AT_INTERMEDIATE_DESTINATION, un número entre [0..N-1] indica en qué destino intermedio se encuentra el vehículo.

Ejemplo

En el siguiente ejemplo de código, se muestra cómo actualizar el estado de un viaje para dirigirlo a su primer destino intermedio, suponiendo que creaste un viaje con varios destinos y que este pasó su punto 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;
}

INSTRUCTIVO: Suscríbete a los mensajes de notificación de la API de Fleet Engine

La API de Fleet Engine usa Google Cloud Pub/Sub para publicar notificaciones sobre el tema que crea el proyecto de Google Cloud del consumidor. Pub/Sub no está habilitado de forma predeterminada para Fleet Engine en tu proyecto de Google Cloud. Presenta un caso de asistencia o comunícate con tu ingeniero de Atención al Cliente para habilitar Pub/Sub.

Para crear un tema en tu proyecto de Cloud, sigue estas instrucciones. El ID del tema debe ser "fleet_engine_notifications".

El tema debe crearse en el mismo proyecto de Cloud que llama a las APIs de Fleet Engine.

Una vez que se cree el tema, deberás otorgar permiso a la API de Fleet Engine para publicar en el tema. Para ello, haz clic en el tema que acabas de crear y agrega un permiso nuevo. Es posible que debas hacer clic en MOSTRAR PANEL DE INFORMACIÓN para abrir el editor de permisos. La principal debe ser geo-fleet-engine@system.gserviceaccount.com y la función debe ser Pub/Sub publisher.

Si deseas configurar tu proyecto de Cloud para suscribirte a las notificaciones, sigue estas instrucciones.

La API de Fleet Engine publicará cada notificación en dos formatos de datos diferentes, protobuf y json. El formato de datos de cada notificación se indica en los atributos de PubsubMessage con la clave como data_format y el valor como protobuf o json.

Esquema de notificaciones:

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