Решение Last Mile Fleet Solution в настоящее время доступно только для избранных клиентов. Свяжитесь с отделом продаж , чтобы узнать больше.

Начало работы с Fleet Engine

API Fleet Engine Deliveries позволяет моделировать действия вашего автопарка на первой и последней милях доставки. API доставки предоставляется через Driver SDK для Android и iOS, а также может использоваться напрямую через вызовы HTTP REST или gRPC.

Начальная настройка

API доставки Fleet Engine настраивается через Google Cloud Console. Сведения о действиях, которые необходимо выполнить в консоли, и о том, как создать веб-токен JSON для авторизации, см. в разделе Аутентификация и авторизация . Подробнее об использовании консоли см. в документации Google Cloud Console .

Проверьте настройки

После создания учетных записей службы вы должны убедиться, что настройка завершена, и вы можете создать средство доставки. Выполнив проверку на этом этапе рабочего процесса, вы убедитесь, что устранены распространенные проблемы с авторизацией, которые могут возникнуть при настройке вашего проекта. Следуйте руководству по проверке установки . В этом руководстве содержится подробная информация о том, как использовать утилиту командной строки gcloud для тестирования двух ключевых частей вашей установки: подписание токена авторизации и создание пробного средства доставки.

В качестве альтернативы вы можете использовать примеры сценариев аутентификации Fleet Engine для проверки вашей установки.

Клиентские библиотеки

Мы публикуем клиентские библиотеки на нескольких распространенных языках программирования. Эти библиотеки обеспечивают лучший опыт разработчиков по сравнению с необработанным REST или gRPC. Инструкции по получению клиентских библиотек для вашего серверного приложения см. в разделе Клиентские библиотеки .

Примеры Java в этой документации предполагают знакомство с gRPC.

Структуры данных

API Delivery использует две структуры данных для моделирования получения и доставки отправлений:

  • Транспортное средство, используемое для перевозки груза.
  • Задачи по забору и доставке груза.

Кроме того, вы можете использовать задачи для моделирования перерывов и запланированных остановок водителя в течение дня.

Транспортные средства доставки

Транспортные средства доставки перевозят грузы со склада в пункт доставки и из пункта выдачи в склад. В некоторых случаях они также могут доставить груз напрямую из пункта выдачи в пункт доставки.

Вы можете использовать Driver SDK для создания объекта DeliveryVehicle в Fleet Engine и для отправки обновлений местоположения для отгрузки и отслеживания автопарка.

Задания

Каждому транспортному средству назначены задачи. Это могут быть задачи по вывозу или доставке, обязательные перерывы для водителей или запланированные остановки в ящиках для выдачи или в местах расположения клиентов. Каждая задача должна иметь уникальный идентификатор задачи, но может иметь один и тот же идентификатор отслеживания. Задачи и порядок их планирования используются для расчета окон ETA для каждой задачи.

Используйте диспетчер задач Driver SDK для создания задач в Fleet Engine.

Отгрузочные задачи

Задачи по отгрузке связаны с получением или выгрузкой груза. При создании задачи на отгрузку необходимо указать номер отслеживания или идентификатор. Вы также должны указать время ожидания, чтобы учесть дополнительное время для выполнения задачи, поиска парковки или ходьбы до места передачи.

  • Создайте задачу самовывоза для получения отправления, указав место получения и номер отслеживания или идентификатор.
  • Создайте задачу доставки на доставку отправления, указав место доставки и номер отслеживания или ID.

Задачи недоступности

Создайте задачу недоступности на период времени, когда транспортное средство не будет доступно для самовывоза или доставки. Это может быть перерыв для дозаправки автомобиля или перерыв для отдыха водителя. Укажите продолжительность перерыва при создании задачи. Перерывы не обязательно делать в определенном месте, но указание места обеспечивает более точное время прибытия в течение дня.

Во время задачи недоступности информация о местоположении не передается конечному пользователю. Например, местоположение транспортного средства скрыто от менеджеров автопарка с помощью библиотеки отслеживания автопарка.

Запланированные остановки задач

Создавайте задачи запланированных остановок для моделирования остановок, которые должны быть сделаны транспортным средством доставки. Например, вы можете создать задачу запланированной остановки для ежедневной запланированной остановки сбора в определенном месте, независимо от других доставок или вывозов в том же месте. Вы также можете создавать задачи запланированных остановок для сборов из ящиков или моделировать пересадку фидерных транспортных средств или остановки в сервисных центрах и точках обслуживания.

Вы можете увидеть конкретные поля, содержащиеся в каждой структуре данных, изучив справочную документацию по API для DeliveryVehicle ( gRPC , REST ) ​​и Task ( gRPC , REST ).

Рекомендации по идентификатору задачи

Идентификаторы задач должны быть уникальными и не должны раскрывать личную информацию (PII) или данные в открытом виде. Идентификаторы задач также должны соответствовать следующим требованиям к формату:

  • Идентификаторы должны быть допустимыми строками Unicode.
  • Идентификаторы должны содержать не более 64 символов.
  • Идентификаторы будут нормализованы в соответствии с формой нормализации Unicode C .
  • Идентификаторы не могут содержать следующие символы ASCII: "/", ":", "\", "?" или "#".

Ниже приведены некоторые примеры хороших идентификаторов задач:

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

В следующей таблице показаны примеры неверных идентификаторов задач:

Неверные идентификаторы задач Причина
31.08.2019-20:48-46.70746,-130.10807,-85.17909,61.33680 Нарушает требования к персональным данным и символам: запятые, точки, двоеточия и косые черты.
JohnDoe-577b484da26f-Купертино-Санта-Крус Нарушает требования PII.
4R0oXLToF”112 Летний доктор Ист Хартфорд, CT06118”577b484da26f8a Нарушает требования к личным данным и символам: пробелы, запятые и кавычки. Длиннее 64 символов.

Срок службы автомобиля

Объект DeliveryVehicle представляет транспортное средство доставки первой или последней мили. Вы создаете объект DeliveryVehicle , используя:

  • Идентификатор проекта Google Cloud, который содержит учетную запись службы, используемую для вызова API Fleet Engine.
  • Идентификатор автомобиля, принадлежащего клиенту.

Идентификаторы транспортных средств должны быть уникальными для каждого транспортного средства. Их не следует повторно использовать для другого транспортного средства, если для этого транспортного средства нет активных задач.

Обязательно проверьте наличие ошибки NOT_FOUND при вызове UpdateDeliveryVehicle , а затем, при необходимости, вызовите CreateDeliveryVehicle для создания нового транспортного средства. Объект DeliveryVehicle , который не был обновлен с помощью UpdateDeliveryVehicle , автоматически удаляется через семь дней. Обратите внимание, что вызов CreateDeliveryVehicle с уже существующей парой идентификатора проекта и идентификатора транспортного средства приводит к ошибке.

Атрибуты автомобиля

Сущность DeliveryVehicle содержит повторяющееся поле DeliveryVehicleAttribute . API ListDeliveryVehicles включает поле filter , которое может ограничивать возвращаемые объекты DeliveryVehicle только объектами с указанными атрибутами. DeliveryVehicleAttribute не влияет на поведение маршрутизации Fleet Engine.

Не включайте в атрибуты личную или конфиденциальную информацию, так как это поле может быть видно пользователям.

Жизнь задачи

Задачи в Fleet Engine можно создавать, обновлять и запрашивать с помощью интерфейсов API доставки gRPC или REST.

Объект Task имеет поле состояния для отслеживания его продвижения по жизненному циклу. Значения перемещаются с OPEN на CLOSED. Новые задачи создаются в состоянии OPEN, что указывает на то, что либо:

  • Задача еще не назначена средству доставки.
  • Транспортное средство доставки еще не проехало назначенную остановку транспортного средства задачи.

Задание может быть назначено транспортному средству, только когда оно находится в ОТКРЫТОМ состоянии.

Задание можно отменить, удалив его из списка остановок транспорта. Затем его статус автоматически устанавливается на ЗАКРЫТО.

Когда транспортное средство задачи завершает остановку транспортного средства задачи, обновите поле результата задачи на SUCCEEDED или FAILED и укажите временную метку события. Результат задачи может быть установлен в любое время до или после завершения задачи, но может быть установлен только один раз.

Затем библиотека JavaScript Fleet Tracking может показать результат задачи. Статус задачи автоматически устанавливается на ЗАКРЫТО. Дополнительные сведения см. в разделе Отслеживание парка с помощью библиотеки отслеживания флота JavaScript .

Как и в случае с транспортными средствами, задачи, которые не обновлялись по истечении семи дней, удаляются, а попытка создать задачу с уже существующим идентификатором возвращает ошибку.

Примечание. Fleet Engine не поддерживает явное удаление задачи. Сервис автоматически удаляет задачи через семь дней без обновлений. Если вы хотите хранить данные задачи дольше семи дней, вы должны реализовать эту функцию самостоятельно.

Атрибуты задачи

Сущность Task содержит повторяющееся поле TaskAttribute , которое может иметь значение одного из трех типов: строка, число и логическое значение. API ListTasks включает поле filter , которое может ограничивать возвращаемые объекты Task теми, у кого есть указанные атрибуты. TaskAttribute не влияют на поведение маршрутизации Fleet Engine.

Не включайте в атрибуты личную или конфиденциальную информацию, так как это поле может быть видно пользователям.

Управление транспортным средством и жизненным циклом задач

Чтобы управлять жизненными циклами транспортных средств и задач в вашей системе, вы используете API доставки транспортных средств для создания, обновления и отслеживания ваших транспортных средств и связанных с ними задач. Ваша внутренняя система выступает в качестве надежного источника данных, которые API доставки дополняется от вашего имени.

В то же время приложение водителя связывается напрямую с Fleet Engine для обновления информации о местоположении устройства и маршруте. Эта модель позволяет Fleet Engine эффективно управлять местоположением в режиме реального времени и отправлять его непосредственно в библиотеку отслеживания, которую затем можно использовать для потребителей, которым нужны обновления статуса их заказа.

Например, предположим, что у вас есть следующий сценарий:

  • Водитель приближается к остановке доставки, и Fleet Engine отправляет местоположение устройства в библиотеку отслеживания, которую ваше потребительское приложение использует для оповещения потребителя о близости его посылки.
  • После того, как водитель завершит отправку, он нажимает кнопку «Отправка доставлена» в приложении водителя.
  • Это отправляет информацию в вашу серверную систему, которая выполняет необходимые шаги проверки и проверки бизнеса.
  • Ваша система подтверждает выполнение задачи как ВЫПОЛНЕННУЮ и обновляет Fleet Engine с помощью API доставки.

Следующая диаграмма иллюстрирует эти процессы на общем уровне. Он также показывает стандартные отношения между вашей системой, клиентом и Fleet Engine.

Интеграция диаграммы API доставки

Управление клиентскими токенами

Для любых обновлений местоположения, исходящих из приложения водителя и отправляемых непосредственно в Fleet Engine, требуются токены авторизации. Рекомендуемый подход к обработке обновлений от клиента к Fleet Engine — предоставить приложению-драйверу токен с ограниченной областью действия, чтобы оно могло обновлять только местоположение устройства в Fleet Engine. Для этого типа токена вы используете роль служебной учетной записи, известную как Пользователь ненадежного водителя Fleet Engine Delivery . Это гарантирует, что вызовы, исходящие с мобильных устройств, которые считаются средами с низким уровнем доверия, соответствуют принципу наименьших привилегий .

Другие роли сервисного аккаунта

Если вместо этого вы хотите разрешить приложениям-драйверам выполнять прямые обновления Fleet Engine помимо тех, которые ограничены ролью «Ненадежный водитель», например, для определенных обновлений задач, вы можете использовать роль «Надежный водитель». Сведения о модели, использующей роль доверенного водителя, см. в разделе Модель доверенного водителя .

Дополнительные сведения об использовании ролей недоверенных и доверенных драйверов см. в разделе Настройка облачного проекта .

Моделирование рабочего дня.

В следующей таблице показано, как может выглядеть рабочий день водителей первой или последней мили в компании по доставке и логистике. Ваша компания может отличаться в деталях, но вы можете увидеть, как вы можете смоделировать рабочий день.

Время Активность Моделирование
В течение 24 часов с начала дня Диспетчер распределяет отправления по транспортным средствам доставки или маршрутам. Задачи на доставку отправлений, заборы, перерывы и т. д. могут быть созданы в Fleet Engine заранее. Например, вы можете создать задачу получения груза , задачу доставки груза , запланированную недоступность или запланированную остановку .

Задачи должны быть назначены транспортному средству после завершения набора пакетов доставки и порядка, в котором они будут доставлены.
Начало дня Водитель начинает день в депо, войдя в приложение Driver. Инициализируйте API драйвера доставки. При необходимости создайте средство доставки в Fleet Engine.
Водитель загружает посылки в машину доставки, сканирует посылки. Если задачи по доставке отправлений не были созданы заранее, создайте задачи по доставке отправлений во время сканирования.
Водитель подтверждает порядок выполнения задач. Если они не были созданы заранее, создайте задачи по вывозу груза , запланированную недоступность и запланированные остановки .
Водитель покидает депо и берется за следующее количество задач, которые необходимо выполнить. Назначьте все задачи или подмножество задач транспортному средству, зафиксировав порядок их выполнения.
Водитель доставляет груз. После прибытия на остановку выдачи выполнить действия, связанные с прибытием транспортного средства на остановку . После доставки отправления закройте задачу доставки и, при желании, сохраните статус отправления и другую метаинформацию . После выполнения всех задач на остановке и перед тем, как начать движение к следующей остановке, выполните действия, связанные с тем, что транспортное средство завершает остановку и движется к следующей остановке .
Водитель встречает фидерное транспортное средство, чтобы передать дополнительные грузы на транспортное средство доставки. Место встречи для пересадки между транспортными средствами подачи и доставки должно быть смоделировано как запланированная остановка .

После передачи и сканирования отправлений создайте задачи доставки , если они еще не созданы. Затем обновите порядок выполнения задач, назначив задачи транспортному средству и обновив порядок выполнения задач .
Водитель получает уведомление о заявке на погрузку. После принятия заявки на самовывоз создайте задачу на самовывоз . Затем обновите порядок выполнения задач, назначив задачи транспортному средству и обновив порядок выполнения задач .
Полдень Водитель берет перерыв на обед. Если расположение связано с задачей недоступности, рассматривайте ее как любую другую задачу. Выполнение действий, связанных с подъездом транспортного средства к остановке , завершением остановки и движением транспортного средства к следующей остановке .

В противном случае никаких дальнейших действий не требуется до окончания перерыва. Удалите задачу, подтвердив следующую и оставшуюся задачи и обновив порядок задач .
Водитель забирает посылку. Это моделируется так же, как остановка доставки. Выполнение действий, связанных с подъездом транспортного средства к остановке и закрытием задачи , а также, опционально, сохранением статуса отгрузки и другой метаинформации . После выполнения всех задач на остановке и перед тем, как начать движение к следующей остановке, выполните действия, связанные с тем, что транспортное средство завершает остановку и движется к следующей остановке . Примечание. Для обеспечения правильного выставления счетов все самовывозы должны иметь соответствующую задачу доставки. Если пикап должен быть доставлен в другое место на том же маршруте водителя в тот же день, мы рекомендуем смоделировать эту задачу доставки как любую другую задачу доставки на маршруте. Если водитель везет пикап обратно в депо, мы рекомендуем создать задачу доставки в пункте назначения депо.
Водитель делает запланированную остановку, чтобы забрать грузы из почтового ящика. Это смоделировано так же, как и любая другая остановка пикапа. Выполнение действий, связанных с подъездом транспортного средства к остановке и закрытием задачи . Выполнив все задачи на остановке и начав движение к следующей остановке, выполните действия, связанные с тем, что транспортное средство завершает остановку и транспортное средство движется к следующей остановке .
Водитель получает уведомление о том, что груз направляется в другое место. Установите для исходной задачи доставки отправления статус ЗАВЕРШЕНА и создайте новую задачу доставки отправления для нового места доставки. Дополнительные сведения см. в разделе Перенаправление отправления .
Водитель пытался доставить посылку, но не смог. Это моделируется аналогично успешной остановке доставки, помечая задачу доставки как выполненную. Выполнять действия, связанные с прибытием транспортного средства на остановку . Если не удалось доставить отправление, закройте задачу и, по желанию, сохраните статус отправления и другую метаинформацию . После выполнения всех задач на остановке и перед тем, как начать движение к следующей остановке, выполните действия, связанные с тем, что транспортное средство завершает остановку и движется к следующей остановке .
Водитель был уведомлен о задержании (не доставке) груза. После получения и подтверждения уведомления установите для задачи статус ЗАВЕРШЕНА.
Водитель был уведомлен о следующей доставке определенного груза, изменив подтвержденный заказ на доставку. Обновите порядок задач .
Водитель решает доставить посылку не в порядке. Обновите порядок задач , а затем действуйте как обычно.
Водитель доставляет несколько отправлений в одно место. Это моделируется аналогично остановке доставки одной партии. После прибытия на остановку выполнить действия, связанные с прибытием транспортного средства на остановку . После доставки каждого отправления закройте все задачи и, при желании, сохраните статус отправления и другую метаинформацию . После выполнения всех задач на остановке и перед тем, как начать движение к следующей остановке, выполните действия, связанные с тем, что транспортное средство завершает остановку и движется к следующей остановке .
Конец дня Водитель возвращается в депо. Если водитель возвращается в депо с отправлениями, забранными во время их маршрута, вы также должны создать и закрыть каждую посылку в качестве задачи доставки, чтобы обеспечить правильное выставление счетов. Вы можете сделать это, смоделировав депо, как и любую другую остановку доставки. Если депо не используется в качестве остановки доставки, вы все равно можете смоделировать депо как запланированную остановку. Это позволит вашим водителям видеть маршрут обратно в депо и предоставит представление об их предполагаемом времени прибытия.

Понимание обновлений местоположения

Обновления местоположения отправляются в Fleet Engine после того, как транспортное средство находится в пути от остановки (включая депо) до прибытия на следующую остановку . Поскольку эти события не обнаруживаются автоматически, их необходимо пометить программно. Используйте библиотеки, которые обнаруживают изменения в способе транспортировки, чтобы инициировать отправку необходимых уведомлений в Fleet Engine.

Обновление местоположения должно быть приостановлено, когда водитель не ведет машину, потому что качество сигналов местоположения резко ухудшается, когда кто-то находится в здании.

Частоту обновления местоположения можно установить в Driver SDK. По умолчанию обновления отправляются каждые 10 секунд.

Остановки транспорта и места доставки

Остановка транспортного средства - это место, где транспортное средство доставки выполняет задачу по доставке или какую-либо другую задачу. Это либо точка доступа, такая как погрузочная площадка, либо место, привязанное к дороге.

Место доставки – это место, где груз доставляется или забирается. Чтобы добраться до места доставки и обратно, может потребоваться некоторая прогулка от остановки транспортного средства.

Например, когда водитель доставляет груз в магазин в торговом центре, машина доставки останавливается на стоянке торгового центра возле ближайшего входа в магазин. Это остановка транспорта. Затем водитель идет от остановки транспортного средства до места в торговом центре, где расположен магазин. Это место доставки.

Для наилучшего отслеживания отгрузки для ваших пользователей подумайте, как задачи доставки назначаются остановкам транспортных средств, и помните, что количество оставшихся остановок транспортных средств для задач доставки сообщается пользователю, чтобы помочь им увидеть ход их доставки.

Например, если водитель выполняет несколько доставок в одно офисное здание, рассмотрите возможность назначения всех задач по доставке на одну остановку транспортного средства. Если каждая задача доставки назначена отдельной остановке транспортного средства, ваш опыт отслеживания доставки будет менее полезен для ваших пользователей, поскольку отслеживание доступно только тогда, когда транспортное средство находится в пределах ограниченного количества остановок транспортного средства до пункта назначения. Наличие большого количества остановок транспортных средств, выполненных за короткое время, не даст пользователю много времени для отслеживания хода доставки.

Использование мобильных SDK

Прежде чем делать какие-либо вызовы Driver SDK, обязательно инициализируйте его.

Инициализация API драйвера доставки

Перед инициализацией API драйвера доставки в Driver SDK обязательно инициализируйте Navigation SDK . Затем инициализируйте API драйвера доставки, как показано в следующем примере:

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

Случаи использования

В этом разделе описывается, как использовать API доставки для моделирования распространенных вариантов использования.

Уникальные идентификаторы объектов

Формат и значение уникальных идентификаторов объектов, используемых в вызовах REST, непрозрачны для Fleet Engine. Избегайте использования автоматически увеличивающихся идентификаторов и убедитесь, что идентификатор не содержит никакой личной информации (PII), такой как номер телефона водителя.

Создать транспортное средство

Вы можете создать автомобиль либо из Driver SDK , либо из серверной среды.

gRPC

Чтобы создать новое транспортное средство, вы делаете вызов CreateDeliveryVehicle для Fleet Engine. Используйте объект CreateDeliveryVehicleRequest , чтобы определить атрибуты нового средства доставки. Обратите внимание, что любое значение, указанное в поле Name , будет игнорироваться в соответствии с рекомендациями API для идентификаторов, указанных пользователем . Вы должны использовать поле DeliveryVehicleId для установки идентификатора транспортного средства.

При создании DeliveryVehicle можно дополнительно указать два поля:

  • Атрибуты
  • ПоследнееМестоположение

Все остальные поля не должны быть установлены; в противном случае Fleet Engine вернет ошибку, поскольку эти поля либо доступны только для чтения, либо могут быть обновлены только с помощью вызовов UpdateDeliveryVehicle .

Чтобы создать транспортное средство без установки каких-либо дополнительных полей, вы можете оставить поле DeliveryVehicle неустановленным в CreateDeliveryVehicleRequest .

В следующем примере показано, как использовать библиотеку 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;
}

ОТДЫХ

Чтобы создать транспортное средство из серверной среды, выполните вызов HTTP REST для CreateDeliveryVehicle :

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

<id> — это уникальный идентификатор транспортного средства доставки в вашем автопарке.

Заголовок запроса должен содержать поле Authorization со значением Bearer <token> , где <token> — это токен, отчеканенный фабрикой токенов Fleet Engine .

Тело POST представляет создаваемую сущность DeliveryVehicle . Вы можете указать следующие необязательные поля:

  • атрибуты
  • lastLocation

Пример команды 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 игнорирует поле name объекта DeliveryVehicle в соответствии с рекомендациями API для идентификаторов, указанных пользователем . Все остальные поля не должны быть установлены; в противном случае Fleet Engine вернет ошибку, поскольку эти поля либо доступны только для чтения, либо могут быть обновлены только с помощью вызовов UpdateDeliveryVehicle .

Чтобы создать транспортное средство без заполнения каких-либо полей, вы можете оставить тело POST-запроса пустым. Вновь созданное транспортное средство будет иметь идентификатор транспортного средства, извлеченный из параметра deliveryVehicleId в URL-адресе POST.

Пример команды 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}"

Создание задачи по вывозу груза

Вы можете создать задачу получения отправления либо из Driver SDK , либо из серверной среды.

gRPC

В следующем примере показано, как использовать библиотеку Java gRPC для создания задачи получения отправления:

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

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Task settings
String parent = "providers/" + PROJECT_ID;
Task task = Task.newBuilder()
  .setType(Task.Type.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;
}

ОТДЫХ

Чтобы создать задачу получения отправления из серверной среды, выполните вызов HTTP REST для `CreateTask':

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

<id>уникальный идентификатор задачи. Это не должен быть номер для отслеживания посылки. Если в вашей системе нет идентификаторов задач, вы можете сгенерировать универсальный уникальный идентификатор (UUID).

Заголовок запроса должен содержать поле Authorization со значением Bearer <token> , где <token> — это токен, отчеканенный фабрикой токенов Fleet Engine .

Тело запроса должно содержать объект Task :

  • Обязательные поля:

    Поле Ценить
    тип Тип.PICKUP
    состояние Состояние.OPEN
    Идентификатор отслеживания Номер или идентификатор, который вы используете для отслеживания отправления.
    запланированноеМестоположение Место, где должна быть выполнена задача, в данном случае место получения груза.
    продолжительность задачи Ожидаемое время в секундах, которое потребуется, чтобы забрать посылку в пункте выдачи.

  • Необязательные поля:

    Поле Ценить
    целевое окно Временное окно, в течение которого задача должна быть выполнена. В настоящее время это не влияет на поведение маршрутизации.
    атрибуты Список настраиваемых атрибутов задачи. Каждый атрибут должен иметь уникальный ключ.

Все остальные поля сущности игнорируются при создании. Fleet Engine выдает исключение, если запрос включает назначенный deliveryVehicleId. Вы назначаете задачи с помощью UpdateDeliveryVehicleRequests . Дополнительные сведения см. в разделе Назначение задач транспортному средству .

Пример команды 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

Создать задачу доставки отправления

Вы можете создать задачу доставки отправления либо из Driver SDK , либо из серверной среды.

gRPC

В следующем примере показано, как использовать библиотеку Java gRPC для создания задачи доставки отправления:

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

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Task settings
String parent = "providers/" + PROJECT_ID;
Task task = Task.newBuilder()
  .setType(Task.Type.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;
}

ОТДЫХ

Чтобы создать задачу доставки отправления из серверной среды, выполните вызов HTTP REST для `CreateTask':

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

<id>уникальный идентификатор задачи. Это не должен быть номер для отслеживания посылки. Если в вашей системе нет идентификаторов задач, вы можете сгенерировать универсальный уникальный идентификатор (UUID).

Заголовок запроса должен содержать поле Authorization со значением Bearer <token> , где <token> — это токен, отчеканенный фабрикой токенов Fleet Engine .

Тело запроса должно содержать объект Task :

  • Обязательные поля:

    Поле Ценить
    тип Тип.ДОСТАВКА
    состояние Состояние.OPEN
    Идентификатор отслеживания Номер или идентификатор, который вы используете для отслеживания отправления.
    запланированноеМестоположение Место, где должно быть выполнено задание, в данном случае место доставки этой партии.
    продолжительность задачи Ожидаемое время в секундах, которое потребуется для доставки груза в место доставки.

  • Необязательные поля:

    Поле Ценить
    целевое окно Временное окно, в течение которого задача должна быть выполнена. В настоящее время это не влияет на поведение маршрутизации.
    атрибуты Список настраиваемых атрибутов задачи. Каждый атрибут должен иметь уникальный ключ.

Все остальные поля сущности игнорируются при создании. Fleet Engine выдает исключение, если запрос включает назначенный deliveryVehicleId. Вы назначаете задачи с помощью UpdateDeliveryVehicleRequests . Дополнительные сведения см. в разделе Назначение задач транспортному средству .

Пример команды 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

Пакетное создание задач

Вы можете создать пакет задач из серверной среды.

gRPC

В следующем примере показано, как использовать библиотеку Java gRPC для создания двух задач: одной для доставки и одной для получения в одном и том же месте:

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

ОТДЫХ

Чтобы создать задачу доставки и самовывоза из серверной среды, выполните вызов HTTP REST для BatchCreateTasks :

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

Заголовок запроса должен содержать поле Authorization со значением Bearer <token> , где <token> — это токен, отчеканенный фабрикой токенов Fleet Engine .

Тело запроса должно содержать сущность BatchCreateTasksRequest :

  • Обязательные поля:

    Поле Ценить
    Запросы Массив CreateTasksRequest

  • Необязательные поля:

    Поле Ценить
    заголовок `DeliveryRequestHeader`

Каждый элемент CreateTasksRequest в requests должен проходить те же правила проверки, что и запрос CreateTask , за исключением того, что parent поля и поля header являются необязательными. Если они установлены, они должны быть идентичны соответствующим полям на верхнем уровне BatchCreateTasksRequest . См. раздел Создание задачи получения отправления и создание задания доставки отправления , чтобы узнать о конкретных правилах проверки для каждого из них.

Дополнительные сведения см. в справочной документации по API для BatchCreateTasks ( gRPC , REST ).

Пример команды 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

Запланированная недоступность

Вы можете создать задачу, указывающую на недоступность (например, на перерывы водителя или заправку автомобиля) либо из Driver SDK , либо из серверной среды. Запланированная задача недоступности не должна включать идентификатор отслеживания. При желании вы можете указать местоположение.

gRPC

В следующем примере показано, как использовать библиотеку Java gRPC для создания задачи недоступности:

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

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

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

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

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

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

ОТДЫХ

Чтобы создать задачу недоступности из серверной среды, выполните вызов HTTP REST для `CreateTask':

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

<id>уникальный идентификатор задачи. Если в вашей системе нет идентификаторов задач, вы можете сгенерировать универсальный уникальный идентификатор (UUID).

Заголовок запроса должен содержать поле Authorization со значением Bearer <token> , где <token> — это токен, отчеканенный фабрикой токенов Fleet Engine .

Тело запроса должно содержать объект Task :

  • Обязательные поля:

    Поле Ценить
    тип Тип.НЕДОСТУПНО
    состояние Состояние.OPEN
    продолжительность задачи Продолжительность перерыва в секундах.

  • Необязательные поля:

    Поле Ценить
    запланированноеМестоположение Место перерыва, если он должен быть сделан в определенном месте.

Все остальные поля сущности игнорируются при создании. Fleet Engine выдает исключение, если запрос включает назначенный deliveryVehicleId. Вы назначаете задачи с помощью UpdateDeliveryVehicleRequests . Дополнительные сведения см. в разделе Назначение задач транспортному средству .

Пример команды 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

Запланированные остановки

Вы можете создать задачу остановки по расписанию либо из Driver SDK , либо из серверной среды. Запланированная задача остановки может не включать идентификатор отслеживания.

gRPC

В следующем примере показано, как использовать библиотеку Java gRPC для создания запланированной задачи остановки:

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

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Task settings
String parent = "providers/" + PROJECT_ID;
Task task = Task.newBuilder()
  .setType(Task.Type.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;
}

ОТДЫХ

Чтобы создать запланированную задачу остановки из серверной среды, выполните вызов HTTP REST для CreateTask :

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

<id>уникальный идентификатор задачи. Если в вашей системе нет идентификаторов задач, вы можете сгенерировать универсальный уникальный идентификатор (UUID).

Заголовок запроса должен содержать поле Authorization со значением Bearer <token> , где <token> — это токен, отчеканенный фабрикой токенов Fleet Engine .

Тело запроса должно содержать объект Task :

  • Обязательные поля:

    Поле Ценить
    тип Тип.SCHEDULED_STOP
    состояние Состояние.OPEN
    запланированноеМестоположение Расположение остановки.
    продолжительность задачи Ожидаемая продолжительность остановки в секундах.

  • Необязательные поля:

    • Никто

Все остальные поля в сущности игнорируются при создании. Fleet Engine выдает исключение, если запрос включает назначенный deliveryVehicleId. Вы назначаете задачи с помощью UpdateDeliveryVehicleRequests . Дополнительные сведения см. в разделе Назначение задач транспортному средству .

Пример команды 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

Установить целевое временное окно

Целевое временное окно — это TimeWindow , в течение которого задача должна быть выполнена. Например, если вы сообщаете временной интервал доставки получателям доставки, вы можете использовать целевое временное окно задачи, чтобы зафиксировать это временное окно и сгенерировать оповещения или проанализировать производительность после поездки с помощью поля.

Окно целевого времени состоит из времени начала и времени окончания и может быть установлено для любого типа задачи. В настоящее время целевое временное окно не влияет на поведение маршрутизации.

gRPC

В следующем примере показано, как использовать библиотеку Java gRPC для установки окна времени задачи:

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

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

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

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

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

ОТДЫХ

Чтобы установить временное окно задачи с помощью HTTP, вызовите UpdateTask :

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

<id>уникальный идентификатор задачи.

Заголовок запроса должен содержать поле Authorization со значением Bearer <token> , где <token> — это токен, отчеканенный фабрикой токенов Fleet Engine .

Тело запроса должно содержать объект Task :

  • Обязательные поля:

    Поле Ценить
    целевое окно Временное окно, в течение которого задача должна быть выполнена. В настоящее время это не влияет на поведение маршрутизации.

  • Необязательные поля:

    • Никто

Все остальные поля сущности игнорируются при обновлении.

Пример команды 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

Установить конфигурацию видимости отслеживания задач

Видимостью данных в библиотеке отслеживания отгрузки и этих данных, возвращаемых вызовом GetTaskTrackingInfo , можно управлять для каждой задачи путем установки TaskTrackingViewConfig для задачи. See Active vehicle tasks for more information. This can be done when either creating or updating the task. The following is an example of updating the task with this config:

gRPC

The following example shows how to use the Java gRPC library to set the task tracking view config:

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

To set the task tracking view config window using HTTP, call UpdateTask :

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

<id> is a unique identifier for the task.

The request header must contain a field Authorization with the value Bearer <token> , where <token> is a token minted by a Fleet Engine token factory .

The request body must contain a Task entity:

  • Required fields:

    Field Value
    taskTrackingViewConfig The configuration for task tracking that specifies which data elements are visible to the end users under what circumstances.

  • Optional fields:

    • None

All other fields in the entity are ignored for the update.

Example curl command:

# 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

Assign tasks to a vehicle

Tasks are assigned to a delivery vehicle by updating the task ordering for the vehicle. The task ordering for a vehicle is determined by the list of vehicle stops for the delivery vehicle. Each vehicle stop can be assigned one or more tasks.

Updating the task ordering for a task that was previously assigned to a different vehicle generates an error.

To change a shipment from one vehicle to another, close the original task and then recreate it before assigning it the new vehicle.

Update task ordering

You can update the order of execution of tasks assigned to a vehicle either from the Driver SDK , or from the server environment. The two methods should not be mixed to avoid race conditions.

Updating the task ordering will also assign tasks to a vehicle if they weren't previously assigned to a vehicle, and close tasks that were previously assigned to a vehicle and left out of the updated ordering. Assigning a task to a different vehicle if it had previously been assigned to another vehicle generates an error. Close the existing task first and then create a new task before assigning it to the new vehicle.

Task ordering can be updated at any time.

gRPC

The following example shows how to use the Java gRPC library to update the task ordering for the vehicle:

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

To update the task ordering for a vehicle from a server environment, make an HTTP REST call to `UpdateDeliveryVehicle':

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

<id> is a unique identifier for a delivery vehicle in your fleet for which you intend to update the task ordering. It is the identifier that you specified when creating the vehicle.

The request header must contain a field Authorization with the value Bearer <token> , where <token> is a token minted by a Fleet Engine token factory .

The request body must contain a DeliveryVehicle entity:

  • Required fields:

    Field Value
    remainingVehicleJourneySegments A list of journey segments for tasks in the order they should be executed. The first task in the list is executed first.
    remainingVehicleJourneySegments[i].stop The stop for task i in the list.
    remainingVehicleJourneySegments[i].stop.plannedLocation The planned location for the stop.
    remainingVehicleJourneySegments[i].stop.tasks A list of tasks to be performed at this vehicle stop.
    remainingVehicleJourneySegments[i].stop.state State.NEW

  • Optional fields:

    • None

All other fields in the entity are ignored for the update.

Example curl command:

# 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

Vehicle is enroute to the next stop

Fleet Engine must be notified when a vehicle departs from a stop or begins navigation. You can notify Fleet Engine either from the Driver SDK , or from the server environment. The two methods should not be mixed to avoid race conditions and to maintain a single source of truth.

gRPC

The following example shows how to use the Java gRPC library to notify Fleet Engine that a vehicle is enroute to its next stop.

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

To notify Fleet Engine that a vehicle is enroute to its next stop from a server environment, make an HTTP REST call to `UpdateDeliveryVehicle':

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

<id> is a unique identifier for the delivery vehicle in your fleet for which you intend to update the task ordering. It is the identifier that you specified when creating the vehicle.

The request header must contain a field Authorization with the value Bearer <token> , where <token> is a token minted by a Fleet Engine token factory .

The request body must contain a DeliveryVehicle entity:

  • Required field:

    Field Value
    remainingVehicleJourneySegments List of remaining vehicle stops with their states marked as State.NEW. The first stop on the list must have its state marked as State.ENROUTE.

  • Optional fields:

    • None

All other fields in the entity are ignored for the notification.

Example curl command:

# 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

Vehicle arrives at a stop

Fleet Engine must be notified when a vehicle arrives at a stop. You can notify Fleet Engine either from the Driver SDK , or from the server environment. The two methods should not be mixed to avoid race conditions and to maintain a single source of truth.

gRPC

The following example shows how to use the Java gRPC library to notify Fleet Engine that a vehicle arrived at a stop:

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

To notify Fleet Engine about the arrival of a vehicle at a stop from a server environment, make an HTTP REST call to `UpdateDeliveryVehicle':

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

<id> is a unique identifier for the delivery vehicle in your fleet for which you intend to update the task ordering. It is the identifier that you specified when creating the vehicle.

The request header must contain a field Authorization with the value Bearer <token> , where <token> is a token minted by a Fleet Engine token factory .

The request body must contain a DeliveryVehicle entity:

  • Required fields:

    Field Value
    remainingVehicleJourneySegments The stop you have arrived at with its state set as State.ARRIVED, followed by a list of remaining vehicle stops with their states marked as State.NEW.

  • Optional fields:

    • None

All other fields in the entity are ignored for the update.

Example curl command:

# 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

Vehicle completes a stop

Fleet Engine must be notified when a vehicle completes a stop. This causes all tasks associated with the stop to be set to a CLOSED state. You can notify Fleet Engine either from the Driver SDK , or from the server environment. The two methods should not be mixed to avoid race conditions and to maintain a single source of truth.

gRPC

The following example shows how to use the Java gRPC library to notify Fleet Engine that a vehicle has completed a stop.

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

To notify Fleet Engine about the completion of a stop from a server environment, make an HTTP REST call to `UpdateDeliveryVehicle':

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

<id> is a unique identifier for the delivery vehicle in your fleet for which you intend to update the task ordering. It is the identifier that you specified when creating the vehicle.

The request header must contain a field Authorization with the value Bearer <token> , where <token> is a token minted by a Fleet Engine token factory .

The request body must contain a DeliveryVehicle entity:

  • Required fields:

    Field Value
    remaining_vehicle_journey_segments The stop you have have completed should no longer be in the list of remaining vehicle stops.

  • Optional fields:

    • None

All other fields in the entity are ignored for the update.

Example curl command:

# 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}",
            "taskDuration": "120s"
          }
        ]
      }
    }
  ]
}
EOM

Update a task

Most task fields are immutable. However, it is possible to modify state, task outcome, task outcome time, task outcome location, and attributes by directly updating the task entity. For example, in cases where a task has not been assigned to a vehicle, it is possible to close the task by updating the state directly.

gRPC

This is an example of updating a task through gRPC.

REST

This is an example of updating a task through REST.

Close a task

To close a task that has been assigned to a vehicle, either notify Fleet Engine that the vehicle has completed the stop where the task takes place or remove it from the list of vehicle stops. To do that you can set the list of the remaining vehicle stops just as when updating the task ordering for a vehicle.

If a task was not yet assigned a vehicle and needs to be closed, update the task to a CLOSED state. However, you may not reopen a CLOSED task.

Closing of a task does not indicate success or failure. It indicates that the task is no longer considered in progress. For fleet tracking, it is important to indicate the actual outcome of a task so that a delivery outcome can be shown.

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

To mark a task as closed from a server environment, make an HTTP REST call to UpdateTask :

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

<id> is a unique identifier for the task.

The request header must contain a field Authorization with the value Bearer <token> , where <token> is a token minted by a Fleet Engine token factory .

The request body must contain a Task entity:

  • Required fields:

    Field Value
    state State.CLOSED

  • Optional fields:

    Field Value
    taskOutcome Outcome.SUCCEEDED or Outcome.FAILED
    taskOutcomeTime The time when the task was completed.
    taskOutcomeLocation The location where the task was completed. Fleet Engine will default this to the last vehicle location unless manually overridden by provider.

All other fields in the entity are ignored for the update.

Example curl command:

# 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

Setting the task outcome and outcome location

The closing of a task does not indicate success or failure, it indicates that the task is no longer considered in progress. For fleet tracking, it is important to indicate the actual outcome of a task so that a delivery outcome can be shown and there is proper billing for the services. Once set, the task outcome cannot be changed. It is possible to modify task outcome time and task outcome location after they have been set.

Tasks that are in the CLOSED state can have their outcome set to either SUCCEEDED or FAILED. Fleet Engine charges only delivery tasks with a state of SUCCEEDED.

When marking the outcome of a task, Fleet Engine automatically fills in the task outcome location with the last known vehicle location. It is possible to override this behavior.

gRPC

You have the option of setting the task outcome location when setting the outcome. This will prevent Fleet Engine from setting it to the default of the last vehicle location. You can also overwrite the task outcome location Fleet Engine set at a later time. Fleet Engine will never overwrite a task outcome location that you provide. It is not possible to set a task outcome location for a task which does not have a task outcome set. It is possible to set both task outcome and task outcome location within the same request.

The following example shows how to use the Java gRPC library to set a task outcome to SUCCEEDED and set the location where the task was completed:

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

To mark a task as completed from a server environment, make an HTTP REST call to UpdateTask :

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

<id> is a unique identifier for the task.

The request header must contain a field Authorization with the value Bearer <token> , where <token> is a token minted by a Fleet Engine token factory .

The request body must contain a Task entity:

  • Required fields:

    Field Value
    taskOutcome Outcome.SUCCEEDED or Outcome.FAILED
    taskOutcomeTime The timestamp of when the task's outcome was set (from provider). This is the time when the task was completed.

  • Optional fields:

    Field Value
    taskOutcomeLocation The location where the task was completed. Fleet Engine will default this to the last vehicle location unless manually overridden by provider.

All other fields in the entity are ignored for the update.

Example curl command:

# 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

Reroute a shipment

Once a shipment task has been created, its planned location can't be changed. To reroute a shipment, close the shipment task without setting an outcome, and then create a new task with the updated planned location. After creating the new task, assign the task to the same vehicle. For more information, see close the shipment task and assign the task .

Use feeder and delivery vehicles

If you use feeder vehicles to transport shipments to delivery vehicles throughout the day, model the transfer of shipments as a scheduled stop task for the delivery vehicle. To ensure accurate location tracking, only assign a shipment delivery task for a transferred shipment after it is loaded onto the delivery vehicle. For more information, see scheduled stop .

Store shipment status and other meta information

When a shipment task is completed, the task state and outcome are recorded in the task. However, you may want to update other meta information specific to the shipment. To store other meta information that you can reference outside the Fleet Engine service, use the tracking_id associated with the task as a key in an external table.

For more information, see Life of a task .

Look up a vehicle

You can look up a vehicle either from the Driver SDK , or from the server environment.

gRPC

The following example shows how to use the Java gRPC library to look up a vehicle:

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

To look up a vehicle from a server environment, make an HTTP REST call to `GetVehicle':

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

<id> is a unique identifier for the task.

<vehicleId> is the ID of the vehicle to look up.

The request header must contain a field Authorization with the value Bearer <token> , where <token> is a token minted by a Fleet Engine token factory .

The request body must be empty.

If the lookup is successful, the response body contains a vehicle entity.

Example curl command:

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

Look up a task

You can look up a task from a server environment. The Driver SDK does not support looking up a task.

gRPC

The following example shows how to use the Java gRPC library to look up a task:

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

To look up a task from a server environment, make an HTTP REST call to `GetTask':

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

<id> is a unique identifier for the task.

<taskId> is the ID of the task to look up.

The request header must contain a field Authorization with the value Bearer <token> , where <token> is a token minted by a Fleet Engine token factory .

The request body must be empty.

If the lookup is successful, the response body contains a task entity.

Example curl command:

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

Look up shipment task information by its tracking ID

You can look up shipment task information in the following ways, each of which has a separate purpose:

  • by a task ID : used by users like fleet operators who have access to the full view of the task data.
  • by a tracking ID : used by your client software to provide limited information to an end user, such as when a package will arrive at their house.

This section discusses looking up task information by a tracking ID. If you want to lookup a task by the task ID, go to looking up a task .

To look up information by a tracking ID, you can use either of the following:

Lookup requirements

  • Shipment information provided by a tracking ID adheres to visibility rules stated in Control the visibility of tracked locations .

  • Use Fleet Engine to look up a shipment information by tracking ID. The Driver SDK does not support information lookups by tracking ID. To do this with Fleet Engine, you will use either a server or browser environment.

  • Use the narrowest token possible to limit security risks. For example, if you use a Delivery Consumer Token, any Fleet Engine Deliveries API calls return only information relevant to that end user, such as the shipper or the receiver of a shipment. All other information in the responses is redacted. For more information about tokens, see Creating a JSON Web Token (JWT) for authorization .

Lookups with Java using gRPC

The following example shows how to use the Java gRPC library to look up information about a shipment task by its tracking ID.

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

Lookups using HTTP

To look up a shipment task from a browser, make an HTTP REST call to GetTaskTrackingInfo :

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

<tracking_id> is the tracking ID associated with the task.

The request header must contain a field Authorization with the value Bearer <token> , where <token> is a token issued by a Fleet Engine token factory .

If the lookup is successful, the response body contains a taskTrackingInfo entity.

Example curl command:

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

List tasks

You can list tasks from a server or browser environment. The Driver SDK does not support listing tasks.

Listing tasks requests broad access to tasks. Listing tasks is intended only for trusted users. Use Delivery Fleet Reader or Delivery Super User Authentication Tokens when making list tasks requests.

Listed tasks have the following fields redacted:

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

Listed tasks can be filtered by most task properties. For filter query syntax, see AIP-160 . The following list shows valid task properties that you can use for filtering:

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

Use the following field formats based on Google API Improvement Proposals:

Field Type Format Example
Timestamp RFC-3339 task_outcome_time = 2022-03-01T11:30:00-08:00
Duration Number of seconds followed by an 's' task_duration = 120s
Enum String state = CLOSED AND type = PICKUP
Location point.latitude and point.longitude planned_location.point.latitude > 36.1 AND planned_location.point.longitude < -122.0

See AIP-160 for a full list of filter query operators.

If no filter query is specified, all tasks are listed.

Task lists are paginated. A page size can be specified in list tasks requests. If a page size is specified, the number of returned tasks is no greater than the specified page size. If no page size is present, a reasonable default is used. If the requested page size exceeds an internal maximum value, then the internal maximum is used.

A task list can include a token for reading the next page of results. Use the page token with a request that is otherwise identical to the previous request to retrieve the next page of tasks. When the returned page token is empty, no more tasks are available for retrieval.

gRPC

The following example shows how to use the Java gRPC library to list tasks for a deliveryVehicleId and a task attribute. A successful response can still be empty. An empty response indicates that no Tasks are associated the supplied deliveryVehicleId.

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

To list tasks from a browser, make an HTTP REST call to ListTasks :

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

To apply a filter to the listed tasks, include a "filter" URL parameter with a URL-escaped filter query as its value.

The request header must contain a field Authorization with the value Bearer <token> , where <token> is a token minted by a Fleet Engine token factory .

If the lookup is successful, the response body contains data with the following structure:

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

A successful response can still be empty. An empty response indicates that no tasks were found meeting the specified filter criteria.

Example curl command:

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

List delivery vehicles

You can list delivery vehicles from a server or browser environment. The Driver SDK does not support listing delivery vehicles.

Listing delivery vehicles requests broad access to delivery vehicles and is intended only for trusted users. Use Delivery Fleet Reader or Delivery Super User Authentication Tokens when making list delivery vehicles requests.

Listed delivery vehicles have the following fields redacted due to their impact on response size:

  • CurrentRouteSegment
  • RemainingVehicleJourneySegments

You can filter list delivery vehicles by their attributes property. For example, to query an attribute with key my_key and value my_value , use attributes.my_key = my_value . To query for multiple attributes, join queries using the logical AND and OR operators as in attributes.key1 = value1 AND attributes.key2 = value2 . See AIP-160 for a full description of filter query syntax.

You can filter listed delivery vehicles by location using the viewport request parameter. The viewport request parameter defines viewports using two bounding coordinates: a high (northeast) and low (southwest) latitude/longitude. Requests are rejected if they contain a high latitude that is geographically lower than a low latitude.

Delivery vehicle lists are paginated by default using a reasonable page size. If you specify a page size, the request returns only the number of vehicles specified by the limit, or fewer. If the requested page size exceeds an internal maximum value, then the internal maximum is used. The default and maximum page sizes are both 100 vehicles.

A delivery vehicles list can include a token for reading the next page of results. A page token is only present in a response when more pages of delivery vehicles are available for retrieval. To retrieve the next page of tasks, use the page token with a request that is otherwise identical to the previous request.

gRPC

The following example shows how to use the Java gRPC library to list delivery vehicles in a particular region with a certain attribute. A successful response can still be empty. When that happens, it means that no vehicles with the specified attribute are currently in the specified viewport.

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

To list tasks from a browser, make an HTTP REST call to ListDeliveryVehicles :

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

To apply a filter to the listed tasks, include a "filter" URL parameter with a URL-escaped filter query as its value.

The request header must contain a field Authorization with the value Bearer <token> , where <token> is a token minted by a Fleet Engine token factory .

If the lookup is successful, the response body contains data with the following structure:

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

A successful response can still be empty. When that happens, it means that no delivery vehicles were found meeting the specified filter query and viewport.

Example curl command:

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

Fleet tracking

You have two options for using the Fleet Engine Deliveries API to enable fleet tracking:

  • Preferred: Use the JavaScript Fleet Tracking library . The library lets you visualize the location of vehicles and locations of interest tracked in Fleet Engine. It contains a JavaScript map component that is a drop-in replacement for a standard google.maps.Map object, and data components to connect with Fleet Engine. This allows you to provide a customizable, animated fleet tracking experience from your web or mobile application.

  • Implement your own fleet tracking on top of the Fleet Engine Deliveries API.

Logging

You can enable an option to allow Fleet Engine to send RPC logs to Cloud Logging. For more information, see Logging .

Authorization Roles and Tokens

As described in Integrating the Deliveries API and the authorization notes for individual uses cases , making calls to Fleet Engine requires authentication with JSON Web Tokens that have been signed using service account credentials. The service accounts used to mint those tokens may have one or more roles, with each role granting a different set of permissions.

For more information, see Authentication and Authorization .

Troubleshooting

Resiliency

Fleet Engine is not considered a source of truth. You are responsible for restoring the state of your system, if necessary, without relying on Fleet Engine.

Lost state in Fleet Engine

When working with Fleet Engine, implement clients so that the system heals itself if there is a failure. For example, when Fleet Engine tries to update a vehicle it may respond with an error indicating that the vehicle does not exist. The client should then recreate the vehicle in the new state. This rarely occurs, the system must be resilient in case it does.

In the extremely unlikely scenario of a catastrophic failure of Fleet Engine, you may need to recreate most or all vehicles and tasks. If the creation rate becomes too high, some requests may fail again due to quota issues since quota checks are in place to avoid denial of service (DOS) attacks. In this case, slow down the recreation rate using a backoff strategy for reattempts.

Lost state in the driver app

If the driver app crashes, the app must recreate the current state within the Driver SDK. The app should attempt to recreate tasks to ensure that they exist and to restore their current states. The app should also recreate and explicitly set the list of stops for the Driver SDK.

Note that these restorations must be done autonomously without relying on information from Fleet Engine, other than errors indicating if and when an entity already exists in the database. If an entity does already exist, then that error can be absorbed and the entity can be updated using its ID.

FAQ

What if a driver stops for a task out of order?

In this case, you should first update the order of the tasks and then proceed as normal, marking the arrival at the stop, task completion, etc. Otherwise, the system may become inconsistent. ETAs may become incorrect and unexpected errors may be reported.