Pierwsze kroki z Fleet Engine do śledzenia przesyłek

Za pomocą interfejsu Fleet Engine Deliveries API modeluj działania floty na pierwszą i ostatnią milę dostaw. Z tego interfejsu API możesz korzystać w pakiecie Driver SDK na Androida i iOS albo bezpośrednio za pomocą wywołań HTTP typu REST lub gRPC.

Konfiguracja początkowa

Interfejs Fleet Engine Deliveries API możesz skonfigurować w konsoli Google Cloud.

Sprawdzanie konfiguracji

Po utworzeniu kont usługi sprawdź, czy konfiguracja została ukończona i czy możesz utworzyć pojazd dostawczy. Natychmiastowa weryfikacja konfiguracji daje pewność, że rozwiążesz typowe problemy z autoryzacją, które mogą się pojawić podczas konfigurowania projektu. Konfigurację możesz zweryfikować na 2 sposoby:

Biblioteki klienta

Aby ułatwić programistom pracę w porównaniu z nieprzetworzonym gRPC lub REST, użyj bibliotek klienta w kilku popularnych językach programowania. Instrukcje uzyskiwania bibliotek klienta dla aplikacji serwerowej znajdziesz w artykule Biblioteki klienta.

W przykładach w Javie w tej dokumentacji zakładamy, że znasz gRPC.

Struktury danych

Interfejs Fleet Engine Deliveries API wykorzystuje 2 struktury danych do modelowania odbioru i dostawy przesyłek:

  • Pojazd dostawczy używany do transportu przesyłki.
  • Zadania związane z odbiorem i dostawą przesyłki.

Za pomocą zadań możesz też modelować przerwy kierowcy i zaplanowane postoje w ciągu dnia.

Pojazdy dostawcze

Pojazdy dostawcze służą do transportu przesyłek z zakładu do miejsca dostawy oraz z miejsca odbioru do magazynu. W niektórych przypadkach firma może również przewieźć przesyłkę bezpośrednio z miejsca odbioru do miejsca dostawy.

Użyj Driver SDK, aby utworzyć obiekt DeliveryVehicle we Fleet Engine i wysyłać aktualizacje lokalizacji na potrzeby śledzenia przesyłki i floty.

Lista zadań

Zadania, które pojazd wykonuje w ciągu dnia, przypisujesz w zależności od ich typu:

  • W przypadku odbioru i dostawy przypisz Zadania związane z dostawą.
  • W sytuacjach, gdy kierowcy nie są dostępni, np. w przypadku wymaganych przerw, przypisz zadania dotyczące niedostępności.
  • Do zadań niezwiązanych z jazdą w skrzynkach referencyjnych lub lokalizacjach klientów przypisz zadania zaplanowanego zatrzymania.

Każde przypisane zadanie musi mieć unikalny identyfikator zadania, ale zadania mogą mieć ten sam identyfikator śledzenia. Gdy Fleet Engine oblicza okna z szacowanym czasem dotarcia na miejsce dla każdego zadania, wykorzystuje wszystkie zadania w kolejności, w której są zaplanowane do szacowania. Więcej informacji o identyfikatorach zadań znajdziesz w artykule ze wskazówkami na temat identyfikatorów zadań.

Aby utworzyć zadania we Fleet Engine, użyj menedżera zadań pakietu Driver SDK.

Zadania związane z dostawą

Utwórz zadania związane z dostawą przesyłki obejmujące zarówno odbiór, jak i dostawę, i podaj w niej te informacje:

  • Lokalizacja odbioru lub dostawy.
  • Numer śledzenia lub identyfikator.
  • To dodatkowy czas na wykonanie zadania, poszukiwanie parkingu lub przejście do miejsca przekazania.
  • Unikalny identyfikator zadania. Zobacz wytyczne dotyczące identyfikatorów zadań.

Więcej informacji znajdziesz w tych tematach:

Android

iOS

Zadania związane z niedostępnością

Zadania związane z niedostępnością obejmują okresy, w których pojazd nie jest dostępny do odbioru lub dostawy, takie jak przerwy na uzupełnienie paliwa lub przerwy kierowcy.

Utwórz zadanie dotyczące niedostępności z tymi informacjami:

  • Długość przerwy.
  • Opcjonalnie lokalizacja przerwy. Nie musisz podawać konkretnej lokalizacji, ale dzięki temu w ciągu dnia będą dostępne dokładniejsze informacje o szacowanym czasie dotarcia na miejsce.

Więcej informacji znajdziesz w tych tematach:

Android

iOS

Zadania zaplanowanego zatrzymania

Utwórz zadania zaplanowanych przystanków, aby modelować przystanki, które musi wykonać pojazd dostawczy. Możesz na przykład utworzyć zaplanowane zadanie zatrzymania dla codziennego zaplanowanego postoju na odbiór w określonej lokalizacji, niezależnie od innych dostaw lub odbioru w tym samym miejscu. Możesz też tworzyć zaplanowane zadania zatrzymania dla odbiór ze skrzynek referencyjnych lub modelowania transferów między pojazdami dostarczającymi informacje o ruchu lub zatrzymania się w centrach serwisowych i punktach serwisowych.

Więcej informacji znajdziesz w tych tematach:

Android

iOS

Wskazówki dotyczące identyfikatora zadania

Podczas tworzenia identyfikatorów zadań postępuj zgodnie z tymi wskazówkami dotyczącymi treści i formatu:

  • Tworzenie unikalnych identyfikatorów zadań
  • Nie ujawniaj żadnych informacji umożliwiających identyfikację osób ani nie ujawniaj danych tekstowych.
  • Użyj prawidłowych ciągów Unicode.
  • Użyj maksymalnie 64 znaków.
  • Nie używaj tych znaków ASCII: „/”, „:”, „\"”, „?” ani „#”.
  • Normalizuj zgodnie z formularzem normalizacji Unicode C.

Oto kilka przykładów prawidłowych identyfikatorów zadań:

  • 566c33d9-2a31-4b6a-9cd4-80ba1a0c643b
  • E4708eabcfa39bf2767c9546c9273f747b4626e8cc44e9630d50f6d129013d38
  • NTA1YTliYWNkYmViMTI0ZmMzMZMWFMOWY2NzNkM2Jk

W tej tabeli znajdziesz przykłady nieobsługiwanych identyfikatorów zadań:

Nieobsługiwane identyfikatory zadań Przyczyna
8/31/2019-20:48-46.70746,-130.10807,-85.17909,61.33680 Narusza wymagania dotyczące informacji umożliwiających identyfikację i znaków: przecinki, kropki, dwukropki i ukośniki.
JohnDoe-577b484da26f-Cupertino-SantaCruz Narusza wymagania dotyczące informacji umożliwiających identyfikację.
4R0oXLToF"112 Summer Dr. East Hartford, CT06118"577b484da26f8a Narusza wymagania dotyczące informacji umożliwiających identyfikację i znaków: odstępy, przecinki i cudzysłowy. Ma ponad 64 znaki.

Więcej materiałów

Aby dowiedzieć się, jakie pola znajdują się w poszczególnych strukturach danych, zapoznaj się z dokumentacją interfejsów API DeliveryVehicle (gRPC, REST) i Task (gRPC, REST).

Żywotność pojazdu

Obiekt DeliveryVehicle reprezentuje pojazd dostarczany na pierwszej lub ostatniej mili. Tworzysz obiekt DeliveryVehicle za pomocą:

  • Identyfikator projektu Google Cloud zawierającego konto usługi używane do wywoływania interfejsów Fleet Engine API.
  • Identyfikator pojazdu należący do klienta.

Każdy pojazd ma unikalny identyfikator. Nie używaj ponownie identyfikatora pojazdu, chyba że pierwotny pojazd nie ma żadnych aktywnych zadań.

Fleet Engine automatycznie usuwa DeliveryVehicle obiekty, które nie zostały zaktualizowane za pomocą UpdateDeliveryVehicle po 7 dniach. Aby sprawdzić, czy pojazd istnieje:

  1. Zadzwoń pod numer UpdateDeliveryVehicle.
  2. Jeśli pojawi się błąd NOT_FOUND, wywołaj CreateDeliveryVehicle, aby odtworzyć pojazd. Jeśli połączenie zwróci pojazd, można go zaktualizować.

Rodzaj pojazdu

Element VehicleType zawiera opcjonalne pole VehicleType, w którym znajduje się wyliczenie Category, które możesz określić jako AUTO, TWO_WHEELER, BICYCLE lub PEDESTRIAN. Jeśli nie skonfigurujesz tego pola, domyślnie przyjęta zostanie wartość AUTO.

Podczas ustalania trasy w przypadku pojazdów używany jest podany typ pojazdu RouteTravelMode.

Atrybuty pojazdu

Element DeliveryVehicle zawiera pole powtarzane DeliveryVehicleAttribute. Interfejs API ListDeliveryVehicles zawiera pole filter, które może ograniczyć zwracane elementy DeliveryVehicle do tych o określonych atrybutach. DeliveryVehicleAttribute nie wpływa na zachowanie routingu Fleet Engine.

Nie podawaj w atrybutach informacji umożliwiających identyfikację osób ani informacji poufnych, ponieważ to pole może być widoczne dla użytkowników.

Cykl życia zadania

Za pomocą interfejsów gRPC lub REST interfejsu Deliveries API możesz tworzyć i aktualizować zadania oraz wykonywać w nich zapytania.

Obiekt Task ma pole stanu umożliwiające śledzenie postępów w cyklu życia. Wartości zmienią się z OTWÓRZ na ZAMKNIĘTE. Nowe zadania są tworzone w stanie OTWARTE, co oznacza, że:

  • Zadanie nie zostało jeszcze przypisane do pojazdu dostawczego.
  • Pojazd dostarczający nie ukończył jeszcze przystanku pojazdu przypisanego do zadania.

Wytyczne dotyczące zadań

Zadanie możesz przypisać do pojazdu tylko w stanie OTWARTY.

Aby anulować zadanie, usuń je z listy przystanków pojazdu, co spowoduje automatyczne ustawienie stanu zadania na ZAMKNIĘTE.

Gdy pojazd wykonujący zadanie ukończy jego zatrzymanie:

  1. Zmień pole wyniku zadania na SUCCEEDED lub FAILED.

  2. Podaj sygnaturę czasową zdarzenia.

    Biblioteka śledzenia przesyłek JavaScript wyświetli wynik zadania, a jego stan zostanie automatycznie zmieniony na ZAMKNIĘTE. Więcej informacji znajdziesz w artykule o śledzeniu przesyłki za pomocą biblioteki śledzenia przesyłki JavaScript.

Podobnie jak w przypadku pojazdów, Fleet Engine usuwa zadania, które nie zostały zaktualizowane po 7 dniach, a jeśli spróbujesz utworzyć zadanie o identyfikatorze, który już istnieje, wyświetli się błąd.

Uwaga: Fleet Engine nie obsługuje wyraźnego usuwania zadania. Usługa automatycznie usuwa zadania po 7 dniach bez aktualizacji. Jeśli chcesz przechowywać dane o zadaniach dłużej niż przez 7 dni, musisz wdrożyć tę funkcję samodzielnie.

Atrybuty zadania

Element Task zawiera pole powtarzane TaskAttribute, które może mieć wartość jednego z 3 typów: ciąg znaków, liczba i wartość logiczna. Interfejs API ListTasks zawiera pole filter, które może ograniczyć zwracane elementy Task do tych o określonych atrybutach. Atrybuty zadań nie mają wpływu na działanie routingu Fleet Engine.

Nie umieszczaj w atrybutach informacji umożliwiających identyfikację osób ani innych informacji poufnych, ponieważ mogą one być widoczne dla użytkowników.

Zarządzanie cyklem życia pojazdu i zadań

Przypomnienie: Twój system wewnętrzny działa jako zaufane źródło danych, które interfejs Fleet Engine Deliveries API rozszerza w Twoim imieniu.

Aby zarządzać cyklami życia pojazdów i zadań w systemie, użyj interfejsu Fleet Engine Deliveries API do tworzenia, aktualizowania i śledzenia pojazdów oraz powiązanych z nimi zadań.

Jednocześnie aplikacja sterownika komunikuje się bezpośrednio z Fleet Engine, aby aktualizować lokalizację urządzenia i informacje o trasie. Ten model pozwala Fleet Engine wydajnie zarządzać lokalizacją w czasie rzeczywistym. Wysyła lokalizację bezpośrednio do biblioteki śledzenia, dzięki której możesz informować klientów o stanie ich zamówienia.

Załóżmy na przykład, że możliwy jest następujący scenariusz:

  • Kierowca w pobliżu przystanku dostawy. Aplikacja sterownika wysyła swoją lokalizację do Fleet Engine.
  • Fleet Engine wysyła lokalizację urządzenia do biblioteki śledzenia, której aplikacja konsumenta używa do ostrzegania konsumenta o pobliżu przesyłki.
  • Gdy kierowca zakończy dostawę, klika przycisk „Przesyłka dostarczona” w aplikacji kierowcy.
  • Czynność „Wysyłka dostarczona” powoduje wysłanie informacji do Twojego systemu backendu, który wykonuje niezbędne kroki weryfikacji i weryfikacji firmy.
  • Twój system potwierdza zadanie jako SUCCEEDED i aktualizuje Fleet Engine za pomocą interfejsu Deliveries API.

Poniższy diagram przedstawia te procesy na poziomie ogólnym. Pokazuje także standardową relację między Twoim systemem, klientem i Fleet Engine.

Korzystanie z interfejsu Deliveries API

Zarządzanie tokenami klientów

Aktualizacje lokalizacji pochodzące z aplikacji sterownika i wysyłane bezpośrednio do Fleet Engine wymagają tokenów autoryzacji. Oto zalecane podejście do obsługi aktualizacji z klienta do Fleet Engine:

  1. Wygeneruj token za pomocą roli konta usługi Niezaufany sterownik sterownika Fleet Engine Delivery.

  2. Udostępnij aplikacji sterownika token ograniczonego zakresu. Ten zakres pozwala tylko na aktualizowanie lokalizacji urządzenia we flocie Flot Engine.

Takie podejście gwarantuje, że połączenia pochodzące z urządzeń mobilnych – środowisk o niskim stopniu zaufania – przestrzegają zasady jak najmniejszych uprawnień.

Inne role konta usługi

Jeśli zamiast tego chcesz autoryzować aplikacje sterowników do wykonywania bezpośrednich aktualizacji Fleet Engine poza tymi, które są ograniczone do roli Niezaufanego sterownika, na przykład w przypadku niektórych aktualizacji zadań, możesz użyć roli Zaufany sterownik. Informacje o modelu, który korzysta z roli zaufanego kierowcy, znajdziesz w artykule o modelu zaufanego kierowcy.

Więcej informacji o użyciu niezaufanych i zaufanych ról sterowników znajdziesz w artykule o konfigurowaniu projektu Cloud.

Utwórz model dnia roboczego

W tabeli poniżej opisujemy, jak może wyglądać dzień pracy kierowców z pierwszej lub ostatniej linii w firmie kurierskiej i logistycznej. Szczegóły Twojej firmy mogą się różnić w szczegółach, ale możesz sprawdzić, jak modelujesz swój dzień pracy.

CzasAktywnośćmodelowania.
W ciągu 24 godzin od początku dnia Dyspozytor przypisuje przesyłki do pojazdów dostawczych lub tras. Możesz z wyprzedzeniem tworzyć w Fleet Engine zadania dotyczące dostaw, odbioru, przerw i innych zadań. Możesz na przykład utworzyć zadanie dotyczące odbioru, zadanie dostawy, zaplanowaną niedostępność lub zaplanowany postój.

Przypisz zadania do pojazdu, gdy zestaw paczek doręczonych i kolejność ich dostarczenia zostanie sfinalizowana.
Początek dnia Kierowca rozpoczyna dzień w zajezdni, logując się w aplikacji Kierowca. Zainicjuj interfejs Delivery Driver API. W razie potrzeby utwórz pojazd dostawy we Fleet Engine.
Kierowca ładuje przesyłki do pojazdu dostawczego i skanuje przesyłki. Jeśli zadania związane z dostawą dostawy nie zostały utworzone z wyprzedzeniem, utwórz zadania związane z dostawą dostawy podczas skanowania.
Kierowca potwierdza kolejność zadań do wykonania. Jeśli nie zostały one utworzone z wyprzedzeniem, utwórz zadania odbioru, zaplanowaną niedostępność i zaplanowane postoje.
Kierowca opuszcza zakład i zobowiązuje się do wykonania następnej liczby zadań. Przypisz do pojazdu wszystkie zadania lub ich podzbiór, zatwierdzając ich kolejność.
Kierowca dostarcza przesyłkę. Po dotarciu do punktu dostawy wykonaj działania związane z pojazdem znajdującym się na przystanku. Po dostarczeniu przesyłki zamknij zadanie dostawy i opcjonalnie zapisz stan wysyłki i inne metadane. Po wykonaniu wszystkich zadań na przystanku, ale przed rozpoczęciem jazdy, wykonaj czynności związane z zatrzymaniem pojazdu i poruszaniem się pojazdem do następnego przystanku.
Kierowca spotyka się z pojazdem dostarczającym dodatkowe przesyłki. Punkt spotkań, w których odbywa się transport między pojazdami dostawczymi i dostawczymi, powinien być modelowany jako zaplanowany przystanek.

Po przeniesieniu i przeskanowaniu przesyłek utwórz zadania dostawy, jeśli nie zostały jeszcze utworzone. Następnie zaktualizuj kolejność wykonywania zadań, przypisując zadania do pojazdu i zmieniając kolejność zadań.
Kierowca otrzymuje powiadomienie o możliwości odbioru. Po zaakceptowaniu prośby o odbiór utwórz zadanie odbioru przesyłki. Następnie zaktualizuj kolejność wykonywania zadań, przypisując zadania do pojazdu i zmieniając kolejność ich wykonywania.
Południe Kierowca robi przerwę na lunch. Jeśli z zadaniem dotyczącym niedostępności jest powiązana lokalizacja, traktuj ją tak jak każde inne zadanie. Wykonuj działania związane z pojazdem dojeżdżającym do przystanku, pojazdem zakończył się zatrzymaniem i pojazdem w drogę do następnego przystanku.

W przeciwnym razie nie musisz robić nic więcej aż do końca przerwy. Aby usunąć zadanie, potwierdź kolejne i pozostałe zadania oraz zaktualizuj kolejność zadań.
Kierowca odbiera przesyłkę. Jest to modelowane tak samo jak przystanek dostarczania. Wykonaj działania związane z pojazdem do przystanku i zamknięciem zadania oraz, opcjonalnie, zapisywaniem stanu wysyłki i innych metainformacji. Po wykonaniu wszystkich zadań na przystanku i przed rozpoczęciem jazdy wykonaj czynności związane z zatrzymaniem pojazdu i poruszaniem się pojazdem do następnego przystanku. Uwaga: aby zapewnić prawidłowe rozliczanie, wszystkie odbioru muszą mieć przypisane zadanie dostawy. Jeśli odbiór ma być dostarczany do innego miejsca tej samej trasy tego samego dnia kierowcy, zalecamy modelowanie tego zadania dostawy jako dowolnego innego zadania dostawy na trasie. Jeśli kierowca będzie prowadził z powrotem do magazynu, zalecamy utworzenie zadania dostawy w miejscu docelowym.
Kierowca zatrzymuje się, aby odebrać przesyłki ze skrzyni. Jest to modelowane tak samo jak każdy inny punkt odbioru. Wykonaj działania związane z pojazdem dojeżdżającym do przystanku i zamknięciem zadania. Po wykonaniu wszystkich zadań na przystanku i rozpoczęciu jazdy do następnego przystanku wykonaj działania związane z zatrzymaniem pojazdu i pojazdem do następnego przystanku.
Kierowca otrzymuje powiadomienie o przekierowaniu przesyłki do innego miejsca. Ustaw oryginalny stan zadania dostawy wysyłki na UKOŃCZONO i utwórz nowe zadanie dostawy dla nowej lokalizacji dostawy. Więcej informacji znajdziesz w artykule o przekierowywaniu przesyłki.
Kierowca próbował dostarczyć przesyłkę, ale nie mógł tego zrobić. Jest to modelowane podobnie do udanego zatrzymania dostarczania, gdzie zadanie dostarczania zostało oznaczone jako ukończone. Wykonaj działania związane z pojazdem dojeżdżającym do przystanku. Jeśli nie uda Ci się dostarczyć przesyłki, zamknij zadanie i opcjonalnie zapisz stan wysyłki i inne metadane. Po wykonaniu wszystkich zadań na przystanku i przed rozpoczęciem jazdy wykonaj czynności związane z zatrzymaniem pojazdu i poruszaniem się pojazdem do następnego przystanku.
Kierowca został poproszony o zatrzymanie przesyłki (a nie jej dostarczenie). Po otrzymaniu i potwierdzeniu powiadomienia ustaw stan zadania na Ukończone.
Kierowca został powiadomiony o konieczności dostarczenia określonej przesyłki w następnej kolejności, co spowodowało zmianę zobowiązania na dostawę. Zmień kolejność zadań.
Kierowca zdecyduje się dostarczyć przesyłkę w sposób niezgodny z zamówieniem. Zmień kolejność zadań i kontynuuj jak zwykle.
Kierowca dostarcza kilka przesyłek do jednego miejsca. Jest to modelowane podobnie jak w przypadku pojedynczego postoju na dostawę. Po dotarciu do przystanku wykonaj czynności związane z pojazdem znajdującym się na przystanku. Po dostarczeniu każdej przesyłki zamknij każde zadanie i opcjonalnie zapisz stan wysyłki i inne metadane. Po wykonaniu wszystkich zadań na przystanku i przed rozpoczęciem jazdy wykonaj czynności związane z zatrzymaniem pojazdu i poruszaniem się pojazdem do następnego przystanku.
Koniec dnia Kierowca wraca do zakładu. Jeśli kierowca wróci do zakładu z odebranymi przesyłkami na trasie, musisz też utworzyć i zamknąć każdą przesyłkę w ramach zadania dostawy, aby zapewnić prawidłowe rozliczenie. Możesz to zrobić, modelując zakład tak jak każdy inny przystanek dostawy. Jeśli depozyt nie jest używany jako przystanek dostawy, możesz opcjonalnie modelować go jako zaplanowany przystanek. Modelowanie przystanku pozwala kierowcom zobaczyć trasę z powrotem do zakładu i uzyskać wgląd w szacowany czas dotarcia na miejsce.

Jak działają aktualizacje lokalizacji

Aby uzyskać najlepszą wydajność w usłudze Fleet Engine, udostępnij jej strumień aktualizacji lokalizacji pojazdu. Zaktualizuj informacje na jeden z tych sposobów:

  1. Użyj pakietu Driver SDK – Android, iOS – najprostsza opcja.
  2. Użyj kodu niestandardowego – przydaje się to, gdy lokalizacje są przekazywane przez Twój backend albo jeśli korzystasz z urządzeń innych niż Android lub iOS.

Niezależnie od tego, jak udostępniasz informacje o lokalizacji pojazdu, Twój backend odpowiada za aktualizację Fleet Engine, gdy pojazd dostawczy jest w drodze do przystanku (w tym do magazynu) i gdy jest na przystanku. Fleet Engine nie wykrywa tych zdarzeń automatycznie.

Miejsca postojów i dostawy pojazdów

Zatrzymanie pojazdu to miejsce, w którym pojazd dostawczy wykonuje zadanie związane z dostawą lub wykonuje inne zadanie. Jest to albo punkt dostępu, taki jak pomost załadunkowy, albo lokalizacja przydrożna.

Lokalizacja dostawy to miejsce, w którym przesyłka jest dostarczona lub odebrana. Aby dotrzeć do i z miejsca dostawy, konieczne może być przejście od przystanku pojazdu.

Na przykład, gdy kierowca dostarcza przesyłkę do sklepu w centrum handlowym, samochód dostawczy zatrzymuje się na parkingu centrum handlowego w pobliżu wejścia do sklepu. To jest postój dla pojazdów. Następnie kierowca przechodzi z przystanku do centrum handlowego, w którym znajduje się sklep. Jest to miejsce dostawy.

Aby zapewnić użytkownikom jak najlepsze śledzenie przesyłki, weź pod uwagę sposób przypisywania zadań związanych z wysyłką do postojów dla pojazdów. Pamiętaj też, że raportowana jest liczba pozostałych postojów związanych z dostawą pojazdu, co pozwala im sprawdzić postęp wysyłki.

Jeśli na przykład kierowca realizuje wiele dostaw do jednego budynku biurowego, rozważ przypisanie wszystkich zadań dostawy do jednego przystanku pojazdu. Jeśli każde zadanie związane z dostawą jest przypisane do osobnego przystanku dla pojazdów, śledzenie przesyłki będzie dla użytkowników mniej przydatne, ponieważ śledzenie przesyłki będzie dostępne tylko wtedy, gdy pojazd znajdzie się w pewnej liczbie postojów przed miejscem docelowym. Realizacja wielu zatrzymania pojazdów w krótkim czasie nie daje użytkownikowi dużo czasu na śledzenie postępów w realizacji dostawy.

Korzystanie z mobilnych pakietów SDK

Zanim wyślesz jakiekolwiek wywołania pakietu Driver SDK, pamiętaj, aby go zainicjować.

Inicjowanie interfejsu Delivery Driver API

Zanim zainicjujesz interfejs Delivery Driver API w pakiecie Driver SDK, zainicjuj pakiet Navigation SDK. Następnie zainicjuj interfejs Delivery Driver API zgodnie z poniższym przykładem:

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

Przykłady zastosowań

W tej sekcji opisaliśmy, jak używać interfejsu Deliveries API do modelowania typowych przypadków użycia.

Unikalne identyfikatory jednostek

Format i wartość unikalnych identyfikatorów jednostek używanych w wywołaniach REST są nieprzejrzyste dla Fleet Engine. Unikaj automatycznego dodawania identyfikatorów i upewnij się, że identyfikator nie zawiera żadnych informacji umożliwiających identyfikację, takich jak numer telefonu kierowcy.

Utwórz pojazd

Pojazd możesz utworzyć za pomocą pakietu Driver SDK lub w środowisku serwera za pomocą gRPC lub REST.

gRPC

Aby utworzyć nowy pojazd, CreateDeliveryVehicle wywołaj funkcję Fleet Engine. Użyj obiektu CreateDeliveryVehicleRequest, aby określić atrybuty nowego pojazdu dostawy. Pamiętaj, że zgodnie ze wskazówkami interfejsu API dotyczącymi identyfikatorów określonych przez użytkowników wszelkie wartości w polu Name są ignorowane. Do skonfigurowania identyfikatora pojazdu należy użyć pola DeliveryVehicleId.

Podczas tworzenia obiektu DeliveryVehicle możesz opcjonalnie określić te pola:

  • Atrybuty
  • LastLocation
  • Typ

Nie ustawiaj żadnych innych pól. Jeśli to zrobisz, Fleet Engine zwróci błąd, ponieważ te pola są tylko do odczytu lub można je zaktualizować tylko za pomocą wywołania UpdateDeliveryVehicle.

Aby utworzyć pojazd bez ustawiania żadnych pól opcjonalnych, możesz zostawić pole DeliveryVehicle nieskonfigurowane w CreateDeliveryVehicleRequest.

Poniższy przykład pokazuje, jak utworzyć pojazd za pomocą biblioteki gRPC Java:

    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

Aby utworzyć pojazd w środowisku serwera, wyślij wywołanie HTTP REST do CreateDeliveryVehicle:

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

<id> to unikalny identyfikator pojazdu dostawczego należącego do Twojej floty.

Nagłówek żądania musi zawierać pole Authorization o wartości Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść POST reprezentuje encję DeliveryVehicle, która ma zostać utworzona. Możesz określić te pola opcjonalne:

  • atrybuty
  • lastLocation
  • Niestandardowy typ treści

Przykładowe polecenie 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

W przypadku identyfikatorów określonych przez użytkowników Fleet Engine ignoruje pole name elementu DeliveryVehicle zgodnie ze wskazówkami dotyczącymi interfejsu API. Nie ustawiaj żadnych innych pól. Jeśli to zrobisz, Fleet Engine zwróci błąd, ponieważ te pola są tylko do odczytu lub można je zaktualizować tylko za pomocą wywołania UpdateDeliveryVehicle.

Aby utworzyć pojazd bez ustawiania żadnych pól, pozostaw treść żądania POST pustą. Nowo utworzony pojazd wyodrębnia identyfikator z parametru deliveryVehicleId w adresie URL żądania POST.

Przykładowe polecenie 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}"

Tworzenie zadania odbioru przesyłki

Zadanie odbioru dostawy możesz utworzyć za pomocą pakietu Driver SDK lub w środowisku serwera za pomocą gRPC lub REST.

gRPC

Poniższy przykład pokazuje, jak za pomocą biblioteki gRPC Java utworzyć zadanie odbioru przesyłki:

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

Aby utworzyć zadanie odbioru przesyłki w środowisku serwera, wyślij wywołanie HTTP REST do CreateTask:

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

<id> to unikalny identyfikator zadania. Nie może to być numer do śledzenia przesyłki. Jeśli w systemie nie masz identyfikatorów zadań, możesz wygenerować unikalny identyfikator uniwersalny (UUID).

Nagłówek żądania musi zawierać pole Authorization o wartości Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść żądania musi zawierać element Task:

  • Pola wymagane:

    PoleWartość
    Niestandardowy typ treści Type.PICKUP
    state State.OPEN
    trackingId Numer lub identyfikator, którego używasz do śledzenia przesyłki.
    plannedLocation Lokalizacja, w której ma zostać wykonane zadanie, w tym przypadku miejsce odbioru przesyłki.
    taskDuration Przewidywany czas w sekundach, w jakim należy odebrać przesyłkę z miejscem odbioru.

  • Pola opcjonalne:

    PoleWartość
    targetTimeWindow Przedział czasu, w którym zadanie ma zostać wykonane. Nie ma to wpływu na routing.
    atrybuty Lista niestandardowych atrybutów Listy zadań. Każdy atrybut musi mieć unikalny klucz.

Podczas tworzenia wszystkie pozostałe pola elementu są ignorowane. Fleet Engine zgłasza wyjątek, jeśli żądanie zawiera przypisany element deliveryVehicleId. Przydzielasz zadania za pomocą interfejsu UpdateDeliveryVehicleRequest. Więcej informacji znajdziesz w artykułach Przypisywanie zadań do pojazdu i UpdateDeliveryVehicleRequest.

Przykładowe polecenie 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

Tworzenie zadania dostawy

Utwórz zadanie dostawy za pomocą pakietu Driver SDK lub w środowisku serwera za pomocą gRPC lub REST.

gRPC

Poniższy przykład pokazuje, jak użyć biblioteki gRPC Java do utworzenia zadania dostawy dostawy:

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

Aby utworzyć zadanie dostawy w środowisku serwera za pomocą gRPC lub REST, wywołaj HTTP REST do CreateTask:

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

<id> to unikalny identyfikator zadania. Nie może to być numer do śledzenia przesyłki. Jeśli w systemie nie masz identyfikatorów zadań, możesz wygenerować unikalny identyfikator uniwersalny (UUID).

Nagłówek żądania musi zawierać pole Authorization o wartości Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść żądania musi zawierać element Task:

  • Pola wymagane:

    PoleWartość
    Niestandardowy typ treści Type.DELIVERY
    state State.OPEN
    trackingId Numer lub identyfikator, którego używasz do śledzenia przesyłki.
    plannedLocation Lokalizacja, w której zadanie ma zostać wykonane, w tym przypadku lokalizacja dostawy tej przesyłki.
    taskDuration Przewidywany czas (w sekundach) oddania przesyłki do miejsca dostawy.

  • Pola opcjonalne:

    PoleWartość
    targetTimeWindow Przedział czasu, w którym zadanie ma zostać wykonane. Nie ma to wpływu na routing.
    atrybuty Lista niestandardowych atrybutów Listy zadań. Każdy atrybut musi mieć unikalny klucz.

Podczas tworzenia wszystkie pozostałe pola elementu są ignorowane. Fleet Engine zgłasza wyjątek, jeśli żądanie zawiera przypisany identyfikator deliveryVehicleId. Przydzielasz zadania za pomocą interfejsu UpdateDeliveryVehicleRequest. Więcej informacji znajdziesz w artykułach Przypisywanie zadań do pojazdu i UpdateDeliveryVehicleRequest.

Przykładowe polecenie 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

Zbiorcze tworzenie zadań

Grupę zadań możesz utworzyć ze środowiska serwera za pomocą gRPC lub REST.

gRPC

Poniższy przykład pokazuje, jak za pomocą biblioteki gRPC Java utworzyć 2 zadania: jedno związane z dostawą, a drugie związane z odbiorem w tej samej lokalizacji:

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

Aby utworzyć w środowisku serwera zadanie dostawy i odbioru, wyślij wywołanie HTTP REST do BatchCreateTasks:

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

Nagłówek żądania musi zawierać pole Authorization o wartości Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść żądania musi zawierać element BatchCreateTasksRequest:

  • Pola wymagane:

    PoleWartość
    żądania Tablica<CreateTasksRequest>

  • Pola opcjonalne:

    PoleWartość
    nagłówek DeliveryRequestHeader

Każdy element CreateTasksRequest w elemencie requests musi przejść te same reguły weryfikacji co żądanie CreateTask z wyjątkiem pola parent i header. Jeśli są ustawione, muszą być identyczne z odpowiadającymi im polami na najwyższym poziomie BatchCreateTasksRequest. Szczegółowe informacje o regułach weryfikacji znajdziesz w artykule o tworzeniu zadania odbioru dostawy i o tworzeniu zadania dostawy.

Więcej informacji znajdziesz w dokumentacji interfejsu API BatchCreateTasks (gRPC, REST).

Przykładowe polecenie 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

Zaplanowana niedostępność

Możesz utworzyć zadanie wskazujące niedostępność (np. związane z przerwami w działaniu kierowcy lub uzupełnianiem paliwa) za pomocą pakietu SDK Driver albo ze środowiska serwera za pomocą gRPC lub REST. Zaplanowane zadanie dotyczące niedostępności nie może zawierać identyfikatora śledzenia. Możesz opcjonalnie podać lokalizację.

gRPC

Poniższy przykład pokazuje, jak za pomocą biblioteki gRPC Java utworzyć zadanie dotyczące niedostępności:

    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

Aby utworzyć zadanie dotyczące niedostępności w środowisku serwera, wyślij wywołanie HTTP REST do CreateTask:

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

<id> to unikalny identyfikator zadania. Jeśli nie masz w systemie identyfikatorów zadań, możesz wygenerować uniwersalny unikalny identyfikator (UUID).

Nagłówek żądania musi zawierać pole Authorization o wartości Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść żądania musi zawierać element Task:

  • Pola wymagane:

    PoleWartość
    Niestandardowy typ treści Type.UNAVAILABLE
    state State.OPEN
    taskDuration Długość przerwy w sekundach.

  • Pola opcjonalne:

    PoleWartość
    plannedLocation Lokalizacja przerwy, jeśli ma zostać wykonana w określonym miejscu.

Podczas tworzenia wszystkie pozostałe pola elementu są ignorowane. Fleet Engine zgłasza wyjątek, jeśli żądanie zawiera przypisany identyfikator deliveryVehicleId. Przydzielasz zadania za pomocą interfejsu UpdateDeliveryVehicleRequest. Więcej informacji znajdziesz w artykułach Przypisywanie zadań do pojazdu i UpdateDeliveryVehicleRequest.

Przykładowe polecenie 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

Zaplanowane przystanki

Zaplanowane zadanie zatrzymania możesz utworzyć za pomocą pakietu Driver SDK lub w środowisku serwera za pomocą gRPC lub REST. Zaplanowane zatrzymanie nie może zawierać identyfikatora śledzenia.

gRPC

Poniższy przykład pokazuje, jak za pomocą biblioteki Java gRPC utworzyć zaplanowane zadanie zatrzymania:

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

Aby utworzyć zaplanowane zadanie zatrzymania w środowisku serwera, wyślij wywołanie HTTP REST do CreateTask:

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

<id> to unikalny identyfikator zadania. Jeśli w systemie nie masz identyfikatorów zadań, możesz wygenerować unikalny identyfikator uniwersalny (UUID).

Nagłówek żądania musi zawierać pole Authorization o wartości Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść żądania musi zawierać element Task:

  • Pola wymagane:

    PoleWartość
    Niestandardowy typ treści Type.SCHEDULED_STOP
    state State.OPEN
    plannedLocation Lokalizacja przystanku.
    taskDuration Przewidywany czas zatrzymania w sekundach.

  • Pola opcjonalne:

    • Brak

Podczas tworzenia wszystkie pozostałe pola elementu są ignorowane. Fleet Engine zgłasza wyjątek, jeśli żądanie zawiera przypisany identyfikator deliveryVehicleId. Przydzielasz zadania za pomocą interfejsu UpdateDeliveryVehicleRequest. Więcej informacji znajdziesz w artykułach Przypisywanie zadań do pojazdu i UpdateDeliveryVehicleRequest.

Przykładowe polecenie 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

Ustaw docelowy przedział czasu

Przedział czasu docelowego to TimeWindow, w którym zadanie ma zostać wykonane. Jeśli na przykład informujesz odbiorców o przedziale czasu dostawy, możesz użyć tego pola, aby uchwycić ten przedział czasu i wygenerować alerty lub przeanalizować wydajność po zakończeniu podróży.

Docelowy przedział czasu składa się z godziny rozpoczęcia i zakończenia. Można go ustawić dla dowolnego typu zadania. Docelowy przedział czasu nie ma wpływu na działanie routingu.

gRPC

Poniższy przykład pokazuje, jak ustawić okno czasu zadania za pomocą biblioteki gRPC Java:

    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

Aby ustawić przedział czasu zadania za pomocą protokołu HTTP, wywołaj UpdateTask:

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

<id> to unikalny identyfikator zadania.

Nagłówek żądania musi zawierać pole Authorization o wartości Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść żądania musi zawierać element Task:

  • Pola wymagane:

    PoleWartość
    targetTimeWindow Przedział czasu, w którym zadanie ma zostać wykonane. To ustawienie nie ma wpływu na routing

  • Pola opcjonalne:

    • Brak

Wszystkie pozostałe pola elementu są ignorowane podczas aktualizacji.

Przykładowe polecenie 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

Ustaw konfigurację widoczności śledzenia zadań

Widoczność danych w bibliotece śledzenia przesyłek oraz danych zwracanych z wywołania GetTaskTrackingInfo można kontrolować dla poszczególnych zadań, ustawiając w zadaniu obiekt TaskTrackingViewConfig. Więcej informacji znajdziesz w artykule Aktywne zadania związane z pojazdem. Możesz to zrobić podczas tworzenia lub aktualizowania zadania. Oto przykład aktualizowania zadania za pomocą tej konfiguracji:

gRPC

Poniższy przykład pokazuje, jak ustawić konfigurację widoku śledzenia zadań za pomocą biblioteki 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)
  .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

Aby ustawić okno konfiguracji widoku śledzenia zadań za pomocą protokołu HTTP, wywołaj UpdateTask:

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

<id> to unikalny identyfikator zadania.

Nagłówek żądania musi zawierać pole Authorization o wartości Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść żądania musi zawierać element Task:

  • Pola wymagane:

    PoleWartość
    taskTrackingViewConfig Konfiguracja śledzenia zadań określająca, które elementy danych są widoczne dla użytkowników w konkretnych okolicznościach.

  • Pola opcjonalne:

    • Brak

Wszystkie pozostałe pola elementu są ignorowane podczas aktualizacji.

Przykładowe polecenie 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

Przypisywanie zadań do pojazdu

Aby przypisać zadania do pojazdu dostawczego, należy zaktualizować kolejność zadań. Kolejność zadań dla pojazdu jest określana na podstawie listy postojów dla tego pojazdu. Do każdego przystanku pojazdu możesz przypisać jedno lub więcej zadań. Szczegółowe informacje znajdziesz w sekcji Aktualizowanie kolejności zadań.

Aby zmienić dostawę z jednego pojazdu na inny, zamknij pierwotne zadanie i utwórz je ponownie, zanim przypiszesz do nowego pojazdu. Jeśli zaktualizujesz kolejność zadań dla zadania, które jest już przypisane do innego pojazdu, pojawi się błąd.

Zaktualizuj kolejność zadań

Zadania związane z kolejnością przypisane do pojazdu możesz aktualizować za pomocą pakietu SDK Driver lub środowiska serwera. Nie stosuj obu metod, aby uniknąć wyścigu i utrzymać jedno źródło prawdy.

Gdy zaktualizujesz kolejność zadań w pojeździe, funkcja wykona też te działania:

  • Przypisuje nowe zadania do pojazdu.
  • Zamyka wszystkie zadania, które zostały wcześniej przypisane do pojazdu, ale nie są uwzględnione w zaktualizowanej kolejności.

Aby zmienić dostawę z jednego pojazdu na inny, zamknij pierwotne zadanie i utwórz je ponownie, zanim przypiszesz do nowego pojazdu. Jeśli zaktualizujesz kolejność zadań dla zadania, które jest już przypisane do innego pojazdu, pojawi się błąd.

Kolejność zadań możesz zmienić w każdej chwili.

gRPC

Poniższy przykład pokazuje, jak za pomocą biblioteki gRPC Java zaktualizować kolejność zadań w pojeździe:

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

Aby zaktualizować kolejność zadań dla pojazdu w środowisku serwera, wyślij wywołanie HTTP REST do UpdateDeliveryVehicle:

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

<id> to unikalny identyfikator pojazdu dostawy we flocie, w przypadku którego chcesz aktualizować kolejność zadań. Jest to identyfikator podany przez Ciebie podczas tworzenia pojazdu.

Nagłówek żądania musi zawierać pole Authorization o wartości Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść żądania musi zawierać element DeliveryVehicle:

  • Pola wymagane:

    PoleWartość
    remainingVehicleJourneySegments Lista segmentów ścieżki dla zadań w kolejności ich wykonania. Pierwsze zadanie na liście jest wykonywane jako pierwsze.
    pozostałeSegmentyWyjazdówPojazdowych[i].stop Zatrzymanie zadania i na liście.
    pozostałyPojazdySegmenty[i].stop.plannedLocation Planowana lokalizacja przystanku.
    pozostałyPojazdySegmenty[i].stop.tasks Lista zadań do wykonania na tym postoju.
    remainingVehicleJourneySegments[i].stop.state State.NEW

  • Pola opcjonalne:

    • Brak

Wszystkie pozostałe pola elementu są ignorowane podczas aktualizacji.

Przykładowe polecenie 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

Pojazd jest w drodze do następnego przystanku

Należy powiadamiać Fleet Engine, gdy pojazd wyruszy z przystanku lub rozpocznie nawigację. Możesz powiadomić Fleet Engine z użyciem pakietu SDK Driver lub ze środowiska serwera za pomocą gRPC lub REST. Nie stosuj obu tych metod, aby uniknąć sytuacji wyścigowych i utrzymać jedno źródło prawdy.

gRPC

Poniższy przykład pokazuje, jak za pomocą biblioteki gRPC Java powiadomić Fleet Engine o tym, że pojazd jest w drodze do następnego przystanku.

    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

Aby powiadomić Fleet Engine, że pojazd jest w drodze do następnego przystanku ze środowiska serwera, wyślij wywołanie HTTP REST do UpdateDeliveryVehicle:

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

<id> to unikalny identyfikator pojazdu dostarczania we flocie, w przypadku którego chcesz aktualizować kolejność zadań. Jest to identyfikator podany przez Ciebie podczas tworzenia pojazdu.

Nagłówek żądania musi zawierać pole Authorization o wartości Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść żądania musi zawierać element DeliveryVehicle:

  • Pole wymagane:

    PoleWartość
    remainingVehicleJourneySegments Lista pozostałych przystanków dla pojazdów ze stanami oznaczonymi jako stan.NOWY. Pierwszy przystanek na liście musi mieć stan State.ENROUTE.

  • Pola opcjonalne:

    • Brak

Wszystkie pozostałe pola elementu są ignorowane w powiadomieniu.

Przykładowe polecenie 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

Zaktualizuj lokalizację pojazdu

Jeśli nie używasz pakietu Driver SDK do aktualizowania lokalizacji pojazdu, możesz nawiązać bezpośrednie wywołanie do Fleet Engine, podając lokalizację pojazdu. W przypadku każdego aktywnego pojazdu Fleet Engine oczekuje aktualizacji lokalizacji co najmniej raz na minutę, a nie częściej niż co 5 sekund.

gRPC

Poniższy przykład pokazuje, jak za pomocą biblioteki gRPC Java zaktualizować lokalizację pojazdu we 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

Aby zaktualizować lokalizację pojazdu we Fleet Engine za pomocą protokołu HTTP REST, wywołaj UpdateDeliveryVehicle:

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

<id> to unikalny identyfikator pojazdu dostawy w Twojej flocie lub którego lokalizację chcesz zaktualizować. Jest to identyfikator podany przez Ciebie podczas tworzenia pojazdu.

Nagłówek żądania musi zawierać pole Authorization o wartości Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść żądania musi zawierać element DeliveryVehicle:

  • Pole wymagane:

    PoleWartość
    lastLocation.supplementalLocation Lokalizacja pojazdu.
    lastLocation.supplementalLocationTime Ostatnia znana sygnatura czasowa, kiedy pojazd znajdował się w tym miejscu.
    lastLocation.supplementalLocationSensor Pole powinno zawierać CUSTOMER_SUPPLIED_LOCATION.

  • Pola opcjonalne:

    PoleWartość
    lastLocation.supplementalLocationAccuracy Dokładność podanej lokalizacji w metrach.

Przykładowe polecenie 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

Pojazd zbliża się do przystanku

Musisz powiadamiać Fleet Engine, gdy pojazd znajdzie się na przystanku. Możesz powiadomić Fleet Engine z pakietu SDK Driver lub ze środowiska serwera za pomocą gRPC lub REST. Nie stosuj obu tych metod, aby uniknąć sytuacji wyścigowych i utrzymać jedno źródło prawdy.

gRPC

Poniższy przykład pokazuje, jak za pomocą biblioteki gRPC Java powiadomić Fleet Engine o zatrzymaniu pojazdu:

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

Aby powiadomić Fleet Engine o przybyciu pojazdu do zatrzymania ze środowiska serwera, wyślij wywołanie HTTP REST do UpdateDeliveryVehicle:

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

<id> to unikalny identyfikator pojazdu dostarczania we flocie, w przypadku którego chcesz aktualizować kolejność zadań. Jest to identyfikator podany przez Ciebie podczas tworzenia pojazdu.

Nagłówek żądania musi zawierać pole Authorization o wartości Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść żądania musi zawierać element DeliveryVehicle:

  • Pola wymagane:

    PoleWartość
    remainingVehicleJourneySegments Przystanek, do którego dotrzesz, ma stan Stan.ARRIVED, a następnie lista pozostałych przystanków dla pojazdów z tymi stanami.NOWY.

  • Pola opcjonalne:

    • Brak

Wszystkie pozostałe pola elementu są ignorowane podczas aktualizacji.

Przykładowe polecenie 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

Pojazd zatrzymuje się

Gdy pojazd się zatrzyma. Spowoduje to, że wszystkie zadania powiązane z przystankiem zostaną ustawione jako ZAMKNIĘTE. Powiadomienia Fleet Engine możesz zgłaszać za pomocą pakietu SDK Driver lub środowiska serwera za pomocą gRPC lub REST. Nie stosuj obu metod, aby uniknąć wyścigów i utrzymać jedno źródło prawdy.

gRPC

Poniższy przykład pokazuje, jak używać biblioteki gRPC Java do powiadamiania Fleet Engine o zatrzymaniu pojazdu.

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

Aby powiadomić Fleet Engine o zakończeniu zatrzymania ze środowiska serwera, wyślij wywołanie HTTP REST do UpdateDeliveryVehicle:

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

<id> to unikalny identyfikator pojazdu dostarczania we flocie, w przypadku którego chcesz aktualizować kolejność zadań. Jest to identyfikator podany przez Ciebie podczas tworzenia pojazdu.

Nagłówek żądania musi zawierać pole Authorization o wartości Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść żądania musi zawierać element DeliveryVehicle:

  • Pola wymagane:

    PoleWartość
    remaining_vehicle_journey_segments Ukończony przystanek nie powinien być już widoczny na liście pozostałych przystanków dla pojazdów.

  • Pola opcjonalne:

    • Brak

Wszystkie pozostałe pola elementu są ignorowane podczas aktualizacji.

Przykładowe polecenie 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

Aktualizowanie zadania

Większość pól zadań nie można zmienić. Można jednak modyfikować stan, wynik zadania, czas wyniku, lokalizację wyniku zadania i atrybuty, bezpośrednio aktualizując encję zadania. Jeśli na przykład zadanie nie zostało przypisane do pojazdu, możesz je zamknąć, bezpośrednio aktualizując stan.

gRPC

Oto przykład aktualizowania zadania za pomocą gRPC.

REST

Oto przykład aktualizowania zadania za pomocą protokołu REST.

Zamykanie zadania

Aby zamknąć zadanie przypisane do pojazdu, powiadom zespół Fleet Engine o zakończeniu przystanku, na którym odbywa się to zadanie lub usuń go z listy postojów. Aby to zrobić, możesz ustawić listę pozostałych przystanków tak samo jak podczas aktualizowania kolejności zadań w przypadku danego pojazdu.

Jeśli do zadania nie przypisano jeszcze pojazdu i trzeba je zamknąć, zmień jego stan na ZAMKNIĘTE. Nie możesz jednak ponownie otworzyć ZAMKNIĘTEGO zadania.

Zamknięcie zadania nie oznacza powodzenia ani niepowodzenia. Oznacza ono, że zadanie nie jest już uważane za wykonane. W przypadku śledzenia przesyłki ważne jest, aby wskazać rzeczywisty wynik zadania, aby można było poznać efekty jego dostawy.

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

Aby oznaczyć zadanie jako zamknięte w środowisku serwera, wyślij wywołanie HTTP REST do UpdateTask:

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

<id> to unikalny identyfikator zadania.

Nagłówek żądania musi zawierać pole Authorization o wartości Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

W treści żądania musisz umieścić element Task:

  • Pola wymagane:

    PoleWartość
    state State.CLOSED

  • Pola opcjonalne:

    PoleWartość
    taskOutcome Wynik.SUCCEEDED lub Wynik.FAILED
    taskOutcomeTime Czas ukończenia zadania.
    taskOutcomeLocation Lokalizacja, w której zadanie zostało ukończone. Fleet Engine ustawia domyślnie tę lokalizację na ostatnią lokalizację pojazdu, chyba że zostanie zastąpiona ręcznie przez dostawcę.

Wszystkie pozostałe pola elementu są ignorowane podczas aktualizacji.

Przykładowe polecenie 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

Określanie wyniku i lokalizacji zadania

Zamknięcie zadania nie oznacza powodzenia ani niepowodzenia zadania, ponieważ nie jest już uznawane za trwające. W przypadku śledzenia przesyłki ważne jest, aby wskazać rzeczywisty wynik zadania, aby można było przedstawić wyniki dostawy i prawidłowo rozliczyć opłaty za usługi. Po skonfigurowaniu tego działania nie można zmienić jego wyniku. Po ustawieniu czasu i lokalizacji wyniku zadania możesz jednak zmienić jego ustawienie.

Zadania, które są w stanie ZAMKNIĘTE, mogą mieć stan ZAKOŃCZONO lub NIE UDAŁO SIĘ. Fleet Engine nalicza opłaty tylko za zadania dostawy ze stanem SUCCEEDED.

Zaznaczając wynik zadania, Fleet Engine automatycznie wypełnia lokalizację wyniku zadania ostatnią znaną lokalizacją pojazdu. Możesz to zmienić.

gRPC

Podczas ustawiania wyniku możesz ustawić lokalizację wyniku zadania. Ustawienie lokalizacji uniemożliwia Fleet Engine ustawienie jej na domyślną lokalizację ostatniej lokalizacji pojazdu. Możesz też zastąpić lokalizację wyniku zadania ustawioną w usłudze Fleet Engine w późniejszym czasie. Fleet Engine nigdy nie zastępuje podanej lokalizacji wyników zadania. Nie możesz ustawić lokalizacji wyniku zadania dla zadania, które nie ma określonego wyniku. W jednym żądaniu możesz ustawić lokalizację zarówno wyniku zadania, jak i tego samego wyniku.

Poniższy przykład pokazuje, jak za pomocą biblioteki gRPC Java ustawić wynik zadania na SUCCEEDED i ustawić lokalizację, w której zostało ono ukończone:

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

Aby oznaczyć zadanie jako ukończone w środowisku serwera, wyślij wywołanie HTTP REST do UpdateTask:

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

<id> to unikalny identyfikator zadania.

Nagłówek żądania musi zawierać pole Authorization o wartości Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść żądania musi zawierać element Task:

  • Pola wymagane:

    PoleWartość
    taskOutcome Wynik.SUCCEEDED lub Wynik.FAILED

  • Pola opcjonalne:

    PoleWartość
    taskOutcomeLocation Lokalizacja, w której zadanie zostało ukończone. Jeśli nie skonfigurujesz tej zasady, Fleet Engine domyślnie ustawi ostatnią lokalizację pojazdu.
    taskOutcomeTime Sygnatura czasowa ukończenia zadania.

Wszystkie pozostałe pola elementu są ignorowane podczas aktualizacji.

Przykładowe polecenie 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

Przekierowywanie dostawy

Po utworzeniu zadania dotyczącego dostawy nie można zmienić jego planowanej lokalizacji. Aby przekierować przesyłkę, zamknij zadanie dostawy bez ustalania wyniku, a następnie utwórz nowe zadanie ze zaktualizowaną, zaplanowaną lokalizacją. Po utworzeniu nowego zadania przypisz je do tego samego pojazdu. Więcej informacji znajdziesz w artykule o zamykaniu zadań związanych z dostawą i przypisywaniu zadania.

Korzystanie z pojazdów dostarczających i dostarczających

Jeśli używasz pojazdów dostawczych do transportu przesyłek do pojazdów dostawczych w ciągu dnia, modeluj przesyłanie przesyłek jako zaplanowane zatrzymania dla pojazdu dostawy. Aby zapewnić dokładne śledzenie lokalizacji, przypisz zadanie dostarczenia przesyłki do przesłanej przesyłki dopiero po tym, jak zostanie ona załadowana do pojazdu dostawy. Więcej informacji znajdziesz w artykule o zaplanowanym przystanku.

Przechowywanie stanu wysyłki i innych metadanych

Gdy zadanie związane z dostawą zostanie wykonane, stan zadania i jego wynik są odnotowywane w zadaniu. Możesz jednak zaktualizować inne metadane dotyczące dostawy. Aby przechowywać inne metadane, do których możesz się odwołać poza usługą Fleet Engine, użyj identyfikatora śledzenia powiązanego z zadaniem jako klucza w tabeli zewnętrznej.

Więcej informacji znajdziesz w artykule Okres wykonywania zadania.

Wyszukaj pojazd

Pojazd możesz wyszukać za pomocą pakietu Driver SDK lub w środowisku serwera za pomocą gRPC lub REST.

gRPC

Poniższy przykład pokazuje, jak wyszukać pojazd za pomocą biblioteki gRPC Java:

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

Aby wyszukać pojazd w środowisku serwera, wykonaj wywołanie HTTP REST do GetVehicle:

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

<id> to unikalny identyfikator zadania.

<vehicleId> to identyfikator pojazdu, który chcesz wyszukać.

Nagłówek żądania musi zawierać pole Authorization o wartości Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść żądania musi być pusta.

Jeśli wyszukiwanie zakończy się powodzeniem, treść odpowiedzi będzie zawierać element dotyczący pojazdu.

Przykładowe polecenie 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}"

Wyszukiwanie zadania

Możesz wyszukać zadanie ze środowiska serwera za pomocą gRPC lub REST. Pakiet Driver SDK nie obsługuje wyszukiwania zadań.

gRPC

Poniższy przykład pokazuje, jak wyszukać zadanie za pomocą biblioteki gRPC Java:

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

Aby wyszukać zadanie w środowisku serwera, wyślij wywołanie HTTP REST do GetTask:

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

<id> to unikalny identyfikator zadania.

<taskId> to identyfikator zadania, które chcesz wyszukać.

Nagłówek żądania musi zawierać pole Authorization o wartości Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść żądania musi być pusta.

Jeśli wyszukiwanie zakończy się powodzeniem, treść odpowiedzi będzie zawierać encję zadania.

Przykładowe polecenie 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}"

Wyszukuj informacje o zadaniu związanym z dostawą według identyfikatora śledzenia

Informacje o zadaniach związanych z dostawą możesz wyszukiwać na kilka sposobów, z których każdy służy do osobnego celu:

  • według identyfikatora zadania: używane przez użytkowników, takich jak operatorzy floty, którzy mają dostęp do pełnego widoku danych zadania.
  • za pomocą identyfikatora śledzenia: używany przez oprogramowanie klienta, aby przekazywać użytkownikowi ograniczone informacje, np. o tym, kiedy przesyłka ma się spodziewać w jego domu.

W tej sekcji omówiono wyszukiwanie informacji o zadaniach przy użyciu identyfikatora śledzenia. Jeśli chcesz wyszukiwać zadanie według identyfikatora zadania, przejdź do sekcji Wyszukiwanie zadania.

Aby wyszukiwać informacje według identyfikatora śledzenia, możesz skorzystać z jednej z tych opcji:

Wymagania dotyczące wyszukiwania

  • Informacje o dostawie dostarczane przez identyfikator śledzenia są zgodne z regułami widoczności wymienionymi w artykule Kontrolowanie widoczności śledzonych lokalizacji.

  • Użyj Fleet Engine do wyszukiwania informacji o dostawie według identyfikatora śledzenia. Pakiet SDK Driver nie obsługuje wyszukiwania informacji według identyfikatora śledzenia. Aby to zrobić za pomocą Fleet Engine, użyj środowiska serwera lub przeglądarki.

  • Aby ograniczyć zagrożenia bezpieczeństwa, używaj najwęższego tokena. Na przykład, jeśli używasz tokena klienta dostawy, wszystkie wywołania interfejsu Fleet Engine Deliveries API zwracają tylko informacje istotne dla tego użytkownika, takie jak nadawca lub odbiorca przesyłki. Pozostałe informacje w odpowiedziach zostaną usunięte. Więcej informacji o tokenach znajdziesz w artykule o tworzeniu tokena internetowego JSON (JWT) na potrzeby autoryzacji.

Wyszukiwanie w Javie przy użyciu gRPC

Poniższy przykład pokazuje, jak za pomocą biblioteki gRPC Java wyszukać informacje o zadaniu dostawy według jego identyfikatora śledzenia.

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

Wyszukiwania z użyciem HTTP

Aby wyszukać zadanie dostawy w przeglądarce, wyślij wywołanie HTTP REST do GetTaskTrackingInfo:

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

<tracking_id> to identyfikator śledzenia powiązany z zadaniem.

Nagłówek żądania musi zawierać pole Authorization o wartości Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Jeśli wyszukiwanie zakończy się pomyślnie, treść odpowiedzi będzie zawierała encję taskTrackingInfo.

Przykładowe polecenie 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}"

Wyświetlenie listy zadań

Możesz wyświetlić listę zadań ze środowiska serwera lub przeglądarki. Pakiet Driver SDK nie obsługuje wyświetlania listy zadań.

Zadania związane z wyświetlaniem listy wymagają szerokiego dostępu do zadań. Zadania związane z wyświetlaniem listy są przeznaczone tylko dla zaufanych użytkowników. Przy wysyłaniu żądań dotyczących zadań związanych z listą używaj tokenów uwierzytelniających superużytkownika Delivery Fleet lub Delivery Super User Tokens.

Te pola na liście zadań są usunięte:

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

Zadania na liście można filtrować według większości właściwości zadań. Informacje o składni zapytań filtra znajdziesz w artykule AIP-160. Na liście poniżej znajdziesz prawidłowe właściwości zadań, których możesz używać do filtrowania:

  • atrybuty
  • delivery_vehicle_id
  • state
  • planned_location
  • task_duration
  • task_outcome
  • task_outcome_location
  • task_outcome_location_source
  • task_outcome_time
  • tracking_id
  • Niestandardowy typ treści

Użyj tych formatów pól na podstawie propozycji ulepszeń interfejsu API Google:

Typ pola Format Przykład
Sygnatura czasowa RFC-3339 task_outcome_time = 2022-03-01T11:30:00-08:00
Czas trwania Liczba sekund, po których następuje znak s task_duration = 120s
Typ wyliczeniowy Ciąg znaków state = CLOSED AND type = PICKUP
Lokalizacja point.latitudepoint.longitude planned_location.point.latitude > 36.1 AND planned_location.point.longitude < -122.0

Pełną listę operatorów zapytań filtra znajdziesz w sekcji AIP-160.

Jeśli nie podasz zapytania filtra, zostaną wyświetlone wszystkie zadania.

Listy zadań są podzielone na strony. Rozmiar strony można określić w żądaniach wyświetlenia listy zadań. Jeśli podasz rozmiar strony, liczba zwróconych zadań nie będzie większa od tego rozmiaru strony. W przypadku braku rozmiaru strony zostanie użyta rozsądna wartość domyślna. Jeśli żądany rozmiar strony przekracza wewnętrzną wartość maksymalną, używana jest wewnętrzna wartość maksymalna.

Lista zadań może zawierać token odczytu następnej strony wyników. Aby pobrać następną stronę zadań, użyj tokena strony z żądaniem, które jest identyczne z poprzednim żądaniem. Gdy zwrócony token strony jest pusty, nie można pobrać więcej zadań.

gRPC

Poniższy przykład pokazuje, jak za pomocą biblioteki gRPC Java wyświetlić listę zadań dla deliveryVehicleId i atrybutu zadania. Pomyślna odpowiedź może być nadal pusta. Pusta odpowiedź oznacza, że nie jest powiązana z listą zadań o podanym identyfikatorze dostawy pojazdu.

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

Aby wyświetlić listę zadań z przeglądarki, wyślij wywołanie HTTP REST do ListTasks:

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

Aby zastosować filtr do wymienionych zadań, dołącz parametr „filtr” adresu URL, a jego wartością jest zapytanie filtra ze zmianą znaczenia adresu URL.

Nagłówek żądania musi zawierać pole Authorization o wartości Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Jeśli wyszukiwanie zakończy się powodzeniem, treść odpowiedzi będzie zawierać dane o następującej strukturze:

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

Pomyślna odpowiedź może być pusta. Pusta odpowiedź oznacza, że nie znaleziono żadnych zadań spełniających określone kryteria filtra.

Przykładowe polecenie 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}"

Wyświetl listę pojazdów dostawczych

Możesz wyświetlić listę pojazdów dostawy ze środowiska serwera lub przeglądarki. Pakiet Driver SDK nie obsługuje wyświetlania informacji o pojazdach dostawczych.

Pojazdy dostawcze wymagają szerokiego dostępu do pojazdów dostawczych i są przeznaczone tylko dla zaufanych użytkowników. Przy wysyłaniu żądań dotyczących pojazdów dostarczających listy używaj tokenów uwierzytelniania superużytkownika Delivery Fleet lub Delivery SuperUser.

Ze względu na wpływ na rozmiar odpowiedzi te pola w przypadku pojazdów dostawy z listą produktów zostały usunięte:

  • CurrentRouteSegment
  • RemainingVehicleJourneySegments

Możesz filtrować listę pojazdów dostawy według właściwości attributes. Aby na przykład wysłać zapytanie o atrybut z kluczem my_key o wartości my_value, użyj attributes.my_key = my_value. Aby wysyłać zapytania obejmujące kilka atrybutów, połącz zapytania za pomocą operatorów logicznych AND i OR, tak jak w przykładzie attributes.key1 = value1 AND attributes.key2 = value2. Pełny opis składni zapytań filtra znajdziesz na stronie AIP-160.

Możesz filtrować wymienione pojazdy dostawy według lokalizacji, używając parametru żądania viewport. Parametr żądania viewport definiuje widoczne obszary za pomocą dwóch współrzędnych ograniczających: high (północny wschód) i low (południowy zachód). Żądania są odrzucane, jeśli zawierają dużą szerokość geograficzną, która jest geograficznie mniejsza niż mała szerokość geograficzna.

Listy pojazdów dostawy są domyślnie podzielone na strony w odpowiednim rozmiarze. Jeśli określisz rozmiar strony, żądanie zwróci tylko liczbę pojazdów określoną w tym limicie lub mniejszą. Jeśli żądany rozmiar strony przekracza wewnętrzną wartość maksymalną, używana jest wewnętrzna wartość maksymalna. Zarówno domyślny, jak i maksymalny rozmiar stron to 100 pojazdów.

Lista pojazdów dostawczych może zawierać token odczytu następnej strony wyników. Token strony występuje w odpowiedzi tylko wtedy, gdy dostępnych jest do pobrania więcej stron pojazdów dostawy. Aby pobrać następną stronę zadań, użyj tokena strony z żądaniem, które jest identyczne z poprzednim żądaniem.

gRPC

Poniższy przykład pokazuje, jak za pomocą biblioteki gRPC Java wyświetlić listę pojazdów dostawy w konkretnym regionie z określonym atrybutem. Pomyślna odpowiedź może być pusta. Oznacza to, że w widocznym obszarze nie znajdują się już żadne pojazdy z określonym atrybutem.

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

Aby wyświetlić listę zadań z przeglądarki, wyślij wywołanie HTTP REST do ListDeliveryVehicles:

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

Aby zastosować filtr do wymienionych zadań, uwzględnij parametr adresu URL „filtr” z zapytaniem filtra ze zmianą znaczenia w adresie URL jako jego wartości.

Nagłówek żądania musi zawierać pole Authorization o wartości Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Jeśli wyszukiwanie zakończy się powodzeniem, treść odpowiedzi będzie zawierać dane o następującej strukturze:

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

Pomyślna odpowiedź może być pusta. Oznacza to, że nie znaleziono pojazdów obsługujących wyświetlenia spełniających określone zapytanie filtra i widoczny obszar.

Przykładowe polecenie 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"

Śledzenie przesyłki

Za pomocą interfejsu Fleet Engine Deliveries API możesz włączyć śledzenie przesyłek na 2 sposoby:

  • Preferowane: użyj biblioteki śledzenia przesyłki JavaScript. Biblioteka umożliwia wizualizację lokalizacji pojazdów i wybranych lokalizacji śledzonych we Fleet Engine. Zawiera komponent mapy JavaScript, który jest zwykłym zamiennikiem standardowego obiektu google.maps.Map i komponentów danych służących do łączenia się z Fleet Engine. Ten komponent umożliwia udostępnienie dostosowywanego, animowanego śledzenia przesyłki z poziomu aplikacji internetowej lub mobilnej.

  • Wdróż własne śledzenie przesyłek w ramach interfejsu Fleet Engine Deliveries API.

Najważniejsze jest wyszukiwanie zadań związanych z dostawą według identyfikatora śledzenia.

Jeśli używasz roli konsumenta dostarczania, wszystkie wywołania interfejsu Fleet Engine Deliveries API zwracają tylko informacje istotne dla nadawcy lub odbiorcy. Pozostałe informacje w odpowiedziach są usuwane. To Ty odpowiadasz za uwierzytelnianie użytkowników. Dodatkowo informacje o lokalizacji są filtrowane na podstawie zadania, które jest już wykonywane. Podczas wykonywania zadania dotyczącego niedostępności informacje o lokalizacji nie są udostępniane użytkownikowi.

Logowanie

Możesz skonfigurować usługę Fleet Engine tak, aby wysyłała logi RPC do Cloud Logging. Więcej informacji znajdziesz w artykule o logowaniu.

Role i tokeny autoryzacji

Jak opisano w artykule Zarządzanie cyklem życia pojazdu i zadań oraz uwagi na temat autoryzacji dotyczące poszczególnych przypadków użycia, wykonywanie wywołań Fleet Engine wymaga uwierzytelniania za pomocą tokenów sieciowych JSON, które zostały podpisane przy użyciu danych logowania konta usługi. Konta usługi używane do wystawiania tych tokenów mogą mieć 1 lub więcej ról, a każda z nich przyznaje inny zestaw uprawnień.

Więcej informacji znajdziesz w artykule na temat uwierzytelniania i autoryzacji.

Rozwiązywanie typowych problemów

Jeśli napotkasz jakieś problemy, przeczytaj te sekcje, aby uzyskać pomoc.

Odporność

Fleet Engine nie jest uważany za źródło danych. Twoim obowiązkiem jest przywrócenie stanu systemu, jeśli to konieczne, bez korzystania z Fleet Engine.

Utracony stan we Fleet Engine

Podczas pracy z Fleet Engine wdróż klienty, tak aby system w razie awarii sam się naprawił. Gdy na przykład Fleet Engine spróbuje zaktualizować pojazd, może wyświetlić się komunikat o błędzie informujący o tym, że pojazd nie istnieje. Następnie klient powinien odtworzyć pojazd w nowym stanie. Ten problem występuje rzadko, ale upewnij się, że Twój system jest wystarczająco odporny, aby go obsłużyć.

W bardzo nieprawdopodobnej sytuacji katastrofalnej awarii Fleet Engine może być konieczne odtworzenie większości lub wszystkich pojazdów i zadań. Jeśli częstotliwość tworzenia będzie zbyt wysoka, niektóre żądania mogą ponownie zostać odrzucone z powodu problemów z limitami, ponieważ przeprowadzane są kontrole limitu w celu uniknięcia ataków typu DoS (odmowa usługi). W takim przypadku zmniejsz wskaźnik odtworzenia, stosując strategię wycofywania i ponownych prób.

Utracony stan w aplikacji kierowcy

Jeśli aplikacja sterownika ulegnie awarii, musi odtworzyć bieżący stan w pakiecie SDK Driver SDK. Aplikacja powinna spróbować odtworzyć zadania, aby sprawdzić, czy istnieją, i przywrócić obecny stan. Aplikacja powinna też odtworzyć i wyraźnie ustawić listę przystanków dla pakietu Driver SDK.

Najczęstsze pytania

Co się stanie, jeśli kierowca zatrzyma się na niezrealizowane zadanie?

W takim przypadku najpierw zaktualizuj kolejność zadań, a potem postępuj jak zwykle – oznacz dojazd, ukończenie zadania i inne szczegóły. Jeśli tego nie zrobisz, system może stać się niespójny, szacowany czas dotarcia na miejsce może stać się nieprawidłowy oraz zgłaszać nieoczekiwane błędy.