الدرس الثاني الاتصال في شبكة إنترنت الأشياء
انظر إلى رأس الصفحة: الدرس الثاني عن الاتصال في شبكة إنترنت الأشياء. شبكات الأجهزة تتبادل البيانات وتختلف في خصائصها مثل النطاق واستهلاك الطاقة. في هذا المشروع ستنفذ نظام مراقبة حرائق في المصانع. فكرة العمل تقوم على محاكاة حرائق عشوائية، حيث ترسل العقد الطرفية رسالة تحذير إلى العقد الوسطى، ومن ثم تصل الرسالة إلى وحدة التحكم الرئيسية. انظر إلى شكل العقد ووظائفها: ثلاث أنواع من العقد، الطرفية التي ترسل رسالة بحدوث حريق عشوائي، والوسطى التي تقرأ الرسالة وتعيد توجيهها، ووحدة التحكم الرئيسية التي تقرأ جميع الرسائل وتطبعها لإبلاغ المستخدم بالخطر.
يقوم هذا الدرس على فكرة محاكاة شبكة إنترنت الأشياء لنظام مراقبة الحريق والتحذير في المصانع باستخدام برنامج كاب كاربون (CupCarbon). تعتمد الشبكة على ثلاثة أنواع من العقد: العقد الطرفية (Edge) التي تفحص حدوث الحرائق بشكل عشوائي، والعقد الوسطى (Proxy) التي تتلقى الرسائل وتعيد توجيهها، ووحدة التحكم الرئيسية (Main Controller) التي تستقبل الإنذار النهائي وتطبع رقم القطاع الذي حدث فيه الحريق. يربط النظام بين هذه العقد برمجياً بلغة بايثون عبر دوال مثل randint لتوليد أرقام عشوائية، ودالة send لإرسال البيانات، ودالة read لقراءتها من المخزن المؤقت (Buffer).
الفكرة الأساسية
تقوم الفكرة الأساسية للدرس على بناء شبكة إنترنت الأشياء لمحاكاة نظام مراقبة الحرائق داخل المصانع. تتوزع الأدوار بين العقد لمراقبة قطاعات المصنع المختلفة، واكتشاف أي حريق عشوائياً، ثم نقل الرسالة تدريجياً من العقد الطرفية مروراً بالعقد الوسطى وصولاً إلى وحدة التحكم الرئيسية لإطلاق التحذير.
الشرح
تتكون شبكة المصنع من ثلاثة أنواع من العقد تؤدي كل منها وظيفة محددة:
- العقد الطرفية (Edges): توجد في الأطراف، وتقوم بتوليد أرقام عشوائية باستخدام دالة مثل randint(1, 6). إذا ظهر الرقم 1 مثلاً، فهذا يعني وجود حريق في القطاع. ترسل العقدة رسالة ذاتية إلى العقدة الوسطى المجاورة لها تحتوي على معرف القطاع باستخدام الدالة node.send(message).
- العقد الوسطى (Proxies): تتلقى الرسائل من العقد الطرفية، وتفحص المخزن المؤقت باستخدام دالة node.bufferSize(). إذا كان المخزن أكبر من صفر، فإنها تقرأ الرسالة عبر node.read() وتطبع عبارة FORWARDING... ثم تعيد توجيه الرسالة إلى وحدة التحكم الرئيسية باستخدام node.send(message, 1) حيث الرقم 1 يمثل معرف وحدة المتحكم.
- وحدة التحكم الرئيسية (Main Controller): تستقبل الرسائل الموجهة إليها من العقد الوسطى، وتقرأ محتواها لتطبع رقم القطاع الذي اشتعل فيه الحريق وتظهر رسالة التحذير النهائية للمستخدم.
مثال محلول خطوة بخطوة
تخيل أننا نكتب برنامج العقدة الطرفية بلغة بايثون لاكتشاف الحريق في القطاع رقم 5: الخطوة الأولى: نكتب دالة اختيار رقم عشوائي بين 1 و 6: fire = random.randint(1, 6) الخطوة الثانية: نتحقق مما إذا كان المتغير fire يساوي 1 كدلالة على وقوع حريق: if fire == 1: الخطوة الثالثة: نحدد نص الرسالة ونربطه برقم معرف العقدة باستخدام دالة id(): message = "FIRE IN SECTOR " + str(node.id()) الخطوة الرابعة: نرسل الرسالة إلى جميع العقد داخل النطاق: node.send(message) هكذا تدرك العقدة وقوع الحريق في قطاعها وتعلن عنه.
أخطاء شائعة
- نسيان وضع العقد الوسطى والطرفية داخل نطاق تغطية بعضها البعض، مما يمنع نجاح الاتصال وتمرير الرسائل بينها.
- إغفال إضافة معرف الوحدة في دالة الإرسال node.send عند محاولة إرسال رسالة إلى وحدة تحكم محددة بدلاً من البث العام.
- عدم التأكد من أن حجم المخزن المؤقت أكبر من الصفر قبل محاولة قراءة الرسائل باستخدام دالة node.read().
سؤالان للتدريب مع الإجابة
السؤال الأول: ما الوظيفة التي تقوم بها العقد الوسطى (Proxy) عند تلقي رسالة من عقدة طرفية؟ الإجابة: تقرأ العقدة الوسطى الرسالة من المخزن المؤقت، وتطبع عبارة FORWARDING... ثم تعيد توجيه الرسالة وتمريرها إلى وحدة التحكم الرئيسية. السؤال الثاني: لماذا نستخدم دالة str() عند دمج نص الرسالة مع معرف العقدة في برنامج العقدة الطرفية؟ الإجابة: لأن معرف العقدة يتم إرجاعه كرقم، ولذلك يجب تحويله إلى نوع نص (String) ليتم ربطه بنص الرسالة المتبقية دون حدوث خطأ برمجي.