جدولة التحكم في MQTT
:::نصيحة التحكم المجدول عبر MQTT مخصص للرسائل المجدولة مسبقًا. للتحكم المباشر، انظر التحكم الحي عبر MQTT بدلاً من ذلك. :::
سيساعدك هذا الدليل على تكوين MQTT على جهازك Sofar EMS للتحكم عن بُعد ومراقبة تركيب البطاريات والألواح الشمسية.
ما تحتاج إليه
- جهاز Sofar EMS متصل بالإنترنت.
- بيانات اعتماد MQTT: يمكن طلبها عن طريق إرسال بريد إلكتروني إلى support@eniris.be.
- بيئة تطوير بايثون (أو أي عميل MQTT آخر). يستخدم هذا الدليل مثالًا أساسيًا مكتوبًا بلغة بايثون لبدء استخدام MQTT وإرسال الأوامر. نوصي باستخدام بايثون لسهولة الاستخدام، لكن أي عميل MQTT آخر مدعوم.
معلومات إضافية
MQTT هو بروتوكول اتصالات سريع عبر الإنترنت. إنه نظام رسائل نشر/اشتراك، مما يسمح باتصال مباشر بين جهاز الكمبيوتر الخاص بك و Sofar EMS. يتم تصنيف أصولك إلى م جموعات من الألواح الشمسية، والبطاريات، والسيارات الكهربائية، وأنظمة HVAC. في الوقت الحالي، يسمح هذا التكامل بالتحكم حسب المجموعة، وليس حسب الجهاز.
الإعداد الأولي (نقطة بدء للمستخدمين الجدد)
لدي جهاز Sofar EMS أرغب في إعداده للتحكم عن بُعد عبر MQTT.
1. تحقق من الشبكة الخاصة بك
تأكد من أن شبكتك تسمح بحركة مرور الشبكات عبر بروتوكول MQTT على المنفذ 1883. يمكنك القيام بذلك باستخدام الأمر:
nc -zv mqtt.eniris.be 1883
عندما لا يكون هذا الأمر متاحًا، يمكنك بدلاً من ذلك تحميل وتنفيذ هذا الكود بلغة بايثون.
عند الشك، استشر مهندس الشبكة الخاص بك أو استخدم مؤقتًا نقطة اتصال 4G/5G من هاتفك عند حدوث أخطاء في الاتصال.
:::ملاحظة عندما لا يكون المنفذ 1883 متاحًا من شبكتك، نقدم بديلًا على المنفذ 80. يمكن تكوين هذا في عميل MQTT الخاص بك في خطوة لاحقة من هذا الدليل. :::
2. إضافة الأجهزة الخاصة بك
تسجيل الدخول إلى واجهة التكليف وتأكد من أن الأجهزة قد أضيفت إلى Sofar EMS.
3. إضافة إشارة خارجية عبر MQTT



4. تفعيل الإشارة الخارجية عبر MQTT
حدد جميع الأجهزة التي ترغب في تضمينها في التحكم عن بُعد عبر MQTT.

5. تم إضافة الإشارة عن بُعد
تم الآن تفعيل واجهة التحكم عن بُعد عبر MQTT على Sofar EMS.
نحن الآن جاهزون لإرسال بعض الأوامر الأساسية باستخدام مثال بسيط. تخبرك عمود الحالة إذا كانت أي أوامر نشطة.
سكربت تجريبي بلغة بايثون
نقطة بداية جيدة ستكون اختبار تكاملك الجديد المُعد باستخدام مثال بسيط.
يقوم هذا الكود التجريبي بعمل بسيط يتمثل في إرسال الجدول التالي بشكل مستمر:
- البطارية: الشحن عند 5 كيلوواط لمدة 15 دقيقة كل 10 دقائق
- الطاقة الشمسية: ضبط الطاقة على 0 كيلوواط لمدة ساعة كل 30 دقيقة
تستجيب Sofar EMS برسالة تأكيد تحتوي على معرف الجدول الفريد، أو رسالة خطأ.
ثم نسترجع الجدول التالي لكل من نوعي الجهاز، مؤكدين أن الأمر كان ناجحًا.
يرجى تحميل الملف أدناه في بيئة تطوير بايثون التي تفضلها. املأ الرقم التسلسلي الخاص بك وبيانات اعتماد MQTT ونفذ السكربت:
عند نجاح ما سبق، يمكنك متابعة إرسال أنواع أخرى من الرسائل. جميع الرسائل موصوفة أدناه.
وثائق MQTT لإرسال الأوامر
هذه القسم يوضح تنسيق رسائل MQTT ومتطلبات الحمل لوضع التحكم المجدول للأجهزة داخل شبكة Sofar EMS.
مواضيع MQTT
- موضوع الاشتراك:
standard1/rp_one_s/remoteScheduleMetrics/<controller SN> - موضوع المعلومات الراجعة:
standard1/outbound/remoteScheduleMetrics/feedback/<controller SN>
حيث يجب استبدال <controller SN> بالرقم التسلسلي الفعلي لجهاز Sofar EMS الذي تنوي التحكم فيه.
أنواع رسائل MQTT
1. إعداد الجدول (set_schedule)
ينشئ جدولًا جديدًا لنوع جهاز.
{
"extraTags": {
"nodeId": "<Controller SN>_site_0"
},
"time": <Unix Timestamp>,
"message_type": "set_schedule",
"fields": {
"device_type": "<Device Type>",
"node_id": "<Node ID>" (اختياري),
"start_time": <Unix Timestamp>,
"end_time": <Unix Timestamp>,
"policy": "<Policy>",
"power_setpoint_w": <Setpoint in watts>,
"site_import": <Site Import in Watts>,
"site_export": <Site Export in Watts>,
"remove_overlap": <True/False> (اختياري) (افتراضي=False),
"tag": <Tag String> (اختياري) (افتراضي=None),
}
}
الاستجابة (نجاح):
{
"requestTime": <Unix Timestamp>,
"time": <Unix Timestamp>,
"siteNodeId": "<Controller SN>_site_0",
"data": {
"message_type": "set_schedule_ack",
"state": {
"schedule_id": <Schedule ID>,
"deleted_ids": <Schedulde IDs deleted if remove_overlap=True>
"tag": <Tag String> (افتراضي=None),
},
"responseCode": 0
}
}
2. إعداد الجداول (set_schedules)
ينشئ جداول جديدة متعددة.
{
"extraTags": {
"nodeId": "<Controller SN>_site_0"
},
"time": <Unix Timestamp>,
"message_type": "set_schedules",
"fields":
"0": '{
"device_type": "<Device Type>",
"node_id": "<Node ID>" (اختياري),
"start_time": <Unix Timestamp>,
"end_time": <Unix Timestamp>,
"policy": "<Policy>",
"power_setpoint_w": <Setpoint in watts>,
"site_import": <Site Import in Watts>,
"site_export": <Site Export in Watts>,
"remove_overlap": <True/False> (اختياري) (افتراضي=False),
}',
"1": '{
"device_type": "<Device Type>",
"node_id": "<Node ID>" (اختياري),
"start_time": <Unix Timestamp>,
"end_time": <Unix Timestamp>,
"policy": "<Policy>",
"power_setpoint_w": <Setpoint in watts>,
"site_import": <Site Import in Watts>,
"site_export": <Site Export in Watts>,
"remove_overlap": <True/False> (اختياري) (افتراضي=False),
}',
...
}
الاستجابة (نجاح):
{
"requestTime": <Unix Timestamp>,
"time": <Unix Timestamp>,
"siteNodeId": "<Controller SN>_site_0",
"data": {
"message_type": "set_schedules_ack",
"state": {
"schedule_ids": <Schedule IDs>,
"deleted_ids": <Schedulde IDs deleted if remove_overlap=True>
},
"responseCode": 0
}
}
3. الحصول على الجدول (get_schedule)
يسترجع جدولًا محددًا بواسطة ID.
{
"extraTags": {
"nodeId": "<Controller SN>_site_0"
},
"time": <Unix Timestamp>,
"message_type": "get_schedule",
"fields": {
"id": <Schedule ID>
}
}
الاستجابة:
{
"requestTime": <Unix Timestamp>,
"time": <Unix Timestamp>,
"siteNodeId": "<Controller SN>_site_0",
"data": {
"message_type": "get_schedule_ack",
"state": <Schedule>,
"responseCode": 0
}
}
4. احصل على الجدول النشط (get_active_schedule)
يسترجع الجدول النشط الحالي لنوع الجهاز.
{
"extraTags": {
"nodeId": "<Controller SN>_site_0"
},
"time": <Unix Timestamp>,
"message_type": "get_active_schedule",
"fields": {
"device_type": "<Device Type>",
"node_id": "<Node ID>" (اختياري),
}
}
الرد (نجاح):
{
"requestTime": <Unix Timestamp>,
"time": <Unix Timestamp>,
"siteNodeId": "<Controller SN>_site_0",
"data": {
"message_type": "get_active_schedule_ack",
"state": <Schedule>,
"responseCode": 0
}
}
5. احصل على الجدول التالي (get_next_schedule)
يسترجع الجدول التالي القادم لنوع الجهاز.
{
"extraTags": {
"nodeId": "<Controller SN>_site_0"
},
"time": <Unix Timestamp>,
"message_type": "get_next_schedule",
"fields": {
"device_type": "<Device Type>",
"node_id": "<Node ID>" (اختياري),
}
}
الرد (نجاح):
{
"requestTime": <Unix Timestamp>,
"time": <Unix Timestamp>,
"siteNodeId": "<Controller SN>_site_0",
"data": {
"message_type": "get_next_schedule_ack",
"state": <Schedule>,
"responseCode": 0
}
}
6. احصل على الجداول (get_schedules)
يسترجع جميع الجداول لتاريخ محدد.
{
"extraTags": {
"nodeId": "<Controller SN>_site_0"
},
"time": <Unix Timestamp>,
"message_type": "get_schedules",
"fields": {
"date": "<Date String of Format dd/mm/yyyy>"
}
}
الرد (نجاح):
{
"requestTime": <Unix Timestamp>,
"time": <Unix Timestamp>,
"siteNodeId": "<Controller SN>_site_0",
"data": {
"message_type": "get_schedules_ack",
"state": {
"schedules": [<Schedule>, ...]
},
"responseCode": 0
}
}
7. احصل على الجداول المستقبلية (get_future_schedules)
يسترجع جميع الجداول المستقبلية.
{
"extraTags": {
"nodeId": "<Controller SN>_site_0"
},
"time": <Unix Timestamp>,
"message_type": "get_future_schedules",
"fields": {}
}
الرد (نجاح):
{
"requestTime": <Unix Timestamp>,
"time": <Unix Timestamp>,
"siteNodeId": "<Controller SN>_site_0",
"data": {
"message_type": "get_future_schedules_ack",
"state": {
"schedules": [<Schedule>, ...]
},
"responseCode": 0
}
}
8. إزالة الجدول (remove_schedule)
يزيل جدولاً محدداً حسب المعرف.
{
"extraTags": {
"nodeId": "<Controller SN>_site_0"
},
"time": <Unix Timestamp>,
"message_type": "remove_schedule",
"fields": {
"id": <Schedule ID>
}
}
الرد (نجاح):
{
"requestTime": <Unix Timestamp>,
"time": <Unix Timestamp>,
"siteNodeId": "<Controller SN>_site_0",
"data": {
"message_type": "remove_schedule_ack",
"state": "تمت إزالة الجدول <Schedule ID> بنجاح",
"responseCode": 0
}
}
9. احصل على تعليقات الموقع (get_feedback)
يسترجع تعليقات تفصيلية حول حالة النظام.
{
"extraTags": {
"nodeId": "<Controller SN>_site_0"
},
"time": <Unix Timestamp>,
"message_type": "get_feedback",
"fields": {
"device": <Device (node) level>
}
}
الرد (نجاح):
10. توبولوجيا الموقع (get_toplogy)
يحصل على توبولوجيا الموقع.
{
"extraTags": {
"nodeId": "<Controller SN>_site_0"
},
"time": <Unix Timestamp>,
"message_type": "get_topology",
"fields": {}
}
الرد (نجاح):
{
"requestTime": <Unix Timestamp>,
"time": <Unix Timestamp>,
"siteNodeId": "<Controller SN>_site_0",
"data": {
"message_type": "get_topology_ack",
"state": {
"nodeId": <nodeId>,
"nodeType": <nodeType>,
"nomCurrent": <nominalCurrent>,
"children": [{<ChildObject>}]
},
"responseCode": 0
}
}