Pierwsze kroki z Fleet Engine

Interfejs Fleet Engine Deliveries API umożliwia modelowanie działań floty na pierwszej i ostatniej mili dostaw. Interfejs Deliveries API jest udostępniany za pomocą pakietu Driver SDK na Androida i iOS. Można go też używać bezpośrednio za pomocą wywołań HTTP REST lub gRPC.

Konfiguracja początkowa

Interfejs Fleet Engine Deliveries API konfiguruje się w konsoli Google Cloud. Informacje o czynnościach, które należy wykonać w konsoli, oraz o tym, jak utworzyć token sieciowy JSON na potrzeby autoryzacji, znajdziesz w opisie uwierzytelniania i autoryzacji. Więcej informacji o korzystaniu z konsoli znajdziesz w dokumentacji Google Cloud Console.

Sprawdzanie konfiguracji

Po utworzeniu kont usługi sprawdź, czy konfiguracja została zakończona, i możesz utworzyć pojazd dostawczy. Jeśli przeprowadzisz weryfikację na tym etapie przepływu pracy, będziesz mieć pewność, że udało Ci się rozwiązać typowe problemy z autoryzacją, które mogą się pojawić podczas konfigurowania projektu. Postępuj zgodnie z instrukcjami podanymi w przewodniku Weryfikacja konfiguracji. Ten przewodnik zawiera szczegółowe informacje na temat używania narzędzia wiersza poleceń gcloud do testowania 2 kluczowych części konfiguracji: podpisywania tokenów autoryzacji i tworzenia pojazdów do dostarczania wersji próbnych.

Do przetestowania konfiguracji możesz użyć przykładowych skryptów uwierzytelniania Fleet Engine.

Biblioteki klienta

Publikujemy biblioteki klienta w kilku popularnych językach programowania. Biblioteki te zapewniają większą wygodę programistycznym niż nieprzetworzony kod REST lub gRPC. Instrukcje dotyczące uzyskiwania bibliotek klienta dla aplikacji serwera znajdziesz w artykule o bibliotekach klienta.

W przykładach w języku Java w tej dokumentacji założono znajomość gRPC.

Struktury danych

Interfejs Shipping API wykorzystuje 2 struktury danych, aby modelować odbiór i dostawę przesyłek:

  • Pojazd służący do transportu przesyłki.
  • Zadania dotyczące odbioru i dostawy przesyłki.

Dodatkowo możesz używać zadań, aby modelować przerwy kierowcy i zaplanowane przystanki na cały dzień.

Pojazdy dostawcze

Pojazdy dostawcze przenoszą przesyłki z depozytu do miejsca dostawy oraz z miejsca odbioru do magazynu. W niektórych przypadkach może też transportować przesyłkę bezpośrednio z miejsca odbioru do miejsca dostawy.

Za pomocą pakietu Driver SDK możesz utworzyć obiekt DeliveryVehicle we Fleet Engine i wysyłać aktualizacje lokalizacji na potrzeby śledzenia przesyłek i floty.

Lista zadań

Do każdego pojazdu są przypisane zadania. Mogą to być zadania związane z odbiorem lub dostawą, wymaganymi przerwami dla kierowców lub zaplanowanymi postojami w skrzynkach odbiorczych lub placówkach klientów. Każde zadanie musi mieć unikalny identyfikator zadania, ale może mieć ten sam identyfikator śledzenia. Zadania i kolejność, w jakiej są zaplanowane, są używane do obliczania okresów szacowania czasu dotarcia na miejsce dla każdego zadania.

Użyj Menedżera zadań pakietu Driver SDK do tworzenia zadań we Fleet Engine.

Zadania związane z dostawą

Zadania związane z dostawą są związane z odbiorem lub przekazaniem przesyłki. Podczas tworzenia zadania dostawy musisz podać numer śledzenia lub identyfikator. Musisz też określić czas kontaktu, aby uwzględnić dodatkowy czas na wykonanie zadania, znalezienie zaparkowania lub dojście do miejsca przekazania.

  • Utwórz zadanie odbioru polegające na odbiorze przesyłki i określ miejsce odbioru oraz numer śledzenia lub identyfikator.
  • Utwórz zadanie dostawy związane z dostarczeniem przesyłki, podając miejsce dostawy oraz numer lub identyfikator śledzenia.

Zadania związane z niedostępnością

Utwórz zadanie niedostępności obejmujące okres, w którym pojazd nie będzie dostępny do odbioru lub dostawy. Może to być przerwa na zatankowanie pojazdu lub przerwa kierowcy.

Podczas tworzenia zadania określ długość przerwy. Podziały na przerwy nie muszą być wykonywane w konkretnej lokalizacji, ale określenie lokalizacji zapewni dokładniejsze informacje o szacowanym czasie dotarcia w ciągu dnia.

Zaplanowane zadania zatrzymania

Utwórz zadania zaplanowanego zatrzymania, które mają być wykonane przez pojazd dostawczy. Możesz na przykład utworzyć zaplanowane zatrzymanie dla zaplanowanego przystanku odbioru w określonej lokalizacji niezależnie od innych dostaw lub odbiorów w tej samej lokalizacji. Możesz też tworzyć zaplanowane zadania zatrzymania w przypadku odbioru ze skrzynki referencyjnej lub modelowania przesyłek w pojazdach dostawczych lub postojów w centrach obsługi bądź punktach obsługi.

Informacje o konkretnych polach zawartych w każdej strukturze danych znajdziesz w dokumentacji API DeliveryVehicle (gRPC, REST) i Task (gRPC, REST).

Wytyczne dotyczące identyfikatora zadania

Identyfikatory zadań muszą być unikalne i nie mogą ujawniać żadnych informacji umożliwiających identyfikację osoby ani danych w postaci zwykłego tekstu.

Identyfikatory zadań muszą spełniać te wymagania dotyczące formatu:

  • Identyfikatory muszą być prawidłowymi ciągami znaków Unicode.
  • Identyfikatory mogą mieć maksymalnie 64 znaki.
  • Identyfikatory zostaną znormalizowane zgodnie z formularzem normalizacji Unicode C.
  • Identyfikatory nie mogą zawierać następujących znaków ASCII: „/”, „:”, „”, „?” ani „#”.

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

  • 566c33d9-2a31-4b6a-9cd4-80ba1a0c643b
  • e4708eabcfa39bf2767c9546c9273f747b4626e8cc44e9630d50f6d129013d38
  • NTA1YTliYWNkYmViMTI0ZmMzMWFm wysokiej jakości2NzNkM2Jk

W tabeli poniżej znajdziesz przykłady nieprawidłowych identyfikatorów zadań:

Nieprawidłowy identyfikator zadania Przyczyna
31.08.2019-20:48-46.70746,-130.10807,-85.17909,61.33680 narusza wymagania dotyczące informacji umożliwiających identyfikację oraz znaków: przecinków, kropek, dwukropków i ukośników;
JanNowak-577b484da26f-Kupertyno-ŚwiętoWybrzeże 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ę oraz znaków: odstępów, przecinków i cudzysłowów. Nazwa przekracza 64 znaki.

Żywotność pojazdu

Obiekt DeliveryVehicle reprezentuje pojazd dostawczy na pierwszą lub ostatnią milę. Tworzysz obiekt DeliveryVehicle za pomocą:

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

Każdy pojazd powinien być niepowtarzalny. Nie należy ich używać ponownie w innym pojeździe, chyba że nie ma dla niego aktywnych zadań.

Sprawdź, czy przy dzwonieniu do: UpdateDeliveryVehicle nie występuje błąd NOT_FOUND. W razie potrzeby użyj polecenia CreateDeliveryVehicle, by utworzyć nowy pojazd. Obiekt DeliveryVehicle, który nie został zaktualizowany za pomocą UpdateDeliveryVehicle, jest automatycznie usuwany po 7 dniach. Pamiętaj, że wywołanie metody CreateDeliveryVehicle przy użyciu istniejącej pary identyfikator projektu/identyfikator pojazdu generuje błąd.

Rodzaj pojazdu

Element Pojazd zawiera opcjonalne pole VehicleType, które zawiera wyliczenie Category, które można określić jako AUTO, TWO_WHEELER, BICYCLE lub PEDESTRIAN. Jeśli to pole nie jest skonfigurowane, domyślnie przyjmuje wartość AUTO.

Wszystkie wyznaczanie tras pojazdów będą używane w przypadku danego typu pojazdu jako RouteTravelMode.

Atrybuty pojazdu

Encja DeliveryVehicle zawiera powtarzane pole DeliveryVehicleAttribute. Interfejs ListDeliveryVehicles API zawiera pole filter, które może ograniczyć zwracane encje DeliveryVehicle do tych ze zdefiniowanymi atrybutami. DeliveryVehicleAttribute nie wpływają na działanie 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.

Życie zadania

Zadania we Fleet Engine można tworzyć, aktualizować i przesłuchiwać za pomocą interfejsów gRPC lub REST interfejsu Deliveries API.

Obiekt Task ma pole stanu, które pozwala śledzić postęp jego cyklu życia. Wartości zostaną zmienione z OPEN na CLOSED (zamknięte). Nowe zadania są tworzone w stanie OTWÓRZ, co oznacza, że:

  • Zadanie nie zostało jeszcze przypisane do pojazdu dostawczego.
  • Pojazd nie przejechał jeszcze przypisanego do zadania postoju.

Zadanie można przypisać do pojazdu tylko wtedy, gdy jest on OTWARTY.

Zadanie można anulować, usuwając je z listy przystanków. Stan konta zostaje automatycznie ustawiony na ZAMKNIĘTE.

Gdy pojazd wykonujący zadanie zakończy jego zatrzymanie, zaktualizuj pole wyniku zadania na SUCCEEDED lub FAILED i podaj sygnaturę czasową zdarzenia. Wynik zadania można ustawić w dowolnym momencie przed jego ukończeniem lub po jego zakończeniu, ale można to zrobić tylko raz.

Biblioteka śledzenia dostawy JavaScript może następnie wskazać wynik zadania. Stan zadania jest automatycznie ustawiany na ZAMKNIĘTE. Więcej informacji znajdziesz w artykule Śledzenie przesyłek za pomocą biblioteki śledzenia przesyłek JavaScript.

Tak jak w przypadku pojazdów zadania, które nie zostały zaktualizowane po 7 dniach, są usuwane, a próba utworzenia zadania o istniejącym identyfikatorze zwraca błąd.

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

Atrybuty zadania

Encja Task zawiera powtarzające się pole TaskAttribute, które może zawierać wartość jednego z 3 typów: ciągu znaków, liczby i wartości logicznej. Interfejs ListTasks API zawiera pole filter, które może ograniczyć zwracane jednostki Task do tych o określonych atrybutach. TaskAttribute nie ma wpływu 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.

Zarządzanie cyklem życia pojazdu i zadań

Aby zarządzać cyklem życia pojazdów i zadań w systemie, możesz tworzyć, aktualizować i śledzić pojazdy oraz powiązane z nimi zadania za pomocą interfejsu Fleet Engine Deliveries API. Twój system wewnętrzny działa jako zaufane źródło danych, które interfejs Fleet Engine Deliveries API uzupełnia w Twoim imieniu.

Jednocześnie aplikacja sterownika komunikuje się bezpośrednio z Fleet Engine, aby aktualizować informacje o lokalizacji urządzenia i trasach. Ten model umożliwia Fleet Engine efektywne zarządzanie lokalizacją w czasie rzeczywistym i wysyłanie tych danych bezpośrednio do biblioteki śledzenia, z której możesz potem korzystać klientom, którzy potrzebują aktualizacji stanu swojego zamówienia.

Załóżmy na przykład, że masz taki scenariusz:

  • Kierowca zbliża się do punktu obsługi paczek, a Fleet Engine wysyła lokalizację urządzenia do biblioteki śledzenia, której aplikacja używa, aby poinformować klienta o tym, jak blisko znajduje się paczka.
  • Gdy kierowca zakończy dostawę, klika przycisk „Dostawa przesyłki” w aplikacji kierowcy.
  • Spowoduje to wysłanie informacji do Twojego systemu backendu, który wykona 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 też standardowe relacje między Twoim systemem, klientem i Fleet Engine.

Korzystanie z diagramu Deliveries API

Zarządzanie tokenami klienta

Wszelkie aktualizacje lokalizacji pochodzące z aplikacji sterownika i wysyłane bezpośrednio do Fleet Engine wymagają tokenów autoryzacji. Zalecaną metodą obsługi aktualizacji z klienta do Fleet Engine jest udostępnienie aplikacji sterownika tokena o ograniczonym zakresie, tak aby mogła ona aktualizować lokalizację urządzenia tylko we Fleet Engine. W przypadku tego typu tokena używasz roli konta usługi o nazwie Użytkownik niezaufanego sterownika Fleet Engine Delivery. Dzięki temu połączenia pochodzące z urządzeń mobilnych – uważanych za środowiska o niskim zaufaniu – są zgodne z zasadą jak najmniejszych uprawnień.

Inne role konta usługi

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

Więcej informacji o wykorzystywaniu ról niezaufanych i zaufanych sterowników znajdziesz w artykule Konfigurowanie projektu Cloud.

Modelowanie dnia pracy

Z tabeli poniżej dowiesz się, jak może wyglądać dzień pracy w firmach transportowych i logistycznych. Szczegóły Twojej firmy mogą się różnić, ale możesz sprawdzić, jak możesz wymodelować dzień pracy.

GodzinaAktywnośćModelowanie
W ciągu 24 godzin od początku dnia Dyspozytor przypisuje przesyłki do pojazdów lub tras dostawy. Zadania związane z dostawami, odbiorami, przerwami itp. można utworzyć we Fleet Engine z wyprzedzeniem. Możesz na przykład utworzyć zadanie związane z odbiorem przesyłki, zadanie związane z dostawą przesyłki, zaplanowaną niedostępność lub zaplanowane zatrzymanie.

Zadania należy przypisać do pojazdu po sfinalizowaniu zestawu paczek i kolejności ich dostarczania.
Początek dnia Kierowca zaczyna dzień w salonie, logując się w aplikacji Driver. Zainicjuj interfejs Delivery Driver API. W razie potrzeby utwórz pojazd dostawczy we Fleet Engine.
Kierowca wczytuje przesyłki do pojazdu dostawczego, skanując przesyłki. Jeśli zadania związane z dostawą nie zostały utworzone z wyprzedzeniem, utwórz zadania dostawy podczas skanowania.
Kierowca potwierdza kolejność zadań do wykonania. Jeśli nie zostały utworzone wcześniej, utwórz zadania odbioru przesyłki, zaplanowaną niedostępność i zaplanowane przystanki.
Kierowca wyjeżdża z dyspozytu i zobowiązuje się do wykonania kolejnych zadań. Przypisz do pojazdu wszystkie zadania lub podzbiór zadań, zatwierdzając ich kolejność.
Kierowca dostarcza przesyłkę. Po dotarciu na miejsce postoju wykonaj czynności związane z przystankiem pojazdu. Po dostarczeniu przesyłki zamknij zadanie dostawy i opcjonalnie zapisz stan wysyłki i inne metadane. Po wykonaniu wszystkich zadań na przystanku i przed rozpoczęciem jazdy na następnym przystanku wykonaj działania związane z zatrzymaniem pojazdu i pojazdem na następny przystanek.
Kierowca spotyka się z pojazdem dostawczym, aby przekazać dodatkowe przesyłki do tego pojazdu. Miejsce spotkań do przesiadki między pojazdami podającymi a pojazdami dostawczymi powinno być modelowane jako zaplanowane przystanki.

Po przeniesieniu i skanowaniu przesyłek utwórz zadania związane z dostawą, jeśli nie zostały jeszcze utworzone. Następnie zaktualizuj kolejność ukończenia zadań, przypisując zadania do pojazdu i aktualizując kolejność zadań.
Kierowca otrzymuje powiadomienie o prośbie o odbiór. 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 aktualizując kolejność zadań.
Południe Kierowca robi sobie przerwę obiadową. Jeśli lokalizacja jest powiązana z zadaniem niedostępności, traktuj ją jak każde inne zadanie. Wykonuj czynności związane z pojazdem, który zatrzymuje się na przystanku, zatrzymuje się i pojazd w drodze do następnego przystanku.

W przeciwnym razie nie musisz podejmować żadnych działań do końca przerwy. Aby usunąć zadanie, potwierdź kolejne i pozostałe zadania oraz zaktualizuj kolejność zadań.
Kierowca odbiera paczkę. Model jest podobny do przystanku dostawy. Wykonuj działania związane z pojazdem na postoju i zamykaniem zadania oraz opcjonalnie zachowuj stan przesyłki i inne metadane. Po wykonaniu wszystkich zadań na przystanku i przed rozpoczęciem jazdu na następny przystanek wykonaj działania związane z zatrzymaniem pojazdu i pojazdem na następny przystanek. Uwaga: aby zapewnić prawidłowe płatności, wszystkie odbiory muszą mieć odpowiadające im zadanie dostawy. Jeśli w tym dniu odbiór ma zostać dostarczony do innej lokalizacji na tej samej trasie kierowcy, zalecamy zamodelowanie tego zadania dostawy jako dowolnego innego zadania dostawy na trasie. Jeśli kierowca przynosi odbiór z powrotem do magazynu, zalecamy utworzenie zadania dostawy w jego miejscu.
Kierowca zatrzymuje się, aby odebrać przesyłki ze skrzynki referencyjnej. Odbiór jest modelowany tak samo jak każdy inny punkt odbioru. Wykonuj działania związane z pojazdem na postoju i zamykaniem 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 na następny przystanek.
Kierowca otrzymuje powiadomienie o przekierowaniu przesyłki w inne miejsce. Ustaw pierwotny stan zadania dostawy na UKOŃCZONE i utwórz nowe zadanie dostawy dla nowego miejsca dostawy. Więcej informacji znajdziesz w artykule Przekierowywanie wysyłki.
Kierowca próbował dostarczyć paczkę, ale nie mógł tego zrobić. Jest to modelowane podobnie do udanego zatrzymania dostarczania, przez co zadanie wyświetlania jest oznaczone jako ukończone. Wykonuj działania związane z pojazdem na przystanku. Jeśli nie dostarczysz przesyłki, zamknij zadanie i opcjonalnie zapisz stan wysyłki i inne metadane. Po wykonaniu wszystkich zadań na przystanku i przed rozpoczęciem jazdu na następny przystanek wykonaj działania związane z zatrzymaniem pojazdu i pojazdem na następny przystanek.
Kierowca otrzymał powiadomienie, że powinien wstrzymać (nie dostarczyć) przesyłkę. Po otrzymaniu i potwierdzeniu powiadomienia ustaw stan zadania na UKOŃCZONE.
Kierowca został poinformowany o konieczności dostarczenia określonej przesyłki w celu zmiany zamówienia w ramach zobowiązania. Zaktualizuj kolejność zadań.
Kierowca decyduje się dostarczyć przesyłkę bez zamówienia. Zaktualizuj kolejność zadań, a następnie kontynuuj normalne działanie.
Kierowca dostarcza kilka przesyłek do jednej lokalizacji. Ten proces jest podobny do pojedynczego postoju dostawy. Po dotarciu na przystanek wykonaj czynności związane z przystankiem pojazdu. 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 jazdu na następny przystanek wykonaj działania związane z zatrzymaniem pojazdu i pojazdem na następny przystanek.
Koniec dnia Kierowca wraca do składu. Jeśli kierowca wróci do magazynu z przesyłki, musisz też utworzyć i zamknąć każdą paczkę jako zadanie dostawy, aby zapewnić prawidłowe rozliczenia. Możesz to zrobić, modelując magazyn tak jak w przypadku każdego innego miejsca dostawy. Jeśli oddział nie jest używany jako postój na dostawy, możesz opcjonalnie zamodelować go na zaplanowanym przystanku. Dzięki temu kierowcy będą mogli zobaczyć trasę z powrotem do zajezdni i zobaczyć szacowany czas dotarcia na miejsce.

Aktualizacje lokalizacji

Aktualizacje lokalizacji są wysyłane do Fleet Engine, gdy pojazd dostawczy jest w drodze ze stacji (łącznie z depozytem) do przystanku na następnym przystanku. Takie zdarzenia nie są wykrywane automatycznie, więc musisz je oznaczyć automatycznie. Użyj bibliotek wykrywających zmiany w środku transportu, aby aktywować wysyłanie wymaganych powiadomień do Fleet Engine.

Aktualizacje lokalizacji powinny być zawieszane, gdy kierowca nie jedziesz, ponieważ jakość sygnałów lokalizacyjnych znacznie pogarsza się, gdy ktoś znajduje się w budynku.

Częstotliwość aktualizacji lokalizacji można ustawić w pakiecie Driver SDK. Domyślnie aktualizacje są wysyłane co 10 sekund.

Miejsca postoju i dostawy pojazdów

Zatrzymanie pojazdu to miejsce, w którym pojazd kurierski wykonuje zadanie dostawy lub inne zadanie. Może to być punkt dostępu, taki jak stacja dokująca do załadunku, lub lokalizacja oddzielona od drogi.

Lokalizacja dostawy to miejsce, w którym zostanie dostarczona lub odebrana. Dojazd do miejsca dostawy i z niego może wymagać przejścia z przystanku pieszo.

Jeśli np. kierowca dostarcza przesyłkę do sklepu w centrum handlowym, samochód dostawczy zatrzymuje się na parkingu centrum handlowym w pobliżu najbliższego wejścia. To jest przystanek dla pojazdów. Następnie kierowca idzie z postoju do lokalizacji w centrum handlowym, w którym znajduje się sklep. Jest to miejsce dostawy.

Aby zapewnić użytkownikom jak największą wygodę śledzenia przesyłek, zastanów się, w jaki sposób zadania związane z dostawą są przypisane do postojów pojazdów. Pamiętaj, że liczba postojów pozostałych pojazdów związanych z zadaniami związanymi z dostawą jest zgłaszana użytkownikowi, aby mógł śledzić postęp przesyłki.

Jeśli na przykład kierowca dostarcza wiele dostaw do jednego budynku biurowego, możesz przypisać wszystkie zadania związane z dostawą do jednego postoju. Jeśli każde zadanie związane z dostawą jest przypisane do własnego postoju pojazdu, śledzenie przesyłki będzie mniej przydatne dla użytkowników, ponieważ śledzenie przesyłki jest dostępne tylko wtedy, gdy pojazd znajduje się w ograniczonej liczbie postojów przed miejscem docelowym. Realizacja wielu postojów samochodowych w krótkim czasie nie daje użytkownikowi dużo czasu na śledzenie postępów dostawy.

Korzystanie z mobilnych pakietów SDK

Przed wykonaniem jakichkolwiek wywołań pakietu Driver SDK musisz 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 w następujący sposób:

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

Przypadki użycia

W tej sekcji opisujemy, jak wykorzystać interfejs Deliveries API do modelowania typowych przypadków użycia.

Unikalne identyfikatory encji

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

Utwórz pojazd

Pojazd możesz utworzyć za pomocą pakietu SDK Driver albo środowiska serwera.

gRPC

Aby utworzyć nowy pojazd, wykonaj wywołanie CreateDeliveryVehicle do Fleet Engine. Atrybuty nowego pojazdu dostawczego możesz określić za pomocą obiektu CreateDeliveryVehicleRequest. Pamiętaj, że wszystkie wartości określone w polu Name będą ignorowane zgodnie ze wskazówkami interfejsu API dotyczącymi identyfikatorów określonych przez użytkowników. Identyfikator pojazdu należy skonfigurować w polu DeliveryVehicleId.

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

  • Atrybuty
  • Ostatnia lokalizacja
  • Typ

Nie można ustawiać wartości innych pól. W przeciwnym razie Fleet Engine zwróci błąd, ponieważ te pola są tylko do odczytu lub można je zaktualizować tylko za pomocą wywołań UpdateDeliveryVehicle.

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

Z przykładu poniżej dowiesz się, jak utworzyć pojazd przy użyciu biblioteki Java gRPC:

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

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

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

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

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

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

REST

Aby utworzyć pojazd ze środowiska serwera, wykonaj wywołanie HTTP REST do CreateDeliveryVehicle:

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

<id> to unikalny identyfikator pojazdu dostawczego w Twojej flocie.

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

Treść POST reprezentuje encję DeliveryVehicle do utworzenia. Możesz określić te opcjonalne pola:

  • atrybuty
  • lastLocation

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

Fleet Engine ignoruje pole name encji DeliveryVehicle zgodnie ze wskazówkami interfejsu API dotyczącymi identyfikatorów określonych przez użytkowników. Innych pól nie można ustawiać. W przeciwnym razie Fleet Engine zwróci błąd, ponieważ te pola są tylko do odczytu lub można je zaktualizować tylko za pomocą wywołań UpdateDeliveryVehicle.

Aby utworzyć pojazd bez ustawiania żadnych pól, możesz pozostawić treść żądania POST pustą. W nowo utworzonym pojeździe będzie wyodrębniony identyfikator pojazdu z parametru deliveryVehicleId w adresie URL 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}"

Utwórz zadanie odbioru przesyłki

Zadanie odbioru przesyłki możesz utworzyć w pakiecie SDK Driver lub w środowisku serwera.

gRPC

Z przykładu poniżej dowiesz się, jak za pomocą biblioteki Java gRPC 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, wykonaj wywołanie HTTP REST „CreateTask”:

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

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

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

Treść żądania musi zawierać encję Task:

  • Pola wymagane:

    PoleWartość
    typ Typ.ODBIÓR
    state State.OPEN
    identyfikator śledzenia Numer lub identyfikator, którego używasz do śledzenia przesyłki.
    planowanaLokalizacja Lokalizacja, w której zadanie ma zostać wykonane, w tym przypadku miejsce odbioru przesyłki.
    zadanieDuration, Oczekiwany czas (w sekundach) odbioru przesyłki z miejsca odbioru.

  • Pola opcjonalne:

    PoleWartość
    czasCzasudocelowy Przedział czasu, w którym należy wykonać zadanie. Obecnie nie ma to wpływu na zachowanie routingu.
    atrybuty Lista niestandardowych atrybutów zadania. Każdy atrybut musi mieć unikalny klucz.

Wszystkie pozostałe pola elementu są ignorowane podczas tworzenia. Fleet Engine zgłasza wyjątek, jeśli żądanie zawiera przypisany identyfikator purchaseVehicleId. Przypisujesz zadania za pomocą polecenia UpdateDeliveryVehicleRequest. Więcej informacji znajdziesz w artykule Przypisywanie zadań do pojazdu.

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 przesyłki

Zadanie dostarczenia przesyłki możesz utworzyć w pakiecie SDK sterownika lub w środowisku serwera.

gRPC

Z przykładu poniżej dowiesz się, jak za pomocą biblioteki Java gRPC utworzyć zadanie dostawy 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.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 związane z dostawą przesyłki w środowisku serwera, wykonaj wywołanie HTTP REST „CreateTask”:

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

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

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

Treść żądania musi zawierać encję Task:

  • Pola wymagane:

    PoleWartość
    typ Typ.DOSTAWA
    state State.OPEN
    identyfikator śledzenia Numer lub identyfikator, którego używasz do śledzenia przesyłki.
    planowanaLokalizacja Lokalizacja, w której zadanie ma zostać wykonane, w tym przypadku miejsce dostawy tej przesyłki.
    zadanieDuration, Oczekiwany czas dostarczenia przesyłki do miejsca dostawy (w sekundach).

  • Pola opcjonalne:

    PoleWartość
    czasCzasudocelowy Przedział czasu, w którym należy wykonać zadanie. Obecnie nie ma to wpływu na zachowanie routingu.
    atrybuty Lista niestandardowych atrybutów zadania. Każdy atrybut musi mieć unikalny klucz.

Wszystkie pozostałe pola elementu są ignorowane podczas tworzenia. Fleet Engine zgłasza wyjątek, jeśli żądanie zawiera przypisany identyfikator purchaseVehicleId. Przypisujesz zadania za pomocą: UpdateDeliveryVehicleRequest. Więcej informacji znajdziesz w artykule Przypisywanie zadań do pojazdu.

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ń

Możesz utworzyć grupę zadań ze środowiska serwera.

gRPC

Z przykładu poniżej dowiesz się, jak za pomocą biblioteki Java gRPC utworzyć 2 zadania – dotyczące dostawy i odbioru 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ć zadanie dostawy i odbioru w środowisku serwera, 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 z wartością Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść żądania musi zawierać encję BatchCreateTasksRequest:

  • Pola wymagane:

    PoleWartość
    żądania Tablica<CreateTasksRequest>

  • Pola opcjonalne:

    PoleWartość
    nagłówek `DeliveryRequestHeader`

Każdy element CreateTasksRequest w elemencie requests musi przechodzić te same reguły weryfikacji co żądanie CreateTask z wyjątkiem pól parent i header, które są opcjonalne. Jeśli je ustawisz, muszą być identyczne z odpowiednimi polami na najwyższym poziomie BatchCreateTasksRequest. Zobacz na temat tworzenia zadania odbioru przesyłki i tworzenia takiego zadania, aby poznać reguły weryfikacji dla każdego z nich.

Więcej informacji znajdziesz w dokumentacji API dotyczącej 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ść

Zadanie wskazujące niedostępność (np. dotyczące kierowców lub tankowania pojazdów) możesz utworzyć za pomocą pakietu SDK Driver albo ze środowiska serwera. Zaplanowane zadanie niedostępności nie może zawierać identyfikatora śledzenia. Opcjonalnie możesz podać lokalizację.

gRPC

Z przykładu poniżej dowiesz się, jak za pomocą biblioteki Java gRPC utworzyć zadanie 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 niedostępności w środowisku serwera, wykonaj 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 z wartością Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść żądania musi zawierać encję Task:

  • Pola wymagane:

    PoleWartość
    typ Typ.UNAVAILABLE
    state State.OPEN
    zadanieDuration, Czas trwania przerwy w sekundach.

  • Pola opcjonalne:

    PoleWartość
    planowanaLokalizacja Miejsce, w którym przerwa ma nastąpić w konkretnym miejscu.

Wszystkie pozostałe pola elementu są ignorowane podczas tworzenia. Fleet Engine zgłasza wyjątek, jeśli żądanie zawiera przypisany identyfikator purchaseVehicleId. Przypisujesz zadania za pomocą polecenia UpdateDeliveryVehicleRequest. Więcej informacji znajdziesz w artykule Przypisywanie zadań do pojazdu.

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 SDK sterownika albo ze środowiska serwera. Zaplanowane zadanie zatrzymania nie może zawierać identyfikatora śledzenia.

gRPC

Z przykładu poniżej dowiesz się, jak za pomocą biblioteki Java gRPC utworzyć zadanie zaplanowanego 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, wykonaj 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 z wartością Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść żądania musi zawierać encję Task:

  • Pola wymagane:

    PoleWartość
    typ Typ.SCHEDULED_STOP
    state State.OPEN
    planowanaLokalizacja Lokalizacja przystanku.
    zadanieDuration, Oczekiwany czas postoju w sekundach.

  • Pola opcjonalne:

    • Brak

Wszystkie pozostałe pola elementu są ignorowane podczas tworzenia. Fleet Engine zgłasza wyjątek, jeśli żądanie zawiera przypisany identyfikator purchaseVehicleId. Przypisujesz zadania za pomocą polecenia UpdateDeliveryVehicleRequest. Więcej informacji znajdziesz w artykule Przypisywanie zadań do pojazdu.

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

Docelowy przedział czasu to TimeWindow, w którym zadanie powinno zostać wykonane. Jeśli na przykład przekazujesz odbiorcom informacje o czasie dostawy, możesz użyć tego pola w celu uchwycenia tego przedziału i wygenerowania alertów lub analizy wyników po podróży.

Docelowy przedział czasu składa się z godziny rozpoczęcia i zakończenia i można go ustawić dla dowolnego typu zadania. Docelowy przedział czasu nie wpływa obecnie na zachowanie routingu.

gRPC

Z przykładu poniżej dowiesz się, jak za pomocą biblioteki Java gRPC ustawić okno czasu zadania:

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 przez 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 z wartością Bearer <token>, gdzie <token> to token wytworzony przez fabrykę tokenów Fleet Engine.

Treść żądania musi zawierać encję Task:

  • Pola wymagane:

    PoleWartość
    czasCzasudocelowy Przedział czasu, w którym należy wykonać zadanie. Obecnie nie ma to wpływu na zachowanie routingu

  • Pola opcjonalne:

    • Brak

Pozostałe pola elementu zostaną zignorowane 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 zwróconych z połączenia do usługi GetTaskTrackingInfo można kontrolować dla poszczególnych zadań, ustawiając dla nich właściwość TaskTrackingViewConfig. Więcej informacji znajdziesz w artykule Aktywne zadania związane z pojazdem. Możesz to zrobić podczas tworzenia lub aktualizowania zadania. Poniżej znajdziesz przykład aktualizowania zadania przy użyciu tej konfiguracji:

gRPC

Z przykładu poniżej dowiesz się, jak za pomocą biblioteki Java gRPC ustawić konfigurację widoku śledzenia zadań:

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 skonfigurować okno konfiguracji widoku śledzenia zadań przy użyciu 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 z wartością Bearer <token>, gdzie <token> to token wytworzony przez fabrykę tokenów Fleet Engine.

Treść żądania musi zawierać encję Task:

  • Pola wymagane:

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

  • Pola opcjonalne:

    • Brak

Pozostałe pola elementu zostaną zignorowane 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

Zadania są przypisywane do pojazdu dostawczego przez aktualizację jego kolejności zadań. Kolejność zadań dla pojazdu dostawczego jest określana na podstawie listy postojów. Każdemu przystankowi można przypisać jedno lub więcej zadań.

Aktualizacja kolejności zadań dla zadania, które było wcześniej przypisane do innego pojazdu, powoduje błąd.

Aby zmienić przesyłkę z jednego pojazdu na inny, zamknij pierwotne zadanie, a następnie odtwórz je ponownie, zanim przypiszesz nowy pojazd.

Zaktualizuj kolejność zadań

Kolejność wykonywania zadań przypisanych do pojazdu możesz zmieniać za pomocą pakietu Driver SDK lub środowiska serwera. Nie należy łączyć 2 metod, by uniknąć wyścigu.

Zaktualizowanie kolejności zadań spowoduje też przypisanie do pojazdu zadań, które nie były wcześniej przypisane do pojazdu, oraz zamknięcie zadań, które były wcześniej przypisane do pojazdu i pominięte w zaktualizowanej kolejności. Przypisanie zadania do innego pojazdu, jeśli zostało ono wcześniej przypisane do innego pojazdu, spowoduje wystąpienie błędu. Najpierw zamknij istniejące zadanie, a następnie utwórz nowe, zanim przypiszesz je do nowego pojazdu.

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

gRPC

Z przykładu poniżej dowiesz się, jak za pomocą biblioteki Java gRPC 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 ze środowiska serwera, wykonaj wywołanie HTTP REST „UpdateDeliveryVehicle”:

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

<id> to unikalny identyfikator pojazdu dostawczego w Twojej flocie, dla którego chcesz zaktualizować kolejność zadań. Jest to identyfikator podany podczas tworzenia pojazdu.

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

Treść żądania musi zawierać encję DeliveryVehicle:

  • Pola wymagane:

    PoleWartość
    pozostałe SegmentyPojazdy Lista segmentów przebiegu dla zadań w kolejności, w której mają być wykonane. Pierwsze zadanie na liście jest wykonywane jako pierwsze.
    pozostałe segmentyPojazdu[i].stop Przystanek zadania i na liście.
    pozostałePojazdyJourneySegments[i].stop.plannedLocation Planowana lokalizacja przystanku.
    pozostałePojazdyJourneySegments[i].stop.zadania Lista zadań do wykonania na tym przystanku.
    pozostałe segmentyPojazdów[i].stop.stan Stan.NEW

  • Pola opcjonalne:

    • Brak

Pozostałe pola elementu zostaną zignorowane 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 jedzie do następnego przystanku

Usługa Fleet Engine musi być powiadamiana, gdy pojazd wychodzi ze postoju lub rozpoczyna nawigację. Możesz to zrobić za pomocą pakietu SDK sterownika albo ze środowiska serwera. Nie należy łączyć 2 metod jednocześnie, aby uniknąć warunków wyścigu i utrzymać jedno źródło wiarygodnych danych.

gRPC

Z przykładu poniżej dowiesz się, jak użyć biblioteki Java gRPC, aby powiadomić Fleet Engine o tym, jak pojazd jest w drodze do następnego postoju.

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, wykonaj wywołanie HTTP REST „UpdateDeliveryVehicle”:

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

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

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

Treść żądania musi zawierać encję DeliveryVehicle:

  • Pole wymagane:

    PoleWartość
    pozostałe SegmentyPojazdy Lista pozostałych przystanków z ich stanami oznaczonymi jako State.NEW. Pierwszy przystanek na liście musi mieć stan oznaczony jako State.ENROUTE.

  • Pola opcjonalne:

    • Brak

Pozostałe pola elementu są ignorowane w przypadku powiadomienia.

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

Pojazd wjeżdżający na przystanek

Usługa Fleet Engine musi być powiadamiana, gdy pojazd się zatrzyma. Możesz to zrobić za pomocą pakietu SDK sterownika albo ze środowiska serwera. Nie należy łączyć 2 metod jednocześnie, aby uniknąć warunków wyścigu i utrzymać jedno źródło wiarygodnych danych.

gRPC

Z przykładu poniżej dowiesz się, jak użyć biblioteki Java gRPC, aby 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 nadejściu pojazdu ze środowiska serwera, wykonaj wywołanie HTTP REST „UpdateDeliveryVehicle”:

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

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

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

Treść żądania musi zawierać encję DeliveryVehicle:

  • Pola wymagane:

    PoleWartość
    pozostałe SegmentyPojazdy Przystanek, na którym się znajdujesz, ma stan ustawiony jako State.ARRIVED, a następnie lista pozostałych przystanków z ich stanami oznaczonymi jako State.NEW.

  • Pola opcjonalne:

    • Brak

Pozostałe pola elementu zostaną zignorowane 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ę

Usługa Fleet Engine musi być powiadamiana o zatrzymaniu pojazdu. Spowoduje to ustawienie wszystkich zadań powiązanych z przystankiem w stanie ZAMKNIĘTE. Powiadomień Fleet Engine możesz wysłać za pomocą pakietu SDK sterownika albo ze środowiska serwera. Nie należy łączyć 2 metod jednocześnie, aby uniknąć wyścigu i utrzymać jedno źródło wiarygodnych informacji.

gRPC

Z przykładu poniżej dowiesz się, jak użyć biblioteki Java gRPC, aby 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()
    // 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 postoju w środowisku serwera, wykonaj wywołanie HTTP REST „UpdateDeliveryVehicle”:

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

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

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

Treść żądania musi zawierać encję DeliveryVehicle:

  • Pola wymagane:

    PoleWartość
    fragmenty_pojazdu_pojazdu Zakończony postój nie powinien już znajdować się na liście pozostałych przystanków.

  • Pola opcjonalne:

    • Brak

Pozostałe pola elementu zostaną zignorowane 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żliwe jest jednak modyfikowanie stanu, wyniku zadania, czasu jego wyniku, lokalizacji wyniku zadania i atrybutów przez bezpośrednią aktualizację encji zadania. Jeśli na przykład zadanie nie zostało przypisane do pojazdu, możesz je zamknąć, bezpośrednio aktualizując jego stan.

gRPC

Oto przykład aktualizowania zadania za pomocą gRPC.

REST

Oto przykład aktualizowania zadania za pomocą REST.

Zamykanie zadania

Aby zamknąć zadanie przypisane do pojazdu, powiadom Fleet Engine o tym, że pojazd zakończył postoje, na którym to zadanie jest wykonywane, lub usuń je z listy postojów. Aby to zrobić, możesz ustawić listę pozostałych pojazdów zatrzymujący się tak samo jak podczas aktualizowania kolejności zadań dla pojazdu.

Jeśli zadanie nie zostało jeszcze przypisane do pojazdu i musi zostać zamknięte, zmień jego stan na ZAMKNIĘTE. Nie można jednak ponownie otworzyć zadania ZAMKNIĘTE.

Zakończenie zadania nie oznacza powodzenia ani niepowodzenia. Wskazuje on, że zadanie nie jest już uważane za w toku. W przypadku śledzenia przesyłki ważne jest, aby określić rzeczywisty wynik zadania, aby można było zobaczyć dane dotyczące 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) // It's only possible to directly CLOSE a
  .build();                    // task which 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 z wartością Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść żądania musi zawierać encję Task:

  • Pola wymagane:

    PoleWartość
    state Stan.ZAMKNIĘTE

  • Pola opcjonalne:

    PoleWartość
    wynik zadania Wynik.SUCCEEDED lub Wynik.FAILED
    ZadanieWyniku Czas ukończenia zadania.
    zadanieWynikLocation Lokalizacja, w której zostało wykonane zadanie. Fleet Engine domyślnie wybierze ostatnią lokalizację pojazdu, chyba że ręcznie zastąpisz to ustawienie przez dostawcę.

Pozostałe pola elementu zostaną zignorowane 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

Ustawianie lokalizacji wyniku zadania i wyników

Zamknięcie zadania nie oznacza powodzenia ani niepowodzenia, wskazuje, że zadanie nie jest już w toku. W przypadku śledzenia przesyłki ważne jest, aby określić rzeczywisty wynik zadania, aby można było uzyskać informacje o dostawie i prawidłowe rozliczanie za usługi. Po ustawieniu zadania nie można go zmienić. Po ustawieniu czasu i lokalizacji wyników zadania można zmienić.

Zadania ze stanem ZAMKNIĘTE mogą mieć wynik SUCCEEDED lub FAILED. Fleet Engine nalicza opłaty tylko za zadania związane z dostarczaniem o stanie SUCCEEDED.

Podczas zaznaczania wyniku zadania Fleet Engine automatycznie uzupełni lokalizację wyniku zadania ostatnią znaną lokalizacją pojazdu. Można je jednak zastąpić.

gRPC

Podczas konfigurowania wyniku zadania możesz ustawić lokalizację wyniku. Uniemożliwi to Fleet Engine ustawienie jej domyślnej wartości dla ostatniej lokalizacji pojazdu. Możesz też zastąpić lokalizację wyniku zadania ustawioną przez Fleet Engine później. Fleet Engine nigdy nie zastąpi podanej przez Ciebie lokalizacji wyniku zadania. Nie można ustawić lokalizacji wyniku zadania dla zadania, które nie ma określonego wyniku. W jednym żądaniu można ustawić zarówno wynik, jak i lokalizację wyniku zadania.

Z przykładu poniżej dowiesz się, jak za pomocą biblioteki Java gRPC ustawić wynik zadania na SUCCEEDED i ustawić lokalizację, w której zostało ono wykonane:

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 z wartością Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Treść żądania musi zawierać encję Task:

  • Pola wymagane:

    PoleWartość
    wynik zadania Wynik.SUCCEEDED lub Wynik.FAILED
    ZadanieWyniku Sygnatura czasowa ustawienia wyniku zadania (od dostawcy). Jest to data ukończenia zadania.

  • Pola opcjonalne:

    PoleWartość
    zadanieWynikLocation Lokalizacja, w której zostało wykonane zadanie. Fleet Engine domyślnie wybierze ostatnią lokalizację pojazdu, chyba że ręcznie zastąpisz to ustawienie przez dostawcę.

Pozostałe pola elementu zostaną zignorowane 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

Przekierowanie przesyłki

Po utworzeniu zadania dostawy nie można zmienić jego zaplanowanej lokalizacji. Aby przekierować przesyłkę, zamknij zadanie dostawy bez określania wyniku, a następnie utwórz nowe zadanie ze zaktualizowaną planowaną lokalizacją. Po utworzeniu nowego zadania przypisz je do tego samego pojazdu. Aby uzyskać więcej informacji, przeczytaj artykuł o zamykaniu zadania dostawy i przypisywaniu zadania.

Używanie modułów dostarczania i pojazdów dostawczych

Jeśli używasz pojazdów dostawczych do transportu przesyłek do pojazdów dostawczych w ciągu dnia, modeluj przeniesienie przesyłek jako zaplanowane zadanie postoju w pojazdach dostawczych. Aby zapewnić dokładne śledzenie lokalizacji, przypisuj zadanie dostawy tylko w przypadku przeniesionej przesyłki dopiero po załadowaniu jej do pojazdu dostawczego. Więcej informacji znajdziesz w artykule o zaplanowanym przystanku.

Przechowuj stan wysyłki i inne metadane

Po zakończeniu zadania dostawy rejestrowany jest w nim stan i wynik zadania. Możesz jednak zaktualizować inne metadane, które dotyczą dostawy. Aby przechowywać inne metainformacje, do których możesz się odwoływać 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 Cykl życia zadania.

Wyszukiwanie pojazdu

Pojazd możesz znaleźć w pakiecie SDK sterownika albo w środowisku serwera.

gRPC

Z przykładu poniżej dowiesz się, jak użyć biblioteki Java gRPC do wyszukania pojazdu:

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 „GetVehicle”:

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

<id> to unikalny identyfikator zadania.

<vehicleId> to identyfikator pojazdu, którego szukasz.

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

Treść żądania musi być pusta.

Jeśli wyszukiwanie się powiedzie, treść odpowiedzi będzie zawierała element 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

Zadanie możesz wyszukać w środowisku serwera. Driver SDK nie obsługuje wyszukiwania zadań.

gRPC

Z przykładu poniżej dowiesz się, jak użyć biblioteki Java gRPC do wyszukania zadania:

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 ze środowiska serwera, wykonaj wywołanie HTTP REST „GetTask”:

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

<id> to unikalny identyfikator zadania.

<taskId> to identyfikator zadania do wyszukania.

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

Treść żądania musi być pusta.

Jeśli wyszukiwanie się powiedzie, treść odpowiedzi będzie zawierała 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}"

wyszukiwać informacje o zadaniach dostawy według identyfikatora śledzenia,

Informacje o zadaniach dostawy możesz wyszukiwać na różne sposoby, z których każdy ma inny cel:

  • 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żywane przez oprogramowanie klienta do przekazywania użytkownikowi ograniczonych informacji, na przykład o tym, kiedy paczka dotrze do klienta.

Z tej sekcji dowiesz się, jak wyszukiwać informacje o zadaniach przy użyciu identyfikatora śledzenia. Jeśli chcesz wyszukać zadanie według identyfikatora zadania, przejdź do sekcji Wyszukiwanie zadania.

Aby wyszukać informacje według identyfikatora śledzenia, możesz skorzystać z jednej z następujących metod:

Wymagania dotyczące wyszukiwania

  • Informacje o dostawie podane przez identyfikator śledzenia są zgodne z regułami widoczności określonymi w artykule Kontrolowanie widoczności monitorowanych lokalizacji.

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

  • Aby ograniczyć zagrożenia dla bezpieczeństwa, użyj możliwie najwęższego tokena. Jeśli na przykład używasz tokena konsumenta dostawy, wszystkie wywołania interfejsu Fleet Engine Deliveries API zwracają tylko informacje istotne dla tego użytkownika, takie jak firma kurierska lub odbiorca przesyłki. Wszystkie inne informacje w odpowiedziach zostaną usunięte. Więcej informacji o tokenach znajdziesz w sekcji Tworzenie tokena internetowego JSON (JWT) do autoryzacji.

Wyszukiwanie w Javie przy użyciu gRPC

Z przykładu poniżej dowiesz się, jak za pomocą biblioteki Java gRPC wyszukiwać 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;
}

Wyszukiwanie przy użyciu protokołu HTTP

Aby wyszukać zadanie dostawy w przeglądarce, wykonaj 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 z wartością Bearer <token>, gdzie <token> to token wydany przez fabrykę tokenów Fleet Engine.

Jeśli wyszukiwanie się powiedzie, 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świetlać zadania ze środowiska serwera lub przeglądarki. Pakiet Driver SDK nie obsługuje wyświetlania listy zadań.

Wyświetlanie listy zadań wymaga szerokiego dostępu do zadań. Zadania związane z wyświetlaniem listy są przeznaczone tylko dla zaufanych użytkowników. Podczas tworzenia żądań zadań list należy używać tokenów uwierzytelniania floty usług dostarczania lub tokenów uwierzytelniania superużytkownika.

Na liście zadań zostaną usunięte te pola:

  • Pojazdy.planned_location
  • VehicleStop.state (stan pojazdu)
  • VehicleStop.TaskInfo.taskId

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

  • atrybuty
  • identyfikator_pojazdu_dostawcy
  • state
  • planowana_lokalizacja
  • challenge_duration
  • wynik_zadania
  • lokalizacja_zadania
  • źródło_lokalizacji_zadania
  • czas_zadania
  • identyfikator_śledzenia
  • typ

Użyj tych formatów pól wybranych na podstawie propozycji poprawy 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
Enum 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ń filtrów znajdziesz w sekcji AIP-160.

Jeśli nie określisz zapytania filtra, zobaczysz wszystkie zadania.

Listy zadań są podzielone na strony. Rozmiar strony można określić w żądaniach zadań listy. Jeśli został określony rozmiar strony, liczba zwróconych zadań nie może być większa niż podany rozmiar strony. W przypadku braku rozmiaru strony używana jest rozsądna wartość domyślna. Jeśli żądany rozmiar strony przekracza wewnętrzną wartość maksymalną, używane jest wewnętrzne maksimum.

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

gRPC

Z przykładu poniżej dowiesz się, jak użyć biblioteki Java gRPC, aby wyświetlić listę zadań związanych z identyfikatorem shippingVehicleId i atrybutem zadania. Pomyślna odpowiedź może być nadal pusta. Pusta odpowiedź oznacza, że do zadań nie są powiązane żadne zadania z dostarczonym identyfikatorem 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ń w przeglądarce, wykonaj 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 z zapytaniem filtra ze zmianą znaczenia w adresie URL.

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

Jeśli wyszukiwanie się powiedzie, treść odpowiedzi będzie zawierała dane o następującej strukturze:

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

Pomyślna odpowiedź może być nadal 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świetlenie listy pojazdów dostawczych

Możesz wyświetlać listę pojazdów realizujących dostawę ze środowiska serwera lub przeglądarki. Pakiet SDK Kierowcy nie obsługuje wyświetlania informacji o pojazdach dostarczających informacje.

Wyświetlanie informacji o pojazdach dostawczych wymaga szerokiego dostępu do pojazdów dostawczych i jest przeznaczone tylko dla zaufanych użytkowników. Używaj tokenów uwierzytelniania floty usług lub tokenów uwierzytelniania superużytkownika podczas tworzenia żądań pojazdów dostarczających listy.

Te pola zostały usunięte ze względu na ich wpływ na rozmiar odpowiedzi:

  • Bieżąca trasaSegment
  • PozostałeSegmentyPojazdówPojazdów

Pojazdy dostawcze z listy możesz filtrować według ich właściwości attributes. Aby na przykład wysłać zapytanie do atrybutu o kluczu my_key i wartości my_value, użyj funkcji attributes.my_key = my_value. Aby wysłać zapytanie o więcej atrybutów, złącz zapytania za pomocą logicznych operatorów AND i OR, jak w przykładzie attributes.key1 = value1 AND attributes.key2 = value2. Pełny opis składni zapytań filtra znajdziesz w AIP-160.

Wymienione pojazdy dostawcze możesz filtrować według lokalizacji za pomocą parametru żądania viewport. Parametr żądania viewport definiuje widoczne obszary za pomocą 2 współrzędnych ograniczających: szerokości i długości geograficznej high (północny wschód) i low (południowy zachód). Żądania są odrzucane, jeśli zawierają dużą szerokość geograficzną, która jest geograficznie krótsza niż niska.

Listy pojazdów realizujących wyświetlenia są domyślnie podzielone na strony, mając uzasadniony rozmiar. Jeśli podasz rozmiar strony, żądanie zwróci tylko nie więcej niż liczbę pojazdów określoną w limicie. Jeśli żądany rozmiar strony przekracza wewnętrzną wartość maksymalną, używane jest wewnętrzne maksimum. Domyślny i maksymalny rozmiar strony to 100 pojazdów.

Lista pojazdów realizujących dostawy może zawierać token umożliwiający odczytywanie następnej strony wyników. Token strony jest obecny w odpowiedzi tylko wtedy, gdy dostępnych jest więcej stron pojazdów dostawczych. Aby pobrać następną stronę zadań, użyj tokena strony z żądaniem, które jest poza tym identyczne z poprzednim żądaniem.

gRPC

Z przykładu poniżej dowiesz się, jak użyć biblioteki Java gRPC, aby wyświetlić listę pojazdów wyświetlających w określonym regionie z określonym atrybutem. Odpowiedź udana może być nadal pusta. Oznacza to, że w określonym widocznym obszarze nie znajdują się obecnie 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ń w przeglądarce, wykonaj 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 „filtra” adresu URL z wartością zapytania filtra ze zmianą znaczenia.

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

Jeśli wyszukiwanie się powiedzie, treść odpowiedzi będzie zawierała dane o następującej strukturze:

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

Pomyślna odpowiedź może być nadal pusta. Oznacza to, że nie znaleziono żadnych pojazdów realizujących wyświetlenia, które spełniają 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

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

  • Preferowana: użyj biblioteki śledzenia dostawy w języku JavaScript. Biblioteka umożliwia wizualizację lokalizacji pojazdów i lokalizacji interesujących Cię, które są monitorowane we Fleet Engine. Zawiera komponent mapy JavaScript, który zastępuje standardowy obiekt google.maps.Map, oraz komponenty danych do łączenia się z Fleet Engine. Dzięki temu możesz udostępnić konfigurowalny, animowany sposób śledzenia przesyłki z poziomu aplikacji internetowej lub mobilnej.

  • Korzystając z interfejsu Fleet Engine Deliveries API, możesz wdrożyć własne śledzenie przesyłek. Kluczem jest wyszukiwanie zadań związanych z dostawą według identyfikatora śledzenia.

Jeśli używasz roli Dostawa na poziomie konsumenta, wszystkie wywołania interfejsu Fleet Engine Deliveries API zwracają tylko informacje istotne dla nadawcy lub odbiorcy. Wszystkie inne informacje w odpowiedziach zostaną usunięte. To Ty odpowiadasz za uwierzytelnianie użytkowników. Dodatkowo informacje o lokalizacji będą filtrowane na podstawie aktualnie wykonywanego zadania. W trakcie zadania związanego z niedostępnością informacje o lokalizacji nie zostaną udostępnione użytkownikowi.

Logging

Możesz włączyć opcję pozwalającą Fleet Engine na wysyłanie logów RPC do Cloud Logging. Więcej informacji znajdziesz w artykule Logowanie.

Role i tokeny autoryzacji

Jak opisano w artykule Zarządzanie cyklem życia pojazdu i zadań oraz w uwagach dotyczących autoryzacji dla poszczególnych przypadków użycia, wywołania Fleet Engine wymagają 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 generowania tych tokenów mogą mieć jedną lub więcej ról, a każda rola musi przyznawać inny zestaw uprawnień.

Więcej informacji znajdziesz w artykule Uwierzytelnianie i autoryzacja.

Rozwiązywanie problemów

Odporność

Fleet Engine nie jest uważany za źródło wiarygodnych danych. Twoim obowiązkiem jest przywrócenie stanu systemu w razie potrzeby bez korzystania z Fleet Engine.

Utracony stan we Fleet Engine

Pracując z Fleet Engine, zaimplementuj klienty, tak aby system naprawiał się automatycznie w przypadku awarii. Na przykład gdy Fleet Engine próbuje zaktualizować pojazd, może wysłać odpowiedź z błędem wskazującym, że pojazd nie istnieje. Klient powinien następnie odtworzyć pojazd w nowym stanie. Rzadko się tak zdarza, dlatego system musi być w razie potrzeby odporny.

W bardzo mało prawdopodobnym scenariuszu katastrofalnej awarii Fleet Engine konieczne może być odtworzenie większości pojazdów i zadań albo wszystkich zadań. Jeśli wskaźnik tworzenia stanie się zbyt wysoki, niektóre żądania mogą zostać ponownie nieudane z powodu problemów z limitami, ponieważ prowadzone są kontrole limitów, które mają na celu uniknięcie ataków typu DoS (odmowa usługi). W takim przypadku możesz zmniejszyć częstotliwość odtwarzania, używając strategii do ponowienia próby w przypadku ponownych prób.

Utracony stan w aplikacji kierowcy

Jeśli aplikacja sterownika ulegnie awarii, musi odtworzyć bieżący stan w pakiecie SDK sterownika. Aplikacja powinna próbować odtworzyć zadania, aby upewnić się, że istnieją, i przywrócić ich obecny stan. Aplikacja powinna też ponownie utworzyć i jawnie ustawić listę przystanków w pakiecie SDK sterownika.

Przywracanie musi być wykonywane samodzielnie, bez korzystania z informacji z Fleet Engine. Wyjątkiem są błędy wskazujące, czy i kiedy element już istnieje w bazie danych. Jeśli encja już istnieje, ten błąd może zostać wchłonięty i można zaktualizować encję za pomocą jej identyfikatora.

Najczęstsze pytania

Co się stanie, jeśli kierowca zatrzyma się w złej kolejności?

W takim przypadku należy najpierw zaktualizować kolejność zadań, a następnie przejść dalej w zwykły sposób, oznaczać przybycie na miejsce, ukończenie zadania itp. W przeciwnym razie system może stać się niespójny. Szacowany czas dotarcia może się okazać nieprawidłowy i mogą pojawić się nieoczekiwane błędy.