Sabay-sabay na speedtest sa ilang LTE modem

Sa panahon ng quarantine, inalok akong lumahok sa pagbuo ng isang device para sa pagsukat ng bilis ng LTE modem para sa ilang cellular operator.

Sabay-sabay na speedtest sa ilang LTE modem

Nais ng customer na suriin ang bilis ng iba't ibang telecom operator sa iba't ibang heograpikal na lokasyon upang maunawaan kung aling cellular operator ang pinakamainam para sa kanya kapag nag-i-install ng kagamitan gamit ang isang LTE na koneksyon, halimbawa, para sa mga video broadcast. Kasabay nito, ang problema ay kailangang malutas nang simple at mura hangga't maaari, nang walang mamahaling kagamitan.

Sasabihin ko kaagad na ang gawain ay hindi ang pinakasimple at pinaka-masinsinang kaalaman; Sasabihin ko sa iyo kung anong mga problema ang naranasan ko at kung paano ko nalutas ang mga ito. So, tara na.

Nota

Ang pagsukat sa bilis ng isang koneksyon sa LTE ay isang napakakomplikadong bagay: kailangan mong piliin ang tamang kagamitan at pamamaraan ng pagsukat, at mayroon ding mahusay na pag-unawa sa topology at pagpapatakbo ng cellular network. Dagdag pa, ang bilis ay maaaring maimpluwensyahan ng ilang mga kadahilanan: ang bilang ng mga subscriber sa isang cell, mga kondisyon ng panahon, kahit na mula sa cell sa cell ang bilis ay maaaring mag-iba nang malaki dahil sa topology ng network. Sa pangkalahatan, ito ay isang problema sa isang malaking bilang ng mga hindi alam, at isang telecom operator lamang ang makakalutas nito nang tama.

Sa una, gusto lang ng customer na imaneho ang courier gamit ang mga telepono ng mga operator, direktang kumuha ng mga sukat sa telepono at pagkatapos ay isulat ang mga resulta ng pagsukat ng bilis sa isang notebook. Ang aking solusyon para sa pagsukat ng bilis ng mga network ng lte, bagaman hindi perpekto, ay nalulutas ang problema.

Dahil sa kakulangan ng oras, gumawa ako ng mga desisyon hindi pabor sa kaginhawahan o pagiging praktikal, ngunit pabor sa bilis ng pag-unlad. Halimbawa, ginamit ang reverse ssh para sa malayuang pag-access, sa halip na ang mas praktikal na VPN, upang makatipid ng oras sa pag-set up ng server at bawat indibidwal na kliyente.

Teknikal na gawain

Gaya ng nakasaad sa artikulo Nang walang mga teknikal na detalye: kung bakit hindi ito gusto ng kliyente: Huwag gumana nang walang teknikal na pagtutukoy! Hindi kailanman, kahit saan!

Ang teknikal na gawain ay medyo simple, palalawakin ko ito ng kaunti para sa pag-unawa ng end user. Ang pagpili ng mga teknikal na solusyon at kagamitan ay idinidikta ng customer. Kaya, ang teknikal na detalye mismo, pagkatapos ng lahat ng pag-apruba:

Batay sa isang solong board computer vim2 gumawa ng speed tester para sa mga lte na koneksyon sa pamamagitan ng H modemuawei e3372h - 153 ilang telecom operator (mula isa hanggang n). Kinakailangan din na makatanggap ng mga coordinate mula sa isang GPS receiver na konektado sa pamamagitan ng UART. Gumawa ng mga sukat ng bilis gamit ang serbisyo www.speedtest.net at ilagay ang mga ito sa isang mesa tulad ng:

Sabay-sabay na speedtest sa ilang LTE modem

Talahanayan sa format na csv. Pagkatapos ay ipadala ang sign na ito sa pamamagitan ng e-mail tuwing 6 na oras. Sa kaso ng mga error, i-blink ang LED na konektado sa GPIO.

Inilarawan ko ang mga teknikal na detalye sa libreng anyo, pagkatapos ng maraming pag-apruba. Ngunit ang kahulugan ng gawain ay nakikita na. Isang linggo ang ibinigay para sa lahat. Ngunit sa katotohanan ay tumagal ito ng tatlong linggo. Ito ay isinasaalang-alang ang katotohanan na ginawa ko lamang ito pagkatapos ng aking pangunahing trabaho at sa katapusan ng linggo.

Dito nais kong muling bigyang pansin ang katotohanan na ang customer ay sumang-ayon nang maaga sa paggamit ng serbisyo ng pagsukat ng bilis at hardware, na lubos na naglimita sa aking mga kakayahan. Limitado din ang budget, kaya walang espesyal na binili. Kaya kailangan naming maglaro ayon sa mga patakarang ito.

Arkitektura at pag-unlad

Ang scheme ay simple at halata. Samakatuwid, iiwan ko ito nang walang anumang mga espesyal na komento.

Sabay-sabay na speedtest sa ilang LTE modem

Nagpasya akong ipatupad ang buong proyekto sa python, sa kabila ng katotohanan na wala akong karanasan sa pagbuo sa wikang ito. Pinili ko ito dahil mayroong isang grupo ng mga nakahandang halimbawa at solusyon na maaaring mapabilis ang pag-unlad. Samakatuwid, hinihiling ko sa lahat ng mga propesyonal na programmer na huwag pagagalitan ang aking unang karanasan sa pagbuo sa python, at lagi akong natutuwa na makarinig ng nakabubuo na pagpuna upang mapabuti ang aking mga kasanayan.

Gayundin sa proseso natuklasan ko na ang python ay may dalawang tumatakbong bersyon 2 at 3, bilang isang resulta ay nanirahan ako sa pangatlo.

Mga node ng hardware

Single-plate vim2

Binigyan ako ng single-board computer bilang aking pangunahing makina vim2

Sabay-sabay na speedtest sa ilang LTE modem

Isang mahusay, makapangyarihang media processor para sa isang matalinong tahanan at SMART-TV, ngunit lubhang hindi angkop para sa gawaing ito, o, sabihin nating, hindi angkop. Halimbawa, ang pangunahing OS nito ay Android, at ang Linux ay isang pangalawang OS, at nang naaayon ay walang gumagarantiya sa mataas na kalidad na operasyon ng lahat ng mga node at driver sa ilalim ng Linux. At ipinapalagay ko na ang ilan sa mga problema ay nauugnay sa mga USB driver ng platform na ito, kaya ang mga modem ay hindi gumana tulad ng inaasahan sa board na ito. Mayroon din itong napakahirap at nakakalat na dokumentasyon, kaya ang bawat operasyon ay tumagal ng maraming oras sa paghuhukay sa mga pantalan. Maging ang ordinaryong trabaho sa GPIO ay kumuha ng maraming dugo. Halimbawa, inabot ako ng ilang oras upang i-set up ang LED. Ngunit, upang maging layunin, sa panimula ay hindi mahalaga kung anong uri ng single-board ito, ang pangunahing bagay ay gumagana ito at mayroong mga USB port.

Una, kailangan kong i-install ang Linux sa board na ito. Upang hindi masuri ang mga ligaw ng dokumentasyon para sa lahat, at para din sa mga haharap sa single-board system na ito, isinusulat ko ang kabanatang ito.

Mayroong dalawang mga opsyon upang i-install ang Linux: sa isang panlabas na SD card o sa isang panloob na MMC. Ginugol ko ang isang gabi na sinusubukang malaman kung paano ito gagawin gamit ang card, kaya nagpasya akong i-install ito sa MMC, kahit na walang pag-aalinlangan na magiging mas madaling magtrabaho sa isang panlabas na card.

Tungkol sa firmware baluktot na sabi dito. Nagsasalin ako mula sa kakaiba sa Russian. Upang i-flash ang board, kailangan kong ikonekta ang UART ng hardware. Nakakonekta ito tulad ng sumusunod.

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

Sabay-sabay na speedtest sa ilang LTE modem

Pagkatapos nito, na-download ko ang firmware kaya. Partikular na bersyon ng firmware VIM1_Ubuntu-server-bionic_Linux-4.9_arm64_EMMC_V20191231.

Upang ma-upload ang firmware na ito, kailangan ko ng mga utility. Higit pang mga detalye tungkol dito dito. Hindi ko pa sinubukang i-flash ito sa ilalim ng Windows, ngunit kailangan kong sabihin sa iyo ang ilang mga salita tungkol sa firmware sa ilalim ng Linux. Una, i-install ko ang mga utility ayon sa mga tagubilin.

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

Aaand... Walang gumagana. Gumugol ako ng ilang oras sa pag-edit ng mga script ng pag-install upang ang lahat ay mai-install nang tama para sa akin. Hindi ko matandaan kung ano ang ginawa ko doon, ngunit mayroon ding sirko na may mga kabayo. Kaya mag-ingat ka. Ngunit kung wala ang mga kagamitang ito ay walang saysay na pahirapan pa ang vim2. Buti na lang wag mo na siyang guluhin!

Pagkatapos ng pitong bilog ng impiyerno, pagsasaayos ng script at pag-install, nakatanggap ako ng isang pakete ng mga gumaganang kagamitan. Ikinonekta ko ang board sa pamamagitan ng USB sa aking Linux computer, at ikinonekta rin ang UART ayon sa diagram sa itaas.
Ise-set up ko ang paborito kong minicom terminal para sa bilis na 115200, nang walang kontrol sa error sa hardware at software. At magsimula na tayo.

Sabay-sabay na speedtest sa ilang LTE modem

Kapag naglo-load ng VIM2 sa terminal ng UART, pinindot ko ang isang key, tulad ng spacebar, upang ihinto ang paglo-load. Pagkatapos lumitaw ang linya

kvim2# 

Ipinasok ko ang utos:

kvim2# run update

Sa host kung saan kami naglo-load, isinasagawa ko ang:

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

Iyon lang, phew. Tinignan ko, may Linux sa board. Login/password khadas:khadas.

Pagkatapos nito, ilang menor de edad na paunang setting. Para sa karagdagang trabaho, hindi ko pinagana ang password para sa sudo (oo, hindi secure, ngunit maginhawa).

sudo visudo

In-edit ko ang linya sa form at i-save

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

Pagkatapos ay binago ko ang kasalukuyang lokal upang ang oras ay nasa Moscow, kung hindi man ay nasa Greenwich.

sudo timedatectl set-timezone Europe/Moscow

o

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

Kung nahihirapan ka, huwag gamitin ang board na ito; Mas mahusay ang Raspberry Pi. Sa totoo lang.

Modem Huawei e3372h – 153

Ang modem na ito ay isang makabuluhang pinagmumulan ng dugo para sa akin, at, sa katunayan, ito ang naging bottleneck ng buong proyekto. Sa pangkalahatan, ang pangalang "modem" para sa mga device na ito ay hindi sumasalamin sa kakanyahan ng trabaho: ito ay isang malakas na pagsasama, ang piraso ng hardware na ito ay may pinagsama-samang aparato na nagpapanggap na isang CD-ROM upang mai-install ang mga driver, at pagkatapos ay lumipat sa network card mode.

Sa arkitektura, mula sa punto ng view ng isang gumagamit ng Linux, pagkatapos ng lahat ng mga setting, ganito ang hitsura: pagkatapos ikonekta ang modem, mayroon akong eth* network interface, na sa pamamagitan ng dhcp ay natatanggap ang IP address na 192.168.8.100, at ang default na gateway ay 192.168.8.1.

At ang pinakamahalagang sandali! Ang modelo ng modem na ito ay hindi maaaring gumana sa modem mode, na kinokontrol ng mga utos ng AT. Ang lahat ay magiging mas simple, lumikha ng mga koneksyon sa PPP para sa bawat modem at pagkatapos ay gumana sa kanila. Ngunit sa aking kaso, ang "kanyang sarili" (mas tiyak, isang Linux diver ayon sa mga panuntunan ng udev), ay lumilikha ng isang eth interface at nagtatalaga ng isang IP address dito sa pamamagitan ng dhcp.

Upang maiwasan ang karagdagang pagkalito, iminumungkahi kong kalimutan ang salitang "modem" at sabihin ang network card at gateway, dahil sa esensya, ito ay tulad ng pagkonekta ng isang bagong network card sa isang gateway.
Kapag mayroong isang modem, hindi ito nagiging sanhi ng anumang mga espesyal na problema, ngunit kapag mayroong higit sa isa, katulad n-piraso, ang sumusunod na larawan ng network ay lumitaw.

Sabay-sabay na speedtest sa ilang LTE modem

Ibig sabihin, n network card, na may parehong IP address, bawat isa ay may parehong default na gateway. Ngunit sa katunayan, ang bawat isa sa kanila ay konektado sa sarili nitong operator.

Sa una, mayroon akong isang simpleng solusyon: gamit ang ifconfig o ip command, patayin ang lahat ng mga interface at i-on lamang ang isa at subukan ito. Ang solusyon ay mabuti para sa lahat, maliban na sa mga sandali ng paglipat ay hindi ako nakakonekta sa device. At dahil madalas at mabilis ang paglipat, wala talaga akong pagkakataon na kumonekta.

Samakatuwid, pinili ko ang landas ng manu-manong pagpapalit ng mga IP address ng mga modem at pagkatapos ay pagmamaneho ng trapiko gamit ang mga setting ng pagruruta.

Sabay-sabay na speedtest sa ilang LTE modem

Hindi ito ang katapusan ng aking mga problema sa mga modem: sa kaso ng mga problema sa kuryente, nahulog sila, at kinakailangan ang isang mahusay na stable na power supply sa USB hub. Nalutas ko ang problemang ito sa pamamagitan ng matigas na paghihinang ng kapangyarihan nang direkta sa hub. Ang isa pang problema na nakatagpo ko at nasira ang buong proyekto: pagkatapos ng pag-reboot o malamig na pagsisimula ng device, hindi lahat ng mga modem ay nakita at hindi palaging, at hindi ko matukoy kung bakit nangyari ito at sa pamamagitan ng kung anong algorithm. Ngunit una sa lahat.

Para gumana ng tama ang modem, na-install ko ang usb-modeswitch package.

sudo apt update
sudo apt install -y usb-modeswitch

Pagkatapos nito, pagkatapos kumonekta, ang modem ay tama na matutukoy at mai-configure ng udev subsystem. Sinusuri ko sa pamamagitan lamang ng pagkonekta sa modem at pagtiyak na lilitaw ang network.
Isa pang problema na hindi ko malutas: paano ko makukuha ang pangalan ng operator na pinagtatrabahuhan namin mula sa modem na ito? Ang pangalan ng operator ay nakapaloob sa modem web interface sa 192.168.8.1. Ito ay isang dynamic na web page na tumatanggap ng data sa pamamagitan ng mga kahilingan ng Ajax, kaya ang simpleng pag-wget sa pahina at pag-parse ng pangalan ay hindi gagana. Kaya sinimulan kong tingnan kung paano bumuo ng isang web page, atbp., at napagtanto na gumagawa ako ng ilang uri ng katarantaduhan. Bilang resulta, dumura siya, at nagsimulang tumanggap ang operator gamit ang Speedtest API mismo.

Mas magiging madali kung ang modem ay may access sa pamamagitan ng AT command. Posibleng i-reconfigure ito, lumikha ng koneksyon sa ppp, magtalaga ng IP, kumuha ng operator ng telecom, atbp. Ngunit sayang, nagtatrabaho ako sa kung ano ang ibinigay sa akin.

GPS

Ang GPS receiver na ibinigay sa akin ay may interface at kapangyarihan ng UART. Hindi ito ang pinakamahusay na solusyon, ngunit ito ay magagawa pa rin at simple. Ang receiver ay ganito ang hitsura.

Sabay-sabay na speedtest sa ilang LTE modem

Sa totoo lang, ito ang unang pagkakataon kong magtrabaho sa isang GPS receiver, ngunit tulad ng inaasahan ko, ang lahat ay pinag-isipan para sa amin matagal na ang nakalipas. Kaya gumagamit na lang kami ng mga ready-made na solusyon.

Una, pinagana ko ang uart_AO_B (UART_RX_AO_B, UART_TX_AO_B) upang ikonekta ang GPS.

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

Pagkatapos ay tinitingnan ko ang tagumpay ng operasyon.

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

Ang utos na ito ay tila nag-e-edit ng devtree sa mabilisang, na napaka-maginhawa.

Pagkatapos ng tagumpay ng operasyong ito, i-reboot at i-install ang GPS daemon.

khadas@Khadas:~$ sudo reboot

Pag-install ng GPS daemon. Ini-install ko ang lahat at pinutol ito kaagad para sa karagdagang pagsasaayos.

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

Pag-edit ng file ng mga setting.

sudo vim /etc/default/gpsd

Nag-i-install ako ng UART kung saan nakabitin ang GPS.

DEVICES="/dev/ttyS4"

At pagkatapos ay i-on namin ang lahat at magsimula.

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

Pagkatapos nito, ikinonekta ko ang GPS.

Sabay-sabay na speedtest sa ilang LTE modem

Ang GPS wire ay nasa aking mga kamay, ang UART debugger wires ay nakikita sa ilalim ng aking mga daliri.

Nag-reboot ako at sinusuri ang operasyon ng GPS gamit ang gpsmon program.

Sabay-sabay na speedtest sa ilang LTE modem

Hindi mo makikita ang mga satellite sa screenshot na ito, ngunit makikita mo ang komunikasyon sa GPS receiver, at nangangahulugan ito na maayos ang lahat.

Sa python, sinubukan ko ang maraming mga pagpipilian para sa pagtatrabaho sa daemon na ito, ngunit nanirahan ako sa isa na gumana nang tama sa python 3.

Nag-install ako ng kinakailangang library.

sudo -H pip3 install gps3 

At nililok ko ang code ng trabaho.

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

Kung kailangan kong makakuha ng mga coordinate, ginagawa ito sa sumusunod na tawag:

longitude, latitude = getPositionData(agps_thread)

At sa loob ng 1-10 segundo makukuha ko ang coordinate o hindi. Oo, mayroon akong sampung pagtatangka upang makakuha ng mga coordinate. Hindi optimal, baluktot at patago, ngunit ito ay gumagana. Nagpasya akong gawin ito dahil ang GPS ay maaaring magkaroon ng mahinang pagtanggap at hindi palaging makatanggap ng data. Kung maghihintay kang makatanggap ng data, kung magtatrabaho ka sa isang malayong silid, ang programa ay mag-freeze sa lugar na ito. Samakatuwid, ipinatupad ko ang hindi magandang opsyong ito.

Sa prinsipyo, kung mayroong mas maraming oras, posibleng makatanggap ng data mula sa GPS nang direkta sa pamamagitan ng UART, i-parse ito sa isang hiwalay na thread at magtrabaho kasama nito. Ngunit walang oras, kaya ang brutal na pangit na code. At oo, hindi ako nahihiya.

LED

Ang pagkonekta sa LED ay simple at mahirap sa parehong oras. Ang pangunahing kahirapan ay ang pin number sa system ay hindi tumutugma sa pin number sa board at dahil ang dokumentasyon ay nakasulat gamit ang kaliwang kamay. Upang ihambing ang numero ng pin ng hardware at ang numero ng pin sa OS, kailangan mong patakbuhin ang command:

gpio readall

Ang isang talaan ng pin na sulat sa system at sa board ay ipapakita. Pagkatapos nito ay maaari ko nang patakbuhin ang pin sa OS mismo. Sa aking kaso ang LED ay konektado sa GPIOH_5.

Sabay-sabay na speedtest sa ilang LTE modem

Inilipat ko ang GPIO pin sa output mode.

gpio -g mode 421 out

Nagsusulat ako ng zero.

gpio -g write 421 0

Nagsusulat ako ng isa.

gpio -g write 421 1

Sabay-sabay na speedtest sa ilang LTE modem
Lahat ay naiilawan, pagkatapos isulat ang "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)

Ngayon, sa kaso ng mga error, tinatawagan ko ang error_blink() at ang LED ay kumikislap nang maganda.

Mga node ng software

Pinakamabilis na API

Isang malaking kagalakan na ang serbisyo ng speedtest.net ay may sariling python-API, maaari mong tingnan Github.

Ang maganda ay mayroong mga source code na maaari ding tingnan. Kung paano magtrabaho sa API na ito (mga simpleng halimbawa) ay makikita sa kaugnay na seksyon.

Nag-install ako ng library ng python gamit ang sumusunod na utos.

sudo -H pip3 install speedtest-cli

Halimbawa, maaari ka ring mag-install ng speed tester sa Ubuntu nang direkta mula sa software. Ito ang parehong python application, na maaaring direktang ilunsad mula sa console.

sudo apt install speedtest-cli -y

At sukatin ang iyong bilis ng Internet.

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

Bilang isang resulta, tulad ng ginawa ko. Kinailangan kong pumasok sa mga source code ng speed test na ito upang mas ganap na maipatupad ang mga ito sa aking proyekto. Isa sa pinakamahalagang gawain ay ang pagkuha ng pangalan ng telecom operator upang mapalitan ito sa plato.

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

Dito, masyadong, ang lahat ay naging hindi gaanong simple, bagaman ito ay tila mas simple. Sa una, ang parameter ng mga server ay katumbas ng [], sabi nila, piliin ang pinakamahusay na server. Bilang resulta, nagkaroon ako ng mga random na server, at, tulad ng maaari mong hulaan, variable na bilis. Ito ay medyo kumplikadong paksa, gamit ang isang nakapirming server, kung gayon, static o dynamic, ay nangangailangan ng pananaliksik. Ngunit narito ang isang halimbawa ng mga graph ng pagsukat ng bilis para sa isang operator ng Beeline kapag dynamic na pumipili ng isang test server at isang statically fixed.

Sabay-sabay na speedtest sa ilang LTE modem
Ang resulta ng pagsukat ng bilis kapag pumipili ng isang dynamic na server.

Sabay-sabay na speedtest sa ilang LTE modem
Ang resulta ng pagsubok sa bilis, na may isang mahigpit na napiling isang server.

Sa panahon ng pagsubok, mayroong "fur" sa parehong mga lugar, at kailangan itong alisin gamit ang mga pamamaraan ng matematika. Ngunit sa isang nakapirming server ito ay bahagyang mas mababa at ang amplitude ay mas matatag.
Sa pangkalahatan, ito ay isang lugar ng mahusay na pananaliksik. At susukatin ko ang bilis ng aking server gamit ang iperf utility. Ngunit nananatili kami sa mga teknikal na pagtutukoy.

Pagpapadala ng mail at mga error

Upang magpadala ng mail, sinubukan ko ang ilang dosenang iba't ibang mga opsyon, ngunit sa huli ay nanirahan ako sa mga sumusunod. Nagrehistro ako ng mailbox sa Yandex at pagkatapos ay kumuha Ito ay isang halimbawa ng pagpapadala ng mail. Sinuri ko ito at ipinatupad ito sa programa. Sinusuri ng halimbawang ito ang iba't ibang opsyon, kabilang ang pagpapadala mula sa gmail, atbp. Hindi ko nais na mag-abala sa pag-set up ng aking mail server at wala akong oras para dito, ngunit sa paglaon, ito ay naging walang kabuluhan.

Ang mga log ay ipinadala ayon sa scheduler, kung may koneksyon, tuwing 6 na oras: sa 00 o'clock, 06 am, 12 noon at 18 pm. Ipinadala ito bilang mga sumusunod.

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

Ang mga error ay ipinadala din sa simula. Upang magsimula sa, sila ay naipon sa listahan, at pagkatapos ay ipinadala din gamit ang scheduler, kung mayroong koneksyon. Gayunpaman, pagkatapos ay lumitaw ang mga problema sa katotohanan na ang Yandex ay may limitasyon sa bilang ng mga mensahe na ipinadala bawat araw (ito ay sakit, kalungkutan at kahihiyan). Dahil maaaring may malaking bilang ng mga error kahit bawat minuto, kinailangan naming iwanan ang pagpapadala ng mga error sa pamamagitan ng koreo. Kaya tandaan kapag awtomatikong nagpapadala ng impormasyon tungkol sa naturang problema sa pamamagitan ng mga serbisyo ng Yandex.

Server ng feedback

Upang magkaroon ng access sa isang malayong piraso ng hardware at ma-customize at ma-reconfigure ito, kailangan ko ng isang panlabas na server. Sa pangkalahatan, upang maging patas, tama na ipadala ang lahat ng data sa server at bumuo ng lahat ng magagandang graph sa web interface. Ngunit hindi lahat ng sabay-sabay.

Para sa VPS ang pinili ko ruvds.com. Maaari mong kunin ang pinakasimpleng server. At sa pangkalahatan, para sa aking mga layunin ito ay sapat na. Ngunit dahil hindi ko binayaran ang server mula sa sarili kong bulsa, nagpasya akong kunin ito gamit ang isang maliit na reserba upang ito ay sapat na kung kami ay mag-deploy ng isang web interface, ang aming sariling SMTP server, VPN, atbp. Dagdag pa, makapag-set up ng Telegram bot at walang mga problema sa pag-block nito. Samakatuwid, pinili ko ang Amsterdam at ang mga sumusunod na parameter.

Sabay-sabay na speedtest sa ilang LTE modem

Bilang isang paraan ng komunikasyon sa hardware, pinili ng vim2 ang isang reverse ssh na koneksyon at, tulad ng ipinakita ng kasanayan, hindi ito ang pinakamahusay. Kung nawala ang koneksyon, hawak ng server ang port at imposibleng kumonekta sa pamamagitan nito nang ilang oras. Samakatuwid, mas mahusay pa ring gumamit ng iba pang mga paraan ng komunikasyon, halimbawa VPN. Sa hinaharap, gusto kong lumipat sa VPN, ngunit wala akong oras.

Hindi ako pupunta sa mga detalye ng pag-set up ng firewall, paghihigpit sa mga karapatan, hindi pagpapagana ng mga koneksyon sa root ssh at iba pang mga katotohanan ng pag-set up ng VPS. Gusto kong maniwala na alam mo na ang lahat. Para sa isang malayuang koneksyon, gumawa ako ng bagong user sa server.

adduser vimssh

Bumubuo ako ng mga ssh connection key sa aming hardware.

ssh-keygen

At kinokopya ko sila sa aming server.

ssh-copy-id [email protected]

Sa aming hardware, gumagawa ako ng awtomatikong reverse ssh na koneksyon sa bawat boot.

[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

Bigyang-pansin ang port 8083: tinutukoy nito kung aling port ang gagamitin ko upang kumonekta sa pamamagitan ng reverse ssh. Idagdag ito sa startup at magsimula.

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

Maaari mo ring makita ang katayuan:

sudo systemctl status autossh.service

Ngayon, sa aming VPS server, kung tatakbo kami:

ssh -p 8083 khadas@localhost

Pagkatapos ay pumunta ako sa aking test piece ng hardware. At mula sa hardware ay maaari rin akong magpadala ng mga log at anumang data sa pamamagitan ng ssh sa aking server, na kung saan ay napaka-maginhawa.

Pinagsama ang lahat

Sabay-sabay na speedtest sa ilang LTE modem
Pag-on, simulan natin ang pag-develop at pag-debug

Phew, well, iyon lang, inilarawan ko ang lahat ng mga node. Ngayon ay oras na upang pagsamahin ang lahat. Maaari mong makita ang code dito.

Isang mahalagang punto sa code: Ang proyektong ito ay maaaring hindi magsimula nang ganito, dahil ito ay iniayon para sa isang partikular na gawain, ng isang partikular na arkitektura. Kahit na ibinibigay ko ang source code, ipapaliwanag ko pa rin ang mga pinakamahalagang bagay dito, sa mismong teksto, kung hindi, ito ay ganap na hindi maintindihan.

Sa simula, sinisimulan ko ang gps, gpio at naglulunsad ng isang hiwalay na thread ng scheduler.

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

Ang scheduler ay medyo simple: tinitingnan nito kung dumating na ang oras upang magpadala ng mga mensahe at kung ano ang kasalukuyang status ng error. Kung mayroong isang error na flag, pagkatapos ay i-blink namin ang 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)

Ang pinakamahirap na bahagi ng proyektong ito ay ang pagpapanatili ng reverse ssh na koneksyon para sa bawat pagsubok. Kasama sa bawat pagsubok ang muling pag-configure ng default na gateway at DNS server. Dahil walang nagbabasa pa rin, alamin na ang tren ay hindi nakasakay sa mga riles na gawa sa kahoy. Kung sinuman ang makakahanap ng Easter egg ay makakakuha ng ilang kendi.

Para magawa ito, gumawa ako ng hiwalay na routing table -set-mark 0x2 at isang panuntunan upang i-redirect ang trapiko.

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

Maaari kang matuto nang higit pa tungkol sa kung paano ito gumagana basahin sa artikulong ito.

Pagkatapos nito ay pumunta ako sa isang walang katapusang loop, kung saan sa bawat oras na nakakakuha kami ng isang listahan ng mga konektadong modem (upang malaman kung ang configuration ng network ay biglang nagbago).

network_list = getNetworklist()

Ang pagkuha ng isang listahan ng mga interface ng network ay medyo simple.

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

Matapos matanggap ang listahan, nagtakda ako ng mga IP address sa lahat ng mga interface, tulad ng ipinakita ko sa larawan sa kabanata tungkol sa 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")

Pagkatapos ay dumaan lang ako sa bawat interface sa isang loop. At kino-configure ko ang bawat 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'")

Sinusuri ko ang interface para sa pag-andar, kung walang network, pagkatapos ay bumubuo ako ng mga error. Kung may network, oras na para kumilos!

Dito ko i-configure ang ssh routing sa interface na ito (kung hindi pa ito nagawa), magpadala ng mga error sa server kung dumating na ang oras, magpadala ng mga log at sa wakas ay magpatakbo ng speedtest at i-save ang mga log sa isang csv file.

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

Ito ay nagkakahalaga ng pagbanggit sa function ng pag-set up ng reverse 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")

At siyempre, kailangan mong idagdag ang lahat ng kagandahang ito sa pagsisimula. Upang gawin ito lumikha ako ng isang file:

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

At isinulat ko dito:

[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

Binuksan ko ang autoloading at magsisimula!

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

Ngayon ay nakikita ko ang mga log ng kung ano ang nangyayari gamit ang command:

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

Natuklasan

Well, ngayon ang pinakamahalagang bagay ay, ano ang nangyari bilang isang resulta? Narito ang ilang mga graph na nagawa kong makuha sa panahon ng proseso ng pag-develop at pag-debug. Ang mga graph ay binuo gamit ang gnuplot na may sumusunod na 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"

Ang unang karanasan ay kasama ang Tele2 operator, na isinagawa ko sa loob ng ilang araw.

Sabay-sabay na speedtest sa ilang LTE modem

Dito ako gumamit ng isang dynamic na server ng pagsukat. Gumagana ang mga pagsukat ng bilis, ngunit napakalaki ng pagbabago, ngunit ang ilang average na halaga ay nakikita pa rin, at ito ay maaaring makuha sa pamamagitan ng pag-filter ng data, halimbawa, na may average na gumagalaw.

Nang maglaon ay gumawa ako ng ilang mga graph para sa iba pang mga operator ng telecom. Sa kasong ito, mayroon nang isang server ng pagsubok, at ang mga resulta ay napaka-interesante din.

Sabay-sabay na speedtest sa ilang LTE modem

Sabay-sabay na speedtest sa ilang LTE modem

Sabay-sabay na speedtest sa ilang LTE modem

Sabay-sabay na speedtest sa ilang LTE modem

Tulad ng nakikita mo, ang paksa ay napakalawak para sa pagsasaliksik at pagproseso ng data na ito, at malinaw na hindi tumatagal ng ilang linggo ng trabaho. Pero…

Ang resulta ng trabaho

Ang gawain ay biglang natapos dahil sa mga pangyayari na hindi ko kontrolado. Ang isa sa mga kahinaan ng proyektong ito, sa aking pansariling opinyon, ay ang modem, na ayaw talagang gumana nang sabay-sabay sa iba pang mga modem, at gumawa ng gayong mga trick sa tuwing ito ay na-load. Para sa mga layuning ito, mayroong isang malaking bilang ng iba pang mga modelo ng modem; kadalasan sila ay nasa Mini PCI-e na format at naka-install sa loob ng device at mas madaling i-configure. Ngunit iyon ay isang ganap na naiibang kuwento. Ang proyekto ay kawili-wili at ako ay labis na natutuwa na ako ay nakilahok dito.

Sabay-sabay na speedtest sa ilang LTE modem

Pinagmulan: www.habr.com

Magdagdag ng komento