Aggiorna lo stato della fermata

Questo documento presuppone che tu abbia familiarità con quanto segue:

  • [Crea attività di spedizione][1]
  • L'introduzione alle [Attività programmate][3], che illustra in dettaglio la relazione tra attività, fermate e veicoli.

Come indicato in [Attività pianificate][3] in Concetti essenziali di Fleet Engine, crei le attività e le associ a una fermata del veicolo per modellare l'associazione reale tra l'attività e la località in cui è previsto che il veicolo si fermi in modo che il conducente possa completare l'attività.

Da qui, gestisci l'avanzamento delle attività durante il loro ciclo di vita inviando aggiornamenti a Fleet Engine in modo che possa eseguire al meglio il routing e gli aggiornamenti di stato durante il percorso dell'attività. Un modo fondamentale per farlo è aggiornare la fermata del veicolo quando questo si avvicina, arriva e parte dalla fermata. In questo modo, è possibile generare report e analisi sull'avanzamento delle attività sia per gli operatori del parco veicoli sia per gli utenti finali. Questi aggiornamenti di stato sono i seguenti:

  • In viaggio: l'enum STATE per VehicleStop utilizza ENROUTE per indicare che la fermata è la successiva nell'elenco dell'itinerario del veicolo. Dal punto di vista dell'attività, significa che qualsiasi attività associata alla fermata è la prossima nell'elenco da completare.
  • Arrivato: l'enum STATE per VehicleStop utilizza ARRIVED per indicare che il veicolo è arrivato alla fermata. Dal punto di vista dell'attività, significa che qualsiasi attività associata non viene più elaborata attivamente.
  • Completata: contrassegni una fermata come completata rimuovendola dall'elenco delle fermate del veicolo. In questo modo, Fleet Engine contrassegna automaticamente tutte le attività associate come CHIUSE. Per maggiori dettagli sulla chiusura delle attività, consulta [Finalizza le attività][4].

Questo documento descrive come aggiornare lo stato delle fermate utilizzando approcci lato server. Puoi farlo anche dalla tua app per conducenti se offri al conducente la possibilità di gestire le attività utilizzando un dispositivo attendibile. Utilizza un solo metodo per evitare race condition e mantenere un'unica Single Source Of Truth.

Il veicolo è in viaggio verso la fermata

Il tuo sistema deve inviare una notifica a Fleet Engine quando il veicolo inizia la navigazione verso la fermata successiva. In questo modo, i calcoli dell'orario di arrivo stimato e del percorso vengono migliorati.

Campi obbligatori per gli aggiornamenti delle fermate

Fleet Engine ignora tutti gli altri campi dell'entità per la notifica.

CampoValore
remainingVehicleJourneySegments Elenco delle fermate del veicolo rimanenti con i relativi stati contrassegnati come State.NEW.

Esempio di percorso verso una fermata

I seguenti esempi mostrano come notificare a Fleet Engine che un veicolo è in viaggio verso la fermata successiva, utilizzando la [libreria gRPC Java][5] o una chiamata REST HTTP a UpdateDeliveryVehicle.Tutte le altre fermate sono contrassegnate come nuove.

gRPC

 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

PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<id>?updateMask=remainingVehicleJourneySegments`
  • <id> è un identificatore univoco dell'attività.
  • L'intestazione della richiesta deve contenere un campo Authorization con il valore Bearer <token>, dove <token> viene emesso dal tuo server in base alle linee guida descritte in [Ruoli dei service account][6] e [Token web JSON][6].
  • Il corpo della richiesta deve contenere un'entità DeliveryVehicle:

Comando curl di esempio:

 # 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

placeidtrips1: /maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.html#locationinfo placeidtrips2: /maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/LocationInfo.html placeidtrips3: /maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.html#maps.fleetengine.delivery.v1.LocationInfo.FIELDS.string.maps.fleetengine.delivery.v1.LocationInfo.place placeidtrips4: /maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/LocationInfo.html#FIELDS.place

Il veicolo arriva alla fermata

Fleet Engine deve essere informato quando un veicolo arriva a una fermata.

Campi obbligatori per gli aggiornamenti delle fermate

Fleet Engine ignora tutti gli altri campi dell'entità per la notifica.

CampoValore
remainingVehicleJourneySegments Elenco delle fermate del veicolo rimanenti con i relativi stati contrassegnati come State.NEW.

Esempio di arrivo alla fermata

I seguenti esempi mostrano come inviare una notifica a Fleet Engine per comunicare che un veicolo è arrivato alla fermata, utilizzando la [libreria gRPC Java][5] o una chiamata REST HTTP a UpdateDeliveryVehicle. Tutte le altre fermate sono contrassegnate come nuove.

gRPC

  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

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<id>?updateMask=remainingVehicleJourneySegments`
  • <id> è un identificatore univoco dell'attività.
  • L'intestazione della richiesta deve contenere un campo Authorization con il valore Bearer <token>, dove <token> viene emesso dal tuo server in base alle linee guida descritte in [Ruoli dei service account][6] e [Token web JSON][6].
  • Il corpo della richiesta deve contenere un'entità DeliveryVehicle:

Comando curl di esempio:

  # 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

Il veicolo completa una sosta

Fleet Engine deve essere informato quando un veicolo completa una sosta. In questo modo, tutte le attività associate alla fermata vengono impostate sullo stato CLOSED.

Campi obbligatori per gli aggiornamenti delle fermate

Fleet Engine ignora tutti gli altri campi dell'entità per la notifica.

CampoValore
remainingVehicleJourneySegments Elenco delle fermate del veicolo rimanenti con i relativi stati contrassegnati come State.NEW. La prima fermata dell'elenco deve avere lo stato impostato su State.ENROUTE.

Completa un esempio di fermata

I seguenti esempi mostrano come inviare una notifica a Fleet Engine per comunicare che un veicolo è arrivato alla fermata, utilizzando la [libreria gRPC Java][5] o una chiamata REST HTTP a UpdateDeliveryVehicle. Tutte le altre fermate sono contrassegnate come nuove.

gRPC

  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

PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<id>?updateMask=remaining_vehicle_journey_segments`
  • <id> è un identificatore univoco dell'attività.
  • L'intestazione della richiesta deve contenere un campo Authorization con il valore Bearer <token>, dove <token> viene emesso dal tuo server in base alle linee guida descritte in [Ruoli dei service account][6] e [Token web JSON][6].
  • Il corpo della richiesta deve contenere un'entità DeliveryVehicle:

Comando curl di esempio:

 # 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

placeidtrips1: /maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.html#locationinfo placeidtrips2: /maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/LocationInfo.html placeidtrips3: /maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.html#maps.fleetengine.delivery.v1.LocationInfo.FIELDS.string.maps.fleetengine.delivery.v1.LocationInfo.place placeidtrips4: /maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/LocationInfo.html#FIELDS.place

Passaggi successivi

  • [Finalizza le attività][4]

[1]: /maps/documentation/mobility/fleet-engine/journeys/tasks/create-shipment-tasks [3]: /maps/documentation/mobility/fleet-engine/essentials/tasks-intro [4]: /maps/documentation/mobility/fleet-engine/journeys/tasks/finalize-tasks [5]: /maps/documentation/mobility/fleet-engine/essentials/client-libraries-tasks [6]: /maps/documentation/mobility/fleet-engine/essentials/set-up-fleet/service-accounts