برنامج تعليمي: تطوير وحدة C IoT Edge باستخدام حاويات لينكس
ينطبق على:
IoT Edge 1.1 IoT Edge 1.2 ![]()
استخدم Visual Studio Code لتطوير التعليمات البرمجية C ونشرها على جهاز يعمل على Azure IoT Edge.
يمكنك استخدام وحدات IoT Edge لنشر التعليمات البرمجية التي تنفذ منطق عملك مباشرة إلى أجهزة IoT Edge. هذا البرنامج التعليمي يرشدك من خلال إنشاء ونشر وحدة IoT Edge التي تقوم بتصفية بيانات الاستشعار. في هذا البرنامج التعليمي، تتعلم كيفية:
- استخدام Visual Studio التعليمات البرمجية لإنشاء وحدة نمطية IoT Edge في C
- استخدام Visual Studio كود وDocker لإنشاء صورة docker ونشرها إلى سجل حاويات
- نشر الوحدة النمطية على جهاز IoT Edge
- عرض البيانات التي تم إنشاؤها
وحدة IoT Edge التي تقوم بإنشائها في هذا البرنامج التعليمي تقوم بتصفية بيانات درجة الحرارة التي تم إنشاؤها بواسطة جهازك. يرسل رسائل فقط تجاه المنبع إذا كانت درجة الحرارة فوق عتبة محددة. هذا النوع من التحليل على الحافة مفيد لتقليل كمية البيانات التي يتم توصيلها وتخزينها في السحابة.
إذا لم يكن لديك اشتراك Azure، فأنشئ حساب Azure مجاني قبل أن تبدأ.
المتطلبات الأساسية
يوضح هذا البرنامج التعليمي كيفية تطوير وحدة في CباستخدامVisual Studio Code، وكيفية نشرها على جهاز IoT Edge. إذا كنت تطور وحدات باستخدام حاويات Windows، فانتقل إلى تطوير وحدة C IoT Edge باستخدام حاويات Windows بدلاً من ذلك.
استخدم الجدول التالي لفهم خياراتك لتطوير ونشر وحدات C باستخدام حاويات Linux:
| C | تعليمة Visual Studio برمجية | Visual Studio |
|---|---|---|
| Linux AMD64 | ![]() |
![]() |
| Linux ARM32 | ![]() |
![]() |
قبل بدء هذا البرنامج التعليمي، يجب الانتهاء من البرنامج التعليمي السابق لإعداد بيئة التطوير الخاصة بك لتطوير حاوية Linux: تطوير وحدات IoT Edge باستخدام حاويات Linux . من خلال استكمال هذا البرنامج التعليمي، يجب أن تكون لديك المتطلبات الأساسية التالية في المكان:
- مركز مجاني أو قياسي لـIoT في Azure.
- جهاز يعمل على Azure IoT Edge مع حاويات لينكس. يمكنك استخدام قوالب التشغيل السريع لإعداد جهاز Linux أو جهاز يعمل بنظام Windows .
- سجل حاوية، مثل Azure Container Registry .
- Visual Studio Code الذي تم تكوينه باستخدام Azure IoT Tools .
- تم تكوين Docker CE لتشغيل حاويات Linux.
لتطوير وحدة نمطية IoT Edge في C يتم تثبيت المتطلبات الأساسية الإضافية التالية على جهاز التطوير الخاص بك:
- امتداد ++C/C لـ Visual Studio Code.
تثبيت Azure IoT C SDK غير مطلوب لهذا البرنامج التعليمي، ولكن يمكن أن توفر وظائف مفيدة مثل التحسس وقراءة تعريفات البرنامج. للحصول على معلومات التثبيت، راجع مكتبات Azure IoT C SDK والمكتبات.
إنشاء مشروع وحدة
تنشئ الخطوات التالية مشروع وحدة نمطية IoT Edge من أجل C باستخدام التعليمات البرمجية Visual Studio وملحق أدوات IoT Azure. بمجرد إنشاء قالب مشروع، أضف تعليمات برمجية جديدة بحيث تقوم الوحدة النمطية بتصفية الرسائل استنادًا إلى خصائصها التي تم الإبلاغ عنها.
إنشاء مشروع جديد
إنشاء قالب حل C يمكنك تخصيصه باستخدام التعليمات البرمجية الخاصة بك.
حدد عرض>لوحة الأوامر لفتح لوحة أوامر VS Code.
في لوحة الأوامر، اكتب الأمر Azure: تسجيل الدخول وقم بتشغيله واتبع الإرشادات لتسجيل الدخول إلى حساب Azure الخاص بك. إذا قمت بتسجيل الدخول بالفعل، يمكنك تخطي هذه الخطوة.
في لوحة الأوامر، اكتب وقم بتشغيل الأمر Azure IoT Edge: حل IoT Edge الجديد. اتبع المطالبات في لوح الأوامر لإنشاء الحل الخاص بك.
الحقل القيمة حدد مجلدًا اختر الموقع على جهاز التطوير الخاص بك لأجل VS Code لإنشاء ملفات الحل. توفير اسم حل أدخل اسمًا وصفيًّا للحل الذي تستخدمه أو اقبل EdgeSolution الافتراضي. تحديد قالب الوحدة النمطية اختر C Module. توفير اسم وحدة نمطية قم بتسمية وحدتك CModule. توفير مستودع صور Docker للوحدة النمطية يتضمن مستودع الصور اسم سجل الحاوية واسم صورة الحاوية. صورة الحاوية الخاصة بك مملوءة مسبقًا بالاسم الذي قدمته في الخطوة الأخيرة. استبدل localhost:5000 بقيمة خادم تسجيل الدخول من سجل حاوية Azure. يمكنك استرداد ملقم تسجيل الدخول من صفحة نظرة عامة من تسجيل الحاوية في مدخل Azure.
يبدو مستودع الصور النهائي مثل <اسم> التسجيل .azurecr.io/cmodule.
أضف بيانات اعتماد التسجيل الخاصة بك
ملف البيئة يخزن بيانات الاعتماد الخاصة بسجل الحاوية ويشاركها مع وقت التشغيل IoT Edge. يحتاج وقت التشغيل إلى بيانات الاعتماد هذه لسحب الصور الخاصة بك إلى جهاز IoT Edge.
يحاول ملحق IoT Edge سحب بيانات اعتماد تسجيل الحاوية من Azure وملأها في ملف البيئة. تحقق لمعرفة ما إذا كانت بيانات الاعتماد الخاصة بك مضمنة بالفعل. إذا لم يكن كذلك، فأضفها الآن:
- في مستكشف التعليمات البرمجية VS فتح الملف .env.
- قم بتحديث الحقول باستخدام قيم اسم المستخدم وكلمة المرور التي نسختها من سجل حاوية Azure.
- احفظ هذا الملف.
ملاحظة
يستخدم هذا البرنامج التعليمي بيانات اعتماد تسجيل دخول المسؤول لسجل Azure Container، والتي تعتبر ملائمة لسيناريوهات التطوير والاختبار. عندما تكون جاهزًا لسيناريوهات الإنتاج، نوصي بخيار مصادقة أقل امتيازًا مثل كيانات الخدمة. لمزيد من المعلومات، راجع إدارة الوصول إلى سجل الحاوية.
حدد بنية الهدف
حالياً، يمكن لـ Visual Studio Code تطوير وحدات C النمطية لأجهزة لينكس AMD64 ولينكس ARM32v7. تحتاج إلى تحديد البنية التي تستهدفها مع كل حل، لأن الحاوية مبنية ويتم تشغيلها بشكل مختلف لكل نوع من أنواع الهندسة المعمارية. الافتراضي هو Linux AMD64.
افتح لوحة الأوامر وابحث عن Azure IoT Edge: تعيين المنصة الهدف الافتراضي؟ لحل Edge، أو حدد رمز الاختصار في الشريط الجانبي أسفل النافذة.
في لوحة الأوامر، حدد بنية الهدف من قائمة الخيارات. في هذا البرنامج التعليمي، نستخدم جهاز Ubuntu الظاهري كجهاز IoT Edge، لذلك سنتخذ amd64 الافتراضي.
تحديث الوحدة النمطية باستخدام التعليمات البرمجية المخصصة
تتلقى التعليمات البرمجية للوحدة النمطية الافتراضية رسائل في قائمة انتظار إدخال وتمررها عبر قائمة انتظار إخراج. دعونا نضف بعض التعليمات البرمجية الإضافية بحيث تقوم الوحدة النمطية بمعالجة الرسائل على الحافة قبل إعادة توجيهها إلى IoT Hub. تحديث الوحدة النمطية بحيث يقوم بتحليل بيانات درجة الحرارة في كل رسالة، ويرسل الرسالة إلى IoT Hub فقط إذا تجاوزت درجة الحرارة عتبة معينة.
البيانات من جهاز الاستشعار في هذا السيناريو يأتي في شكل JSON. لتصفية الرسائل بتنسيق JSON، قم باستيراد مكتبة JSON ل C. يستخدم هذا البرنامج التعليمي بارسون.
قم بتنزيل مستودع Parson GitHub. انسخ ملفي parson.c وparson.h إلى المجلد CModule.
افتح وحدات>CModule>CMakeLists.txt. في الجزء العلوي من الملف، قم باستيراد ملفات Parson كمكتبة تسمى my_parson.
add_library(my_parson parson.c parson.h )أضف
my_parsonإلى قائمة المكتبات في وظيفةtarget_link_libraries في CMakeLists.txt.احفظ ملف CMakeLists.txt.
افتح modules>CModule>main.c. في أسفل قائمة عبارات التضمين، أضف واحدة جديدة لتضمين
parson.hلدعم JSON:#include "parson.h"
في ملف main.c، أضف متغيرًا عامًا يسمى
temperatureThresholdبعد قسم التضمين. يعين هذا المتغير القيمة التي يجب أن تتجاوزها درجة الحرارة المقاسة لكي يتم إرسال البيانات إلى مركز IoT.static double temperatureThreshold = 25;ابحث عن
CreateMessageInstanceالوظيفة في main.c. استبدال عبارة إن كان آخر الداخلية مع التعليمات البرمجية التالية التي تضيف بضعة أسطر من الوظائف:if ((messageInstance->messageHandle = IoTHubMessage_Clone(message)) == NULL) { free(messageInstance); messageInstance = NULL; } else { messageInstance->messageTrackingId = messagesReceivedByInput1Queue; MAP_HANDLE propMap = IoTHubMessage_Properties(messageInstance->messageHandle); if (Map_AddOrUpdate(propMap, "MessageType", "Alert") != MAP_OK) { printf("ERROR: Map_AddOrUpdate Failed!\r\n"); } }إضافة أسطر التعليمات البرمجية الجديدة في العبارة آخر خاصية جديدة إلى الرسالة التي تسمي الرسالة تنبيهات. هذا الرمز يصنف كافة الرسائل كتنبيهات، لأننا سوف نقوم بإضافة وظائف ترسل الرسائل إلى مركز IoT فقط إذا كانت التقارير تبلغ عن درجات حرارة عالية.
استبدل وظيفة
InputQueue1Callbackبأكملها بالشفرة التالية. تقوم هذه الدالة بتنفيذ عامل تصفية المراسلة الفعلي. عند تلقي رسالة، فإنه يتحقق ما إذا كانت درجة الحرارة المبلغ عنها تتجاوز العتبة. إذا كانت الإجابة نعم، فإنه يقوم بإعادة توجيه الرسالة من خلال قائمة انتظار الإخراج الخاصة به. إذا لم يكن كذلك، فإنه يتجاهل الرسالة.static unsigned char *bytearray_to_str(const unsigned char *buffer, size_t len) { unsigned char *ret = (unsigned char *)malloc(len + 1); memcpy(ret, buffer, len); ret[len] = '\0'; return ret; } static IOTHUBMESSAGE_DISPOSITION_RESULT InputQueue1Callback(IOTHUB_MESSAGE_HANDLE message, void* userContextCallback) { IOTHUBMESSAGE_DISPOSITION_RESULT result; IOTHUB_CLIENT_RESULT clientResult; IOTHUB_MODULE_CLIENT_LL_HANDLE iotHubModuleClientHandle = (IOTHUB_MODULE_CLIENT_LL_HANDLE)userContextCallback; unsigned const char* messageBody; size_t contentSize; if (IoTHubMessage_GetByteArray(message, &messageBody, &contentSize) == IOTHUB_MESSAGE_OK) { messageBody = bytearray_to_str(messageBody, contentSize); } else { messageBody = "<null>"; } printf("Received Message [%zu]\r\n Data: [%s]\r\n", messagesReceivedByInput1Queue, messageBody); // Check if the message reports temperatures higher than the threshold JSON_Value *root_value = json_parse_string(messageBody); JSON_Object *root_object = json_value_get_object(root_value); double temperature; if (json_object_dotget_value(root_object, "machine.temperature") != NULL && (temperature = json_object_dotget_number(root_object, "machine.temperature")) > temperatureThreshold) { printf("Machine temperature %f exceeds threshold %f\r\n", temperature, temperatureThreshold); // This message should be sent to next stop in the pipeline, namely "output1". What happens at "outpu1" is determined // by the configuration of the Edge routing table setup. MESSAGE_INSTANCE *messageInstance = CreateMessageInstance(message); if (NULL == messageInstance) { result = IOTHUBMESSAGE_ABANDONED; } else { printf("Sending message (%zu) to the next stage in pipeline\n", messagesReceivedByInput1Queue); clientResult = IoTHubModuleClient_LL_SendEventToOutputAsync(iotHubModuleClientHandle, messageInstance->messageHandle, "output1", SendConfirmationCallback, (void *)messageInstance); if (clientResult != IOTHUB_CLIENT_OK) { IoTHubMessage_Destroy(messageInstance->messageHandle); free(messageInstance); printf("IoTHubModuleClient_LL_SendEventToOutputAsync failed on sending msg#=%zu, err=%d\n", messagesReceivedByInput1Queue, clientResult); result = IOTHUBMESSAGE_ABANDONED; } else { result = IOTHUBMESSAGE_ACCEPTED; } } } else { printf("Not sending message (%zu) to the next stage in pipeline.\r\n", messagesReceivedByInput1Queue); result = IOTHUBMESSAGE_ACCEPTED; } messagesReceivedByInput1Queue++; return result; }أضف دالة
moduleTwinCallback. تتلقى هذه الطريقة تحديثات على الخصائص المطلوبة من الوحدة المزدوجة، وتقوم بتحديث متغير temperatureThreshold لمطابقته. تحتوي جميع الوحدات النمطية على وحدة مزدوجة خاصة بها، ما يتيح لك تكوين التعليمات البرمجية التي تعمل داخل وحدة نمطية مباشرة من السحابة.static void moduleTwinCallback(DEVICE_TWIN_UPDATE_STATE update_state, const unsigned char* payLoad, size_t size, void* userContextCallback) { printf("\r\nTwin callback called with (state=%s, size=%zu):\r\n%s\r\n", MU_ENUM_TO_STRING(DEVICE_TWIN_UPDATE_STATE, update_state), size, payLoad); JSON_Value *root_value = json_parse_string(payLoad); JSON_Object *root_object = json_value_get_object(root_value); if (json_object_dotget_value(root_object, "desired.TemperatureThreshold") != NULL) { temperatureThreshold = json_object_dotget_number(root_object, "desired.TemperatureThreshold"); } if (json_object_get_value(root_object, "TemperatureThreshold") != NULL) { temperatureThreshold = json_object_get_number(root_object, "TemperatureThreshold"); } }ابحث عن وظيفة
SetupCallbacksForModule. استبدل الوظيفة بالتعليمة البرمجية التالية التي تضيف عبارة else if للتحقق مما إذا كان قد تم تحديث الوحدة النمطية المزدوجة أم لا.static int SetupCallbacksForModule(IOTHUB_MODULE_CLIENT_LL_HANDLE iotHubModuleClientHandle) { int ret; if (IoTHubModuleClient_LL_SetInputMessageCallback(iotHubModuleClientHandle, "input1", InputQueue1Callback, (void*)iotHubModuleClientHandle) != IOTHUB_CLIENT_OK) { printf("ERROR: IoTHubModuleClient_LL_SetInputMessageCallback(\"input1\")..........FAILED!\r\n"); ret = MU_FAILURE; } else if (IoTHubModuleClient_LL_SetModuleTwinCallback(iotHubModuleClientHandle, moduleTwinCallback, (void*)iotHubModuleClientHandle) != IOTHUB_CLIENT_OK) { printf("ERROR: IoTHubModuleClient_LL_SetModuleTwinCallback(default)..........FAILED!\r\n"); ret = MU_FAILURE; } else { ret = 0; } return ret; }احفظ ملف main.c.
في مستكشف VS Code، افتح ملفpublish.template.json في مساحة عمل حل IoT Edge.
إضافة الوحدة النمطية CModule التوأم إلى بيان النشر. أدخل محتوى JSON التالي في الجزء السفلي من القسم
moduleContent، بعد الوحدة المزدوجة$edgeHub:"CModule": { "properties.desired":{ "TemperatureThreshold":25 } }
احفظ ملف deployment.template.js.
بناء ودفع الوحدة النمطية الخاصة بك
في المقطع السابق، قمت بإنشاء حل IoT Edge وإضافة تعليمات برمجية إلى CModule التي ستقوم بتصفية الرسائل حيث درجة حرارة الجهاز التي تم الإبلاغ عنها ضمن الحدود المقبولة. الآن تحتاج إلى بناء الحل كصورة حاوية ودفعها إلى سجل الحاوية الخاص بك.
افتح محطة VS Code بتحديد عرض>المحطة الطرفية.
تسجيل الدخول إلى Docker بإدخال الأمر التالي في المحطة الطرفية. قم بتسجيل الدخول باستخدام اسم المستخدم وكلمة المرور وخادم تسجيل الدخول من سجل الحاويات Azure. يمكنك استرداد هذه القيم من قسم Access keys في السجل الخاص بك في منصة Azure.
docker login -u <ACR username> -p <ACR password> <ACR login server>قد تتلقى تحذيرًا أمنيًا يوصي باستخدام
--password-stdin. على الرغم من أن أفضل الممارسات موصى بها لسيناريوهات الإنتاج، إلا أنها خارج نطاق هذا البرنامج التعليمي. لمزيد من المعلومات، راجع مرجع تسجيل دخول docker.في مستكشف VS Code، انقر بزر الماوس الأيمن فوق ملف publish.template.json وحدد Build and Push IoT Edge Solution.
يبدأ أمر الإنشاء والدفع ثلاث عمليات. أولاً، ينشئ مجلدًا جديدًا في الحل يسمى config والذي يحتوي على بيان النشر الكامل، والذي تم إنشاؤه بناءً على المعلومات الموجودة في قالب النشر وملفات الحل الأخرى. ثانياً، يقوم بتشغيل
docker buildلإنشاء صورة الحاوية بناءً على ملف dockerfile المناسب للبنية المستهدفة. بعد ذلك، يقوم بتشغيلdocker pushلدفع مستودع الصور إلى سجل الحاوية الخاص بك.قد تستغرق هذه العملية عدة دقائق في المرة الأولى ولكن أسرع في المرة التالية التي تقوم بتشغيل الأوامر.
نشر الوحدات النمطية على الجهاز
استخدم مستكشف التعليمات البرمجية Visual Studio وملحق أدوات إنترنت Azure IoT لنشر مشروع الوحدة النمطية على جهاز IoT Edge. لديك بالفعل بيان نشر مُجهز للسيناريو الخاص بك، الملف deployment.amd64.json في مجلد التكوين. كل ما عليك القيام به الآن هو تحديد جهاز لتلقي النشر.
تأكد من أن جهاز IoT Edge الخاص بك يعمل.
في مستكشف Visual Studio Code ضمن قسم Azure IoT Hub، قم بتوسيع الأجهزة لمشاهدة قائمة أجهزة إنترنت الأشياء الخاصة بك.
انقر بزر الماوس الأيمن فوق اسم جهاز IoT Edge الخاص بك، ثم حدد Create Deployment for Single Device.
افتح الملف deployment.amd64.json في المجلد config ثم انقر فوق Select Edge Deployment Manifest. لا تستخدم الملف deployment.template.js.
تحت جهازك، قم بتوسيع الوحدات النمطية لمشاهدة قائمة بالوحدات التي تم نشرها وتشغيلها. انقر فوق الزر تحديث. من المفترض أن ترى الوحدةالجديدة تعمل جنبًا إلى جنب مع الوحدة النمطيةSimulatedTemperatureSensor و $ edgeAgent وedgeHub$ .
قد يستغرق الأمر بضع دقائق لبدء تشغيل الوحدات النمطية. يحتاج وقت تشغيل IoT Edge إلى استلام بيان النشر الجديد الخاص به، وسحب صور الوحدة النمطية من وقت تشغيل الحاوية، ثم بدء تشغيل كل وحدة نمطية جديدة.
عرض البيانات التي تم إنشاؤها
بعد تطبيق بيان النشر على جهاز IoT Edge، يعمل وقت تشغيل IoT Edge على الجهاز على تجميع معلومات النشر الجديدة وبدء التنفيذ عليها. يتم إيقاف أي وحدات نمطية تعمل على الجهاز غير مضمنة في بيان النشر. يتم بدء تشغيل أي وحدات مفقودة من الجهاز.
في مستكشف Visual Studio Code، انقر بزر الماوس الأيمن فوق اسم جهاز IoT Edge وحدد Start Monitoring Built-in Event Endpoint.
عرض الرسائل التي تصل إلى مركز IoT. قد يستغرق وصول الرسائل بعض الوقت، لأن جهاز IoT Edge يجب أن يتلقى عملية النشر الجديد وبدء تشغيل جميع الوحدات النمطية. وبعد ذلك، تنتظر التغييرات التي أجريناها على رمز CModule حتى تصل درجة حرارة الجهاز إلى 25 درجة قبل إرسال الرسائل. كما أنها تضيف نوع الرسالة Alert إلى أي رسائل تصل إلى الحد الأدنى لدرجة الحرارة.

تحرير الوحدة النمطية التوأم
استخدمنا وحدة CModule التوأم في بيان النشر لتعيين عتبة درجة الحرارة في 25 درجة. يمكنك استخدام الوحدة النمطية التوأم لتغيير الوظيفة دون الحاجة إلى تحديث التعليمات البرمجية للوحدة النمطية.
في Visual Studio Code، قم بتوسيع التفاصيل الموجودة تحت جهاز IoT Edge لرؤية الوحدات النمطية قيد التشغيل.
انقر بزر الماوس الأيمن فوق CModule وحدد تعديل وحدة ثنائية.
ابحث عن TemperatureThreshold في الخصائص المطلوبة. تغيير قيمته إلى درجة حرارة جديدة من 5 درجات إلى 10 درجات أعلى من آخر درجة حرارة مبلغ عنها.
احفظ ملف الوحدة النمطية المزدوجة.
انقر بزر الماوس الأيمن في أي مكان في جزء تحرير الوحدة النمطية المزدوجة وحدد تحديث الوحدة النمطية المزدوجة.
وراقب الرسائل الواردة من الجهاز إلى السحابة. يجب أن تشاهد الرسائل تتوقف حتى يتم الوصول إلى حد درجة الحرارة الجديد.
تنظيف الموارد
إذا كنت تخطط للمتابعة إلى المقالة التالية الموصى بها، يمكنك الاحتفاظ بالموارد والتكوينات التي قمت بإنشائها وإعادة استخدامها. يمكنك أيضًا الاستمرار في استخدام نفس جهاز IoT Edge كجهاز اختبار.
غير ذلك يمكنك حذف التكوينات المحلية وموارد Azure التي استخدمتها في هذه المقالة لتجنب التكاليف.
حذف موارد Azure
حذف موارد Azure ومجموعات الموارد لا رجعة فيه. تأكد من عدم حذفك لمجموعة المورد (الموارد) الخاطئة عن غير قصد. إذا قمت بإنشاء مركز IoT داخل مجموعة موارد موجودة لديها موارد تريد الاحتفاظ بها، فاحذف فقط مورد محور IoT نفسه، وليس مجموعة الموارد.
لحذف الموارد:
سجّل الدخول إلى مدخل Microsoft Azure، ثم حدد Resource groups.
حدد اسم مجموعة الموارد التي تحتوي على موارد اختبار IoT Edge.
راجع قائمة الموارد الموجودة في مجموعة الموارد الخاصة بك. إذا كنت تريد حذفها جميعاً، يمكنك تحديد Delete resource group. إذا كنت تريد حذف بعضها فقط، فيمكنك النقر فوق كل مورد لحذفها بشكل فردي.
الخطوات التالية
لقد أنشأت في هذا البرنامج التعليمي وحدة IoT Edge النمطية التي تحتوي على تعليمات برمجية لتصفية البيانات الأولية التي أنشأها جهاز IoT Edge.
يمكنك متابعة الدروس التالية لمعرفة كيف يمكن أن تساعدك Azure IoT Edge في نشر خدمات سحابة Azure لمعالجة البيانات وتحليلها على الحافة.
