اختبار سرعة متزامن على عدة أجهزة مودم LTE

أثناء الحجر الصحي، عُرض علي المشاركة في تطوير جهاز لقياس سرعة أجهزة المودم LTE للعديد من مشغلي الهواتف المحمولة.

اختبار سرعة متزامن على عدة أجهزة مودم LTE

أراد العميل تقييم سرعة مشغلي الاتصالات المختلفين في مواقع جغرافية مختلفة حتى يتمكن من فهم مشغل الهاتف الخلوي الأكثر مثالية بالنسبة له عند تثبيت المعدات باستخدام اتصال LTE، على سبيل المثال، لبث الفيديو. وفي الوقت نفسه، كان لا بد من حل المشكلة ببساطة وبتكلفة زهيدة قدر الإمكان، دون الحاجة إلى معدات باهظة الثمن.

سأقول على الفور أن المهمة ليست الأبسط والأكثر كثافة في المعرفة، وسأخبرك بالمشاكل التي واجهتها وكيف قمت بحلها. إذا هيا بنا.

لاحظ

يعد قياس سرعة اتصال LTE أمرًا معقدًا للغاية: تحتاج إلى اختيار المعدات المناسبة وتقنية القياس، كما يجب أن يكون لديك فهم جيد لطوبولوجيا الشبكة الخلوية وتشغيلها. بالإضافة إلى ذلك، يمكن أن تتأثر السرعة بعدة عوامل: عدد المشتركين في الخلية، والظروف الجوية، وحتى من خلية إلى أخرى، يمكن أن تختلف السرعة بشكل كبير بسبب طوبولوجيا الشبكة. بشكل عام، هذه مشكلة بها عدد كبير من الأشياء المجهولة، ولا يستطيع حلها بشكل صحيح إلا مشغل الاتصالات.

في البداية، أراد العميل فقط قيادة الناقل باستخدام هواتف المشغلين، وأخذ القياسات مباشرة على الهاتف ثم تدوين نتائج قياس السرعة في دفتر ملاحظات. الحل الخاص بي لقياس سرعة شبكات LTE، على الرغم من أنه ليس مثاليًا، إلا أنه يحل المشكلة.

نظرًا لضيق الوقت، اتخذت قرارات ليس لصالح الراحة أو التطبيق العملي، ولكن لصالح سرعة التطوير. على سبيل المثال، تم استخدام ssh العكسي للوصول عن بعد، بدلاً من VPN الأكثر عملية، وذلك لتوفير الوقت في إعداد الخادم وكل عميل على حدة.

مهمة فنية

كما جاء في المقال بدون مواصفات فنية: لماذا لا يريدها العميل: لا تعمل بدون المواصفات الفنية! أبدا، في أي مكان!

كانت المهمة الفنية بسيطة للغاية، وسوف أقوم بتوسيعها قليلاً لفهم المستخدم النهائي. تم اختيار الحلول التقنية والمعدات من قبل العميل. إذن المواصفات الفنية نفسها بعد كل الموافقات:

يعتمد على كمبيوتر لوحي واحد vim2 قم بإجراء اختبار سرعة لاتصالات LTE عبر أجهزة المودم Hهواوي e3372h - 153 العديد من مشغلي الاتصالات (من واحد إلى ن). من الضروري أيضًا تلقي الإحداثيات من جهاز استقبال GPS متصل عبر UART. قم بإجراء قياسات السرعة باستخدام الخدمة www.speedtest.net ووضعهم في جدول مثل:

اختبار سرعة متزامن على عدة أجهزة مودم LTE

الجدول بتنسيق CSV. ثم أرسل هذه الإشارة بالبريد الإلكتروني كل 6 ساعات. في حالة حدوث أخطاء، وميض مؤشر LED المتصل بـ GPIO.

لقد وصفت المواصفات الفنية بشكل حر بعد العديد من الموافقات. لكن معنى المهمة واضح بالفعل. تم إعطاء أسبوع لكل شيء. ولكن في الواقع استمر لمدة ثلاثة أسابيع. هذا مع الأخذ في الاعتبار حقيقة أنني لم أفعل ذلك إلا بعد وظيفتي الرئيسية وفي عطلات نهاية الأسبوع.

هنا أريد أن ألفت الانتباه مرة أخرى إلى حقيقة أن العميل وافق مسبقًا على استخدام خدمة قياس السرعة والأجهزة، مما حد من قدراتي بشكل كبير. كانت الميزانية أيضًا محدودة، لذلك لم يتم شراء أي شيء خاص. لذلك كان علينا أن نلعب بهذه القواعد.

العمارة والتنمية

المخطط بسيط وواضح. ولذلك، سأترك الأمر دون أي تعليقات خاصة.

اختبار سرعة متزامن على عدة أجهزة مودم LTE

قررت تنفيذ المشروع بأكمله بلغة بايثون، على الرغم من أنه ليس لدي أي خبرة في التطوير بهذه اللغة على الإطلاق. اخترته لأن هناك مجموعة من الأمثلة والحلول الجاهزة التي يمكن أن تسرع عملية التطوير. لذلك أطلب من جميع المبرمجين المحترفين عدم توبيخ تجربتي الأولى في التطوير في لغة بايثون، ويسعدني دائمًا سماع النقد البناء لتحسين مهاراتي.

وفي هذه العملية أيضًا، اكتشفت أن بايثون لديها إصداران قيد التشغيل، 2 و 3، ونتيجة لذلك استقرت على الإصدار الثالث.

عقد الأجهزة

لوحة واحدة vim2

لقد تم إعطائي جهاز كمبيوتر ذو لوحة واحدة ليكون جهازي الرئيسي vim2

اختبار سرعة متزامن على عدة أجهزة مودم LTE

معالج وسائط ممتاز وقوي للمنزل الذكي والتلفزيون الذكي، ولكنه غير مناسب تمامًا لهذه المهمة، أو على سبيل المثال، غير مناسب. على سبيل المثال، نظام التشغيل الرئيسي الخاص به هو Android، و Linux هو نظام تشغيل ثانوي، وبالتالي لا أحد يضمن التشغيل عالي الجودة لجميع العقد وبرامج التشغيل في Linux. وأفترض أن بعض المشاكل كانت مرتبطة ببرامج تشغيل USB لهذه المنصة، وبالتالي فإن أجهزة المودم لم تعمل كما هو متوقع على هذه اللوحة. كما أنها تحتوي على وثائق رديئة ومتناثرة للغاية، لذا استغرقت كل عملية الكثير من الوقت في التنقيب في الأرصفة. حتى العمل العادي مع GPIO استغرق الكثير من الدماء. على سبيل المثال، استغرق الأمر عدة ساعات لإعداد مؤشر LED. ولكن لكي نكون موضوعيين، لم يكن من المهم بشكل أساسي نوع اللوحة الواحدة، والشيء الرئيسي هو أنها تعمل وكانت هناك منافذ USB.

أولاً، أحتاج إلى تثبيت Linux على هذا المنتدى. لكي لا أبحث في براري التوثيق للجميع، وأيضًا لأولئك الذين سيتعاملون مع نظام اللوحة الواحدة هذا، أكتب هذا الفصل.

هناك خياران لتثبيت Linux: على بطاقة SD خارجية أو على MMC داخلي. لقد أمضيت أمسية في محاولة معرفة كيفية جعلها تعمل مع البطاقة، لذلك قررت تثبيتها على MMC، على الرغم من أنه سيكون من الأسهل بلا شك العمل باستخدام بطاقة خارجية.

حول البرامج الثابتة وقال ملتوية هنا. أترجم من الغريب إلى اللغة الروسية. من أجل وميض اللوحة، أحتاج إلى توصيل UART بالجهاز. توصيله على النحو التالي.

  • دبوس الأداة GND: <—> Pin17 من GPIO الخاص بـ VIMs
  • دبوس الأداة TXD: <—> Pin18 من GPIO الخاص بـ VIMs (Linux_Rx)
  • دبوس الأداة RXD: <—> Pin19 من GPIO الخاص بـ VIMs (Linux_Tx)
  • دبوس الأداة VCC: <—> Pin20 من GPIO الخاص بـ VIMs

اختبار سرعة متزامن على عدة أجهزة مودم LTE

وبعد ذلك، قمت بتنزيل البرنامج الثابت من هنا. إصدار البرامج الثابتة المحددة VIM1_Ubuntu-server-bionic_Linux-4.9_arm64_EMMC_V20191231.

من أجل تحميل هذه البرامج الثابتة، أحتاج إلى أدوات مساعدة. مزيد من التفاصيل حول هذا هنا. لم أحاول تحديثه لنظام التشغيل Windows، ولكن أريد أن أخبرك ببضع كلمات حول البرامج الثابتة لنظام التشغيل Linux. أولاً، سأقوم بتثبيت الأدوات المساعدة وفقًا للتعليمات.

git clone https://github.com/khadas/utils
cd /path/to/utils
sudo ./INSTALL

آآند... لا شيء يعمل. لقد أمضيت بضع ساعات في تحرير نصوص التثبيت حتى يتم تثبيت كل شيء بشكل صحيح بالنسبة لي. لا أتذكر ما فعلته هناك، ولكن كان هناك أيضًا ذلك السيرك بالخيول. لذا كن حذرا. لكن بدون هذه الأدوات المساعدة، لا فائدة من تعذيب vim2 أكثر. من الأفضل عدم العبث معه على الإطلاق!

بعد سبع دوائر من الجحيم، وتكوين البرنامج النصي وتثبيته، تلقيت حزمة من أدوات العمل المساعدة. لقد قمت بتوصيل اللوحة عبر USB بجهاز الكمبيوتر الذي يعمل بنظام Linux، وقمت أيضًا بتوصيل UART وفقًا للرسم البياني أعلاه.
أقوم بإعداد محطة minicom المفضلة لدي بسرعة 115200، دون التحكم في أخطاء الأجهزة والبرامج. ودعنا نبدأ.

اختبار سرعة متزامن على عدة أجهزة مودم LTE

عند تحميل VIM2 في محطة UART، أضغط على مفتاح، مثل مفتاح المسافة، لإيقاف التحميل. بعد ظهور السطر

kvim2# 

أدخل الأمر:

kvim2# run update

على المضيف الذي نقوم بالتحميل منه، أقوم بتنفيذ ما يلي:

burn-tool -v aml -b VIM2 -i  VIM2_Ubuntu-server-bionic_Linux-4.9_arm64_EMMC_V20191231.img

هذا كل شيء، أوه. لقد تحققت من وجود Linux على اللوحة. تسجيل الدخول/كلمة المرور khadas:khadas.

بعد ذلك، بعض الإعدادات الأولية البسيطة. لمزيد من العمل، أقوم بتعطيل كلمة المرور لـ Sudo (نعم، ليست آمنة، ولكنها مريحة).

sudo visudo

أقوم بتحرير السطر في النموذج وحفظه

# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) NOPASSWD: ALL

ثم أقوم بتغيير اللغة الحالية بحيث يكون الوقت في موسكو، وإلا فإنه سيكون في غرينتش.

sudo timedatectl set-timezone Europe/Moscow

أو

ln -s /usr/share/zoneinfo/Europe/Moscow /etc/localtime

إذا وجدت صعوبة، فلا تستخدم هذه اللوحة، Raspberry Pi أفضل. بصدق.

مودم هواوي e3372h – 153

كان هذا المودم مصدرًا مهمًا للدم بالنسبة لي، وفي الواقع، أصبح عنق الزجاجة للمشروع بأكمله. بشكل عام، اسم "المودم" لهذه الأجهزة لا يعكس جوهر العمل على الإطلاق: هذا دمج قوي، تحتوي هذه القطعة من الأجهزة على جهاز مركب يتظاهر بأنه قرص مضغوط من أجل تثبيت برامج التشغيل، ثم ينتقل إلى وضع بطاقة الشبكة.

من الناحية المعمارية، من وجهة نظر مستخدم Linux، بعد كل الإعدادات، يبدو الأمر كما يلي: بعد توصيل المودم، لدي واجهة شبكة eth*، والتي تتلقى عبر dhcp عنوان IP 192.168.8.100، والبوابة الافتراضية هو 192.168.8.1.

واللحظة الأكثر أهمية! لا يمكن أن يعمل طراز المودم هذا في وضع المودم، الذي يتم التحكم فيه بواسطة أوامر AT. سيكون كل شيء أبسط من ذلك بكثير، قم بإنشاء اتصالات PPP لكل مودم ثم قم بالعمل معهم. ولكن في حالتي، "نفسه" (بتعبير أدق، غواص Linux وفقًا لقواعد udev)، ينشئ واجهة eth ويعين لها عنوان IP عبر dhcp.

لتجنب المزيد من الالتباس، أقترح نسيان كلمة "مودم" وقول بطاقة الشبكة والبوابة، لأن الأمر في جوهره يشبه توصيل بطاقة شبكة جديدة ببوابة.
عندما يكون هناك مودم واحد فإن ذلك لا يسبب أي مشاكل خاصة، ولكن عندما يكون هناك أكثر من قطعة وهي n-pieces تظهر صورة الشبكة التالية.

اختبار سرعة متزامن على عدة أجهزة مودم LTE

أي أن بطاقات الشبكة تحمل نفس عنوان IP، ولكل منها نفس البوابة الافتراضية. ولكن في الواقع، كل واحد منهم متصل بالمشغل الخاص به.

في البداية، كان لدي حل بسيط: باستخدام الأمر ifconfig أو ip، قم بإيقاف تشغيل جميع الواجهات، ثم قم ببساطة بتشغيل واحدة بدورها واختبارها. وكان الحل جيدًا للجميع، إلا أنه خلال لحظات التبديل لم أتمكن من الاتصال بالجهاز. وبما أن التبديل متكرر وسريع، لم تتح لي الفرصة للاتصال على الإطلاق.

ولذلك، اخترت مسار تغيير عناوين IP الخاصة بأجهزة المودم يدويًا ثم توجيه حركة المرور باستخدام إعدادات التوجيه.

اختبار سرعة متزامن على عدة أجهزة مودم LTE

لم تكن هذه هي نهاية مشاكلي مع أجهزة المودم: في حالة حدوث مشكلات في الطاقة، فقد سقطت، وكان من الضروري توفير مصدر طاقة جيد ومستقر لمحور USB. لقد قمت بحل هذه المشكلة عن طريق لحام الطاقة مباشرة إلى المحور. مشكلة أخرى واجهتها والتي دمرت المشروع بأكمله: بعد إعادة التشغيل أو التشغيل البارد للجهاز، لم يتم اكتشاف جميع أجهزة المودم وليس دائمًا، ولم أتمكن من تحديد سبب حدوث ذلك وبأي خوارزمية. ولكن أول الأشياء أولا.

لكي يعمل المودم بشكل صحيح، قمت بتثبيت حزمة usb-modeswitch.

sudo apt update
sudo apt install -y usb-modeswitch

وبعد ذلك، بعد الاتصال، سيتم اكتشاف المودم وتكوينه بشكل صحيح بواسطة نظام udev الفرعي. أتحقق بمجرد توصيل المودم والتأكد من ظهور الشبكة.
مشكلة أخرى لم أتمكن من حلها: كيف يمكنني الحصول على اسم المشغل الذي نعمل معه من هذا المودم؟ اسم المشغل موجود في واجهة الويب للمودم على 192.168.8.1. هذه صفحة ويب ديناميكية تتلقى البيانات من خلال طلبات Ajax، لذا فإن مجرد الحصول على الصفحة وتحليل الاسم لن ينجح. لذلك بدأت أبحث في كيفية تطوير صفحة ويب، وما إلى ذلك، وأدركت أنني كنت أفعل نوعًا من الهراء. ونتيجة لذلك، بصق، وبدأ المشغل في تلقي استخدام Speedtest API نفسه.

سيكون الأمر أسهل كثيرًا إذا كان للمودم إمكانية الوصول عبر أوامر AT. سيكون من الممكن إعادة تكوينه، وإنشاء اتصال PPP، وتعيين IP، والحصول على مشغل اتصالات، وما إلى ذلك. ولكن للأسف، أنا أعمل مع ما أعطيت لي.

نظام تحديد المواقع جي بي اس

يحتوي جهاز استقبال GPS الذي حصلت عليه على واجهة UART وطاقة. لم يكن هذا هو الحل الأفضل، لكنه كان لا يزال عمليًا وبسيطًا. بدا المتلقي شيئا من هذا القبيل.

اختبار سرعة متزامن على عدة أجهزة مودم LTE

لأكون صادقًا، كانت هذه هي المرة الأولى التي أعمل فيها مع جهاز استقبال GPS، ولكن كما توقعت، فقد تم التفكير في كل شيء بالنسبة لنا منذ وقت طويل. لذلك نحن فقط نستخدم الحلول الجاهزة.

أولاً، أقوم بتمكين uart_AO_B (UART_RX_AO_B, UART_TX_AO_B) لتوصيل GPS.

khadas@Khadas:~$ sudo fdtput -t s /dtb.img /serial@c81004e0 status okay

بعد ذلك أتحقق من نجاح العملية.

khadas@Khadas:~$ fdtget /dtb.img /serial@c81004e0 status
okay

يبدو أن هذا الأمر يقوم بتحرير devtree بسرعة، وهو أمر مريح للغاية.

بعد نجاح هذه العملية، قم بإعادة التشغيل وتثبيت برنامج GPS الخفي.

khadas@Khadas:~$ sudo reboot

تثبيت البرنامج الخفي GPS. أقوم بتثبيت كل شيء وأقطعه على الفور لمزيد من التكوين.

sudo apt install gpsd gpsd-clients -y
sudo killall gpsd
 
/* GPS daemon stop/disable */
sudo systemctl stop gpsd.socket
sudo systemctl disable gpsd.socket

تحرير ملف الإعدادات.

sudo vim /etc/default/gpsd

أقوم بتثبيت UART الذي سيعلق عليه نظام تحديد المواقع العالمي (GPS).

DEVICES="/dev/ttyS4"

وبعد ذلك نقوم بتشغيل كل شيء ونبدأ.

/* GPS daemon enable/start */
sudo systemctl enable gpsd.socket
sudo systemctl start gpsd.socket

بعد ذلك، أقوم بتوصيل GPS.

اختبار سرعة متزامن على عدة أجهزة مودم LTE

سلك GPS في يدي، وأسلاك مصحح أخطاء UART مرئية تحت أصابعي.

أقوم بإعادة التشغيل والتحقق من تشغيل GPS باستخدام برنامج gpsmon.

اختبار سرعة متزامن على عدة أجهزة مودم LTE

لا يمكنك رؤية الأقمار الصناعية في لقطة الشاشة هذه، ولكن يمكنك رؤية الاتصال مع جهاز استقبال GPS، وهذا يعني أن كل شيء على ما يرام.

في بايثون، جربت العديد من الخيارات للعمل مع هذا البرنامج الخفي، لكنني استقرت على الخيار الذي يعمل بشكل صحيح مع بايثون 3.

أقوم بتثبيت المكتبة اللازمة.

sudo -H pip3 install gps3 

وأنا نحت رمز العمل.

from gps3.agps3threaded import AGPS3mechanism
...

def getPositionData(agps_thread):
	counter = 0;
	while True:
		longitude = agps_thread.data_stream.lon
		latitude = agps_thread.data_stream.lat
		if latitude != 'n/a' and longitude != 'n/a':
			return '{}' .format(longitude), '{}' .format(latitude)
		counter = counter + 1
		print ("Wait gps counter = %d" % counter)
		if counter == 10:
			ErrorMessage("Ошибка GPS приемника!!!")
			return "NA", "NA"
		time.sleep(1.0)
...
f __name__ == '__main__':
...
	#gps
	agps_thread = AGPS3mechanism()  # Instantiate AGPS3 Mechanisms
	agps_thread.stream_data()  # From localhost (), or other hosts, by example, (host='gps.ddns.net')
	agps_thread.run_thread()  # Throttle time to sleep after an empty lookup, default '()' 0.2 two tenths of a second

إذا كنت بحاجة للحصول على الإحداثيات، يتم ذلك عن طريق الاتصال التالي:

longitude, latitude = getPositionData(agps_thread)

وفي غضون 1-10 ثوانٍ سأحصل على الإحداثيات أم لا. نعم، لقد قمت بعشر محاولات للحصول على الإحداثيات. ليست مثالية، ملتوية ومنحرفة، لكنها تعمل. قررت أن أفعل ذلك لأن نظام تحديد المواقع العالمي (GPS) يمكن أن يكون استقباله سيئًا ولا يستقبل البيانات دائمًا. إذا كنت تنتظر تلقي البيانات، فإذا كنت تعمل في غرفة بعيدة، فسوف يتجمد البرنامج في هذا المكان. لذلك قمت بتنفيذ هذا الخيار غير الأنيق.

من حيث المبدأ، إذا كان هناك المزيد من الوقت، سيكون من الممكن تلقي البيانات من GPS مباشرة عبر UART، وتحليلها في موضوع منفصل والعمل معها. ولكن لم يكن هناك وقت على الإطلاق، ومن هنا جاء الكود القبيح الوحشي. ونعم، أنا لا أخجل.

الصمام الثنائي الباعث للضوء

كان توصيل LED بسيطًا وصعبًا في نفس الوقت. تكمن الصعوبة الرئيسية في أن الرقم السري الموجود في النظام لا يتوافق مع الرقم السري الموجود على اللوحة ولأن الوثائق مكتوبة باليد اليسرى. لمقارنة الرقم السري للجهاز والرقم السري في نظام التشغيل، تحتاج إلى تشغيل الأمر:

gpio readall

سيتم عرض جدول لمراسلات الدبوس في النظام وعلى اللوحة. وبعد ذلك يمكنني بالفعل تشغيل الدبوس في نظام التشغيل نفسه. في حالتي يتم توصيل LED ل GPIOH_5.

اختبار سرعة متزامن على عدة أجهزة مودم LTE

أقوم بتبديل دبوس GPIO إلى وضع الإخراج.

gpio -g mode 421 out

أنا أكتب الصفر.

gpio -g write 421 0

أنا أكتب واحدة.

gpio -g write 421 1

اختبار سرعة متزامن على عدة أجهزة مودم LTE
كل شيء مضاء بعد كتابة "1"

#gpio subsistem
def gpio_init():
	os.system("gpio -g mode 421 out")
	os.system("gpio -g write 421 1")

def gpio_set(val):
	os.system("gpio -g write 421 %d" % val)
	
def error_blink():
	gpio_set(0)
	time.sleep(0.1)
	gpio_set(1)
	time.sleep(0.1)
	gpio_set(0)
	time.sleep(0.1)
	gpio_set(1)
	time.sleep(0.1)
	gpio_set(0)
	time.sleep(1.0)
	gpio_set(1)

def good_blink():
	gpio_set(1)

الآن، في حالة حدوث أخطاء، أقوم باستدعاء error_blink() وسيومض مؤشر LED بشكل جميل.

العقد البرمجية

واجهة برمجة تطبيقات سبيد تيست

إنه لمن دواعي سرورنا أن تتمتع خدمة speedtest.net بواجهة برمجة تطبيقات python-API الخاصة بها، يمكنك إلقاء نظرة على جيثب.

والشيء الجيد هو أن هناك أكواد مصدر يمكن مشاهدتها أيضًا. يمكن العثور على كيفية العمل مع واجهة برمجة التطبيقات هذه (أمثلة بسيطة) في القسم ذي الصلة.

أقوم بتثبيت مكتبة بايثون باستخدام الأمر التالي.

sudo -H pip3 install speedtest-cli

على سبيل المثال، يمكنك أيضًا تثبيت أداة اختبار السرعة في Ubuntu مباشرة من البرنامج. هذا هو نفس تطبيق python، والذي يمكن تشغيله مباشرة من وحدة التحكم.

sudo apt install speedtest-cli -y

وقياس سرعة الإنترنت لديك.

speedtest-cli
Retrieving speedtest.net configuration...
Testing from B***** (*.*.*.*)...
Retrieving speedtest.net server list...
Selecting best server based on ping...
Hosted by MTS (Moscow) [0.12 km]: 11.8 ms
Testing download speed................................................................................
Download: 7.10 Mbit/s
Testing upload speed......................................................................................................
Upload: 3.86 Mbit/s

ونتيجة لذلك، تماما كما فعلت. كان عليّ الدخول إلى الأكواد المصدرية لاختبار السرعة هذا من أجل تنفيذها بشكل كامل في مشروعي. من أهم المهام الحصول على اسم مشغل الاتصالات من أجل استبداله في اللوحة.

import speedtest
from datetime import datetime
...
#Указываем конкретный сервер для теста
#6053) MaximaTelecom (Moscow, Russian Federation)
servers = ["6053"]
# If you want to use a single threaded test
threads = None
s = speedtest.Speedtest()
#получаем имя оператора сотовой связи
opos = '%(isp)s' % s.config['client']
s.get_servers(servers)
#получаем текстовую строку с параметрами сервера
testserver = '%(sponsor)s (%(name)s) [%(d)0.2f km]: %(latency)s ms' % s.results.server
#тест загрузки
s.download(threads=threads)
#тест выгрузки
s.upload(threads=threads)
#получаем результаты
s.results.share()

#После чего формируется строка для записи в csv-файл.
#получаем позицию GPS
longitude, latitude = getPositionData(agps_thread)
#время и дата
curdata = datetime.now().strftime('%d.%m.%Y')
curtime = datetime.now().strftime('%H:%M:%S')
delimiter = ';'
result_string = opos + delimiter + str(curpos) + delimiter + 
	curdata + delimiter + curtime + delimiter + longitude + ', ' + latitude + delimiter + 
	str(s.results.download/1000.0/1000.0) + delimiter + str(s.results.upload / 1000.0 / 1000.0) + 
	delimiter + str(s.results.ping) + delimiter + testserver + "n"
#тут идет запись в файл логов

هنا أيضًا، تبين أن كل شيء ليس بهذه البساطة، على الرغم من أنه قد يبدو أسهل بكثير. في البداية، كانت معلمة الخوادم تساوي []يقولون، اختر أفضل خادم. ونتيجة لذلك، كان لدي خوادم عشوائية، وكما قد تتخيل، متغيرة السرعة. هذا موضوع معقد للغاية، واستخدام خادم ثابت، إذا كان الأمر كذلك، ثابتًا أو ديناميكيًا، يتطلب البحث. ولكن فيما يلي مثال على الرسوم البيانية لقياس السرعة لمشغل الخط المباشر عند الاختيار الديناميكي لخادم اختبار وخادم ثابت بشكل ثابت.

اختبار سرعة متزامن على عدة أجهزة مودم LTE
نتيجة قياس السرعة عند اختيار السيرفر الديناميكي.

اختبار سرعة متزامن على عدة أجهزة مودم LTE
نتيجة اختبار السرعة، مع خادم واحد تم اختياره بدقة.

أثناء الاختبار، يوجد "فرو" في كلا المكانين، ويجب إزالته باستخدام الطرق الرياضية. ولكن مع الخادم الثابت يكون الأمر أقل قليلاً وتكون السعة أكثر استقرارًا.
بشكل عام، هذا مكان للبحث العظيم. وأقوم بقياس سرعة الخادم الخاص بي باستخدام الأداة المساعدة iperf. لكننا نلتزم بالمواصفات الفنية.

إرسال البريد والأخطاء

لإرسال البريد، جربت عدة عشرات من الخيارات المختلفة، ولكن في النهاية استقرت على ما يلي. لقد قمت بتسجيل صندوق بريد على ياندكس ثم أخذت وهذا مثال على إرسال البريد. لقد قمت بفحصه وطبقته في البرنامج. يفحص هذا المثال خيارات متعددة، بما في ذلك الإرسال من Gmail، وما إلى ذلك. لم أكن أرغب في إعداد خادم البريد الخاص بي ولم يكن لدي الوقت لذلك، ولكن كما اتضح لاحقًا، كان ذلك أيضًا بلا جدوى.

تم إرسال السجلات وفقا للجدول الزمني، إذا كان هناك اتصالكل 6 ساعات: الساعة 00 ظهرًا و06 صباحًا و12 ظهرًا و18 مساءً. أرسلها على النحو التالي.

from send_email import *
...
message_log = "Логи тестирования платы №1"
EmailForSend = ["[email protected]", "[email protected]"]
files = ["/home/khadas/modems_speedtest/csv"]
...
def sendLogs():
	global EmailForSend
	curdata = datetime.now().strftime('%d.%m.%Y')
	сurtime = datetime.now().strftime('%H:%M:%S')
	try:
		for addr_to in EmailForSend:
			send_email(addr_to, message_log, "Логи за " + curdata + " " + сurtime, files)
	except:
		print("Network problem for send mail")
		return False
	return True

تم أيضًا إرسال الأخطاء في البداية. لتبدأ، تم تجميعها في القائمة، ثم إرسالها أيضا باستخدام المجدول، إذا كان هناك اتصال. ومع ذلك، نشأت مشاكل مع حقيقة أن ياندكس لديه حد لعدد الرسائل المرسلة يوميا (هذا هو الألم والحزن والإذلال). نظرًا لأنه قد يكون هناك عدد كبير من الأخطاء حتى في الدقيقة الواحدة، فقد اضطررنا إلى التخلي عن إرسال الأخطاء عبر البريد. لذا ضع في اعتبارك عند إرسال معلومات حول مثل هذه المشكلة تلقائيًا عبر خدمات Yandex.

خادم ردود الفعل

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

بالنسبة لـ VPS اخترت ruvds.com. يمكنك أن تأخذ أبسط خادم. وبشكل عام، لأغراضي، سيكون هذا كافيا. ولكن نظرًا لأنني لم أدفع ثمن الخادم من جيبي الخاص، فقد قررت أن آخذه باحتياطي صغير بحيث يكون كافيًا إذا أردنا نشر واجهة ويب، وخادم SMTP الخاص بنا، وشبكة VPN، وما إلى ذلك. بالإضافة إلى ذلك، ستكون قادرًا على إعداد روبوت Telegram وعدم مواجهة مشكلات في حظره. لذلك اخترت أمستردام والمعلمات التالية.

اختبار سرعة متزامن على عدة أجهزة مودم LTE

كوسيلة للتواصل مع الأجهزة، اختار vim2 اتصال ssh عكسي، وكما أظهرت الممارسة، فهو ليس الأفضل. في حالة فقدان الاتصال، يحتفظ الخادم بالمنفذ ومن المستحيل الاتصال من خلاله لبعض الوقت. لذلك، لا يزال من الأفضل استخدام طرق اتصال أخرى، على سبيل المثال VPN. في المستقبل كنت أرغب في التبديل إلى VPN، لكن لم يكن لدي الوقت.

لن أخوض في تفاصيل إعداد جدار الحماية، وتقييد الحقوق، وتعطيل اتصالات الجذر ssh وغيرها من الحقائق البديهية لإعداد VPS. أود أن أصدق أنك تعرف كل شيء بالفعل. للاتصال عن بعد، أقوم بإنشاء مستخدم جديد على الخادم.

adduser vimssh

أقوم بإنشاء مفاتيح اتصال ssh على أجهزتنا.

ssh-keygen

وأنا نسخها إلى الخادم الخاص بنا.

ssh-copy-id [email protected]

على أجهزتنا، أقوم بإنشاء اتصال SSH عكسي تلقائي عند كل عملية تمهيد.

[Unit] Description=Auto Reverse SSH
Requires=systemd-networkd-wait-online.service
After=systemd-networkd-wait-online.service
[Service] User=khadas
ExecStart=/usr/bin/ssh -NT -o ExitOnForwardFailure=yes -o ServerAliveInterval=60 -CD 8080 -R 8083:localhost:22 [email protected]
RestartSec=5
Restart=always
[Install] WantedBy=multi-user.target

انتبه إلى المنفذ 8083: فهو يحدد المنفذ الذي سأستخدمه للاتصال عبر ssh العكسي. إضافته إلى بدء التشغيل والبدء.

sudo systemctl enable autossh.service
sudo systemctl start autossh.service

يمكنك حتى رؤية الحالة:

sudo systemctl status autossh.service

الآن، على خادم VPS الخاص بنا، إذا قمنا بتشغيل:

ssh -p 8083 khadas@localhost

ثم أصل إلى قطعة الاختبار الخاصة بي. ومن الأجهزة، يمكنني أيضًا إرسال السجلات وأي بيانات عبر SSH إلى الخادم الخاص بي، وهو أمر مريح للغاية.

وضع كل ذلك معا

اختبار سرعة متزامن على عدة أجهزة مودم LTE
عند التشغيل، لنبدأ في التطوير وتصحيح الأخطاء

أوه، حسنًا، هذا كل شيء، لقد وصفت جميع العقد. الآن حان الوقت لتجميع كل ذلك معًا. يمكنك رؤية الكود هنا.

نقطة مهمة تتعلق بالكود: قد لا يبدأ هذا المشروع بهذه الطريقة، لأنه مصمم لمهمة محددة، ذات بنية محددة. على الرغم من أنني أعطي الكود المصدري، سأظل أشرح الأشياء الأكثر قيمة هنا، مباشرة في النص، وإلا فسيكون الأمر غير مفهوم تمامًا.

في البداية، أقوم بتهيئة نظام تحديد المواقع العالمي (GPS)، وGPIO، وإطلاق سلسلة جدولة منفصلة.

#запуск потока планировщика
pShedulerThread = threading.Thread(target=ShedulerThread, args=(1,))
pShedulerThread.start()

برنامج الجدولة بسيط للغاية: فهو يبحث لمعرفة ما إذا كان الوقت قد حان لإرسال الرسائل وما هي حالة الخطأ الحالية. إذا كان هناك علامة خطأ، فإننا يومض مؤشر LED.

#sheduler
def ShedulerThread(name):
	global ready_to_send
	while True:
		d = datetime.today()
		time_x = d.strftime('%H:%M')
		if time_x in time_send_csv:
			ready_to_send = True
		if error_status:
			error_blink()
		else:
			good_blink()
		time.sleep(1)

أصعب جزء في هذا المشروع هو الحفاظ على اتصال ssh العكسي لكل اختبار. يتضمن كل اختبار إعادة تكوين البوابة الافتراضية وخادم DNS. وبما أنه لا أحد يقرأ على أي حال، فاعلم أن القطار لا يركب على قضبان خشبية. من يجد بيضة عيد الفصح يحصل على بعض الحلوى.

للقيام بذلك، أقوم بإنشاء جدول توجيه منفصل -set-mark 0x2 وقاعدة لإعادة توجيه حركة المرور.

def InitRouteForSSH():
	cmd_run("sudo iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 22 -j MARK --set-mark 0x2")
	cmd_run("sudo ip rule add fwmark 0x2/0x2 lookup 102")

يمكنك معرفة المزيد حول كيفية عمله اقرأ في هذا المقال.

بعد ذلك، أذهب إلى حلقة لا نهاية لها، حيث نحصل في كل مرة على قائمة بأجهزة المودم المتصلة (لمعرفة ما إذا كان تكوين الشبكة قد تغير فجأة).

network_list = getNetworklist()

الحصول على قائمة بواجهات الشبكة أمر بسيط للغاية.

def getNetworklist():
	full_networklist = os.listdir('/sys/class/net/')
	network_list = [x for x in full_networklist if "eth" in x and x != "eth0"]
	return network_list

بعد استلام القائمة قمت بضبط عناوين IP لجميع الواجهات كما بينت في الصورة في الفصل الخاص بالمودم.

SetIpAllNetwork(network_list)

def SetIpAllNetwork(network_list):
	for iface in network_list:
		lastip = "%d" % (3 + network_list.index(iface))
		cmd_run ("sudo ifconfig " + iface + " 192.168.8." + lastip +" up")

ثم أقوم ببساطة بتمرير كل واجهة في حلقة. وأنا تكوين كل واجهة.

	for iface in network_list:
		ConfigNetwork(iface)

def ConfigNetwork(iface):
#сбрасываем все настройки
		cmd_run("sudo ip route flush all")
#Назначаем шлюз по умолчанию
		cmd_run("sudo route add default gw 192.168.8.1 " + iface)
#задаем dns-сервер (это нужно для работы speedtest)
		cmd_run ("sudo bash -c 'echo nameserver 8.8.8.8 > /etc/resolv.conf'")

أتحقق من وظائف الواجهة، إذا لم تكن هناك شبكة، فأنا أقوم بإنشاء أخطاء. إذا كانت هناك شبكة، فقد حان وقت العمل!

أقوم هنا بتكوين توجيه ssh إلى هذه الواجهة (إذا لم يتم ذلك)، وإرسال الأخطاء إلى الخادم إذا حان الوقت، وإرسال السجلات، وأخيرًا تشغيل اختبار السرعة وحفظ السجلات في ملف csv.

if not NetworkAvalible():
....
#Здесь мы формируем ошибки
....
else: #Есть сеть, ура, работаем!
#Если у нас проблемный интерфейс, на котором ssh, то меняем его
  if (sshint == lastbanint or sshint =="free"):
    print("********** Setup SSH ********************")
    if sshint !="free":
      сmd_run("sudo ip route del default via 192.168.8.1 dev " + sshint +" table 102")
    SetupReverseSSH(iface)
    sshint = iface
#раз сетка работает, то давай срочно все отправим!!!
    if ready_to_send:
      print ("**** Ready to send!!!")
        if sendLogs():
          ready_to_send = False
        if error_status:
          SendErrors()
#и далее тестируем скорость и сохраняем логи. 

تجدر الإشارة إلى وظيفة إعداد SSH العكسي.

def SetupReverseSSH(iface):
	cmd_run("sudo systemctl stop autossh.service")
	cmd_run("sudo ip route add default via 192.168.8.1 dev " + iface +" table 102")
	cmd_run("sudo systemctl start autossh.service")

وبطبيعة الحال، تحتاج إلى إضافة كل هذا الجمال لبدء التشغيل. للقيام بذلك أقوم بإنشاء ملف:

sudo vim /etc/systemd/system/modems_speedtest.service

وأكتب فيها:

[Unit] Description=Modem Speed Test
Requires=systemd-networkd-wait-online.service
After=systemd-networkd-wait-online.service
[Service] User=khadas
ExecStart=/usr/bin/python3.6 /home/khadas/modems_speedtest/networks.py
RestartSec=5
Restart=always
[Install] WantedBy=multi-user.target

أقوم بتشغيل التحميل التلقائي وأبدأ!

sudo systemctl enable modems_speedtest.service
sudo systemctl start modems_speedtest.service

يمكنني الآن رؤية سجلات ما يحدث باستخدام الأمر:

journalctl -u modems_speedtest.service --no-pager -f

النتائج

حسنًا، الأهم الآن هو ماذا حدث نتيجة لذلك؟ فيما يلي بعض الرسوم البيانية التي تمكنت من التقاطها أثناء عملية التطوير والتصحيح. تم إنشاء الرسوم البيانية باستخدام gnuplot مع البرنامج النصي التالي.

#! /usr/bin/gnuplot -persist
set terminal postscript eps enhanced color solid
set output "Rostelecom.ps"
 
#set terminal png size 1024, 768
#set output "Rostelecom.png"
 
set datafile separator ';'
set grid xtics ytics
set xdata time
set ylabel "Speed Mb/s"
set xlabel 'Time'
set timefmt '%d.%m.%Y;%H:%M:%S'
set title "Rostelecom Speed"

plot "Rostelecom.csv" using 3:6 with lines title "Download", '' using 3:7 with lines title "Upload"
 
set title "Rostelecom 2 Ping"
set ylabel "Ping ms"
plot "Rostelecom.csv" using 3:8 with lines title "Ping"

كانت التجربة الأولى مع مشغل Tele2، والتي أجريتها لعدة أيام.

اختبار سرعة متزامن على عدة أجهزة مودم LTE

لقد استخدمت هنا خادم قياس ديناميكي. تعمل قياسات السرعة، ولكنها تتقلب بشكل كبير جدًا، ولكن بعض القيمة المتوسطة لا تزال مرئية، ويمكن الحصول على ذلك عن طريق تصفية البيانات، على سبيل المثال، باستخدام المتوسط ​​المتحرك.

لاحقًا قمت ببناء عدد من الرسوم البيانية لمشغلي الاتصالات الآخرين. في هذه الحالة، كان هناك بالفعل خادم اختبار واحد، وكانت النتائج أيضًا مثيرة جدًا للاهتمام.

اختبار سرعة متزامن على عدة أجهزة مودم LTE

اختبار سرعة متزامن على عدة أجهزة مودم LTE

اختبار سرعة متزامن على عدة أجهزة مودم LTE

اختبار سرعة متزامن على عدة أجهزة مودم LTE

كما ترون، فإن الموضوع واسع جدًا للبحث ومعالجة هذه البيانات، ومن الواضح أنه لا يستمر لبضعة أسابيع من العمل. لكن…

نتيجة العمل

تم الانتهاء من العمل فجأة لظروف خارجة عن إرادتي. أحد نقاط الضعف في هذا المشروع، في رأيي الشخصي، كان المودم، الذي لا يريد حقًا العمل في وقت واحد مع أجهزة المودم الأخرى، ويقوم بمثل هذه الحيل في كل مرة يتم تحميله فيها. لهذه الأغراض، هناك عدد كبير من نماذج المودم الأخرى، وعادة ما تكون موجودة بالفعل بتنسيق Mini PCI-e ويتم تثبيتها داخل الجهاز وهي أسهل بكثير في التكوين. لكن هذه قصة مختلفة تمامًا. كان المشروع مثيرًا للاهتمام وكنت سعيدًا جدًا لأنني تمكنت من المشاركة فيه.

اختبار سرعة متزامن على عدة أجهزة مودم LTE

المصدر: www.habr.com

إضافة تعليق