يتوفّر Last Mile Fleet Solution حاليًا لعملاء محدّدين فقط. يمكنك التواصل مع فريق المبيعات لمعرفة المزيد من المعلومات.

بدء استخدام Fleet Engine

تتيح لك واجهة برمجة التطبيقات Fleet Engine Deliveries API تصميم أنشطة أسطولك خلال الفترة الأولى والأخيرة من عمليات التسليم. يتم عرض واجهة برمجة تطبيقات Deliveries API من خلال حزمة تطوير البرامج Driver SDK لنظامَي التشغيل Android وiOS، ويمكن أيضًا استخدامها مباشرةً من خلال طلبات HTTP REST أو gRPC.

الإعداد الأولي

يتم ضبط واجهة برمجة تطبيقات Fleet Engine Deliveries API من خلال Google Cloud Console. للحصول على معلومات عن الخطوات التي يجب اتّخاذها في وحدة التحكّم وكيفية إنشاء رمز JSON المميّز للويب للتفويض، يُرجى الاطّلاع على المصادقة والتفويض. للحصول على تفاصيل حول استخدام وحدة التحكّم، راجِع مستندات Google Cloud Console.

التحقّق من صحة الإعداد

بعد إنشاء حسابات الخدمة، عليك التحقق من اكتمال عملية الإعداد وإمكانية إنشاء مركبة توصيل. من خلال إجراء التحقق في هذه المرحلة من سير العمل، ستضمن أنك قد عالجت مشكلات التفويض الشائعة التي يمكن أن تنشأ عند إعداد مشروعك. اتّبِع دليل التحقُّق من الإعداد. يقدّم هذا الدليل تفاصيل حول كيفية استخدام أداة سطر الأوامر gcloud لاختبار قسمَين رئيسيَّين من عملية الإعداد: التوقيع على الرمز المميّز للتفويض وإنشاء مركبة تسليم تجريبية.

بدلاً من ذلك، يمكنك استخدام نماذج النصوص البرمجية للمصادقة الخاصة بـ Fleet Engine لاختبار الإعداد الخاص بك.

مكتبات العملاء

ننشر مكتبات البرامج بعدة لغات برمجة شائعة. وتقدِّم هذه المكتبات تجربة مطور أفضل على REST أو gRPC. للحصول على تعليمات حول كيفية الحصول على مكتبات البرامج لتطبيق الخادم، يُرجى الاطّلاع على مكتبات العميل.

تفترض أمثلة Java في هذا المستند الإلمام بـ gRPC.

هياكل البيانات

تستخدم Deliveries API هيكليَن للبيانات لوضع نموذج لاستلام الشحنات وتسليمها:

  • مركبة التسليم المستخدَمة لنقل الشحنة
  • مهام استلام الشحنة وتوصيلها.

بالإضافة إلى ذلك، يمكنك استخدام المهام لتحديد أوقات استراحة السائق ومحطات التوقف المجدوَلة على مدار اليوم.

مركبات توصيل

تنقل مركبات التسليم الشحنات من مستودع إلى موقع التسليم، ومن موقع الاستلام إلى المستودع. في بعض الحالات، يمكنهم أيضًا نقل شحنة مباشرة من موقع الاستلام إلى موقع التسليم.

يمكنك استخدام Driver SDK لإنشاء عنصر DeliveryVehicle في Fleet Engine ولإرسال تحديثات الموقع الجغرافي لعمليات الشحن وتتبُّع الأساطيل.

مهام Google

لكل مركبة مهام مُسنَدة إليها. يمكن أن تتضمن هذه مهام الاستلام أو التوصيل، أو الفواصل المطلوبة للسائقين، أو محطات التوقف المجدولة في صناديق التسليم أو مواقع العملاء. يجب أن يكون لكل مهمة معرف مهمة فريد، ولكن قد تشترك في نفس معرف التتبع. يتم استخدام المهام والترتيب الذي تمت جدولتها به لحساب نوافذ الوقت المقدر للوصول لكل مهمة.

استخدام إدارة المهام لـ Driver SDK لإنشاء مهام في Fleet Engine.

مهام الشحن

ترتبط مهام الشحن باستلام الشحنة أو تسليمها. يجب تحديد رقم تتبُّع أو معرّف عند إنشاء مهمة شحن. يجب عليك أيضًا تحديد وقت الثبات لحساب الوقت الإضافي لإكمال المهمة أو البحث عن موقف سيارات أو المشي إلى موقع التسليم.

  • قم بإنشاء مهمة الاستلام لاستلام شحنة، مع تحديد موقع الاستلام ورقم التتبع أو رقم التعريف.
  • قم بإنشاء مهمة تسليم لتسليم شحنة، وتحديد موقع التسليم ورقم التتبع أو معرف.

مهام عدم التوفّر

قم بإنشاء مهمة غير متوفرة لفترة زمنية لا تكون فيها المركبة متاحة للاستلام أو التوصيل. يمكن أن يكون هذا استراحة لإعادة التزود بالوقود أو استراحة للسائق. حدد طول الفاصل عند إنشاء المهمة. ليس من الضروري أخذ فترات استراحة في موقع معين، ولكن تحديد الموقع يوفر نوافذ أكثر دقة للوقت المقدّر للوصول على مدار اليوم.

أثناء مهمة عدم التوفّر، لا تتم مشاركة معلومات الموقع الجغرافي مع المستخدم النهائي. على سبيل المثال، يتم إخفاء موقع مركبة التوصيل عن مديري الأسطول باستخدام مكتبة تتبع الأسطول.

مهام التوقف المجدوَلة

يمكنك إنشاء مهام توقّف مُجدوَلة لوضع نماذج للمحطات التي ستنتجها مركبة توصيل. على سبيل المثال، يمكنك إنشاء مهمة توقّف مجدولة لمحطة جمع مجدوَلة يومية في موقع جغرافي معيّن، بعيدًا عن عمليات التسليم الأخرى أو الاستلام في الموقع الجغرافي نفسه. يمكنك أيضًا إنشاء مهام توقّف مجدولة للمجموعات من الصناديق البريدية المخصصة للمركبات أو لوضع نماذج لعمليات نقل مركبات التغذية أو المحطات في مراكز الخدمة ونقاط الخدمة.

يمكنك الاطّلاع على الحقول المحددة المضمَّنة في كل بنية بيانات من خلال الاطّلاع على المستندات المرجعية لواجهة برمجة التطبيقات في DeliveryVehicle (gRPC وREST) وTask (gRPC وREST).

إرشادات معرّف المهمّة

يجب أن تكون معرّفات المهام فريدة ويجب ألا تكشف عن أي معلومات لتحديد الهوية الشخصية أو بيانات نصية واضحة. يجب أن تتوافق معرفات المهام أيضًا مع متطلبات التنسيق التالية:

فيما يلي بعض الأمثلة على معرفات المهام الجيدة:

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

يوضح الجدول التالي أمثلة لمعرّفات المهام غير الصالحة:

معرّفات المهام غير الصالحة السبب
31/8/2019-20:48-46.70746,-130.10807,-85.17909,61.33680 يخالف معلومات تحديد الهوية الشخصية ومتطلبات الأحرف: الفواصل والنقاط والنقطتان والشرطات المائلة.
JohnDoe-577b484da26f-كوبرتينو-سانتا كروز يخالف متطلبات معلومات تحديد الهوية الشخصية.
4R0oXLToF”112 Summer Dr. East Hartford, CT06118”577b484da26f8a يخالف معلومات تحديد الهوية الشخصية ومتطلبات الأحرف: المسافات البيضاء والفواصل وعلامات الاقتباس. أطول من 64 حرفًا.

مدة تشغيل المركبة

يمثّل الكائن DeliveryVehicle مركبة توصيل من الميل الأول أو الأخير. يمكنك إنشاء كائن DeliveryVehicle باستخدام:

  • رقم تعريف المشروع لمشروع Google Cloud الذي يحتوي على حساب الخدمة المستخدم لاستدعاء واجهات برمجة تطبيقات Fleet Engine.
  • رقم تعريف مركبة يملكها العميل.

يجب أن تكون معرّفات المركبات فريدة لكل مركبة. ولا يجب إعادة استخدامها لمركبة مختلفة ما لم تكن هناك مهام نشطة لتلك المركبة.

احرص على البحث عن الخطأ NOT_FOUND عند إجراء اتصال برقم UpdateDeliveryVehicle ثم، إذا لزم الأمر، اتصل برقم CreateDeliveryVehicle لإنشاء مركبة جديدة. ويتم حذف عنصر DeliveryVehicle الذي لم يتم تعديله باستخدام UpdateDeliveryVehicle تلقائيًا بعد سبعة أيام. يُرجى العِلم أنّ طلب الرمز CreateDeliveryVehicle باستخدام رقم تعريف المشروع/رقم تعريف المركبة المتوفّر يؤدّي إلى حدوث خطأ.

سمات المركبات

يحتوي الكيان DeliveryVehicle على حقل متكرّر للسمة DeliveryVehicleAttribute. تشمل واجهة برمجة التطبيقات ListDeliveryVehicles حقل filter الذي يمكنه حصر عناصر DeliveryVehicle التي تم عرضها على العناصر التي تتضمّن السمات المحددة، مع العلم بأنّ DeliveryVehicleAttribute لا تؤثر في سلوك التوجيه في Fleet Engine.

لا تضمِّن معلومات تحديد الهوية الشخصية أو معلومات حساسة في السمات، لأنّ هذا الحقل قد يكون مرئيًا للمستخدمين.

مدة المهمة

يمكن إنشاء المهام في Fleet Engine وتحديثها والتحقيق فيها باستخدام واجهات gRPC أو REST لواجهة برمجة التطبيقات Deliveries API.

يحتوي الكائن Task على حقل حالة لتتبُّع مستوى تقدُّمه خلال مراحل نشاطه. تنتقل القيم من OPEN إلى CLOSED. يتم إنشاء مهام جديدة في الحالة OPEN، مما يشير إلى أي مما يلي:

  • لم يتم تعيين المهمة بعد لمركبة توصيل.
  • لم تجتز مركبة التسليم بعد المحطة المخصصة للمهمة.

لا يمكن تعيين مهمة لمركبة إلا عندما تكون في حالة الوضع المفتوح.

يمكن إلغاء مهمة عن طريق إزالتها من قائمة محطات المركبات. بعد ذلك، يتم ضبط حالتها تلقائيًا على "مغلقة".

عندما تكمل مركبة المهمة توقف مركبة المهمة، قم بتحديث حقل النتيجة للمهمة إما إلى SUCCEEDED أو "تعذّر" وتحديد الطابع الزمني للحدث. يمكن تحديد نتيجة المهمة في أي وقت قبل أو بعد اكتمال المهمة، ولكن يمكن تحديدها مرة واحدة فقط.

يمكن لمكتبة تتبع أسطول JavaScript أن تشير بعد ذلك إلى نتيجة المهمة. يتم ضبط حالة المهمة تلقائيًا على "مغلقة". لمزيد من المعلومات، يُرجى الاطّلاع على مقالة تتبُّع مجموعة الأجهزة باستخدام مكتبة تتبُّع مجموعة JavaScript.

كما هو الحال مع المركبات، يتم حذف المهام التي لم يتم تحديثها بعد سبعة أيام، وعند محاولة إنشاء مهمة بمعرف موجود بالفعل، يتم عرض خطأ.

ملاحظة: لا يتيح Fleet Engine حذف مهمة بشكل صريح. تحذف الخدمة المهام تلقائيًا بعد سبعة أيام بدون تحديثات. إذا كنت تريد الاحتفاظ ببيانات المهمة لأكثر من سبعة أيام، فيجب عليك تنفيذ هذه الوظيفة بنفسك.

سمات المهام

يحتوي الكيان Task على حقل متكرّر للسمة TaskAttribute، والذي يمكن أن يكون له قيمة من أحد الأنواع الثلاثة: سلسلة ورقم وقيمة منطقية. تتضمن واجهة برمجة التطبيقات ListTasks حقل filter يمكنه حصر عناصر Task التي يتم عرضها على العناصر التي تتضمن السمات المحددة، مع العِلم بأنّ TaskAttribute لا تؤثر في سلوك توجيه Fleet Engine.

لا تضمِّن معلومات تحديد الهوية الشخصية أو معلومات حساسة في السمات، لأنّ هذا الحقل قد يكون مرئيًا للمستخدمين.

إدارة دورة حياة المركبات والمهام

لإدارة دورات حياة المركبات والمهام في نظامك، تستخدم واجهة برمجة التطبيقات Fleet Engine Deliveries API لإنشاء وتحديث وتتبع مركباتك والمهام المرتبطة بها. يعمل نظامك الداخلي كمصدر موثوق للبيانات التي تعززها واجهة برمجة تطبيقات Fleet Engine Deliveries API بالنيابة عنك.

في الوقت نفسه، يتواصل تطبيق برنامج التشغيل مباشرةً مع Fleet Engine لأغراض تحديث معلومات موقع الجهاز ومساره. ويتيح هذا النموذج لـ Fleet Engine إدارة الموقع في الوقت الفعلي بكفاءة وإرسال ذلك مباشرة إلى مكتبة التتبع، التي يمكنك استخدامها بعد ذلك للمستهلكين الذين يحتاجون إلى تحديثات حالة طلباتهم.

على سبيل المثال، لنفترض أن لديك السيناريو التالي:

  • يقترب سائق من محطة تسليم ويرسل Fleet Engine موقع الجهاز إلى مكتبة التتبع، التي يستخدمها تطبيق المستهلك لتنبيه المستهلك إلى قرب طرده.
  • بعد أن يكمل السائق الشحنة، ينقر على زر "تم تسليم الشحنة" في تطبيق السائق.
  • يؤدي ذلك إلى إرسال المعلومات إلى نظام الخلفية، الذي ينفذ الخطوات اللازمة للتحقق من صحة النشاط التجاري والتحقق منه.
  • يؤكد نظامك المهمة على أنها SUCCEEDED ويحدث Fleet Engine باستخدام واجهة برمجة تطبيقات Deliveries.

ويوضح الرسم البياني التالي هذه العمليات على مستوى عام. كما يعرض العلاقة القياسية بين نظامك والعميل وFleet Engine.

دمج الرسم التخطيطي لواجهة برمجة تطبيقات Deliveries

إدارة الرموز المميّزة للعميل

تتطلب أي تحديثات للموقع تنشأ من تطبيق برنامج التشغيل ويتم إرسالها مباشرةً إلى Fleet Engine وجود رموز تفويض. النهج الموصى به للتعامل مع التحديثات من البرنامج إلى Fleet Engine هو تزويد تطبيق برنامج التشغيل برمز مميز للنطاق المحدود بحيث يمكنه فقط تحديث موقع الجهاز في Fleet Engine. بالنسبة إلى هذا النوع من الرموز المميّزة، يمكنك استخدام دور حساب خدمة يُعرف باسم مستخدم Drive غير موثوق به لتسليم محرك الأقراص. وهذا يضمن أن تلتزم المكالمات التي تنشأ من الأجهزة الجوّالة، التي تعتبر بيئات منخفضة الثقة، بمبدأ الامتياز الأقل.

أدوار حساب الخدمة الأخرى

إذا كنت تريد بدلاً من ذلك السماح لتطبيقات برنامج التشغيل بإجراء تحديثات مباشرة على Fleet Engine غير تلك المخصّصة لدور "سائق غير موثوق به" كما هو الحال بالنسبة إلى تحديثات معيّنة للمهام، يمكنك استخدام دور "السائق الموثوق به". للحصول على معلومات عن الطراز الذي يستخدم دور "السائق الموثوق به"، راجِع نموذج برنامج التشغيل الموثوق به.

لمزيد من المعلومات عن استخدامات أدوار السائق الموثوق بها وغير الموثوق بها، يُرجى الاطّلاع على إعداد المشروع على السحابة الإلكترونية.

وضع نماذج يوم العمل

يصف الجدول التالي كيف يمكن أن يبدو يوم العمل للسائقين من مواصلات الانطلاق أو الانطلاق في رحلاتهم الأخيرة في شركة توصيل وخدمات لوجستية. قد تختلف شركتك في التفاصيل، ولكن يمكنك أن ترى كيف يمكنك تصميم نموذج ليوم العمل.

الوقتنشاطوضع النماذج
خلال 24 ساعة من بداية اليوم يقوم المرسل بتعيين الشحنات لمركبات التوصيل أو مسارات التوصيل. قد يتم إنشاء مهام تسليم الشحنات واستلام الطلبات والاستراحة وما إلى ذلك في Fleet Engine مسبقًا. على سبيل المثال، يمكنك إنشاء مهمة لاستلام الشحن أو مهمة تسليم الشحن أو عدم توفّر الخدمة في موعد محدّد أو محطة مُجدوَلة.

يجب إسناد المهام إلى مركبة بعد الانتهاء من مجموعة طرود التسليم وترتيب التسليم.
بداية اليوم يبدأ السائق اليوم في المستودع من خلال تسجيل الدخول إلى تطبيق Driver. إعداد Delivery Driver API أنشئ مركبة توصيل في Fleet Engine حسب الحاجة.
يقوم السائق بتحميل الشحنات على مركبة التسليم، ثم مسح الشحنات ضوئيًا. إذا لم يتم إنشاء مهام تسليم الشحن مسبقًا، يمكنك إنشاء مهام تسليم الشحن في وقت الفحص.
يؤكد السائق ترتيب المهام التي سيتم تنفيذها. إذا لم يتم إنشاؤها مسبقًا، يمكنك إنشاء مهام استلام الشحنة وعدم التوفّر المجدوَل ومحطات التوقّف المجدولة.
يغادر السائق المستودع ويلتزم بالعدد التالي من المهام التي ستخضع للمنافسة. إسناد جميع المهام أو مجموعة فرعية من المهام إلى المركبة من خلال تنفيذ أمر إكمالها.
السائق يسلم شحنة. بعد الوصول إلى محطة التسليم، اتّخِذ الإجراءات المتعلّقة بوصول مركبة إلى محطة تسليم. بعد تسليم الشحنة، أغلِق مَهمّة التسليم، ويمكنك اختيار حالة الشحن إلى المتجر وغيرها من المعلومات الوصفية إذا أردت. بعد إكمال جميع المهام عند المحطة وقبل البدء في القيادة إلى المحطة التالية، يمكنك تنفيذ الإجراءات المتعلقة بإكمال المركبة لإيقاف التوقّف والمركبة في طريقها إلى المحطة التالية.
يلتقي السائق بمركبة تغذية لنقل شحنات إضافية إلى مركبة التسليم. يجب تحديد صيغة نقطة الاجتماع المخصّصة للنقل بين مركبات التغذية ومركبات التسليم على أنها محطة توقف مجدولة.

بعد نقل عمليات الشحن وفحصها، يمكنك إنشاء مهام التسليم إذا لم يسبق إنشاؤها. بعد ذلك، يمكنك تعديل ترتيب إكمال المهام من خلال إسناد المهام لمركبة وتعديل ترتيب المهام.
يتلقى السائق إشعارًا بطلب الاستلام. بعد قبول طلب الاستلام، عليك إنشاء مهمة استلام الطلب. بعد ذلك، يمكنك تعديل ترتيب تنفيذ المهام من خلال إسناد المهام لمركبة وتعديل ترتيب المهام.
وقت الظهر يأخذ السائق استراحة الغداء. إذا كان موقع جغرافي مرتبطًا بالمهمة غير المتوفّرة، تعامل معها كأي مهمة أخرى. تنفيذ إجراءات تتعلّق بمركبة تصل إلى محطة معيّنة وإكمال المركبة والمركبة في طريقها إلى المحطة التالية

وبخلاف ذلك، لا يلزم اتخاذ أي إجراء آخر حتى نهاية الفاصل. يمكنك إزالة المهمة من خلال تأكيد المهام التالية والمتبقية وتعديل ترتيب المهام.
يلتقط السائق شحنة. يشبه هذا محطة التسليم تمامًا. تنفيذ الإجراءات ذات الصلة بالمركَبة التي ستصل إلى محطة وإغلاق مهمة، واختيار حفظ حالة الشحن وغيرها من المعلومات الوصفية إذا أردتَ بعد إكمال جميع المهام عند المحطة وقبل البدء في القيادة إلى المحطة التالية، يمكنك تنفيذ الإجراءات المتعلقة بإكمال المركبة لإيقافها والمركبة في طريقها إلى المحطة التالية. ملاحظة: لضمان دقة معلومات الفوترة، يجب أن يتم في كل طلبات استلام الطلبات مهمة تسليم مقابلة. إذا كان سيتم تسليم الطرد إلى موقع جغرافي آخر على المسار نفسه في ذلك اليوم، ننصحك بإنشاء نموذج لمهمة التسليم هذه كأي مهمة تسليم أخرى على المسار. إذا كان السائق سيعيد استلام الطرد إلى المستودع، ننصحك بإنشاء مَهمّة توصيل في وجهة المستودع.
يقوم السائق بإجراء محطة محددة لاستلام الشحنات من صندوق إيداع. يشبه هذا النموذج أي محطة نقل أخرى. تنفيذ إجراءات تتعلّق بمركبة ستصل إلى محطة وإغلاق مهمة بعد إكمال جميع المهام عند المحطة والبدء في القيادة إلى المحطة التالية، نفِّذ الإجراءات المتعلقة بإكمال المركبة المتوقفة والمركبة في طريقها إلى المحطة التالية.
سيتلقى السائق إشعارًا بتحويل شحنة إلى مكان بديل. اضبط حالة مهمة تسليم الشحنة الأصلية على "مكتملة" وأنشئ مهمة تسليم شحن جديدة لموقع التسليم الجديد. لمزيد من المعلومات، يُرجى الاطّلاع على إعادة توجيه الشحنة.
حاول السائق تسليم طرد ولكنه لم يتمكن من القيام بذلك. تم تصميم ذلك على غرار محطة تسليم ناجحة، ما يشير إلى اكتمال مهمة التسليم. تنفيذ إجراءات تتعلّق بمركبة ستصل إلى محطة معيّنة بعد عدم تسليم الشحنة، أغلِق المهمة وحالة الشحن إلى المتجر والمعلومات الوصفية الأخرى إذا أردت. بعد إكمال جميع المهام عند المحطة وقبل البدء في القيادة إلى المحطة التالية، يمكنك تنفيذ الإجراءات المتعلقة بإكمال المركبة لإيقافها والمركبة في طريقها إلى المحطة التالية.
تم إبلاغ السائق لحجز (عدم تسليم) شحنة. بعد تلقّي الإشعار وتأكيده، اضبط حالة المهمة على "مكتملة".
تم إبلاغ السائق بتسليم شحنة معينة بعد ذلك، مما أدى إلى تغيير طلب التسليم الملتزم. تعديل ترتيب المهام
يختار السائق تسليم شحنة خارج الطلب. عدِّل ترتيب المهام ثم المتابعة كالمعتاد.
يسلم السائق شحنات متعددة إلى موقع واحد. يتم وضع نموذج مشابه لمحطة تسليم شحنة واحدة. بعد الوصول إلى المحطة، اتّخِذ الإجراءات المناسبة لوصول مركبة إلى محطة معيّنة. بعد تسليم كل شحنة، أغلِق كل مهمة، ويمكنك اختيار حالة الشحن إلى المتجر وغيرها من المعلومات الوصفية إذا أردت. بعد إكمال جميع المهام عند المحطة وقبل البدء في القيادة إلى المحطة التالية، يمكنك تنفيذ الإجراءات المتعلقة بإكمال المركبة لإيقافها والمركبة في طريقها إلى المحطة التالية.
نهاية اليوم يعود السائق إلى المستودع. إذا عاد السائق إلى المستودع واستلام الشحنات خلال مساره، عليك أيضًا إنشاء كل طرد وإغلاقه كمهمة تسليم لضمان صحة الفوترة. يمكنك إجراء ذلك من خلال تصميم مستودع مثل أي محطة تسليم أخرى. إذا لم يكن المستودع قيد الاستخدام كمحطة تسليم، يمكنك اختيار نموذج للمستودع على أنّه محطة مُجدوَلة. سيتيح ذلك للسائقين الاطّلاع على مسار العودة إلى المستودع ومنحهم إذن الوصول المقدر إلى المستودع.

فهم تحديثات الموقع الجغرافي

يتم إرسال تحديثات الموقع الجغرافي إلى Fleet Engine بعد أن تكون مركبة التوصيل على الطريق من المحطة (بما في ذلك المستودع) حتى تصل في المحطة التالية. ولأن هذه الأحداث لا يتم رصدها تلقائيًا، يجب وضع علامة عليها آليًا. استخدم المكتبات التي تكتشف التغييرات في وسيلة النقل لبدء إرسال الإشعارات المطلوبة إلى Fleet Engine.

يجب تعليق تحديثات الموقع عندما لا يكون السائق يقودًا لأن جودة إشارات الموقع تقلل بشكل كبير عندما يكون شخص داخل مبنى.

يمكن تحديد معدّل تعديل الموقع الجغرافي ضمن "حزمة تطوير البرامج (SDK) لنظام التشغيل". يتم بشكل افتراضي إرسال التحديثات كل 10 ثوانٍ.

محطات توقّف المركبات ومواقع التسليم

محطة المركبة هي المكان الذي تكمل فيه مركبة توصيل مهمة الشحن أو بعض المهام الأخرى. وهي إما نقطة وصول مثل رصيف تحميل أو موقع تم التقاطه بطريق.

موقع التسليم هو الموقع الذي يتم فيه تسليم الشحنة أو استلامها. قد يتطلب الوصول إلى موقع التسليم ومنه بعض المشي من محطة المركبة.

على سبيل المثال، عندما يسلّم سائق شحنة إلى متجر في مركز تجاري، تتوقف مركبة التوصيل في موقف السيارات في المركز التجاري بالقرب من أقرب مدخل للمتجر. هذه هي محطة المركبة. ثم يسير السائق من محطة المركبات إلى الموقع داخل المركز التجاري حيث يوجد المتجر. هذا هو الموقع الجغرافي للتسليم.

للحصول على أفضل تجربة لتتبع الشحن للمستخدمين، ضع في اعتبارك كيفية تعيين مهام الشحن لمحطات المركبات وتذكر أنه يتم إبلاغ المستخدم بعدد محطات التوقف المتبقية للمركبات لمهام الشحن لمساعدته في عرض التقدم المحرز في الشحن.

على سبيل المثال، إذا كان السائق يقوم بالعديد من عمليات التوصيل إلى مبنى مكتبي واحد، ففكر في تعيين جميع مهام التوصيل لمحطة واحدة للمركبة. إذا تم إسناد كل مهمة تسليم إلى محطة مركبة خاصة بها، فستكون تجربة تتبع الشحن الخاصة بك أقل فائدة للمستخدمين لأن التتبع لا يتوفر إلا بمجرد أن تكون المركبة ضمن عدد محدود من محطات التوقف قبل وجهتها. إن اكتمال العديد من محطات التوقف للمركبات في وقت قصير لن يمنح المستخدم الكثير من الوقت لتتبعه لتتبع تقدم عملية التسليم.

استخدام حزم تطوير البرامج (SDK) للأجهزة الجوّالة

قبل إجراء أي استدعاءات باستخدام حزمة تطوير البرامج (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

لإنشاء مركبة جديدة، عليك إجراء اتصال عبر CreateDeliveryVehicle مع Fleet Engine. استخدم الكائن CreateDeliveryVehicleRequest لتحديد سمات مركبة التسليم الجديدة. تجدر الإشارة إلى أنّه سيتم تجاهل أي قيمة محدّدة للحقل Name وفقًا لإرشادات واجهة برمجة التطبيقات لأرقام التعريف المحدّدة من جانب المستخدم. يجب استخدام الحقل DeliveryVehicleId لضبط رقم تعريف المركبة.

عند إنشاء DeliveryVehicle، يمكنك اختياريًا تحديد حقلَين:

  • السمات
  • الموقع الجغرافي الأخير

يجب عدم ضبط جميع الحقول الأخرى، وإلا سيعرض Fleet Engine خطأ لأن هذه الحقول إما للقراءة فقط أو لا يمكن تعديلها إلا من خلال استدعاءات UpdateDeliveryVehicle.

لإنشاء مركبة بدون ضبط أي حقول اختيارية، يمكنك ترك الحقل DeliveryVehicle بدون ضبط في CreateDeliveryVehicleRequest.

يوضّح المثال التالي كيفية استخدام مكتبة Java gRPC لإنشاء مركبة:

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

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

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

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

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

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

راحة

لإنشاء مركبة من بيئة خادم، عليك إجراء استدعاء HTTP REST إلى CreateDeliveryVehicle:

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

<id> هو معرِّف فريد لمركبة توصيل في أسطولك.

يجب أن يحتوي عنوان الطلب على حقل التفويض مع القيمة الحامل <token>، حيث يكون <token> رمزًا مميّزًا تم صكه من قِبل مصنع الرموز المميّزة Fleet Engine.

يمثل نص POST الكيان DeliveryVehicle الذي سيتم إنشاؤه. يمكنك تحديد الحقول الاختيارية التالية:

  • attributes
  • الموقع الجغرافي الأخير

مثال على أمر 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 وفقًا لإرشادات واجهة برمجة التطبيقات للأرقام التعريفية المحددة من قِبل المستخدم. يجب عدم ضبط جميع الحقول الأخرى، وإلا سيعرض Fleet Engine رسالة خطأ لأن هذه الحقول إما للقراءة فقط أو لا يمكن تعديلها إلا من خلال استدعاءات UpdateDeliveryVehicle.

لإنشاء مركبة بدون ضبط أي حقول، يمكنك ترك نص طلب POST فارغًا. سيكون للمركبة التي تم إنشاؤها حديثًا رقم تعريف مركبة مستخرج من المَعلمة deliveryVehicleId في عنوان URL للمشاركة.

مثال على أمر 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}"

إنشاء مهمة استلام الشحنة

يمكنك إنشاء مهمة لاستلام الشحنة إما من حزمة تطوير البرامج (SDK) لبرنامج التشغيل) أو من بيئة الخادم.

gRPC

يوضح المثال التالي كيفية استخدام مكتبة Java gRPC لإنشاء مهمة استلام الشحن:

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

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Task settings
String parent = "providers/" + PROJECT_ID;
Task task = Task.newBuilder()
  .setType(Task.Type.PICKUP)
  .setState(Task.State.OPEN)
  .setTrackingId("my-tracking-id")
  .setPlannedLocation(               // Grand Indonesia East Mall
    LocationInfo.newBuilder().setPoint(
      LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
  .setTaskDuration(
    Duration.newBuilder().setSeconds(2 * 60))
  .setTargetTimeWindow(
    TimeWindow.newBuilder()
      .setStartTime(Timestamp.newBuilder().setSeconds(1680123600))
      .setEndTime(Timestamp.newBuilder().setSeconds(1680130800)))
  .addAttributes(TaskAttribute.newBuilder().setKey("foo").setStringValue("value"))
  .addAttributes(TaskAttribute.newBuilder().setKey("bar").setNumberValue(10))
  .addAttributes(TaskAttribute.newBuilder().setKey("baz").setBoolValue(false))
  .build();

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

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

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

راحة

لإنشاء مهمة استلام شحنة من بيئة خادم، عليك إجراء استدعاء HTTP REST إلى `CreateTask':

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

<id> هو معرِّف فريد للمهمة. يجب ألا يكون رقم تتبع الشحنة. إذا لم يكن لديك معرِّفات مهام في نظامك، يمكنك إنشاء معرِّف فريد عالمي (UUID).

يجب أن يحتوي عنوان الطلب على حقل التفويض مع القيمة الحامل <token>، حيث يكون <token> رمزًا مميّزًا تم صكه من قِبل مصنع الرموز المميّزة Fleet Engine.

يجب أن يحتوي نص الطلب على كيان Task:

  • الحقول المطلوبة:

    الحقلالقيمة
    كتابة النوع.PICKUP
    ولاية ولاية.مفتوح
    رقم تعريف التتبع الرقم أو المعرّف المستخدَم لتتبّع شحنة
    الموقع الجغرافي المخطط له تمثّل هذه السمة الموقع الجغرافي الذي سيتم فيه إنجاز المهمة، وفي هذه الحالة الموقع الجغرافي لاستلام الشحن.
    taskDuration الوقت المتوقّع، بالثواني، الذي سيستغرقه استلام الشحنة في الموقع الجغرافي للاستلام.

  • الحقول الاختيارية:

    الحقلالقيمة
    targetTimeWindow الفترة الزمنية التي يجب إكمال المهمة خلالها. ولا يؤثر ذلك حاليًا في سلوك التوجيه.
    attributes قائمة بسمات المهام المخصّصة يجب أن يكون لكل سمة مفتاح فريد.

ويتم تجاهل جميع الحقول الأخرى في الكيان عند إنشائها. يقدم Fleet Engine استثناءً إذا كان الطلب يتضمن معلمة التسليمVehicleId المخصصة. يمكنك إسناد المهام باستخدام UpdateDeliveryVehicleRequests. لمزيد من المعلومات، اطّلِع على إسناد المهام لمركبة.

مثال على أمر curl:

# Set $JWT, $PROJECT_ID, $TRACKING_ID, and $TASK_ID in the local
# environment
curl -X POST "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks?taskId=${TASK_ID}" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "type": "PICKUP",
  "state": "OPEN",
  "trackingId": "${TRACKING_ID}",
  "plannedLocation": {
     "point": {
        "latitude": -6.195139,
        "longitude": 106.820826
     }
  },
  "taskDuration": "90s",
  "targetTimeWindow": {
    "startTime": "2023-03-29T21:00:00Z",
    "endTime": "2023-03-29T23:00:00Z"
  }
}
EOM

إنشاء مهمة تسليم شحنة

يمكنك إنشاء مهمة تسليم شحن إما من حزمة SDK لبرنامج التشغيل أو من بيئة الخادم.

gRPC

يوضح المثال التالي كيفية استخدام مكتبة Java gRPC لإنشاء مهمة تسليم الشحن:

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

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Task settings
String parent = "providers/" + PROJECT_ID;
Task task = Task.newBuilder()
  .setType(Task.Type.DELIVERY)
  .setState(Task.State.OPEN)
  .setTrackingId("my-tracking-id")
  .setPlannedLocation(               // Grand Indonesia East Mall
    LocationInfo.newBuilder().setPoint(
      LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
  .setTaskDuration(
    Duration.newBuilder().setSeconds(2 * 60))
  .setTargetTimeWindow(
    TimeWindow.newBuilder()
      .setStartTime(Timestamp.newBuilder().setSeconds(1680123600))
      .setEndTime(Timestamp.newBuilder().setSeconds(1680130800)))
  .addAttributes(TaskAttribute.newBuilder().setKey("foo").setStringValue("value"))
  .addAttributes(TaskAttribute.newBuilder().setKey("bar").setNumberValue(10))
  .addAttributes(TaskAttribute.newBuilder().setKey("baz").setBoolValue(false))
  .build();

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

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

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

راحة

لإنشاء مهمة تسليم شحن من بيئة خادم، قم بإجراء استدعاء HTTP REST إلى `CreateTask':

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

<id> هو معرِّف فريد للمهمة. يجب ألا يكون رقم تتبع الشحنة. إذا لم يكن لديك معرِّفات مهام في نظامك، يمكنك إنشاء معرِّف فريد عالمي (UUID).

يجب أن يحتوي عنوان الطلب على حقل التفويض مع القيمة الحامل <token>، حيث يكون <token> رمزًا مميّزًا تم صكه من قِبل مصنع الرموز المميّزة Fleet Engine.

يجب أن يحتوي نص الطلب على كيان Task:

  • الحقول المطلوبة:

    الحقلالقيمة
    كتابة النوع.DELIVERY
    ولاية ولاية.مفتوح
    رقم تعريف التتبع الرقم أو المعرّف المستخدَم لتتبّع شحنة
    الموقع الجغرافي المخطط له الموقع الذي سيتم فيه إنجاز المهمة، في هذه الحالة موقع التسليم لهذه الشحنة.
    taskDuration الوقت المتوقّع بالثواني لتسليم الشحنة في موقع التسليم

  • الحقول الاختيارية:

    الحقلالقيمة
    targetTimeWindow الفترة الزمنية التي يجب إكمال المهمة خلالها. ولا يؤثر ذلك حاليًا في سلوك التوجيه.
    attributes قائمة بسمات المهام المخصّصة يجب أن يكون لكل سمة مفتاح فريد.

ويتم تجاهل جميع الحقول الأخرى في الكيان عند إنشائها. يقدم Fleet Engine استثناءً إذا كان الطلب يتضمن معلمة التسليمVehicleId المخصصة. يمكنك إسناد المهام باستخدام UpdateDeliveryVehicleRequests. لمزيد من المعلومات، اطّلِع على إسناد المهام لمركبة.

مثال على أمر curl:

# Set $JWT, $PROJECT_ID, $TRACKING_ID, and $TASK_ID in the local
# environment
curl -X POST "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks?taskId=${TASK_ID}" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "type": "DELIVERY",
  "state": "OPEN",
  "trackingId": "${TRACKING_ID}",
  "plannedLocation": {
     "point": {
        "latitude": -6.195139,
        "longitude": 106.820826
     }
  },
  "taskDuration": "90s",
  "targetTimeWindow": {
    "startTime": "2023-03-29T21:00:00Z",
    "endTime": "2023-03-29T23:00:00Z"
  }
}
EOM

إنشاء مهام مجمّعة

يمكنك إنشاء مجموعة من المهام من بيئة الخادم.

gRPC

يوضّح المثال التالي كيفية استخدام مكتبة Java gRPC لإنشاء مهمتَين، إحداهما للتسليم والأخرى للاستلام في الموقع الجغرافي نفسه:

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

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Delivery Task settings
Task deliveryTask = Task.newBuilder()
  .setType(Task.Type.DELIVERY)
  .setState(Task.State.OPEN)
  .setTrackingId("delivery-tracking-id")
  .setPlannedLocation(               // Grand Indonesia East Mall
    LocationInfo.newBuilder().setPoint(
      LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
  .setTaskDuration(
    Duration.newBuilder().setSeconds(2 * 60))
  .build();

// Delivery Task request
CreateTaskRequest createDeliveryTaskRequest =
  CreateTaskRequest.newBuilder()  // No need for the header or parent fields
      .setTaskId("task-8312508")  // Task ID assigned by the Provider
      .setTask(deliveryTask)      // Initial state
      .build();

// Pickup Task settings
Task pickupTask = Task.newBuilder()
  .setType(Task.Type.PICKUP)
  .setState(Task.State.OPEN)
  .setTrackingId("pickup-tracking-id")
  .setPlannedLocation(               // Grand Indonesia East Mall
    LocationInfo.newBuilder().setPoint(
      LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
  .setTaskDuration(
    Duration.newBuilder().setSeconds(2 * 60))
  .build();

// Pickup Task request
CreateTaskRequest createPickupTaskRequest =
  CreateTaskRequest.newBuilder()  // No need for the header or parent fields
      .setTaskId("task-8241890")  // Task ID assigned by the Provider
      .setTask(pickupTask)        // Initial state
      .build();

// Batch Create Tasks settings
String parent = "providers/" + PROJECT_ID;

// Batch Create Tasks request
BatchCreateTasksRequest batchCreateTasksRequest =
  BatchCreateTasksRequest.newBuilder()
      .setParent(parent)
      .addRequests(createDeliveryTaskRequest)
      .addRequests(createPickupTaskRequest)
      .build();

// Error handling
// If Fleet Engine does not have any task(s) with these task ID(s) and the
// credentials of the requestor pass, the service creates the task(s)
// successfully.

try {
  BatchCreateTasksResponse createdTasks = deliveryService.batchCreateTasks(
    batchCreateTasksRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
     case ALREADY_EXISTS:
       break;
     case PERMISSION_DENIED:
       break;
  }
  return;
}

راحة

لإنشاء مهمة تسليم واستلام من بيئة الخادم، عليك إجراء استدعاء HTTP REST إلى BatchCreateTasks:

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

يجب أن يحتوي عنوان الطلب على حقل التفويض مع القيمة حامل <token>، حيث <token> هو رمز مميّز تم صكه من قِبل مصنع الرموز المميّزة Fleet Engine.

يجب أن يحتوي نص الطلب على كيان BatchCreateTasksRequest:

  • الحقول المطلوبة:

    الحقلالقيمة
    طلبات مصفوفة<CreateTasksRequest>

  • الحقول الاختيارية:

    الحقلالقيمة
    header `DeliveryRequestHeader`

يجب أن يجتاز كل عنصر CreateTasksRequest في requests قواعد التحقّق نفسها في الطلب CreateTask، باستثناء أنّ الحقلَين parent وheader اختياريَين. وفي حال ضبط هذه السياسة، يجب أن تكون متطابقة مع الحقول الخاصة بها في المستوى الأعلى من BatchCreateTasksRequest. يمكنك الاطّلاع على إنشاء مهمة استلام شحنة وإنشاء مهمة تسليم شحن لقواعد التحقق المحددة لكل منها.

لمزيد من المعلومات، اطّلِع على المستندات المرجعية لواجهة برمجة التطبيقات الخاصة بـ 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

عدم التوفُّر المُجدوَل

يمكنك إنشاء مهمة تشير إلى عدم التوفُّر (على سبيل المثال، حالات توقف السائق أو إعادة وقود السيارة) إما من حزمة تطوير البرامج (SDK) للسائق أو من بيئة الخادم. يجب ألا تتضمّن مهمة عدم التوفّر المُجدوَلة رقم تعريف تتبّع. يمكنك إدخال موقع جغرافي بشكل اختياري.

gRPC

يوضّح المثال التالي كيفية استخدام مكتبة Java gRPC لإنشاء مهمة غير متوفّرة:

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

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

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

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

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

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

راحة

لإنشاء مهمة عدم التوفّر من بيئة الخادم، عليك إجراء استدعاء HTTP REST إلى `CreateTask':

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

<id> هو معرِّف فريد للمهمة. إذا لم يكن لديك معرِّفات مهام في نظامك، يمكنك إنشاء معرِّف فريد عالمي (UUID).

يجب أن يحتوي عنوان الطلب على حقل التفويض مع القيمة الحامل <token>، حيث يكون <token> رمزًا مميّزًا تم صكه من قِبل مصنع الرموز المميّزة Fleet Engine.

يجب أن يحتوي نص الطلب على كيان Task:

  • الحقول المطلوبة:

    الحقلالقيمة
    كتابة النوع.UNAVAILABLE
    ولاية ولاية.مفتوح
    taskDuration مدة الفاصل بالثواني.

  • الحقول الاختيارية:

    الحقلالقيمة
    الموقع الجغرافي المخطط له تمثّل هذه السمة موقع استراحة إذا كان يجب أخذها في موقع جغرافي معيّن.

ويتم تجاهل جميع الحقول الأخرى في الكيان عند إنشائها. يقدم Fleet Engine استثناءً إذا كان الطلب يتضمن معلمة التسليمVehicleId المخصصة. يمكنك إسناد المهام باستخدام UpdateDeliveryVehicleRequests. لمزيد من المعلومات، اطّلِع على إسناد المهام لمركبة.

مثال على أمر curl:

# Set $JWT, $PROJECT_ID, and $TASK_ID in the local environment
curl -X POST "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks?taskId=${TASK_ID}" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "type": "UNAVAILABLE",
  "state": "OPEN",
  "plannedLocation": {
     "point": {
        "latitude": -6.195139,
        "longitude": 106.820826
     }
  },
  "taskDuration": "300s"
}
EOM

محطات التوقف المجدولة

يمكنك إنشاء مهمة إيقاف مُجدوَلة إما من حزمة تطوير البرامج (SDK) لبرنامج التشغيل) أو من بيئة الخادم. وقد لا تتضمن مهمة التوقف المجدولة رقم تعريف تتبع.

gRPC

يوضح المثال التالي كيفية استخدام مكتبة Java gRPC لإنشاء مهمة إيقاف مجدولة:

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

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Task settings
String parent = "providers/" + PROJECT_ID;
Task task = Task.newBuilder()
  .setType(Task.Type.SCHEDULED_STOP)
  .setState(Task.State.OPEN)
  .setPlannedLocation(               // Grand Indonesia East Mall
    LocationInfo.newBuilder().setPoint(
      LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
  .setTaskDuration(
    Duration.newBuilder().setSeconds(2 * 60))
  .build();

// Task request
CreateTaskRequest createTaskRequest =
  CreateTaskRequest.newBuilder()  // No need for the header
      .setParent(parent)
      .setTaskId("task-8241890")  // Task ID assigned by the Provider
      .setTrip(task)              // Initial state
      .build();

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

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

راحة

لإنشاء مهمة إيقاف مُجدوَلة من بيئة الخادم، عليك إجراء استدعاء HTTP REST إلى CreateTask:

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

<id> هو معرِّف فريد للمهمة. إذا لم يكن لديك معرِّفات مهام في نظامك، يمكنك إنشاء معرِّف فريد عالمي (UUID).

يجب أن يحتوي عنوان الطلب على حقل التفويض مع القيمة الحامل <token>، حيث يكون <token> رمزًا مميّزًا تم صكه من قِبل مصنع الرموز المميّزة Fleet Engine.

يجب أن يحتوي نص الطلب على كيان Task:

  • الحقول المطلوبة:

    الحقلالقيمة
    كتابة اكتب.SCHEDULED_STOP
    ولاية ولاية.مفتوح
    الموقع الجغرافي المخطط له موقع المحطة.
    taskDuration المدة المتوقعة للمحطة بالثواني.

  • الحقول الاختيارية:

    • لا ينطبق

ويتم تجاهل جميع الحقول الأخرى في الكيان عند إنشائها. يقدم Fleet Engine استثناءً إذا كان الطلب يتضمن معلمة التسليمVehicleId المخصصة. يمكنك إسناد المهام باستخدام UpdateDeliveryVehicleRequests. لمزيد من المعلومات، اطّلِع على إسناد المهام لمركبة.

مثال على أمر curl:

# Set $JWT, $PROJECT_ID, and $TASK_ID in the local environment
curl -X POST "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks?taskId=${TASK_ID}" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
  --data-binary @- << EOM
{
  "type": "SCHEDULED_STOP",
  "state": "OPEN",
  "plannedLocation": {
     "point": {
        "latitude": -6.195139,
        "longitude": 106.820826
     }
  },
  "taskDuration": "600s"
}
EOM

ضبط الفترة الزمنية المستهدَفة

الإطار الزمني المستهدَف هو TimeWindow الذي يجب إكمال المهمة خلاله. على سبيل المثال، إذا أعلمت مستلمي التسليم بالفترة الزمنية للتسليم، يمكنك استخدام النافذة الزمنية المستهدفة للمهمة لالتقاط هذه النافذة الزمنية وإنشاء تنبيهات أو تحليل أداء ما بعد الرحلة باستخدام الحقل.

تتألف الفترة الزمنية المستهدَفة من وقت بدء ووقت انتهاء، ويمكن ضبطها على أي نوع مهمة. لا تؤثر الفترة الزمنية المستهدفة حاليًا على سلوك التوجيه.

gRPC

يوضِّح المثال التالي كيفية استخدام مكتبة Java gRPC لتحديد فترة زمنية للمهمة:

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

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

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

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

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

راحة

لضبط نافذة لوقت المهمة باستخدام HTTP، يمكنك استدعاء UpdateTask:

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

<id> هو معرِّف فريد للمهمة.

يجب أن يحتوي عنوان الطلب على حقل التفويض مع القيمة الحامل <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;
}

راحة

لضبط نافذة إعدادات عرض تتبُّع المهام باستخدام HTTP، يمكنك استدعاء UpdateTask:

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

<id> هو معرِّف فريد للمهمة.

يجب أن يحتوي عنوان الطلب على حقل التفويض مع القيمة الحامل <token>، حيث يكون <token> رمزًا مميّزًا تم صكه من قِبل مصنع الرموز المميّزة Fleet Engine.

يجب أن يحتوي نص الطلب على كيان Task:

  • الحقول المطلوبة:

    الحقلالقيمة
    functionTrackingViewConfig إن التهيئة لتتبع المهام التي تحدد عناصر البيانات التي تظهر للمستخدمين النهائيين وتحت أي ظروف.

  • الحقول الاختيارية:

    • لا ينطبق

ويتم تجاهل جميع الحقول الأخرى في الكيان عند إجراء التعديل.

مثال على أمر 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

تعيين المهام لمركبة

يتم إسناد المهام لمركبة توصيل من خلال تعديل ترتيب المهام للمركبة. يتم تحديد ترتيب المهام للمركبة من خلال قائمة محطات التوقف للمركبة لمركبة التسليم. يمكن تعيين مهمة واحدة أو أكثر لكل محطة مركبة.

يؤدي تحديث ترتيب المهام لمهمة تم تعيينها مسبقًا لمركبة مختلفة إلى حدوث خطأ.

لتغيير شحنة من مركبة إلى أخرى، عليك إغلاق المهمة الأصلية ثم إعادة إنشائها قبل نقل المركبة الجديدة إليها.

تعديل ترتيب المهام

يمكنك تعديل ترتيب تنفيذ المهام التي تم إسنادها إلى مركبة إما من حزمة تطوير البرامج (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;
}

راحة

لتحديث ترتيب المهام لمركبة من بيئة الخادم، عليك إجراء استدعاء HTTP REST إلى `UpdateDeliveryVehicle':

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

<id> هو معرّف فريد لمركبة توصيل في أسطولك تنوي تعديل ترتيب المهام لها. إنها المعرف الذي حددته عند إنشاء المركبة.

يجب أن يحتوي عنوان الطلب على حقل التفويض مع القيمة الحامل <token>، حيث يكون <token> رمزًا مميّزًا تم صكه من قِبل مصنع الرموز المميّزة Fleet Engine.

يجب أن يحتوي نص الطلب على كيان DeliveryVehicle:

  • الحقول المطلوبة:

    الحقلالقيمة
    متبقٍVehicleJourneyClips قائمة بشرائح الرحلة للمهام بالترتيب الذي يجب تنفيذها فيه يتم تنفيذ المهمة الأولى في القائمة أولاً.
    قَائِمَةVehicleJourneyparagraphs[i].stop نقطة التوقف للمهمة i في القائمة.
    متبقيةVehicleJourneyClips[i].stop.plannedLocation الموقع المخطط للمحطة.
    متبقيةVehicleJourneyClips[i].stop.tasks قائمة بالمهام التي سيتم أداؤها في محطة التوقف هذه.
    متبقيةVehicleJourneysegments[i].stop.state الولاية.جديد

  • الحقول الاختيارية:

    • لا ينطبق

ويتم تجاهل جميع الحقول الأخرى في الكيان عند إجراء التعديل.

مثال على أمر 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 عند خروج مركبة من محطة توقف أو بدء التنقّل. يمكنك إرسال إشعارات Fleet Engine إما من حزمة SDK لبرنامج التشغيل أو من بيئة الخادم. يجب عدم الخلط بين الطريقتين لتجنب شروط العرق والحفاظ على مصدر واحد للحقيقة.

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

راحة

لإبلاغ Fleet Engine بأنّ المركبة في طريقها إلى محطتها التالية من بيئة الخادم، يمكنك إجراء استدعاء HTTP REST إلى `UpdateDeliveryVehicle':

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

<id> هو معرِّف فريد لمركبة التسليم في أسطولك والتي تنوي تعديل ترتيب المهام لها. إنها المعرف الذي حددته عند إنشاء المركبة.

يجب أن يحتوي عنوان الطلب على حقل التفويض مع القيمة الحامل <token>، حيث يكون <token> رمزًا مميّزًا تم صكه من قِبل مصنع الرموز المميّزة Fleet Engine.

يجب أن يحتوي نص الطلب على كيان DeliveryVehicle:

  • الحقل المطلوب:

    الحقلالقيمة
    متبقٍVehicleJourneyClips قائمة بمحطات المركبات المتبقية التي تحمل علامة 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

وصول مركبة إلى محطة

يجب إرسال إشعار إلى Fleet Engine عند وصول مركبة إلى محطة. ويمكنك إرسال إشعارات إلى Fleet Engine إمّا من حزمة SDK لبرنامج التشغيل أو من بيئة الخادم. يجب عدم الخلط بين الطريقتين لتجنب شروط العرق والحفاظ على مصدر واحد للحقيقة.

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

راحة

لإبلاغ Fleet Engine بوصول مركبة إلى محطة من بيئة الخادم، عليك إجراء استدعاء HTTP REST إلى "UpdateDeliveryVehicle":

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

<id> هو معرِّف فريد لمركبة التسليم في أسطولك والتي تنوي تعديل ترتيب المهام لها. إنها المعرف الذي حددته عند إنشاء المركبة.

يجب أن يحتوي عنوان الطلب على حقل التفويض مع القيمة الحامل <token>، حيث يكون <token> رمزًا مميّزًا تم صكه من قِبل مصنع الرموز المميّزة Fleet Engine.

يجب أن يحتوي نص الطلب على كيان DeliveryVehicle:

  • الحقول المطلوبة:

    الحقلالقيمة
    متبقٍVehicleJourneyClips المحطة التي وصلت إليها مع ضبط حالتها على 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 عند إكمال مركبة للتوقّف. يؤدي ذلك إلى تعيين جميع المهام المرتبطة بالمحطة على حالة "مغلقة". يمكنك إبلاغ Fleet Engine إما من حزمة SDK لبرنامج التشغيل أو من بيئة الخادم. ويجب عدم الخلط بين الطريقتين لتجنّب ظروف العِرق وللحفاظ على مصدر واحد للحقيقة.

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

راحة

لإبلاغ Fleet Engine بانتهاء عملية الإيقاف من بيئة الخادم، عليك إجراء استدعاء HTTP REST إلى "UpdateDeliveryVehicle":

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

<id> هو معرِّف فريد لمركبة التسليم في أسطولك والتي تنوي تعديل ترتيب المهام لها. إنها المعرف الذي حددته عند إنشاء المركبة.

يجب أن يحتوي عنوان الطلب على حقل التفويض مع القيمة الحامل <token>، حيث يكون <token> رمزًا مميّزًا تم صكه من قِبل مصنع الرموز المميّزة Fleet Engine.

يجب أن يحتوي نص الطلب على كيان DeliveryVehicle:

  • الحقول المطلوبة:

    الحقلالقيمة
    شرائح_المركبة_المتبقية_للرحلات من المفترض ألا تكون المحطة التي أكملتها مُدرَجة في قائمة المحطات المتبقية للمركبة.

  • الحقول الاختيارية:

    • لا ينطبق

ويتم تجاهل جميع الحقول الأخرى في الكيان عند إجراء التعديل.

مثال على أمر 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}",
            "taskDuration": "120s"
          }
        ]
      }
    }
  ]
}
EOM

تعديل مهمة

معظم حقول المهام غير قابلة للتغيير. ومع ذلك، من الممكن تعديل الحالة ونتائج المهمة ووقت نتيجة المهمة وموقع نتيجة المهمة والسمات من خلال تحديث عنصر المهمة مباشرةً. على سبيل المثال، في الحالات التي لم يتم إسناد مهمة فيها إلى مركبة، من الممكن إغلاق المهمة عن طريق تحديث الحالة مباشرةً.

gRPC

هذا مثال على تعديل مهمة من خلال استراتيجية gRPC.

راحة

هذا مثال على تعديل مهمة من خلال 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) // It's only possible to directly CLOSE a
  .build();                    // task which is NOT assigned to a vehicle.

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

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

راحة

لوضع علامة "مغلقة" على مهمة من بيئة الخادم، عليك إجراء استدعاء HTTP REST إلى UpdateTask:

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

<id> هو معرِّف فريد للمهمة.

يجب أن يحتوي عنوان الطلب على حقل التفويض مع القيمة الحامل <token>، حيث يكون <token> رمزًا مميّزًا تم صكه من قِبل مصنع الرموز المميّزة Fleet Engine.

يجب أن يحتوي نص الطلب على كيان Task:

  • الحقول المطلوبة:

    الحقلالقيمة
    ولاية الولاية.مغلقة

  • الحقول الاختيارية:

    الحقلالقيمة
    نتيجة المهمة النتيجة.SUCCEEDED أو النتيجة.تعذَّرت
    مهمة_النتيجة الوقت الذي تم فيه إنجاز المهمة
    موقع نتيجة المهمة الموقع الذي تم فيه إنجاز المهمة. سيضبط 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

تحديد نتيجة المهمة وموقع النتائج

لا يشير إغلاق المهمة إلى النجاح أو الفشل، بل يشير إلى أن المهمة لم تعد تُعد قيد التقدم. بالنسبة إلى تتبع الأسطول، من المهم الإشارة إلى النتيجة الفعلية للمهمة بحيث يمكن عرض نتيجة التسليم وهناك فوترة مناسبة للخدمات. لا يمكن تغيير نتيجة المهمة بعد ضبطها. من الممكن تعديل وقت نتيجة المهمة وموقع نتائج المهمة بعد تعيينها.

يمكن ضبط نتيجتها للمهام التي تكون في الحالة "مغلقة" على "SUCCEEDED" أو "فشل". لا يحصّل Fleet Engine سوى مهام التسليم التي تكون بالحالة SUCCEEDED.

عند وضع علامة على نتيجة مهمة ما، يملأ Fleet Engine تلقائيًا موقع نتائج المهمة بآخر موقع معروف للمركبة. من الممكن التغاضي عن هذا السلوك.

gRPC

لديك خيار تحديد موقع نتيجة المهمة عند تحديد النتيجة. سيؤدي ذلك إلى منع Fleet Engine من ضبطه على الإعداد التلقائي لآخر موقع للمركبة. يمكنك أيضًا الكتابة فوق موقع نتائج المهمة الذي تم إعداده Fleet Engine في وقت لاحق. لن يستبدل Fleet Engine أبدًا موقع نتائج المهمة الذي تقدمه. لا يمكن تعيين موقع نتيجة مهمة لمهمة لم يتم تحديد نتائجها للمهمة. من الممكن تعيين كل من نتيجة المهمة وموقع نتيجة المهمة في نفس الطلب.

يوضح المثال التالي كيفية استخدام مكتبة Java gRPC لتحديد نتيجة المهمة على SUCCEEDED وتحديد موقع اكتمال المهمة:

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

راحة

لوضع علامة على مهمة باعتبارها مكتملة من بيئة الخادم، يمكنك إجراء استدعاء HTTP REST إلى UpdateTask:

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

<id> هو معرِّف فريد للمهمة.

يجب أن يحتوي عنوان الطلب على حقل التفويض مع القيمة الحامل <token>، حيث يكون <token> رمزًا مميّزًا تم صكه من قِبل مصنع الرموز المميّزة Fleet Engine.

يجب أن يحتوي نص الطلب على كيان Task:

  • الحقول المطلوبة:

    الحقلالقيمة
    نتيجة المهمة النتيجة.SUCCEEDED أو النتيجة.تعذَّرت
    مهمة_النتيجة الطابع الزمني لوقت ضبط نتيجة المهمة (من مقدّم الخدمة) هذا هو الوقت الذي تم فيه إنجاز المهمة.

  • الحقول الاختيارية:

    الحقلالقيمة
    موقع نتيجة المهمة الموقع الذي تم فيه إنجاز المهمة. سيضبط 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=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، استخدم track_id المرتبط بالمهمة كمفتاح في جدول خارجي.

لمزيد من المعلومات، اطّلع على سير المهمة.

البحث عن مركبة

يمكنك البحث عن مركبة من خلال Driver SDK أو من بيئة الخادم.

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

راحة

للبحث عن مركبة من بيئة الخادم، يمكنك إجراء استدعاء HTTP REST إلى `GetVehicle':

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

<id> هو معرِّف فريد للمهمة.

<vehicleId> هو رقم تعريف المركبة المطلوب البحث عنها.

يجب أن يحتوي عنوان الطلب على حقل التفويض مع القيمة الحامل <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}"

البحث عن مهمة

يمكنك البحث عن مهمة من بيئة الخادم. لا تتيح حزمة 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;
}

راحة

للبحث عن مهمة من بيئة الخادم، يمكنك إجراء استدعاء HTTP REST إلى `GetTask':

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

<id> هو معرِّف فريد للمهمة.

<taskId> هو معرّف المهمة التي يجب البحث عنها.

يجب أن يحتوي عنوان الطلب على حقل التفويض مع القيمة الحامل <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}"

البحث عن معلومات مهمة الشحن من خلال رقم تعريف التتبّع

يمكنك البحث عن معلومات مهام الشحن بالطرق التالية، ولكل منها غرض منفصل:

  • بواسطة معرّف مهمة: يستخدمها المستخدمون مثل مشغّلي الأسطول الذين لديهم الإذن بالوصول إلى العرض الكامل لبيانات المهمة.
  • من خلال رقم تعريف تتبُّع: يستخدِمه برنامج العميل لتقديم معلومات محدودة إلى المستخدم النهائي، مثل وقت وصول طرد إلى منزله.

يناقش هذا القسم البحث عن معلومات المهمة باستخدام رقم تعريف تتبع. في حال كنت تريد البحث عن مهمة من خلال معرّف المهمة، انتقِل إلى البحث عن مهمة.

للبحث عن معلومات من خلال رقم تعريف تتبُّع، يمكنك استخدام أيّ مما يلي:

متطلبات البحث

  • تلتزم معلومات الشحن التي يقدّمها رقم تعريف التتبّع بقواعد إذن الوصول المذكورة في التحكّم في إمكانية رؤية المواقع الجغرافية التي يتم تتبّعها.

  • استخدام Fleet Engine للبحث عن معلومات الشحن من خلال رقم تعريف التتبّع ولا توفِّر حزمة تطوير البرامج (SDK) لبرامج التشغيل عمليات البحث عن المعلومات من خلال رقم تعريف التتبّع. لإجراء ذلك باستخدام FleetEngine، يمكنك استخدام إما بيئة خادم أو متصفح.

  • استخدِم أضيق رمز مميّز ممكن للحدّ من المخاطر الأمنية. على سبيل المثال، إذا كنت تستخدم رمز Delivery Consumer Token، لن تعرض أي طلبات من واجهة Fleet 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> هو رقم تعريف التتبع المرتبط بالمهمة.

يجب أن يحتوي عنوان الطلب على حقل التفويض مع القيمة حامل <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}"

سرد المهام

يمكنك إدراج المهام من بيئة خادم أو متصفّح. لا تتوافق حزمة تطوير البرامج (SDK) لبرنامج التشغيل مع مهام إدراج البيانات.

تتطلّب بطاقة بيانات المهام الوصول على نطاق واسع إلى المهام. تهدف قائمة المهام فقط للمستخدمين الموثوق بهم. استخدام رمز مصادقة مجموعة التسليم أو رمز مصادقة المستخدم المميز للتسليم عند إجراء طلبات المهام في القائمة.

يتم إخفاء الحقول التالية في المهام المُدرَجة:

  • vehicleStop.planned_location
  • vehicleStop.state
  • vehicleStop.TaskInfo.taskId

يمكن فلترة المهام المدرَجة حسب معظم خصائص المهام. بالنسبة إلى بنية طلب بحث عامل التصفية، راجع AIP-160. تعرض القائمة التالية خصائص مهام صالحة يمكنك استخدامها للتصفية:

  • attributes
  • معرّف_التسليم_المركبة
  • ولاية
  • الموقع_المُخطَّط له
  • مدة المهمة
  • نتيجة_المهمة
  • موقع_إخراج_المهمة
  • مصدر المهمة
  • وقت_نهاية_المهمة
  • رقم تعريف التتبع
  • كتابة

يمكنك استخدام تنسيقات الحقول التالية بناءً على اقتراحات تحسين Google API:

نوع الحقل التنسيق مثال
الطابع الزمني RFC-3339 task_outcome_time = 2022-03-01T11:30:00-08:00
المدة عدد الثواني متبوعة بحرف "s" task_duration = 120s
قيم التعداد سلسلة 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 لسرد المهام لمعرّف التسليمVehicleId وسمة مهمة. وقد يكون الرد الناجح فارغًا. تشير الاستجابة الفارغة إلى أنه لا يتم ربط أي مهام بـ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;
}

راحة

لعرض المهام من متصفّح، يمكنك إجراء استدعاء HTTP REST إلى ListTasks:

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

لتطبيق فلتر على المهام المدرَجة، أدرِج مَعلمة عنوان URL "فلترة" مع طلب بحث عن فلتر يتضمّن أحرف إلغاء لعنوان URL كقيمتها.

يجب أن يحتوي عنوان الطلب على حقل التفويض مع القيمة الحامل <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) للسائقين عرض بيانات مركبات التسليم.

تتطلب مركبات التسليم المدرجة وصولاً واسع النطاق إلى مركبات التسليم، وهي مخصّصة فقط للمستخدمين الموثوق بهم. استخدام قارئ مجموعة التوصيل أو الرمز المميز لمصادقة التسليم المميّز للمستخدم عند تقديم طلبات مركبات التسليم إلى القائمة.

تم إخفاء الحقول التالية في مركبات التوصيل المدرَجة بسبب تأثيرها على حجم الاستجابة:

  • جزء المسار الحالي
  • شرائح رحلات المركبات المتبقية

يمكنك فلترة مركبات التسليم المعروضة حسب السمة 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;
}

راحة

لعرض المهام من متصفّح، يمكنك إجراء استدعاء HTTP REST إلى ListDeliveryVehicles:

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

لتطبيق فلتر على المهام المدرَجة، أدرِج مَعلمة عنوان URL "فلترة" وقيمتها مع طلب بحث يتضمّن أحرف إلغاء لعنوان URL.

يجب أن يحتوي عنوان الطلب على حقل التفويض مع القيمة الحامل <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.

التسجيل

يمكنك تفعيل خيار للسماح لـ Fleet Engine بإرسال سجلات RPC إلى Cloud Logging. لمزيد من المعلومات، راجع تسجيل الدخول.

أدوار التفويض والرموز المميزة

كما هو موضّح في دمج واجهة برمجة تطبيقات التسليم وملاحظات التفويض لـ حالات الاستخدام الفردية، يتطلب إجراء استدعاءات إلى Fleet Engine المصادقة باستخدام الرموز المميزة للويب JSON التي تم توقيعها باستخدام بيانات اعتماد حساب الخدمة. قد يكون لحسابات الخدمة المستخدمة لاستخراج تلك الرموز المميّزة دور واحد أو أكثر، مع منح كل دور مجموعة مختلفة من الأذونات.

لمزيد من المعلومات، راجع المصادقة والتفويض.

تحديد المشاكل وحلّها

المرونة

لا يمكن اعتبار Fleet Engine مصدرًا للحقيقة. أنت مسؤول عن استعادة حالة نظامك إذا لزم الأمر، بدون الاعتماد على Fleet Engine.

الحالة المفقودة في Fleet Engine

عند العمل باستخدام Fleet Engine، يجب تنفيذ البرامج بحيث يشفي النظام نفسه في حال حدوث عطل. على سبيل المثال، عندما يحاول Fleet Engine تحديث مركبة، قد يستجيب برسالة خطأ يشير إلى عدم وجود المركبة. على العميل بعد ذلك إعادة إنشاء المركبة في الحالة الجديدة. نادرًا ما يحدث هذا، ويجب أن يتحلى النظام بالمرونة في حال حدوث ذلك.

وفي سيناريو مستبعد للغاية وهو عطل كارثي في Fleet Engine، قد تحتاج إلى إعادة إنشاء معظم أو كل المركبات والمهام. وإذا أصبح معدل الإنشاء مرتفعًا جدًا، قد يتعذّر تنفيذ بعض الطلبات مرة أخرى بسبب مشاكل في الحصة لأنّه يتم فرض عمليات فحص للحصص لتجنُّب هجمات رفض الخدمة (DOS). في هذه الحالة، قم بإبطاء معدل إعادة المحاولة باستخدام استراتيجية التراجع لإعادة المحاولة.

حالة فقدان البيانات في تطبيق السائق

في حال تعطّل تطبيق برنامج التشغيل، على التطبيق إعادة إنشاء الحالة الحالية ضمن حزمة تطوير البرامج (SDK) لبرنامج التشغيل. يجب أن يحاول التطبيق إعادة إنشاء المهام للتأكد من وجودها واستعادة حالاتها الحالية. على التطبيق أيضًا إعادة إنشاء قائمة محطات التوقف لـ Driver SDK وتحديدها صراحةً.

تجدر الإشارة إلى أنّ عمليات الاستعادة يجب أن تتم بشكل مستقل بدون الاعتماد على معلومات من Fleet Engine، بخلاف الأخطاء التي تشير إلى ما إذا كان الكيان موجودًا في قاعدة البيانات أم لا. إذا كان هناك كيان موجود بالفعل، فيمكن إذًا استيعاب هذا الخطأ ويمكن تحديث الكيان باستخدام رقم التعريف الخاص به.

الأسئلة الشائعة

ماذا لو توقف سائق عن مهمة خارج الترتيب؟

في هذه الحالة، يجب أولاً تحديث ترتيب المهام ثم المتابعة على النحو المعتاد، مع وضع علامة على الوصول إلى المحطة وإنجاز المهمة وما إلى ذلك. وإلا، فقد يصبح النظام غير متسق. قد تصبح الأوقات المقدّرة للوصول غير صحيحة وقد يتم الإبلاغ عن أخطاء غير متوقعة.