Samtempa rapidtesto sur pluraj LTE-modemoj

Dum kvaranteno, mi estis proponita partopreni en la disvolviĝo de aparato por mezuri la rapidecon de LTE-modemoj por pluraj ĉelaj telefonistoj.

Samtempa rapidtesto sur pluraj LTE-modemoj

La kliento volis taksi la rapidecon de diversaj telekomunikaj telefonistoj en malsamaj geografiaj lokoj por povi kompreni, kiu ĉela operatoro estis plej optimuma por li kiam oni instalas ekipaĵon uzante LTE-konekton, ekzemple por videoelsendoj. Samtempe, la problemo devis esti solvita kiel eble plej simple kaj malmultekoste, sen multekostaj ekipaĵoj.

Mi tuj diros, ke la tasko ne estas la plej simpla kaj plej scion-intensa; mi rakontos al vi kiajn problemojn mi renkontis kaj kiel mi solvis ilin. Do, ni iru.

Примечание

Mezuri la rapidecon de LTE-konekto estas tre kompleksa afero: vi devas elekti la ĝustan ekipaĵon kaj mezuran teknikon, kaj ankaŭ bone kompreni la topologion kaj funkciadon de la ĉela reto. Plie, la rapideco povas esti influita de pluraj faktoroj: la nombro da abonantoj sur ĉelo, veterkondiĉoj, eĉ de ĉelo al ĉelo la rapido povas varii draste pro la retotopologio. Ĝenerale, ĉi tio estas problemo kun grandega nombro da nekonataĵoj, kaj nur telekomunika operatoro povas ĝuste solvi ĝin.

Komence, la kliento nur volis veturi la kurieron per la telefonoj de la telefonistoj, preni mezurojn rekte sur la telefono kaj poste noti la rapidecmezurrezultojn en kajeron. Mia solvo por mezuri la rapidecon de lte-retoj, kvankam ne ideala, solvas la problemon.

Pro manko de tempo, mi faris decidojn ne favore al oportuneco aŭ praktikeco, sed favore al rapido de disvolviĝo. Ekzemple, inversa ssh estis uzata por fora aliro, anstataŭ la pli praktika VPN, por ŝpari tempon pri agordo de la servilo kaj ĉiu individua kliento.

Teknika tasko

Kiel dirite en la artikolo Sen teknikaj specifoj: kial la kliento ne volas ĝin: Ne laboru sen teknikaj specifoj! Neniam, ie ajn!

La teknika tasko estis sufiĉe simpla, mi iom pligrandigos ĝin por la kompreno de la fina uzanto. La elekto de teknikaj solvoj kaj ekipaĵo estis diktita de la kliento. Do, la teknika specifo mem, post ĉiuj aproboj:

Surbaze de ununura tabulokomputilo vim2 faru rapidtestilon por lte-konektoj per H-modemojuawei e3372h - 153 pluraj teleentreprenistoj (de unu ĝis n). Ankaŭ necesas ricevi koordinatojn de GPS-ricevilo konektita per UART. Faru rapidmezurojn uzante la servon www.speedtest.net kaj metu ilin en tablon kiel:

Samtempa rapidtesto sur pluraj LTE-modemoj

Tabelo en csv-formato. Poste sendu ĉi tiun signon retpoŝte ĉiujn 6 horojn. En kazo de eraroj, palpebrumu la LED kiu estas konektita al la GPIO.

Mi priskribis la teknikajn specifojn en libera formo, post multaj aproboj. Sed la signifo de la tasko jam estas videbla. Oni donis semajnon por ĉio. Sed fakte ĝi daŭris tri semajnojn. Ĉi tio konsideras la fakton, ke mi faris tion nur post mia ĉefa laboro kaj semajnfine.

Ĉi tie mi volas denove atentigi la fakton, ke la kliento anticipe konsentis pri la uzo de la rapidmezura servo kaj aparataro, kiuj multe limigis miajn kapablojn. La buĝeto ankaŭ estis limigita, do nenio speciala estis aĉetita. Do ni devis ludi laŭ ĉi tiuj reguloj.

Arkitekturo kaj evoluo

La skemo estas simpla kaj evidenta. Tial mi lasos ĝin sen specialaj komentoj.

Samtempa rapidtesto sur pluraj LTE-modemoj

Mi decidis efektivigi la tutan projekton en python, malgraŭ tio, ke mi tute ne havis sperton pri evoluado en ĉi tiu lingvo. Mi elektis ĝin ĉar estis amaso da pretaj ekzemploj kaj solvoj, kiuj povus akceli disvolviĝon. Tial mi petas ĉiujn profesiajn programistojn ne riproĉi mian unuan sperton pri evoluado en python, kaj mi ĉiam ĝojas aŭdi konstruajn kritikojn por plibonigi miajn kapablojn.

Ankaŭ en la procezo mi malkovris, ke python havas du kurantajn versiojn 2 kaj 3, kiel rezulto mi decidis por la tria.

Aparataj nodoj

Unuplata vim2

Oni donis al mi unutablan komputilon kiel mia ĉefa maŝino vim2

Samtempa rapidtesto sur pluraj LTE-modemoj

Bonega, potenca amaskomunikila procesoro por inteligenta hejmo kaj SMART-TELEVIDO, sed ege maltaŭga por ĉi tiu tasko, aŭ, ni diru, malbone taŭga. Ekzemple, ĝia ĉefa OS estas Android, kaj Linukso estas malĉefa OS, kaj sekve neniu garantias la altkvalitan funkciadon de ĉiuj nodoj kaj ŝoforoj sub Linukso. Kaj mi supozas, ke iuj el la problemoj estis rilataj al la USB-ŝoforoj de ĉi tiu platformo, do la modemoj ne funkciis kiel atendite sur ĉi tiu tabulo. Ĝi ankaŭ havas tre malbonan kaj disan dokumentadon, do ĉiu operacio prenis multe da tempo fosi tra la dokoj. Eĉ ordinara laboro kun GPIO prenis multe da sango. Ekzemple, mi bezonis plurajn horojn por agordi la LED. Sed, por esti objektiva, esence ne estis grave kia unu-tabulo ĝi estis, la ĉefa afero estis, ke ĝi funkciis kaj estis USB-havenoj.

Unue, mi devas instali Linukso sur ĉi tiu tabulo. Por ne traserĉi la sovaĝajn dokumentojn por ĉiuj, kaj ankaŭ por tiuj, kiuj traktos ĉi tiun unu-tabulan sistemon, mi verkas ĉi tiun ĉapitron.

Estas du ebloj por instali Linukso: sur ekstera SD-karto aŭ sur interna MMC. Mi pasigis vesperon provante eltrovi kiel ĝin funkcii per la karto, do mi decidis instali ĝin sur la MMC, kvankam sendube estus multe pli facile labori kun ekstera karto.

Pri la firmware malrekte rakontis ĉi tie. Mi tradukas el stranga en la rusan. Por ekbriligi la tabulon, mi devas konekti la aparataron UART. Konektis ĝin en la sekva maniero.

  • Ilo Pinglo GND: <—> Pin17 de la GPIO de VIMs
  • Ila Pinglo TXD: <—> Pin18 de la GPIO de VIMs (Linux_Rx)
  • Ila Pinglo RXD: <—> Pin19 de la GPIO de VIMs (Linux_Tx)
  • Ilo Pinglo VCC: <—> Pin20 de la GPIO de VIMs

Samtempa rapidtesto sur pluraj LTE-modemoj

Post tio, mi elŝutis la firmware de ĉi tie. Specifa firmware versio VIM1_Ubuntu-server-bionic_Linux-4.9_arm64_EMMC_V20191231.

Por alŝuti ĉi tiun firmvaro, mi bezonas ilojn. Pli da detaloj pri ĉi tio tie. Mi ne provis fulmi ĝin sub Vindozo, sed mi devas diri al vi kelkajn vortojn pri firmware sub Linukso. Unue, mi instalos la ilojn laŭ la instrukcioj.

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

Aaand... Nenio funkcias. Mi pasigis kelkajn horojn redaktante la instalajn skriptojn por ke ĉio instalu ĝuste por mi. Mi ne memoras, kion mi faris tie, sed estis ankaŭ tiu cirko kun ĉevaloj. Do atentu. Sed sen ĉi tiuj utilecoj ne utilas plu torturi vim2. Pli bone tute ne fuŝi kun li!

Post sep rondoj de la infero, agordo de skripto kaj instalado, mi ricevis pakaĵon da funkciaj iloj. Mi konektis la tabulon per USB al mia Linuksa komputilo, kaj ankaŭ konektis la UART laŭ la supra diagramo.
Mi agordas mian plej ŝatatan minicom-terminalon por rapido de 115200, sen erarkontrolo de aparataro kaj programaro. Kaj ni komencu.

Samtempa rapidtesto sur pluraj LTE-modemoj

Kiam vi ŝarĝas VIM2 en la UART-terminalo, mi premas klavon, kiel la spacostangon, por ĉesi ŝarĝi. Post kiam la linio aperas

kvim2# 

Mi enigas la komandon:

kvim2# run update

Sur la gastiganto de kiu ni ŝarĝas, mi plenumas:

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

Jen ĝi, uf. Mi kontrolis, estas Linukso sur la tabulo. Ensaluto/pasvorto khadas:khadas.

Post tio, kelkaj etaj komencaj agordoj. Por plua laboro, mi malŝaltas la pasvorton por sudo (jes, ne sekura, sed oportuna).

sudo visudo

Mi redaktas la linion al la formularo kaj konservas

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

Poste mi ŝanĝas la nunan lokon, por ke la horo estu en Moskvo, alie ĝi estos en Greenwich.

sudo timedatectl set-timezone Europe/Moscow

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

Se vi trovas ĝin malfacila, tiam ne uzu ĉi tiun tabulon; Raspberry Pi estas pli bona. Sincere.

Modemo Huawei e3372h - 153

Ĉi tiu modemo estis signifa fonto de sango por mi, kaj, fakte, ĝi fariĝis la proplemkolo de la tuta projekto. Ĝenerale, la nomo "modemo" por ĉi tiuj aparatoj tute ne reflektas la esencon de la laboro: ĉi tio estas potenca kombinaĵo, ĉi tiu aparataro havas kunmetitan aparaton, kiu ŝajnigas esti KD-ROM por instali ŝoforojn, kaj poste ŝanĝas al retkarta reĝimo.

Arkitekture, el la vidpunkto de Linukso-uzanto, post ĉiuj agordoj, ĝi aspektas jene: post konekto de la modemo, mi havas retan interfacon eth*, kiu per dhcp ricevas la IP-adreson 192.168.8.100, kaj la defaŭltan enirejon. estas 192.168.8.1.

Kaj la plej grava momento! Ĉi tiu modemmodelo ne povas funkcii en modema reĝimo, kiu estas kontrolita per AT-komandoj. Ĉio estus multe pli simpla, kreu PPP-ligojn por ĉiu modemo kaj poste funkciigu per ili. Sed en mia kazo, "sin" (pli precize, Linukso-plonĝisto laŭ la udev-reguloj), kreas eth-interfacon kaj asignas al ĝi IP-adreson per dhcp.

Por eviti plian konfuzon, mi sugestas forgesi la vorton "modemo" kaj diri retkarton kaj enirejon, ĉar esence, ĝi estas kiel konekti novan retkarton kun enirejo.
Kiam ekzistas unu modemo, tio ne kaŭzas specialajn problemojn, sed kiam estas pli ol unu, nome n-pecoj, aperas jena retbildo.

Samtempa rapidtesto sur pluraj LTE-modemoj

Tio estas, n retaj kartoj, kun la sama IP-adreso, ĉiu kun la sama defaŭlta enirejo. Sed fakte, ĉiu el ili estas konektita al sia propra funkciigisto.

Komence, mi havis simplan solvon: uzante la komandon ifconfig aŭ ip, malŝaltu ĉiujn interfacojn kaj simple ŝalti unu laŭvice kaj testi ĝin. La solvo estis bona por ĉiuj, krom ke dum la ŝanĝmomentoj mi ne povis konekti al la aparato. Kaj ĉar la ŝanĝado estas ofta kaj rapida, mi fakte tute ne havis ŝancon konektiĝi.

Tial mi elektis la vojon mane ŝanĝi la IP-adresojn de la modemoj kaj poste veturi trafikon per vojaj agordoj.

Samtempa rapidtesto sur pluraj LTE-modemoj

Ĉi tio ne estis la fino de miaj problemoj kun modemoj: en kazo de elektroproblemoj, ili defalis, kaj bona stabila nutrado al la USB-nabo estis postulata. Mi solvis ĉi tiun problemon per forte lutante la potencon rekte al la nabo. Alia problemo, kiun mi renkontis kaj kiu ruinigis la tutan projekton: post rekomenco aŭ malvarma ekfunkciigo de la aparato, ne ĉiuj modemoj estis detektitaj kaj ne ĉiam, kaj mi ne povis determini kial tio okazis kaj per kia algoritmo. Sed unue aferojn.

Por ke la modemo funkciu ĝuste, mi instalis la pakaĵon usb-modeswitch.

sudo apt update
sudo apt install -y usb-modeswitch

Post tio, post konekto, la modemo estos ĝuste detektita kaj agordita de la udev-subsistemo. Mi kontrolas simple konektante la modemon kaj certigante ke la reto aperas.
Alia problemo, kiun mi ne povis solvi: kiel mi povas ricevi la nomon de la operatoro kun kiu ni laboras de ĉi tiu modemo? La funkciigistonomo estas enhavita en la modema retinterfaco ĉe 192.168.8.1. Ĉi tio estas dinamika retpaĝo, kiu ricevas datumojn per Ajax-petoj, do simple elpreni la paĝon kaj analizi la nomon ne funkcios. Do mi ekrigardis kiel disvolvi retpaĝon ktp., kaj konstatis, ke mi faras ian sensencaĵon. Kiel rezulto, li kraĉis, kaj la funkciigisto komencis ricevi uzante la Speedtest API mem.

Multe estus pli facila se la modemo havus aliron per AT-komandoj. Eblus reagordi ĝin, krei ppp-konekton, asigni IP-on, akiri telekomunikan funkciigiston ktp. Sed ve, mi laboras kun tio, kion mi ricevis.

GPS

La GPS-ricevilo, kiun mi ricevis, havis UART-interfacon kaj potencon. Ĝi ne estis la plej bona solvo, sed ĝi estis ankoraŭ farebla kaj simpla. La ricevilo aspektis io tia.

Samtempa rapidtesto sur pluraj LTE-modemoj

Verdire, ĉi tio estis mia unua fojo laboranta kun GPS-ricevilo, sed kiel mi atendis, ĉio estis elpensita por ni antaŭ longe. Do ni nur uzas pretajn solvojn.

Unue, mi ebligas uart_AO_B (UART_RX_AO_B, UART_TX_AO_B) por konekti GPS.

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

Poste mi kontrolas la sukceson de la operacio.

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

Ĉi tiu komando ŝajne redaktas la dev-arbon sur la flugo, kio estas tre oportuna.

Post la sukceso de ĉi tiu operacio, rekomencu kaj instalu la GPS-demonon.

khadas@Khadas:~$ sudo reboot

Instalante la GPS-demonon. Mi instalas ĉion kaj tuj detranĉas ĝin por plia agordo.

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

Redaktante la agordan dosieron.

sudo vim /etc/default/gpsd

Mi instalas UART sur kiu la GPS pendos.

DEVICES="/dev/ttyS4"

Kaj tiam ni ŝaltas ĉion kaj komencas.

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

Post tio, mi konektas la GPS.

Samtempa rapidtesto sur pluraj LTE-modemoj

La GPS-drato estas en miaj manoj, la UART-sencimigilo-dratoj estas videblaj sub miaj fingroj.

Mi rekomencas kaj kontrolas la funkciadon de GPS per la programo gpsmon.

Samtempa rapidtesto sur pluraj LTE-modemoj

Vi ne povas vidi la satelitojn en ĉi tiu ekrankopio, sed vi povas vidi komunikadon kun la GPS-ricevilo, kaj tio signifas, ke ĉio estas bona.

En python, mi provis multajn eblojn por labori kun ĉi tiu demono, sed mi decidis por tiu, kiu funkciis ĝuste kun python 3.

Mi instalas la necesan bibliotekon.

sudo -H pip3 install gps3 

Kaj mi skulptas la laborkodon.

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

Se mi bezonas akiri koordinatojn, tio estas farita per la sekva alvoko:

longitude, latitude = getPositionData(agps_thread)

Kaj ene de 1-10 sekundoj mi aŭ ricevos la koordinaton aŭ ne. Jes, mi havis dek provojn akiri koordinatojn. Ne optimuma, kurba kaj malrekte, sed ĝi funkcias. Mi decidis fari tion ĉar GPS povas havi malbonan ricevon kaj ne ĉiam ricevi datumojn. Se vi atendas ricevi datumojn, tiam se vi laboras en fora ĉambro, la programo frostos en ĉi tiu loko. Tial mi efektivigis ĉi tiun malelegantan opcion.

Principe, se estus pli da tempo, eblus ricevi datumojn de GPS rekte per UART, analizi ĝin en aparta fadeno kaj labori kun ĝi. Sed tute ne estis tempo, tial la brutale malbela kodo. Kaj jes, mi ne hontas.

Lumelsenda diodo

Konekti la LED estis simpla kaj malfacila samtempe. La ĉefa malfacilaĵo estas, ke la pinglonumero en la sistemo ne respondas al la pinglonumero sur la tabulo kaj ĉar la dokumentado estas skribita per la maldekstra mano. Por kompari la numeron de la aparataro kaj la numero de la aparataro en la OS, vi devas ruli la komandon:

gpio readall

Tablo de pingla korespondado en la sistemo kaj sur la tabulo estos montrata. Post kio mi jam povas funkcii la pinglo en la OS mem. En mia kazo la LED estas konektita al GPIOH_5.

Samtempa rapidtesto sur pluraj LTE-modemoj

Mi ŝanĝas la GPIO-pinglon al eliga reĝimo.

gpio -g mode 421 out

Mi skribas nulon.

gpio -g write 421 0

Mi skribas unu.

gpio -g write 421 1

Samtempa rapidtesto sur pluraj LTE-modemoj
Ĉio estas lumigita, post skribado "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)

Nun, kaze de eraroj, mi vokas error_blink() kaj la LED palpebrumos bele.

Programaraj nodoj

Speedtest API

Estas granda ĝojo, ke la servo speedtest.net havas sian propran python-API, kiun vi povas rigardi GitHub.

La bona afero estas, ke ekzistas fontkodoj, kiuj ankaŭ videblas. Kiel labori kun ĉi tiu API (simplaj ekzemploj) troveblas en koncerna sekcio.

Mi instalas la python-bibliotekon per la sekva komando.

sudo -H pip3 install speedtest-cli

Ekzemple, vi eĉ povas instali rapidtestilon en Ubuntu rekte de la programaro. Ĉi tiu estas la sama python-aplikaĵo, kiu tiam povas esti lanĉita rekte de la konzolo.

sudo apt install speedtest-cli -y

Kaj mezuru vian interretan rapidon.

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

Kiel rezulto, same kiel mi faris. Mi devis eniri la fontkodojn de ĉi tiu rapidtesto por pli plene efektivigi ilin en mian projekton. Unu el la plej gravaj taskoj estas akiri la nomon de la teleentreprenisto por anstataŭigi ĝin en la teleron.

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

Ankaŭ ĉi tie ĉio montriĝis ne tiel simpla, kvankam ĝi ŝajnus multe pli simpla. Komence, la parametro de serviloj estis egala al [], ili diras, elektu la plej bonan servilon. Kiel rezulto, mi havis hazardajn servilojn, kaj, kiel vi povas supozi, ŝanĝiĝeman rapidon. Ĉi tio estas sufiĉe kompleksa temo, uzi fiksan servilon, se jes, statika aŭ dinamika, postulas esploradon. Sed jen ekzemplo de rapidmezuraj grafikaĵoj por Beeline-funkciigisto kiam dinamike elektas testan servilon kaj statike fiksitan.

Samtempa rapidtesto sur pluraj LTE-modemoj
La rezulto de mezurado de rapideco elektante dinamikan servilon.

Samtempa rapidtesto sur pluraj LTE-modemoj
La rezulto de rapida testado, kun unu strikte elektita unu servilo.

Dum testado, estas "pelto" en ambaŭ lokoj, kaj ĝi devas esti forigita per matematikaj metodoj. Sed kun fiksa servilo ĝi estas iomete malpli kaj la amplitudo estas pli stabila.
Ĝenerale, ĉi tio estas loko de granda esploro. Kaj mi mezurus la rapidecon de mia servilo uzante la ilon iperf. Sed ni restas al la teknikaj specifoj.

Sendante poŝton kaj erarojn

Por sendi poŝton, mi provis plurajn dekojn da diversaj ebloj, sed finfine mi decidis je la sekvanta. Mi registris leterkeston sur Yandex kaj poste prenis Ĉi tio estas ekzemplo de sendo de poŝto. Mi kontrolis ĝin kaj efektivigis ĝin en la programon. Ĉi tiu ekzemplo ekzamenas diversajn opciojn, inkluzive de sendo de gmail, ktp. Mi ne volis zorgi pri agordo de mia poŝtservilo kaj ne havis tempon por ĝi, sed kiel poste montriĝis, ankaŭ estis vane.

La protokoloj estis senditaj laŭ la planisto, se estas rilato, ĉiujn 6 horojn: je la 00-a, 06-a, 12-a kaj 18-a. Sendis ĝin jene.

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

Eraroj ankaŭ estis senditaj komence. Komence, ili estis akumulitaj en la listo, kaj poste senditaj ankaŭ uzante la planilon, se estis konekto. Tamen, tiam aperis problemoj kun la fakto, ke Yandex havas limon pri la nombro da mesaĝoj senditaj tage (ĉi tio estas doloro, malĝojo kaj humiligo). Ĉar eĉ po minuto povus esti grandega nombro da eraroj, ni devis rezigni sendi erarojn per poŝto. Do memoru, kiam aŭtomate sendas informojn pri tia problemo per Yandex-servoj.

Reagoservilo

Por havi aliron al fora aparataro kaj povi personecigi kaj reagordi ĝin, mi bezonis eksteran servilon. Ĝenerale, por esti juste, estus ĝuste sendi ĉiujn datumojn al la servilo kaj konstrui ĉiujn belajn grafikaĵojn en la retinterfaco. Sed ne ĉiuj samtempe.

Por VPS mi elektis ruvds.com. Vi povus preni la plej simplan servilon. Kaj ĝenerale, por miaj celoj ĉi tio sufiĉus. Sed ĉar mi ne pagis la servilon el mia propra poŝo, mi decidis preni ĝin kun malgranda rezervo, por ke sufiĉus, se ni disfaldiĝus retan interfacon, nian propran SMTP-servilon, VPN, ktp. Krome, povu agordi Telegram-robotilon kaj ne havi problemojn pri ĝi blokita. Tial mi elektis Amsterdamon kaj la sekvajn parametrojn.

Samtempa rapidtesto sur pluraj LTE-modemoj

Kiel metodo de komunikado kun la aparataro, vim2 elektis inversan ssh-konekton kaj, kiel praktiko montris, ĝi ne estas la plej bona. Se la konekto estas perdita, la servilo tenas la havenon kaj estas neeble konekti tra ĝi dum iom da tempo. Tial, estas ankoraŭ pli bone uzi aliajn komunikajn metodojn, ekzemple VPN. Estonte mi volis ŝanĝi al VPN, sed ne havis tempon.

Mi ne eniros detalojn pri starigo de fajroŝirmilo, limigado de rajtoj, malfunkciigado de radikaj ssh-konektoj kaj aliaj truismoj pri agordo de VPS. Mi ŝatus kredi, ke vi jam scias ĉion. Por fora konekto, mi kreas novan uzanton sur la servilo.

adduser vimssh

Mi generas ssh-konektajn ŝlosilojn sur nia aparataro.

ssh-keygen

Kaj mi kopias ilin al nia servilo.

ssh-copy-id [email protected]

Sur nia aparataro, mi kreas aŭtomatan inversan ssh-konekton ĉe ĉiu ekkuro.

[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

Atentu pordon 8083: ĝi determinas kiun havenon mi uzos por konekti per inversa ssh. Aldonu ĝin al ekfunkciigo kaj komencu.

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

Vi eĉ povas vidi la staton:

sudo systemctl status autossh.service

Nun, sur nia VPS-servilo, se ni kuras:

ssh -p 8083 khadas@localhost

Poste mi atingas mian provpecon de aparataro. Kaj de la aparataro mi ankaŭ povas sendi protokolojn kaj ajnajn datumojn per ssh al mia servilo, kio estas tre oportuna.

Kunmetante ĉion

Samtempa rapidtesto sur pluraj LTE-modemoj
Ŝaltante, ni komencu disvolviĝon kaj sencimigon

Huf, nu, jen, mi priskribis ĉiujn nodojn. Nun estas tempo kunmeti ĉion. Vi povas vidi la kodon ĝuste ĉi tie.

Grava punkto kun la kodo: Ĉi tiu projekto eble ne komenciĝas tiel, ĉar ĝi estis tajlorita por specifa tasko, de specifa arkitekturo. Kvankam mi donas la fontkodon, mi ankoraŭ klarigos la plej valorajn aferojn ĉi tie, ĝuste en la teksto, alie ĝi estas tute nekomprenebla.

Komence, mi pravigigas gps, gpio kaj lanĉas apartan horaran fadenon.

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

La planilo estas sufiĉe simpla: ĝi rigardas ĉu venis la tempo por sendi mesaĝojn kaj kia estas la nuna erarstato. Se estas erara flago, tiam ni palpebrumas la 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)

La plej malfacila parto de ĉi tiu projekto estas konservi la inversan ssh-konekton por ĉiu testo. Ĉiu testo implikas re-agordi la defaŭltan enirejon kaj DNS-servilon. Ĉar neniu ĉiuokaze legas, sciu, ke la trajno ne veturas sur lignaj reloj. Kiu trovas la paskan ovon, tiu ricevas dolĉaĵon.

Por fari tion, mi kreas apartan vojtablon -set-mark 0x2 kaj regulon por redirekti trafikon.

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

Vi povas lerni pli pri kiel ĝi funkcias legu en ĉi tiu artikolo.

Post kio mi iras en senfinan buklon, kie ĉiufoje ni ricevas liston de konektitaj modemoj (por ekscii, ĉu la reto-agordo subite ŝanĝiĝis).

network_list = getNetworklist()

Akiri liston de retaj interfacoj estas sufiĉe simpla.

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

Post ricevi la liston, mi fiksis IP-adresojn al ĉiuj interfacoj, kiel mi montris en la bildo en la ĉapitro pri la modemo.

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

Tiam mi simple trapasas ĉiun interfacon en buklo. Kaj mi agordas ĉiun interfacon.

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

Mi kontrolas la interfacon por funkciado, se ne ekzistas reto, tiam mi generas erarojn. Se ekzistas reto, tiam estas tempo agi!

Ĉi tie mi agordas ssh-vojadon al ĉi tiu interfaco (se ĝi ne estis farita), sendas erarojn al la servilo se venis la tempo, sendas protokolojn kaj fine ruli speedtest kaj konservas la protokolojn al csv-dosiero.

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

Menciindas la funkcio agordi inversan 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")

Kaj kompreneble, vi devas aldoni ĉi tiun tutan belecon al ekfunkciigo. Por fari tion mi kreas dosieron:

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

Kaj mi skribas en ĝi:

[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

Mi ŝaltas aŭtomatan ŝarĝon kaj komencas!

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

Nun mi povas vidi protokolojn de kio okazas uzante la komandon:

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

Результаты

Nu, nun la plej grava afero estas, kio okazis kiel rezulto? Jen kelkaj grafikaĵoj, kiujn mi sukcesis kapti dum la disvolva kaj sencimiga procezo. La grafikaĵoj estis konstruitaj uzante gnuplot kun la sekva skripto.

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

La unua sperto estis kun la telefonisto Tele2, kiun mi faris dum pluraj tagoj.

Samtempa rapidtesto sur pluraj LTE-modemoj

Ĉi tie mi uzis dinamikan mezurservilon. Rapidmezuradoj funkcias, sed tre varias, sed iu averaĝa valoro ankoraŭ videblas, kaj ĉi tio povas esti akirita filtrinte la datumojn, ekzemple, kun moviĝanta mezumo.

Poste mi konstruis kelkajn grafikaĵojn por aliaj teleentreprenistoj. En ĉi tiu kazo, estis jam unu testa servilo, kaj la rezultoj ankaŭ estis tre interesaj.

Samtempa rapidtesto sur pluraj LTE-modemoj

Samtempa rapidtesto sur pluraj LTE-modemoj

Samtempa rapidtesto sur pluraj LTE-modemoj

Samtempa rapidtesto sur pluraj LTE-modemoj

Kiel vi povas vidi, la temo estas tre ampleksa por esplorado kaj prilaborado de ĉi tiuj datumoj, kaj klare ne daŭras dum kelkaj semajnoj da laboro. Sed…

Rezulto de laboro

La laboro estis abrupte finita pro cirkonstancoj ekster mia kontrolo. Unu el la malfortoj de ĉi tiu projekto, laŭ mia subjektiva opinio, estis la modemo, kiu ne vere volis funkcii samtempe kun aliaj modemoj, kaj faris tiajn lertaĵojn ĉiufoje kiam ĝi estis ŝarĝita. Por ĉi tiuj celoj, ekzistas grandega nombro da aliaj modemmodeloj; kutime ili jam estas en la formato Mini PCI-e kaj estas instalitaj en la aparato kaj estas multe pli facile agordeblaj. Sed tio estas tute alia historio. La projekto estis interesa kaj mi tre ĝojis, ke mi povis partopreni ĝin.

Samtempa rapidtesto sur pluraj LTE-modemoj

fonto: www.habr.com

Aldoni komenton