Premiers pas avec Fleet Engine pour le suivi des colis

Modélisez les activités de votre parc pour le premier et le dernier kilomètre de livraison avec l'API Fleet Engine Deliveries. Vous pouvez utiliser cette API à l'aide du SDK Driver pour Android et iOS, ou directement via des appels HTTP REST ou gRPC.

Configuration initiale

Vous configurez l'API Fleet Engine Deliveries dans la console Google Cloud.

Vérifier votre configuration

Après avoir créé les comptes de service, vérifiez que la configuration est terminée et que vous pouvez créer un véhicule de livraison. La validation immédiate de votre configuration vous permet de vous assurer que vous avez résolu les problèmes d'autorisation courants qui peuvent survenir lors de la configuration de votre projet. Il existe deux façons de vérifier votre configuration:

Bibliothèques clientes

Pour améliorer l'expérience développeur avec le protocole gRPC ou REST brut, utilisez les bibliothèques clientes dans plusieurs langages de programmation courants. Pour savoir comment obtenir des bibliothèques clientes pour votre application serveur, consultez la page Bibliothèques clientes.

Les exemples Java de cette documentation supposent que vous connaissez gRPC.

Structures de données

L'API Fleet Engine Deliveries utilise deux structures de données pour modéliser le retrait et la livraison des expéditions:

  • Véhicule de livraison utilisé pour transporter le colis.
  • Les tâches de retrait et de livraison des envois.

Les tâches permettent également de modéliser les pauses et les arrêts planifiés tout au long de la journée.

Véhicules de livraison

Les véhicules de livraison transportent les colis d'un dépôt à un lieu de livraison, et d'un lieu de retrait au dépôt. Dans certains cas, ils peuvent également transporter directement un colis du lieu de retrait jusqu'au lieu de livraison.

Utilisez le SDK Driver pour créer un objet DeliveryVehicle dans Fleet Engine, puis envoyer des mises à jour de position pour le suivi de l'expédition et de la flotte.

Tâches

Pour les actions effectuées par un véhicule au cours de la journée, vous attribuez des tâches en fonction du type d'action:

  • Pour les retraits et les livraisons, attribuez des tâches de livraison.
  • Pour les moments où les conducteurs sont indisponibles, comme les coupures obligatoires, attribuez des tâches d'indisponibilité.
  • Pour les tâches non liées à la conduite dans les boîtes de dépôt ou chez les clients, attribuez des tâches d'arrêt planifié.

Chaque tâche que vous attribuez doit avoir un ID de tâche unique, mais les tâches peuvent partager le même ID de suivi. Lorsque Fleet Engine calcule les périodes de l'heure d'arrivée prévue pour chaque tâche, il utilise toutes les tâches et l'ordre dans lequel elles sont planifiées pour effectuer des estimations. Pour en savoir plus sur les ID de tâche, consultez les consignes relatives aux ID de tâche.

Pour créer des tâches dans Fleet Engine, utilisez le gestionnaire de tâches du SDK pilote.

Tâches liées à l'expédition

Créez des tâches de livraison pour le retrait et la livraison d'un colis, et incluez les informations suivantes:

  • Lieu du retrait ou de la livraison.
  • Un numéro de suivi ou un identifiant
  • Temps d'interaction pour prendre en compte le temps supplémentaire nécessaire pour effectuer la tâche, rechercher une place de parking ou marcher jusqu'au lieu de transfert.
  • ID de tâche unique. Consultez les consignes relatives aux ID de tâche.

Pour plus d'informations, consultez les articles suivants :

Android

iOS

Tâches liées à l'indisponibilité

Les tâches d'indisponibilité couvrent les périodes pendant lesquelles un véhicule n'est pas disponible pour le retrait ou la livraison (par exemple, les pauses pour faire le plein du véhicule ou les pauses du conducteur).

Créez une tâche d'indisponibilité avec les informations suivantes:

  • Durée de la coupure.
  • L'emplacement de la coupure (facultatif) Vous n'avez pas besoin de fournir de lieu spécifique, mais cela vous permet d'obtenir des heures d'arrivée prévues plus précises tout au long de la journée.

Pour plus d'informations, consultez les articles suivants :

Android

iOS

Tâches d'arrêt planifiées

Créer des tâches d'arrêt planifiées pour modéliser les arrêts qu'un véhicule de livraison doit effectuer Par exemple, créez une tâche d'arrêt programmée pour un arrêt planifié quotidien à un emplacement spécifique, indépendamment des autres livraisons ou retraits au même endroit. Vous pouvez également créer des tâches d'arrêt planifiées pour les collectes depuis des boîtes de dépôt, pour modéliser les correspondances entre véhicules d'actualisation, ou les arrêts dans des centres de service et des points de service.

Pour plus d'informations, consultez les articles suivants :

Android

iOS

Consignes concernant les ID de tâche

Lorsque vous créez des ID de tâche, suivez ces consignes concernant le contenu et le format:

  • Créer des ID de tâche uniques
  • N'exposez pas d'informations permettant d'identifier personnellement l'utilisateur ni de données en texte clair.
  • Utilisez des chaînes Unicode valides.
  • Utilisez 64 caractères au maximum.
  • N'utilisez aucun des caractères ASCII suivants: "/", ":", "\"", "?" ou "#".
  • Effectuez une normalisation en respectant le formulaire de normalisation Unicode C.

Voici quelques exemples d'ID de tâche corrects:

  • 566c33d9-2a31-4b6a-9cd4-80ba1a0c643b
  • e4708eabcfa39bf2767c9546c9273f747b4626e8cc44e9630d50f6d129013d38
  • NTA1YTliYWNkYmViMTI0ZmMzMWFmOWY2NzNkM2Jk

Le tableau suivant présente des exemples d'ID de tâche non compatibles:

ID de tâches non compatibles Motif
8/31/2019-20:48-46.70746,-130.10807,-85.17909,61.33680 Non-respect des exigences concernant les informations permettant d'identifier personnellement l'utilisateur et les caractères: virgules, points, deux-points et barres obliques.
JohnDoe-577b484da26f-Cupertino-SantaCruz Non-respect des exigences concernant les informations permettant d'identifier personnellement l'utilisateur.
4R0oXLToF"112 Summer Dr. East Hartford, CT06118"577b484da26f8a Non-respect des exigences concernant les informations permettant d'identifier personnellement l'utilisateur et les caractères: espaces blancs, virgules et guillemets. contenir plus de 64 caractères ;

Autres ressources

Pour afficher les champs spécifiques contenus dans chaque structure de données, consultez la documentation de référence de l'API pour DeliveryVehicle (gRPC, REST) et Task (gRPC, REST).

Durée de vie d'un véhicule

L'objet DeliveryVehicle représente un véhicule de livraison sur le premier ou le dernier kilomètre. Créez un objet DeliveryVehicle à l'aide de la commande suivante:

  • ID du projet Google Cloud contenant le compte de service utilisé pour appeler les API Fleet Engine.
  • ID du véhicule appartenant au client.

Utilisez des identifiants propres à chaque véhicule. Ne réutilisez pas l'ID d'un véhicule, sauf s'il n'existe aucune tâche active pour le véhicule d'origine.

Fleet Engine supprime automatiquement les objets DeliveryVehicle qui n'ont pas été mis à jour à l'aide de UpdateDeliveryVehicle après sept jours. Pour voir si un véhicule existe:

  1. Appelez UpdateDeliveryVehicle.
  2. Si vous obtenez une erreur NOT_FOUND, appelez CreateDeliveryVehicle pour recréer le véhicule. Si l'appel renvoie un véhicule, celui-ci reste disponible pour la mise à jour.

Type de véhicule

L'entité VehicleType contient un champ facultatif de VehicleType, qui contient une énumération Category que vous pouvez spécifier comme AUTO, TWO_WHEELER, BICYCLE ou PEDESTRIAN. Si vous ne définissez pas ce champ, la valeur par défaut est AUTO.

Tous les itinéraires pour les véhicules utilisent le RouteTravelMode correspondant au type de véhicule.

Attributs du véhicule

L'entité DeliveryVehicle contient un champ répété de DeliveryVehicleAttribute. L'API ListDeliveryVehicles inclut un champ filter qui peut limiter les entités DeliveryVehicle renvoyées à celles ayant les attributs spécifiés. DeliveryVehicleAttribute n'a aucune incidence sur le comportement de routage de Fleet Engine.

N'incluez pas d'informations personnelles ni d'informations sensibles dans les attributs, car ce champ pourrait être visible par les utilisateurs.

Cycle de vie d'une tâche

Vous pouvez créer, mettre à jour et interroger des tâches dans Fleet Engine avec les interfaces gRPC ou REST de l'API Deliveries.

Un objet Task comporte un champ d'état pour suivre sa progression tout au long de son cycle de vie. Les valeurs passent de OPEN à CLOSED. Les nouvelles tâches sont créées à l'état OPEN, ce qui indique que:

  • La tâche n'a pas encore été attribuée à un véhicule de livraison.
  • Le véhicule de livraison n'a pas encore dépassé l'arrêt attribué à la tâche.

Consignes concernant la tâche

Vous ne pouvez attribuer une tâche à un véhicule que lorsqu'il est à l'état OUVERT.

Pour annuler une tâche, vous devez la supprimer de la liste des arrêts de véhicule, ce qui définit automatiquement son état sur CLOSED (FERMÉE).

Lorsque le véhicule associé à la tâche termine son arrêt:

  1. Définissez le champ de résultat de la tâche sur "SUCCEEDED" (Réussite) ou "FAILED" (ÉCHEC).

  2. Indiquez le code temporel de l'événement.

    La bibliothèque de suivi des expéditions JavaScript indique ensuite le résultat de la tâche, et son état est automatiquement défini sur CLOSED. Pour en savoir plus, consultez Suivre votre envoi avec la bibliothèque JavaScript Shipment Tracking.

Comme pour les véhicules, Fleet Engine supprime les tâches qui n'ont pas été mises à jour après sept jours, et si vous essayez de créer une tâche avec un ID qui existe déjà, une erreur est renvoyée.

Remarque:Fleet Engine ne permet pas de supprimer explicitement une tâche. Le service supprime automatiquement les tâches après sept jours sans mises à jour. Si vous souhaitez conserver des données de tâches plus de sept jours, vous devez implémenter cette fonctionnalité vous-même.

Attributs de la tâche

L'entité Task contient un champ répété de TaskAttribute, qui peut avoir une valeur de l'un des trois types suivants: chaîne, nombre et valeur booléenne. L'API ListTasks inclut un champ filter qui peut limiter les entités Task renvoyées à celles ayant les attributs spécifiés. Les attributs de tâche n'ont aucune incidence sur le comportement de routage de Fleet Engine.

N'incluez pas d'informations personnelles ni d'autres informations sensibles dans les attributs, car ces attributs peuvent être visibles par les utilisateurs.

Gérer le cycle de vie des véhicules et des tâches

Rappel: Votre système interne sert de source fiable des données que l'API Fleet Engine Deliveries enrichit en votre nom.

Pour gérer le cycle de vie des véhicules et des tâches dans votre système, utilisez l'API Fleet Engine Deliveries pour créer, mettre à jour et suivre vos véhicules et leurs tâches associées.

Dans le même temps, l'application du pilote communique directement avec Fleet Engine pour mettre à jour la position de l'appareil et les informations sur l'itinéraire. Ce modèle permet à Fleet Engine de gérer efficacement la localisation en temps réel. Il envoie directement l'emplacement à la bibliothèque de suivi, que vous pouvez ensuite utiliser pour informer les consommateurs sur l'état de leur commande.

Par exemple, supposons que vous disposiez du scénario suivant:

  • Un chauffeur s'approche d'un arrêt de livraison. L'application du pilote envoie son emplacement à Fleet Engine.
  • Fleet Engine envoie la position de l'appareil à la bibliothèque de suivi, que votre application consommateur utilise pour alerter le consommateur de la proximité de son colis.
  • Une fois que le chauffeur a terminé l'expédition, il clique sur un bouton "Expédition livrée" dans l'application du pilote.
  • L'action "Expédition livrée" envoie les informations à votre système backend, qui effectue les étapes nécessaires de validation et de vérification de l'activité.
  • Votre système confirme que la tâche est RÉUSSITE et met à jour Fleet Engine à l'aide de l'API Deliveries.

Le schéma suivant illustre ces processus à un niveau générique. Il indique également la relation standard entre votre système, le client et Fleet Engine.

Utiliser l'API Deliveries

Gérer les jetons client

Les mises à jour de la position provenant de l'application du pilote et envoyées directement à Fleet Engine nécessitent des jetons d'autorisation. Voici l'approche recommandée pour gérer les mises à jour du client vers Fleet Engine:

  1. Générez le jeton à l'aide du rôle de compte de service Utilisateur de pilote non approuvé Fleet Engine Delivery.

  2. Fournissez à l'application de pilote un jeton de portée limitée. Ce champ d'application ne lui permet de mettre à jour que la position de l'appareil dans Fleet Engine.

Cette approche garantit que les appels provenant d'appareils mobiles (considérés comme des environnements de faible confiance) respectent le principe du moindre privilège.

Autres rôles de compte de service

Si vous souhaitez autoriser les applications de pilote à effectuer des mises à jour directes de Fleet Engine autres que celles limitées au rôle de Conducteur non approuvé, par exemple pour certaines modifications de tâches, vous pouvez utiliser le rôle Conducteur de confiance. Pour en savoir plus sur un modèle qui utilise le rôle de Conducteur de confiance, consultez la section Modèle de Conducteur de confiance.

Pour en savoir plus sur l'utilisation des rôles de pilote non approuvé et approuvé, consultez la page Configurer un projet Cloud.

Modélisez une journée de travail

Le tableau suivant décrit à quoi peut ressembler une journée de travail pour les chauffeurs se trouvant sur le premier ou le dernier kilomètre dans une entreprise de livraison et de logistique. Les détails de votre entreprise peuvent différer, mais vous pouvez voir comment modéliser une journée de travail.

HeureActivitéModélisation
Dans les 24 heures qui suivent le début de la journée Le coordinateur attribue les expéditions aux véhicules ou aux itinéraires de livraison. Vous pouvez créer à l'avance des tâches pour les livraisons, les retraits, les pauses et d'autres tâches dans Fleet Engine. Par exemple, vous pouvez créer une tâche de retrait de la livraison, une tâche de livraison de la livraison, une indisponibilité planifiée ou un arrêt planifié.

Attribuez des tâches à un véhicule une fois que l'ensemble des colis et l'ordre de livraison sont finalisés.
Début de journée Le conducteur commence la journée au dépôt en se connectant à son application. Initialisez l'API Delivery Driver. Créez le véhicule de livraison dans Fleet Engine si nécessaire.
Le chauffeur charge les colis dans le véhicule de livraison. Il scanne les colis. Si les tâches de livraison des colis n'ont pas été créées à l'avance, créez des tâches de livraison au moment de l'analyse.
Le conducteur confirme l'ordre des tâches à effectuer. S'ils n'ont pas été créés à l'avance, créez des tâches de retrait des livraisons, des indisponibilités planifiées et des arrêts planifiés.
Le conducteur quitte le dépôt et valide le prochain nombre de tâches à effectuer. Attribuez toutes les tâches ou un sous-ensemble de tâches au véhicule en validant leur ordre d'achèvement.
Le chauffeur livre un colis. Une fois arrivé à l'arrêt de livraison, effectuez les actions liées à l'arrivée d'un véhicule à un arrêt. Une fois le colis livré, clôture la tâche de livraison et, éventuellement, l'état de l'expédition en magasin et d'autres méta-informations. Après avoir effectué toutes les tâches à l'arrêt et avant de commencer à rouler jusqu'au prochain arrêt, effectuez les actions liées au véhicule jusqu'à l'arrêt et au véhicule jusqu'au prochain arrêt.
Le conducteur rencontre un véhicule d'alimentation pour transférer les autres colis dans le véhicule de livraison. Le point de rendez-vous d'une correspondance entre les véhicules d'accueil et de livraison doit être modélisé comme un arrêt planifié.

Après avoir transféré et analysé les livraisons, créez des tâches de livraison si ce n'est pas déjà fait. Modifiez ensuite l'ordre d'exécution des tâches en attribuant des tâches à un véhicule et en modifiant l'ordre des tâches.
Le conducteur reçoit une notification d'une demande de retrait. Après avoir accepté la demande de retrait, créez une tâche de retrait de colis. Ensuite, mettez à jour l'ordre d'exécution des tâches en attribuant des tâches à un véhicule et en modifiant l'ordre d'exécution des tâches.
Midi Conducteur qui fait la pause déjeuner. Si un emplacement est associé à la tâche d'indisponibilité, traitez-le comme n'importe quelle autre tâche. Effectuez des actions concernant les véhicules arrivant à un arrêt, le véhicule finissant un arrêt et en route vers le prochain arrêt.

Sinon, aucune autre action n'est requise avant la fin de la coupure. Supprimez la tâche en confirmant les tâches suivantes et restantes, et en modifiant l'ordre des tâches.
Le chauffeur récupère un colis. Ce fonctionnement est modélisé comme un arrêt de livraison. Effectuez des actions liées à l'arrivée d'un véhicule à un arrêt et à la fermeture d'une tâche, et éventuellement le stockage de l'état de la livraison et d'autres métadonnées. Après avoir effectué toutes les tâches à l'arrêt et avant de commencer à rouler jusqu'au prochain arrêt, effectuez les actions liées au véhicule qui termine un arrêt et au véhicule jusqu'au prochain arrêt. Remarque: Pour garantir une facturation correcte, tous les retraits doivent être associés à une tâche de livraison. Si le retrait doit être livré à un autre endroit sur le même itinéraire ce jour-là, nous vous recommandons de modéliser cette tâche de livraison comme toute autre tâche de livraison sur l'itinéraire. Si le livreur ramène le retrait au dépôt, nous vous recommandons de créer une tâche de livraison à la destination du dépôt.
Le chauffeur s'arrête pour récupérer les colis à partir d'un dépôt. Cet arrêt est modélisé comme n'importe quel autre arrêt de prise en charge. Effectuez des actions liées à la fermeture d'un véhicule qui arrive à un arrêt et à la fermeture d'une tâche. Une fois que vous avez effectué toutes les tâches à l'arrêt et commencé à rouler jusqu'au prochain arrêt, effectuez les actions liées au véhicule qui termine un arrêt et au véhicule jusqu'au prochain arrêt.
Le conducteur reçoit une notification indiquant qu'un colis a été dévié vers un autre lieu. Définissez l'état de la tâche de livraison d'origine sur COMPLETED et créez une tâche de livraison pour le nouveau lieu de livraison. Pour en savoir plus, consultez Réacheminer un envoi.
Le conducteur a essayé de livrer un colis, mais n'a pas pu le faire. Ce processus est modélisé de la même manière qu'un arrêt de livraison réussi, marquant la tâche de livraison comme étant terminée. Effectuez des actions liées à un véhicule arrivant à un arrêt. En cas d'échec de livraison, fermez la tâche et, éventuellement, l'état de la livraison en magasin et d'autres méta-informations. Après avoir effectué toutes les tâches à l'arrêt et avant de commencer à rouler jusqu'au prochain arrêt, effectuez les actions liées au véhicule qui termine un arrêt et au véhicule jusqu'au prochain arrêt.
Le chauffeur a été informé qu'un colis était en attente (et non livré). Une fois la notification reçue et confirmée, définissez l'état de la tâche sur COMPLETED.
Le livreur a été informé de la livraison d'un certain colis par la suite, ce qui a modifié la commande de livraison prévue. Modifiez l'ordre des tâches.
Le livreur choisit de livrer un colis dans le désordre. Mettez à jour l'ordre des tâches, puis continuez comme d'habitude.
Le chauffeur livre plusieurs colis au même endroit. Le modèle est semblable à celui d'un arrêt de livraison unique. Une fois arrivé à l'arrêt, effectuez les actions liées à un véhicule arrivant à un arrêt. Après avoir livré chaque envoi, fermez chaque tâche et, éventuellement, l'état de la livraison en magasin et d'autres méta-informations. Après avoir effectué toutes les tâches à l'arrêt et avant de commencer à rouler jusqu'au prochain arrêt, effectuez les actions liées au véhicule qui termine un arrêt et au véhicule jusqu'au prochain arrêt.
Fin de journée Le chauffeur retourne au dépôt. Si le livreur retourne au dépôt avec les commandes retirées pendant l'acheminement, vous devez également créer et fermer chaque colis en tant que tâche de livraison pour garantir une facturation correcte. Pour ce faire, modélisez le dépôt comme n'importe quel autre arrêt de livraison. Si le dépôt n'est pas utilisé comme arrêt de livraison, vous avez toujours la possibilité de le modéliser comme un arrêt planifié. La modélisation de l'arrêt permet aux conducteurs de connaître l'itinéraire de retour au dépôt et d'indiquer leur heure d'arrivée prévue.

Fonctionnement des mises à jour de la position

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 le SDK Driver (Android, iOS) comme l'option la plus simple.
  2. Utilisez du code personnalisé. Cela peut s'avérer utile si les emplacements sont transmis via votre backend, ou si vous utilisez des appareils autres qu'Android ou iOS.

Quelle que soit la façon dont vous fournissez les mises à jour de la position des véhicules, votre backend est responsable de la mise à jour de Fleet Engine lorsqu'un véhicule de livraison est en route vers un arrêt (y compris le dépôt) et lorsqu'il arrive à un arrêt. Fleet Engine ne détecte pas ces événements automatiquement.

Arrêts et lieux de livraison

Un arrêt de véhicule est celui où un véhicule de livraison effectue une tâche d'expédition ou une autre tâche. Il peut s'agir d'un point d'accès tel qu'une quai de chargement ou d'un emplacement signalé par une route.

Le lieu de livraison est le lieu où le colis est livré ou retiré. Pour vous rendre au lieu de livraison et en revenir, vous devrez peut-être marcher à pied depuis l'arrêt du véhicule.

Par exemple, lorsqu'un livreur livre un colis dans un magasin d'un centre commercial, le véhicule de livraison s'arrête sur le parking du centre commercial près de l'entrée la plus proche du magasin. Il s'agit de l'arrêt du véhicule. Le chauffeur se rend ensuite de l'arrêt du véhicule à l'emplacement du centre commercial où se trouve le magasin. Il s'agit du lieu de livraison.

Pour optimiser l'expérience de suivi des expéditions pour vos utilisateurs, réfléchissez à la manière dont les tâches d'expédition sont attribuées aux arrêts des véhicules. N'oubliez pas que le nombre d'arrêts restants pour les tâches d'expédition est consigné pour l'utilisateur afin de l'aider à suivre son expédition.

Par exemple, si un livreur effectue de nombreuses livraisons dans un même immeuble de bureaux, envisagez d'attribuer toutes les tâches de livraison à un seul arrêt de véhicule. Si chaque tâche de livraison est attribuée à son propre arrêt de véhicule, votre expérience de suivi des livraisons sera moins utile pour vos utilisateurs, car le suivi n'est disponible qu'une fois que le véhicule se trouve dans un nombre limité d'arrêts avant sa destination. Le fait que le véhicule s'arrête plusieurs fois en peu de temps ne laisse pas beaucoup de temps à l'utilisateur pour suivre la progression de sa livraison.

Utiliser les SDK pour mobile

Avant d'appeler le SDK Driver, veillez à l'initialiser.

Initialiser l'API Delivery Driver

Avant d'initialiser l'API Delivery Driver dans le SDK Driver, veillez à initialiser le SDK Navigation. Ensuite, initialisez l'API Delivery Driver comme indiqué dans l'exemple suivant:

static final String PROVIDER_ID = "provider-1234";
static final String VEHICLE_ID = "vehicle-8241890";

NavigationApi.getNavigator(
   this, // Activity.
   new NavigatorListener() {
     @Override
     public void onNavigatorReady(Navigator navigator) {
       DeliveryDriverApi.createInstance(DriverContext.builder(getApplication())
         .setNavigator(navigator)
         .setProviderId(PROVIDER_ID)
         .setVehicleId(VEHICLE_ID)
         .setAuthTokenFactory((context) -> "JWT") // AuthTokenFactory returns JWT for call context.
         .setRoadSnappedLocationProvider(NavigationApi.getRoadSnappedLocationProvider(getApplication()))
         .setNavigationTransactionRecorder(NavigationApi.getNavigationTransactionRecorder(getApplication()))
         .setStatusListener((statusLevel,statusCode,statusMsg) -> // Optional, surfaces polling errors.
             Log.d("TAG", String.format("New status update. %s, %s, %s", statusLevel, statusCode, statusMsg)))
         .build));
     }
     @Override
     public void onError(int errorCode) {
       Log.e("TAG", String.format("Error loading Navigator instance: %s", errorCode));
     }
   });

Cas d'utilisation

Cette section explique comment utiliser l'API Deliveries pour modéliser des cas d'utilisation courants.

Identifiants d'entité uniques

Le format et la valeur des identifiants d'entité unique utilisés dans les appels REST sont opaques pour Fleet Engine. Évitez d'utiliser des ID d'incrémentation automatique et assurez-vous qu'ils ne contiennent aucune information permettant d'identifier personnellement l'utilisateur, comme le numéro de téléphone du conducteur.

Créer un véhicule

Vous pouvez créer un véhicule à partir du SDK Driver ou d'un environnement de serveur à l'aide de gRPC ou REST.

gRPC

Pour créer un véhicule, vous devez appeler CreateDeliveryVehicle Fleet Engine. Utilisez l'objet CreateDeliveryVehicleRequest pour définir les attributs du nouveau véhicule de livraison. Notez que toute valeur spécifiée pour le champ Name est ignorée, conformément aux instructions de l'API pour les ID spécifiés par l'utilisateur. Vous devez utiliser le champ DeliveryVehicleId pour définir l'ID du véhicule.

Lorsque vous créez un DeliveryVehicle, vous pouvez éventuellement spécifier les champs suivants:

  • Attributs
  • LastLocation
  • Type

Ne définissez aucun autre champ. Dans ce cas, Fleet Engine renvoie une erreur, car ces champs sont en lecture seule ou ne peuvent être mis à jour qu'avec un appel à UpdateDeliveryVehicle.

Pour créer un véhicule sans définir de champs facultatifs, vous pouvez laisser le champ DeliveryVehicle non défini dans CreateDeliveryVehicleRequest.

L'exemple suivant montre comment créer un véhicule à l'aide de la bibliothèque Java gRPC:

    static final String PROJECT_ID = "my-delivery-co-gcp-project";
    static final String VEHICLE_ID = "vehicle-8241890"; // Avoid auto-incrementing IDs.

    DeliveryServiceBlockingStub deliveryService =
      DeliveryServiceGrpc.newBlockingStub(channel);

    // Vehicle settings
    String parent = "providers/" + PROJECT_ID;
    DeliveryVehicle vehicle = DeliveryVehicle.newBuilder()
      .addAttributes(DeliveryVehicleAttribute.newBuilder()
        .setKey("route_number").setValue("1"))  // Opaque to the Fleet Engine
      .build();

    // Vehicle request
    CreateDeliveryVehicleRequest createVehicleRequest =
      CreateDeliveryVehicleRequest.newBuilder()  // No need for the header
          .setParent(parent)
          .setDeliveryVehicleId(VEHICLE_ID)     // Vehicle ID assigned by the Provider
          .setDeliveryVehicle(vehicle)
          .build();

    // Error handling
    // If Fleet Engine does not have vehicle with that ID and the credentials of the
    // requestor pass, the service creates the vehicle successfully.

    try {
      DeliveryVehicle createdVehicle =
        deliveryService.createDeliveryVehicle(createVehicleRequest);
    } catch (StatusRuntimeException e) {
      Status s = e.getStatus();
      switch (s.getCode()) {
         case ALREADY_EXISTS:
           break;
         case PERMISSION_DENIED:
           break;
      }
      return;
    }

REST

Pour créer un véhicule à partir d'un environnement de serveur, envoyez un appel REST HTTP à CreateDeliveryVehicle:

POST https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles?deliveryVehicleId=<id>

<id> est un identifiant unique attribué à un véhicule de livraison dans votre parc.

L'en-tête de requête doit contenir un champ Authorization avec la valeur Bearer <token>, où <token> est un jeton émis par une fabrique de jetons Fleet Engine.

Le corps POST représente l'entité DeliveryVehicle à créer. Vous pouvez spécifier les champs facultatifs suivants:

  • attributs
  • lastLocation
  • type

Exemple de commande curl :

# Set $JWT, $PROJECT_ID, and $VEHICLE_ID in the local
# environment
curl -X POST "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles?deliveryVehicleId=${VEHICLE_ID}" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
--data-binary @- << EOM
{
  "attributes": [{"key": "model", "value": "sedan"}],
  "lastLocation": {"location": {"latitude": 12.1, "longitude": 14.5}}
}
EOM

Fleet Engine ignore le champ name de l'entité DeliveryVehicle conformément aux instructions de l'API pour les ID spécifiés par l'utilisateur. Ne définissez aucun autre champ. Dans ce cas, Fleet Engine renvoie une erreur, car ces champs sont en lecture seule ou ne peuvent être mis à jour qu'à l'aide d'un appel à UpdateDeliveryVehicle.

Pour créer un véhicule sans définir de champ, laissez le corps de la requête POST vide. Le véhicule que vous venez de créer extrait ensuite un ID de véhicule à partir du paramètre deliveryVehicleId de l'URL POST.

Exemple de commande curl :

# Set $JWT, $PROJECT_ID, and $VEHICLE_ID in the local
# environment
curl -X POST "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles?deliveryVehicleId=${VEHICLE_ID}" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}"

Créer une tâche de retrait de colis

Vous pouvez créer une tâche de retrait de colis à partir du SDK pilote ou d'un environnement de serveur à l'aide de gRPC ou de REST.

gRPC

L'exemple suivant montre comment utiliser la bibliothèque Java gRPC pour créer une tâche de retrait de colis:

static final String PROJECT_ID = "my-delivery-co-gcp-project";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Task settings
String parent = "providers/" + PROJECT_ID;
Task task = Task.newBuilder()
  .setType(Task.Type.PICKUP)
  .setState(Task.State.OPEN)
  .setTrackingId("my-tracking-id")
  .setPlannedLocation(               // Grand Indonesia East Mall
    LocationInfo.newBuilder().setPoint(
      LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
  .setTaskDuration(
    Duration.newBuilder().setSeconds(2 * 60))
  .setTargetTimeWindow(
    TimeWindow.newBuilder()
      .setStartTime(Timestamp.newBuilder().setSeconds(1680123600))
      .setEndTime(Timestamp.newBuilder().setSeconds(1680130800)))
  .addAttributes(TaskAttribute.newBuilder().setKey("foo").setStringValue("value"))
  .addAttributes(TaskAttribute.newBuilder().setKey("bar").setNumberValue(10))
  .addAttributes(TaskAttribute.newBuilder().setKey("baz").setBoolValue(false))
  .build();

// Task request
CreateTaskRequest createTaskRequest =
  CreateTaskRequest.newBuilder()  // No need for the header
      .setParent(parent)          // Avoid using auto-incrementing IDs for the taskId
      .setTaskId("task-8241890")  // Task ID assigned by the Provider
      .setTask(task)              // Initial state
      .build();

// Error handling
// If Fleet Engine does not have a task with that ID and the credentials of the
// requestor pass, the service creates the task successfully.

try {
  Task createdTask = deliveryService.createTask(createTaskRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case ALREADY_EXISTS:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

Pour créer une tâche de retrait de colis à partir d'un environnement de serveur, envoyez un appel REST HTTP à CreateTask:

`POST https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks?taskId=<id>`

<id> est un identifiant unique pour la tâche. Il ne doit pas s'agir du numéro de suivi du colis. Si vous ne disposez pas d'ID de tâches dans votre système, vous pouvez générer un identifiant unique universel (UUID).

L'en-tête de requête doit contenir un champ Authorization avec la valeur Bearer <token>, où <token> est un jeton émis par une fabrique de jetons Fleet Engine.

Le corps de la requête doit contenir une entité Task:

  • Champs obligatoires :

    ChampValeur
    type Type.PICKUP
    state State.OPEN
    trackingId Numéro ou identifiant que vous utilisez pour suivre un envoi.
    plannedLocation Lieu où la tâche doit être effectuée, dans ce cas le lieu de retrait du colis.
    taskDuration Durée prévue, en secondes, pour retirer le colis au point de retrait.

  • Champs facultatifs :

    ChampValeur
    targetTimeWindow Période pendant laquelle la tâche doit être effectuée. Cela n'affecte pas le comportement de routage.
    attributs Une liste d'attributs Task personnalisés. Chaque attribut doit avoir une clé unique.

Tous les autres champs de l'entité sont ignorés pour la création. Fleet Engine génère une exception si la requête inclut un deliveryVehicleId attribué. Vous attribuez les tâches à l'aide de UpdateDeliveryVehicleRequest. Pour en savoir plus, consultez Attribuer des tâches à un véhicule et UpdateDeliveryVehicleRequest.

Exemple de commande curl :

# Set $JWT, $PROJECT_ID, $TRACKING_ID, and $TASK_ID in the local
# environment
curl -X POST "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks?taskId=${TASK_ID}" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "type": "PICKUP",
  "state": "OPEN",
  "trackingId": "${TRACKING_ID}",
  "plannedLocation": {
     "point": {
        "latitude": -6.195139,
        "longitude": 106.820826
     }
  },
  "taskDuration": "90s",
  "targetTimeWindow": {
    "startTime": "2023-03-29T21:00:00Z",
    "endTime": "2023-03-29T23:00:00Z"
  }
}
EOM

Créer une tâche de livraison d'expédition

Créez une tâche de livraison de livraison à partir du SDK Driver ou d'un environnement de serveur à l'aide de gRPC ou de REST.

gRPC

L'exemple suivant montre comment utiliser la bibliothèque Java gRPC pour créer une tâche de livraison de livraison:

static final String PROJECT_ID = "my-delivery-co-gcp-project";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Task settings
String parent = "providers/" + PROJECT_ID;
Task task = Task.newBuilder()
  .setType(Task.Type.DELIVERY)
  .setState(Task.State.OPEN)
  .setTrackingId("my-tracking-id")
  .setPlannedLocation(               // Grand Indonesia East Mall
    LocationInfo.newBuilder().setPoint(
      LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
  .setTaskDuration(
    Duration.newBuilder().setSeconds(2 * 60))
  .setTargetTimeWindow(
    TimeWindow.newBuilder()
      .setStartTime(Timestamp.newBuilder().setSeconds(1680123600))
      .setEndTime(Timestamp.newBuilder().setSeconds(1680130800)))
  .addAttributes(TaskAttribute.newBuilder().setKey("foo").setStringValue("value"))
  .addAttributes(TaskAttribute.newBuilder().setKey("bar").setNumberValue(10))
  .addAttributes(TaskAttribute.newBuilder().setKey("baz").setBoolValue(false))
  .build();

// Task request
CreateTaskRequest createTaskRequest =
  CreateTaskRequest.newBuilder()  // No need for the header
      .setParent(parent)          // Avoid using auto-incrementing IDs for the taskId
      .setTaskId("task-8241890")  // Task ID assigned by the Provider
      .setTask(task)              // Initial state
      .build();

// Error handling
// If Fleet Engine does not have task with that ID and the credentials of the
// requestor pass, the service creates the task successfully.

try {
  Task createdTask = deliveryService.createTask(createTaskRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case ALREADY_EXISTS:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

Pour créer une tâche de livraison de livraison à partir d'un environnement de serveur à l'aide de gRPC ou de REST, envoyez un appel REST HTTP à CreateTask:

`POST https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks?taskId=<id>`

<id> est un identifiant unique pour la tâche. Il ne doit pas s'agir du numéro de suivi du colis. Si vous ne disposez pas d'ID de tâches dans votre système, vous pouvez générer un identifiant unique universel (UUID).

L'en-tête de requête doit contenir un champ Authorization avec la valeur Bearer <token>, où <token> est un jeton émis par une fabrique de jetons Fleet Engine.

Le corps de la requête doit contenir une entité Task:

  • Champs obligatoires :

    ChampValeur
    type Type.DELIVERY
    state State.OPEN
    trackingId Numéro ou identifiant que vous utilisez pour suivre un envoi.
    plannedLocation Lieu où la tâche doit être effectuée, dans ce cas le lieu de livraison de la livraison.
    taskDuration Durée prévue, en secondes, nécessaire pour déposer le colis au lieu de livraison.

  • Champs facultatifs :

    ChampValeur
    targetTimeWindow Période pendant laquelle la tâche doit être effectuée. Cela n'affecte pas le comportement de routage.
    attributs Une liste d'attributs Task personnalisés. Chaque attribut doit avoir une clé unique.

Tous les autres champs de l'entité sont ignorés pour la création. Fleet Engine génère une exception si la requête inclut un DeliveryVehicleId attribué. Vous attribuez les tâches à l'aide de UpdateDeliveryVehicleRequest. Pour en savoir plus, consultez Attribuer des tâches à un véhicule et UpdateDeliveryVehicleRequest.

Exemple de commande curl :

# Set $JWT, $PROJECT_ID, $TRACKING_ID, and $TASK_ID in the local
# environment
curl -X POST "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks?taskId=${TASK_ID}" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "type": "DELIVERY",
  "state": "OPEN",
  "trackingId": "${TRACKING_ID}",
  "plannedLocation": {
     "point": {
        "latitude": -6.195139,
        "longitude": 106.820826
     }
  },
  "taskDuration": "90s",
  "targetTimeWindow": {
    "startTime": "2023-03-29T21:00:00Z",
    "endTime": "2023-03-29T23:00:00Z"
  }
}
EOM

Tâches de création groupée

Vous pouvez créer un lot de tâches à partir d'un environnement de serveur à l'aide de gRPC ou de REST.

gRPC

L'exemple suivant montre comment utiliser la bibliothèque Java gRPC pour créer deux tâches, l'une pour une distribution et l'autre pour un retrait au même emplacement:

static final String PROJECT_ID = "my-delivery-co-gcp-project";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Delivery Task settings
Task deliveryTask = Task.newBuilder()
  .setType(Task.Type.DELIVERY)
  .setState(Task.State.OPEN)
  .setTrackingId("delivery-tracking-id")
  .setPlannedLocation(               // Grand Indonesia East Mall
    LocationInfo.newBuilder().setPoint(
      LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
  .setTaskDuration(
    Duration.newBuilder().setSeconds(2 * 60))
  .build();

// Delivery Task request
CreateTaskRequest createDeliveryTaskRequest =
  CreateTaskRequest.newBuilder()  // No need for the header or parent fields
      .setTaskId("task-8312508")  // Task ID assigned by the Provider
      .setTask(deliveryTask)      // Initial state
      .build();

// Pickup Task settings
Task pickupTask = Task.newBuilder()
  .setType(Task.Type.PICKUP)
  .setState(Task.State.OPEN)
  .setTrackingId("pickup-tracking-id")
  .setPlannedLocation(               // Grand Indonesia East Mall
    LocationInfo.newBuilder().setPoint(
      LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
  .setTaskDuration(
    Duration.newBuilder().setSeconds(2 * 60))
  .build();

// Pickup Task request
CreateTaskRequest createPickupTaskRequest =
  CreateTaskRequest.newBuilder()  // No need for the header or parent fields
      .setTaskId("task-8241890")  // Task ID assigned by the Provider
      .setTask(pickupTask)        // Initial state
      .build();

// Batch Create Tasks settings
String parent = "providers/" + PROJECT_ID;

// Batch Create Tasks request
BatchCreateTasksRequest batchCreateTasksRequest =
  BatchCreateTasksRequest.newBuilder()
      .setParent(parent)
      .addRequests(createDeliveryTaskRequest)
      .addRequests(createPickupTaskRequest)
      .build();

// Error handling
// If Fleet Engine does not have any task(s) with these task ID(s) and the
// credentials of the requestor pass, the service creates the task(s)
// successfully.

try {
  BatchCreateTasksResponse createdTasks = deliveryService.batchCreateTasks(
    batchCreateTasksRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case ALREADY_EXISTS:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

Pour créer une tâche de livraison et de retrait à partir d'un environnement de serveur, effectuez un appel HTTP REST à BatchCreateTasks:

POST https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks:batchCreate

L'en-tête de requête doit contenir un champ Authorization avec la valeur Bearer <token>, où <token> est un jeton émis par une fabrique de jetons Fleet Engine.

Le corps de la requête doit contenir une entité BatchCreateTasksRequest:

  • Champs obligatoires :

    ChampValeur
    requêtes Tableau<CreateTasksRequest>

  • Champs facultatifs :

    ChampValeur
    en-tête "DeliveryRequestHeader"

Chaque élément CreateTasksRequest de requests doit passer les mêmes règles de validation qu'une requête CreateTask, à l'exception des champs parent et header qui sont facultatifs. S'ils sont définis, ils doivent être identiques à leurs champs respectifs au niveau de l'BatchCreateTasksRequest de premier niveau. Consultez les sections Créer une tâche de retrait à la livraison et Créer une tâche de livraison de livraison pour connaître les règles de validation spécifiques à chacune d'elles.

Pour en savoir plus, consultez la documentation de référence de l'API pour BatchCreateTasks (gRPC, REST).

Exemple de commande curl :

# Set $JWT, $PROJECT_ID, $DELIVERY_TRACKING_ID, $DELIVERY_TASK_ID,
# $PICKUP_TRACKING_ID, and $PICKUP_TASK_ID in the local environment
curl -X POST "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks:batchCreate" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "requests" : [
    {
      "taskId": "${DELIVERY_TASK_ID}",
      "task" : {
        "type": "DELIVERY",
        "state": "OPEN",
        "trackingId": "${DELIVERY_TRACKING_ID}",
        "plannedLocation": {
          "point": {
              "latitude": -6.195139,
              "longitude": 106.820826
          }
        },
        "taskDuration": "90s"
      }
    },
    {
      "taskId": "${PICKUP_TASK_ID}",
      "task" : {
        "type": "PICKUP",
        "state": "OPEN",
        "trackingId": "${PICKUP_TRACKING_ID}",
        "plannedLocation": {
          "point": {
              "latitude": -6.195139,
              "longitude": 106.820826
          }
        },
        "taskDuration": "90s"
      }
    }
  ]
}
EOM

Indisponibilité planifiée

Vous pouvez créer une tâche indiquant une indisponibilité (par exemple, pour des temps de pause ou le ravitaillement d'un véhicule) à partir du SDK pilote ou d'un environnement de serveur utilisant gRPC ou REST. Une tâche d'indisponibilité planifiée ne doit pas inclure d'ID de suivi. Vous pouvez éventuellement indiquer un lieu.

gRPC

L'exemple suivant montre comment créer une tâche d'indisponibilité à l'aide de la bibliothèque Java gRPC:

    static final String PROJECT_ID = "my-delivery-co-gcp-project";

    DeliveryServiceBlockingStub deliveryService =
      DeliveryServiceGrpc.newBlockingStub(channel);

    // Task settings
    String parent = "providers/" + PROJECT_ID;
    Task task = Task.newBuilder()
      .setType(Task.Type.UNAVAILABLE)
      .setState(Task.State.OPEN)
      .setTaskDuration(
        Duration.newBuilder().setSeconds(60 * 60))  // 1hr break
      .build();

    // Task request
    CreateTaskRequest createTaskRequest =
      CreateTaskRequest.newBuilder()  // No need for the header
          .setParent(parent)          // Avoid using auto-incrementing IDs for the taskId
          .setTaskId("task-8241890")  // Task ID assigned by the Provider
          .setTask(task)              // Initial state
          .build();

    // Error handling
    // If Fleet Engine does not have task with that ID and the credentials of the
    // requestor pass, the service creates the task successfully.

    try {
      Task createdTask = deliveryService.createTask(createTaskRequest);
    } catch (StatusRuntimeException e) {
      Status s = e.getStatus();
      switch (s.getCode()) {
         case ALREADY_EXISTS:
           break;
         case PERMISSION_DENIED:
           break;
      }
      return;
    }

REST

Pour créer une tâche d'indisponibilité à partir d'un environnement de serveur, envoyez un appel REST HTTP à CreateTask:

`POST https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks?taskId=<id>`

<id> est un identifiant unique pour la tâche. Si vous n'avez pas d'ID de tâche dans votre système, vous pouvez générer un identifiant unique universel (UUID).

L'en-tête de requête doit contenir un champ Authorization avec la valeur Bearer <token>, où <token> est un jeton émis par une fabrique de jetons Fleet Engine.

Le corps de la requête doit contenir une entité Task:

  • Champs obligatoires :

    ChampValeur
    type Type.UNAVAILABLE
    state State.OPEN
    taskDuration Durée de la coupure en secondes.

  • Champs facultatifs :

    ChampValeur
    plannedLocation Lieu de la coupure (si elle doit être prise à un endroit spécifique).

Tous les autres champs de l'entité sont ignorés pour la création. Fleet Engine génère une exception si la requête inclut un DeliveryVehicleId attribué. Vous attribuez les tâches à l'aide de UpdateDeliveryVehicleRequest. Pour en savoir plus, consultez Attribuer des tâches à un véhicule et UpdateDeliveryVehicleRequest.

Exemple de commande curl :

    # Set $JWT, $PROJECT_ID, and $TASK_ID in the local environment
    curl -X POST "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks?taskId=${TASK_ID}" \
      -H "Content-type: application/json" \
      -H "Authorization: Bearer ${JWT}" \
      --data-binary @- << EOM
    {
      "type": "UNAVAILABLE",
      "state": "OPEN",
      "plannedLocation": {
         "point": {
            "latitude": -6.195139,
            "longitude": 106.820826
         }
      },
      "taskDuration": "300s"
    }
    EOM

Arrêts planifiés

Vous pouvez créer une tâche d'arrêt programmée à partir du SDK Driver ou d'un environnement de serveur à l'aide de gRPC ou de REST. Une tâche d'arrêt planifiée ne peut pas inclure d'ID de suivi.

gRPC

L'exemple suivant montre comment utiliser la bibliothèque Java gRPC pour créer une tâche d'arrêt programmée:

static final String PROJECT_ID = "my-delivery-co-gcp-project";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Task settings
String parent = "providers/" + PROJECT_ID;
Task task = Task.newBuilder()
  .setType(Task.Type.SCHEDULED_STOP)
  .setState(Task.State.OPEN)
  .setPlannedLocation(               // Grand Indonesia East Mall
    LocationInfo.newBuilder().setPoint(
      LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
  .setTaskDuration(
    Duration.newBuilder().setSeconds(2 * 60))
  .build();

// Task request
CreateTaskRequest createTaskRequest =
  CreateTaskRequest.newBuilder()  // No need for the header
      .setParent(parent)
      .setTaskId("task-8241890")  // Task ID assigned by the Provider
      .setTrip(task)              // Initial state
      .build();

// Error handling
// If Fleet Engine does not have task with that ID and the credentials of the
// requestor pass, the service creates the task successfully.

try {
  Task createdTask = deliveryService.createTask(createTaskRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case ALREADY_EXISTS:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

Pour créer une tâche d'arrêt programmée à partir d'un environnement de serveur, envoyez un appel REST HTTP à CreateTask:

`POST https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks?taskId=<id>`

<id> est un identifiant unique pour la tâche. Si vous n'avez pas d'ID de tâche dans votre système, vous pouvez générer un identifiant unique universel (UUID).

L'en-tête de requête doit contenir un champ Authorization avec la valeur Bearer <token>, où <token> est un jeton émis par une fabrique de jetons Fleet Engine.

Le corps de la requête doit contenir une entité Task:

  • Champs obligatoires :

    ChampValeur
    type Type.SCHEDULED_STOP
    state State.OPEN
    plannedLocation Emplacement de l'arrêt.
    taskDuration Durée prévue de l'arrêt, en secondes.

  • Champs facultatifs :

    • Aucun

Tous les autres champs de l'entité sont ignorés pour la création. Fleet Engine génère une exception si la requête inclut un DeliveryVehicleId attribué. Vous attribuez les tâches à l'aide de UpdateDeliveryVehicleRequest. Pour en savoir plus, consultez Attribuer des tâches à un véhicule et UpdateDeliveryVehicleRequest.

Exemple de commande curl :

    # Set $JWT, $PROJECT_ID, and $TASK_ID in the local environment
    curl -X POST "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks?taskId=${TASK_ID}" \
      -H "Content-type: application/json" \
      -H "Authorization: Bearer ${JWT}" \
      --data-binary @- << EOM
    {
      "type": "SCHEDULED_STOP",
      "state": "OPEN",
      "plannedLocation": {
         "point": {
            "latitude": -6.195139,
            "longitude": 106.820826
         }
      },
      "taskDuration": "600s"
    }
    EOM

Définir la période cible

La fenêtre temporelle cible correspond à la fenêtre TimeWindow au cours de laquelle la tâche doit être effectuée. Par exemple, si vous indiquez un délai de livraison à des destinataires, vous pouvez utiliser la période cible de la tâche pour capturer cette fenêtre temporelle et générer des alertes ou analyser les performances post-trajet à l'aide de ce champ.

La période cible se compose d'une heure de début et d'une heure de fin, et peut être définie sur n'importe quel type de tâche. La période cible n'affecte pas le comportement de routage.

gRPC

L'exemple suivant montre comment définir une fenêtre de temps de tâche à l'aide de la bibliothèque Java gRPC:

    static final String PROJECT_ID = "my-delivery-co-gcp-project";
    static final String TASK_ID = "task-8241890";

    DeliveryServiceBlockingStub deliveryService =
      DeliveryServiceGrpc.newBlockingStub(channel);

    // Task settings
    String taskName = "providers/" + PROJECT_ID + "/tasks/" + TASK_ID;
    Task task = Task.newBuilder()
      .setName(taskName)
      .setTargetTimeWindow(
        TimeWindow.newBuilder()
          .setStartTime(Timestamp.newBuilder().setSeconds(1680123600))
          .setEndTime(Timestamp.newBuilder().setSeconds(1680130800)))
      .build();

    // Task request
    UpdateTaskRequest updateTaskRequest =
      UpdateTaskRequest.newBuilder()  // No need for the header
          .setTask(task)
          .setUpdateMask(FieldMask.newBuilder().addPaths("targetTimeWindow"))
          .build();

    try {
      Task updatedTask = deliveryService.updateTask(updateTaskRequest);
    } catch (StatusRuntimeException e) {
      Status s = e.getStatus();
      switch (s.getCode()) {
         case NOT_FOUND:
           break;
         case PERMISSION_DENIED:
           break;
      }
      return;
    }

REST

Pour définir une fenêtre de temps de tâche à l'aide du protocole HTTP, appelez UpdateTask:

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks/<id>?updateMask=targetTimeWindow`

<id> est un identifiant unique pour la tâche.

L'en-tête de requête doit contenir un champ Authorization avec la valeur Bearer <token>, où <token> est un jeton émis par une fabrique de jetons Fleet Engine.

Le corps de la requête doit contenir une entité Task:

  • Champs obligatoires :

    ChampValeur
    targetTimeWindow Période pendant laquelle la tâche doit être effectuée. Ce paramètre n'affecte pas le comportement de routage

  • Champs facultatifs :

    • Aucun

Tous les autres champs de l'entité sont ignorés pour la mise à jour.

Exemple de commande curl :

# Set JWT, PROJECT_ID, and TASK_ID in the local environment
curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks/${TASK_ID}?updateMask=targetTimeWindow" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "targetTimeWindow": {
    "startTime": "2023-03-29T21:00:00Z",
    "endTime": "2023-03-29T23:00:00Z"
  }
}
EOM

Définir la configuration de la visibilité du suivi des tâches

La visibilité des données dans la bibliothèque Shipment Tracking et de celles renvoyées par un appel à GetTaskTrackingInfo peut être contrôlée par tâche en définissant un TaskTrackingViewConfig sur la tâche. Pour en savoir plus, consultez Tâches actives d'un véhicule. Vous pouvez effectuer cette opération lors de la création ou de la mise à jour de la tâche. Voici un exemple de mise à jour de la tâche avec cette configuration:

gRPC

L'exemple suivant montre comment utiliser la bibliothèque Java gRPC pour définir la configuration de la vue de suivi des tâches:

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String TASK_ID = "task-8241890";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Task settings
String taskName = "providers/" + PROJECT_ID + "/tasks/" + TASK_ID;
Task task = Task.newBuilder()
  .setName(taskName)
  .setTaskTrackingViewConfig(
    TaskTrackingViewConfig.newBuilder()
      .setRoutePolylinePointsVisibility(
        VisibilityOption.newBuilder().setRemainingStopCountThreshold(3))
      .setEstimatedArrivalTimeVisibility(
        VisibilityOption.newBuilder().remainingDrivingDistanceMetersThreshold(5000))
      .setRemainingStopCountVisibility(
        VisibilityOption.newBuilder().setNever(true)))
  .build();

// Task request
UpdateTaskRequest updateTaskRequest =
  UpdateTaskRequest.newBuilder()  // No need for the header
      .setTask(task)
      .setUpdateMask(FieldMask.newBuilder().addPaths("taskTrackingViewConfig"))
      .build();

try {
  Task updatedTask = deliveryService.updateTask(updateTaskRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
      case NOT_FOUND:
        break;
      case PERMISSION_DENIED:
        break;
  }
  return;
}

REST

Pour définir la fenêtre de configuration de la vue de suivi des tâches à l'aide du protocole HTTP, appelez UpdateTask:

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks/<id>?updateMask=taskTrackingViewConfig`

<id> est un identifiant unique pour la tâche.

L'en-tête de requête doit contenir un champ Authorization avec la valeur Bearer <token>, où <token> est un jeton émis par une fabrique de jetons Fleet Engine.

Le corps de la requête doit contenir une entité Task:

  • Champs obligatoires :

    ChampValeur
    taskTrackingViewConfig Configuration du suivi des tâches qui spécifie les éléments de données visibles par les utilisateurs finaux dans quelles circonstances.

  • Champs facultatifs :

    • Aucun

Tous les autres champs de l'entité sont ignorés pour la mise à jour.

Exemple de commande curl :

# Set JWT, PROJECT_ID, and TASK_ID in the local environment
curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks/${TASK_ID}?updateMask=taskTrackingViewConfig" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "taskTrackingViewConfig": {
    "routePolylinePointsVisibility": {
      "remainingStopCountThreshold": 3
    },
    "estimatedArrivalTimeVisibility": {
      "remainingDrivingDistanceMetersThreshold": 5000
    },
    "remainingStopCountVisibility": {
      "never": true
    }
  }
}
EOM

Attribuer des tâches à un véhicule

Pour attribuer des tâches à un véhicule de livraison, mettez à jour l'ordre des tâches pour ce véhicule. L'ordre des tâches d'un véhicule est déterminé par la liste des arrêts associés au véhicule de livraison. Vous pouvez attribuer une ou plusieurs tâches à chaque arrêt du véhicule. Pour en savoir plus, consultez Mettre à jour l'ordre des tâches.

Pour passer d'un véhicule à un autre, fermez la tâche d'origine, puis recréez-la avant de lui attribuer le nouveau véhicule. Si vous mettez à jour l'ordre des tâches pour une tâche déjà attribuée à un autre véhicule, vous obtenez une erreur.

Modifier l'ordre des tâches

Vous pouvez mettre à jour les tâches de commande attribuées à un véhicule à partir du SDK Driver ou de l'environnement de serveur. N'utilisez pas les deux méthodes pour éviter les conditions de concurrence et maintenir une source unique fiable.

Lorsque vous modifiez l'ordre des tâches d'un véhicule, il effectue également les opérations suivantes:

  • Attribue des tâches inédites dans le véhicule.
  • Ferme toutes les tâches précédemment attribuées au véhicule, mais qui ne figurent pas dans l'ordre mis à jour.

Pour passer d'un véhicule à un autre, fermez la tâche d'origine, puis recréez-la avant de lui attribuer le nouveau véhicule. Si vous mettez à jour l'ordre des tâches pour une tâche déjà attribuée à un autre véhicule, vous obtenez une erreur.

Vous pouvez modifier l'ordre des tâches à tout moment.

gRPC

L'exemple suivant montre comment utiliser la bibliothèque Java gRPC pour mettre à jour l'ordre des tâches du véhicule:

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String VEHICLE_ID = "vehicle-8241890";
static final String TASK1_ID = "task-756390";
static final String TASK2_ID = "task-849263";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Vehicle settings
String vehicleName = "providers/" + PROJECT_ID + "/deliveryVehicles/" + VEHICLE_ID;
DeliveryVehicle deliveryVehicle = DeliveryVehicle.newBuilder()
    .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()  // 1st stop
       .setStop(VehicleStop.newBuilder()
           .setPlannedLocation(LocationInfo.newBuilder()
               .setPoint(LatLng.newBuilder()
                   .setLatitude(37.7749)
                   .setLongitude(122.4194)))
           .addTasks(TaskInfo.newBuilder().setTaskId(TASK1_ID))
           .setState(VehicleStop.State.NEW)))
    .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()  // 2nd stop
       .setStop(VehicleStop.newBuilder()
           .setPlannedLocation(LocationInfo.newBuilder()
               .setPoint(LatLng.newBuilder()
                   .setLatitude(37.3382)
                   .setLongitude(121.8863)))
           .addTasks(TaskInfo.newBuilder().setTaskId(TASK2_ID))
           .setState(VehicleStop.State.NEW)))
    .build();

// DeliveryVehicle request
UpdateDeliveryVehicleRequest updateDeliveryRequest =
  UpdateDeliveryVehicleRequest.newBuilder()  // No need for the header
      .setName(vehicleName)
      .setDeliveryVehicle(deliveryVehicle)
      .setUpdateMask(FieldMask.newBuilder().addPaths("remaining_vehicle_journey_segments"))
      .build();

try {
  DeliveryVehicle updatedDeliveryVehicle =
      deliveryService.updateDeliveryVehicle(updateDeliveryVehicleRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case NOT_FOUND:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

Pour mettre à jour l'ordre des tâches d'un véhicule à partir d'un environnement de serveur, envoyez un appel HTTP REST à UpdateDeliveryVehicle:

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<id>?updateMask=remainingVehicleJourneySegments`

<id> est un identifiant unique d'un véhicule de livraison de votre parc pour lequel vous souhaitez mettre à jour l'ordre des tâches. Il s'agit de l'identifiant que vous avez spécifié lors de la création du véhicule.

L'en-tête de requête doit contenir un champ Authorization avec la valeur Bearer <token>, où <token> est un jeton émis par une fabrique de jetons Fleet Engine.

Le corps de la requête doit contenir une entité DeliveryVehicle:

  • Champs obligatoires :

    ChampValeur
    remainingVehicleJourneySegments Une liste de segments de parcours pour les tâches, dans l'ordre dans lequel elles doivent être exécutées. La première tâche de la liste est exécutée en premier.
    restantVehicleJourneySegments[i].arrêt L'arrêt de la tâche i dans la liste.
    restantVehicleJourneySegments[i].stop.plannedLocation Emplacement prévu de l'arrêt.
    restantVehicleJourneySegments[i].stop.tasks Liste des tâches à effectuer à cet arrêt du véhicule.
    remainingVehicleJourneySegments[i].stop.state State.NEW

  • Champs facultatifs :

    • Aucun

Tous les autres champs de l'entité sont ignorés pour la mise à jour.

Exemple de commande curl :

# Set JWT, PROJECT_ID, VEHICLE_ID, TASK1_ID, and TASK2_ID in the local
# environment
curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles/${VEHICLE_ID}?updateMask=remainingVehicleJourneySegments" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "remainingVehicleJourneySegments": [
    {
      "stop": {
        "state": "NEW",
        "plannedLocation": {
          "point": {
            "latitude": 37.7749,
            "longitude": -122.084061
          }
        },
        "tasks": [
          {
            "taskId": "${TASK1_ID}"
          }
        ]
      }
    },
    {
      "stop": {
        "state": "NEW",
        "plannedLocation": {
          "point": {
            "latitude": 37.3382,
            "longitude": 121.8863
          }
        },
        "tasks": [
          {
            "taskId": "${TASK2_ID}"
          }
        ]
      }
    }
  ]
}
EOM

Véhicule en route vers le prochain arrêt

Fleet Engine doit être averti lorsqu'un véhicule quitte un arrêt ou démarre la navigation. Vous pouvez envoyer une notification à Fleet Engine à partir du SDK pilote ou à partir d'un environnement de serveur à l'aide de gRPC ou de REST. N'utilisez pas les deux méthodes pour éviter les conditions de concurrence et maintenir une source unique de vérité.

gRPC

L'exemple suivant montre comment utiliser la bibliothèque Java gRPC pour avertir Fleet Engine qu'un véhicule est en route vers son prochain arrêt.

    static final String PROJECT_ID = "my-delivery-co-gcp-project";
    static final String VEHICLE_ID = "vehicle-8241890";

    DeliveryServiceBlockingStub deliveryService =
      DeliveryServiceGrpc.newBlockingStub(channel);

    // Vehicle settings
    DeliveryVehicle deliveryVehicle = DeliveryVehicle.newBuilder()
        // Next stop marked as ENROUTE
        .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()  // 1st stop
           .setStop(VehicleStop.newBuilder()
               .setPlannedLocation(LocationInfo.newBuilder()
                   .setPoint(LatLng.newBuilder()
                       .setLatitude(37.7749)
                       .setLongitude(122.4194)))
               .addTasks(TaskInfo.newBuilder().setTaskId(TASK1_ID))
               .setState(VehicleStop.State.ENROUTE)))
        // All other stops marked as NEW
        .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()  // 2nd stop
           .setStop(VehicleStop.newBuilder()
               .setPlannedLocation(LocationInfo.newBuilder()
                   .setPoint(LatLng.newBuilder()
                       .setLatitude(37.3382)
                       .setLongitude(121.8863)))
               .addTasks(TaskInfo.newBuilder().setTaskId(TASK2_ID))
               .setState(VehicleStop.State.NEW)))
        .build();

    // DeliveryVehicle request
    UpdateDeliveryVehicleRequest updateDeliveryVehicleRequest =
      UpdateDeliveryVehicleRequest.newBuilder()  // No need for the header
          .setName(vehicleName)
          .setDeliveryVehicle(deliveryVehicle)
          .setUpdateMask(FieldMask.newBuilder().addPaths("remaining_vehicle_journey_segments"))
          .build();

    try {
      DeliveryVehicle updatedDeliveryVehicle =
          deliveryService.updateDeliveryVehicle(updateDeliveryVehicleRequest);
    } catch (StatusRuntimeException e) {
      Status s = e.getStatus();
      switch (s.getCode()) {
         case NOT_FOUND:
           break;
         case PERMISSION_DENIED:
           break;
      }
      return;
    }

REST

Pour avertir Fleet Engine qu'un véhicule est en route vers son prochain arrêt depuis un environnement de serveur, envoyez un appel REST HTTP à UpdateDeliveryVehicle:

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<id>?updateMask=remainingVehicleJourneySegments`

<id> est un identifiant unique du véhicule de livraison de votre parc pour lequel vous souhaitez mettre à jour l'ordre des tâches. Il s'agit de l'identifiant que vous avez spécifié lors de la création du véhicule.

L'en-tête de requête doit contenir un champ Authorization avec la valeur Bearer <token>, où <token> est un jeton émis par une fabrique de jetons Fleet Engine.

Le corps de la requête doit contenir une entité DeliveryVehicle:

  • Champ obligatoire:

    ChampValeur
    remainingVehicleJourneySegments Liste des arrêts de véhicules restants, avec leurs états marqués comme State.NEW. L'état du premier arrêt de la liste doit être State.ENROUTE.

  • Champs facultatifs :

    • Aucun

Tous les autres champs de l'entité sont ignorés pour la notification.

Exemple de commande curl :

# Set JWT, PROJECT_ID, VEHICLE_ID, TASK1_ID, and TASK2_ID in the local
# environment
curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles/${VEHICLE_ID}?updateMask=remainingVehicleJourneySegments" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "remainingVehicleJourneySegments": [
    {
      "stop": {
        "state": "ENROUTE",
        "plannedLocation": {
          "point": {
            "latitude": 37.7749,
            "longitude": -122.084061
          }
        },
        "tasks": [
          {
            "taskId": "${TASK1_ID}"
          }
        ]
      }
    },
    {
      "stop": {
        "state": "NEW",
        "plannedLocation": {
          "point": {
            "latitude": 37.3382,
            "longitude": 121.8863
          }
        },
        "tasks": [
          {
            "taskId": "${TASK2_ID}"
          }
        ]
      }
    }
  ]
}
EOM

Mettre à jour la position du véhicule

Si vous n'utilisez pas le SDK Driver pour mettre à jour la position du véhicule, vous pouvez appeler Fleet Engine directement avec cette position. Pour tout véhicule actif, Fleet Engine attend une mise à jour de la position au moins une fois par minute et au maximum une fois toutes les cinq secondes.

gRPC

L'exemple suivant montre comment utiliser la bibliothèque Java gRPC pour mettre à jour l'emplacement d'un véhicule dans Fleet Engine:

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String VEHICLE_ID = "vehicle-8241890";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Vehicle settings
String vehicleName = "providers/" + PROJECT_ID + "/deliveryVehicles/" + VEHICLE_ID;
DeliveryVehicle myDeliveryVehicle = DeliveryVehicle.newBuilder()
    .setLastLocation(DeliveryVehicleLocation.newBuilder()
        .setSupplementalLocation(LatLng.newBuilder()
            .setLatitude(37.3382)
            .setLongitude(121.8863))
        .setSupplementalLocationTime(now())
        .setSupplementalLocationSensor(DeliveryVehicleLocationSensor.CUSTOMER_SUPPLIED_LOCATION)
        .setSupplementalLocationAccuracy(DoubleValue.of(15.0)))  // Optional
    .build();

// DeliveryVehicle request
UpdateDeliveryVehicleRequest updateDeliveryVehicleRequest =
  UpdateDeliveryVehicleRequest.newBuilder()  // No need for the header
      .setName(vehicleName)
      .setDeliveryVehicle(myDeliveryVehicle)
      .setUpdateMask(FieldMask.newBuilder()
          .addPaths("last_location"))
      .build();

try {
  DeliveryVehicle updatedDeliveryVehicle =
      deliveryService.updateDeliveryVehicle(updateDeliveryVehicleRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case NOT_FOUND:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

Pour mettre à jour la position d'un véhicule dans Fleet Engine à l'aide de HTTP REST, appelez UpdateDeliveryVehicle:

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<id>?updateMask=last_location`

<id> est un identifiant unique pour le véhicule de livraison de votre parc ou pour lequel vous souhaitez mettre à jour l'emplacement. Il s'agit de l'identifiant que vous avez spécifié lors de la création du véhicule.

L'en-tête de requête doit contenir un champ Authorization avec la valeur Bearer <token>, où <token> est un jeton émis par une fabrique de jetons Fleet Engine.

Le corps de la requête doit contenir une entité DeliveryVehicle:

  • Champ obligatoire:

    ChampValeur
    lastLocation.supplementalLocation L'emplacement du véhicule
    lastLocation.supplementalLocationTime Dernier horodatage connu du véhicule à cet endroit.
    lastLocation.supplementalLocationSensor Doit être renseigné avec la valeur CUSTOMER_SUPPLIED_LOCATION.

  • Champs facultatifs :

    ChampValeur
    lastLocation.supplementalLocationAccuracy Précision de la position fournie, en mètres.

Exemple de commande curl :

# Set JWT, PROJECT_ID, VEHICLE_ID, TASK1_ID, and TASK2_ID in the local
# environment
curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles/${VEHICLE_ID}?updateMask=remainingVehicleJourneySegments" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "lastLocation": {
    "supplementalLocation": {"latitude": 12.1, "longitude": 14.5},
    "supplementalLocationTime": "$(date -u --iso-8601=seconds)",
    "supplementalLocationSensor": "CUSTOMER_SUPPLIED_LOCATION",
    "supplementalLocationAccuracy": 15
  }
}
EOM

Le véhicule arrive à un arrêt

Fleet Engine doit être averti lorsqu'un véhicule arrive à un arrêt. Vous pouvez envoyer une notification à Fleet Engine à partir du SDK pilote ou à partir d'un environnement de serveur à l'aide de gRPC ou de REST. N'utilisez pas les deux méthodes pour éviter les conditions de concurrence et maintenir une source unique de vérité.

gRPC

L'exemple suivant montre comment utiliser la bibliothèque Java gRPC pour avertir Fleet Engine qu'un véhicule est arrivé à l'arrêt:

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String VEHICLE_ID = "vehicle-8241890";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Vehicle settings
String vehicleName = "providers/" + PROJECT_ID + "/deliveryVehicles/" + VEHICLE_ID;
DeliveryVehicle deliveryVehicle = DeliveryVehicle.newBuilder()
    // Marking the arrival at stop.
    .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()
       .setStop(VehicleStop.newBuilder()
           .setPlannedLocation(LocationInfo.newBuilder()
               .setPoint(LatLng.newBuilder()
                   .setLatitude(37.7749)
                   .setLongitude(122.4194)))
           .addTasks(TaskInfo.newBuilder().setTaskId(TASK1_ID))
           .setState(VehicleStop.State.ARRIVED)))
    // All other remaining stops marked as NEW.
    .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()  // 2nd stop
       .setStop(VehicleStop.newBuilder()
           .setPlannedLocation(LocationInfo.newBuilder()
               .setPoint(LatLng.newBuilder()
                   .setLatitude(37.3382)
                   .setLongitude(121.8863)))
           .addTasks(TaskInfo.newBuilder().setTaskId(TASK2_ID))
           .setState(VehicleStop.State.NEW))) // Remaining stops must be NEW.
    .build();

// DeliveryVehicle request
UpdateDeliveryVehicleRequest updateDeliveryVehicleRequest =
  UpdateDeliveryVehicleRequest.newBuilder()  // No need for the header
      .setName(vehicleName)
      .setDeliveryVehicle(deliveryVehicle)
      .setUpdateMask(FieldMask.newBuilder()
          .addPaths("remaining_vehicle_journey_segments"))
      .build();

try {
  DeliveryVehicle updatedDeliveryVehicle =
      deliveryService.updateDeliveryVehicle(updateDeliveryVehicleRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case NOT_FOUND:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

Pour informer Fleet Engine de l'arrivée d'un véhicule à un arrêt depuis un environnement de serveur, envoyez un appel HTTP REST à UpdateDeliveryVehicle:

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<id>?updateMask=remainingVehicleJourneySegments`

<id> est un identifiant unique du véhicule de livraison de votre parc pour lequel vous souhaitez mettre à jour l'ordre des tâches. Il s'agit de l'identifiant que vous avez spécifié lors de la création du véhicule.

L'en-tête de requête doit contenir un champ Authorization avec la valeur Bearer <token>, où <token> est un jeton émis par une fabrique de jetons Fleet Engine.

Le corps de la requête doit contenir une entité DeliveryVehicle:

  • Champs obligatoires :

    ChampValeur
    remainingVehicleJourneySegments L'arrêt où vous êtes arrivé avec son état défini sur State.ARRIVED, suivi de la liste des arrêts de véhicules restants avec leurs états marqués comme State.NEW.

  • Champs facultatifs :

    • Aucun

Tous les autres champs de l'entité sont ignorés pour la mise à jour.

Exemple de commande curl :

# Set JWT, PROJECT_ID, VEHICLE_ID, TASK1_ID, and TASK2_ID in the local
# environment
curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles/${VEHICLE_ID}?updateMask=remainingVehicleJourneySegments" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "remainingVehicleJourneySegments": [
    {
      "stop": {
        "state": "ARRIVED",
        "plannedLocation": {
          "point": {
            "latitude": 37.7749,
            "longitude": -122.084061
          }
        },
        "tasks": [
          {
            "taskId": "${TASK1_ID}"
          }
        ]
      }
    },
    {
      "stop": {
        "state": "NEW",
        "plannedLocation": {
          "point": {
            "latitude": 37.3382,
            "longitude": 121.8863
          }
        },
        "tasks": [
          {
            "taskId": "${TASK2_ID}"
          }
        ]
      }
    }
  ]
}
EOM

Le véhicule effectue un arrêt

Fleet Engine doit être averti lorsqu'un véhicule est à l'arrêt. Toutes les tâches associées à l'arrêt sont alors définies sur l'état CLOSED (FERMÉE). Vous pouvez envoyer des notifications à Fleet Engine à partir du SDK pilote ou d'un environnement de serveur à l'aide de gRPC ou de REST. N'utilisez pas les deux méthodes pour éviter les conditions de concurrence et maintenir une source unique de vérité.

gRPC

L'exemple suivant montre comment utiliser la bibliothèque Java gRPC pour avertir Fleet Engine qu'un véhicule a terminé un arrêt.

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String VEHICLE_ID = "vehicle-8241890";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Vehicle settings
String vehicleName = "providers/" + PROJECT_ID + "/deliveryVehicles/" + VEHICLE_ID;
DeliveryVehicle deliveryVehicle = DeliveryVehicle.newBuilder()
    // This stop has been completed and is commented out to indicate it
    // should be removed from the list of vehicle journey segments.
    // .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()
    //    .setStop(VehicleStop.newBuilder()
    //        .setPlannedLocation(LocationInfo.newBuilder()
    //            .setPoint(LatLng.newBuilder()
    //                .setLatitude(37.7749)
    //                .setLongitude(122.4194)))
    //        .addTasks(TaskInfo.newBuilder().setTaskId(TASK1_ID))
    //        .setState(VehicleStop.State.ARRIVED)))
    // All other remaining stops marked as NEW.
    // The next stop could be marked as ENROUTE if the vehicle has begun
    // its journey to the next stop.
    .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()  // Next stop
       .setStop(VehicleStop.newBuilder()
           .setPlannedLocation(LocationInfo.newBuilder()
               .setPoint(LatLng.newBuilder()
                   .setLatitude(37.3382)
                   .setLongitude(121.8863)))
           .addTasks(TaskInfo.newBuilder().setTaskId(TASK2_ID))
           .setState(VehicleStop.State.NEW)))
    .build();

// DeliveryVehicle request
UpdateDeliveryVehicleRequest updateDeliveryVehicleRequest =
  UpdateDeliveryVehicleRequest.newBuilder()  // no need for the header
      .setName(vehicleName)
      .setDeliveryVehicle(deliveryVehicle)
      .setUpdateMask(FieldMask.newBuilder()
          .addPaths("remaining_vehicle_journey_segments"))
      .build();

try {
  DeliveryVehicle updatedDeliveryVehicle =
      deliveryService.updateDeliveryVehicle(updateDeliveryVehicleRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case NOT_FOUND:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

Pour informer Fleet Engine de la fin d'un arrêt depuis un environnement de serveur, envoyez un appel REST HTTP à UpdateDeliveryVehicle:

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<id>?updateMask=remaining_vehicle_journey_segments`

<id> est un identifiant unique du véhicule de livraison de votre parc pour lequel vous souhaitez mettre à jour l'ordre des tâches. Il s'agit de l'identifiant que vous avez spécifié lors de la création du véhicule.

L'en-tête de requête doit contenir un champ Authorization avec la valeur Bearer <token>, où <token> est un jeton émis par une fabrique de jetons Fleet Engine.

Le corps de la requête doit contenir une entité DeliveryVehicle:

  • Champs obligatoires :

    ChampValeur
    remaining_vehicle_journey_segments L'arrêt que vous avez terminé ne devrait plus figurer dans la liste des arrêts restants pour véhicules.

  • Champs facultatifs :

    • Aucun

Tous les autres champs de l'entité sont ignorés pour la mise à jour.

Exemple de commande curl :

    # Set JWT, PROJECT_ID, VEHICLE_ID, TASK1_ID, and TASK2_ID in the local
    # environment
    curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles/${VEHICLE_ID}?updateMask=remainingVehicleJourneySegments" \
      -H "Content-type: application/json" \
      -H "Authorization: Bearer ${JWT}" \
      --data-binary @- << EOM
    {
      "remainingVehicleJourneySegments": [
        {
          "stop": {
            "state": "NEW",
            "plannedLocation": {
              "point": {
                "latitude": 37.3382,
                "longitude": 121.8863
              }
            },
            "tasks": [
              {
                "taskId": "${TASK2_ID}"
              }
            ]
          }
        }
      ]
    }
    EOM

Mettre à jour une tâche

La plupart des champs de tâche sont immuables. Toutefois, vous pouvez modifier l'état, le résultat de la tâche, l'heure du résultat de la tâche, l'emplacement du résultat de la tâche et les attributs en mettant directement à jour l'entité de la tâche. Par exemple, si une tâche n'a pas été attribuée à un véhicule, vous pouvez la fermer en mettant à jour directement l'état.

gRPC

Voici un exemple de mise à jour d'une tâche via gRPC.

REST

Voici un exemple de mise à jour d'une tâche via REST.

Fermer une tâche

Pour fermer une tâche attribuée à un véhicule, informez Fleet Engine que le véhicule a terminé l'arrêt où la tâche a lieu ou supprimez-la de la liste des arrêts des véhicules. Pour ce faire, vous pouvez définir la liste des arrêts restants pour un véhicule, comme vous le feriez pour mettre à jour l'ordre des tâches pour un véhicule.

Si une tâche n'a pas encore de véhicule et doit être fermée, définissez-la sur CLOSED (FERMÉE). Toutefois, vous ne pourrez pas rouvrir une tâche FERMÉE.

La clôture d'une tâche n'indique pas la réussite ou l'échec. Cela indique que la tâche n'est plus considérée comme en cours. Pour le suivi des expéditions, il est important d'indiquer le résultat réel d'une tâche afin qu'un résultat de livraison puisse être affiché.

gRPC

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String TASK_ID = "task-8241890";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Task settings
String taskName = "providers/" + PROJECT_ID + "/tasks/" + TASK_ID;
Task task = Task.newBuilder()
  .setName(taskName)
  .setState(Task.State.CLOSED) // You can only directly CLOSE a
  .build();                    // task that is NOT assigned to a vehicle.

// Task request
UpdateTaskRequest updateTaskRequest =
  UpdateTaskRequest.newBuilder()  // No need for the header
      .setTask(task)
      .setUpdateMask(FieldMask.newBuilder().addPaths("state"))
      .build();

try {
  Task updatedTask = deliveryService.updateTask(updateTaskRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case NOT_FOUND:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

Pour marquer une tâche comme fermée dans un environnement de serveur, envoyez un appel REST HTTP à UpdateTask:

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks/<id>?updateMask=state`

<id> est un identifiant unique pour la tâche.

Votre en-tête de requête doit contenir un champ Authorization avec la valeur Bearer <token>, où <token> est un jeton émis par une fabrique de jetons Fleet Engine.

Vous devez inclure une entité Task dans le corps de la requête:

  • Champs obligatoires :

    ChampValeur
    state State.CLOSED

  • Champs facultatifs :

    ChampValeur
    taskOutcome Outcome.SUCCEEDED ou Outcome.FAILED.
    taskOutcomeTime Heure à laquelle la tâche a été effectuée.
    taskOutcomeLocation Emplacement où la tâche a été effectuée. Fleet Engine est défini par défaut sur le dernier emplacement du véhicule, sauf si le fournisseur le remplace manuellement.

Tous les autres champs de l'entité sont ignorés pour la mise à jour.

Exemple de commande curl :

    # Set JWT, PROJECT_ID, and TASK_ID in the local environment
    curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks/${TASK_ID}?updateMask=state,taskOutcome,taskOutcomeTime" \
      -H "Content-type: application/json" \
      -H "Authorization: Bearer ${JWT}" \
      --data-binary @- << EOM
    {
      "state": "CLOSED",
      "taskOutcome": "SUCCEEDED",
      "taskOutcomeTime": "$(date -u --iso-8601=seconds)"
    }
    EOM

Définir le résultat de la tâche et son emplacement

La clôture d'une tâche n'indique pas la réussite ni l'échec, mais qu'elle n'est plus considérée comme en cours. Pour le suivi des expéditions, il est important d'indiquer le résultat réel d'une tâche afin qu'un résultat de livraison puisse être indiqué et que la facturation des services soit appropriée. Une fois défini, vous ne pouvez plus modifier le résultat de la tâche. Vous pouvez toutefois modifier l'heure et l'emplacement du résultat de la tâche après les avoir définis.

Le résultat des tâches à l'état FERMÉE peut être défini sur SUCCEEDED (SUCCEEDED) ou sur FAILED (ÉCHEC). Fleet Engine ne facture que les tâches de livraison dont l'état est SUCCEEDED.

Lors du marquage du résultat d'une tâche, Fleet Engine remplit automatiquement l'emplacement du résultat de la tâche avec la dernière position connue du véhicule. Vous pouvez ignorer ce comportement.

gRPC

Vous avez la possibilité de définir l'emplacement du résultat de la tâche lorsque vous définissez le résultat. La définition de l'emplacement empêche Fleet Engine de la définir sur la valeur par défaut du dernier emplacement du véhicule. Vous pouvez également écraser ultérieurement l'emplacement de résultat de la tâche défini par Fleet Engine. Fleet Engine n'écrase jamais un emplacement de résultat de tâche que vous indiquez. Vous ne pouvez pas définir d'emplacement de résultat pour une tâche pour laquelle aucun résultat n'est défini. Vous pouvez définir à la fois le résultat de la tâche et son emplacement dans la même requête.

L'exemple suivant montre comment utiliser la bibliothèque Java gRPC pour définir le résultat d'une tâche sur SUCCEEDED et l'emplacement où la tâche a été terminée:

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String TASK_ID = "task-8241890";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Task settings
String taskName = "providers/" + PROJECT_ID + "/tasks/" + TASK_ID;
Task task = Task.newBuilder()
  .setName(taskName)
  .setTaskOutcome(TaskOutcome.SUCCEEDED)
  .setTaskOutcomeTime(now())
  .setTaskOutcomeLocation(               // Grand Indonesia East Mall
    LocationInfo.newBuilder().setPoint(
      LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
  .build();

// Task request
UpdateTaskRequest updateTaskRequest =
  UpdateTaskRequest.newBuilder()  // No need for the header
      .setTask(task)
      .setUpdateMask(FieldMask.newBuilder().addPaths("task_outcome", "task_outcome_time", "task_outcome_location"))
      .build();

try {
  Task updatedTask = deliveryService.updateTask(updateTaskRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case NOT_FOUND:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

Pour marquer une tâche comme terminée à partir d'un environnement de serveur, envoyez un appel REST HTTP à UpdateTask:

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks/<id>?updateMask=taskOutcome,taskOutcomeTime,taskOutcomeLocation`

<id> est un identifiant unique pour la tâche.

L'en-tête de requête doit contenir un champ Authorization avec la valeur Bearer <token>, où <token> est un jeton émis par une fabrique de jetons Fleet Engine.

Le corps de la requête doit contenir une entité Task:

  • Champs obligatoires :

    ChampValeur
    taskOutcome Outcome.SUCCEEDED ou Outcome.FAILED.
    taskOutcomeTime Code temporel du moment où le résultat de la tâche a été défini (à partir du fournisseur). Il s'agit du moment où la tâche a été terminée.

  • Champs facultatifs :

    ChampValeur
    taskOutcomeLocation Emplacement où la tâche a été effectuée. Fleet Engine est défini par défaut sur le dernier emplacement du véhicule, sauf si le fournisseur le remplace manuellement.

Tous les autres champs de l'entité sont ignorés pour la mise à jour.

Exemple de commande curl :

# Set JWT, PROJECT_ID, and TASK_ID in the local environment
curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks/${TASK_ID}?updateMask=taskOutcome,taskOutcomeTime,taskOutcomeLocation" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "taskOutcome": "SUCCEEDED",
  "taskOutcomeTime": "$(date -u --iso-8601=seconds)",
  "taskOutcomeLocation": {
    "point": {
      "latitude": -6.195139,
      "longitude": 106.820826
    }
  }
}
EOM

Réacheminer un colis

Une fois qu'une tâche d'expédition a été créée, son emplacement planifié ne peut plus être modifié. Pour réacheminer un envoi, fermez la tâche d'expédition sans définir de résultat, puis créez une tâche avec l'emplacement planifié mis à jour. Après avoir créé la tâche, attribuez-la au même véhicule. Pour en savoir plus, consultez Fermer la tâche d'expédition et attribuer la tâche.

Utiliser des véhicules d'alimentation et de livraison

Si vous utilisez des véhicules d'alimentation pour transporter des envois vers des véhicules de livraison tout au long de la journée, modélisez le transfert des expéditions comme une tâche d'arrêt programmée pour le véhicule de livraison. Pour assurer un suivi précis de l'emplacement, n'attribuez une tâche de livraison à un colis transféré qu'après son chargement dans le véhicule de livraison. Pour en savoir plus, consultez la section Arrêt programmé.

État de l'expédition du magasin et autres méta-informations

Lorsqu'une tâche d'expédition est terminée, l'état et le résultat de la tâche sont enregistrés dans la tâche. Toutefois, vous pouvez modifier d'autres métadonnées spécifiques à la livraison. Pour stocker d'autres méta-informations que vous pouvez référencer en dehors du service Fleet Engine, utilisez l'ID de suivi associé à la tâche comme clé dans une table externe.

Pour en savoir plus, consultez la page Cycle de vie d'une tâche.

Rechercher un véhicule

Vous pouvez rechercher un véhicule à partir du SDK Driver ou d'un environnement de serveur à l'aide de gRPC ou REST.

gRPC

L'exemple suivant montre comment rechercher un véhicule à l'aide de la bibliothèque Java gRPC:

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String VEHICLE_ID = "vehicle-8241890";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Vehicle request
String name = "providers/" + PROJECT_ID + "/deliveryVehicles/" + VEHICLE_ID;
GetDeliveryVehicleRequest getVehicleRequest = GetDeliveryVehicleRequest.newBuilder()  // No need for the header
    .setName(name)
    .build();

try {
  DeliveryVehicle vehicle = deliveryService.getDeliveryVehicle(getVehicleRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case NOT_FOUND:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

Pour rechercher un véhicule à partir d'un environnement de serveur, envoyez un appel REST HTTP à GetVehicle:

`GET https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<vehicleId>`

<id> est un identifiant unique pour la tâche.

<vehicleId> est l'ID du véhicule à rechercher.

L'en-tête de requête doit contenir un champ Authorization avec la valeur Bearer <token>, où <token> est un jeton émis par une fabrique de jetons Fleet Engine.

Le corps de la requête doit être vide.

Si la recherche aboutit, le corps de la réponse contient une entité de véhicule.

Exemple de commande curl :

# Set JWT, PROJECT_ID, and VEHICLE_ID in the local environment
curl -H "Authorization: Bearer ${JWT}" \
  "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles/${VEHICLE_ID}"

Rechercher une tâche

Vous pouvez rechercher une tâche à partir d'un environnement de serveur à l'aide de gRPC ou de REST. Le SDK Driver ne permet pas de rechercher une tâche.

gRPC

L'exemple suivant montre comment rechercher une tâche à l'aide de la bibliothèque Java gRPC:

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String TASK_ID = "task-8597549";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Task request
String taskName = "providers/" + PROJECT_ID + "/tasks/" + TASK_ID;
GetTaskRequest getTaskRequest = GetTaskRequest.newBuilder()  // No need for the header
    .setName(taskName)
    .build();

try {
  Task task = deliveryService.getTask(getTaskRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case NOT_FOUND:
       break;

     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

Pour rechercher une tâche à partir d'un environnement de serveur, envoyez un appel REST HTTP à GetTask:

`GET https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks/<taskId>`

<id> est un identifiant unique pour la tâche.

<taskId> est l'ID de la tâche à rechercher.

L'en-tête de requête doit contenir un champ Authorization avec la valeur Bearer <token>, où <token> est un jeton émis par une fabrique de jetons Fleet Engine.

Le corps de la requête doit être vide.

Si la recherche aboutit, le corps de la réponse contient une entité de tâche.

Exemple de commande curl :

    # Set JWT, PROJECT_ID, and TASK_ID in the local environment
    curl -H "Authorization: Bearer ${JWT}" \
      "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks/${TASK_ID}"

Rechercher les informations sur la tâche d'expédition selon son ID de suivi

Vous pouvez consulter les informations sur les tâches d'expédition de différentes manières, chacune ayant un objectif distinct:

  • Par un ID de tâche: utilisé par les utilisateurs tels que les opérateurs de parc qui ont accès à une vue complète des données de tâche.
  • Par un ID de suivi: utilisé par votre logiciel client pour fournir des informations limitées à un utilisateur final, par exemple lorsqu'un colis est attendu chez lui.

Cette section explique comment rechercher des informations sur une tâche à l'aide d'un ID de suivi. Si vous souhaitez rechercher une tâche à partir de son ID, consultez la section Rechercher une tâche.

Pour rechercher des informations à l'aide d'un ID de suivi, vous pouvez utiliser l'une des méthodes suivantes:

Exigences concernant la recherche

  • Les informations de livraison fournies par un ID de suivi respectent les règles de visibilité définies dans la section Contrôler la visibilité des établissements suivis.

  • Utilisez Fleet Engine pour rechercher des informations de livraison par ID de suivi. Le SDK Driver ne prend pas en charge la recherche d'informations par ID de suivi. Pour ce faire avec Fleet Engine, vous utilisez un environnement de serveur ou de navigateur.

  • Utilisez le jeton le plus étroit possible pour limiter les risques de sécurité. Par exemple, si vous utilisez un jeton de consommateur de livraison, tous les appels de l'API Fleet Engine Deliveries renvoient uniquement des informations pertinentes pour cet utilisateur final, comme le transporteur ou le destinataire d'une livraison. Toutes les autres informations contenues dans les réponses sont masquées. Pour en savoir plus sur les jetons, consultez la page Créer un jeton Web JSON (JWT) pour l'autorisation.

Recherches avec Java à l'aide de gRPC

L'exemple suivant montre comment utiliser la bibliothèque Java gRPC pour rechercher des informations sur une tâche de livraison à l'aide de son ID de suivi.

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String TRACKING_ID = "TID-7449w087464x5";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Tasks request
String parent = "providers/" + PROJECT_ID;
GetTaskTrackingInfoRequest getTaskTrackingInfoRequest = GetTaskTrackingInfoRequest.newBuilder()  // No need for the header
    .setParent(parent)
    .setTrackingId(TRACKING_ID)
    .build();

try {
  TaskTrackingInfo taskTrackingInfo = deliveryService.getTaskTrackingInfo(getTaskTrackingInfoRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case NOT_FOUND:
       break;

     case PERMISSION_DENIED:
       break;
  }
  return;
}

Recherches utilisant HTTP

Pour rechercher une tâche de livraison dans un navigateur, envoyez un appel REST HTTP à GetTaskTrackingInfo:

`GET https://fleetengine.googleapis.com/v1/providers/<project_id>/taskTrackingInfo/<tracking_id>`

<tracking_id> est l'ID de suivi associé à la tâche.

L'en-tête de requête doit contenir un champ Authorization avec la valeur Bearer <token>, où <token> est un jeton émis par une fabrique de jetons Fleet Engine.

Si la recherche aboutit, le corps de la réponse contient une entité taskTrackingInfo.

Exemple de commande curl :

# Set JWT, PROJECT_ID, and TRACKING_ID in the local environment
curl -H "Authorization: Bearer ${JWT}" \
  "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/taskTrackingInfo/${TRACKING_ID}"

Répertorier les tâches

Vous pouvez répertorier les tâches à partir d'un environnement de serveur ou de navigateur. Le SDK Driver n'est pas compatible avec l'établissement de listes de tâches.

L'affichage d'une liste de tâches nécessite un accès étendu aux tâches. La liste des tâches est destinée uniquement aux utilisateurs de confiance. Utilisez le lecteur de parc de livraison ou les jetons d'authentification de super-utilisateur de livraison lorsque vous effectuez des requêtes de tâches de liste.

Les champs suivants sont masqués pour les tâches répertoriées:

  • VehicleStop.planned_location
  • VehicleStop.state
  • VehicleStop.TaskInfo.taskId

Les tâches répertoriées peuvent être filtrées selon la plupart des propriétés de tâche. Pour connaître la syntaxe des requêtes de filtre, consultez AIP-160. La liste suivante présente les propriétés de tâche valides que vous pouvez utiliser pour le filtrage:

  • attributs
  • delivery_vehicle_id
  • state
  • planned_location
  • task_duration
  • task_outcome
  • task_outcome_location
  • task_outcome_location_source
  • task_outcome_time
  • tracking_id
  • type

Utilisez les formats de champs suivants en fonction des propositions d'amélioration de l'API Google:

Type de champ Format Exemple
Code temporel RFC-3339 task_outcome_time = 2022-03-01T11:30:00-08:00
Durée Nombre de secondes suivies d'un élément s task_duration = 120s
Énumération Chaîne state = CLOSED AND type = PICKUP
Emplacement point.latitude et point.longitude planned_location.point.latitude > 36.1 AND planned_location.point.longitude < -122.0

Consultez AIP-160 pour obtenir la liste complète des opérateurs de requête de filtre.

Si aucune requête de filtre n'est spécifiée, toutes les tâches sont répertoriées.

Les listes de tâches sont paginées. Une taille de page peut être spécifiée dans les demandes de liste de tâches. Si une taille de page est spécifiée, le nombre de tâches renvoyées n'est pas supérieur à la taille de page spécifiée. Si aucune taille de page n'est indiquée, une valeur par défaut raisonnable est utilisée. Si la taille de page demandée dépasse une valeur maximale interne, la valeur maximale interne est utilisée.

Une liste de tâches peut inclure un jeton permettant de lire la page de résultats suivante. Utilisez le jeton de page avec une requête identique à la requête précédente pour récupérer la page de tâches suivante. Lorsque le jeton de page renvoyé est vide, plus aucune tâche n'est disponible pour la récupération.

gRPC

L'exemple suivant montre comment utiliser la bibliothèque Java gRPC pour répertorier les tâches pour un DeliveryVehicleId et un attribut de tâche. Une réponse réussie peut toujours être vide. Une réponse vide indique qu'aucune tâche n'est associée à l'identifiant DeliveryVehicleId fourni.

static final String PROJECT_ID = "my-delivery-co-gcp-project";
static final String TRACKING_ID = "TID-7449w087464x5";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Tasks request
String parent = "providers/" + PROJECT_ID;
ListTasksRequest listTasksRequest = ListTasksRequest.newBuilder()  // No need for the header
    .setParent(parent)
    .setFilter("delivery_vehicle_id = 123 AND attributes.foo = true")
    .build();

try {
  ListTasksResponse listTasksResponse = deliveryService.listTasks(listTasksRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case NOT_FOUND:
       break;

     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

Pour répertorier les tâches à partir d'un navigateur, envoyez un appel REST HTTP à ListTasks:

`GET https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks`

Pour appliquer un filtre aux tâches listées, incluez un paramètre d'URL "filter" avec une requête de filtre avec échappement comme valeur d'URL.

L'en-tête de requête doit contenir un champ Authorization avec la valeur Bearer <token>, où <token> est un jeton émis par une fabrique de jetons Fleet Engine.

Si la recherche aboutit, le corps de la réponse contient des données présentant la structure suivante:

    // JSON representation
    {
      "tasks": [
        {
          object (Task)
        }
      ],
      "nextPageToken": string,
      "totalSize": integer
    }

Une réponse positive peut rester vide. Une réponse vide indique qu'aucune tâche ne correspond aux critères de filtre spécifiés.

Exemple de commande curl :

    # Set JWT, PROJECT_ID, and VEHICLE_ID in the local environment
    curl -H "Authorization: Bearer ${JWT}" \
      "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks?filter=state%20%3D%20OPEN%20AND%20delivery_vehicle_id%20%3D%20${VEHICLE_ID}"

Lister les véhicules de livraison

Vous pouvez lister les véhicules de livraison à partir d'un environnement de serveur ou de navigateur. Le SDK Driver ne permet pas de lister les véhicules de livraison.

Répertorier les véhicules de livraison nécessite un accès étendu aux véhicules de livraison et est destiné uniquement aux utilisateurs de confiance. Utilisez des lecteurs de parc de livraison ou des jetons d'authentification super-utilisateur de livraison lorsque vous effectuez des requêtes de véhicules de livraison de listes.

Les champs suivants des véhicules de livraison répertoriés sont masqués en raison de leur impact sur la taille des réponses:

  • CurrentRouteSegment
  • RemainingVehicleJourneySegments

Vous pouvez filtrer les véhicules de livraison de liste en fonction de leur propriété attributes. Par exemple, pour interroger un attribut avec la clé my_key et la valeur my_value, utilisez attributes.my_key = my_value. Pour interroger plusieurs attributs, joignez les requêtes à l'aide des opérateurs logiques AND et OR, comme dans attributes.key1 = value1 AND attributes.key2 = value2. Consultez la page AIP-160 pour obtenir une description complète de la syntaxe des requêtes de filtre.

Vous pouvez filtrer les véhicules de livraison répertoriés par emplacement à l'aide du paramètre de requête viewport. Le paramètre de requête viewport définit les fenêtres d'affichage à l'aide de deux coordonnées de délimitation: une paire de coordonnées de latitude et de longitude high (nord-ouest) et low (sud-ouest). Les requêtes sont refusées si elles contiennent une haute latitude géographiquement plus basse qu'une faible latitude.

Par défaut, les listes des véhicules de livraison sont paginées à l'aide d'une taille de page raisonnable. Si vous spécifiez une taille de page, la requête ne renvoie que le nombre de véhicules spécifié par cette limite, au maximum. Si la taille de page demandée dépasse une valeur interne maximale, la valeur maximale interne est utilisée. Les tailles de page par défaut et maximale sont toutes deux de 100 véhicules.

Une liste de véhicules de livraison peut inclure un jeton permettant de lire la page de résultats suivante. Un jeton de page n'est présent dans une réponse que lorsque davantage de pages de véhicules de livraison peuvent être récupérées. Pour récupérer la page de tâches suivante, utilisez le jeton de page avec une requête identique à la précédente.

gRPC

L'exemple suivant montre comment utiliser la bibliothèque Java gRPC pour lister les véhicules de livraison d'une région particulière avec un certain attribut. Une réponse réussie peut toujours être vide. Dans ce cas, cela signifie qu'aucun véhicule avec l'attribut spécifié ne se trouve déjà dans la fenêtre d'affichage spécifiée.

static final String PROJECT_ID = "my-delivery-co-gcp-project";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Tasks request
String parent = "providers/" + PROJECT_ID;
ListDeliveryVehiclesRequest listDeliveryVehiclesRequest =
  ListDeliveryVehiclesRequest.newBuilder()  // No need for the header
      .setParent(parent)
      .setViewport(
            Viewport.newBuilder()
              .setHigh(LatLng.newBuilder()
                  .setLatitude(37.45)
                  .setLongitude(-122.06)
                  .build())
              .setLow(LatLng.newBuilder()
                  .setLatitude(37.41)
                  .setLongitude(-122.11)
                  .build())
      .setFilter("attributes.my_key = my_value")
      .build();

try {
  ListDeliveryVehiclesResponse listDeliveryVehiclesResponse =
      deliveryService.listDeliveryVehicles(listDeliveryVehiclesRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
      case NOT_FOUND:
          break;

      case PERMISSION_DENIED:
          break;
  }
  return;
}

REST

Pour répertorier les tâches à partir d'un navigateur, envoyez un appel REST HTTP à ListDeliveryVehicles:

`GET https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles`

Pour appliquer un filtre aux tâches listées, incluez un paramètre d'URL "filter" avec une requête de filtre avec échappement comme valeur.

L'en-tête de requête doit contenir un champ Authorization avec la valeur Bearer <token>, où <token> est un jeton émis par une fabrique de jetons Fleet Engine.

Si la recherche aboutit, le corps de la réponse contient des données présentant la structure suivante:

// JSON representation
{
  "deliveryVehicles": [
    {
      object (DeliveryVehicle)
    }
  ],
  "nextPageToken": string,
  "totalSize": integer
}

Une réponse positive peut rester vide. Dans ce cas, cela signifie qu'aucun véhicule de livraison ne correspond à la requête de filtre et à la fenêtre d'affichage spécifiées.

Exemple de commande curl :

# Set JWT, PROJECT_ID, and VEHICLE_ID in the local environment
curl -H "Authorization: Bearer ${JWT}" \
  "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles?filter=attributes.my_key%20%3D%20my_value%20&viewport.high.latitude=37.45&viewport.high.longitude=-122.06&viewport.low.latitude=37.41&viewport.low.longitude=-122.11"

Suivi de la livraison

Vous avez deux options pour utiliser l'API Fleet Engine Deliveries afin d'activer le suivi des expéditions:

  • Préféré:utilisez la bibliothèque JavaScript Shipment Tracking. La bibliothèque vous permet de visualiser l'emplacement des véhicules et les lieux d'intérêt suivis dans Fleet Engine. Elle contient un composant de carte JavaScript qui remplace directement un objet google.maps.Map standard, ainsi que des composants de données à connecter à Fleet Engine. Ce composant vous permet de proposer une expérience de suivi des livraisons animée et personnalisable à partir de votre application Web ou mobile.

  • Mettez en place votre propre suivi des expéditions en plus de l'API Fleet Engine Deliveries.

La solution consiste à rechercher les tâches de livraison par ID de suivi.

Si vous utilisez le rôle Consommateur de livraison, les appels de l'API Fleet Engine Deliveries ne renvoient que des informations pertinentes pour un expéditeur ou un destinataire. Toutes les autres informations contenues dans les réponses sont masquées. Vous êtes responsable de l’authentification des utilisateurs finaux. De plus, les informations de localisation sont filtrées en fonction de la tâche déjà en cours. Lors d'une tâche d'indisponibilité, aucune information de localisation n'est partagée avec un utilisateur final.

Journalisation

Vous pouvez configurer Fleet Engine pour qu'il envoie des journaux RPC à Cloud Logging. Pour en savoir plus, consultez la section Journalisation.

Rôles d'autorisation et jetons

Comme décrit dans Gérer le cycle de vie du véhicule et des tâches et dans les notes d'autorisation pour des cas d'utilisation individuels, les appels à Fleet Engine nécessitent une authentification avec des jetons Web JSON signés à l'aide des identifiants du compte de service. Les comptes de service utilisés pour émettre ces jetons peuvent avoir un ou plusieurs rôles, chacun accordant un ensemble d'autorisations différent.

Pour en savoir plus, consultez la page Authentification et autorisation.

Résoudre les problèmes courants

En cas de problème, consultez les sections suivantes pour obtenir de l'aide.

Résilience

Fleet Engine n'est pas considéré comme une source de référence. Il vous incombe de restaurer l'état de votre système, si nécessaire, sans dépendre de Fleet Engine.

État perdu dans Fleet Engine

Lorsque vous utilisez Fleet Engine, implémentez des clients de sorte que le système répare lui-même en cas de défaillance. Par exemple, lorsque Fleet Engine tente de mettre à jour un véhicule, il peut renvoyer une erreur indiquant que le véhicule n'existe pas. Le client doit ensuite recréer le véhicule dans son nouvel état. Bien que ce problème se produise rarement, assurez-vous que votre système est suffisamment résilient pour le gérer.

Dans le scénario extrêmement improbable d'une défaillance catastrophique de Fleet Engine, vous devrez peut-être recréer la plupart ou l'ensemble des véhicules et des tâches. Si le taux de création devient trop élevé, certaines requêtes peuvent échouer à nouveau en raison de problèmes de quota, car des vérifications de quota sont en place pour éviter les attaques par déni de service (DoS). Dans ce cas, ralentissez le taux de recréation à l'aide d'une stratégie d'intervalle entre les tentatives pour les nouvelles tentatives.

État perdu dans l'application du conducteur

Si l'application de pilote plante, elle doit recréer l'état actuel dans le SDK Driver. L'application doit tenter de recréer des tâches pour s'assurer qu'elles existent et restaurer leurs états actuels. L'application doit également recréer et définir explicitement la liste des arrêts pour le SDK Driver.

Questions fréquentes

Que se passe-t-il si un chauffeur s'arrête pour une tâche dans le désordre ?

Dans ce cas, commencez par mettre à jour l'ordre des tâches, puis continuez comme prévu, en indiquant l'arrivée à l'arrêt, l'achèvement de la tâche et d'autres détails. Si vous ne le faites pas, le système peut devenir incohérent, les ATA peuvent devenir incorrectes et des erreurs inattendues peuvent être signalées.