תחילת העבודה עם Fleet Engine למעקב אחר משלוחים

בעזרת Fleet Engine Deliveries API אפשר לבנות מודלים של פעילויות כלל המכשירים בארגון בשביל המשלוח הראשון והאחרון. אפשר להשתמש ב-API הזה באמצעות Driver SDK ל-Android ול-iOS, או ישירות באמצעות קריאות HTTP REST או gRPC.

הגדרה ראשונית

אתם מגדירים את Fleet Engine Deliveries API במסוף Google Cloud.

אימות ההגדרה

אחרי שיוצרים חשבונות שירות, חשוב לוודא שההגדרה הושלמה ושאפשר ליצור רכב משלוח. אימות מיידי של ההגדרה מבטיח שפתרתם את הבעיות הנפוצות שקשורות להרשאות, שעלולות להתעורר במהלך הגדרת הפרויקט. יש שתי דרכים לאמת את ההגדרות:

ספריות לקוח

כדי ליהנות מחוויית פיתוח טובה יותר ב-gRPC או ב-REST גולמיים, כדאי להשתמש בספריות הלקוח בכמה שפות תכנות נפוצות. להוראות איך להשיג ספריות לקוח לאפליקציית השרת, ראו ספריות לקוח.

בדוגמאות של Java בתיעוד הזה, ההנחה היא שאתם מכירים את gRPC.

מבני נתונים

ב-Fleet Engine Deliveries API משתמשים בשני מבני נתונים כדי לבנות מודל של האיסוף והמסירה של המשלוחים:

  • רכב המסירה שמשמש להובלת המשלוח.
  • המשימות שקשורות לאיסוף ולמשלוח.

אתם יכולים גם להשתמש במשימות כדי לבנות מודלים של הפסקות עצירה לנהגים ועצירות מתוזמנות לאורך היום.

רכבי משלוח

רכבי משלוחים מעבירים משלוחים מתחנה ליעד משלוחים ומנקודת איסוף אל התחנה. במקרים מסוימים, יכול להיות שהמשלוח יהיה גם ישירות מנקודת האיסוף אל יעד המשלוח.

משתמשים ב-Driver SDK כדי ליצור אובייקט DeliveryVehicle ב-Fleet Engine ולשלוח עדכוני מיקום למעקב אחרי משלוחים ומעקב אחרי כלל המכשירים.

Tasks

מקצים משימות לפי סוג הפעולה לפעולות שהרכב מבצע במהלך היום:

  • לאיסוף ומשלוחים, צריך להקצות משימות של משלוח.
  • במקרים שבהם הנהגים לא זמינים, כמו הפסקות נדרשות, אפשר להקצות משימות של חוסר זמינות.
  • למשימות שלא קשורות לנהיגה בתיבות בענן או במיקומים של לקוחות, צריך להקצות משימות עם עצירה מתוזמנת.

לכל משימה שמקצים מזהה צריך להיות מזהה ייחודי, אבל לכל משימה יכולה להיות אותו מזהה לצורכי מעקב. כש-Fleet Engine מחשב את חלונות זמן ההגעה המשוער לכל משימה, הוא משתמש בכל המשימות ובסדר שבו הן מתוזמנות לבצע הערכות. מידע נוסף על מזהי משימות מופיע במאמר הנחיות לגבי מזהי משימות.

כדי ליצור משימות ב-Fleet Engine, אפשר להשתמש במנהל המשימות של Driver SDK.

משימות משלוח

יוצרים משימות משלוח לאיסוף ולמסירה של משלוח וכוללים את הפרטים הבאים:

  • המיקום של האיסוף או של המשלוח.
  • מספר או מזהה למעקב.
  • זמן שהייה שיכול לקחת בחשבון זמן נוסף להשלמת המשימה, לחפש חניה או ללכת למיקום המסירה.
  • מזהה משימה ייחודי. כדאי לעיין בהנחיות למזהה המשימה.

אפשר למצוא מידע נוסף בנושאים הבאים:

Android

iOS

משימות של חוסר זמינות

משימות של אי זמינות כוללות תקופות שבהן הרכב לא זמין לאיסוף או למשלוח, כמו הפסקות לתדלוק או להפסקות מנוחה לנהג.

יוצרים משימת אי-זמינות עם הפרטים הבאים:

  • משך ההפסקה.
  • אפשר גם לבחור את מיקום ההפסקה. אתם לא חייבים לציין מיקום ספציפי, אבל כך תוכלו לקבל חלונות מדויקים יותר של זמן הגעה משוער לאורך היום.

אפשר למצוא מידע נוסף בנושאים הבאים:

Android

iOS

משימות עם עצירה מתוזמנת

אפשר ליצור משימות מתוזמנות בעצירה כדי ליצור מודל של העצירות שרכב המשלוחים צריך לבצע. לדוגמה, תוכלו ליצור משימה מתוזמנת של עצירה מתוזמנת לעצירת איסוף יומית במיקום ספציפי, ללא קשר למשלוחים או לאיסוף עצמי אחרים באותו מיקום. אפשר גם ליצור משימות מתוזמנות עם עצירה מתוזמנת לגבי קולקציות מתיבות איסוף, או כדי לבנות מודלים להעברות של כלי רכב או עצירות במרכזי שירות ובנקודות שירות.

אפשר למצוא מידע נוסף בנושאים הבאים:

Android

iOS

הנחיות בנושא מזהה המשימה

כשיוצרים את מזהי המשימות, צריך לפעול לפי הנחיות התוכן והפורמט הבאות:

  • יצירת מזהי משימות ייחודיים
  • אסור לחשוף פרטים אישיים מזהים (PII) או נתוני טקסט ברורים.
  • צריך להשתמש במחרוזות Unicode חוקיות.
  • אפשר להזין עד 64 תווים.
  • אסור לכלול אף אחד מתווי ASCII הבאים: "/", ":", "\", "?" או "#".
  • יש לבצע נירמול בהתאם לטופס הנירמול של Unicode C.

דוגמאות למזהי משימות טובים:

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

בטבלה הבאה מוצגות דוגמאות למזהי משימות שאינם נתמכים:

מזהי משימות לא נתמכים הסיבה
8/31/2019-20:48-46.70746,-130.10807,-85.17909,61.33680 מפירה את דרישות המדיניות בנושא פרטים אישיים מזהים (PII) ותווים: פסיקים, נקודות, נקודתיים ולוכסנים.
JohnDoe-577b484da26f-Cupertino-SantaCruz מפירה את הדרישות בנושא פרטים אישיים מזהים (PII).
4R0oXLToF"112 Summer Dr. East Hartford, CT06118"577b484da26f8a מפירה את דרישות המדיניות בנושא פרטים אישיים מזהים ותווים: רווחים לבנים, פסיקים ומירכאות. מכילה יותר מ-64 תווים.

מקורות מידע נוספים

כדי לראות מהם השדות הספציפיים שנכללים בכל מבנה נתונים, תוכלו לעיין במאמרי העזרה של ה-API ל-DeliveryVehicle (gRPC, ל-REST) ול-Task (gRPC, REST).

חיי הרכב

האובייקט DeliveryVehicle מייצג רכב עם אפשרות משלוח מייל ראשון או אחרון. יוצרים אובייקט DeliveryVehicle באמצעות:

  • מזהה הפרויקט ב-Google Cloud שמכיל את חשבון השירות שמשמש לקריאה לממשקי ה-API של Fleet Engine.
  • מזהה רכב בבעלות הלקוח.

צריך להשתמש במזהי רכב ייחודיים לכל רכב. אסור להשתמש שוב באותו מזהה רכב, אלא אם אין משימות פעילות ברכב המקורי.

DeliveryVehicle אובייקטים שלא עודכנו באמצעות UpdateDeliveryVehicle, נמחקים מ-Fleet Engine באופן אוטומטי אחרי שבעה ימים. כדי לבדוק אם קיים רכב:

  1. ביצוע שיחה אל UpdateDeliveryVehicle.
  2. אם מופיעה שגיאת NOT_FOUND, אז קוראים לפונקציה CreateDeliveryVehicle כדי ליצור מחדש את הרכב. אם השיחה מחזירה רכב, הוא עדיין זמין לעדכון.

סוגים של כלי רכב

הישות VehicleType מכילה שדה אופציונלי של VehicleType, שמכיל enum Category שאפשר לציין בתור AUTO, TWO_WHEELER, BICYCLE או PEDESTRIAN. אם לא מגדירים את השדה, ברירת המחדל שלו היא AUTO.

בכל המסלולים בכלי רכב נעשה שימוש בערך RouteTravelMode המתאים לסוג הרכב.

מאפייני הרכב

הישות DeliveryVehicle מכילה שדה חוזר של DeliveryVehicleAttribute. ה-API ListDeliveryVehicles כולל את השדה filter שיכול להגביל ישויות DeliveryVehicle שמוחזרות עם המאפיינים שצוינו. ל-DeliveryVehicleAttribute אין השפעה על התנהגות הניתוב של Fleet Engine.

אסור לכלול במאפיינים פרטים אישיים מזהים (PII) או מידע רגיש, כי השדה הזה יכול להיות גלוי למשתמשים.

חיי משימה

אפשר ליצור, לעדכן משימות ולשלוח שאילתות ב-Fleet Engine באמצעות ממשקי gRPC או REST של Deliveries.

אובייקט Task כולל שדה מצב למעקב אחר ההתקדמות שלו במחזור החיים שלו. הערכים יכולים לעבור מ'פתוח' ל'סגור'. משימות חדשות נוצרות במצב Open, שמציין את אחת האפשרויות הבאות:

  • המשימה עדיין לא הוקצתה לרכב משלוחים.
  • רכב המסירה עדיין לא עבר את העצירה שהוקצתה למשימה.

הנחיות למשימה

אפשר להקצות משימה לרכב במצב 'פתוח' רק.

כדי לבטל משימה מסוימת, מסירים אותה מרשימת העצירות של הרכב, ומצב המשימה הזה מוגדר אוטומטית כ'סגור'.

כשהרכב של המשימה מסיים את עצירת הרכב במשימה:

  1. מעדכנים את שדה התוצאה של המשימה לאפשרות 'דיווח' או 'נכשל'.

  2. מציינים את חותמת הזמן של האירוע.

    לאחר מכן, הספרייה 'מעקב אחר משלוחים ב-JavaScript' מציינת את תוצאת המשימה והסטטוס של המשימה מוגדר כ'סגור' באופן אוטומטי. מידע נוסף זמין במאמר מעקב אחרי המשלוח באמצעות הספרייה של JavaScript Shipment Tracking.

בדומה לרכבים, ב-Fleet Engine מוחקים משימות שלא עודכנו אחרי שבעה ימים, ומנסים ליצור משימה עם מזהה שכבר קיים.

הערה: Fleet Engine לא תומך במחיקה מפורשת של משימה. השירות מוחק משימות באופן אוטומטי אחרי שבעה ימים ללא עדכונים. אם תרצו לשמור נתוני משימות למשך יותר משבעה ימים, עליכם להטמיע את היכולת הזו בעצמכם.

מאפייני המשימה

הישות Task מכילה שדה חוזר של TaskAttribute, שיכול לקבל ערך מאחד מ-3 הסוגים: מחרוזת, מספר ובוליאני. ה-API ListTasks כולל את השדה filter שיכול להגביל ישויות Task שהוחזרו לאלה עם המאפיינים שצוינו. מאפייני המשימות לא משפיעים על התנהגות הניתוב של Fleet Engine.

לא מומלץ לכלול במאפיינים פרטים אישיים מזהים (PII) או מידע רגיש אחר, כי המאפיינים האלה עשויים להיות גלויים למשתמשים.

ניהול מחזור החיים של רכב ומשימה

תזכורת: המערכת הפנימית שלכם משמשת כמקור המהימן של הנתונים ש-Fleet Engine Deliveries מרחיב בשבילכם.

כדי לנהל את מחזורי החיים של הרכבים והמשימות במערכת, תוכלו להשתמש ב-Fleet Engine Deliveries API כדי ליצור, לעדכן את הרכבים והמשימות שמשויכות אליהם ולעקוב אחריהם.

במקביל, אפליקציית הנהג מתקשרת ישירות ל-Fleet Engine כדי לעדכן את מיקום המכשיר ואת פרטי המסלול. המודל הזה מאפשר ל-Fleet Engine לנהל ביעילות את המיקום בזמן אמת. הוא שולח את המיקום ישירות לספריית המעקב, ואז אפשר להשתמש בה כדי לעדכן את הצרכנים בסטטוס ההזמנה שלהם.

לדוגמה, נניח שיש לכם את התרחיש הבא:

  • נהג מתקרב לתחנת משלוחים. אפליקציית מנהל ההתקן שולחת את המיקום שלה ל-Fleet Engine.
  • Fleet Engine שולח את מיקום המכשיר לספריית המעקב, שבה האפליקציה לצרכן משתמשת כדי להתריע בפני הצרכן על הקרבה של החבילה שלו.
  • אחרי שהנהג משלים את המשלוח, הוא לוחץ על הלחצן 'המשלוח נמסר' באפליקציית הנהג.
  • הפעולה 'משלוח נמסר' שולחת את המידע למערכת הקצה העורפי שלכם, שמבצעת את שלבי האימות העסקי והאימות העסקיים הנדרשים.
  • המערכת יאשרה את המשימה כ- Storage ומעדכנת את Fleet Engine באמצעות ה-Deliveries API.

התרשים הבא ממחיש את התהליכים האלה ברמה כללית. מוצג בו גם הקשר הרגיל בין המערכת, הלקוח ו-Fleet Engine.

שימוש ב-Deliveries API

ניהול אסימוני לקוח

לעדכוני מיקום שמקורם באפליקציית מנהל ההתקן ונשלחים ישירות ל-Fleet Engine נדרשים אסימוני הרשאה. זאת הגישה המומלצת לטיפול בעדכונים מהלקוח ל-Fleet Engine:

  1. יוצרים את האסימון באמצעות התפקיד בחשבון השירות משתמש נהיגה לא מהימן ב-Fleet Engine Delivery.

  2. צריך לספק לאפליקציית מנהל ההתקן עם אסימון בהיקף מוגבל. ההיקף הזה מאפשר לעדכן רק את מיקום המכשיר ב-Fleet Engine.

הגישה הזו מבטיחה שקריאות שמגיעות ממכשירים ניידים, שנחשבות בסביבות עם אמינות נמוכה, בהתאם לעקרון של הרשאות מינימליות.

תפקידים אחרים של חשבון שירות

אם רוצים לאשר לאפליקציות של מנהלי ההתקנים לבצע עדכונים ישירים ב-Fleet Engine, מעבר לאלה שמוגבלים לתפקיד 'נהג לא מהימן', למשל בעדכונים מסוימים של משימות, אפשר להשתמש בתפקיד 'מנהל התקן מהימן'. מידע על מודל שמשתמש בתפקיד 'נהג מהימן' מופיע במאמר מודל של נהג מהימן.

מידע נוסף על השימושים בתפקידי נהגים לא מהימנים ומהימנים מופיע במאמר הגדרת פרויקט ב-Cloud.

בניית מודל של יום עבודה

בטבלה הבאה מוסבר איך ייראה יום העבודה של נהגים באזור הראשון או האחרון בחברת משלוחים ולוגיסטיקה. הפרטים של החברה שלכם עשויים להיות שונים זה מזה, אבל תוכלו לראות איך אפשר לבנות מודל של יום עבודה.

שעהפעילותבניית מודלים
תוך 24 שעות מתחילת היום הסדרן מקצה משלוחים לרכבים או למסלולים למשלוחים. אפשר ליצור מראש ב-Fleet Engine משימות למשלוחים, לאיסוף, להפסקות ועוד. לדוגמה, אתם יכולים ליצור משימה של איסוף משלוח, משימה של שליחת משלוח, חוסר זמינות מתוזמן או עצירה מתוזמנת.

מקצים משימות לרכב אחרי שמסיימים להגדיר את חבילות המשלוח והסדר שבו הן אמורות להישלח.
תחילת היום הנהג מתחיל את היום בתחנה בכניסה לאפליקציית Drive. מפעילים את Delivery Driver API. יוצרים את הרכב למשלוח ב-Fleet Engine לפי הצורך.
נהג טוען את המשלוחים לרכב המשלוחים וסורק את המשלוחים. אם לא יצרתם מראש משימות של משלוחים בזמן הזה, תוכלו ליצור משימות של מסירת משלוחים בזמן הסריקה.
הנהג/ת מאשר/ת את הסדר של המשימות לביצוע. אם הן לא נוצרו מראש, צריך ליצור משימות לאיסוף משלוחים, משימות מתוזמנות לא זמינות ועצירות מתוזמנות.
הנהג עוזב את התחנה ומתחייב למספר המשימות הבא שצריך להשלים. מקצים את כל המשימות או קבוצת משנה של משימות לרכב על ידי קביעת סדר ההשלמה שלהן.
הנהג מבצע משלוח. אחרי שמגיעים לתחנת המשלוח, צריך לבצע פעולות שקשורות לרכב שמגיע לעצירה. אחרי מסירת המשלוח, סוגרים את משימת המסירה, ואפשר גם סטטוס המשלוח בחנות ומטא-מידע נוסף. אחרי שמשלימים את כל המשימות בעצירה ולפני שמתחילים לנסוע לתחנה הבאה, צריך לבצע פעולות שקשורות לכלי רכב משלים עצירה ולכלי הרכב בדרך לתחנה הבאה.
הנהג/ת פוגש/ת רכב הזנה כדי להעביר משלוחים נוספים לרכב המשלוחים. את נקודת המפגש להעברה בין כלי רכב עם אספקת מזון לכלי משלוח צריך להיות מודל של עצירה מתוזמנת.

אחרי העברה וסריקה של המשלוחים, צריך ליצור משימות מסירה אם הן עדיין לא נוצרו. לאחר מכן, אפשר לעדכן את סדר ההשלמה של המשימות כך: מקצים משימות לרכב ומעדכנים את סדר המשימות.
הנהג מקבל הודעה על בקשת איסוף. אחרי שמאשרים את בקשת האיסוף, צריך ליצור משימה לאיסוף משלוח. לאחר מכן, אפשר לעדכן את סדר הביצוע של המשימות על ידי הקצאת משימות לרכב ועדכון של סדר המשימות.
צהריים הנהג יוצא להפסקת צהריים. אם מיקום מסוים משויך למשימה של חוסר זמינות, צריך להתייחס אליו כמו לכל משימה אחרת. ביצוע פעולות שקשורות לכלי רכב שמגיעים לעצירה, הרכב נעצר בעצירה וכלי הרכב בדרך לתחנה הבאה.

אחרת, לא נדרשת פעולה נוספת עד סיום ההפסקה. כדי להסיר את המשימה, מאשרים את המשימות הבאות ואת המשימות שנותרו ומעדכנים את סדר המשימות.
נהג אוסף משלוח. התכנון הזה הוא בדיוק כמו תחנת משלוח. ביצוע פעולות שקשורות לרכב שמגיע בעצירה ולסגירת משימה, ובאופן אופציונלי, לשמירת סטטוס המשלוח ומטא-נתונים נוספים. אחרי שמשלימים את כל המשימות בעצירה ולפני שמתחילים לנסוע לתחנה הבאה, צריך לבצע פעולות שקשורות לכלי רכב משלימים עצירה ולרכב בדרך לתחנה הבאה. הערה: כדי להבטיח שהחיוב יהיה נכון, לכל האיסוף צריך להיות משימת מסירה תואמת. אם האיסוף מתבצע למיקום אחר במסלול של הנהג באותו יום, מומלץ ליצור מודל של משימת המסירה הזו כמו כל משימת מסירה אחרת במסלול. אם הנהג מחזיר את האיסוף לתחנת היעד, מומלץ ליצור משימת משלוח ביעד.
הנהג/ת עוצר/ת את המשלוח/ים כדי לאסוף את המשלוחים מתיבת הדואר הנכנס. המודל הזה מחושב לפי מודל של כל תחנת איסוף אחרת. ביצוע פעולות שקשורות לכלי רכב שמגיע לעצירה ולסגירת משימה. אחרי שמשלימים את כל המשימות בעצירה ומתחילים לנסוע לתחנה הבאה, צריך לבצע פעולות שקשורות לכלי רכב משלימים עצירה ולרכב בדרך לתחנה הבאה.
הנהג מקבל הודעה על כך שמשלוח מופנה למיקום חלופי. מגדירים את הסטטוס של המשימה המקורית של מסירת המשלוח ל-הושלם ויוצרים משימה חדשה של מסירת משלוח ליעד המשלוח החדש. מידע נוסף זמין במאמר ניתוב מחדש של משלוח.
הנהג ניסה למסור חבילה אבל לא ניתן היה למסור אותה. המודל הזה נוצר באופן דומה לעצירת אספקה מוצלחת, שמסמן שמשימת ההעברה בוצעה. ביצוע פעולות שקשורות לכלי רכב שמגיע לעצירה. אחרי שהמשלוח לא יגיע, סוגרים את המשימה, ואפשר גם סטטוס המשלוח בחנות ומטא-פרטים נוספים. אחרי שמשלימים את כל המשימות בעצירה ולפני שמתחילים לנסוע לתחנה הבאה, צריך לבצע פעולות שקשורות לכלי רכב משלימים עצירה ולרכב בדרך לתחנה הבאה.
הנהג/ת קיבל/ה הודעה לשמור (לא למסור) משלוח. אחרי שההתראה תתקבל ותאושר, צריך להגדיר את סטטוס המשימה כ'הושלם'.
הנהג/ת קיבל/ה הודעה למסור משלוח מסוים בהמשך, וההזמנה משתנה בהתאם להתחייבות. מעדכנים את סדר המשימות.
הנהג בוחר לשלוח משלוח שלא היה תקין. מעדכנים את סדר המשימות וממשיכים כרגיל.
הנהג/ת שולח/ת כמה משלוחים למיקום אחד. המודל הזה מחושב באופן דומה למועד של עצירת משלוח אחת. אחרי שמגיעים לעצירה, מבצעים פעולות שקשורות לרכב שמגיע לעצירה. אחרי מסירת כל אחד מהמשלוחים, סוגרים כל משימה, ואפשר גם לסגור את סטטוס המשלוח בחנות ומטא-נתונים נוספים. אחרי שמשלימים את כל המשימות בעצירה ולפני שמתחילים לנסוע לתחנה הבאה, צריך לבצע פעולות שקשורות לכלי רכב משלימים עצירה ולרכב בדרך לתחנה הבאה.
סוף יום הנהג חוזר לתחנת הרכבת. אם הנהג חוזר לתחנה והמשלוחים נאספים במהלך המסלול, צריך גם ליצור ולסגור כל חבילה כמשימת מסירה כדי להבטיח שהחיוב יהיה נכון. כדי לעשות את זה, אפשר לבנות את המאגר כמו כל שירות אחר של עצירת משלוחים. גם אם המחסן לא משמש כעצרת מסירה, אפשר עדיין להגדיר מודל של המאגר כעצירה מתוזמנת. בניית מודל של התחנה מאפשרת לנהגים לראות את המסלול בחזרה לתחנת היעד ולקבל מידע על זמן ההגעה המשוער.

איך פועלים עדכוני המיקום

כדי ליהנות מהביצועים הטובים ביותר עם Fleet Engine, יש לספק לו רצף של עדכונים לגבי מיקום הרכב. אפשר לספק את העדכונים האלה באחת מהדרכים הבאות:

  1. שימוש ב-Driver SDK – האפשרות הפשוטה ביותר – Android, iOS.
  2. כדאי להשתמש בקוד מותאם אישית – שימושי אם המיקומים מועברים דרך הקצה העורפי, או אם אתם משתמשים במכשירים אחרים שאינם Android או iOS.

בלי קשר לאופן שבו מספקים עדכונים לגבי מיקום הרכב, הקצה העורפי שלכם אחראי לעדכון ה-Fleet Engine כשרכב המשלוחים בעצירה (כולל התחנה) וכשהוא מגיע בעצירה. Fleet Engine לא מזהה את האירועים האלה באופן אוטומטי.

תחנות משלוחים ומקומות למשלוחים

עצירת רכב היא המקום שבו רכב משלוחים משלים משימת משלוח או משימה אחרת. היא נקודת גישה כמו עמדת טעינה או מיקום שנתפס בכביש.

יעד המשלוח הוא המיקום שאליו נמסרים או אוספים את המשלוח. יכול להיות שיהיה צורך בהליכה מתחנת הרכב כדי להגיע ליעד המשלוח וממנו.

לדוגמה, כשנהג שולח משלוח לחנות בקניון, רכב המשלוחים עוצר בחניון של הקניון שליד הכניסה הקרובה ביותר לחנות. זוהי העצירה של הרכב. אחר כך הנהג הולך מתחנת הרכב אל המיקום בתוך הקניון שבו החנות ממוקמת. זה יעד המשלוח.

כדי לאפשר למשתמשים לעקוב אחרי המשלוח בצורה הטובה ביותר, כדאי לשקול את האופן שבו משימות של שילוח מוקצות לעצירות רכב, ולזכור שדיווח למשתמש על מספר התחנות שנותרו במשימות המשלוח מדווח למשתמש כדי לעזור לו לראות את התקדמות המשלוח.

לדוגמה, אם הנהג מבצע הרבה משלוחים לבניין משרדים אחד, אפשר להקצות את כל משימות המסירה לתחנת רכב אחת. אם כל משימת מסירה מוקצה לתחנת רכב נפרדת, חוויית המעקב שלכם אחרי המשלוח תהיה פחות מועילה למשתמשים, כי המעקב זמין רק כשהרכב נמצא בטווח של מספר מוגבל של עצירות לפני היעד שלו. כשיש הרבה עצירות ביניים בזמן קצר, לא נשאר למשתמש הרבה זמן לעקוב אחרי ההתקדמות במסירה.

שימוש בערכות SDK לנייד

לפני שמבצעים קריאות ל-Driver SDK, חשוב לאתחל אותו.

אתחול ממשק ה-API של מנהל התקן המסירה

לפני שמפעילים את Delivery Driver API ב-Driver SDK, צריך לאתחל את ה-Navigation SDK. לאחר מכן מאתחלים את Delivery Driver 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));
     }
   });

תרחישים לדוגמה

בקטע הזה נסביר איך להשתמש ב-Deliveries API כדי לבנות מודלים של תרחישים נפוצים לדוגמה.

מזהי ישויות ייחודיים

הפורמט והערך של מזהי הישויות הייחודיים שמשמשים בקריאות REST הם אטומים ל-Fleet Engine. לא מומלץ להשתמש בהוספה אוטומטית של מזהים ולא לכלול פרטים אישיים מזהים (PII), כמו מספר הטלפון של הנהג.

יצירת רכב

אפשר ליצור רכב באמצעות Driver SDK או מסביבת שרת באמצעות gRPC או REST.

gRPC

כדי ליצור רכב חדש, צריך לבצע קריאה של CreateDeliveryVehicle ל-Fleet Engine. משתמשים באובייקט CreateDeliveryVehicleRequest כדי להגדיר את המאפיינים של רכב המשלוחים החדש. שימו לב שבהתאם להנחיות של ה-API, המערכת תתעלם מכל ערך שצוין בשדה Name לגבי מזהים שצוינו על ידי המשתמש. עליכם להשתמש בשדה DeliveryVehicleId כדי להגדיר את מזהה הרכב.

כשיוצרים DeliveryVehicle, אפשר לציין את השדות הבאים:

  • מאפיינים
  • LastLocation
  • סוג

לא מגדירים שדות אחרים. אם כן, 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;
    }

REST

כדי ליצור רכב מסביבת שרת, שולחים קריאה ל-CreateDeliveryVehicle ב-REST של HTTP:

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

בכל הנחיות API, המערכת של Fleet Engine מתעלם מהשדה name של הישות DeliveryVehicle לגבי מזהים שצוינו על ידי המשתמש. לא מגדירים שדות אחרים. אם כן, 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 או REST.

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

REST

כדי ליצור משימה של איסוף משלוח מסביבת שרת, יוצרים קריאה של HTTP REST ל-CreateTask:

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

<id> הוא מזהה ייחודי של המשימה. זה לא יכול להיות מספר המעקב של המשלוח. אם אין במערכת מזהי משימות, אפשר ליצור מזהה ייחודי אוניברסלי (UUID).

כותרת הבקשה חייבת להכיל שדה Authorization עם הערך Bearer <token>, כאשר <token> הוא אסימון שהונפק על ידי מפעל לאסימונים של Fleet Engine.

גוף הבקשה חייב להכיל ישות Task:

  • שדות חובה:

    שדהערך
    סוג Type.PICKUP
    state State.OPEN
    trackingId המספר או המזהה שמשמשים אותך למעקב אחרי משלוח.
    plannedLocation המיקום שבו צריך להשלים את המשימה, במקרה הזה מיקום האיסוף של המשלוח.
    taskDuration משך הזמן הצפוי (בשניות) הצפוי כדי לאסוף את המשלוח בנקודת האיסוף.

  • שדות אופציונליים:

    שדהערך
    targetTimeWindow חלון הזמן שבמהלכו צריך להשלים את המשימה. אין לכך השפעה על ההתנהגות בתכנון.
    מאפיינים רשימה של מאפיינים מותאמים אישית למשימה. לכל מאפיין צריך להיות מפתח ייחודי.

המערכת מתעלמת מכל שאר השדות בישות במהלך היצירה. Fleet Engine גורם לחריגה אם הבקשה כוללת deliveryVehicleId שהוקצה. אתם מקצים משימות באמצעות UpdateDeliveryVehicleRequest. מידע נוסף זמין במאמרים הקצאת משימות לרכב ו-UpdateDeliveryVehicleRequest.

פקודת 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 או REST.

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

REST

כדי ליצור משימת מסירת משלוח מסביבת שרת באמצעות gRPC או REST, צריך ליצור קריאה ל-CreateTask ב-REST:

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

<id> הוא מזהה ייחודי של המשימה. זה לא יכול להיות מספר המעקב של המשלוח. אם אין במערכת מזהי משימות, אפשר ליצור מזהה ייחודי אוניברסלי (UUID).

כותרת הבקשה חייבת להכיל שדה Authorization עם הערך Bearer <token>, כאשר <token> הוא אסימון שהונפק על ידי מפעל לאסימונים של Fleet Engine.

גוף הבקשה חייב להכיל ישות Task:

  • שדות חובה:

    שדהערך
    סוג Type.DELIVERY
    state State.OPEN
    trackingId המספר או המזהה שמשמשים אותך למעקב אחרי משלוח.
    plannedLocation המיקום שבו צריך להשלים את המשימה, במקרה הזה מיקום המשלוח של המשלוח הזה.
    taskDuration הזמן הצפוי בשניות עד למסירת המשלוח במיקום המשלוח.

  • שדות אופציונליים:

    שדהערך
    targetTimeWindow חלון הזמן שבמהלכו צריך להשלים את המשימה. אין לכך השפעה על ההתנהגות בתכנון.
    מאפיינים רשימה של מאפיינים מותאמים אישית למשימה. לכל מאפיין צריך להיות מפתח ייחודי.

המערכת מתעלמת מכל שאר השדות בישות במהלך היצירה. מערכת Fleet Engine מקפיצה הודעת שגיאה אם הבקשה כוללת הקצאת Fleet EngineId. אתם מקצים משימות באמצעות UpdateDeliveryVehicleRequest. מידע נוסף זמין במאמרים הקצאת משימות לרכב ו-UpdateDeliveryVehicleRequest.

פקודת 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 או REST.

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

REST

כדי ליצור משימה של מסירה ואיסוף מסביבת שרת, צריך לשלוח קריאת 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 או REST. משימת אי-זמינות מתוזמנת לא יכולה לכלול מזהה לצורכי מעקב. אפשר גם לציין מיקום.

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

REST

כדי ליצור משימת unavailability מסביבת שרת, יוצרים קריאה של HTTP REST ל-CreateTask:

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

<id> הוא מזהה ייחודי של המשימה. אם אין במערכת מזהי משימות, אפשר ליצור מזהה ייחודי אוניברסלי (UUID).

כותרת הבקשה חייבת להכיל שדה Authorization עם הערך Bearer <token>, כאשר <token> הוא אסימון שהונפק על ידי מפעל לאסימונים של Fleet Engine.

גוף הבקשה חייב להכיל ישות Task:

  • שדות חובה:

    שדהערך
    סוג Type.UNAVAILABLE
    state State.OPEN
    taskDuration משך ההפסקה בשניות.

  • שדות אופציונליים:

    שדהערך
    plannedLocation מיקום ההפסקה, אם היא צריכה להתבצע במיקום ספציפי.

המערכת מתעלמת מכל שאר השדות בישות במהלך היצירה. מערכת Fleet Engine מקפיצה הודעת שגיאה אם הבקשה כוללת הקצאת Fleet EngineId. אתם מקצים משימות באמצעות UpdateDeliveryVehicleRequest. מידע נוסף זמין במאמרים הקצאת משימות לרכב ו-UpdateDeliveryVehicleRequest.

פקודת 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 או REST. משימה של עצירה מתוזמנת לא יכולה לכלול מזהה מעקב.

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

REST

כדי ליצור משימה של עצירה מתוזמנת מסביבת שרת, יוצרים קריאה של HTTP REST ל-CreateTask:

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

<id> הוא מזהה ייחודי של המשימה. אם אין מזהי משימות במערכת, אפשר ליצור מזהה ייחודי אוניברסלי (UUID).

כותרת הבקשה חייבת להכיל שדה Authorization עם הערך Bearer <token>, כאשר <token> הוא אסימון שהונפק על ידי מפעל לאסימונים של Fleet Engine.

גוף הבקשה חייב להכיל ישות Task:

  • שדות חובה:

    שדהערך
    סוג Type.SCHEDULED_STOP
    state State.OPEN
    plannedLocation מיקום העצירה.
    taskDuration משך העצירה הצפוי בשניות.

  • שדות אופציונליים:

    • אין

המערכת מתעלמת מכל שאר השדות בישות במהלך היצירה. מערכת Fleet Engine מקפיצה הודעת שגיאה אם הבקשה כוללת הקצאת Fleet EngineId. אתם מקצים משימות באמצעות UpdateDeliveryVehicleRequest. מידע נוסף זמין במאמרים הקצאת משימות לרכב ו-UpdateDeliveryVehicleRequest.

פקודת 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;
    }

REST

כדי להגדיר חלון זמן למשימה באמצעות HTTP, קוראים לפונקציה UpdateTask:

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

<id> הוא מזהה ייחודי של המשימה.

כותרת הבקשה חייבת להכיל שדה Authorization עם הערך Bearer <token>, כאשר <token> הוא אסימון שהונפק על ידי מפעל לאסימונים של Fleet Engine.

גוף הבקשה חייב להכיל ישות Task:

  • שדות חובה:

    שדהערך
    targetTimeWindow חלון הזמן שבמהלכו צריך להשלים את המשימה. ההגדרה הזו לא משפיעה על התנהגות הניתוב

  • שדות אופציונליים:

    • אין

המערכת תתעלם מכל השדות האחרים בישות במהלך העדכון.

פקודת 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 למשימה. מידע נוסף זמין במאמר משימות של רכבים פעילים. אפשר לעשות את זה כשיוצרים את המשימה או מעדכנים אותה. דוגמה לעדכון המשימה באמצעות ההגדרה הזאת:

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)
  .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

כדי להגדיר את חלון התצורה של תצוגת המעקב באמצעות HTTP, קוראים לפונקציה UpdateTask:

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

<id> הוא מזהה ייחודי של המשימה.

כותרת הבקשה חייבת להכיל שדה Authorization עם הערך Bearer <token>, כאשר <token> הוא אסימון שהונפק על ידי מפעל לאסימונים של Fleet Engine.

גוף הבקשה חייב להכיל ישות Task:

  • שדות חובה:

    שדהערך
    taskTrackingViewConfig ההגדרה של מעקב אחר משימות, שמציינת אילו רכיבי נתונים גלויים למשתמשי הקצה ובאילו נסיבות.

  • שדות אופציונליים:

    • אין

המערכת תתעלם מכל השדות האחרים בישות במהלך העדכון.

פקודת curl לדוגמה:

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

הקצאת משימות לרכב

אתם מקצים משימות לרכב משלוחים על ידי עדכון סדר המשימות ברכב. סדר המשימות ברכב נקבע לפי רשימת התחנות של כלי הרכב, ואפשר להקצות משימה אחת או יותר לכל עצירה. למידע נוסף, ראו עדכון של סדר המשימות.

כדי להעביר משלוח מרכב אחד לרכב אחר, סוגרים את המשימה המקורית ואז יוצרים אותה מחדש לפני שמקצים את הרכב החדש. אם תעדכנו את סדר המשימות של משימה שכבר הוקצתה לרכב אחר, תופיע הודעת שגיאה.

עדכון סדר המשימות

אתם יכולים לעדכן את סדר המשימות שהוקצו לרכב מ-Driver SDK או מסביבת השרת. לא מומלץ להשתמש בשתי השיטות כדי להימנע ממרוץ תהליכים ולשמור על מקור מהימן אחד.

כשמעדכנים את סדר המשימות של רכב, מתבצעות גם הפעולות הבאות:

  • הקצאת משימות חדשות לרכב.
  • הלחצן סוגר את כל המשימות שהוקצו לרכב בעבר, אבל לא נמצאות בסדר המעודכן.

כדי להעביר משלוח מרכב אחד לרכב אחר, צריך לסגור את המשימה המקורית ואז ליצור אותה מחדש לפני שמקצים את הרכב החדש. אם תעדכנו את סדר המשימות של משימה שכבר הוקצתה לרכב אחר, תופיע הודעת שגיאה.

אתם יכולים לעדכן את סדר המשימות מתי שתרצו.

gRPC

הדוגמה הבאה ממחישה איך להשתמש בספריית Java gRPC כדי לעדכן את סדר המשימות ברכב:

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

כדי לעדכן את סדר המשימות ברכב מסביבת שרת, מבצעים קריאה של HTTP REST ל-UpdateDeliveryVehicle:

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

<id> הוא מזהה ייחודי של רכב משלוח בארגון שלכם שמתכוונים לעדכן את סדר המשימות שלו. זה המזהה שציינתם כשיצרתם את הרכב.

כותרת הבקשה חייבת להכיל שדה Authorization עם הערך Bearer <token>, כאשר <token> הוא אסימון שהונפק על ידי מפעל לאסימונים של Fleet Engine.

גוף הבקשה חייב להכיל ישות DeliveryVehicle:

  • שדות חובה:

    שדהערך
    remainingVehicleJourneySegments רשימה של מקטעי המסלול למשימות לפי הסדר שבו צריך לבצע אותן. המשימה הראשונה ברשימה מבוצעת ראשונה.
    leftVehicleJourneySegments[i].stop העצירה של משימה i ברשימה.
    leftVehicleJourneySegments[i].stop.plannedLocation המיקום המתוכנן של העצירה.
    leftVehicleJourneySegments[i].stop.tasks רשימת משימות שצריך לבצע בתחנה הזו של הרכב.
    remainingVehicleJourneySegments[i].stop.state State.NEW

  • שדות אופציונליים:

    • אין

המערכת תתעלם מכל השדות האחרים בישות במהלך העדכון.

פקודת curl לדוגמה:

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

הרכב בדרך לתחנה הבאה

חובה לקבל התראה כשרכב יוצא מעצירה או מתחיל בניווט. אפשר להודיע ל-Fleet Engine דרך Driver SDK או מסביבת שרת באמצעות gRPC או REST. לא מומלץ להשתמש בשתי השיטות כדי להימנע ממרוץ תהליכים וגם כדי לשמור על מקור מהימן אחד.

gRPC

הדוגמה הבאה מראה איך להשתמש בספריית Java gRPC כדי להודיע ל-Fleet Engine שרכב נמצא בדרך לתחנה הבאה שלו.

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

    DeliveryServiceBlockingStub deliveryService =
      DeliveryServiceGrpc.newBlockingStub(channel);

    // Vehicle settings
    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

כדי להודיע ל-Fleet Engine שרכב נמצא בדרך לתחנה הבאה שלו מסביבת שרת, צריך לבצע קריאת HTTP REST ל-UpdateDeliveryVehicle:

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

<id> הוא מזהה ייחודי של רכב המסירה בארגון שלכם שמתכוונים לעדכן את סדר המשימות שלו. זה המזהה שציינתם כשיצרתם את הרכב.

כותרת הבקשה חייבת להכיל שדה Authorization עם הערך Bearer <token>, כאשר <token> הוא אסימון שהונפק על ידי מפעל לאסימונים של Fleet Engine.

גוף הבקשה חייב להכיל ישות DeliveryVehicle:

  • שדה חובה:

    שדהערך
    remainingVehicleJourneySegments רשימת העצירות הנותרות של הרכבים, ומדינת היעד שלהן מסומנת כ-State.NEW. המצב של התחנה הראשונה ברשימה צריך להיות מסומן כ-State.ENROUTE.

  • שדות אופציונליים:

    • אין

המערכת מתעלמת מכל שאר השדות בישות עבור ההתראה.

פקודת curl לדוגמה:

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

עדכון מיקום הרכב

אם אתם לא משתמשים ב-Driver SDK כדי לעדכן את מיקום הרכב, תוכלו לבצע קריאה ישירה ל-Fleet Engine עם מיקום הרכב. לכל כלי רכב פעיל, Fleet Engine מצפה לעדכון מיקום לפחות פעם בדקה, לכל היותר פעם ב-5 שניות.

gRPC

הדוגמה הבאה מראה איך להשתמש בספריית Java gRPC כדי לעדכן את מיקום הרכב ב-Fleet Engine:

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

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

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

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

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

REST

כדי לעדכן את מיקום הרכב ב-Fleet Engine באמצעות HTTP REST, מבצעים קריאה ל-UpdateDeliveryVehicle:

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

<id> הוא מזהה ייחודי של הרכב למשלוחים בצי שלכם או של הרכב שאתם מתכוונים לעדכן את המיקום שלו. זה המזהה שציינתם כשיצרתם את הרכב.

כותרת הבקשה חייבת להכיל שדה Authorization עם הערך Bearer <token>, כאשר <token> הוא אסימון שהונפק על ידי מפעל לאסימונים של Fleet Engine.

גוף הבקשה חייב להכיל ישות DeliveryVehicle:

  • שדה חובה:

    שדהערך
    lastLocation.supplementalLocation המיקום של הרכב.
    lastLocation.supplementalLocationTime חותמת הזמן הידועה האחרונה שבה היה הרכב במיקום הזה.
    lastLocation.supplementalLocationSensor יש לאכלס אותו ב-CUSTOMER_SUPPLIED_LOCATION.

  • שדות אופציונליים:

    שדהערך
    lastLocation.supplementalLocationAccuracy הדיוק של המיקום שסופק, במטרים.

פקודת curl לדוגמה:

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

רכב מגיע בעצירה

יש ליידע את ה-Fleet Engine כשרכב מגיע לעצירה. אפשר להודיע על כך ל-Fleet Engine דרך Driver SDK או מסביבת שרת באמצעות gRPC או REST. לא מומלץ להשתמש בשתי השיטות כדי להימנע ממרוץ תהליכים וגם כדי לשמור על מקור מהימן אחד.

gRPC

הדוגמה הבאה מראה איך להשתמש בספריית Java gRPC כדי להודיע ל-Fleet Engine שרכב הגיע לעצירה:

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

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Vehicle settings
String vehicleName = "providers/" + PROJECT_ID + "/deliveryVehicles/" + VEHICLE_ID;
DeliveryVehicle 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

כדי להודיע ל-Fleet Engine על הגעה של רכב לעצירה מסביבת שרת, צריך לבצע קריאת HTTP REST ל-UpdateDeliveryVehicle:

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

<id> הוא מזהה ייחודי של רכב המסירה בארגון שלכם שמתכוונים לעדכן את סדר המשימות שלו. זה המזהה שציינתם כשיצרתם את הרכב.

כותרת הבקשה חייבת להכיל שדה Authorization עם הערך Bearer <token>, כאשר <token> הוא אסימון שהונפק על ידי מפעל לאסימונים של Fleet Engine.

גוף הבקשה חייב להכיל ישות DeliveryVehicle:

  • שדות חובה:

    שדהערך
    remainingVehicleJourneySegments התחנה שבה הגעת לתחנה מוגדרת כ-State.ARRIVED, ולאחר מכן מופיעה רשימה של עצירות הביניים שנותרו כשהמדינה מסומנת כ-State.NEW.

  • שדות אופציונליים:

    • אין

המערכת תתעלם מכל השדות האחרים בישות במהלך העדכון.

פקודת curl לדוגמה:

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

הרכב עומד בעצירה

חובה להודיע למנוע בכלל בעת עצירה של כלי רכב. כתוצאה מכך, כל המשימות שמשויכות לעצירה יועברו למצב 'סגור'. אפשר להודיע ל-Fleet Engine באמצעות Driver SDK או סביבת שרת באמצעות gRPC או REST. אין להשתמש בשתי השיטות כדי להימנע ממרוץ תהליכים וגם כדי לשמור על מקור מהימן אחד.

gRPC

הדוגמה הבאה מראה איך להשתמש בספריית Java gRPC כדי להודיע ל-Fleet Engine שרכב השלים עצירה.

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

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Vehicle settings
String vehicleName = "providers/" + PROJECT_ID + "/deliveryVehicles/" + VEHICLE_ID;
DeliveryVehicle 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

כדי להודיע ל-Fleet Engine לגבי השלמה של עצירה בסביבת שרת, צריך לבצע קריאת HTTP REST ל-UpdateDeliveryVehicle:

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

<id> הוא מזהה ייחודי של רכב המסירה בארגון שלכם שמתכוונים לעדכן את סדר המשימות שלו. זה המזהה שציינתם כשיצרתם את הרכב.

כותרת הבקשה חייבת להכיל שדה Authorization עם הערך Bearer <token>, כאשר <token> הוא אסימון שהונפק על ידי מפעל לאסימונים של Fleet Engine.

גוף הבקשה חייב להכיל ישות DeliveryVehicle:

  • שדות חובה:

    שדהערך
    remaining_vehicle_journey_segments עצירת הביניים שהשלמת לא אמורה להופיע יותר ברשימה של תחנות העצירה שנותרו.

  • שדות אופציונליים:

    • אין

המערכת תתעלם מכל השדות האחרים בישות במהלך העדכון.

פקודת curl לדוגמה:

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

עדכון משימה

רוב שדות המשימה לא ניתנים לשינוי. עם זאת, אפשר לשנות ישירות את ישות המשימה כדי לשנות את המצב, את תוצאת המשימה, את הזמן של התוצאה, את המיקום של המשימה ואת המאפיינים שלה. לדוגמה, אם המשימה לא הוקצתה לרכב, תוכלו לעדכן את המצב ישירות כדי לסגור אותה.

gRPC

דוגמה לעדכון משימה דרך gRPC

REST

דוגמה לעדכון משימה באמצעות REST

סגירת משימה

כדי לסגור משימה שהוקצתה לרכב, צריך להודיע ל-Fleet Engine כי הרכב השלים את העצירה שבה המשימה מתבצעת או להסיר אותה מרשימת התחנות של כלי הרכב. לשם כך, אפשר להגדיר את רשימת התחנות הנותרות בדיוק כמו שמעדכנים את סדר המשימות של רכב מסוים.

אם למשימה עדיין לא הוקצה רכב וצריך לסגור אותה, צריך לעדכן את המשימה למצב 'סגור'. עם זאת, אי אפשר לפתוח מחדש משימה שסגרה.

סגירה של משימה לא מצביעה על הצלחה או כישלון. ההודעה מציינת שהמשימה כבר לא מתבצעת. לצורך מעקב אחרי משלוחים, חשוב לציין את התוצאה בפועל של המשימה, כדי שאפשר יהיה להציג את תוצאת המסירה.

gRPC

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

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

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

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

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

REST

כדי לסמן משימה כ'סגורה' מסביבת שרת, צריך לשלוח קריאת HTTP REST ל-UpdateTask:

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

<id> הוא מזהה ייחודי של המשימה.

כותרת הבקשה חייבת להכיל שדה Authorization עם הערך Bearer <token>, כאשר <token> הוא אסימון שהונפק על ידי מפעל לאסימונים של Fleet Engine.

צריך לכלול ישות Task בגוף הבקשה:

  • שדות חובה:

    שדהערך
    state State.CLOSED

  • שדות אופציונליים:

    שדהערך
    taskOutcome תוצאה.דיווח או שהתקבלו.נכשל
    taskOutcomeTime השעה שבה המשימה הושלמה.
    taskOutcomeLocation המיקום שבו המשימה הושלמה. ברירת המחדל של ה-Fleet Engine היא מיקום הרכב האחרון, אלא אם הספק שינה זאת באופן ידני.

המערכת תתעלם מכל השדות האחרים בישות במהלך העדכון.

פקודת curl לדוגמה:

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

מגדירים את תוצאת המשימה ואת המיקום שלה

אם סגרתם משימה, זה לא אומר שהיא הצליחה או נכשלה, אלא מצביעה על כך שמשימה כבר לא מתבצעת. לצורך מעקב אחרי משלוחים, חשוב לציין את התוצאה של המשימה בפועל, כדי שאפשר יהיה להציג את תוצאת המסירה ולקבל חיוב על השירותים. אחרי שמגדירים את המשימה, אי אפשר לשנות אותה. עם זאת, אפשר לשנות את מועד התוצאה של המשימה ואת המיקום שלה אחרי שהוגדרו.

במשימות שנמצאות במצב CLOSED, אפשר להגדיר את התוצאה שלהן כ-{2} מציגה לסירוגין או כ-נכשל. Fleet Engine מחויב רק במשימות מסירה עם מצב חולפות.

כשמסמנים תוצאה של משימה, המערכת של Fleet Engine ממלאת באופן אוטומטי את המיקום של תוצאת המשימה במיקום הרכב הידוע האחרון. אפשר לשנות את ההתנהגות הזו.

gRPC

אתם יכולים לבחור את המיקום של תוצאת המשימה כשאתם מגדירים את התוצאה. הגדרת המיקום מונעת מ-Fleet Engine להגדיר את ברירת המחדל של מיקום הרכב האחרון. אפשר גם להחליף את המיקום שהוגדר לתוצאה של המשימה ב-Fleet Engine בשלב מאוחר יותר. Fleet Engine אף פעם לא מחליף מיקום של תוצאת משימה שאתם מספקים. אי אפשר לקבוע מיקום לתוצאת משימה. אתם יכולים להגדיר גם את תוצאת המשימה וגם את המיקום שלה באותה בקשה.

הדוגמה הבאה ממחישה איך להשתמש בספריית 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)
  .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

כדי לסמן שמשימה בוצעה מסביבת שרת, צריך לשלוח ל-UpdateTask קריאה ל-HTTP REST:

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

<id> הוא מזהה ייחודי של המשימה.

כותרת הבקשה חייבת להכיל שדה Authorization עם הערך Bearer <token>, כאשר <token> הוא אסימון שהונפק על ידי מפעל לאסימונים של Fleet Engine.

גוף הבקשה חייב להכיל ישות Task:

  • שדות חובה:

    שדהערך
    taskOutcome תוצאה.דיווח או שהתקבלו.נכשל

  • שדות אופציונליים:

    שדהערך
    taskOutcomeLocation המיקום שבו המשימה הושלמה. אם המדיניות לא מוגדרת, Fleet Engine קובע את ברירת המחדל של מיקום הרכב האחרון.
    taskOutcomeTime חותמת הזמן של מועד השלמת המשימה.

המערכת תתעלם מכל השדות האחרים בישות במהלך העדכון.

פקודת curl לדוגמה:

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

ניתוב מחדש של משלוח

אחרי שיוצרים משימת משלוח, אי אפשר לשנות את המיקום המתוכנן שלה. כדי לנתב מחדש משלוח, סוגרים את משימת המשלוח בלי לקבוע תוצאה, ואז יוצרים משימה חדשה עם המיקום המתוכנן המעודכן. אחרי שיוצרים את המשימה החדשה, מקצים את המשימה לאותו כלי רכב. למידע נוסף, ראו סגירת משימת המשלוח והקצאת המשימה.

משתמשים ברכבי הזנה וכלי משלוח

אם אתם משתמשים ברכבים למילוי בקבוקים כדי להעביר משלוחים לרכבי הובלה במהלך היום, אתם יכולים לבנות מודל של העברת המשלוחים כמשימה מתוזמנת של עצירת המשלוח. כדי שיהיה מעקב מדויק אחרי המיקום, כדאי להקצות משימת מסירה של משלוח שהועבר רק אחרי שהוא נטען לרכב המסירה. מידע נוסף זמין במאמר בנושא עצירה מתוזמנת.

סטטוס משלוח של חנות ומטא-נתונים נוספים

כשמשימת משלוח מסתיימת, מצב המשימה והתוצאה שלה מתועדים. עם זאת, יכול להיות שתרצו לעדכן מטא-פרטים אחרים שספציפיים למשלוח. כדי לאחסן מטא-נתונים נוספים שאפשר להפנות אליהם מחוץ לשירות Fleet Engine, משתמשים ב-tracking_id שמשויך למשימה כמפתח בטבלה חיצונית.

מידע נוסף מופיע במאמר חיי המשימה.

חיפוש כלי רכב

אפשר לחפש רכב ב-Driver SDK או בסביבת שרת באמצעות gRPC או REST.

gRPC

תוכלו להיעזר בדוגמה הבאה כדי לחפש רכב באמצעות ספריית Java gRPC:

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

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

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

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

REST

כדי לחפש רכב מסביבת שרת, צריך לבצע קריאה ל-GetVehicle ב-REST של HTTP:

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

<id> הוא מזהה ייחודי של המשימה.

<vehicleId> הוא מזהה הרכב שצריך לחפש.

כותרת הבקשה חייבת להכיל שדה Authorization עם הערך Bearer <token>, כאשר <token> הוא אסימון שהונפק על ידי מפעל לאסימונים של Fleet Engine.

גוף הבקשה חייב להיות ריק.

אם החיפוש יסתיים בהצלחה, גוף התגובה יכלול ישות של רכב.

פקודת curl לדוגמה:

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

חיפוש משימה

אפשר לחפש משימות בסביבת שרת באמצעות gRPC או REST. ה-Driver SDK לא תומך בחיפוש משימה.

gRPC

בדוגמה הבאה תוכלו לראות איך משתמשים בספריית Java gRPC כדי לחפש משימה:

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

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

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

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

     case PERMISSION_DENIED:
       break;
  }
  return;
}

REST

כדי לחפש משימה מסביבת שרת, צריך לבצע קריאה ל-GetTask ב-REST של HTTP:

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

<id> הוא מזהה ייחודי של המשימה.

<taskId> הוא המזהה של המשימה לחיפוש.

כותרת הבקשה חייבת להכיל שדה Authorization עם הערך Bearer <token>, כאשר <token> הוא אסימון שהונפק על ידי מפעל לאסימונים של Fleet Engine.

גוף הבקשה חייב להיות ריק.

אם החיפוש יסתיים בהצלחה, גוף התגובה יכלול ישות משימה.

פקודת curl לדוגמה:

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

מחפשים מידע על משימת משלוח לפי המזהה לצורכי מעקב

אפשר לחפש מידע על משימת משלוח בדרכים הבאות, ולכל אחת מהן יש מטרה נפרדת:

  • by a Task ID: משמש משתמשים כמו מפעילים של כלל המכשירים בארגון, שיש להם גישה לתצוגה המלאה של נתוני המשימה.
  • באמצעות מזהה לצורכי מעקב: משמש את תוכנת הלקוח כדי לספק מידע מוגבל למשתמש הקצה, למשל המועד שבו החבילה צפויה להגיע בבית.

בקטע הזה נסביר איך מחפשים פרטי משימה לפי מזהה לצורכי מעקב. כדי לחפש משימה לפי מזהה המשימה, תוכלו להיעזר במאמר חיפוש משימה.

כדי לחפש מידע לפי מזהה לצורכי מעקב, אפשר להשתמש באחת מהאפשרויות הבאות:

דרישות לחיפוש

  • פרטי המשלוח שמסופקים על ידי מזהה לצורכי מעקב עומדים בכללי החשיפה המפורטים בקטע שליטה בגישה של מיקומים שבמעקב.

  • אפשר להשתמש ב-Fleet Engine כדי לחפש פרטי משלוח לפי מזהה לצורכי מעקב. ערכת ה-SDK של הנהג לא תומכת בחיפוש מידע באמצעות מזהה לצורכי מעקב. כדי לעשות זאת באמצעות Fleet Engine, צריך להשתמש בסביבת שרת או בסביבת דפדפן.

  • השתמשו באסימון הצר ביותר שאפשר כדי להגביל את סיכוני האבטחה. לדוגמה, אם משתמשים באסימון הצרכן למשלוח, כל קריאות ל-API של Fleet Engine Deliveries מחזירות רק מידע שרלוונטי לאותו משתמש הקצה, כמו השולח או המקבל של המשלוח. כל שאר המידע בתשובות מושמט. מידע נוסף על אסימונים זמין במאמר יצירת אסימון אינטרנט מסוג JSON (JWT) להרשאה.

חיפושים ב-Java באמצעות gRPC

הדוגמה הבאה מראה איך משתמשים בספריית Java gRPC כדי לחפש מידע על משימת משלוח לפי המזהה לצורכי מעקב.

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

חיפושי מידע שמשתמשים ב-HTTP

כדי לחפש משימת משלוח מדפדפן, יוצרים קריאה של HTTP REST אל GetTaskTrackingInfo:

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

<tracking_id> הוא המזהה לצורכי מעקב שמשויך למשימה.

כותרת הבקשה חייבת להכיל שדה Authorization עם הערך Bearer <token>, כאשר <token> הוא אסימון שהונפק על ידי מפעל אסימון של Fleet Engine.

אם החיפוש יתבצע בהצלחה, גוף התגובה יכיל ישות taskTrackingInfo.

פקודת curl לדוגמה:

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

הצגת רשימת המשימות

אתם יכולים להציג רשימה של משימות משרת או מסביבת דפדפן. ה-Driver SDK לא תומך בהצגת רשימות של משימות.

הצגת רשימה של משימות מבקשת גישה רחבה למשימות. הצגת רשימה של משימות מיועדת רק למשתמשים מהימנים. כששולחים בקשות למשימות של רשימות, אפשר להשתמש באסימוני הקורא של Fleet להעברת נתונים או מסירת אסימוני אימות משתמש מיוחד.

במשימות שברשימה מצונזרים השדות הבאים:

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

אפשר לסנן את המשימות שברשימה לפי רוב מאפייני המשימות. למידע על התחביר של שאילתות סינון, ראו AIP-160. ברשימה הבאה מוצגים מאפייני משימה תקינים שאפשר להשתמש בהם לסינון:

  • מאפיינים
  • delivery_vehicle_id
  • state
  • planned_location
  • task_duration
  • task_outcome
  • task_outcome_location
  • task_outcome_location_source
  • task_outcome_time
  • tracking_id
  • סוג

משתמשים בפורמטים הבאים של השדות, שמבוססים על הצעות לשיפור של Google API:

סוג שדה פורמט דוגמה
חותמת זמן RFC-3339 task_outcome_time = 2022-03-01T11:30:00-08:00
משך הקורס מספר השניות ואחריהן s task_duration = 120s
טיפוסים בני מנייה (enum) מחרוזת state = CLOSED AND type = PICKUP
מיקום point.latitude וגם point.longitude planned_location.point.latitude > 36.1 AND planned_location.point.longitude < -122.0

לרשימה המלאה של אופרטורים של שאילתות סינון, ראו AIP-160.

אם לא צוינה שאילתת סינון, כל המשימות יופיעו ברשימה.

רשימות של משימות מחולקות לדפים. אפשר לציין גודל דף בבקשות למשימות של רשימה. אם מציינים גודל דף, מספר המשימות שמוחזרות לא גדול מגודל הדף שצוין. אם לא קיים גודל דף, כדאי להשתמש בברירת מחדל סבירה. אם גודל הדף המבוקש חורג מערך מקסימלי פנימי, המערכת תשתמש בערך המקסימלי הפנימי.

רשימת משימות יכולה לכלול אסימון לקריאת דף התוצאות הבא. כדי לאחזר את דף המשימות הבא, משתמשים באסימון של הדף עם בקשה שזהה אחרת לבקשה הקודמת. כשהאסימון של הדף שמוחזר ריק, אי אפשר לאחזר עוד משימות.

gRPC

הדוגמה הבאה ממחישה איך להשתמש בספריית Java gRPC כדי להציג רשימת משימות של deliveryVehicleId ומאפיין משימה. תשובה מוצלחת עדיין יכולה להיות ריקה. תגובה ריקה מציינת שלא משויך אף משימה ל-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

כדי להציג רשימת משימות מדפדפן, צריך לשלוח קריאה ל-HTTP REST ל-ListTasks:

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

כדי להחיל מסנן על המשימות ברשימה, צריך לכלול את הערך של הפרמטר 'סינון' של כתובת ה-URL, עם שאילתת סינון שמסומנת בתו בריחה של כתובת URL.

כותרת הבקשה חייבת להכיל שדה Authorization עם הערך Bearer <token>, כאשר <token> הוא אסימון שהונפק על ידי מפעל לאסימונים של Fleet Engine.

אם החיפוש יסתיים בהצלחה, גוף התגובה יכיל נתונים במבנה הבא:

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

תגובה מוצלחת עדיין יכולה להיות ריקה. תגובה ריקה מציינת שלא נמצאו משימות שעומדות בקריטריוני הסינון שצוינו.

פקודת curl לדוגמה:

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

הצגה של רשימת רכבים למשלוחים

אתם יכולים להציג רשימה של כלי רכב למשלוחים מסביבת שרת או דפדפן. ה-SDK לנהג לא תומך בכרטיסי מוצר למשלוחים.

רכבים למשלוח כרטיסי מוצר מבקשים גישה רחבה לכלי רכב למשלוחים, והם מיועדים רק למשתמשים מהימנים. כשמגישים בקשות של כלי רכב למסירה של רשימות, צריך להשתמש באסימוני הקורא של צי המסירה או בהעברה.

עקב ההשפעה של כלי ההובלה על גודל התגובה, מצונזרים השדות הבאים ברכבי שינוע:

  • CurrentRouteSegment
  • RemainingVehicleJourneySegments

אפשר לסנן את רשימת כלי הרכב שמוצעים למכירה לפי מאפיין attributes שלהם. לדוגמה, כדי לשלוח שאילתה על מאפיין עם המפתח my_key ועם הערך my_value, משתמשים ב-attributes.my_key = my_value. כדי לשלוח שאילתה על מספר מאפיינים, צריך לאחד שאילתות באמצעות האופרטורים הלוגיים AND ו-OR כמו ב-attributes.key1 = value1 AND attributes.key2 = value2. למידע מלא על התחביר של שאילתות המסנן, ראו AIP-160.

בעזרת פרמטר הבקשה viewport אפשר לסנן את רכבי המשלוח הרשומים לפי מיקום. פרמטר הבקשה viewport מגדיר את אזורי התצוגה באמצעות שתי קואורדינטות תוחמות: צמד קואורדינטות של high (צפון מזרח) ו-low (דרום מערב) של קו הרוחב וקו האורך. הבקשות נדחות אם הן מכילות קו רוחב גבוה שנמוך מבחינה גיאוגרפית מקו רוחב נמוך.

כברירת מחדל, רשימות של רכבי משלוח מחולקות לדפים, לפי גודל דף סביר. אם מציינים גודל דף, הבקשה מחזירה רק את מספר כלי הרכב שצוינו במגבלה או פחות. אם גודל הדף המבוקש חורג מערך פנימי מקסימלי, המערכת תשתמש בערך המקסימלי הפנימי. גודל ברירת המחדל וגודל הדף המקסימלי הם 100 כלי רכב.

רשימת כלי רכב למשלוחים יכולה לכלול אסימון לקריאת דף התוצאות הבא. אסימון דף מופיע בתגובה רק כשדפים נוספים של כלי רכב זמינים לאחזור. כדי לאחזר את דף המשימות הבא, צריך להשתמש באסימון הדף עם בקשה שזהה בדרך אחרת לבקשה הקודמת.

gRPC

הדוגמה הבאה ממחישה איך להשתמש בספריית Java gRPC כדי להציג רשימה של רכבים למשלוח באזור מסוים עם מאפיין מסוים. תגובה שהסתיימה בהצלחה עדיין יכולה להיות ריקה. במקרה כזה, המשמעות היא שאין כלי רכב עם המאפיין שצוין כבר באזור התצוגה שצוין.

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

כדי להציג רשימת משימות מדפדפן, צריך לשלוח קריאה ל-HTTP REST ל-ListDeliveryVehicles:

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

כדי להחיל מסנן על המשימות ברשימה, צריך לכלול את הפרמטר של כתובת ה-URL 'סינון' עם שאילתת סינון שמסומנת בתו בריחה (escape) של כתובת URL.

כותרת הבקשה חייבת להכיל שדה Authorization עם הערך Bearer <token>, כאשר <token> הוא אסימון שהונפק על ידי מפעל לאסימונים של Fleet Engine.

אם החיפוש יסתיים בהצלחה, גוף התגובה יכיל נתונים במבנה הבא:

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

תגובה מוצלחת עדיין יכולה להיות ריקה. במצב כזה, לא נמצאו רכבים למשלוח שעומדים בשאילתת המסנן ובאזור התצוגה שצוינו.

פקודת curl לדוגמה:

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

מעקב אחר משלוחים

יש שתי דרכים להשתמש ב-Fleet Engine Deliveries API כדי להפעיל מעקב אחרי משלוחים:

  • מועדף: השתמשו בספריית המעקב אחר משלוחים ב-JavaScript. הספרייה מאפשרת להציג את המיקום של כלי הרכב והמיקומים המעניינים אתכם במעקב ב-Fleet Engine. היא מכילה רכיב מפה של JavaScript שמחליף את ההתקנה של אובייקט google.maps.Map סטנדרטי, ורכיבי נתונים לחיבור עם Fleet Engine. הרכיב הזה מאפשר לכם לספק חוויה מונפשת ומותאמת אישית של מעקב אחרי המשלוח, מאפליקציית האינטרנט או מהאפליקציה לנייד.

  • אתם יכולים להטמיע מעקב משלכם אחרי המשלוח בנוסף ל-Fleet Engine Deliveries API.

המפתח הוא לחפש משימות משלוח לפי מזהה לצורכי מעקב.

אם אתם משתמשים בתפקיד צרכן משלוחים, כל קריאות ל-API של Fleet Engine Deliveries מחזירות רק מידע שרלוונטי לשולח או למקבל. כל שאר המידע בתשובות מושמט. באחריותכם לאמת משתמשי קצה. בנוסף, פרטי המיקום מסוננים לפי המשימה שכבר בוצעה. במהלך משימה של חוסר זמינות, פרטי המיקום לא משותפים עם משתמשי הקצה.

רישום ביומן

אפשר להגדיר את Fleet Engine כך שישלח יומני RPC ל-Cloud Logging. למידע נוסף, ראו רישום ביומן.

תפקידים ואסימונים

כפי שמתואר במאמר ניהול מחזור החיים של רכבים ומשימות ובהערות ההרשאה לתרחישי שימוש ספציפיים, ביצוע קריאות ל-Fleet Engine מחייב אימות באמצעות אסימוני אינטרנט מסוג JSON שנחתמו באמצעות פרטי כניסה של חשבון שירות. לחשבונות השירות שמשמשים להנפקת האסימונים האלה יכול להיות תפקיד אחד או יותר, וכל תפקיד מקצה קבוצה שונה של הרשאות.

למידע נוסף, ראו אימות והרשאה.

פתרון בעיות נפוצות

אם נתקלתם בבעיות, כדאי לעיין בקטעים הבאים כדי לקבל עזרה.

עמידות

Fleet Engine לא נחשב למקור מידע. באחריותכם לשחזר את מצב המערכת במקרה הצורך, בלי להסתמך עלFleet Engine.

מצב אובדן מכשיר ב-Fleet Engine

כשעובדים עם Fleet Engine, כדאי להטמיע לקוחות כדי שהמערכת תתקן את עצמה במקרה של כשל. לדוגמה, כש-Fleet Engine מנסה לעדכן רכב, יכול להיות שבתגובה תוצג שגיאה שמציינת שהרכב לא קיים. לאחר מכן הלקוח צריך ליצור מחדש את הרכב במצב החדש. למרות שהבעיה הזו מתרחשת לעיתים רחוקות, חשוב לוודא שהמערכת עמידה מספיק כדי לטפל בה.

בתרחיש הנדיר ביותר של כשל קטסטרופלי ב-Fleet Engine, יכול להיות שתצטרכו ליצור מחדש את רוב כלי הרכב והמשימות, או את כולם. אם קצב היצירה גבוה מדי, בקשות מסוימות עלולות להיכשל שוב בגלל בעיות מכסות, כי בדיקות המכסות מתבצעות כדי למנוע התקפות מניעת שירות (DoS). במקרה כזה, כדאי להאט את קצב ההפעלה מחדש באמצעות אסטרטגיית השהיה לפני ניסיון חוזר.

מצב אובדן מכשיר באפליקציית הנהג

אם אפליקציית מנהל ההתקן קורסת, האפליקציה צריכה ליצור מחדש את המצב הנוכחי ב-Driver SDK. האפליקציה צריכה לנסות ליצור מחדש משימות כדי לוודא שהן קיימות ולשחזר את המצבים שלהן. האפליקציה צריכה גם ליצור מחדש ולהגדיר באופן מפורש את רשימת העצירות ל-Driver SDK.

שאלות נפוצות

מה קורה אם נהג עוצר לקראת משימה שלא תקינה?

במקרה כזה, קודם מעדכנים את הסדר של המשימות ואז ממשיכים כרגיל – מסמנים את ההגעה לעצירה, מסמנים שהמשימה הושלמה ופרטים נוספים. אם לא תעשו זאת, ייתכן שהמערכת לא תהיה עקבית, זמני ההגעה המשוערים עלולים להיות שגויים וייתכן שיתקבלו דיווחים על שגיאות בלתי צפויות.