Comienza a usar Fleet Engine

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

Requisitos previos

Para el desarrollo, asegúrate de instalar el SDK de Cloud (gcloud) y de estar autenticado 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 ...

Verifica que las APIs de On-demand Rides and Deliveries Solution Fleet Engine estén configuradas de forma correcta.

shell

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

Si este comando genera un error, comunícate con el administrador del proyecto y 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 la plataforma de Google Cloud. 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 del desarrollador en comparación con REST o gRPC sin procesar. Si quieres obtener instrucciones para obtener bibliotecas cliente para tu aplicación de servidor, consulta la sección Bibliotecas cliente.

En los ejemplos de Java que se incluyen en esta documentación, se da por sentado que tienes conocimientos de gRPC.

Autenticación y autorización

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

Configuración de un proyecto de Cloud

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

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

  1. Crear 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 utiliza los siguientes roles:

RolDescripción
Usuario del SDK para el consumidor de Fleet Engine

roles/fleetengine.consumerSdkUser
Otorga permiso para buscar vehículos y recuperar información sobre ellos y los viajes. Por lo general, los tokens creados por una cuenta de servicio con este rol se usan desde dispositivos móviles de tus apps para consumidores de transporte compartido o entrega.
Usuario de SDK de Fleet Engine Driver

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. Por lo general, los tokens creados por una cuenta de servicio con esta función se usan desde tus dispositivos móviles de transporte compartido o de la app del repartidor.
Superusuario del servicio de Fleet Engine

roles/fleetengine.serviceSuperUser
Otorga permisos a todas las APIs de vehículos y viajes. Por lo general, los tokens creados por una cuenta de servicio con esta función se usan desde tus servidores de backend.

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

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 estas funciones estándar.

Como alternativa, es posible crear funciones personalizadas que permitan agrupar un conjunto arbitrario de permisos. Los SDK de Driver y Consumer mostrarán mensajes de error cuando falte un permiso obligatorio. Por lo tanto, recomendamos enfáticamente usar el conjunto estándar de funciones que se mencionaron 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 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 autenticar 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 API 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 que no sean el uso de archivos de credenciales (como actuar en nombre de una cuenta de servicio).
  • Adjunta tokens firmados a las solicitudes salientes realizadas desde un stub de gRPC o un cliente de GCC.

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 la base de código. Esto requiere que tengas un conocimiento profundo de los JWT y cómo se relacionan con Fleet Engine. Es por eso que recomendamos 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 reclamación contiene información como la hora de creación del token, su tiempo de actividad, los servicios a los que reclama el acceso y otra información de autorización para reducir el alcance; por ejemplo, el ID del vehículo.

Una sección de 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 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 una clave de una cuenta de servicio con el nivel correcto de permisos.

La sección de reclamaciones 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 tu 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 vencimiento del token, especificada en los 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 a futuro.
autorización Según el caso de uso, puede contener "vehicleid" o "tripid".

Crear un token JWT hace referencia a firmarlo. Si deseas obtener instrucciones y muestras de código para crear y firmar el JWT, consulta Autorización de la cuenta de servicio sin OAuth. Luego, puedes adjuntar un token firmado a las llamadas de gRPC o a otros métodos que se usan 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 establecida en el valor del ID de vehículo o ID de viaje para el que se realiza la llamada.

El SDK de Driver siempre usa la reclamación vehicleid, ya sea que se opere en un viaje o en 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 la reclamación tripid.

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

Casos de uso de JWT

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

{
  "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 controlador:

{
  "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/.
  • En 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.
  • En el campo exp, usa la marca de tiempo de cuándo vence el token, que se especifica 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 para pasarlo a un dispositivo móvil, asegúrate de usar la cuenta de servicio para el rol de SDK de consumidor o controlador. 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 las 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 para realizar pruebas.

Para poder seguir estos pasos, tu cuenta de usuario debe tener la función de creador de tokens de cuentas 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 de la época, que se puede recuperar si ejecutas date +%s en la terminal. La propiedad exp es la hora de vencimiento en segundos después de la época, que se puede calcular si agregas 3,600 a iat. La fecha de vencimiento no puede ser de 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 siguiente comando 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 debería 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 la lista de vehículos:

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

Vehículos y su ciclo de vida

El vehículo es la entidad que representa un par conductor y vehículo. Actualmente, no se puede hacer un seguimiento de un Conductor y un Vehículo por separado. El proveedor de transporte compartido o de entrega 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 API de Fleet Engine) y un ID de vehículo que pertenezca al proveedor de transporte compartido o entrega.

Los vehículos que no se actualicen mediante UpdateVehicle después de siete días se borrarán automáticamente. Es un error llamar 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: con frecuencia llamando a CreateVehicle con un par de ID de proveedor o ID de vehículo esperado y descartando el error si el vehículo ya existe, o llamar a CreateVehicle después de que UpdateVehicle muestra un error NOT_FOUND.

Actualizaciones de ubicación de vehículos

Para obtener el mejor rendimiento con Fleet Engine, proporciónale un flujo de actualizaciones de la ubicación del vehículo. Usa cualquiera de las siguientes formas para proporcionar estas actualizaciones:

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

Tipos de vehículos

La entidad Vehículo contiene 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 criterio de filtro en SearchVehicles y ListVehicles.

Todas las rutas para vehículos usarán el RouteTravelMode correspondiente si la categoría se establece en AUTO, TWO_WHEELER, BICYCLE o PEDESTRIAN. Si la categoría se establece como 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 las Vehicles coincidentes contengan todos los atributos incluidos establecidos en el valor especificado.

Ten en cuenta que el campo de atributo se suma a muchos 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 los alcanza. Fleet Engine calcula este campo a medida que se asignan viajes al vehículo y lo actualiza a medida que cambian de estado. Estos puntos de referencia se pueden identificar mediante los campos TripId y WaypointType.

Cómo expandir la elegibilidad de un vehículo para buscar coincidencias

Por lo general, los servicios de transporte compartido o proveedor de servicios de transporte son responsables de hacer coincidir las solicitudes de viaje con los vehículos. El servicio puede usar los atributos de vehículo para incluir un vehículo en una mayor cantidad de búsquedas. Por ejemplo, el proveedor puede implementar un conjunto de atributos correspondientes a los niveles de beneficios o capacidades que proporciona un vehículo. Por ejemplo, tres niveles pueden 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 de 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 usas esta API, el conjunto completo de Atributos de vehículos se establece en el valor. No se puede actualizar un solo atributo. El otro método es la API de UpdateVehicleAttributes. Este método toma solo 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.

CÓMO: crear un vehículo

Se debe crear una entidad Vehicle para cada vehículo que se realice en la flota.

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

El provider_id de Vehicle debe ser el ID del proyecto (p.ej., mi proyecto-on demand) 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, Fleet Engine no admite actualmente cuentas de servicio de varios proyectos de Google Cloud que acceden al mismo Vehicles.

El Vehicle se puede crear en el estado OFFLINE o ONLINE. Si se crea ONLINE, se puede mostrar de inmediato en respuesta a las consultas de 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 los tipos de vehículo para obtener detalles acerca del campo de tipo de vehículo.

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

La API de Fleet Engine escribe una entrada de registro a través de los registros de la plataforma de Google Cloud 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 ejecuta correctamente, también se incluirá información sobre el 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"
'

Debes mostrar 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 se indican aquí.

Instructivo: Actualiza 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 la ubicación del vehículo. Para cualquier vehículo activo, Fleet Engine espera una actualización de la ubicación al menos una vez por minuto y una vez cada 5 segundos como máximo. Estas actualizaciones solo requieren privilegios de usuario del SDK de Fleet Engine Driver.

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

Instructivo: Actualiza otros campos de vehículos

Las actualizaciones de otros atributos del estado del vehículo ocurren con menos frecuencia que las de posición. Las actualizaciones de 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 el que se indica 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 que se conservarán. 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 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 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 la plataforma de Google Cloud 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 ejecuta correctamente, también se incluirá información sobre el 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 se indican 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 que se ajustan mejor a una tarea, como el servicio de un viaje o una solicitud de entrega. La API de SearchVehicles muestra una lista clasificada de conductores que coinciden los atributos de la tarea con los atributos de los vehículos de tu flota. Para obtener más información, consulta Cómo buscar conductores cercanos.

Ejemplo

Cuando se buscan vehículos disponibles, Fleet Engine excluye vehículos en viajes activos de forma predeterminada. Los servicios del proveedor de transporte compartido o de transporte 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 Grand Indonesia East Mall hasta el Balai Sidang Yakarta Convention Center.

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 ejecute 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 mostrar, al menos, 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 sobre el filtrado de vehículos

SearchVehicles y ListVehicles admiten el filtrado en atributos de vehículos mediante una búsqueda de filtro. Para ver ejemplos sobre la sintaxis de la consulta de filtros, consulta AIP-160.

Ten en cuenta que las consultas de filtro SOLO admiten el filtrado por atributos de vehículos 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: Genera una lista de vehículos

SearchVehicles está optimizado para encontrar una pequeña cantidad de vehículos en orden clasificado de forma muy rápida y se usa principalmente para encontrar conductores cercanos que sean más adecuados para una tarea. Sin embargo, en ocasiones, es necesario buscar 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 filtran vehicle_type y atributos que usan la 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

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

Los viajes y su ciclo de vida

La API de Trip y su ciclo de vida son similares a los de la API y el ciclo de vida de los vehículos. El proveedor de transporte compartido es responsable de crear viajes mediante 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 actualización.

Un elemento Trip tiene un campo de estado para realizar un seguimiento de su progreso en el ciclo de vida. Los valores se mueven 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 tu 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 el servicio intenta crear un viaje con un ID que ya existe, se mostrará un error. Un viaje se considera "activo" si su estado no es COMPLETE ni CANCELED. Esta distinción es importante en el campo active_trips de la entidad Vehículo y SearchTripsRequest.

El servicio solo puede cambiar el 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 cambiar o borrar vehicle_id.

El estado es importante cuando se implementa la compatibilidad de viaje consecutiva. Esta compatibilidad permite al Proveedor asignar un viaje nuevo a un Vehículo mientras este está en un Viaje activo. El código para crear un viaje seguido 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 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á viajar en orden antes del punto de bajada final de este 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 restante de puntos de referencia del vehículo cuando tripStatus(RPC | REST) se cambie de otro estado a ENROUTE_TO_XXX. Es decir, cuando el estado del viaje cambie 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. Sin embargo, cuando el estado del viaje cambie a ENROUTE_TO_INTERMEDIATE_DESTINATION o ENROUTE_TO_DROPOFF, su punto de partida se quitará del vehículo.

Esto es lo mismo para ARRIVED_AT_INTERMEDIATE_DESTINATION y ENROUTE_TO_INTERMDEDIATE_DESTINATION. Cuando 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 cambie a COMPLETED, no habrá puntos de referencia de este viaje en la lista restante de puntos de referencia del vehículo.

CÓMO crear un viaje

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

Se requieren los siguientes atributos para crear un viaje:

  • parent: Es una string que incluye el ID de proveedor que se generó cuando se creó el proyecto de Google Cloud.
  • trip_id: Es una string 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 una parte (EXCLUSIVE).
    • pickup_point: 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 number_of_passengers, dropoff_point y vehicle_id. Aunque estos campos no son obligatorios, se conservan si los proporcionas. Se ignoran 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 Grand Indonesia East Mall. El viaje es para dos pasajeros y es exclusivo. El provider_id del 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 el 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 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 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 realiza correctamente, también se incluirá información sobre el Trip que se mostró.

PROCEDIMIENTO: Cómo actualizar un viaje

La entidad Viaje 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 del consumidor. Para actualizar las propiedades, usa el mensaje UpdateTripRequest. Esto actualiza los campos de Trip 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 de forma automática los siguientes campos cuando se usa la función de viaje compartido a través del 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 Trip que se mostró.

CÓMO: buscar viajes

Fleet Engine admite la búsqueda de viajes. Como se indicó anteriormente, un Viaje se borra 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, en la siguiente lista, se consideran 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.

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

Para usar SearchTrips de esta manera, deja vehicle_id vacío, establece active_trips_only en true y establece minimum_staleness en una hora mayor que la duración de la mayoría de los viajes. Por ejemplo, puedes usar una hora. Los resultados incluyen Viajes que no están COMPLETOS ni CANCELADOS, 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 201 (CREATED) o 409 (CONFLICT). En el último caso, la solicitud anterior se realizó correctamente antes de 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 de SHARED a un vehículo que admite TripType.SHARED. Debes especificar el orden de todos los puntos de referencia no pasados para todos los Viajes asignados al vehículo en este viaje compartido mediante Trip.vehicle_waypoints cuando asignes 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

El campo intermediateDestinations y el campo intermediateDestinationIndex de Trip (RPC | REST) se combinan para indicar el destino.

Actualizar destino intermedio

Puedes actualizar los destinos intermedios mediante UpdateTrip. Cuando actualizas destinos intermedios, debes proporcionar una lista completa de destinos intermedios, incluidos los que se visitaron, no solo el que se agregó o se modificará. Cuando intermediateDestinationIndex apunta a un índice después de la posición del destino intermedio agregado o modificado recientemente, el destino intermedio nuevo o actualizado no se agregará al waypoints del vehículo ni al remainingWaypoints del viaje. Esto se debe a que cualquier destino intermedio antes de 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 del estado de viaje que se envía a Fleet Engine para indicar que ya pasó un destino intermedio. 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 el destino intermedio que 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 que se dirija a su primer destino intermedio, siempre y cuando hayas creado un viaje con varios destinos y que este haya pasado 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 a fin de publicar notificaciones sobre el tema creado por el proyecto de Google Cloud para consumidores. 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 crea el tema, deberás otorgar a la API de Fleet Engine permiso 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 quieres 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 para cada notificación se denota en los atributos de PubsubMessage con la clave como data_format y el valor como protobuf o json.

Esquema de notificación:

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