Në karantinë, më propozuan të marr pjesë në zhvillimin e një pajisjeje për matjen e shpejtësisë së modemëve LTE për disa operatorë të telefonisë celulare.
Klienti donte të vlerësonte shpejtësinë e të gjithë operatorëve të komunikimit në pika të ndryshme gjeografike, për të kuptuar se cili operator celular është më optimal për instalimin e pajisjeve që përdorin lidhjen LTE, për shembull, për transmetime video. Në të njëjtën kohë, duhej të zgjidhej detyra sa më thjesht dhe më lirë, pa pajisje të shtrenjta.
Të them të drejtën, detyra nuk është më e thjeshta dhe është e ndërlikuar, do t'ju tregoj për problemet që kam hasur dhe si i kam zgjidhur ato. Le të fillojmë.
Shënim
Mërmëria e shpejtësisë së lidhjes LTE është një proces mjaft i komplikuar: është e nevojshme të zgjidhen saktësisht pajisjet dhe metoda e matjes, gjithashtu duhet të kuptohet mirë topologjia dhe funksionimi i rrjetit celular. Plus, shpejtësinë mund ta ndikojnë disa faktorë: numri i abonentëve në qeli, kushtet meteorologjike, madje nga qelia në qeli shpejtësia mund të ndryshojë ndjeshëm për shkak të topologjisë së rrjetit. Në përgjithësi, ky është një detyrë me një mori të madhe të panjohurash, dhe vetëm operatori i komunikimit e zgjidh atë saktësisht.
Fillimisht, klienti donte që thjesht të dërgonte një kurier me telefonat e operatorëve, duke kryer matjet drejtpërdrejt me telefon dhe më pas regjistruar rezultatet e matjes në një copë letër. Zgjidhja ime për matjen e shpejtësisë së rrjetit LTE, ndonëse jo e përsosur, zgjidh detyrën e vendosur.
Për shkak të mungesës së kohës, merrja vendime jo në favor të komoditetit ose praktikës, por në favor të shpejtësisë në zhvillim. Për shembull, për qasje të largët, u ngrit një ssh mbrapsht, në vend të një vpn më praktike, për të kursyer kohë në konfigurimin e serverit dhe të çdo klienti individual.
Detyra teknike
Siç thuhet nĂ« artikull : Mos punoni pa TĂ! KurrĂ«, askund!
Detyra teknike ishte mjaft e thjeshtĂ«, do ta zgjas pak pĂ«r tĂ« kuptuar pĂ«rdoruesin e fundit. Zgjedhja e zgjidhjeve teknike dhe pajisjeve u dikthua nga klienti. Pra, vetĂ« TĂ, pas tĂ« gjitha miratimeve:
NĂ« bazĂ« tĂ« njĂ« kompjuteri me njĂ« pllake vim2 tĂ« bĂ«jmĂ« njĂ« tester tĂ« shpejtĂ«sisĂ« sĂ« lidhjes LTE pĂ«rmes modemĂ«ve Huawei e3372h â 153 disa operatorĂ«ve tĂ« komunikacionit (nga njĂ« nĂ« n). Po ashtu, Ă«shtĂ« e nevojshme tĂ« marrim koordinatat nga GPS-prerĂ«si, i lidhur pĂ«rmes UART. Matjet e shpejtĂ«sisĂ« do tĂ« kryhen pĂ«rmes shĂ«rbimit dhe do tĂ« mbledhĂ« ato nĂ« njĂ« tabelĂ« tĂ« tipit:
Tabelë në formatin csv. Pas kësaj, do të dërgoj këtë tabelë në e-mail çdo 6 orë. Në rast të gabimeve, do të ndriçoj me një LED që është i lidhur me GPIO.
Detyra e projektit e kam përshkruar në formë të lirë, pas shumë miratimeve. Por kuptimi i detyrës tashmë është i qartë. Koha për të gjitha ishte caktuar një javë. Por në realitet, ajo u zgjat në tre javë. Kjo duke marrë parasysh se unë e bëja këtë vetëm pas punës kryesore dhe gjatë fundjavave.
Këtu dua të theksoj përsëri se nga ana e klientit ishte paraprakisht biseduar për përdorimin e shërbimeve të matjes së shpejtësisë dhe pajisjeve, çka e kufizoi ndjeshëm mundësitë e mia. Buxheti ishte gjithashtu i kufizuar, kështu që nuk u ble asgjë tjetër. Pra, duhej të luaja sipas këtyre rregullave.
Arkitektura dhe zhvillimi
Schemi është e thjeshtë dhe e qartë. Prandaj, do ta lë pa komente të veçanta.

E vendosa të realizoj tërë projektin në python, pavarësisht se nuk kisha asnjë përvojë zhvillimi në këtë gjuhë. E zgjodha sepse kishte shumë shembuj dhe zgjidhje gatish që mund të përshpejtonin zhvillimin. Prandaj, kërkoj nga të gjithë programuesit profesionistë të mos më kritikojnë për përvojën time të parë në python, dhe gjithmonë jam i hapur për kritika konstruktive për të rritur aftësitë e mia.
Po ashtu, gjatë procesit zbulova se python ka dy versione kryesore 2 dhe 3, si rezultat ndaluam në versionin e tretë.
Njësitë harduerike
Një përcaktues vim2
Si makinë kryesore më është dhënë një përcaktues me një plakatë

Një kombinim i shkëlqyer, i fuqishëm për shtëpi inteligjente dhe SMART-TV, por jashtëzakonisht i papërshtatshëm për këtë qëllim, ose të paktën kështu mund të them. Për shembull, sistemi kryesor i tij operativ është Android, ndërsa Linux është një sistem operativ ndihmës, dhe si pasojë askush nuk garanton funksionimin e mirë të të gjitha njësive dhe drejtpërdrejtësve nën Linux. Kështu që mendoj se një pjesë e problemeve ishte e lidhur me drejtpërdrejtësit USB të kësaj platforme, kështu që modemët nuk punonin siç e prisja me këtë pllakë. Gjithashtu, ai ka dokumentacion shumë të dobët dhe të çrregullt, kështu që çdo operacion merrte shumë kohë për të kërkuar në dokumente. Edhe një punë e zakonshme me GPIO është një proces i vështirë. Për shembull, për të konfiguruar punën me një LED, më duheshin disa orë. Por, nëse duam të jemi objektivë, në thelb nuk kishte rëndësi se çfarë lloj pllakë ishte, kryesore ishte që të funksiononte dhe të kishte porte USB.
Së pari, duhet të instaloj Linux në këtë pllakë. Që të mos shpenzoj shumë kohë duke kërkuar në dokumentacion, dhe gjithashtu për ata që do të merren me këtë njësi, po shkruaj këtë kapitull.
Ka dy mënyra për të instaluar Linux: në një kartë SD të jashtme, ose në MMC të brendshëm. Kam kaluar një natë me kartën, por nuk munda ta kuptoj si ta bëj të punojë, kështu që vendosa ta instaloj në MMC, megjithëse pa dyshim do të ishte më e lehtë të punoja me një kartë të jashtme.
Për programimin . Po e përkthej nga një gjuhë të çuditshme në rusisht. Për të programuar pllakën, duhet të lidh një UART harduerik. E lidha atë
- Tool Pin GND: Pin17 i GPIO të VIM
- Tool Pin TXD: Pin18 i GPIO të VIM (Linux_Rx)
- Tool Pin RXD: Pin19 i GPIO të VIM (Linux_Tx)
- Tool Pin VCC: Pin20 i GPIO të VIM

Pas kësaj, shkarkova programin . Versioni specifik i programit .
Për të ngarkuar këtë program, më nevojiten disa utilitare. Më shumë detaje rreth kësaj janë dhënë . Nuk kam provuar të programoj nën Windows, por duhet të them disa fjalë për programimin nën Linux. Së pari, do të instaloj utilitat, sipas udhëzimeve.
git clone https://github.com/khadas/utils
cd /path/to/utils
sudo ./INSTALLDheiii⊠AsgjĂ« nuk funksionon. Kalova disa orĂ« duke bĂ«rĂ« ndryshime nĂ« skriptet e instalimit, nĂ« mĂ«nyrĂ« qĂ« gjithçka tĂ« instalohej saktĂ«. ĂfarĂ« bĂ«nte nuk e mbaj mend, por ishte njĂ« cirk i vĂ«rtetĂ«. Pra, bĂ«ni kujdes. Por pa kĂ«to utilitare, nuk ka kuptim tĂ« vazhdoni me vim2. MĂ« mirĂ« mos e lidhni fare me tĂ«!
Pas pas shtatë rrethesh ferri, konfigurimeve të skripteve dhe instalimeve, kam marrë një paketë funksionale të utilitarëve. E lidha pllakën përmes USB në kompjuterin tim Linux, dhe gjithashtu lidha UART sipas skemës më lart.
Po konfiguroni terminalin tim të preferuar minicom me shpejtësi 115200, pa kontroll të gabimeve nga hardueri dhe softueri. Dhe le të fillojmë.

Kur ngarkohet VIM2 në terminalin UART, shtyp ndonjë buton, për shembull hapësirën, për të ndaluar ngarkimin. Pas shfaqjes së rreshtit
kvim2# Shtyp komandën:
kvim2# run updateNĂ« hostin nga i cili ngarkohet, ekzekutoj:
burn-tool -v aml -b VIM2 -i VIM2_Ubuntu-server-bionic_Linux-4.9_arm64_EMMC_V20191231.imgE gjithë kjo, uff. U flashua, ka Linux në pllakat. Login/Password khadas:khadas.
Pas kësaj, disa konfigurime të bëra së pari. Për punë të mëtejshme, çaktivizoj fjalëkalimin për sudo (po, nuk është e sigurt, por është e përshtatshme).
sudo visudoPo redaktoj rreshtin deri në formatin dhe e ruaj
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) NOPASSWD: ALLPas kësaj, ndryshoj gjuhën aktuale që koha të jetë sipas Moskës, përndryshe do të jetë sipas Greenwich-it.
sudo timedatectl set-timezone Europe/Moscowose
ln -s /usr/share/zoneinfo/Europe/Moscow /etc/localtimeNëse ju duket se është e komplikuar, atëherë mos përdorni këtë pllakë, më mirë Raspberry Pi. Sinqerisht.
Modemi Huawei e3372h â 153
Ky modem më ka shkaktuar shumë ndërlikime, dhe në thelb ai u bë pika më e ngushtë e projektit të gjithmbarshëm. Në të vërtetë, emri "modem" për këto pajisje nuk reflekton përmbajtjen e vërtetë të funksionit të tyre: kjo është një makinë e fuqishme, ky metal ka një pajisje përbërëse që sillet si CD-ROM për të instaluar drejtuese, dhe pastaj kalon në modin e kartës rrjet.
Arkitektura, nga këndvështimi i përdoruesit Linux, pas të gjithë konfigurimeve, duket kështu: pas lidhjes së modem, më shfaqet një ndërfaqe rrjeti eth*, e cila merr adresën IP 192.168.8.100 dhe derguesin e paracaktuar 192.168.8.1 përmes DHCP.
Dhe momenti më i rëndësishëm! Ky model modemi nuk di të punojë në modin e modemit që kontrollohet me komanda AT.. Të gjitha do të ishin shumë më të thjeshta, të krijosh lidhje ppp për çdo modem dhe pastaj të veprosh me to. Por në rastin tim "vetë" (në fakt, drejtuarit e Linux sipas rregullave të udev), krijon ndërfaqen eth dhe përmes DHCP i cakton një adresë IP.
Për të mos u ngatërruar më tej, propozoj të harrojmë fjalën "modem" dhe të flasim për kartë rrjeti dhe dergues, për arsyen se në thelb, është si lidhja e një karte të re rrjeti me dergues.
Kur ka vetëm një modem, kjo nuk paraqet probleme të veçanta, por kur ka më shumë se një, dhe konkretisht n-modeme, atëherë na del ky pamje e rrjetit.

Pra nënkupton se ka n kartela rrjeti, çdo njëra me të njëjtin IP-adresë, me të njëjtin gateway për default. Megjithatë, në fakt, secila prej tyre është lidhur me operatorin e vet.
Fillimisht, kisha një zgjidhje të thjeshtë: me komandën ifconfig ose ip të çaktivizoj të gjitha ndërfaqet dhe thjesht të aktivizoj njëra pas tjetrës për ta testuar. Ky zgjidhje ishte e mirë për të gjithë, përveç faktit se gjatë kalimeve nuk kam pasur mundësi të lidhem me pajisjen. Dërgimi ishte i shpeshtë dhe i shpejtë, kështu që në praktikë nuk kam pasur mundësi të lidhem fare.
Prandaj, zgjodha rrugën për të ndryshuar "në mënyrë manuale" adresat IP të modemeve dhe më pas të dërgoj trafikun përmes konfigurimeve të routing.

Pas kësaj, problemet me modemet nuk mbaruan: në rast problemeve me energjinë, ato fikeshin, ishte e nevojshme një energji USB-hubi e qëndrueshme. Këtë problem e zgjidhja duke e lidhur energjinë direkt në hub. Problemi tjetër, me të cilin u ndesha dhe që më shkatërroi të gjithë projektin: pas rinisjes ose ndezjes së ftohtë të pajisjes, nuk të gjithë modemet identifikoheshin gjithmonë, dhe nuk arrita të kuptoja arsyeh për këtë dhe me çfarë algoritmi ndodhte. Por le të kalojmë tek detajet.
Për funksionimin e duhur të modemave, instaluam paketën usb-modeswitch.
sudo apt update
sudo apt install -y usb-modeswitch Pas kësaj, modemi pas lidhjes do të identifikohet dhe konfigurohet siç duhet nga nën-sistemi udev. E testoj duke e lidhur thjesht modem dhe duke u siguruar se rrjeti u shfaq.
Një problem tjetër, që nuk arrita ta zgjidhja: si të marr emrin e operatorit që po përdorim nga ky modem? Emri i operatorit është i vendosur në ndërfaqen në internet të modemave në adresën 192.168.8.1. Kjo është një faqe interneti dinamike që merr të dhënat përmes kërkesave ajax, kështu që nuk do të mund të tërhiqja faqen me wget dhe të nxirrja emrin. Prandaj, fillova të shikoj se si të punoj me faqen në internet dhe tjerë, dhe kuptova se po merresha me diçka të pavlerë. Në fund, hodha dorë dhe fillova të merrja emrin e operatorit përmes API-së së Speedtest.
Shumë do të kishte qenë më e lehtë nëse modemi do të kishte qasje përmes komandave AT. Do të kishim mundur ta riprogramonim, të krijonim një lidhje ppp, të emëronim IP, të merrnim operatorin e komunikimit etj. Por, fatkeqësisht, po punoj me atë që më dhanë.
GPS
GPS pranuese, që më dhanë, kishte një ndërfaqe UART dhe energji. Kjo nuk ishte zgjidhja më e mirë, por megjithatë ishte funksionale dhe e thjeshtë. Pranuesej ishte rreth kësaj forme.

Sinqerisht, punoja për herë të parë me një GPS pranuese, por siç e parashikoja, gjithçka është menduar prej shumë kohësh nga ne. Prandaj thjesht përdorim zgjidhjet e gatshme.
Përfillimisht, aktivizoj uart_AO_B (UART_RX_AO_B, UART_TX_AO_B) për lidhjen me GPS.
khadas@Khadas:~$ sudo fdtput -t s /dtb.img /serial@c81004e0 status okayPasi kontrolloj suksesin e veprimit.
khadas@Khadas:~$ fdtget /dtb.img /serial@c81004e0 status
okayKjo komandë, duket se redakton devtree-në në kohë reale, që është shumë e përshtatshme.
Pas suksesit të këtij veprimi, rindizim dhe instalojmë gps-daemon.
khadas@Khadas:~$ sudo rebootInstalimi i gps-daemon. Instaloj gjithçka dhe e ndal menjëherë për konfigurim të mëtejshëm.
sudo apt install gpsd gpsd-clients -y
sudo killall gpsd
/* Ndalimi/çaktivizimi i GPS daemon */
sudo systemctl stop gpsd.socket
sudo systemctl disable gpsd.socketRedaktoj skedarin e konfigurimit.
sudo vim /etc/default/gpsdAktivizoj UART-in, në të cilin do të lidhet GPS.
DEVICES="/dev/ttyS4"Dhe pastaj gjithçka e aktivizojmë dhe fillojmë.
/* GPS daemon enable/start */
sudo systemctl enable gpsd.socket
sudo systemctl start gpsd.socketPas kësaj, lidhem me GPS.

Në duar kam një kabllo GPS, poshtë gishta duken kabllot UART të debugarit.
Rindizem dhe kontrolloj funksionimin e GPS me programin gpsmon.

Në këtë skrin, nuk duket ndonjë satelit, por duket komunikimi me GPS-pranuese, dhe kjo tregon se gjithçka është mirë.
Kam provuar shumë variacione të punës me këtë daemon në python, por ndalova në atë që punonte saktësisht me python 3.
Instaloj bibliotekën e nevojshme.
sudo -H pip3 install gps3 Dhe krijoj kodin për funksionimin.
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("Gabimi i pranuese GPS!!!")
return "NA", "NA"
time.sleep(1.0)
...
f __name__ == '__main__':
...
#gps
agps_thread = AGPS3mechanism() # Krijo mekanizma AGPS3
agps_thread.stream_data() # Nga localhost (), ose hoste të tjera, për shembull, (host='gps.ddns.net')
agps_thread.run_thread() # Koha e ngadalësimit pas një kërkese bosh, e zakonshme '()' 0.2 dy të dhjetat e një sekondës
Nëse më nevojitet të marr koordinatat, atëherë bëhet me thirrjen e mëposhtme:
longitude, latitude = getPositionData(agps_thread)
Dhe në 1-10 sekonda, ose do të marr koordinatën, ose jo. Po, pata dhjetë përpjekje për të marrë koordinatat. Nuk është optimale, është e ndërlikuar, por funksionon. E bëra kështu sepse GPS mund të kapë dobët dhe nuk merr gjithmonë të dhënat. Nëse pres të marr të dhënat, në rast se punoj në një ambient të mbyllur, programi do të ngecë në atë pikë. Prandaj realizova një variant të tillë, jo shumë elegant.
Në parim, po të kisha më shumë kohë, do të mund të merrja të dhënat nga GPS-në direkt përmes UART, t'i analizoja ato në një rrjedhë të veçantë dhe të punoja me to. Por nuk kisha fare kohë, pra, kodi është tepër i shëmtuar. Dhe po, nuk ndjehem keq për këtë.
Diodë LED
Me lidhjen e diodës LED, gjithçka ishte e thjeshtë dhe e komplikuar njëkohësisht. Vështirësia kryesore ishte se numri i pin-it në sistem nuk përputhet me numrin e pin-it në bord dhe sepse dokumentacioni është shkruar keq. Për të përputhur numrin e pin-it fizik dhe numrin e pin-it në OS, duhet të ekzekutoj komandën:
gpio readallDo të shfaqet një tabelë përputhjeje e pin-it në sistem dhe në bord. Pas kësaj, unë tashmë mund të operoj me pin-in në OS. Në rastin tim, dioda LED është lidhur me GPIOH_5.

Po e çoj pin-in GPIO në modalitetin e daljes.
gpio -g mode 421 outPo shkruaj zero.
gpio -g write 421 0Po shkruaj një.
gpio -g write 421 1 
Të gjitha ndriçojnë, pas shkrimit të "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)
Tani, në rast gabimesh, unëthërras error_blink() dhe dioda LED na bën një flash të bukur.
Njësitë programore
Speedtest API
Një gëzim i madh është që shërbimi speedtest.net ka API-të e veta python, të cilat mund t'i shikoni në .
E mira është se ka kode burimore që gjithashtu mund të shikoni. Si të punoni me këtë API (shembuj të thjeshtë) mund të shihni në .
Unë instalohem bibliotekën python me komandën e mëposhtme.
sudo -H pip3 install speedtest-cliPër shembull, mund ta instaloni speedtester-in në Ubuntu direkt nga rep. Ky është gjithashtu një aplikacion python, të cilin mund ta lanconi direkt nga konsola.
sudo apt install speedtest-cli -yDhe të kryeni matjet e shpejtësisë së internetit tuaj.
speedtest-cli
Po marrjen e konfigurimit speedtest.net...
Duke testuar nga B***** (*.*.*.*)...
Po marrjen e listës së serverëve speedtest.net...
Duke zgjedhur serverin më të mirë në bazë të ping...
E pritur nga MTS (Moskë) [0.12 km]: 11.8 ms
Duke testuar shpejtësinë e shkarkimit................................................................................
Shkarkimi: 7.10 Mbit/s
Duke testuar shpejtësinë e ngarkimit......................................................................................................
Ngarkimi: 3.86 Mbit/s
Si rezultat, ashtu si e bëra unë. Më duhej të hyja në kodet burimore të këtij speedtest-i për ta integruar më shumë në projektin tim. Një nga detyrat më të rëndësishme është të marr emrin e operatorit të telefonisë për ta vendosur në tabelën.
import speedtest
from datetime import datetime
...
# Specify a specific server for testing
#6053) MaximaTelecom (Moscow, Russian Federation)
servers = ["6053"]
# If you want to use a single-threaded test
threads = None
s = speedtest.Speedtest()
# obtain the name of the mobile operator
opos = '%(isp)s' % s.config['client']
s.get_servers(servers)
# obtain a text string with server parameters
testserver = '%(sponsor)s (%(name)s) [%(d)0.2f km]: %(latency)s ms' % s.results.server
# download test
s.download(threads=threads)
# upload test
s.upload(threads=threads)
# obtain results
s.results.share()
# After that, a string is formed for writing to a csv file.
# obtain GPS position
longitude, latitude = getPositionData(agps_thread)
# time and date
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"
# here goes the logging into the file
Here, it also turned out not to be so simple, although it seemed straightforward. Initially, the servers parameter was equal to [], which meant picking the best server. As a result, I had random servers, and as one can guess, fluctuating speeds. This is quite a complex topic; using a fixed server, whether static or dynamic, requires research. But here is an example of the speed measurement graphs of the Beeline operator with dynamically chosen test servers and a statically fixed one.

The speed measurement result when choosing a dynamic server.

The speed test result when a strictly chosen single server is used.
There is some 'noise' during testing both ways, and it needs to be removed using mathematical methods. However, with a fixed server, there's a bit less noise, and the amplitude is more stable.
In general, this is a place for extensive research. I would conduct speed measurements to my server using the iperf tool. But we adhere to the specifications.
Sending Mail and Errors
For sending mail, I tried several dozen different options, but in the end, I settled on the following. I registered an email account with yandex and then took . I tested it and integrated it into the program. In this example, various options are discussed, including sending from gmail, etc. I didnât want to deal with setting up my own mail server and didn't have time for that, but as it turned out later, it was also in vain.
Dërgimi i logeve u realizua përmes planifikuesit, në prani të lidhjes, çdo 6 orë: në orën 00, 06 të mëngjesit, 12 të ditës dhe 18 të mbrëmjes. Dërgohej në mënyrën e mëposhtme.
from send_email import *
...
message_log = "Loget e testimit të bordit nr. 1"
EmailForSend = ["dlinyj@trololo.ru", "pupkin@trololo.ru"]
files = ["/home/khadas/modems_speedtest/csv"]
...
def sendLogs():
global EmailForSend
curdata = datetime.now().strftime('%d.%m.%Y')
curtime = datetime.now().strftime('%H:%M:%S')
try:
for addr_to in EmailForSend:
send_email(addr_to, message_log, "Loget për " + curdata + " " + curtime, files)
except:
print("Problemi i rrjetit për dërgimin e emailit")
return False
return True
Gabimet gjithashtu dërgoheshin fillimisht. Në fillim ato akumuloheshin në një listë, dhe më pas dërgoheshin po ashtu me ndihmën e planifikuesit, në prani të lidhjes. Megjithatë, më vonë u shfaqën probleme me faktin se Yandex ka një kufizim për numrin e mesazheve që mund të dërgohen çdo ditë (këto janë dhimbje, pikëllim dhe poshtërim). Duke qenë se gabimet mund të ishin shumë në një minutë, për rrjedhojë u detyrova të heq dorë nga dërgimi i gabimeve me email. Pra, kini parasysh se, gjatë dërgimit automatik përmes shërbimeve të Yandex, ka një problem të tillë.
Serveri i feedback-ut
Për të pasur qasje në pajisjen e largët dhe për të pasur mundësinë për ta konfiguruar dhe rikonfiguruar, më nevojitej një server i jashtëm. Në përgjithësi, për të qenë i drejtë, do të ishte më mirë që të gjitha të dhënat të dërgoheshin në server dhe në ndërfaqen web të ndërtoheshin të gjitha grafikat e bukura. Por jo gjithçka menjëherë.
Si VPS, kam zgjedhur . Do të mund të merrja serverin më të thjeshtë. Dhe në tërësi, për qëllimet e mia, kjo do të mjaftonte. Por, duke qenë se nuk po paguaja për serverin nga xhepi im, vendosa të marr me një rezerva të vogël, për t'u siguruar që do të mjaftonte, nëse do të realizonim ndërfaqen web, serverin tonë SMTP, VPN, etj. Për më tepër, të kem mundësinë të konfiguroj një bot Telegram dhe të mos kem probleme me bllokimin e tij. Prandaj, zgjodha Amsterdam dhe parametrat e mëposhtëm.

Si mĂ«nyrĂ« lidhjeje me pajisjen vim2, kam zgjedhur lidhjen e kundĂ«rt ssh dhe siç tregon praktika â nuk Ă«shtĂ« mĂ«nyra mĂ« e mirĂ«. NĂ«se lidhja prishhet, serveri mbajnĂ« portin dhe nuk Ă«shtĂ« e mundur tĂ« lidhem pĂ«r njĂ« kohĂ« tĂ« caktuar. Prandaj, gjithsesi Ă«shtĂ« mĂ« mirĂ« tĂ« pĂ«rdoren mĂ«nyra tĂ« tjera lidhjeje, pĂ«r shembull VPN. NĂ« tĂ« ardhmen do tĂ« doja tĂ« kaloj nĂ« VPN, por nuk arrita.
Nuk do të hyj në detajet e konfigurimit të firewalleve, kufizimeve të të drejtave, çaktivizimit të lidhjes ssh për root dhe të vërtetat e tjera të zakonshme të konfigurimit të VPS. Shpresoj të besoni se ju e dini këtë. Për lidhjen e remote, krijoj një përdorues të ri në server.
adduser vimsshNë serverin tonë gjeneroj çelësat e lidhjes ssh.
ssh-keygenDhe i kopjoj në serverin tonë.
ssh-copy-id vimssh@host.comNë serverin tonë krijoj një lidhje automatike të kthyer ssh me çdo ngarkim.
[Unit]
Përshkrimi=Auto Reverse SSH
Kërkon=systemd-networkd-wait-online.service
Pas=systemd-networkd-wait-online.service
[Shërbimi]
Përdorues=khadas
ExecStart=/usr/bin/ssh -NT -o ExitOnForwardFailure=yes -o ServerAliveInterval=60 -CD 8080 -R 8083:localhost:22 vimssh@host.com
RestartSec=5
Rivendos=always
[Install]
WantedBy=multi-user.target
Vini re portin 8083: ai përcakton portin me të cilin unë do të lidhem përmes ssh të kthyer. E shtojmë në ngarkimin automatik dhe e nisim.
sudo systemctl enable autossh.service
sudo systemctl start autossh.serviceMund të shikoni madje statusin:
sudo systemctl status autossh.serviceTani, në serverin tonë VPS, nëse ekzekutoni:
ssh -p 8083 khadas@localhostDo të arrij në pajisjen time testuese. Dhe nga pajisja mund të dërgoj gjithashtu log-et dhe të dhëna të tjera përmes ssh në serverin tim, që është shumë e përshtatshme.
Mblidhni gjithçka së bashku

Fillojmë, kalojmë në zhvillim dhe debugging
Uffff, duket se kam përshkruar të gjitha nyjet. Tani është koha për të mbledhur gjithçka në një grumbull. Mund të shihni kodin .
Një moment i rëndësishëm me kodin: Ky projekt nuk mund të ekzekutohet kështu «në formë të papërpunuar», pasi është përshtatur për një detyrë specifike, për një arkitekturë të caktuar. Edhe pse po ofroj kodi burimor, gjithsesi do të shpjegoj gjërat më të rëndësishme këtu, në tekst, nd otherwise e paqartë.
Në fillim, unë kryej inicializimin e gps, gpio dhe nisim një varg të veçantë të planifikuesit.
#запŃŃĐș ĐżĐŸŃĐŸĐșа ĐżĐ»Đ°ĐœĐžŃĐŸĐČŃĐžĐșа
pShedulerThread = threading.Thread(target=ShedulerThread, args=(1,))
pShedulerThread.start()Planifikuesi është mjaft i thjeshtë: ai kontrollon nëse është koha për të dërguar mesazhe dhe cili është statusi aktual i gabimeve. Nëse ka një flamur gabimi, ndriçojmë me një dritë 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)Pika më e vështirë në këtë projekt është të ruash lidhjen ssh të kthyer në çdo test. Në çdo test, duhet të konfigurohet me të re porta standarde dhe serveri dns. Duke e ditur që askush nuk e lexon, të dini se treni nuk lëviz mbi shina druri. Kush e gjen të fshehtën, do të ketë një ëmbëlsirë.
PĂ«r kĂ«tĂ« krijoj njĂ« tabelĂ« tĂ« veçantĂ« rregullash tĂ« rrugĂ«zimit âset-mark 0x2 dhe njĂ« rregull pĂ«r tĂ« redirigjuar trafikun.
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ë shumë mbi se si funksionon këtë mund të .
Pas kësaj kaloj në një cikël pa fund, ku çdo herë marr një listë të modemëve të lidhur (për të parë, ndoshta konfigurimi i rrjetit ka ndryshuar).
network_list = getNetworklist()Marrja e listës së ndërfaqeve të rrjetit është mjaft e thjeshtë.
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_listPas marrjes së listës, caktoj adresat IP për të gjitha ndërfaqet, siç e kam paraqitur në figurën në kapitullin mbi modemët.
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")Më pas thjesht kaloj nëpër çdo ndërfaqe. Dhe konfiguroni çdo ndërfaqe.
for iface in network_list:
ConfigNetwork(iface)def ConfigNetwork(iface):
#Rivendosim të gjitha konfigurimet
cmd_run("sudo ip route flush all")
#Caktojmë kalimin e parazgjedhur
cmd_run("sudo route add default gw 192.168.8.1 " + iface)
#caktojmë serverin DNS (këto janë të nevojshme për funksionimin e speedtest)
cmd_run ("sudo bash -c 'echo nameserver 8.8.8.8 > \/etc\/resolv.conf'")Kontrolloj ndërfaqen për funksionimin, nëse nuk ka rrjet, formuloj gabime. Nëse ka rrjet, është koha për të vepruar!
Këtu e konfiguroni rrugën ssh për këtë ndërfaqe (nëse nuk është bërë), dërgoj gabimet në server, nëse ka ardhur koha, dërgoj log-et dhe në fund bëj një speedtest dhe ruaj log-et në një skedat csv.
if not NetworkAvalible():
....
#Këtu formulojmë gabimet
....
else: #Ka rrjet, urime, punojmë!
#Nëse kemi një ndërfaqe problematike, në të cilën është ssh, atëherë e ndryshojmë atë
if (sshint == lastbanint or sshint =="free"):
print("********** Konfiguro SSH ********************")
if sshint !="free":
Ńmd_run("sudo ip route del default via 192.168.8.1 dev " + sshint +" table 102")
SetupReverseSSH(iface)
sshint = iface
#tani që rrjeti funksionon, le të dërgojmë gjithçka me ngut!!!
if ready_to_send:
print ("**** Gati për të dërguar!!!")
if sendLogs():
ready_to_send = False
if error_status:
SendErrors()
#dhe më pas testojmë shpejtësinë dhe ruajmë log-et. Ndoshta duhet të flasim për funksionin e konfigurimit të ssh të kundërt.
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")Dhe natyrisht, është e nevojshme ta shtojmë gjithë këtë bukuri në fillim automatik. Për këtë krijoj një skedar:
sudo vim \/etc\/systemd\/system\/modems_speedtest.serviceDhe e regjistroj në të:
[Unit]
Përshkrimi=Testimi i Shpejtësisë së Modemit
Kërkon=systemd-networkd-wait-online.service
Pas=systemd-networkd-wait-online.service
[Shërbimi]
Përdorues=khadas
ExecStart=\/usr\/bin\/python3.6 \/home\/khadas\/modems_speedtest\/networks.py
RestartSec=5
Rivendos=always
[Install]
WantedBy=multi-user.target
Aktivizoj fillimin automatik dhe filloj!
sudo systemctl enable modems_speedtest.service
sudo systemctl start modems_speedtest.serviceTani mund të shikoj log-et e asaj që ndodh me komandën:
journalctl -u modems_speedtest.service --no-pager -fRezultatet
Tani është tani çelësi kryesor, çfarë arritëm si rezultat? Dëgjo disa grafike që arrita të kap nga procesi i zhvillimit dhe debuggingut. Grafiket u ndërtuan me ndihmën e gnuplot me skriptin e mëposhtëm.
#! /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"
Eksperimenti i parë ishte me operatorin Tele2, i cili u zhvillua gjatë disa ditëve.

Këtu përdora një server matës dinamik. Matjet e shpejtësisë funksionojnë, por janë shumë të pashtuara, megjithatë shpesh shihet një mesatare e caktuar, dhe kjo mund të merret duke bërë filtrimin e të dhënave, për shembull, me mesatare lëvizëse.
Më vonë ndërtova një sërë grafikësh për operatorë të tjerë. Në këtë rast, serveri i testimit ishte një, dhe rezultatet ishin gjithashtu shumë interesante.




Siç duket, tema është shumë e gjerë për studim dhe përpunim të këtyre të dhënave, dhe padyshim nuk mund të mjaftohet me disa javë pune. Por...
Përfundimi i punës
Puna përfundoi papritur për arsye që nuk varet nga unë. Një nga dobësitë e këtij projekti, sipas mendimit tim subjektiv, ishte modemi, i cili nuk donte shumë të punonte njëkohësisht me modema të tjerë, dhe në çdo ngarkim bënte këto truke. Për këto qëllime, ka një numër të madh të modeleve të tjera të modemave, të cilat zakonisht kanë formatin Mini PCI-e dhe vendosen brenda pajisjes, dhe është shumë më e lehtë t'i konfigurosh ato. Por kjo është një histori krejt tjetër. Projekti ishte interesante dhe isha shumë i lumtur që arrita të merrja pjesë në të.
Burimi: habr.com

