Prueba de velocidad simultánea en varios módems LTE
Durante la cuarentena, me ofrecieron participar en el desarrollo de un dispositivo para medir la velocidad de los módems LTE para varios operadores de telefonía móvil.
El cliente quería evaluar la velocidad de varios operadores de telecomunicaciones en diferentes ubicaciones geográficas para poder entender qué operador celular era el más óptimo para él al instalar equipos que utilizan una conexión LTE, por ejemplo, para transmisiones de video. Al mismo tiempo, el problema debía resolverse de la forma más sencilla y económica posible, sin necesidad de equipos costosos.
Diré de inmediato que la tarea no es la más simple ni la que requiere más conocimientos, les diré qué problemas encontré y cómo los resolví. Entonces vamos.
Nota
Medir la velocidad de una conexión LTE es una cuestión muy compleja: es necesario elegir el equipo y la técnica de medición adecuados, así como tener un buen conocimiento de la topología y el funcionamiento de la red celular. Además, la velocidad puede verse influenciada por varios factores: el número de suscriptores en un celular, las condiciones climáticas, incluso de un celular a otro la velocidad puede variar dramáticamente debido a la topología de la red. En general, se trata de un problema con una gran cantidad de incógnitas y sólo un operador de telecomunicaciones puede resolverlo correctamente.
Al principio, el cliente sólo quería conducir el mensajero con los teléfonos de los operadores, tomar medidas directamente en el teléfono y luego anotar los resultados de la medición de velocidad en una libreta. Mi solución para medir la velocidad de las redes LTE, aunque no es ideal, resuelve el problema.
Por falta de tiempo, tomé decisiones no por conveniencia o practicidad, sino por la velocidad de desarrollo. Por ejemplo, se utilizó ssh inverso para el acceso remoto, en lugar de la más práctica VPN, para ahorrar tiempo en la configuración del servidor y de cada cliente individual.
La tarea técnica fue bastante sencilla, la ampliaré un poco para la comprensión del usuario final. La elección de las soluciones técnicas y del equipamiento fue dictada por el cliente. Entonces, la especificación técnica en sí, después de todas las aprobaciones:
Basado en una computadora de placa única vim2 hacer un probador de velocidad para conexiones lte a través de módems HHuawei e3372h - 153 varios operadores de telecomunicaciones (de uno a n). También es necesario recibir coordenadas de un receptor GPS conectado vía UART. Realice mediciones de velocidad utilizando el servicio. www.speedtest.net y ponerlos en una mesa como:
Tabla en formato csv. Luego envíe este cartel por correo electrónico cada 6 horas. En caso de errores, haga parpadear el LED que está conectado al GPIO.
Describí las especificaciones técnicas de forma libre, después de muchas aprobaciones. Pero el significado de la tarea ya es visible. Se dio una semana para todo. Pero en realidad duró tres semanas. Esto teniendo en cuenta el hecho de que lo hacía sólo después de mi trabajo principal y los fines de semana.
Aquí quiero llamar la atención una vez más sobre el hecho de que el cliente acordó de antemano el uso del servicio y el hardware de medición de velocidad, lo que limitó en gran medida mis capacidades. El presupuesto también era limitado, por lo que no se compró nada especial. Así que teníamos que seguir estas reglas.
Arquitectura y desarrollo
El esquema es simple y obvio. Por tanto, lo dejaré sin ningún comentario especial.
Decidí implementar todo el proyecto en Python, a pesar de que no tenía ninguna experiencia desarrollando en este lenguaje. Lo elegí porque había muchos ejemplos y soluciones ya preparados que podrían acelerar el desarrollo. Por lo tanto, pido a todos los programadores profesionales que no regañen mi primera experiencia de desarrollo en Python, y siempre me alegra escuchar críticas constructivas para mejorar mis habilidades.
También en el proceso descubrí que Python tiene dos versiones en ejecución, 2 y 3, como resultado me decidí por la tercera.
Nodos de hardware
vim2 de placa única
Me dieron una computadora de placa única como mi máquina principal. vim2
Un excelente y potente procesador multimedia para hogares inteligentes y SMART-TV, pero extremadamente inadecuado para esta tarea o, digamos, poco adecuado. Por ejemplo, su sistema operativo principal es Android y Linux es un sistema operativo secundario y, en consecuencia, nadie garantiza el funcionamiento de alta calidad de todos los nodos y controladores en Linux. Y supongo que algunos de los problemas estaban relacionados con los controladores USB de esta plataforma, por lo que los módems no funcionaron como se esperaba en esta placa. Además tiene documentación muy pobre y dispersa, por lo que cada operación requirió mucho tiempo excavando en los muelles. Incluso el trabajo normal con GPIO requirió mucha sangre. Por ejemplo, me llevó varias horas configurar el LED. Pero, para ser objetivo, en principio no importaba qué tipo de placa única fuera, lo principal era que funcionara y que hubiera puertos USB.
Primero, necesito instalar Linux en esta placa. Para no buscar documentación para todos, y también para aquellos que se ocuparán de este sistema de placa única, estoy escribiendo este capítulo.
Hay dos opciones para instalar Linux: en una tarjeta SD externa o en una MMC interna. Estuve una tarde intentando descubrir cómo hacer que funcionara con la tarjeta, así que decidí instalarla en la MMC, aunque sin duda sería mucho más fácil trabajar con una tarjeta externa.
Acerca del firmware dicho torcidamente aquí. Traduzco del extraño al ruso. Para flashear la placa, necesito conectar el hardware UART. Lo conecté como sigue.
Pin de herramienta GND: <—> Pin17 del GPIO de VIM
Pin de herramienta TXD: <—> Pin18 del GPIO de VIM (Linux_Rx)
Pin de herramienta RXD: <—> Pin19 del GPIO de VIM (Linux_Tx)
Para cargar este firmware, necesito utilidades. Más detalles sobre esto aquí. No he intentado actualizarlo en Windows, pero necesito contarles algunas palabras sobre el firmware en Linux. Primero, instalaré las utilidades según las instrucciones.
git clone https://github.com/khadas/utils
cd /path/to/utils
sudo ./INSTALL
Y... Nada funciona. Pasé un par de horas editando los scripts de instalación para que todo se instalara correctamente. No recuerdo qué hice allí, pero también estaba ese circo con caballos. Así que ten cuidado. Pero sin estas utilidades no tiene sentido torturar más a vim2. ¡Es mejor no meterse con él en absoluto!
Después de siete círculos del infierno, configuración e instalación del script, recibí un paquete de utilidades que funcionan. Conecté la placa vía USB a mi computadora Linux y también conecté el UART de acuerdo con el diagrama anterior.
Estoy configurando mi terminal minicom favorito para una velocidad de 115200, sin control de errores de hardware ni software. Y comencemos.
Al cargar VIM2 en la terminal UART, presiono una tecla, como la barra espaciadora, para detener la carga. Después de que aparezca la línea
kvim2#
Ingreso el comando:
kvim2# run update
En el host desde el que estamos cargando ejecuto:
burn-tool -v aml -b VIM2 -i VIM2_Ubuntu-server-bionic_Linux-4.9_arm64_EMMC_V20191231.img
Eso es todo, uf. Lo comprobé, hay Linux en la placa. Inicio de sesión/contraseña khadas:khadas.
Después de eso, algunas configuraciones iniciales menores. Para seguir trabajando, desactivo la contraseña de sudo (sí, no es segura, pero sí conveniente).
sudo visudo
Edito la línea al formulario y guardo.
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) NOPASSWD: ALL
Luego cambio la ubicación actual para que la hora sea en Moscú; de lo contrario, será en Greenwich.
Si te resulta difícil, no utilices esta placa; Raspberry Pi es mejor. Honestamente.
Módem Huawei e3372h – 153
Este módem fue una importante fuente de sangre para mí y, de hecho, se convirtió en el cuello de botella de todo el proyecto. En general, el nombre "módem" para estos dispositivos no refleja en absoluto la esencia del trabajo: se trata de una cosechadora potente, esta pieza de hardware tiene un dispositivo compuesto que se hace pasar por un CD-ROM para instalar los controladores, y luego cambia al modo de tarjeta de red.
Arquitectónicamente, desde el punto de vista de un usuario de Linux, después de todas las configuraciones, se ve así: después de conectar el módem, tengo una interfaz de red eth*, que a través de dhcp recibe la dirección IP 192.168.8.100 y la puerta de enlace predeterminada es 192.168.8.1.
¡Y el momento más importante! Este modelo de módem no puede funcionar en modo módem, que está controlado por comandos AT. Todo sería mucho más sencillo, crear conexiones PPP para cada módem y luego operar con ellas. Pero en mi caso, "él mismo" (más precisamente, un buzo de Linux según las reglas de udev), crea una interfaz eth y le asigna una dirección IP a través de dhcp.
Para evitar mayor confusión, sugiero olvidar la palabra “módem” y decir tarjeta de red y puerta de enlace, porque en esencia, es como conectar una nueva tarjeta de red con una puerta de enlace.
Cuando hay un módem, esto no causa ningún problema especial, pero cuando hay más de uno, es decir, n piezas, surge la siguiente imagen de red.
Es decir, n tarjetas de red, con la misma dirección IP, cada una con la misma puerta de enlace predeterminada. Pero, de hecho, cada uno de ellos está conectado a su propio operador.
Inicialmente, tenía una solución simple: usando el comando ifconfig o ip, apague todas las interfaces y simplemente encienda una por turno y pruébela. La solución fue buena para todos, excepto que durante los momentos de cambio no pude conectarme al dispositivo. Y como el cambio es frecuente y rápido, en realidad no tuve ninguna oportunidad de conectarme.
Por lo tanto, elegí la opción de cambiar manualmente las direcciones IP de los módems y luego dirigir el tráfico usando la configuración de enrutamiento.
Este no fue el final de mis problemas con los módems: en caso de problemas de energía, se caían y se necesitaba una fuente de alimentación buena y estable para el concentrador USB. Resolví este problema soldando la alimentación directamente al concentrador. Otro problema que encontré y que arruinó todo el proyecto: después de reiniciar o arrancar en frío el dispositivo, no se detectaron todos los módems ni siempre, y no pude determinar por qué sucedió esto y mediante qué algoritmo. Pero primero lo primero.
Para que el módem funcione correctamente, instalé el paquete usb-modeswitch.
Después de lo cual, después de conectarse, el subsistema udev detectará y configurará correctamente el módem. Lo compruebo simplemente conectando el módem y asegurándome de que aparece la red.
Otro problema que no pude solucionar: ¿cómo puedo obtener el nombre del operador con el que estamos trabajando desde este módem? El nombre del operador está contenido en la interfaz web del módem en 192.168.8.1. Esta es una página web dinámica que recibe datos a través de solicitudes Ajax, por lo que simplemente crear la página y analizar el nombre no funcionará. Entonces comencé a buscar cómo desarrollar una página web, etc., y me di cuenta de que estaba haciendo una especie de tontería. Como resultado, escupió y el operador comenzó a recibir utilizando la propia API Speedtest.
Sería mucho más fácil si el módem tuviera acceso mediante comandos AT. Sería posible reconfigurarlo, crear una conexión ppp, asignar una IP, conseguir un operador de telecomunicaciones, etc. Pero, por desgracia, estoy trabajando con lo que me han dado.
GPS
El receptor GPS que me dieron tenía una interfaz UART y alimentación. No era la mejor solución, pero aun así era viable y sencilla. El receptor se parecía a esto.
Para ser honesto, esta fue la primera vez que trabajo con un receptor GPS, pero como esperaba, todo fue pensado para nosotros hace mucho tiempo. Así que simplemente utilizamos soluciones ya preparadas.
Primero, habilito uart_AO_B (UART_RX_AO_B, UART_TX_AO_B) para conectar el GPS.
khadas@Khadas:~$ sudo fdtput -t s /dtb.img /serial@c81004e0 status okay
Después compruebo el éxito de la operación.
khadas@Khadas:~$ fdtget /dtb.img /serial@c81004e0 status
okay
Este comando aparentemente edita el árbol de desarrollo sobre la marcha, lo cual es muy conveniente.
Después del éxito de esta operación, reinicie e instale el demonio GPS.
khadas@Khadas:~$ sudo reboot
Instalación del demonio GPS. Instalo todo y lo corto inmediatamente para realizar más configuraciones.
El cable del GPS está en mis manos, los cables del depurador UART son visibles bajo mis dedos.
Reinicio y verifico el funcionamiento del GPS usando el programa gpsmon.
No puedes ver los satélites en esta captura de pantalla, pero puedes ver la comunicación con el receptor GPS, y esto significa que todo está bien.
En Python, probé muchas opciones para trabajar con este demonio, pero me decidí por la que funcionaba correctamente con Python 3.
Instalo la biblioteca necesaria.
sudo -H pip3 install gps3
Y esculpo el código de trabajo.
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
Si necesito obtener coordenadas, esto se hace con la siguiente llamada:
longitude, latitude = getPositionData(agps_thread)
Y dentro de 1 a 10 segundos obtendré la coordenada o no. Sí, tuve diez intentos de obtener coordenadas. No es óptimo, está torcido y torcido, pero funciona. Decidí hacer esto porque el GPS puede tener mala recepción y no siempre recibir datos. Si espera recibir datos, si trabaja en una habitación remota, el programa se congelará en este lugar. Por eso, implementé esta opción poco elegante.
En principio, si hubiera más tiempo, sería posible recibir datos del GPS directamente a través de UART, analizarlos en un hilo separado y trabajar con ellos. Pero no hubo tiempo en absoluto, de ahí el código brutalmente feo. Y sí, no me avergüenzo.
LED
Conectar el LED fue sencillo y difícil al mismo tiempo. La principal dificultad es que el número de pin del sistema no se corresponde con el número de pin de la pizarra y porque la documentación está escrita con la mano izquierda. Para comparar el número de pin del hardware y el número de pin en el sistema operativo, debe ejecutar el comando:
gpio readall
Se mostrará una tabla de correspondencia de pines en el sistema y en el tablero. Después de lo cual ya puedo operar el pin en el propio sistema operativo. En mi caso el LED está conectado a GPIOH_5.
Ahora, en caso de errores, llamo a error_blink() y el LED parpadeará maravillosamente.
Nodos de software
API de prueba de velocidad
Es una gran alegría que el servicio speedtest.net tenga su propia API de Python, puedes verlo Github.
Lo bueno es que hay códigos fuente que también se pueden visualizar. Cómo trabajar con esta API (ejemplos simples) se puede encontrar en sección relevante.
Instalo la biblioteca de Python con el siguiente comando.
sudo -H pip3 install speedtest-cli
Por ejemplo, incluso puedes instalar un probador de velocidad en Ubuntu directamente desde el software. Esta es la misma aplicación de Python, que luego se puede iniciar directamente desde la consola.
sudo apt install speedtest-cli -y
Y mide tu velocidad de 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
Como resultado, tal como lo hice yo. Tuve que profundizar en los códigos fuente de esta prueba de velocidad para poder implementarlos más completamente en mi proyecto. Una de las tareas más importantes es obtener el nombre del operador de telecomunicaciones para poder sustituirlo en la placa.
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"
#тут идет запись в файл логов
Aquí tampoco todo resultó tan sencillo, aunque parecería mucho más sencillo. Inicialmente, el parámetro de los servidores era igual a [], dicen, elige el mejor servidor. Como resultado, tenía servidores aleatorios y, como puedes imaginar, velocidad variable. Este es un tema bastante complejo, el uso de un servidor fijo, si es estático o dinámico, requiere investigación. Pero aquí hay un ejemplo de gráficos de medición de velocidad para un operador de Beeline cuando selecciona dinámicamente un servidor de prueba y uno fijo estáticamente.
El resultado de medir la velocidad a la hora de elegir un servidor dinámico.
El resultado de las pruebas de velocidad, con un servidor estrictamente seleccionado.
Durante la prueba, hay "pelaje" en ambos lugares y es necesario eliminarlo mediante métodos matemáticos. Pero con un servidor fijo es un poco menor y la amplitud es más estable.
En general, este es un lugar de gran investigación. Y mediría la velocidad de mi servidor usando la utilidad iperf. Pero nos atenemos a las especificaciones técnicas.
Envío de correo y errores
Para enviar correo, probé varias docenas de opciones diferentes, pero al final me decidí por la siguiente. Registré un buzón en Yandex y luego tomé Este es un ejemplo de envío de correo.. Lo verifiqué y lo implementé en el programa. Este ejemplo examina varias opciones, incluido el envío desde Gmail, etc. No quería molestarme en configurar mi servidor de correo y no tuve tiempo para ello, pero como resultó más tarde, también fue en vano.
Los registros se enviaron según el planificador, si hay una conexión, cada 6 horas: a las 00 h, 06 h, 12 h y 18 h. Lo envió de la siguiente manera.
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
Inicialmente también se enviaron errores. Para empezar, se acumulaban en la lista y luego se enviaban también mediante el programador, si había una conexión. Sin embargo, luego surgieron problemas con el hecho de que Yandex tiene un límite en la cantidad de mensajes enviados por día (esto es dolor, tristeza y humillación). Como podía haber una gran cantidad de errores incluso por minuto, tuvimos que abandonar el envío de errores por correo. Así que tenga en cuenta al enviar automáticamente información sobre un problema de este tipo a través de los servicios de Yandex.
Servidor de comentarios
Para tener acceso a una pieza de hardware remota y poder personalizarla y reconfigurarla, necesitaba un servidor externo. En general, para ser justos, sería correcto enviar todos los datos al servidor y crear todos los gráficos hermosos en la interfaz web. Pero no todos a la vez.
Para VPS elegí ruvds.com. Podrías elegir el servidor más simple. Y en general, para mis propósitos esto sería suficiente. Pero como no pagué el servidor de mi bolsillo, decidí comprarlo con una pequeña reserva para que fuera suficiente si tuviéramos que implementar una interfaz web, nuestro propio servidor SMTP, VPN, etc. Además, poder configurar un bot de Telegram y no tener problemas con que lo bloqueen. Por eso, elegí Amsterdam y los siguientes parámetros.
Como método de comunicación con el hardware, vim2 eligió una conexión ssh inversa y, como ha demostrado la práctica, no es la mejor. Si se pierde la conexión, el servidor retiene el puerto y es imposible conectarse a través de él durante algún tiempo. Por lo tanto, es mejor utilizar otros métodos de comunicación, por ejemplo VPN. En el futuro quise cambiarme a VPN, pero no tuve tiempo.
No entraré en detalles sobre cómo configurar un firewall, restringir derechos, deshabilitar las conexiones ssh raíz y otras perogrulladas sobre la configuración de un VPS. Me gustaría creer que ya lo sabes todo. Para una conexión remota, creo un nuevo usuario en el servidor.
adduser vimssh
Genero claves de conexión ssh en nuestro hardware.
Luego llego a mi pieza de hardware de prueba. Y desde el hardware también puedo enviar registros y cualquier dato vía ssh a mi servidor, lo cual es muy conveniente.
Poniendo todo junto
Encendido, comencemos el desarrollo y la depuración.
Uf, bueno, eso es todo, describí todos los nodos. Ahora es el momento de juntarlo todo. Puedes ver el código. aquí.
Un punto importante con el código: es posible que este proyecto no comience así, porque fue diseñado para una tarea específica, de una arquitectura específica. Aunque estoy dando el código fuente, explicaré las cosas más valiosas aquí, directamente en el texto, de lo contrario es completamente incomprensible.
Al principio, inicializo gps, gpio y lanzo un hilo de programación separado.
El programador es bastante simple: mira para ver si ha llegado el momento de enviar mensajes y cuál es el estado de error actual. Si hay un indicador de error, hacemos parpadear el 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 parte más difícil de este proyecto es mantener la conexión ssh inversa para cada prueba. Cada prueba implica reconfigurar la puerta de enlace predeterminada y el servidor DNS. Como de todos modos nadie lee, sepa que el tren no viaja sobre rieles de madera. Quien encuentre el huevo de Pascua recibirá unos dulces.
Para hacer esto, creo una tabla de enrutamiento separada -set-mark 0x2 y una regla para redirigir el tráfico.
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")
Después de lo cual entro en un bucle sin fin, donde cada vez obtenemos una lista de módems conectados (para saber si la configuración de la red ha cambiado repentinamente).
network_list = getNetworklist()
Obtener una lista de interfaces de red es bastante sencillo.
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
Después de recibir la lista, configuro las direcciones IP para todas las interfaces, como mostré en la imagen del capítulo sobre el módem.
Luego simplemente reviso cada interfaz en un bucle. Y configuro cada interfaz.
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'")
Verifico la funcionalidad de la interfaz, si no hay red, genero errores. Si existe una red, ¡es hora de actuar!
Aquí configuro el enrutamiento ssh a esta interfaz (si no se ha hecho), envío errores al servidor si ha llegado el momento, envío registros y finalmente ejecuto una prueba de velocidad y guardo los registros en un archivo csv.
if not NetworkAvalible():
....
#Здесь мы формируем ошибки
....
else: #Есть сеть, ура, работаем!
#Если у нас проблемный интерфейс, на котором ssh, то меняем его
if (sshint == lastbanint or sshint =="free"):
print("********** Setup SSH ********************")
if sshint !="free":
сmd_run("sudo ip route del default via 192.168.8.1 dev " + sshint +" table 102")
SetupReverseSSH(iface)
sshint = iface
#раз сетка работает, то давай срочно все отправим!!!
if ready_to_send:
print ("**** Ready to send!!!")
if sendLogs():
ready_to_send = False
if error_status:
SendErrors()
#и далее тестируем скорость и сохраняем логи.
Vale la pena mencionar la función de configurar ssh inverso.
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")
Y, por supuesto, debes agregar toda esta belleza al inicio. Para hacer esto creo un archivo:
sudo vim /etc/systemd/system/modems_speedtest.service
Bueno, ahora lo más importante es, ¿qué pasó como resultado? Aquí hay algunos gráficos que logré capturar durante el proceso de desarrollo y depuración. Los gráficos se construyeron usando gnuplot con el siguiente 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"
La primera experiencia fue con el operador Tele2, que realicé durante varios días.
Aquí utilicé un servidor de medición dinámica. Las mediciones de velocidad funcionan, pero fluctúan mucho, pero todavía se ve algún valor promedio, y esto se puede obtener filtrando los datos, por ejemplo, con una media móvil.
Posteriormente construí varios gráficos para otros operadores de telecomunicaciones. En este caso ya existía un servidor de pruebas y los resultados también fueron muy interesantes.
Como puede ver, el tema es muy extenso para la investigación y el procesamiento de estos datos, y claramente no dura ni un par de semanas de trabajo. Pero…
El resultado del trabajo.
El trabajo se completó abruptamente debido a circunstancias fuera de mi control. Una de las debilidades de este proyecto, en mi opinión subjetiva, fue el módem, que realmente no quería funcionar simultáneamente con otros módems y hacía tales trucos cada vez que se cargaba. Para estos fines, existe una gran cantidad de otros modelos de módems, generalmente ya están en formato Mini PCI-e, se instalan dentro del dispositivo y son mucho más fáciles de configurar. Pero esa es una historia completamente diferente. El proyecto fue interesante y me alegré mucho de poder participar en él.