Simultánny test rýchlosti na niekoľkých LTE modemoch

Počas karantény som dostal ponuku podieľať sa na vývoji zariadenia na meranie rýchlosti LTE modemov pre viacerých mobilných operátorov.

Simultánny test rýchlosti na niekoľkých LTE modemoch

Zákazník chcel zhodnotiť rýchlosť rôznych telekomunikačných operátorov v rôznych geografických lokalitách, aby vedel pochopiť, ktorý mobilný operátor je pre neho najoptimálnejší pri inštalácii zariadení využívajúcich LTE pripojenie, napríklad na video vysielanie. Zároveň bolo treba problém vyriešiť čo najjednoduchšie a najlacnejšie, bez drahého vybavenia.

Hneď poviem, že úloha nie je najjednoduchšia a najnáročnejšia na znalosti; Poviem vám, s akými problémami som sa stretol a ako som ich vyriešil. Tak, poďme.

Poznámka

Meranie rýchlosti LTE pripojenia je veľmi zložitá záležitosť: musíte si vybrať správne zariadenie a techniku ​​merania a tiež dobre rozumieť topológii a prevádzke mobilnej siete. Navyše rýchlosť môže byť ovplyvnená niekoľkými faktormi: počtom účastníkov v bunke, poveternostnými podmienkami, dokonca aj medzi bunkami a bunkami sa rýchlosť môže dramaticky líšiť v dôsledku topológie siete. Vo všeobecnosti ide o problém s obrovským množstvom neznámych a správne ho môže vyriešiť iba telekomunikačný operátor.

Spočiatku chcel zákazník len odviezť kuriéra s telefónmi operátorov, urobiť merania priamo na telefóne a výsledky merania rýchlosti si zapísať do notebooku. Moje riešenie na meranie rýchlosti lte sietí, aj keď nie ideálne, problém rieši.

Pre nedostatok času som sa rozhodoval nie v prospech pohodlnosti či praktickosti, ale v prospech rýchlosti vývoja. Napríklad reverzné ssh bolo použité na vzdialený prístup namiesto praktickejšej VPN, aby sa ušetril čas na nastavovanie servera a každého jednotlivého klienta.

Technická úloha

Ako je uvedené v článku Bez technických špecifikácií: prečo to klient nechce: Nepracujte bez technických špecifikácií! Nikdy, nikde!

Technická úloha bola celkom jednoduchá, pre pochopenie koncového používateľa ju trochu rozšírim. Výber technických riešení a vybavenia bol diktovaný zákazníkom. Takže samotná technická špecifikácia po všetkých schváleniach:

Založené na jednom palubnom počítači vim2 urobte tester rýchlosti pre lte pripojenia cez H modemyuawei e3372h - 153 niekoľko telekomunikačných operátorov (od jedného po n). Taktiež je potrebné prijímať súradnice z GPS prijímača pripojeného cez UART. Vykonajte merania rýchlosti pomocou služby www.speedtest.net a vložte ich do tabuľky, ako je:

Simultánny test rýchlosti na niekoľkých LTE modemoch

Tabuľka vo formáte csv. Toto znamenie potom posielajte e-mailom každých 6 hodín. V prípade chýb zablikajte LED, ktorá je pripojená k GPIO.

Technické špecifikácie som opísal vo voľnej forme, po mnohých schváleniach. Ale zmysel úlohy je už viditeľný. Na všetko bol daný týždeň. Ale v skutočnosti to trvalo tri týždne. Berúc do úvahy skutočnosť, že som to robil len po hlavnej práci a cez víkendy.

Tu chcem ešte raz upozorniť na skutočnosť, že zákazník sa vopred dohodol na využívaní služby merania rýchlosti a hardvéru, čo značne obmedzovalo moje možnosti. Rozpočet bol tiež obmedzený, takže sa nič špeciálne nenakupovalo. Takže sme museli hrať podľa týchto pravidiel.

Architektúra a development

Schéma je jednoduchá a jasná. Preto to nechám bez špeciálnych komentárov.

Simultánny test rýchlosti na niekoľkých LTE modemoch

Celý projekt som sa rozhodol implementovať v pythone aj napriek tomu, že som nemal s vývojom v tomto jazyku vôbec žiadne skúsenosti. Vybral som si to, pretože tam bolo veľa hotových príkladov a riešení, ktoré by mohli urýchliť vývoj. Preto žiadam všetkých profesionálnych programátorov, aby nehanili moju prvú skúsenosť s vývojom v pythone a vždy si rád vypočujem konštruktívnu kritiku na zlepšenie mojich zručností.

V tomto procese som tiež zistil, že python má dve spustené verzie 2 a 3, v dôsledku čoho som sa rozhodol pre tretiu.

Hardvérové ​​uzly

Jednoplatničkový vim2

Ako hlavný stroj som dostal jednodoskový počítač vim2

Simultánny test rýchlosti na niekoľkých LTE modemoch

Vynikajúci, výkonný multimediálny procesor pre inteligentnú domácnosť a SMART-TV, no na túto úlohu extrémne nevhodný, alebo povedzme málo vhodný. Napríklad jeho hlavný OS je Android a Linux je sekundárny OS, a preto nikto nezaručuje kvalitnú prevádzku všetkých uzlov a ovládačov pod Linuxom. A predpokladám, že niektoré problémy súviseli s USB ovládačmi tejto platformy, takže modemy na tejto doske nefungovali podľa očakávania. Má tiež veľmi zlú a rozhádzanú dokumentáciu, takže každá operácia zabrala veľa času prehrabávaním sa v dokoch. Aj obyčajná práca s GPIO vzala veľa krvi. Napríklad nastavenie LED mi trvalo niekoľko hodín. Ale aby som bol objektívny, v podstate nebolo dôležité, čo to bolo za jednodosku, hlavné bolo, že to fungovalo a boli tam USB porty.

Najprv musím nainštalovať Linux na túto dosku. Aby sme všetkým a aj tým, ktorí sa budú zaoberať týmto jednodoskovým systémom, nehrabali v divočine dokumentácie, píšem túto kapitolu.

Existujú dve možnosti inštalácie Linuxu: na externú SD kartu alebo na internú MMC. Strávil som večer tým, že som prišiel na to, ako to s kartou sfunkčniť, a tak som sa rozhodol nainštalovať ju na MMC, aj keď s externou kartou by sa nepochybne pracovalo oveľa jednoduchšie.

O firmvéri tu krivo povedané. Prekladám z divného do ruštiny. Aby som mohol flashovať dosku, potrebujem pripojiť hardvérový UART. Pripojené to nasledujúcim spôsobom.

  • Tool Pin GND: <—> Pin 17 GPIO VIM
  • Tool Pin TXD: <—> Pin 18 GPIO VIM (Linux_Rx)
  • Tool Pin RXD: <—> Pin 19 GPIO VIM (Linux_Tx)
  • Tool Pin VCC: <—> Pin20 GPIO VIM

Simultánny test rýchlosti na niekoľkých LTE modemoch

Potom som si stiahol firmvér preto. Konkrétna verzia firmvéru VIM1_Ubuntu-server-bionic_Linux-4.9_arm64_EMMC_V20191231.

Na nahranie tohto firmvéru potrebujem pomocné programy. Viac podrobností o tomto tu. Neskúšal som to flashovať pod Windows, ale musím vám povedať pár slov o firmvéri pod Linuxom. Najprv nainštalujem nástroje podľa pokynov.

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

Aaa... Nič nefunguje. Strávil som pár hodín úpravou inštalačných skriptov, aby sa mi všetko nainštalovalo správne. Nepamätám si, čo som tam robil, ale bol tam aj cirkus s koňmi. Buď opatrný. Ale bez týchto nástrojov nemá zmysel vim2 ďalej mučiť. Je lepšie sa s ním vôbec nebaviť!

Po siedmich kruhoch pekla, konfigurácii skriptu a inštalácii som dostal balík pracovných utilít. Dosku som pripojil cez USB k počítaču s Linuxom a tiež som pripojil UART podľa schémy vyššie.
Nastavujem svoj obľúbený minicom terminál na rýchlosť 115200, bez kontroly chýb hardvéru a softvéru. A poďme na to.

Simultánny test rýchlosti na niekoľkých LTE modemoch

Pri načítavaní VIM2 v termináli UART stlačím kláves, napríklad medzerník, aby som zastavil načítanie. Potom, čo sa zobrazí riadok

kvim2# 

Zadávam príkaz:

kvim2# run update

Na hostiteľovi, z ktorého načítavame, vykonám:

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

To je všetko, fuj. Skontroloval som, že na doske je Linux. Prihlasovacie meno/heslo khadas:khadas.

Potom niekoľko menších počiatočných nastavení. Pre ďalšiu prácu deaktivujem heslo pre sudo (áno, nie je bezpečné, ale pohodlné).

sudo visudo

Upravím riadok do formulára a uložím

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

Potom zmením aktuálne miestne nastavenie tak, aby bol čas v Moskve, inak bude v Greenwichi.

sudo timedatectl set-timezone Europe/Moscow

alebo

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

Ak sa vám to zdá ťažké, túto dosku nepoužívajte, Raspberry Pi je lepšia. úprimne.

Modem Huawei e3372h – 153

Tento modem bol pre mňa významným zdrojom krvi a v podstate sa stal prekážkou celého projektu. Vo všeobecnosti názov „modem“ pre tieto zariadenia vôbec neodráža podstatu práce: ide o výkonný kombajn, tento hardvér má zložené zariadenie, ktoré predstiera, že je CD-ROM, aby sa nainštalovali ovládače, a potom sa prepne do režimu sieťovej karty.

Architektonicky to z pohladu linuxaka po vsetkych nastaveniach vyzera takto: po pripojeni modemu mam sietove rozhranie eth*, ktore cez dhcp prijima IP adresu 192.168.8.100 a default gateway je 192.168.8.1.

A najdôležitejší moment! Tento model modemu nemôže pracovať v režime modemu, ktorý je riadený príkazmi AT. Všetko by bolo oveľa jednoduchšie, vytvoriť spojenia PPP pre každý modem a potom s nimi pracovať. Ale v mojom prípade si „sám“ (presnejšie linuxový potápač podľa pravidiel udev) vytvorí eth rozhranie a cez dhcp mu pridelí IP adresu.

Aby ste sa vyhli ďalšiemu zmätku, navrhujem zabudnúť na slovo „modem“ a povedať sieťová karta a brána, pretože v podstate je to ako pripojenie novej sieťovej karty s bránou.
Keď je jeden modem, nespôsobuje to žiadne zvláštne problémy, ale keď je viac ako jeden, konkrétne n-kusov, vzniká nasledujúci sieťový obraz.

Simultánny test rýchlosti na niekoľkých LTE modemoch

To znamená, že n sieťových kariet s rovnakou IP adresou, každá s rovnakou predvolenou bránou. Ale v skutočnosti je každý z nich pripojený k svojmu operátorovi.

Spočiatku som mal jednoduché riešenie: pomocou príkazu ifconfig alebo ip vypnite všetky rozhrania a jednoducho zapnite jedno a otestujte ho. Riešenie bolo dobré pre všetkých, až na to, že počas prepínacích momentov som sa nevedel pripojiť k zariadeniu. A keďže je prepínanie časté a rýchle, vlastne som nemal možnosť sa vôbec pripojiť.

Preto som zvolil cestu ručnej zmeny IP adries modemov a následného riadenia prevádzky pomocou nastavení smerovania.

Simultánny test rýchlosti na niekoľkých LTE modemoch

Týmto sa moje problémy s modemami nekončili: v prípade problémov s napájaním odpadli a bolo potrebné dobré stabilné napájanie rozbočovača USB. Tento problém som vyriešil tvrdým spájkovaním výkonu priamo do náboja. Ďalší problém, s ktorým som sa stretol a ktorý zničil celý projekt: po reštarte alebo studenom štarte zariadenia neboli detekované všetky modemy a nie vždy a nemohol som určiť, prečo sa to stalo a akým algoritmom. Ale prvé veci.

Aby modem fungoval správne, nainštaloval som balík usb-modeswitch.

sudo apt update
sudo apt install -y usb-modeswitch

Potom, po pripojení, bude modem správne detekovaný a nakonfigurovaný subsystémom udev. Skontrolujem to jednoduchým pripojením modemu a uistením sa, že sa zobrazí sieť.
Ďalší problém, ktorý sa mi nepodarilo vyriešiť: ako môžem z tohto modemu získať názov operátora, s ktorým pracujeme? Meno operátora je uvedené vo webovom rozhraní modemu na 192.168.8.1. Toto je dynamická webová stránka, ktorá prijíma údaje prostredníctvom požiadaviek Ajaxu, takže jednoduché wgetovanie stránky a analýza názvu nebude fungovať. Začal som teda hľadať, ako vytvoriť webovú stránku atď., a uvedomil som si, že robím nejaký nezmysel. V dôsledku toho si odpľul a operátor začal prijímať pomocou samotného API Speedtest.

Oveľa jednoduchšie by bolo, keby mal modem prístup cez AT príkazy. Bolo by možné ho prekonfigurovať, vytvoriť ppp pripojenie, prideliť IP, získať telekomunikačného operátora atď. Ale bohužiaľ, pracujem s tým, čo mi bolo dané.

GPS

Prijímač GPS, ktorý som dostal, mal rozhranie UART a napájanie. Nebolo to najlepšie riešenie, ale stále to bolo funkčné a jednoduché. Prijímač vyzeral asi takto.

Simultánny test rýchlosti na niekoľkých LTE modemoch

Úprimne povedané, toto bola moja prvá práca s prijímačom GPS, ale ako som očakával, všetko bolo pre nás vymyslené už dávno. Takže používame len hotové riešenia.

Najprv povolím uart_AO_B (UART_RX_AO_B, UART_TX_AO_B) na pripojenie GPS.

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

Potom skontrolujem úspešnosť operácie.

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

Tento príkaz zjavne upravuje devtree za behu, čo je veľmi výhodné.

Po úspešnom vykonaní tejto operácie reštartujte a nainštalujte démona GPS.

khadas@Khadas:~$ sudo reboot

Inštalácia démona GPS. Všetko nainštalujem a hneď odrežem pre ďalšiu konfiguráciu.

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

Úprava súboru s nastaveniami.

sudo vim /etc/default/gpsd

Inštalujem UART, na ktorom bude visieť GPS.

DEVICES="/dev/ttyS4"

A potom všetko zapneme a začneme.

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

Potom pripojím GPS.

Simultánny test rýchlosti na niekoľkých LTE modemoch

Drôt GPS mám v rukách, vodiče ladiaceho zariadenia UART sú viditeľné pod prstami.

Reštartujem a kontrolujem fungovanie GPS pomocou programu gpsmon.

Simultánny test rýchlosti na niekoľkých LTE modemoch

Na tejto snímke nevidíte satelity, ale vidíte komunikáciu s prijímačom GPS, čo znamená, že je všetko v poriadku.

V pythone som vyskúšal veľa možností práce s týmto démonom, ale rozhodol som sa pre tú, ktorá fungovala správne s pythonom 3.

Nainštalujem potrebnú knižnicu.

sudo -H pip3 install gps3 

A vytvoril som pracovný kód.

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

Ak potrebujem získať súradnice, urobím to pomocou nasledujúceho hovoru:

longitude, latitude = getPositionData(agps_thread)

A do 1-10 sekúnd buď dostanem súradnicu alebo nie. Áno, mal som desať pokusov získať súradnice. Nie optimálne, krivé a nakrivo, ale funguje to. Rozhodol som sa to urobiť, pretože GPS môže mať slabý príjem a nie vždy prijímať dáta. Ak čakáte na príjem dát, tak ak pracujete vo vzdialenej miestnosti, program na tomto mieste zamrzne. Preto som implementoval túto nevkusnú možnosť.

V zásade, ak by bolo viac času, bolo by možné prijímať dáta z GPS priamo cez UART, analyzovať ich v samostatnom vlákne a pracovať s nimi. Ale nebol vôbec čas, preto ten brutálne škaredý kód. A áno, nehanbím sa.

Dióda vyžarujúca svetlo

Zapojenie LED bolo jednoduché a náročné zároveň. Hlavným problémom je, že číslo PIN v systéme nezodpovedá číslu PIN na doske a pretože dokumentácia je písaná ľavou rukou. Ak chcete porovnať hardvérové ​​​​číslo PIN a číslo PIN v OS, musíte spustiť príkaz:

gpio readall

Zobrazí sa tabuľka pinovej korešpondencie v systéme a na nástenke. Potom už môžem pin obsluhovať v samotnom OS. V mojom prípade je LED pripojená k GPIOH_5.

Simultánny test rýchlosti na niekoľkých LTE modemoch

Prepnem GPIO pin do výstupného režimu.

gpio -g mode 421 out

Zapisujem si nulu.

gpio -g write 421 0

Jednu si zapisujem.

gpio -g write 421 1

Simultánny test rýchlosti na niekoľkých LTE modemoch
Po napísaní „1“ všetko svieti

#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)

Teraz v prípade chýb volám error_blink() a LED bude krásne blikať.

Softvérové ​​uzly

Speedtest API

Je veľkou radosťou, že služba speedtest.net má svoje vlastné python-API, môžete sa pozrieť na GitHub.

Dobrá vec je, že existujú zdrojové kódy, ktoré sa dajú aj prezerať. Ako s týmto API pracovať (jednoduché príklady) nájdete v príslušný oddiel.

Nainštalujem knižnicu python pomocou nasledujúceho príkazu.

sudo -H pip3 install speedtest-cli

Napríklad priamo zo softvéru môžete nainštalovať tester rýchlosti v Ubuntu. Ide o rovnakú aplikáciu python, ktorú je možné následne spustiť priamo z konzoly.

sudo apt install speedtest-cli -y

A zmerajte si rýchlosť internetu.

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

Vo výsledku presne ako ja. Musel som sa dostať do zdrojových kódov tohto testu rýchlosti, aby som ich mohol úplnejšie implementovať do môjho projektu. Jednou z najdôležitejších úloh je získať meno telekomunikačného operátora, aby ste ho mohli nahradiť na štítku.

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"
#тут идет запись в файл логов

Aj tu sa ukázalo, že všetko nie je také jednoduché, hoci by sa to zdalo oveľa jednoduchšie. Pôvodne bol parameter serverov rovný [], hovoria, vybrať najlepší server. V dôsledku toho som mal náhodné servery a, ako by ste mohli hádať, premenlivú rýchlosť. Toto je pomerne zložitá téma, použitie pevného servera, ak áno, statického alebo dynamického, vyžaduje výskum. Tu je však príklad grafov merania rýchlosti pre operátora Beeline pri dynamickom výbere testovacieho servera a staticky pevného servera.

Simultánny test rýchlosti na niekoľkých LTE modemoch
Výsledok merania rýchlosti pri výbere dynamického servera.

Simultánny test rýchlosti na niekoľkých LTE modemoch
Výsledok testovania rýchlosti s jedným prísne vybraným serverom.

Počas testovania je na oboch miestach „kožušina“ a je potrebné ju odstrániť pomocou matematických metód. Ale s pevným serverom je to o niečo menej a amplitúda je stabilnejšia.
Vo všeobecnosti je to miesto veľkého výskumu. A zmeral by som rýchlosť môjho servera pomocou nástroja iperf. Držíme sa však technických špecifikácií.

Odosielanie pošty a chyby

Na odosielanie pošty som vyskúšal niekoľko desiatok rôznych možností, ale nakoniec som sa rozhodol pre nasledujúce. Zaregistroval som poštovú schránku na Yandex a potom som ju vzal Toto je príklad odosielania pošty. Skontroloval som to a implementoval do programu. Tento príklad skúma rôzne možnosti vrátane odosielania z gmailu atď. Nechcel som sa obťažovať nastavovaním svojho poštového servera a nemal som na to čas, ale ako sa neskôr ukázalo, bolo to tiež márne.

Protokoly boli odoslané podľa plánovača, ak existuje spojenie, každých 6 hodín: o 00:06, 12:18, XNUMX:XNUMX a XNUMX:XNUMX. Pošlite to nasledovne.

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

Pôvodne boli odoslané aj chyby. Najprv boli nazhromaždené v zozname a potom odoslané aj pomocou plánovača, ak existovalo spojenie. Potom však vznikli problémy s tým, že Yandex má limit na počet správ odoslaných za deň (to je bolesť, smútok a poníženie). Keďže sa môže vyskytnúť obrovské množstvo chýb aj za minútu, museli sme upustiť od odosielania chýb poštou. Majte na pamäti pri automatickom odosielaní informácií o takomto probléme prostredníctvom služieb Yandex.

Server spätnej väzby

Aby som mal prístup k vzdialenému hardvéru a mohol ho prispôsobiť a prekonfigurovať, potreboval som externý server. Vo všeobecnosti, aby sme boli spravodliví, bolo by správne odoslať všetky údaje na server a vytvoriť všetky krásne grafy vo webovom rozhraní. Ale nie všetko naraz.

Pre VPS som si vybral ruvds.com. Môžete si vziať najjednoduchší server. A vo všeobecnosti by to na moje účely stačilo. Ale keďže som za server neplatil z vlastného vrecka, rozhodol som sa to brať s malou rezervou, aby nám stačilo nasadiť webové rozhranie, vlastný SMTP server, VPN atď. Navyše si môžete nastaviť telegramového robota a nebudete mať problémy s jeho zablokovaním. Preto som si vybral Amsterdam a nasledujúce parametre.

Simultánny test rýchlosti na niekoľkých LTE modemoch

Ako spôsob komunikácie s hardvérom zvolil vim2 reverzné ssh pripojenie a ako prax ukázala, nie je to najlepšie. Ak sa spojenie stratí, server drží port a nie je možné sa cez neho nejaký čas pripojiť. Preto je stále lepšie používať iné spôsoby komunikácie, napríklad VPN. V budúcnosti som chcel prejsť na VPN, ale nemal som čas.

Nebudem zachádzať do podrobností o nastavovaní firewallu, obmedzovaní práv, zakázaní pripojení root ssh a iných hlúpostiach pri nastavovaní VPS. Chcel by som veriť, že už všetko viete. Pre vzdialené pripojenie vytvorím nového používateľa na serveri.

adduser vimssh

Generujem kľúče pripojenia ssh na našom hardvéri.

ssh-keygen

A skopírujem ich na náš server.

ssh-copy-id [email protected]

Na našom hardvéri vytváram automatické reverzné ssh pripojenie pri každom bootovaní.

[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

Venujte pozornosť portu 8083: určuje, ktorý port použijem na pripojenie cez reverzné ssh. Pridajte ho do spustenia a začnite.

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

Môžete dokonca vidieť stav:

sudo systemctl status autossh.service

Ak teraz na našom serveri VPS spustíme:

ssh -p 8083 khadas@localhost

Potom sa dostanem k môjmu testovaciemu kusu hardvéru. A z hardvéru môžem tiež posielať protokoly a akékoľvek údaje cez ssh na môj server, čo je veľmi pohodlné.

Všetko to spolu

Simultánny test rýchlosti na niekoľkých LTE modemoch
Zapneme, začneme s vývojom a ladením

Fíha, to je všetko, opísal som všetky uzly. Teraz je čas dať to všetko dokopy. Môžete vidieť kód tu.

Dôležitý bod s kódom: Tento projekt nemusí začať takto, pretože bol prispôsobený pre konkrétnu úlohu, špecifickú architektúru. Aj keď uvádzam zdrojový kód, to najcennejšie vysvetlím tu, priamo v texte, inak je to úplne nezrozumiteľné.

Na začiatku inicializujem gps, gpio a spustím samostatné vlákno plánovača.

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

Plánovač je celkom jednoduchý: pozerá sa, či nastal čas na odosielanie správ a aký je aktuálny chybový stav. Ak sa vyskytne chybový príznak, potom LED dióda bliká.

#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)

Najťažšou časťou tohto projektu je udržiavanie reverzného pripojenia ssh pre každý test. Každý test zahŕňa prekonfigurovanie predvolenej brány a servera DNS. Keďže aj tak nikto nečíta, vedzte, že vlak nejazdí po drevených koľajniciach. Kto nájde veľkonočné vajíčko, dostane sladkosti.

Na tento účel vytvorím samostatnú smerovaciu tabuľku -set-mark 0x2 a pravidlo na presmerovanie prevádzky.

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")

Môžete sa dozvedieť viac o tom, ako to funguje prečítajte si v tomto článku.

Potom idem do nekonečnej slučky, kde zakaždým dostaneme zoznam pripojených modemov (aby sme zistili, či sa konfigurácia siete náhle zmenila).

network_list = getNetworklist()

Získanie zoznamu sieťových rozhraní je celkom jednoduché.

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

Po obdržaní zoznamu som všetkým rozhraniam nastavil IP adresy, ako som to ukázal na obrázku v kapitole o modeme.

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")

Potom jednoducho prechádzam každým rozhraním v slučke. A nakonfigurujem každé rozhranie.

	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'")

Kontrolujem funkčnosť rozhrania, ak nie je sieť, generujem chyby. Ak existuje sieť, potom je čas konať!

Tu nastavím smerovanie ssh na toto rozhranie (ak to nebolo urobené), pošlem chyby na server, ak nadišiel čas, pošlem protokoly a nakoniec spustím speedtest a uložím protokoly do súboru 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()
#и далее тестируем скорость и сохраняем логи. 

Za zmienku stojí funkcia nastavenia spätného 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")

A samozrejme, musíte pridať všetku túto krásu do startupu. Na tento účel vytvorím súbor:

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

A píšem v ňom:

[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

Zapnem automatické načítanie a začnem!

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

Teraz môžem vidieť protokoly toho, čo sa deje pomocou príkazu:

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

výsledky

No a teraz je najdôležitejšie, čo sa stalo výsledkom? Tu je pár grafov, ktoré sa mi podarilo zachytiť počas procesu vývoja a ladenia. Grafy boli vytvorené pomocou gnuplot s nasledujúcim skriptom.

#! /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"

Prvá skúsenosť bola s operátorom Tele2, ktorú som viedol niekoľko dní.

Simultánny test rýchlosti na niekoľkých LTE modemoch

Tu som použil dynamický merací server. Merania rýchlosti fungujú, ale veľmi kolíšu, ale stále je viditeľná určitá priemerná hodnota, ktorú možno získať filtrovaním údajov, napríklad pomocou kĺzavého priemeru.

Neskôr som vytvoril množstvo grafov pre iných telekomunikačných operátorov. V tomto prípade už jeden testovací server existoval a výsledky boli tiež veľmi zaujímavé.

Simultánny test rýchlosti na niekoľkých LTE modemoch

Simultánny test rýchlosti na niekoľkých LTE modemoch

Simultánny test rýchlosti na niekoľkých LTE modemoch

Simultánny test rýchlosti na niekoľkých LTE modemoch

Ako vidíte, téma je na výskum a spracovanie týchto údajov veľmi rozsiahla a zjavne netrvá na pár týždňov práce. Ale…

Výsledok práce

Práca bola náhle dokončená kvôli okolnostiam, ktoré som nemohol ovplyvniť. Jednou zo slabín tohto projektu bol podľa môjho subjektívneho názoru modem, ktorý veľmi nechcel pracovať súčasne s inými modemami a pri každom načítaní robil takéto triky. Na tieto účely existuje veľké množstvo iných modelov modemov, zvyčajne sú už vo formáte Mini PCI-e a sú inštalované vo vnútri zariadenia a ich konfigurácia je oveľa jednoduchšia. Ale to je úplne iný príbeh. Projekt bol zaujímavý a bola som veľmi rada, že som sa ho mohla zúčastniť.

Simultánny test rýchlosti na niekoľkých LTE modemoch

Zdroj: hab.com

Pridať komentár