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

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

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

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

אימות ההגדרה

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

ספריות לקוח

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

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

מבני נתונים

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

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

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

משלוחי רכב

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

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

משימות

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

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

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

כדי ליצור משימות ב-Flet Engine, צריך להשתמש במנהל המשימות של Driver SDK.

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

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

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

מידע נוסף זמין בנושאים הבאים:

Android

iOS

משימות לא זמינות

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

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

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

מידע נוסף זמין בנושאים הבאים:

Android

iOS

משימות של הפסקה מתוזמנת

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

מידע נוסף זמין בנושאים הבאים:

Android

iOS

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

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

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

דוגמאות למזהי משימות תקינים:

  • 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 מפרה את הדרישות לגבי פרטים אישיים מזהים.
4R0oXLToF"112 Summer Dr. East Hartford, CT06118"577b484da26f8a המדיניות מפרה פרטים אישיים מזהים (PII) ואת דרישות התווים: רווחים, פסיקים ומירכאות. ארוך מ-64 תווים.

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

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

חייו של כלי רכב

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

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

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

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

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

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

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

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

מאפייני הרכב

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

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

חייה של משימה

אפשר ליצור משימות, לעדכן אותן ולבצע שאילתות עליהן ב-Flet Engine באמצעות הממשקים של Deliveries API gRPC או REST.

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

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

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

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

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

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

  1. מעדכנים את שדה התוצאה של המשימה ל-'עבד' או ל'נכשל'.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

שימוש ב-Deliveries API

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

תחנות עצירה ומיקומי משלוחים

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

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

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

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

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

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

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

מפעילים את Delivery Driver API.

לפני שמפעילים את Delivery Driver API ב-Driver SDK, חשוב לאתחל את הניווט 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 ל-Feet Engine. משתמשים באובייקט CreateDeliveryVehicleRequest כדי להגדיר את המאפיינים של כלי המסירה החדש. שימו לב: המערכת תתעלם מכל ערך שצוין בשדה Name בהתאם להנחיות API עבור מזהים שצוינו על ידי משתמשים. עליך להשתמש בשדה 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

כדי ליצור כלי רכב מסביבת שרת, יש לבצע קריאה ל-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 או 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, צריך ליצור קריאה ל-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.DELIVERY
    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": "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

כדי ליצור פעולת העברה ומשימת איסוף מסביבת שרת, צריך לבצע קריאה ל-REST של HTTP ל-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

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

הגדרה של הרשאות הגישה למעקב אחרי משימות

אפשר להגדיר למשימה TaskTrackingViewConfig כדי לקבוע את הרשאות הגישה לנתונים בספריית Shipment Tracking (מעקב אחר משלוחים) ונתונים שהוחזרו משיחה אל GetTaskTrackingInfo, על בסיס כל משימה. למידע נוסף קראו את המאמר משימות פעילות ברכב. אפשר לעשות זאת כשיוצרים או מעדכנים את המשימה. דוגמה לעדכון של המשימה באמצעות ההגדרות האלה:

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 רשימה של קטעי מסלול למשימות לפי הסדר שבו צריך לבצע אותן. המשימה הראשונה ברשימה מתבצעת ראשונה.
    belowVehicleJourneySegments[i].stop התחנה של משימה i ברשימה.
    belowVehicleJourneySegments[i].stop.plannedLocation המיקום המתוכנן לעצירה.
    belowVehicleJourneySegments[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 כשהרכב יוצא מעצירה או מתחיל בניווט. אפשר לעדכן את 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

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

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

gRPC

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

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

סגירת משימה

כדי לסגור משימה שהוקצתה לרכב, צריך להודיע ל-Flit 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 result.AUTH או result.FAILED
    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

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

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

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

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

gRPC

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

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

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

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

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

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

  • שדות חובה:

    שעון שדהתמורה לכסף
    taskOutcome result.AUTH או result.FAILED

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

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

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

חיפוש כלי רכב

אפשר לחפש כלי רכב דרך 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

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

`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. ה-SDK של Drive לא תומך בחיפוש משימות.

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

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

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

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

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

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

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

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

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

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

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

  • שימוש באסימון הצר ביותר האפשרי כדי להגביל את סיכוני האבטחה. לדוגמה, אם אתם משתמשים ב-Deliver Consumer Token, כל הקריאות ל-Feet Engine Deliveries API מחזירות רק מידע שרלוונטי למשתמש הקצה, כמו השולח או המקבל של המשלוח. כל שאר המידע בתשובות מצונזר. מידע נוסף על אסימונים זמין במאמר יצירת אסימון אינטרנט מסוג 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 אין תמיכה בהצגת משימות.

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

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

  • 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
  • סוג

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

סוג שדה פורמט דוגמה
חותמת זמן 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 שמסומנת בתו בריחה (escape).

כותרת הבקשה חייבת להכיל שדה 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"

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

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

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

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

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

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

רישום ביומן

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

תפקידים ואסימונים של הרשאות

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

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

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

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

עמידות

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

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

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

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

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

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

שאלות נפוצות

מה קורה אם נהג עוצר למשימה שלא לפי הסדר?

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