البرنامج التعليمي: تطوير وحدات C# IoT Edge باستخدام حاويات Windows
ينطبق على:
IoT الحافة 1.1
توضح هذه المقالة كيفية استخدام Visual Studio لتطوير كود C# ونشرها على جهاز Windows الذي يقوم بتشغيل Azure IoT Edge.
ملاحظة
IoT Edge 1.1 LTS هي قناة الإصدار الأخيرة التي تدعم حاويات Windows. بدءا من الإصدار 1.2، تكون الحاويات الخاصة بـ Windows غير معتمدة. ضع في اعتبارك استخدام IoT Edge لنظام تشغيل Linux على Windows أو الانتقال إليه لتشغيل IoT Edge على أجهزة Windows.
يمكنك استخدام الوحدات لـ Azure IoT Edge لنشر التعليمات البرمجية التي تطبق منطق عملك مباشرة في أجهزة IoT Edge. هذا البرنامج التعليمي يرشدك من خلال إنشاء ونشر وحدة IoT Edge التي تقوم بتصفية بيانات الاستشعار.
في هذا البرنامج التعليمي، تتعلم كيفية:
- استخدم Visual Studio لإنشاء وحدةIoT Edge التي تعتمد على SDK C#.
- استخدم Visual Studio وDocker لإنشاء صورة Docker ونشرها في السجل الخاص بك.
- نشر الوحدة إلى جهاز IoT Edge الخاص بك.
- عرض البيانات التي تم إنشاؤها.
تقوم وحدة IoT Edge التي تقوم بإنشائها في هذا البرنامج التعليمي بتصفية بيانات درجة الحرارة التي تم إنشاؤها بواسطة جهازك. لا ترسل الوحدة الرسائل عند أعلى التدفق إلا إذا تجاوزت درجة الحرارة عتبة محددة. هذا النوع من التحليل على الحافة مفيد لتقليل كمية البيانات التي يتم توصيلها وتخزينها في السحابة.
في حال لم يكن لديك اشتراك Azure، قم بإنشاء حساب مجاني قبل البدء.
المتطلبات الأساسية
يوضح هذا البرنامج التعليمي كيفية تطوير وحدة نمطية في C# باستخدام Visual Studio 2019 ثم نشرها على جهاز Windows. إذا كنت تقوم بتطوير وحدات باستخدام حاويات Linux، فانتقل إلى تطوير وحدات C# IoT Edge باستخدام حاويات Linux بدلًا من ذلك.
راجع الجدول التالي لفهم خياراتك لتطوير ونشر وحدات C# باستخدام حاويات Linux:
| C# | تعليمة Visual Studio برمجية | Visual Studio 2017 و 2019 |
|---|---|---|
| تطوير Windows AMD64 | ![]() |
![]() |
| تصحيح أخطاء Windows AMD64 | ![]() |
قبل أن تبدأ هذا البرنامج التعليمي، قم بإعداد بيئة التطوير الخاصة بك باتباع الإرشادات الموجودة في البرنامج التعليميتطوير IoT Edge باستخدام حاويات Windows. بعد إكماله، ستحتوي البيئة على المتطلبات الأساسية التالية:
- مركز IoTمجاني أو قياسي المستوى في Azure.
- جهاز Windows الذي يقوم بتشغيل Azure IoT Edge.
- سجل حاوية، مثل Azure Container Registry .
- Visual Studio 2019، تم تكوينه باستخدام ملحق Azure IoT Edge Tools.
- Docker Desktop، تم تكوينه لتشغيل حاويات Windows.
تلميح
إذا كنت تستخدم Visual Studio 2017 (إصدار 15.7 أو أحدث)، فقم بتنزيل وتثبيت Azure IoT Edge Tools لـ Visual Studio 2017 من Visual Studio Marketplace.
إنشاء مشروع وحدة
في هذا القسم، تقوم بإنشاء مشروع وحدةIoT Edge باستخدام Visual Studio وملحق Azure IoT Edge Tools. بمجرد إنشاء قالب مشروع، أضف تعليمات برمجية جديدة بحيث تقوم الوحدة بتصفية الرسائل استنادًا إلى خصائصها المُبلَّغ عنها.
إنشاء مشروع جديد
توفر أدوات Azure IoT Edge قوالب مشروع لجميع لغات وحدة IoT Edge المدعومة في Visual Studio. تحتوي هذه القوالب على كافة الملفات والتعليمات البرمجية التي تحتاجها لنشر وحدة عمل لاختبار IoT Edge. يمكنها أيضًا إعطاءك نقطة بداية لتخصيصها مع منطق الأعمال الخاصة بك.
افتح Visual Studio 2019 وحدد Create New Projectً .
في جزء Create a new project، ابحث عن IoT Edge ثم حدد في قائمة النتائج مشروع Azure IoT Edge (Windows amd64) .

حدد "Next".
يفتح جزء Configure your new project.

في جزء تكوين مشروعك الجديد، قم بإعادة تسمية المشروع والحل إلى شيء أكثر وصفًا، مثل CSharpTutorialApp.
حدد Create لإنشاء المشروع.
يتم فتح جزء Add Module.

في صفحة تكوين مشروعك الجديد، قم بما يلي:
أ. في الجزء الأيمن، حدد قالب C# Module.
ب. في مربع Module Name، أدخل CSharpModule.
ج. في المربع Url مستودع استبدال localhost:5000 مع قيمة ملقم تسجيل الدخول من تسجيل حاوية Azure الخاص بك بالتنسيق التالي:ملاحظة
يتضمن مستودع الصور اسم سجل الحاوية واسم صورة الحاوية. تمت تعبئة صورة الحاوية مسبقًا من قيمة project-name للوحدة. يمكنك استرداد خادم تسجيل الدخول من صفحة نظرة عامة على سجل الحاوية في مدخل Azure.
حدد Add لإنشاء المشروع.
أضف بيانات اعتماد التسجيل الخاصة بك
يشارك بيان النشر بيانات الاعتماد الخاصة بسجل الحاوية مع وقت تشغيل IoT Edge. يحتاج وقت التشغيل إلى بيانات الاعتماد هذه لسحب الصور الخاصة بك إلى جهاز IoT Edge. استخدم بيانات الاعتماد من القسم Access keys من سجل حاويات Azure.
في Visual Studio Solution Explorer، افتح ملفdeployment.template.json.
ابحث عن خاصية registryCredentials في خصائص $edgeAgent المطلوبة. يجب ملء عنوان السجل الخاص بالخاصية تلقائيًا بالمعلومات التي قمت بتوفيرها عند إنشاء المشروع. يجب أن يحتوي حقلا اسم المستخدم وكلمة المرور على أسماء متغيرات. على سبيل المثال:
"registryCredentials": { "<registry name>": { "username": "$CONTAINER_REGISTRY_USERNAME_<registry name>", "password": "$CONTAINER_REGISTRY_PASSWORD_<registry name>", "address": "<registry name>.azurecr.io" } }افتح ملف البيئة (ENV) في حل الوحدة الخاصة بك. بشكل افتراضي، يتم إخفاء الملف في Solution Explorer، لذلك قد تحتاج إلى تحديد الزر Show All Files لعرضه. يجب أن يحتوي ملف ENV على نفس متغيرات اسم المستخدم وكلمة المرور التي رأيتها في ملف deployment.template.json.
أضف قيمUsername وPassword من سجل حاوية Azure الخاص بك.
احفظ تغييراتك التي قمت بها في ملف ENV.
تحديث الوحدة النمطية باستخدام التعليمات البرمجية المخصصة
تتلقى التعليمات البرمجية للوحدة النمطية الافتراضية رسائل في قائمة انتظار الإدخال وتمررها عبر قائمة انتظار إخراج. دعنا نضيف بعض التعليمات البرمجية الإضافية بحيث تقوم الوحدة بمعالجة الرسائل على الحافة قبل إعادة توجيهها إلى مركز IoT. قم بتحديث الوحدة بحيث تقوم بتحليل بيانات درجة الحرارة في كل رسالة، وترسل الرسالة إلى مركز IoT فقط إذا تجاوزت درجة الحرارة حدًا معينًا.
في Visual Studio، حدد برنامج CSharpModule.cs.
في الجزء العلوي من مساحة الاسم CSharpModule، أضف ثلاثة عباراتاستخدام للأنواع التي يتم استخدامها لاحقًا:
using System.Collections.Generic; // For KeyValuePair<> using Microsoft.Azure.Devices.Shared; // For TwinCollection using Newtonsoft.Json; // For JsonConvertأضف متغير temperatureThreshold إلى فئة البرنامج بعد متغير العداد. يحدد متغير حد درجة الحرارة القيمة التي يجب أن تتجاوزها درجة الحرارة المقاسة للبيانات التي سيتم إرسالها إلى مركز IoT.
static int temperatureThreshold { get; set; } = 25;أضف فئات MessageBodyو Machineو Ambient إلى فئة Program بعد تعريفات المتغير. تحدد هذه الفئات المخطط المتوقع لجسم الرسائل الواردة.
class MessageBody { public Machine machine {get;set;} public Ambient ambient {get; set;} public string timeCreated {get; set;} } class Machine { public double temperature {get; set;} public double pressure {get; set;} } class Ambient { public double temperature {get; set;} public int humidity {get; set;} }ابحث عن طريقة Init. تقوم هذه الطريقة بإنشاء كائن ModuleClient وتكوينه، مما يسمح للوحدة النمطية بالاتصال بوقت تشغيل Azure IoT Edge المحلي لإرسال الرسائل وتلقيها. كما تسجل التعليمات البرمجية رد اتصال لتلقي الرسائل من مركز IoT Edge عبر نقطة نهاية input1.
استبدل طريقة التهيئة بأكملها بالكود التالي:
static async Task Init() { AmqpTransportSettings amqpSetting = new AmqpTransportSettings(TransportType.Amqp_Tcp_Only); ITransportSettings[] settings = { amqpSetting }; // Open a connection to the Edge runtime. ModuleClient ioTHubModuleClient = await ModuleClient.CreateFromEnvironmentAsync(settings); await ioTHubModuleClient.OpenAsync(); Console.WriteLine("IoT Hub module client initialized."); // Read the TemperatureThreshold value from the module twin's desired properties. var moduleTwin = await ioTHubModuleClient.GetTwinAsync(); await OnDesiredPropertiesUpdate(moduleTwin.Properties.Desired, ioTHubModuleClient); // Attach a callback for updates to the module twin's desired properties. await ioTHubModuleClient.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertiesUpdate, null); // Register a callback for messages that are received by the module. await ioTHubModuleClient.SetInputMessageHandlerAsync("input1", FilterMessages, ioTHubModuleClient); }لا تزال طريقة التهيئة المحدثة هذه تعمل على إعداد الاتصال بوقت تشغيل IoT Edge باستخدام ModuleClient، ولكنها أيضًا تضيف وظائف جديدة. يقرأ الخصائص المرغوبة للوحدة التوأم لاسترداد قيمة temperatureThreshold. ثم يقوم بإنشاء رد اتصال يستمع لأي تحديثات مستقبلية للخصائص المطلوبة للوحدة التوأم. باستخدام رد الاتصال هذا، يمكنك تحديث عتبة درجة الحرارة في الوحدة التوأم عن بُعد، وسيتم دمج التغييرات في هذه الوحدة.
تقوم طريقة التهيئة المحدثة أيضًا بتغيير طريقة SetInputMessageHandlerAsync الحالية. في نموذج التعليمات البرمجية، تتم معالجة الرسائل الواردة على input1 باستخدام الدالة PipeMessage، ولكننا نريد تغيير ذلك لاستخدام الدالة FilterMessages التي سنقوم بإنشائها في الخطوات التالية.
قم بإضافة طريقة onDesiredPropertiesUpdate جديدة إلى فئة Program. تتلقى هذه الطريقة تحديثات على الخصائص المطلوبة من الوحدة المزدوجة، وتقوم بتحديث متغير temperatureThreshold لمطابقته. تحتوي جميع الوحدات النمطية على وحدة مزدوجة خاصة بها، ما يتيح لك تكوين التعليمات البرمجية التي تعمل داخل وحدة نمطية مباشرة من السحابة.
static Task OnDesiredPropertiesUpdate(TwinCollection desiredProperties, object userContext) { try { Console.WriteLine("Desired property change:"); Console.WriteLine(JsonConvert.SerializeObject(desiredProperties)); if (desiredProperties["TemperatureThreshold"]!=null) temperatureThreshold = desiredProperties["TemperatureThreshold"]; } catch (AggregateException ex) { foreach (Exception exception in ex.InnerExceptions) { Console.WriteLine(); Console.WriteLine("Error when receiving desired property: {0}", exception); } } catch (Exception ex) { Console.WriteLine(); Console.WriteLine("Error when receiving desired property: {0}", ex.Message); } return Task.CompletedTask; }قم بإزالة نموذج PipeMessage واستبداله بطريقة FilterMessagesجديدة. يتم استدعاء هذه الطريقة عندما تتلقى الوحدة النمطية رسالة من مركز IoT Edge. يقوم بتصفية الرسائل التي تبلغ عن درجات حرارة أقل من عتبة درجة الحرارة التي تم تعيينها عبر الوحدة المزدوجة. يضيف الأسلوب أيضًا خاصية MessageType إلى الرسالة مع تعيين القيمة إلى Alert.
static async Task<MessageResponse> FilterMessages(Message message, object userContext) { var counterValue = Interlocked.Increment(ref counter); try { ModuleClient moduleClient = (ModuleClient)userContext; var messageBytes = message.GetBytes(); var messageString = Encoding.UTF8.GetString(messageBytes); Console.WriteLine($"Received message {counterValue}: [{messageString}]"); // Get the message body. var messageBody = JsonConvert.DeserializeObject<MessageBody>(messageString); if (messageBody != null && messageBody.machine.temperature > temperatureThreshold) { Console.WriteLine($"Machine temperature {messageBody.machine.temperature} " + $"exceeds threshold {temperatureThreshold}"); using(var filteredMessage = new Message(messageBytes)) { foreach (KeyValuePair<string, string> prop in message.Properties) { filteredMessage.Properties.Add(prop.Key, prop.Value); } filteredMessage.Properties.Add("MessageType", "Alert"); await moduleClient.SendEventAsync("output1", filteredMessage); } } // Indicate that the message treatment is completed. return MessageResponse.Completed; } catch (AggregateException ex) { foreach (Exception exception in ex.InnerExceptions) { Console.WriteLine(); Console.WriteLine("Error in sample: {0}", exception); } // Indicate that the message treatment is not completed. var moduleClient = (ModuleClient)userContext; return MessageResponse.Abandoned; } catch (Exception ex) { Console.WriteLine(); Console.WriteLine("Error in sample: {0}", ex.Message); // Indicate that the message treatment is not completed. ModuleClient moduleClient = (ModuleClient)userContext; return MessageResponse.Abandoned; } }حفظ ملف «Program.cs»
افتح ملف deployment.template.js في حل IoT Edge. يخبر هذا الملف وكيل IoT Edge بالوحدات التي سيتم نشرها ويخبر مركز IoT Edge بكيفية توجيه الرسائل بينهما. هنا، الوحدات النمطية التي سيتم نشرها هي SimulatedTemperatureSensor و CSharpModule.
قم بإضافة الوحدة النمطية CSharpModule التوأم إلى بيان النشر. إدراج محتوى JSON التالي في الجزء السفلي من
modulesContentالمقطع، بعد التوأم الوحدة النمطيةmodulesContent"CSharpModule": { "properties.desired":{ "TemperatureThreshold":25 } }
احفظ ملف deployment.template.js.
قم ببناء الوحدة الخاصة بك وادفعها
في المقطع السابق، قمت بإنشاء حل IoT Edge ثم إضافة تعليمات برمجية إلى CSharpModule لتصفية الرسائل حيث تكون درجة حرارة الجهاز المبلغ عنها أقل من الحد المقبول. أنت الآن تحتاج إلى بناء الحل كصورة حاوية ودفعه إلى سجل الحاوية الخاص بك.
تسجيل الدخول إلى Docker
استخدم الأمر التالي لتسجيل الدخول إلى Docker على جهاز التطوير الخاص بك. استخدم اسم المستخدم وكلمة المرور وخادم تسجيل الدخول من سجل حاويات Azure. يمكنك استرداد هذه القيم من قسم Access keys في السجل الخاص بك في منصة Azure.
docker login -u <ACR username> -p <ACR password> <ACR login server>قد تتلقى تحذيرًا أمنيًا يوصي باستخدام
--password-stdin. على الرغم من أننا نوصي بهذا كأفضل ممارسة لسيناريوهات الإنتاج، فإنه خارج نطاق هذا البرنامج التعليمي. لمزيد من المعلومات، راجع مرجع تسجيل دخول docker .
بناء وادفع
في مستكشف الحلول الخاص بـ Visual Studio، انقر بزر الماوس الأيمن فوق اسم المشروع الذي تريد إنشاءه. الاسم الافتراضي هو AzureIotEdgeApp1، ولأنك تقوم بإنشاء وحدة Windows، يجب أن يكون الامتداد Windows. Amd64.
حدد Build and Push IoT Edge Modules.
يبدأ الأمران إنشاء ودفع ثلاث عمليات:
- أولاً، فإنه ينشئ مجلدًا جديدًا في الحل المسمى config، الذي يحمل بيان النشر الكامل. تم بناؤه من المعلومات في قالب النشر وملفات الحلول الأخرى.
- ثانيًا، يتم تشغيله
docker buildلبناء صورة الحاوية بناءً على ملف Dockerfile المناسب للبنية المستهدفة. - بعد ذلك، يتم تشغيله
docker pushلدفع مستودع الصورة إلى سجل الحاوية الخاص بك.
قد تستغرق هذه العملية عدة دقائق في المرة الأولى، ولكنها سوف تسير بشكل أسرع في المرة التالية التي تقوم فيها بتشغيل الأوامر.
نشر وحدات على الجهاز
استخدم Visual Studio Cloud Explorer وملحق Azure IoT Edge Tools لنشر مشروع الوحدة على جهاز IoT Edge. لقد قمت مسبقًا بإعداد بيان نشر للسيناريو الخاص بك، ملفdeployment.windows-amd64.json في مجلد config. كل ما عليك القيام به الآن هو تحديد جهاز لتلقي النشر.
تأكد من أن جهاز IoT Edge الخاص بك يعمل.
في Visual Studio Cloud Explorer، قم بتوسيع الموارد لعرض قائمة أجهزة IoT.
انقر بزر الماوس الأيمن فوق اسم جهاز IoT Edge الذي تريده لاستلام النشر.
حدد Create Deployment.
في Visual Studio File Explorer، حدد ملفdeployment.windows-amd64.json في مجلد config الخاص بحلك.
قم بتحديث Cloud Explorer لعرض الوحدات المنشورة المسرودة تحت جهازك.
عرض البيانات التي تم إنشاؤها
بعد تطبيق بيان النشر على جهاز IoT Edge، يقوم وقت تشغيل IoT Edge على الجهاز بتجميع معلومات النشر الجديدة وبدء تنفيذها. يتم إيقاف أي وحدات قيد التشغيل على الجهاز ولكن غير مضمنة في بيان النشر. يتم بدء تشغيل أي وحدات مفقودة من الجهاز.
يمكنك استخدام ملحق IoT Edge Tools لعرض الرسائل عند وصولها إلى مركز IoT الخاص بك.
في Visual Studio Cloud Explorer، حدد اسم جهاز IoT Edge.
في قائمة Actions حدد Start Monitoring Built-in Event Endpoint.
قم بعرض الرسائل التي تصل إلى مركز IoT. قد يستغرق وصول الرسائل بعض الوقت، لأن جهاز IoT Edge يجب أن يتلقى نشره الجديد وبدء تشغيل كافة الوحدات النمطية. يجب أن تنتظر التغييرات التي أُجرِيت على التعليمات البرمجية CSharpModule حتى تصل درجة حرارة الجهاز إلى 25 درجة قبل إرسال الرسائل. كما تضيف نوع الرسالة Alert إلى أي رسائل تصل إلى حد درجة الحرارة هذا.

تحرير الوحدة النمطية التوأم
لقد استخدمت وحدة CSharpModule التوأم لضبط عتبة درجة الحرارة عند 25 درجة. يمكنك استخدام الوحدة النمطية التوأم لتغيير الوظيفة دون الحاجة إلى تحديث التعليمات البرمجية الوحدة النمطية.
في Visual Studio، افتح الملفdeployment.windows-amd64.json.
لا تفتح ملف deployment.template. إذا لم تشاهد بيان التوزيع في ملف config في مستكشف الحلول، حدد أيقونة Show all files في شريط أدوات مستكشف الحلول.
ابحث عن التوأم CSharpModule، وقم بتغيير قيمة معلمة temperatureThreshold إلى درجة حرارة جديدة أعلى من 5 إلى 10 درجات من آخر درجة الحرارة تم الإبلاغ عنها.
حفظ ملف deployment.windows-amd64.js.
اتبع إرشادات النشر مرة أخرى لتطبيق بيان النشر المحدث على جهازك.
وراقب الرسائل الواردة من الجهاز إلى السحابة. يجب أن تتوقف الرسائل حتى يتم الوصول إلى عتبة درجة الحرارة الجديدة.
تنظيف الموارد
إذا كنت تخطط للمتابعة إلى المقالة التالية الموصى بها، يمكنك الاحتفاظ بالموارد والتكوينات التي قمت بإنشائها في هذا البرنامج التعليمي وإعادة استخدامها. يمكنك أيضًا الاستمرار في استخدام نفس جهاز IoT Edge كجهاز اختبار.
وإلا، لتجنب تكبد المصاريف، يمكنك حذف التكوينات المحلية وموارد Azure التي استخدمتها هنا.
حذف موارد Azure
حذف موارد Azure ومجموعات الموارد لا رجعة فيه. تأكد من عدم حذفك لمجموعة المورد (الموارد) الخاطئة عن غير قصد. إذا قمت بإنشاء مركز IoT داخل مجموعة موارد موجودة لديها موارد تريد الاحتفاظ بها، فاحذف فقط مورد محور IoT نفسه، وليس مجموعة الموارد.
لحذف الموارد:
سجّل الدخول إلى مدخل Microsoft Azure، ثم حدد Resource groups.
حدد اسم مجموعة الموارد التي تحتوي على موارد اختبار IoT Edge.
راجع قائمة الموارد الموجودة في مجموعة الموارد الخاصة بك. إذا كنت تريد حذفها جميعاً، يمكنك تحديد Delete resource group. إذا كنت تريد حذف بعضها فقط، فيمكنك النقر فوق كل مورد لحذفها بشكل فردي.
الخطوات التالية
في هذا البرنامج التعليمي، قمت بإنشاء وحدة IoT Edge مع التعليمات البرمجية لتصفية البيانات الأولية التي تم إنشاؤها بواسطة جهاز IoT Edge.
لمعرفة كيف يمكن لـ Azure IoT Edge مساعدتك في نشر خدمات Azure السحابية لمعالجة البيانات وتحليلها على الحافة، تابع الدروس التعليمية التالية.
