صفحة ٢٩٢
انظر إلى الشكل: سلة القماش أو النفايات ترسل بيانات البيئة عبر وسيط MQTT لتصل إلى ملف بايثون يسمي mqtt_receiver.py فيخزنها، ثم يفتح ملف data_analysis.ipynb عبر مفكرة جوبيتر لتحليل البيانات ورسم المخططات البيانية. هذا يربط بين الأردوينو الذي يراقب البيئة وينتج المستشعرات رسائل، وبين لغة بايثون التي تجمع هذه الرسائل، وفي كل مرة تمتلىء سلة النفايات يُنشأ تقرير ويُخزّن في ملف آخر، ليُقرأ لاحقاً ويُحول إلى رؤى وتصورات حول كمية النفايات وأوقات الامتلاء.
صفحة ٢٩٣
افتح برنامج PyCharm وأنشئ ملفاً جديداً باسم data.json، واجعل محتواه مصفوفة فارغة هكذا: []. هذا الملف سيحفظ كائنات JSON الخاصة بالتقارير. بعد ذلك، أنشئ ملف بايثون جديد باسم mqtt_receiver.py، وفي بدايته استورد الحزم الأربع الأساسية: datetime لتنشئ طابعاً زمنياً للرسائل المرسلة، json للتعامل مع كائنات JSON، paho.mqtt.client لإنشاء عملاء للاتصال مع وسطاء MQTT، وos للتعامل مع الملفات على حاسوبك الخاص. ثم أنشئ المتغيرين data_file وdata_file_objects لتتفاعل مع ملف بيانات JSON.
صفحة ٢٩٤
أنشئ المتغيرات التي ستستخدم لعمليل MQTT مثل CLIENT_ID باسم RECEIVER_01 وهو معرف العميل، وMQTT_BROKER بعنوان الوسيط العام مثل broker.emqx.io الذي سيتم الاتصال به، وTOPIC بالموضوع الذي سيشترك فيه العميل وهو waste/drops، وPORT إلى منفذ الخادم الافتراضي للاتصال بالوسيط، وFLAG_CONNECTED كمتغير إشارة في دالة معالج الأحداث. ثم أنشئ المتغيرين messages_stack وreports لاستخدامها لتخزين المعلومات من الرسائل المنشورة. بعد ذلك أنشئ دالة معالج الأحداث on_connect والتي تطبع رسالة تأكيد إلى الواجهة الطرفية Terminal حول نجاح الاتصال بالعميل من عدمه عبر فحص إن كان rc يساوي الصفر.
صفحة ٢٩٥
انظر إلى الكود: الدالة on_message تستقبل الرسالة عبر البايثون، وتحول محتواها المشفّر إلى نص عبر دالة decode ثم str، ثم تحوله إلى كائن JSON وتضيفه إلى قائمة الرسائل messages_stack. عندما تتلقى الرسالة، تطبع في الواجهة الطرفية رسالة تفيد باستقبال رسالة وتציض قيمتها. وعندما يكون الحقل can_filled يساوي True، فإن البرنامج ينفذ دالة generate_report لإنشاء بيانات التقرير فقط عند امتلاء حاوية القمامة. انتبه إلى أن برنامج البايثون هنا يمكن أن يعمل كمستقبل MQTT ليجمع رسائل من عدة ناشري أردوينو في نفس الوقت.
صفحة ٢٩٦
أنشئ دالة generate_report لتُنشئ كائناً للتقرير وتلحقه بملف البيانات في كل مرة تُستلم فيها رسالة تشير إلى امتلاء حاوية النفايات. تستخدم الدالة الرسالتين الأولى والأخيرة لحساب فرق الوقت، وتستخدم دالة datetime.strptime لتحويل النصوص إلى تواريخ، ثم تحسب الوقت المستغرق لامتلاء السلة بجمع الثواني وقسمتها على ستين لتحويلها إلى دقائق. بعد ذلك، تُنشئ كائن التقرير الذي يحتوي على معرّف التقرير id، والطابع الزمني time_filled_timestamp، وعدد قطرات النفايات garbage_drops، ووقت الامتلاء time_to_fill.
صفحة ٢٩٧
ستتحقق في الجزء الرئيس من البرنامج مما إذا كانت البيانات موجودة وتقوم بفتحها، ثم تقوم بتهيئة عميل MQTT وترتبط معالجات الأحداث on_connect وon_message بالدوال المذكورة أعلاه، ثم تقوم بالاتصال بوسيط MQTT والاشتراك في الموضوع المحدد والاستماع إلى الرسائل الواردة. انظر إلى كود بايثون: يستخدم الأمر data_file_objects.append لإضافة التقرير الجديد إلى المصفوفة، ثم يحفظها في ملف JSON باستخدام json.dump مع إزاحة قدرها أربعة. وفي قسم التحقق، يتأكد الكود من وجود الملف عبر path.isfile، وإلا فإنه يرفع استثناء بأن الملف غير موجود، ثم يربط العميل بالوسيط.
صفحة ٢٩٨
عرض الكود البرمجي الكامل لملف استقبال البيانات عبر MQTT وإنشاء التقارير في لغة بايثون، ويظهر فيه استيراد المكتبات الأساسية مثل datetime وjson وpaho.mqtt.client وos. كما يتضمن تعريف مسار ملف البيانات data_file ومصفوفة الكائنات فارغة، بالإضافة إلى ضبط متغيرات الاتصال مثل CLIENT_ID وMQTT_BROKER وTOPIC وPORT وFLAG_CONNECTED. تلي ذلك مصفوفات messages_stack وreports ودالة الاتصال on_connect.
صفحة ٢٩٩
استكمال الكود البرمجي لمستقبل MQTT في لغة بايثون، حيث يظهر جزء معالجة الرسائل المستلمة عبر دالة on_message. يتضمن الكفك فك تشفير الرسالة وتحويلها إلى كائن JSON وإضافتها إلى مكدس الرسائل messages_stack. كما يوضح الشفرة المسؤولة عن فحص ما إذا كانت الحاوية ممتلئة عبر شرط can_filled == True، لتنفيذ دالة generate_report التي تحسب زمن الامتلاء والفرق الزمني بين أول وآخر رسالة وصولاً إلى حفظ التقارير.
صفحة ٣٠٠
الجزء الأخير من الكود البرمجي الكامل لمستقبل بيانات سلة النفايات الذكية بلغة بايثون. يظهر هنا حساب الوقت اللازم لامتلاء السلة بوضع الناتج في متغير time_to_fill، ثم إلحاق التقرير بملف JSON عبر دالة json.dump مع تحديد المسارات والمحددات. كما يبرز جزء التحقق من وجود ملف البيانات قبل فتحه، وتهيئة عميل MQTT والاتصال بالوسيط والاشتراك بالموضوع ثم الاستماع المستمر للرسائل عبر client.loop_forever.
صفحة ٣٠١
انظر إلى مفكرة جوبيتر: لتحليل البيانات من ملف JSON، نبدأ باستيراد المكتبات عبر import os وimport pandas as pd وimport matplotlib.pyplot as plt. بعد ذلك، نقرأ ملف البيانات باستخدام دالة pd.read_json مع تحويل التواريخ. انظر إلى الجدول الناتج من دالة data.describe(): يظهر لك عدد القراءات count وهي خمسون، والمتوسط mean والانحراف المعياري std وأقل قيمة min والنسب المئوية مثل خمسة وعشرين بالمئة وخمسين بالمئة وحتى القيمة العظمى max لكل من معرّف الحاوية id وعدد مرات امتلاء السلة garbage_drops ووقت الامتلاء time_to_fill.
صفحة ٣٠٢
انظر إلى المخططات البيانية: لإنشاء مخططين بيانيين مجمعين حسب خصائص garbage_drops وtime_to_fill، نستخدم دالة data.hist مع تحديد ثماني مجموعات bins=8. يظهر المخطط الأول توزيع عدد النفايات، بينما يوضح الثاني توزيع أوقات الامتلاء. بعد ذلك، يمكنك إنشاء مخططات من نوع stem plots باستخدام plt.stem لعرض تباين قيم كل متغير عبر الزمن، مع استخدام علامات على شكل معين عبر markerfmt='D' لتوضيح كل قراءة زمنية بدقة على المخطط.
صفحة ٣٠٣
انظر إلى المخططات التجميعية في مفكرة جوبيتر: لإنشاء مخططين يجمعان عدد النفايات garbage_drops لكل ساعة من اليوم ولكل ساعة خلال الأسبوع، نستخدم دالة plt.subplots مع تحديد سطرين وعمود واحد. نستخدم دالة dt.hour لتجميع البيانات حسب ساعة اليوم وعرضها في المخطط الأول بأعمدة بيانية، بينما نستخدم dt.day_of_week لتجميعها حسب أيام الأسبوع حيث الاثنين يمثل الصفر والأحد يمثل الستة، لعرض متوسط كمية النفايات في المخطط الثاني.
صفحة ٣٠٤
هذه صفحة تمارين. في التمرين الأول، طُلِب منك إنشاء مخطط يوضح العلاقة بين ملفي البايثون وملف JSON المحتفظ بالبيانات، ففكر في كيف ينتقل الكائن من الأردوينو إلى وسيط MQTT ثم يستقبله برنامج بايثون ليخزنه في JSON. في التمرين الثاني، طُلب منك إنشاء ملف بايثون يتصل بثلاثة موضوعات ويكتب معالج أحداث on_connect، فابحث في كيفية تعريف دالة معالج الاتصال وطباعة معلومات التكوين في الواجهة الطرفية Terminal لكل موضوع اشتريت فيه.
صفحة ٣٠٥
هذه صفحة تمارين لتطوير مهاراتك في بايثون ومفكرة جوبيتر. في التمرين الثالث، حدّث كائن on_message لطباعة معلومات العميل والموضوع إلى Terminal. في التمرين الرابع، أنشئ ملف JSON جديد يحتوي على قيم من قائمة الرسائل مستخدماً دالة create_report لإلحاق القيم بملف JSON الجديد. في التمرين الخامس، أنشئ مخطط مبعثر Scatter Diagram لنفس البيانات التي عولجت في الدرس. في التمرين السادس، أضف مقطعاً برمجياً يستقبل الرسائل التي نشرتها في التمرين السادس من الدرس الثاني.
صفحة ٣٠٦
هذه صفحة مشروع تطبيقي شامل. المطلوب في الخطوة الأولى هو إنشاء دائرة جديدة باستخدام لوحة أردوينو ومستشعر درجة الحرارة ومستشعر رطوبة التربة وترانزستور ضوئي. في الخطوة الثانية، أنشئ برنامج بايثون آخر بمثابة مستقبل للبيانات التي جمعت بواسطة الأردوينو، بحيث يشترك في الموضوع المختار ويصدر تنبيهاً إذا وجد ارتفاعاً في القيم المحدثة. في الخطوة الثالثة، أنشئ برنامج بايثون يشترك في موضوع بكافة القراءات ويحفظها في ملف JSON. في الخطوة الرابعة، شغّل مقاطع البايثون الثلاثة في آن واحد واضبط بيئة الأردوينو لتحديث القراءات ومراقبة النتائج.
صفحة ٣٠٧
خلاصة الدرس والمصطلحات الرئيسية. انظر إلى قائمة المصطلحات: ناشر Publisher، عميل Client، وسيط الرسائل Message Broker، خادم MQTT Server، الترانزستور الضوئي Phototransistor، نموذج أولي Prototype، جودة الخدمة Quality of Service، مستقبل Receiver، طبقة الخدمات Services Layer، طبقة الشارع Street Layer، مشترك Subscriber، ومستشعر الإمالة Tilt Sensor. تمثل هذه المصطلحات المفاتيح الأساسية لفهم منظومة إنترنت الأشياء والمدن الذكية وتحليل البيانات.