Premiers pas avec Fleet Engine

L'API On-demand Rides and Deliveries Fleet Engine vous permet de gérer les trajets et l'état des véhicules pour vos applications Trip and Order Progress. Il gère les transactions entre le SDK Driver, le SDK Consumer et votre service de backend, qui peut communiquer avec Fleet Engine via des appels gRPC ou REST.

Prérequis

Pour le développement, assurez-vous d'installer le SDK Cloud (gcloud) et d'être authentifié auprès de votre projet.

shell

gcloud auth login

Un message indiquant que l'opération a réussi devrait s'afficher:

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

Vérifiez que les API Fleet Engine de la solution On-demand Rides and Deliveries sont correctement configurées.

shell

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

Si cette commande génère une erreur, contactez votre administrateur de projet et votre représentant de l'assistance Google pour obtenir l'accès.

Journalisation

Fleet Engine peut écrire des messages de journal concernant les appels d'API reçus dans les journaux Google Cloud Platform. Consultez la documentation de Cloud Logging pour découvrir comment lire et analyser les journaux.

Il est possible que la journalisation ne soit pas activée par défaut pour les projets créés avant le 10 février 2022. Pour en savoir plus, consultez la documentation sur la journalisation.

Bibliothèques clientes

Nous publions des bibliothèques clientes dans plusieurs langages de programmation courants. Ces bibliothèques permettent d'offrir une meilleure expérience de développement par rapport aux bibliothèques REST ou gRPC brutes. Pour savoir comment obtenir des bibliothèques clientes pour votre application de serveur, consultez la section Bibliothèques clientes.

Les exemples Java de cette documentation supposent une bonne connaissance de gRPC.

Authentification et autorisation

Vous pouvez configurer les fonctionnalités fournies par "Trip and Order Progress" via la console Google Cloud. Ces API et SDK nécessitent l'utilisation de jetons Web JSON qui ont été signés à l'aide de comptes de service créés à partir de Cloud Console.

Configurer un projet Cloud

Pour configurer votre projet cloud, commencez par créer votre projet, puis créez des comptes de service.

Pour créer votre projet Google Cloud, procédez comme suit:

  1. Créer un projet Google Cloud à l'aide de la console Google Cloud
  2. À l'aide du tableau de bord des API et des services, activez l'API Local Rides and Deliveries.

Les comptes de service sont associés à un ou plusieurs rôles. Ils permettent de créer des jetons Web JSON qui accordent différents ensembles d'autorisations en fonction des rôles. En règle générale, pour réduire le risque d'abus, vous pouvez créer plusieurs comptes de service, chacun avec l'ensemble minimal de rôles requis.

L'outil Trip and Order Progress utilise les rôles suivants:

RôleDescription
Utilisateur du SDK client Fleet Engine

roles/fleetengine.consumerSdkUser
Permet de rechercher des véhicules et de récupérer des informations sur les véhicules et les trajets. Les jetons créés par un compte de service doté de ce rôle sont généralement utilisés à partir des appareils mobiles de votre application de partage de course ou de livraison grand public.
Utilisateur du SDK pilote Fleet Engine

roles/fleetengine.driverSdkUser
Permet de mettre à jour l'emplacement et les itinéraires des véhicules, et de récupérer des informations sur ces derniers et les trajets. Les jetons créés par un compte de service avec ce rôle sont généralement utilisés à partir des appareils mobiles de votre application de partage de course ou de chauffeur-livreur.
Super-utilisateur du service Fleet Engine

roles/fleetengine.serviceSuperUser
Accorde l'autorisation d'accéder à tous les véhicules et à toutes les API trips. Les jetons créés par un compte de service doté de ce rôle sont généralement utilisés à partir de vos serveurs backend.

Par exemple, créez un compte de service pour chacun des trois rôles et attribuez-leur leurs rôles respectifs.

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

Les SDK pilote et client s'articulent autour de ces rôles standards.

Il est également possible de créer des rôles personnalisés permettant de regrouper un ensemble arbitraire d'autorisations. Les SDK pilote et grand public affichent des messages d'erreur lorsqu'une autorisation requise est manquante. Par conséquent, nous vous recommandons vivement d'utiliser l'ensemble de rôles standard présenté ci-dessus et non les rôles personnalisés.

Pour plus de commodité, si vous devez créer des jetons JWT pour des clients non approuvés, l'ajout d'utilisateurs au rôle Créateur de jetons du compte de service leur permet de créer des jetons avec les outils de ligne de commande gcloud.

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

my-user@example.com est l'adresse e-mail utilisée pour l'authentification avec gcloud (gcloud auth list --format='value(account)').

Bibliothèque d'authentifications Fleet Engine

Fleet Engine utilise des jetons Web JSON (JWT) pour limiter l'accès aux API Fleet Engine. La nouvelle bibliothèque d'authentification Fleet Engine, disponible sur GitHub, simplifie la construction des jetons JWT Fleet Engine et les signe de manière sécurisée.

Elle offre les avantages suivants:

  • Simplifie le processus de création de jetons Fleet Engine.
  • Fournit des mécanismes de signature de jetons autres que l'utilisation de fichiers d'identifiants (par exemple, l'emprunt d'identité d'un compte de service).
  • Associe des jetons signés aux requêtes sortantes effectuées à partir d'un bouchon gRPC ou d'un client GAPIC.

Créer un jeton Web JSON (JWT) pour l'autorisation

Lorsque vous n'utilisez pas la bibliothèque d'authentification Fleet Engine, les jetons Web JSON (JWT) doivent être créés directement dans votre codebase. Pour cela, vous devez bien comprendre les jetons JWT et leur lien avec Fleet Engine. C'est pourquoi nous vous recommandons vivement de tirer parti de la bibliothèque d'authentification Fleet Engine.

Dans Fleet Engine, les jetons Web JSON (JWT) fournissent une authentification de courte durée et garantissent que les appareils ne peuvent modifier que les véhicules, les trajets ou les tâches pour lesquels ils sont autorisés. Les jetons JWT contiennent un en-tête et une section de revendication. La section d'en-tête contient des informations telles que la clé privée à utiliser (obtenue auprès des comptes de service) et l'algorithme de chiffrement. La section de revendication contient des informations telles que la date et l'heure de création du jeton, sa valeur TTL, les services auxquels il demande l'accès et d'autres informations d'autorisation permettant de limiter l'accès (par exemple, l'ID du véhicule).

Une section d'en-tête JWT contient les champs suivants:

ChampDescription
alg Algorithme à utiliser. "RS256".
typ Type de jeton. "JWT".
enfant ID de la clé privée de votre compte de service. Vous trouverez cette valeur dans le champ "private_key_id" du fichier JSON de votre compte de service. Veillez à utiliser une clé provenant d'un compte de service disposant des autorisations appropriées.

Une section des revendications JWT contient les champs suivants:

ChampDescription
iss Adresse e-mail de votre compte de service.
sub Adresse e-mail de votre compte de service.
aud le nom de service (SERVICE_NAME) de votre compte de service (ici, https://fleetengine.googleapis.com/) ;
iat Horodatage de la création du jeton, spécifié en secondes écoulées depuis le 1er janvier 1970 à 00:00:00 UTC. Prévoyez 10 minutes pour le décalage. Si l'horodatage est trop éloigné dans le passé ou futur, le serveur peut signaler une erreur.
exp Code temporel d'expiration du jeton, spécifié en secondes écoulées depuis le 1er janvier 1970 à 00:00:00 UTC. La requête échoue si l'horodatage est postérieur à plus d'une heure.
autorisation Selon le cas d'utilisation, peut contenir "vehicleid" ou "tripid".

La création d'un jeton JWT correspond à sa signature. Pour obtenir des instructions et des exemples de code pour la création et la signature du jeton JWT, consultez la section Autorisation de compte de service sans OAuth. Vous pouvez ensuite associer un jeton signé aux appels gRPC ou à d'autres méthodes utilisées pour accéder à Fleet Engine.

Revendications JWT

Lors de la création de la charge utile JWT, ajoutez une revendication supplémentaire dans la section d'autorisation avec la clé vehicleid ou tripid définie sur la valeur de l'ID du véhicule ou de l'ID de trajet pour lequel l'appel est effectué.

Le SDK Driver utilise toujours la revendication vehicleid, qu'il s'agisse d'un trajet ou d'un véhicule. Le backend Fleet Engine s'assure que le véhicule est associé au trajet demandé avant d'effectuer la modification.

Le SDK grand public utilise toujours la revendication tripid.

Le fournisseur de courses en VTC ou de livraison doit utiliser l'attribut vehicleid ou tripid avec un "*" pour correspondre à tous les véhicules et à tous les trajets. Notez que le jeton JWT peut contenir les deux jetons, même s'ils ne sont pas requis, ce qui peut simplifier l'implémentation de la signature des jetons.

Cas d'utilisation des jetons JWT

Voici un exemple de jeton pour le serveur du fournisseur:

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

Voici un exemple de jeton pour l'application consommateur:

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

Voici un exemple de jeton pour l'application de pilote:

{
  "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"
   }
}
  • Dans le champ kid de l'en-tête, spécifiez l'ID de clé privée de votre compte de service. Vous trouverez cette valeur dans le champ private_key_id du fichier JSON de votre compte de service.
  • Dans les champs iss et sub, indiquez l'adresse e-mail de votre compte de service. Vous trouverez cette valeur dans le champ client_email du fichier JSON de votre compte de service.
  • Dans le champ aud, spécifiez https://SERVICE_NAME/.
  • Pour le champ iat, utilisez l'horodatage de la création du jeton, spécifié en secondes écoulées depuis le 1er janvier 1970 à 00:00:00 UTC. Prévoyez 10 minutes pour le décalage. Si le code temporel est trop ancien ou se situe dans le futur, le serveur peut signaler une erreur.
  • Pour le champ exp, utilisez l'horodatage de l'expiration du jeton, spécifié en secondes depuis le 1er janvier 1970 à 00:00:00 UTC. La valeur maximale autorisée est iat + 3 600.

Lorsque vous signez le jeton JWT à transmettre à un appareil mobile, veillez à utiliser le compte de service pour le rôle SDK pilote ou client. Sinon, l'appareil mobile pourra modifier l'état qu'il ne devrait pas avoir.

De même, lorsque vous signez le JWT à utiliser pour les appels privilégiés, veillez à utiliser le compte de service avec le rôle de super-utilisateur. Sinon, l'opération échouera.

Générer un jeton JWT pour les tests

La génération de jetons à partir du terminal peut être utile lors des tests.

Pour que vous puissiez suivre ces étapes, votre compte utilisateur doit disposer du rôle Créateur de jetons du compte de service:

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

Créez un fichier nommé unsigned_token.json avec le contenu ci-dessous. La propriété iat correspond à l'heure actuelle exprimée en nombre de secondes après l'epoch. Vous pouvez la récupérer en exécutant date +%s dans votre terminal. La propriété exp correspond au délai d'expiration en secondes après l'epoch, qui peut être calculé en ajoutant 3 600 à iat. La date/heure d'expiration ne peut pas être fixée à plus d'une heure dans le futur.

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

Exécutez ensuite la commande gcloud suivante pour signer le jeton au nom de votre compte de service de super-utilisateur:

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

Un jeton JWT signé en base64 doit maintenant être stocké dans le fichier signed_token.jwt. Le jeton est valide pendant l'heure suivante.

Vous pouvez maintenant tester le jeton en exécutant une commande curl sur le point de terminaison REST Lister les véhicules:

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

Véhicules et cycle de vie

Le véhicule est l'entité représentant un couple conducteur/véhicule. Actuellement, le conducteur et le véhicule ne peuvent pas être suivis séparément. Le fournisseur de courses en VTC crée un véhicule à l'aide d'un ID de fournisseur (qui doit être identique à l'ID du projet Google Cloud contenant le compte de service utilisé pour appeler les API Fleet Engine) et d'un ID de véhicule appartenant au fournisseur de courses ou de livraison.

Un véhicule qui n'a pas été mis à jour via UpdateVehicle après sept jours sera automatiquement supprimé. Une erreur s'est produite lors de l'appel de CreateVehicle avec une paire ID de fournisseur/ID de véhicule existante. Le cas de véhicules qui ne sont pas mis à jour fréquemment peut être géré de deux manières: appeler fréquemment CreateVehicle avec une paire ID de fournisseur/ID de véhicule attendue et supprimer l'erreur si le véhicule existe déjà ; ou appeler CreateVehicle après qu'une UpdateVehicle renvoie une erreur NOT_FOUND.

Mises à jour de la position des véhicules

Pour optimiser les performances avec Fleet Engine, fournissez-lui un flux de mises à jour de la position des véhicules. Pour fournir ces mises à jour, procédez de l'une des façons suivantes:

  1. Utilisez l'option la plus simple pour le SDK Driver (Android, iOS).
  2. Utilisez du code personnalisé. Cette option est utile si les emplacements sont transmis via votre backend, ou si vous utilisez des appareils autres qu'Android ou iOS.

Type de véhicule

L'entité Vehicle contient un champ obligatoire VehicleType, qui contient une énumération Category pouvant être spécifiée en tant que AUTO, TAXI, TRUCK, TWO_WHEELER, BICYCLE ou PEDESTRIAN. Le type de véhicule peut servir de critère de filtre dans SearchVehicles et ListVehicles.

Tous les itinéraires des véhicules utiliseront le RouteTravelMode correspondant si la catégorie est définie sur AUTO, TWO_WHEELER, BICYCLE ou PEDESTRIAN. Si la catégorie est définie sur TAXI ou TRUCK, le routage est traité de la même manière que le mode AUTO.

Attributs du véhicule

L'entité "Véhicule" contient un champ répété de VehicleAttribute. Ces attributs ne sont pas interprétés par Fleet Engine. L'API SearchVehicles inclut un champ qui exige que le Vehicles correspondant contienne tous les attributs inclus définis sur la valeur spécifiée.

Notez que le champ d'attribut s'ajoute à plusieurs autres champs compatibles dans le message Vehicle, tels que vehicle_type et supported_trip_types.

Points de cheminement restants du véhicule

L'entité Vehicle contient un champ répété de TripWaypoint (RPC | REST), appelé waypoints(RPC | REST). Ce champ inclut les points de cheminement restants des trajets, dans l'ordre dans lequel le véhicule les atteint. Fleet Engine calcule ce champ à mesure que les trajets sont attribués au véhicule, et le met à jour à mesure que les trajets changent d'état. Ces points de cheminement peuvent être identifiés grâce aux champs TripId et WaypointType.

Élargir l'éligibilité d'un véhicule aux correspondances

En règle générale, les services de partage de course ou de fournisseur de livraison sont responsables de la mise en correspondance des demandes de trajet avec les véhicules. Le service peut utiliser les attributs du véhicule pour l'inclure dans un plus grand nombre de recherches. Par exemple, le fournisseur peut implémenter un ensemble d'attributs correspondant aux niveaux d'avantages ou de capacités offerts par un véhicule. Par exemple, trois niveaux peuvent être un ensemble d'attributs avec des valeurs booléennes: is_bronze_level, is_silver_level et is_gold_level. Un véhicule peut être éligible à ces trois produits. Lorsque Fleet Engine reçoit une requête pour un trajet nécessitant des capacités de niveau Argent, la recherche inclut ce véhicule. Cette manière d'utiliser des attributs inclut les véhicules offrant des capacités diverses.

Il existe deux façons de mettre à jour les attributs du véhicule. L'une d'elles est l'API UpdateVehicle. Lorsque vous utilisez cette API, l'ensemble des attributs du véhicule est défini sur cette valeur. Il n'est pas possible de mettre à jour un seul attribut. L'autre méthode est l'API UpdateVehicleAttributes. Cette méthode ne nécessite que les attributs à mettre à jour. Les attributs inclus dans la requête seront définis sur la nouvelle valeur ou ajoutés. Les attributs non spécifiés ne seront pas modifiés.

PROCÉDURE: Créer un véhicule

Une entité Vehicle doit être créée pour chaque véhicule à suivre dans le parc.

Utilisez le point de terminaison CreateVehicle avec CreateVehicleRequest pour créer un véhicule.

Le provider_id de Vehicle doit être l'ID du projet Google Cloud (par exemple, my-on-demand-project) contenant les comptes de service qui seront utilisés pour appeler Fleet Engine. Notez que même si plusieurs comptes de service peuvent accéder à Fleet Engine pour le même fournisseur de services de covoiturage ou de livraison, Fleet Engine n'est actuellement pas compatible avec les comptes de service de plusieurs projets Google Cloud accédant au même Vehicles.

Le Vehicle peut être créé à l'état OFFLINE ou ONLINE. Si vous créez une valeur ONLINE, elle peut être immédiatement renvoyée en réponse aux requêtes SearchVehicles.

Un last_location initial peut être inclus dans l'appel CreateVehicle. Bien que cela soit autorisé, un Vehicle ne doit pas être créé à l'état ONLINE sans last_location.

Consultez la section Types de véhicules pour en savoir plus sur le champ "Type de véhicule".

Consultez la page Attributs du véhicule pour en savoir plus sur les champs d'attributs.

La valeur renvoyée par CreateVehicle est l'entité Vehicle créée.

Exemple

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

Consultez la documentation de référence sur 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.

Journaux Google Cloud Platform pour la création de véhicules

L'API Fleet Engine écrit une entrée de journal via les journaux Google Cloud Platform lorsqu'un appel au point de terminaison CreateVehicle est reçu. L'entrée de journal inclut des informations sur les valeurs de la requête CreateVehicle. Si l'appel aboutit, il inclut également des informations sur le Vehicle qui a été renvoyé.

shell

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

Un enregistrement semblable à celui-ci doit s'afficher:

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

Notifications Cloud Pub/Sub pour la création de véhicules

L'API Fleet Engine publie une notification via Cloud Pub/Sub lors de la création d'un véhicule. Pour recevoir ces notifications, veuillez suivre ces instructions.

PROCÉDURE: Mettre à jour la position d'un véhicule

Si vous n'utilisez pas le SDK Driver pour mettre à jour l'emplacement du véhicule, vous pouvez appeler directement Fleet Engine en indiquant sa position. Pour tout véhicule actif, Fleet Engine s'attend à une mise à jour de la position au moins une fois toutes les minutes et au maximum une fois toutes les cinq secondes. Ces mises à jour ne nécessitent que les droits d'utilisateur du SDK pilote Fleet Engine.

Exemple

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

Consultez la documentation de référence sur 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.

PROCÉDURE: Mettre à jour d'autres champs relatifs au véhicule

Les mises à jour des autres attributs de l'état du véhicule sont moins fréquentes que celles des positions. Les mises à jour d'attributs autres que last_location nécessitent les droits de super-utilisateur Fleet Engine.

UpdateVehicleRequest inclut une update_mask pour indiquer les champs à mettre à jour. Le comportement du champ est identique à celui décrit dans la documentation Protobuf pour les masques de champ.

Comme indiqué dans Attributs du véhicule, la mise à jour du champ attributes nécessite d'écrire tous les attributs à conserver. Il n'est pas possible de simplement mettre à jour la valeur d'une paire clé-valeur dans un appel UpdateVehicle. Pour mettre à jour les valeurs d'attributs spécifiques, vous pouvez utiliser l'API UpdateVehicleAttributes.

Exemple

Cet exemple active 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

Consultez la documentation de référence sur 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.

Journaux Google Cloud Platform pour les mises à jour des véhicules

L'API Fleet Engine écrit une entrée de journal via les journaux Google Cloud Platform lorsqu'un appel au point de terminaison UpdateVehicle est reçu. L'entrée de journal inclut des informations sur les valeurs de la requête UpdateVehicle. Si l'appel aboutit, il inclut également des informations sur le Vehicle qui a été renvoyé.

shell

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

Notifications Cloud Pub/Sub pour les mises à jour de véhicules

L'API Fleet Engine publie une notification via Cloud Pub/Sub lorsqu'un véhicule existant est mis à jour. Pour recevoir ces notifications, veuillez suivre ces instructions.

Tutoriel: Rechercher des véhicules

Fleet Engine prend en charge la recherche de véhicules. L'API SearchVehicles vous permet de trouver les chauffeurs disponibles à proximité les mieux adaptés à une tâche, comme le traitement d'un trajet ou d'une demande de livraison. L'API SearchVehicles renvoie une liste classée de conducteurs correspondant aux attributs de tâche à ceux des véhicules de votre parc. Pour en savoir plus, consultez la section Rechercher des conducteurs à proximité.

Exemple

Lorsque vous recherchez des véhicules disponibles, Fleet Engine exclut par défaut les véhicules effectuant des trajets actifs. Les services du fournisseur de courses en VTC ou du fournisseur de livraison doivent les inclure explicitement dans les requêtes de recherche. L'exemple suivant montre comment inclure ces véhicules dans une recherche de véhicules correspondant à un trajet entre le Grand Indonesia East Mall et le Balai Sidang Jakarta Convention Center.

shell

Commencez par modifier l'emplacement du véhicule que nous avons créé aux étapes précédentes afin qu'il soit éligible. En situation réelle, cette opération serait effectuée par le SDK Driver exécuté sur un appareil Android ou iOS du véhicule.

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 recherche doit permettre de trouver au moins ce véhicule.

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

Consultez la documentation de référence sur 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;
}

Requête de filtrage des véhicules

SearchVehicles et ListVehicles acceptent le filtrage des attributs du véhicule à l'aide d'une requête de filtre. Pour connaître la syntaxe des requêtes de filtre, consultez la section AIP-160 pour obtenir des exemples.

Notez que les requêtes de filtre ne prennent en charge QUE le filtrage sur les attributs du véhicule et ne peuvent pas être utilisées pour d'autres champs. La requête de filtre fonctionne comme une clause AND avec d'autres contraintes, telles que minimum_capacity ou vehicle_types dans SearchVehiclesRequest.

Tutoriel: Lister les véhicules

SearchVehicles est optimisé pour trouver très rapidement un petit nombre de véhicules classés par ordre. Il est principalement utilisé pour trouver les conducteurs à proximité les mieux aptes à effectuer une tâche. Cependant, vous pouvez parfois rechercher tous les véhicules qui répondent à certains critères, même si une pagination des résultats est nécessaire. ListVehicles est conçu pour ce cas d'utilisation.

L'API ListVehicles vous permet de rechercher tous les véhicules qui répondent à certaines options de requête spécifiques. L'API ListVehicles renvoie une liste paginée des véhicules du projet qui répond à certaines exigences.

Pour filtrer les données en fonction des attributs des véhicules, consultez la section Requête de filtrage des véhicules.

Exemple

Cet exemple effectue un filtrage sur vehicle_type et les attributs à l'aide de la chaîne 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

Consultez la documentation de référence sur 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;
}

Voyages et leur cycle de vie

L'API Trip et son cycle de vie sont semblables à ceux de Vehicle. Le fournisseur de courses en VTC est responsable de la création de trajets à l'aide des interfaces Fleet Engine. Fleet Engine fournit à la fois un service RPC, TripService, et des ressources REST, provider.trips. Ces interfaces permettent de créer des entités de trajet, de demander des informations, ainsi que de rechercher et de mettre à jour des entités.

Un Trip comporte un champ d'état pour suivre sa progression tout au long du cycle de vie. Les valeurs passent de NEW à COMPLETE, plus CANCELED et UNKNOWN_TRIP_STATUS. Reportez-vous à trip_status pour RPC ou à TripStatus pour REST.

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

Votre service peut mettre à jour le trajet vers CANCELED à partir de n'importe lequel de ces états. Lorsque votre service crée un trajet, le moteur définit l'état sur NEW. Un vehicle_id est facultatif. Comme pour les véhicules, les services suppriment automatiquement les trajets au bout de sept jours sans mise à jour. Si votre service tente de créer un trajet avec un identifiant qui existe déjà, une erreur est renvoyée. Un trajet est considéré comme "actif" s'il a un état autre que COMPLETE ou CANCELED. Cette distinction est importante dans le champ active_trips de l'entité Véhicule et dans SearchTripsRequest.

Le service ne peut modifier le vehicle_id attribué à un trajet que lorsque l'état est NEW ou CANCELED. Si un Conducteur annule un trajet au cours du trajet, l'état du trajet doit être défini sur NEW ou CANCELED avant que le vehicle_id ne soit modifié ou effacé.

L'état est important lors de la mise en œuvre de la prise en charge des trajets aller-retour. Cette prise en charge permet au fournisseur d'attribuer un nouveau trajet à un véhicule lorsque celui-ci est sur un trajet actif. Le code permettant de créer un trajet aller-retour est identique à un trajet unique et utilise le même ID de véhicule. Fleet Engine ajoute le point de départ et la destination du nouveau trajet aux points de cheminement du véhicule. Pour plus d'informations sur les trajets aller-retour, consultez la page Créer des trajets à plusieurs points de cheminement.

Points de cheminement restants du trajet

L'entité "Trip" contient un champ répété TripWaypoint (RPC | REST), appelé remainingWaypoints(RPC | REST). Ce champ inclut tous les points de cheminement que le véhicule devra parcourir dans l'ordre avant le point de dépôt final de ce trajet. Le calcul est effectué à partir des points de cheminement restants du véhicule. Pour les cas d'utilisation "Sans restriction" et "Carpool", cette liste contient les points de cheminement d'autres trajets qui seront empruntés avant celui-ci, à l'exception des points ultérieurs. Le point de cheminement de la liste peut être identifié à l'aide de son TripId et de son WaypointType.

Relation entre l'état du trajet et les points de cheminement restants du véhicule

Les points de cheminement restants du véhicule (RPC | REST) sont mis à jour lorsque Fleet Engine reçoit une requête de modification de l'état du trajet. Le point de cheminement précédent sera supprimé de la liste des points de cheminement restants du véhicule lorsque tripStatus(RPC | REST) passe d'un autre état à ENROUTE_TO_XXX. Autrement dit, si l'état du trajet passe de ENROUTE_TO_PICKUP à ARRIVED_AT_PICKUP, le point de prise en charge du trajet reste dans la liste des points de cheminement restants du véhicule, mais lorsque l'état du trajet passe à ENROUTE_TO_INTERMEDIATE_DESTINATION ou ENROUTE_TO_DROPOFF, son point de prise en charge est supprimé des points de départ restants du véhicule.

Il en va de même pour ARRIVED_AT_INTERMEDIATE_DESTINATION et ENROUTE_TO_INTERMDEDIATE_DESTINATION. Lorsque ARRIVED_AT_INTERMEDIATE_DESTINATION, la destination intermédiaire actuelle n'est pas supprimée de la liste des points de cheminement restants du véhicule tant que celui-ci n'a pas signalé qu'il s'est arrêté au prochain point de cheminement.

Lorsque l'état du trajet est défini sur COMPLETED, aucun point de cheminement de ce trajet ne figure dans la liste des points de cheminement restants du véhicule.

PROCÉDURE: Créer un voyage

Une entité Trip doit être créée pour que chaque demande de trajet soit suivie et associée aux véhicules du parc. Utilisez le point de terminaison CreateTrip avec CreateTripRequest pour créer un trajet.

Les attributs suivants sont obligatoires pour créer un trajet:

  • parent : chaîne qui inclut l'ID du fournisseur créé lors de la création du projet Google Cloud.
  • trip_id : chaîne créée par le fournisseur de courses en VTC.
  • trip : conteneur avec des métadonnées de base décrivant le trajet.
    • trip_type : énumération indiquant si le trajet peut accueillir d'autres usagers du même véhicule (SHARED) ou d'un seul groupe (EXCLUSIVE) pour des points de départ et d'arrivée différents.
    • pickup_point : TerminalLocation représentant le point de départ du trajet. Reportez-vous à la documentation de référence sur RPC ou à la documentation de référence sur REST.

Lorsque vous créez un trajet, vous pouvez fournir les informations number_of_passengers, dropoff_point et vehicle_id. Bien que ces champs ne soient pas obligatoires, si vous les fournissez, ils sont conservés. Tous les autres champs "Trip" sont ignorés. Par exemple, tous les trajets commencent par un trip_status de NEW, même si vous transmettez un trip_status de CANCELED dans la requête de création.

Exemple

L'exemple suivant crée un trajet vers le centre commercial Grand Indonesia East Mall. Le trajet est réservé à deux passagers. La propriété provider_id de Trip doit être identique à l'ID du projet. Dans cet exemple, le fournisseur de courses en VTC a créé le projet Google Cloud, project-id. Ce projet doit disposer des comptes de service utilisés pour appeler Fleet Engine. L'état du trajet est NEW.

Plus tard, une fois que le service a mis en correspondance le trajet avec un véhicule, il peut appeler UpdateTrip et modifier le vehicle_id lorsque le trajet est attribué à un véhicule.

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

Consultez la documentation de référence sur 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;
}

Journaux Google Cloud Platform pour la création de trajets

L'API Fleet Engine écrit une entrée de journal à l'aide des journaux Google Cloud Platform lorsqu'un appel au point de terminaison CreateTrip est reçu. L'entrée de journal inclut des informations sur les valeurs de la requête CreateTrip. Si l'appel aboutit, il inclut également des informations sur le Trip qui a été renvoyé.

PROCÉDURE: Mettre à jour un trajet

L'entité "Trip" contient des champs qui permettent le suivi par le service et permettent de signaler la progression du trajet par le SDK Driver et par le SDK Consommateur. Pour mettre à jour les propriétés, utilisez le message UpdateTripRequest. Les champs "Trip" sont alors mis à jour en fonction du field_mask de la requête. Consultez UpdateTripRequest.

Le fournisseur de courses en VTC est chargé de mettre à jour les attributs suivants:

  • État du trajet.
  • ID du véhicule. Soit au moment de la création, soit après avoir associé le véhicule à un trajet.
  • les modifications apportées aux points de prise en charge, de dépose et de cheminement ;

Fleet Engine met automatiquement à jour les champs suivants lorsque vous utilisez la fonctionnalité de partage de parcours via le SDK Driver ou le SDK consommateur:

  • Routes
  • Heure d'arrivée prévue
  • Distance restante
  • Emplacement du véhicule
  • Points de cheminement restants

Reportez-vous à Trip dans RPC ou à Resource.Trip dans REST.

Journaux Google Cloud Platform pour les mises à jour de trajets

L'API Fleet Engine écrit une entrée de journal à l'aide des journaux Google Cloud Platform lorsqu'un appel au point de terminaison UpdateTrip est reçu. L'entrée de journal inclut des informations sur les valeurs de la requête UpdateTrip. Si l'appel aboutit, il inclut également des informations sur le Trip renvoyé.

CONSEILS: Recherchez des voyages

Fleet Engine prend en charge la recherche de trajets. Comme indiqué précédemment, un trajet est automatiquement supprimé au bout de sept jours. Par conséquent, SearchTrips n'expose pas l'historique complet de tous les trajets.

Bien que SearchTrips soit une API flexible, la liste ci-dessous prend en compte deux cas d'utilisation.

  • Déterminer les trajets actifs d'un véhicule : le fournisseur peut déterminer les trajets actuellement actifs d'un véhicule. Dans SearchTripsRequest, vehicle_id est défini sur le véhicule à l'étude, et active_trips_only doit être défini sur true.

  • Rapprochement de l'état du fournisseur et du moteur du parc : le fournisseur peut utiliser SearchTrips pour s'assurer que l'état de son trajet et celui de Fleet Engine correspondent. Ce point est particulièrement important pour TripStatus. Si l'état d'un trajet attribué à un véhicule n'est pas correctement défini sur COMPLETE ou CANCELED, le véhicule n'est pas inclus dans SearchVehicles.

Pour utiliser SearchTrips de cette manière, laissez vehicle_id vide, définissez active_trips_only sur true et minimum_staleness sur une durée supérieure à la plupart des durées de trajet. Par exemple, vous pouvez indiquer une heure. Les résultats incluent les trajets qui ne sont ni TERMINÉS ni ANNULÉS, et qui n'ont pas été mis à jour depuis plus d'une heure. Le fournisseur doit examiner ces trajets pour s'assurer que leur état dans Fleet Engine est correctement mis à jour.

Dépannage

Dans le cas d'une erreur DEADLINE_EXCEEDED, l'état du parc Fleet Engine est inconnu. Le fournisseur doit à nouveau appeler CreateTrip, qui renvoie un code 201 (CREATED) ou 409 (CONFLICT). Dans ce dernier cas, la requête précédente a abouti avant DEADLINE_EXCEEDED. Consultez les guides de l'API Consumer pour en savoir plus sur la gestion des erreurs de trajet: Android ou iOS.

Assistance pour les trajets Carpool

Vous pouvez attribuer plusieurs trajets SHARED à un véhicule compatible avec TripType.SHARED. Vous devez spécifier l'ordre de tous les points de cheminement non franchis pour tous les trajets attribués au véhicule dans ce trajet partagé via Trip.vehicle_waypoints lorsque vous attribuez vehicle_id à un trajet partagé (dans une requête CreateTrip ou UpdateTrip). Reportez-vous à vehicle_waypoints pour RPC ou à vehicleWaypoints pour REST.

Compatibilité avec plusieurs destinations

Identifier une destination intermédiaire

Les champs intermediateDestinations et intermediateDestinationIndex dans "Trip" (RPC | REST) sont combinés pour indiquer la destination.

Mettre à jour la destination intermédiaire

Vous pouvez mettre à jour les destinations intermédiaires via UpdateTrip. Lors de la mise à jour des destinations intermédiaires, vous devez fournir la liste complète des destinations intermédiaires, y compris celles qui ont été visitées, et pas seulement celles que vous venez d'ajouter ou à modifier. Lorsque intermediateDestinationIndex pointe vers un index après la position de la destination intermédiaire récemment ajoutée ou modifiée, la destination intermédiaire nouvelle ou mise à jour n'est pas ajoutée au waypoints du véhicule ni au remainingWaypoints du trajet. En effet, toutes les destinations intermédiaires avant intermediateDestinationIndex sont traitées comme déjà visitées.

Modifications de l'état des trajets

Le champ intermediateDestinationsVersion dans (RPC | REST) est obligatoire dans la requête de mise à jour de l'état du trajet envoyée à Fleet Engine pour indiquer qu'une destination intermédiaire est passée. La destination intermédiaire ciblée est spécifiée via le champ intermediateDestinationIndex. Lorsque tripStatus (RPC | REST) est ENROUTE_TO_INTERMEDIATE_DESTINATION, un nombre compris entre [0..N-1] indique la destination intermédiaire que le véhicule passera ensuite. Lorsque tripStatus correspond à ARRIVED_AT_INTERMEDIATE_DESTINATION, un nombre compris entre [0..N-1] indique la destination intermédiaire où se trouve le véhicule.

Exemple

L'exemple de code suivant montre comment mettre à jour l'état d'un trajet pour qu'il atteigne sa première destination intermédiaire, en supposant que vous avez créé un trajet multidestination et que ce trajet est passé à son point de départ.

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

Tutoriel: S'abonner aux messages de notification de l'API Fleet Engine

L'API Fleet Engine utilise Google Cloud Pub/Sub pour publier des notifications sur le sujet créé par le projet Google Cloud consommateur. Pub/Sub n'est pas activé par défaut pour Fleet Engine sur votre projet Google Cloud. Veuillez envoyer une demande d'assistance ou contacter votre ingénieur client pour activer Pub/Sub.

Pour créer un sujet dans votre projet Cloud, suivez ces instructions. L'ID du sujet doit être "fleet_engine_notifications".

Le sujet doit être créé dans le projet Cloud qui appelle les API Fleet Engine.

Une fois le sujet créé, vous devez autoriser l'API Fleet Engine à y publier des messages. Pour ce faire, cliquez sur le sujet que vous venez de créer et ajoutez une nouvelle autorisation. Vous devrez peut-être cliquer sur AFFICHER LE PANNEAU D'INFORMATIONS pour ouvrir l'éditeur d'autorisations. Le compte principal doit être geo-fleet-engine@system.gserviceaccount.com et le rôle Pub/Sub publisher.

Pour configurer votre projet Cloud afin de vous abonner aux notifications, suivez ces instructions.

L'API Fleet Engine publie chaque notification dans deux formats de données différents : protobuf et json. Le format de données de chaque notification est indiqué dans les attributs PubsubMessage avec la clé data_format et la valeur protobuf ou json.

Schéma de notification:

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