lora --- مشغّل مودم LoRa#

توفّر الوحدة lora مشغّلاً لمودم LoRa من نوع Murata CMWX1ZZABZ الموجود على Arduino Portenta Vision Shield. وهي تتيح فئة عالية المستوى Lora تغلّف مجموعة أوامر AT المستخدمة من قبل البرنامج الثابت للمودم (بما في ذلك البرنامج الثابت Arduino MKRWAN ARD-078) بحيث يستطيع التطبيق الانضمام إلى شبكة LoRaWAN وإرسال/استقبال الحزم.

مثال:

import lora

modem = lora.Lora(band=lora.BAND_EU868, debug=True)
print("Device EUI:", modem.get_device_eui())
if modem.join_OTAA("0000000000000000", "00000000000000000000000000000000"):
    modem.send_data(b"hello", confirmed=True)

الثوابت#

أوضاع التفعيل#

lora.MODE_ABP: int#

وضع التفعيل بالتخصيص (Activation By Personalization).

lora.MODE_OTAA: int#

وضع التفعيل عبر الأثير (Over-The-Air Activation).

أوضاع خرج التردد الراديوي#

lora.RF_MODE_RFO: int#

استخدام خرج التردد الراديوي RFO (منخفض الطاقة) الخاص بالمودم.

lora.RF_MODE_PABOOST: int#

استخدام خرج التردد الراديوي PA_BOOST (عالي الطاقة) الخاص بالمودم.

النطاقات#

lora.BAND_AS923: int#

النطاق الإقليمي AS923 (آسيا 923 ميجاهرتز).

lora.BAND_AU915: int#

النطاق الإقليمي AU915 (أستراليا 915 ميجاهرتز).

lora.BAND_EU868: int#

النطاق الإقليمي EU868 (أوروبا 868 ميجاهرتز).

lora.BAND_KR920: int#

النطاق الإقليمي KR920 (كوريا 920 ميجاهرتز).

lora.BAND_IN865: int#

النطاق الإقليمي IN865 (الهند 865 ميجاهرتز).

lora.BAND_US915: int#

النطاق الإقليمي US915 (الولايات المتحدة 915 ميجاهرتز).

lora.BAND_US915_HYBRID: int#

الخطة الإقليمية الهجينة US915 (نطاق فرعي).

فئات الأجهزة#

lora.CLASS_A: str#

جهاز LoRaWAN الطرفي من الفئة A.

lora.CLASS_B: str#

جهاز LoRaWAN الطرفي من الفئة B.

lora.CLASS_C: str#

جهاز LoRaWAN الطرفي من الفئة C.

الاستثناءات#

exception lora.LoraError#

الاستثناء الأساسي الذي يُطلَق لأي خطأ يُرجِعه المودم أو المشغّل.

exception lora.LoraErrorTimeout#

يُطلَق عندما لا يستجيب المودم خلال المهلة المُهيَّأة (مخزن الاستقبال فارغ).

exception lora.LoraErrorParam#

يُطلَق عند استجابة +ERR_PARAM حين يُصدَر أمر AT بمعامل غير صالح.

exception lora.LoraErrorBusy#

يُطلَق عند استجابة +ERR_BUSY حين يكون المودم مشغولاً بمعالجة أمر سابق.

exception lora.LoraErrorOverflow#

يُطلَق عند استجابة +ERR_PARAM_OVERFLOW حين يتجاوز معامل الطول الأقصى المسموح به.

exception lora.LoraErrorNoNetwork#

يُطلَق عند استجابة +ERR_NO_NETWORK حين لا يكون المودم قد انضم إلى شبكة.

exception lora.LoraErrorRX#

يُطلَق عند استجابة +ERR_RX حين يحدث خطأ أثناء استقبال وصلة نازلة.

exception lora.LoraErrorUnknown#

يُطلَق عند استجابة +ERR_UNKNOWN أو حين يُبلِغ المودم عن خطأ غير موثّق.

الفئات#

class lora.Lora(uart: machine.UART | None = None, rst_pin: machine.Pin | None = None, boot_pin: machine.Pin | None = None, band: int = BAND_EU868, poll_ms: int = 300000, debug: bool = False)#

إنشاء مشغّل مودم جديد. يقوم المُنشئ بتهيئة (أو إنشاء تلقائي) دبابيس UART وإعادة الضبط/الإقلاع، ويُعيد ضبط الوحدة عتادياً، ويُجري مزامنة معدل الباود التلقائي (autobaud)، ويُعيد إقلاع الوحدة، ويستعلم عن إصدار برنامجها الثابت، ويُهيّئ النطاق الإقليمي band المطلوب.

المعاملات:
  • uart -- مثيل machine.UART مُهيَّأ مسبقاً يُستخدم للتواصل مع المودم. إذا كان None، يفتح المشغّل UART(8, 19200) بتأطير 8N2 (الإعداد الافتراضي لـ Portenta Vision Shield).

  • rst_pin -- مثيل machine.Pin يقود خط إعادة ضبط المودم. إذا كان None، يُهيّأ "PC6" كخرج دافع-ساحب (push-pull).

  • boot_pin -- مثيل machine.Pin يقود خط اختيار الإقلاع للمودم. إذا كان None، يُهيّأ "PG7" كخرج دافع-ساحب مسحوب إلى المستوى المنخفض.

  • band -- النطاق الإقليمي المراد تهيئته. أحد ثوابت BAND_*.

  • poll_ms -- الفاصل الزمني بالميلي ثانية بين الوصلات الصاعدة الفارغة التلقائية التي تطلقها poll() لإبقاء نافذة الوصلة النازلة مفتوحة.

  • debug -- عندما يكون True، تُطبَع كل حركة مرور UART عبر print().

LoraErrors: dict#

التعيين من سلاسل استجابة الأخطاء للمودم (مثل "+ERR_BUSY") إلى فئة الاستثناء المقابلة. يُستخدم داخلياً من قبل handle_error().

init_modem() None#

تهيئة كسولة لـ self.uart و self.rst_pin و self.boot_pin إلى إعداداتها الافتراضية لـ Portenta Vision Shield إن لم تكن مُعيَّنة مسبقاً. تُستدعى من المُنشئ؛ ولا يستدعيها كود المستخدم عادةً.

debug_print(data: str) None#

تطبع data إذا كان debug مُفعَّلاً وقت الإنشاء، وإلا فلا تفعل شيئاً.

is_arduino_firmware() bool#

تُرجِع True إذا كان المودم يشغّل البرنامج الثابت Arduino MKRWAN ARD-078 (يُكتشَف من سلسلة fw_version المخزّنة مؤقتاً).

configure_class(_class: str) None#

تهيئة فئة جهاز LoRaWAN.

المعاملات:

_class -- أحد CLASS_A أو CLASS_B أو CLASS_C.

configure_band(band: int) bool#

تهيئة النطاق الإقليمي، وعلى البرنامج الثابت Arduino مع BAND_EU868، تفعيل محدِّد دورة العمل وفق ETSI. تُرجِع True عند النجاح.

المعاملات:

band -- أحد ثوابت BAND_*.

set_baudrate(baudrate: int) None#

تغيير معدل الباود لـ UART الخاص بالمودم (AT+UART).

المعاملات:

baudrate -- معدل الباود الجديد، بالبت في الثانية.

set_autobaud(timeout: int = 10000) bool#

إرسال أوامر AT فارغة حتى يستجيب المودم بـ +OK أو حتى تنقضي timeout ميلي ثانية. تُرجِع True إذا نجحت المزامنة.

المعاملات:

timeout -- الحد الأقصى للوقت المراد قضاؤه في المحاولة، بالميلي ثانية.

get_fw_version() str#

الاستعلام عن سلسلة جهاز المودم (AT+DEV?) وإصدار البرنامج الثابت (AT+VER?) وإرجاعهما كسلسلة واحدة مفصولة بمسافة.

get_device_eui() str#

تُرجِع معرّف الجهاز Device EUI ذا الـ 64 بت للمودم كسلسلة سداسية عشرية.

factory_default() None#

استعادة الإعدادات الافتراضية للمصنع عبر AT+FACNEW.

restart() None#

إعادة مزامنة معدل الباود، وإعادة إقلاع المودم، وإعادة قراءة إصدار البرنامج الثابت، وإعادة تطبيق النطاق الإقليمي المُهيَّأ. يُطلِق LoraError عند الفشل.

set_rf_power(mode: int, power: int) None#

تهيئة مرحلة خرج التردد الراديوي للمودم (AT+RFPOWER).

المعاملات:
  • mode -- أحد RF_MODE_RFO أو RF_MODE_PABOOST.

  • power -- مؤشر طاقة الخرج، بوحدات خاصة بالبرنامج الثابت.

set_port(port: int) None#

تهيئة منفذ تطبيق LoRaWAN (1..223) المستخدَم في استدعاءات send_data() اللاحقة.

المعاملات:

port -- منفذ FPort لـ LoRaWAN.

set_public_network(enable: bool) None#

تفعيل أو تعطيل كلمة المزامنة للشبكة العامة.

المعاملات:

enable -- True لكلمة مزامنة LoRaWAN العامة، و False للخاصة.

sleep(enable: bool) None#

وضع المودم في سُبات منخفض الطاقة (True) أو إيقاظه (False).

format(hexMode: bool) None#

اختيار تنسيق البيانات المستخدَم عبر UART لبايتات الحمولة.

المعاملات:

hexMode -- True لتنسيق الحمولة بالنظام السداسي العشري ASCII، و False للثنائي الخام.

set_datarate(dr: int) None#

تعيين مؤشر معدل بيانات LoRaWAN (AT+DR).

المعاملات:

dr -- مؤشر معدل البيانات الخاص بالمنطقة.

get_datarate() int#

تُرجِع مؤشر معدل بيانات LoRaWAN الحالي.

set_adr(adr: bool) None#

تفعيل أو تعطيل معدل البيانات التكيفي (Adaptive Data Rate).

المعاملات:

adr -- True لتفعيل ADR، و False لتعطيله.

get_adr() int#

تُرجِع إعداد ADR الحالي (1 إذا كان مُفعَّلاً، و 0 خلاف ذلك).

get_devaddr() str#

تُرجِع عنوان الجهاز DevAddr الحالي ذا الـ 32 بت كسلسلة سداسية عشرية.

get_nwk_skey() str#

تُرجِع مفتاح جلسة الشبكة الحالي كسلسلة سداسية عشرية.

get_appskey() str#

تُرجِع مفتاح جلسة التطبيق الحالي كسلسلة سداسية عشرية.

get_rx2dr() int#

تُرجِع مؤشر معدل البيانات المستخدَم لنافذة الاستقبال RX2.

set_rx2dr(dr: int) None#

تعيين مؤشر معدل البيانات المستخدَم لنافذة الاستقبال RX2.

المعاملات:

dr -- مؤشر معدل البيانات الخاص بالمنطقة.

get_ex2freq() int#

تُرجِع التردد، بالهرتز، المستخدَم لنافذة الاستقبال RX2.

set_rx2freq(freq: int) None#

تعيين التردد المستخدَم لنافذة الاستقبال RX2.

المعاملات:

freq -- التردد بالهرتز.

set_fcu(fcu: int) None#

تعيين عدّاد إطارات الوصلة الصاعدة (AT+FCU).

المعاملات:

fcu -- قيمة عدّاد إطارات الوصلة الصاعدة الجديدة.

get_fcu() int#

تُرجِع عدّاد إطارات الوصلة الصاعدة الحالي.

set_fcd(fcd: int) None#

تعيين عدّاد إطارات الوصلة النازلة (AT+FCD).

المعاملات:

fcd -- قيمة عدّاد إطارات الوصلة النازلة الجديدة.

get_fcd() int#

تُرجِع عدّاد إطارات الوصلة النازلة الحالي.

change_mode(mode: int) None#

تبديل وضع التفعيل.

المعاملات:

mode -- أحد MODE_ABP أو MODE_OTAA.

join(timeout_ms: int) bool#

إصدار AT+JOIN والانتظار لحدث قبول الانضمام. تُرجِع True إذا أبلغ المودم عن +EVENT=1,1 (نجح الانضمام) خلال timeout_ms.

المعاملات:

timeout_ms -- الحد الأقصى للوقت المراد انتظاره لكل من +ACK وحدث الانضمام اللاحق، بالميلي ثانية.

get_join_status() bool#

تُرجِع True إذا كان المودم منضماً حالياً إلى شبكة.

get_max_size() int#

تُرجِع الحجم الأقصى لحمولة LoRaWAN، بالبايت، لمعدل البيانات الحالي. على البرنامج الثابت Arduino يكون هذا ثابتاً عند 64.

poll() None#

إذا انقضى أكثر من poll_ms ميلي ثانية منذ آخر استدعاء، يُرسَل وصلة صاعدة مؤكَّدة فارغة لتفريغ الوصلات النازلة المعلّقة. مُخصَّص ليُستدعى بشكل متكرر من الحلقة الرئيسية للتطبيق.

send_data(buff: bytes, confirmed: bool = True) bool#

إرسال وصلة صاعدة لـ LoRaWAN. يُطلِق LoraError إذا كان buff أكبر من get_max_size().

المعاملات:
  • buff -- بايتات الحمولة المراد إرسالها.

  • confirmed -- عندما يكون True، تُرسَل وصلة صاعدة مؤكَّدة (+CTX) ويُنتظَر +ACK من خادم الشبكة. وعندما يكون False، تُرسَل وصلة صاعدة غير مؤكَّدة (+UTX).

تُرجِع:

True إذا قبل المودم الحزمة (وفي حالة الوصلات الصاعدة المؤكَّدة، إذا أقرّتها الشبكة)، و False خلاف ذلك.

receive_data(timeout: int = 1000) dict | None#

الانتظار لوصلة نازلة. تُرجِع None إذا لم يُستقبَل حدث +RECV خلال timeout ميلي ثانية، وإلا تُرجِع قاموساً {"port": str, "data": str} يحتوي على FPort وبايتات الحمولة.

المعاملات:

timeout -- الحد الأقصى للوقت المراد انتظاره، بالميلي ثانية.

receive(delimiter: str | list | None = None, max_bytes: int | None = None, timeout: int = 1000) str#

قراءة UART منخفضة المستوى. تقرأ الأحرف من المودم حتى يُطابَق فاصل، أو حتى تُقرأ max_bytes حرفاً، أو حتى تنقضي timeout ميلي ثانية، ثم تُرجِع السلسلة المتراكمة مع إزالة أي \r لاحق.

المعاملات:
  • delimiter -- إما حرف واحد للمطابقة في نهاية المخزن، أو سلسلة متعددة الأحرف للمطابقة مقابل المخزن المُشذَّب الكامل، أو قائمة بمثل هذه السلاسل.

  • max_bytes -- إذا عُيِّن، تُرجِع بمجرد قراءة هذا العدد من البايتات بالضبط.

  • timeout -- المهلة الإجمالية للقراءة، بالميلي ثانية.

available() int#

تُرجِع عدد البايتات المتاحة حالياً في مخزن استقبال UART الخاص بالمودم.

join_OTAA(appEui: str, appKey: str, devEui: str = None, timeout: int = 60000) bool#

تبديل المودم إلى وضع OTAA، وبرمجة المفاتيح ومعرّفات EUI المقدّمة، ثم محاولة الانضمام إلى الشبكة. تُرجِع True إذا نجح الانضمام.

المعاملات:
  • appEui -- معرّف التطبيق/الانضمام Application/Join EUI ذو الـ 64 بت كسلسلة سداسية عشرية.

  • appKey -- مفتاح التطبيق Application Key ذو الـ 128 بت كسلسلة سداسية عشرية.

  • devEui -- معرّف الجهاز Device EUI الاختياري ذو الـ 64 بت كسلسلة سداسية عشرية. إذا كان None، يُستخدَم معرّف الجهاز المبرمَج من المصنع.

  • timeout -- مهلة الانضمام، بالميلي ثانية.

join_ABP(nwkId: int, devAddr: str, nwkSKey: str, appSKey: str, timeout: int = 60000) bool#

تبديل المودم إلى وضع ABP، وبرمجة العناوين والمفاتيح المقدّمة، ثم محاولة الانضمام. تُرجِع نتيجة get_join_status().

المعاملات:
  • nwkId -- معرّف الشبكة (يتجاهله البرنامج الثابت حالياً).

  • devAddr -- عنوان الجهاز Device Address ذو الـ 32 بت كسلسلة سداسية عشرية.

  • nwkSKey -- مفتاح جلسة الشبكة Network Session Key ذو الـ 128 بت كسلسلة سداسية عشرية.

  • appSKey -- مفتاح جلسة التطبيق Application Session Key ذو الـ 128 بت كسلسلة سداسية عشرية.

  • timeout -- مهلة الانضمام، بالميلي ثانية.

handle_error(command: str, data: str) None#

فحص استجابة المودم وإطلاق فئة LoraError الفرعية المطابِقة إذا كانت تمثّل خطأً. لا تفعل شيئاً للاستجابات غير الخاطئة.

المعاملات:
  • command -- أمر AT (بدون البادئة AT) الذي أنتج data.

  • data -- سلسلة الاستجابة التي أرجعها المودم.

send_command(cmd: str, *args, delimiter: str = '\\r', data: bytes = None, timeout: int = 1000, raise_error: bool = True) str#

بناء أمر AT من cmd و args، وإلحاق حمولة data خام اختيارياً، وإرساله، وإرجاع استجابة المودم. لأوامر الاستعلام المنتهية بـ ?، يُرجَع جزء القيمة فقط (السلسلة الفرعية بعد =).

المعاملات:
  • cmd -- لاحقة أمر AT (مثل "+JOIN" و "+DR=")؛ تُضاف البادئة "AT" و \r اللاحق تلقائياً.

  • args -- وسائط إضافية تُسلسَل مع cmd بعد التحويل إلى سلسلة.

  • delimiter -- الفاصل المُمرَّر إلى receive().

  • data -- بايتات خام اختيارية تُكتَب فور أمر AT (تُستخدَم لحمولات الوصلة الصاعدة الثنائية).

  • timeout -- مهلة الاستجابة، بالميلي ثانية.

  • raise_error -- عندما يكون True، تُحوَّل استجابات الأخطاء إلى استثناءات LoraError؛ وعندما يكون False، تُرجَع الاستجابة الخام إلى المستدعي.