Gelijktijdige speedtest op meerdere LTE-modems

Tijdens de quarantaine werd mij aangeboden om deel te nemen aan de ontwikkeling van een apparaat voor het meten van de snelheid van LTE-modems voor verschillende mobiele operators.

Gelijktijdige speedtest op meerdere LTE-modems

De klant wilde de snelheid van verschillende telecomoperatoren op verschillende geografische locaties evalueren om te kunnen begrijpen welke mobiele operator voor hem het meest optimaal was bij het installeren van apparatuur via een LTE-verbinding, bijvoorbeeld voor video-uitzendingen. Tegelijkertijd moest het probleem zo eenvoudig en goedkoop mogelijk worden opgelost, zonder dure apparatuur.

Ik zal meteen zeggen dat de taak niet de eenvoudigste en meest kennisintensieve is; ik zal je vertellen welke problemen ik tegenkwam en hoe ik ze heb opgelost. Dus laten we gaan.

Noot

Het meten van de snelheid van een LTE-verbinding is een zeer complexe zaak: je moet de juiste apparatuur en meettechniek kiezen, en ook een goed inzicht hebben in de topologie en werking van het mobiele netwerk. Bovendien kan de snelheid door verschillende factoren worden beïnvloed: het aantal abonnees op een cel, weersomstandigheden en zelfs van cel tot cel kan de snelheid dramatisch variëren als gevolg van de netwerktopologie. Over het algemeen is dit een probleem met een groot aantal onbekenden, en alleen een telecomoperator kan dit correct oplossen.

In eerste instantie wilde de klant alleen maar de koerier besturen met de telefoons van de operators, direct aan de telefoon metingen uitvoeren en vervolgens de snelheidsmeetresultaten in een notitieboekje noteren. Mijn oplossing voor het meten van de snelheid van lte-netwerken, hoewel niet ideaal, lost het probleem op.

Vanwege tijdgebrek heb ik geen beslissingen genomen ten gunste van gemak of bruikbaarheid, maar ten gunste van de snelheid van ontwikkeling. Voor toegang op afstand werd bijvoorbeeld reverse ssh gebruikt, in plaats van de meer praktische VPN, om tijd te besparen bij het instellen van de server en elke individuele client.

Technische taak

Zoals vermeld in het artikel Zonder technische specificaties: waarom de klant het niet wil: Werk niet zonder technische specificaties! Nooit, overal!

De technische taak was vrij eenvoudig, ik zal deze een beetje uitbreiden voor het begrip van de eindgebruiker. De keuze voor technische oplossingen en apparatuur werd bepaald door de klant. Dus de technische specificatie zelf, na alle goedkeuringen:

Gebaseerd op een enkele boardcomputer vim2 maak een snelheidstester voor lte-verbindingen via H-modemsHuawei e3372h - 153 meerdere telecomoperatoren (van één tot n). Het is ook nodig om coördinaten te ontvangen van een GPS-ontvanger die via UART is aangesloten. Voer snelheidsmetingen uit met behulp van de service www.speedtest.net en plaats ze in een tabel als volgt:

Gelijktijdige speedtest op meerdere LTE-modems

Tabel in csv-formaat. Stuur dit bord dan elke 6 uur per e-mail. Bij fouten knippert de LED die op de GPIO is aangesloten.

De technische specificaties heb ik, na vele goedkeuringen, in vrije vorm beschreven. Maar de betekenis van de taak is al zichtbaar. Voor alles werd een week gegeven. Maar in werkelijkheid duurde het drie weken. Hierbij wordt rekening gehouden met het feit dat ik dit alleen deed na mijn hoofdbaan en in de weekenden.

Hier wil ik nogmaals de aandacht vestigen op het feit dat de klant vooraf akkoord ging met het gebruik van de snelheidsmeetservice en hardware, wat mijn mogelijkheden enorm beperkte. Ook het budget was beperkt, dus er werd niets bijzonders aangeschaft. We moesten dus volgens deze regels spelen.

Architectuur en ontwikkeling

Het schema is eenvoudig en duidelijk. Daarom laat ik het zonder speciale opmerkingen achter.

Gelijktijdige speedtest op meerdere LTE-modems

Ik besloot het hele project in Python te implementeren, ondanks het feit dat ik helemaal geen ervaring had met het ontwikkelen in deze taal. Ik heb ervoor gekozen omdat er een heleboel kant-en-klare voorbeelden en oplossingen waren die de ontwikkeling konden versnellen. Daarom vraag ik alle professionele programmeurs om mijn eerste ervaring met het ontwikkelen in Python niet te bekritiseren, en ik ben altijd blij om opbouwende kritiek te horen om mijn vaardigheden te verbeteren.

Ook ontdekte ik tijdens het proces dat Python twee actieve versies 2 en 3 heeft, waardoor ik voor de derde kwam.

Hardware-knooppunten

Vim2 met enkele plaat

Ik kreeg een computer met één board als mijn hoofdmachine vim2

Gelijktijdige speedtest op meerdere LTE-modems

Een prima, krachtige mediaprocessor voor een smart home en SMART-TV, maar uiterst ongeschikt voor deze taak, of zeg maar, matig geschikt. Het belangrijkste besturingssysteem is bijvoorbeeld Android en Linux is een secundair besturingssysteem, en daarom garandeert niemand de hoogwaardige werking van alle knooppunten en stuurprogramma's onder Linux. En ik neem aan dat sommige problemen verband hielden met de USB-stuurprogramma's van dit platform, dus de modems werkten niet zoals verwacht op dit bord. Het beschikt ook over zeer slechte en verspreide documentatie, waardoor elke operatie veel tijd kostte om door de dokken te graven. Zelfs het gewone werk met GPIO kostte veel bloed. Het kostte me bijvoorbeeld enkele uren om de LED in te stellen. Maar om objectief te zijn, het was fundamenteel niet belangrijk wat voor soort single-board het was, het belangrijkste was dat het werkte en dat er USB-poorten waren.

Eerst moet ik Linux op dit bord installeren. Om niet voor iedereen de documentatiewereld af te speuren, en ook voor degenen die met dit single-board-systeem te maken krijgen, schrijf ik dit hoofdstuk.

Er zijn twee opties om Linux te installeren: op een externe SD-kaart of op een interne MMC. Ik heb een avond besteed aan het uitzoeken hoe ik het met de kaart kon laten werken, dus besloot ik het op de MMC te installeren, hoewel het ongetwijfeld veel gemakkelijker zou zijn om met een externe kaart te werken.

Over de firmware hier krom verteld. Ik vertaal van vreemd naar Russisch. Om het bord te flashen, moet ik de hardware-UART aansluiten. Verbonden als volgt.

  • Tool Pin GND: <—> Pin17 van de GPIO van VIM's
  • Tool Pin TXD: <—> Pin18 van VIM's GPIO (Linux_Rx)
  • Tool Pin RXD: <—> Pin19 van VIM's GPIO (Linux_Tx)
  • Tool Pin VCC: <—> Pin20 van de GPIO van VIM's

Gelijktijdige speedtest op meerdere LTE-modems

Daarna heb ik de firmware gedownload vandaar. Specifieke firmwareversie VIM1_Ubuntu-server-bionic_Linux-4.9_arm64_EMMC_V20191231.

Om deze firmware te uploaden, heb ik hulpprogramma's nodig. Meer details hierover hier. Ik heb niet geprobeerd het onder Windows te flashen, maar ik moet je een paar woorden vertellen over firmware onder Linux. Eerst installeer ik de hulpprogramma's volgens de instructies.

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

Aaand... Niets werkt. Ik heb een paar uur besteed aan het bewerken van de installatiescripts, zodat alles voor mij correct zou worden geïnstalleerd. Ik weet niet meer wat ik daar deed, maar daar was ook dat circus met paarden. Dus wees voorzichtig. Maar zonder deze hulpprogramma's heeft het geen zin om vim2 verder te martelen. Het is beter om helemaal niet met hem te rotzooien!

Na zeven cirkels van de hel, scriptconfiguratie en installatie, ontving ik een pakket met werkende hulpprogramma's. Ik heb het bord via USB op mijn Linux-computer aangesloten en ook de UART aangesloten volgens het bovenstaande diagram.
Ik stel mijn favoriete minicomterminal in op een snelheid van 115200, zonder hardware- en softwarefoutcontrole. En laten we beginnen.

Gelijktijdige speedtest op meerdere LTE-modems

Wanneer ik VIM2 in de UART-terminal laad, druk ik op een toets, zoals de spatiebalk, om het laden te stoppen. Nadat de lijn verschijnt

kvim2# 

Ik voer het commando in:

kvim2# run update

Op de host waarvan we laden, voer ik het volgende uit:

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

Dat is het, pfff. Ik heb het gecontroleerd, er staat Linux op het bord. Inloggen/wachtwoord Khadas:khadas.

Daarna enkele kleine initiële instellingen. Voor verder werk schakel ik het wachtwoord voor sudo uit (ja, niet veilig, maar handig).

sudo visudo

Ik bewerk de regel in het formulier en sla deze op

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

Vervolgens verander ik de huidige locatie zodat de tijd in Moskou is, anders in Greenwich.

sudo timedatectl set-timezone Europe/Moscow

of

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

Als je het moeilijk vindt, gebruik dit bord dan niet; Raspberry Pi is beter. Eerlijk gezegd.

Modem Huawei e3372h – 153

Deze modem was voor mij een belangrijke bloedbron en werd in feite het knelpunt van het hele project. Over het algemeen weerspiegelt de naam "modem" voor deze apparaten helemaal niet de essentie van het werk: dit is een krachtige combinatie, dit stuk hardware heeft een samengesteld apparaat dat zich voordoet als een cd-rom om stuurprogramma's te installeren, en schakelt vervolgens over naar de netwerkkaartmodus.

Architectonisch gezien, vanuit het standpunt van een Linux-gebruiker, ziet het er na alle instellingen als volgt uit: nadat ik de modem heb aangesloten, heb ik een eth*-netwerkinterface, die via DHCP het IP-adres 192.168.8.100 ontvangt, en de standaardgateway is 192.168.8.1.

En het belangrijkste moment! Dit modemmodel kan niet werken in de modemmodus, die wordt bestuurd door AT-opdrachten. Alles zou veel eenvoudiger zijn: maak PPP-verbindingen voor elke modem en werk er vervolgens mee. Maar in mijn geval creëert “zichzelf” (meer precies, een Linux-duiker volgens de udev-regels) een eth-interface en wijst er via dhcp een IP-adres aan toe.

Om verdere verwarring te voorkomen, stel ik voor om het woord ‘modem’ te vergeten en netwerkkaart en gateway te zeggen, omdat het in wezen hetzelfde is als het verbinden van een nieuwe netwerkkaart met een gateway.
Wanneer er één modem is levert dit geen bijzondere problemen op, maar wanneer er meer dan één modem is, namelijk n-stukken, ontstaat het volgende netwerkbeeld.

Gelijktijdige speedtest op meerdere LTE-modems

Dat wil zeggen, n netwerkkaarten, met hetzelfde IP-adres, elk met dezelfde standaardgateway. Maar in feite is elk van hen verbonden met zijn eigen operator.

Aanvankelijk had ik een eenvoudige oplossing: gebruik het ifconfig- of ip-commando, schakel alle interfaces uit en schakel er eenvoudigweg één in en test deze. De oplossing was voor iedereen goed, behalve dat ik tijdens de schakelmomenten geen verbinding kon maken met het apparaat. En omdat er frequent en snel wordt geschakeld, had ik eigenlijk helemaal geen gelegenheid om verbinding te maken.

Daarom koos ik voor het pad waarbij ik handmatig de IP-adressen van de modems veranderde en vervolgens verkeer aanstuurde met behulp van de routeringsinstellingen.

Gelijktijdige speedtest op meerdere LTE-modems

Dit was niet het einde van mijn problemen met modems: bij stroomproblemen vielen ze uit en was een goede stabiele voeding naar de USB-hub vereist. Ik heb dit probleem opgelost door de stroom rechtstreeks aan de hub te solderen. Een ander probleem dat ik tegenkwam en dat het hele project verpestte: na een herstart of koude start van het apparaat werden niet alle modems gedetecteerd en niet altijd, en ik kon niet vaststellen waarom dit gebeurde en door welk algoritme. Maar eerst dingen eerst.

Om de modem correct te laten werken, heb ik het usb-modeswitch-pakket geïnstalleerd.

sudo apt update
sudo apt install -y usb-modeswitch

Hierna wordt de modem, na verbinding te hebben gemaakt, correct gedetecteerd en geconfigureerd door het udev-subsysteem. Ik controleer dit door simpelweg de modem aan te sluiten en ervoor te zorgen dat het netwerk verschijnt.
Nog een probleem dat ik niet kon oplossen: hoe kan ik de naam van de operator waarmee we werken uit dit modem halen? De operatornaam staat in de modemwebinterface op 192.168.8.1. Dit is een dynamische webpagina die gegevens ontvangt via Ajax-verzoeken, dus eenvoudigweg de pagina ophalen en de naam ontleden zal niet werken. Dus begon ik te kijken hoe ik een webpagina kon ontwikkelen, enz., en besefte dat ik een of andere onzin deed. Als gevolg hiervan spuugde hij en begon de operator te ontvangen met behulp van de Speedtest API zelf.

Het zou veel eenvoudiger zijn als de modem toegang had via AT-opdrachten. Het zou mogelijk zijn om het opnieuw te configureren, een ppp-verbinding te maken, een IP toe te wijzen, een telecomoperator te krijgen, enz. Maar helaas, ik werk met wat mij is gegeven.

GPS

De GPS-ontvanger die ik kreeg had een UART-interface en voeding. Het was niet de beste oplossing, maar het was nog steeds werkbaar en eenvoudig. De ontvanger zag er ongeveer zo uit.

Gelijktijdige speedtest op meerdere LTE-modems

Eerlijk gezegd was dit de eerste keer dat ik met een GPS-ontvanger werkte, maar zoals ik had verwacht, was alles al lang geleden voor ons bedacht. Wij gebruiken dus alleen kant-en-klare oplossingen.

Eerst schakel ik uart_AO_B (UART_RX_AO_B, UART_TX_AO_B) in om verbinding te maken met GPS.

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

Daarna controleer ik het succes van de operatie.

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

Dit commando bewerkt blijkbaar de devtree onmiddellijk, wat erg handig is.

Na het succes van deze operatie start u opnieuw op en installeert u de GPS-daemon.

khadas@Khadas:~$ sudo reboot

De GPS-daemon installeren. Ik installeer alles en sluit het meteen af ​​voor verdere configuratie.

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

Het instellingenbestand bewerken.

sudo vim /etc/default/gpsd

Ik installeer een UART waaraan de GPS gaat hangen.

DEVICES="/dev/ttyS4"

En dan zetten we alles aan en beginnen.

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

Daarna sluit ik de GPS aan.

Gelijktijdige speedtest op meerdere LTE-modems

De GPS-draad ligt in mijn handen, de UART-debuggerdraden zijn zichtbaar onder mijn vingers.

Ik start opnieuw op en controleer de GPS-werking met behulp van het gpsmon-programma.

Gelijktijdige speedtest op meerdere LTE-modems

Je kunt de satellieten in deze schermafbeelding niet zien, maar je kunt wel de communicatie met de GPS-ontvanger zien, en dit betekent dat alles in orde is.

In Python heb ik veel opties geprobeerd om met deze daemon te werken, maar ik heb gekozen voor degene die correct werkte met Python 3.

Ik installeer de benodigde bibliotheek.

sudo -H pip3 install gps3 

En ik vorm de werkcode.

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

Als ik coördinaten nodig heb, gebeurt dit met de volgende oproep:

longitude, latitude = getPositionData(agps_thread)

En binnen 1-10 seconden krijg ik de coördinaat of niet. Ja, ik heb tien pogingen gehad om coördinaten te krijgen. Niet optimaal, scheef en scheef, maar het werkt. Ik besloot dit te doen omdat GPS een slechte ontvangst kan hebben en niet altijd gegevens kan ontvangen. Als u wacht op het ontvangen van gegevens, zal het programma op deze plek vastlopen als u in een afgelegen kamer werkt. Daarom heb ik deze onelegante optie geïmplementeerd.

Als er meer tijd zou zijn, zou het in principe mogelijk zijn om gegevens van GPS rechtstreeks via UART te ontvangen, deze in een aparte thread te parseren en ermee te werken. Maar er was helemaal geen tijd, vandaar de brutaal lelijke code. En ja, ik schaam me er niet voor.

Lichtgevende diode

Het aansluiten van de LED was eenvoudig en moeilijk tegelijk. De grootste moeilijkheid is dat het pinnummer in het systeem niet overeenkomt met het pinnummer op het bord en dat de documentatie met de linkerhand wordt geschreven. Om het hardwarepincodenummer en het pincodenummer in het besturingssysteem te vergelijken, moet u de opdracht uitvoeren:

gpio readall

Er wordt een tabel met pincorrespondentie in het systeem en op het bord weergegeven. Waarna ik de pin al kan bedienen in het besturingssysteem zelf. In mijn geval is de LED aangesloten GPIOH_5.

Gelijktijdige speedtest op meerdere LTE-modems

Ik schakel de GPIO-pin naar de uitvoermodus.

gpio -g mode 421 out

Ik schrijf nul op.

gpio -g write 421 0

Ik schrijf er één op.

gpio -g write 421 1

Gelijktijdige speedtest op meerdere LTE-modems
Alles is verlicht, nadat u “1” hebt geschreven

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

In geval van fouten roep ik nu error_blink() aan en de LED zal prachtig knipperen.

Softwareknooppunten

Speedtest-API

Het is een grote vreugde dat de speedtest.net-service zijn eigen Python-API heeft, kun je bekijken GitHub.

Het mooie is dat er broncodes bij zitten die ook bekeken kunnen worden. Hoe u met deze API kunt werken (eenvoudige voorbeelden) vindt u in relevante sectie.

Ik installeer de Python-bibliotheek met de volgende opdracht.

sudo -H pip3 install speedtest-cli

U kunt bijvoorbeeld zelfs rechtstreeks vanuit de software een snelheidstester in Ubuntu installeren. Dit is dezelfde Python-applicatie, die vervolgens rechtstreeks vanaf de console kan worden gestart.

sudo apt install speedtest-cli -y

En meet uw internetsnelheid.

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

Met als resultaat, net zoals ik deed. Ik moest in de broncodes van deze snelheidstest duiken om ze vollediger in mijn project te implementeren. Een van de belangrijkste taken is het verkrijgen van de naam van de telecomoperator, zodat deze in de plaat kan worden vervangen.

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

Ook hier bleek alles niet zo eenvoudig te zijn, hoewel het veel eenvoudiger lijkt. Aanvankelijk was de serverparameter gelijk aan [], zeggen ze, kies de beste server. Als gevolg hiervan had ik willekeurige servers en, zoals je misschien wel raadt, variabele snelheid. Dit is een behoorlijk complex onderwerp; het gebruik van een vaste server, statisch of dynamisch, vereist onderzoek. Maar hier is een voorbeeld van snelheidsmetingsgrafieken voor een Beeline-operator bij het dynamisch selecteren van een testserver en een statisch vaste server.

Gelijktijdige speedtest op meerdere LTE-modems
Het resultaat van het meten van snelheid bij het kiezen van een dynamische server.

Gelijktijdige speedtest op meerdere LTE-modems
Het resultaat van een snelheidstest, met één strikt geselecteerde server.

Tijdens het testen zit er op beide plaatsen “pels” en deze moet met behulp van wiskundige methoden worden verwijderd. Maar bij een vaste server is het iets minder en is de amplitude stabieler.
Over het algemeen is dit een plaats van geweldig onderzoek. En ik zou de snelheid van mijn server meten met behulp van het iperf-hulpprogramma. Maar wij houden ons aan de technische specificaties.

E-mail verzenden en fouten

Om e-mail te verzenden heb ik tientallen verschillende opties geprobeerd, maar uiteindelijk kwam ik op het volgende uit. Ik registreerde een mailbox op Yandex en nam vervolgens Dit is een voorbeeld van het verzenden van e-mail. Ik heb het gecontroleerd en in het programma geïmplementeerd. In dit voorbeeld worden verschillende opties onderzocht, waaronder verzenden vanuit Gmail, enz. Ik had geen zin om me bezig te houden met het opzetten van mijn mailserver en had er ook geen tijd voor, maar ook dat was, zo bleek later, tevergeefs.

De logs zijn verzonden volgens de planner, als er een verbinding is, elke 6 uur: om 00 uur, 06 uur, 12 uur en 18 uur. Heb het als volgt verzonden.

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

In eerste instantie werden er ook fouten verzonden. Om te beginnen werden ze verzameld in de lijst en vervolgens ook verzonden via de planner, als er een verbinding was. Toen ontstonden er echter problemen met het feit dat Yandex een limiet heeft op het aantal verzonden berichten per dag (dit is pijn, verdriet en vernedering). Omdat er zelfs per minuut een groot aantal fouten kon optreden, moesten we afzien van het verzenden van fouten per e-mail. Houd er dus rekening mee wanneer u automatisch informatie over een dergelijk probleem verzendt via Yandex-services.

Feedbackserver

Om toegang te krijgen tot een extern stuk hardware en dit te kunnen aanpassen en opnieuw configureren, had ik een externe server nodig. Over het algemeen zou het, om eerlijk te zijn, correct zijn om alle gegevens naar de server te sturen en alle prachtige grafieken in de webinterface te bouwen. Maar niet allemaal tegelijk.

Voor VPS heb ik gekozen ruvds.com. Je zou de eenvoudigste server kunnen nemen. En over het algemeen zou dit voor mijn doeleinden voldoende zijn. Maar aangezien ik de server niet uit eigen zak betaalde, besloot ik hem met een kleine reserve te nemen, zodat het voldoende zou zijn als we een webinterface, onze eigen SMTP-server, VPN, enz. zouden inzetten. Bovendien kunt u een Telegram-bot instellen zonder dat deze wordt geblokkeerd. Daarom heb ik voor Amsterdam en de volgende parameters gekozen.

Gelijktijdige speedtest op meerdere LTE-modems

Als communicatiemethode met de hardware koos vim2 voor een omgekeerde ssh-verbinding en zoals de praktijk heeft uitgewezen, is dit niet de beste. Als de verbinding verbroken wordt, houdt de server de poort vast en is het enige tijd onmogelijk om via deze poort verbinding te maken. Daarom is het nog steeds beter om andere communicatiemethoden te gebruiken, bijvoorbeeld VPN. In de toekomst wilde ik overstappen op VPN, maar had geen tijd.

Ik zal niet ingaan op details over het opzetten van een firewall, het beperken van rechten, het uitschakelen van root-ssh-verbindingen en andere waarheden over het opzetten van een VPS. Ik zou graag willen geloven dat je alles al weet. Voor een externe verbinding maak ik een nieuwe gebruiker aan op de server.

adduser vimssh

Ik genereer ssh-verbindingssleutels op onze hardware.

ssh-keygen

En ik kopieer ze naar onze server.

ssh-copy-id [email protected]

Op onze hardware creëer ik bij elke opstart een automatische omgekeerde ssh-verbinding.

[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

Let op poort 8083: deze bepaalt welke poort ik ga gebruiken om verbinding te maken via reverse ssh. Voeg het toe aan het opstarten en begin.

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

Je kunt zelfs de status zien:

sudo systemctl status autossh.service

Als we nu op onze VPS-server het volgende uitvoeren:

ssh -p 8083 khadas@localhost

Dan kom ik bij mijn teststukje hardware. En vanaf de hardware kan ik ook logs en eventuele data via ssh naar mijn server sturen, erg handig.

Alles bij elkaar

Gelijktijdige speedtest op meerdere LTE-modems
Laten we beginnen met ontwikkelen en debuggen

Oef, nou, dat is het, ik heb alle knooppunten beschreven. Nu is het tijd om alles op een rij te zetten. Je kunt de code zien hier.

Een belangrijk punt met de code: dit project begint misschien niet zo, omdat het op maat is gemaakt voor een specifieke taak, van een specifieke architectuur. Ook al geef ik de broncode, toch leg ik hier, midden in de tekst, de meest waardevolle dingen uit, anders is het volkomen onbegrijpelijk.

In het begin initialiseer ik gps, gpio en start ik een aparte plannerthread.

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

De planner is vrij eenvoudig: hij kijkt of het tijd is om berichten te verzenden en wat de huidige foutstatus is. Als er een foutvlag is, knipperen we de 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)

Het moeilijkste deel van dit project is het onderhouden van de omgekeerde ssh-verbinding voor elke test. Elke test omvat het opnieuw configureren van de standaardgateway en DNS-server. Omdat toch niemand leest, weet dat de trein niet op houten rails rijdt. Wie het paasei vindt, krijgt een snoepje.

Om dit te doen, maak ik een aparte routeringstabel -set-mark 0x2 en een regel om verkeer om te leiden.

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

U kunt meer leren over hoe het werkt lees in dit artikel.

Waarna ik in een eindeloze lus terechtkom, waarbij we elke keer een lijst met aangesloten modems krijgen (om erachter te komen of de netwerkconfiguratie plotseling is gewijzigd).

network_list = getNetworklist()

Het verkrijgen van een lijst met netwerkinterfaces is vrij eenvoudig.

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

Nadat ik de lijst had ontvangen, stelde ik IP-adressen in voor alle interfaces, zoals ik liet zien in de afbeelding in het hoofdstuk over de modem.

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

Vervolgens doorloop ik eenvoudigweg elke interface in een lus. En ik configureer elke interface.

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

Ik controleer de interface op functionaliteit, als er geen netwerk is, genereer ik fouten. Als er een netwerk is, dan is het tijd om actie te ondernemen!

Hier configureer ik ssh-routing naar deze interface (als dit nog niet is gebeurd), stuur ik fouten naar de server als de tijd daar is, stuur ik logs en voer ten slotte een speedtest uit en sla de logs op in een csv-bestand.

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()
#и далее тестируем скорость и сохраняем логи. 

Het is de moeite waard om de functie van het instellen van reverse ssh te vermelden.

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

En natuurlijk moet je al dit moois toevoegen aan het opstarten. Om dit te doen maak ik een bestand aan:

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

En ik schrijf daarin:

[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

Ik zet automatisch laden aan en begin!

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

Nu kan ik logboeken zien van wat er gebeurt met behulp van de opdracht:

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

Bevindingen

Het belangrijkste is nu: wat is er als gevolg daarvan gebeurd? Hier zijn een paar grafieken die ik heb kunnen vastleggen tijdens het ontwikkel- en foutopsporingsproces. De grafieken zijn gebouwd met behulp van gnuplot met het volgende script.

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

De eerste ervaring was met de Tele2-operator, die ik een aantal dagen heb uitgevoerd.

Gelijktijdige speedtest op meerdere LTE-modems

Hier heb ik een dynamische meetserver gebruikt. Snelheidsmetingen werken, maar fluctueren erg, maar er is nog steeds een gemiddelde waarde zichtbaar en deze kan worden verkregen door de gegevens te filteren met bijvoorbeeld een voortschrijdend gemiddelde.

Later heb ik voor andere telecomoperatoren een aantal grafieken gebouwd. In dit geval was er al één testserver en de resultaten waren ook erg interessant.

Gelijktijdige speedtest op meerdere LTE-modems

Gelijktijdige speedtest op meerdere LTE-modems

Gelijktijdige speedtest op meerdere LTE-modems

Gelijktijdige speedtest op meerdere LTE-modems

Zoals u kunt zien, is het onderwerp zeer uitgebreid voor onderzoek en verwerking van deze gegevens, en duurt het duidelijk niet voor een paar weken werk. Maar…

Het resultaat van het werk

Door omstandigheden buiten mijn wil werd het werk abrupt afgerond. Een van de zwakke punten van dit project was, naar mijn subjectieve mening, de modem, die niet echt tegelijkertijd met andere modems wilde werken, en zulke trucjes maakte elke keer dat hij werd geladen. Voor deze doeleinden zijn er een groot aantal andere modemmodellen, meestal hebben ze al het Mini PCI-e-formaat en zijn ze in het apparaat geïnstalleerd en zijn ze veel eenvoudiger te configureren. Maar dat is een heel ander verhaal. Het project was interessant en ik was erg blij dat ik eraan kon deelnemen.

Gelijktijdige speedtest op meerdere LTE-modems

Bron: www.habr.com

Voeg een reactie