Kiểm tra tốc độ đồng thời trên một số modem LTE

Trong thời gian cách ly, tôi được đề nghị tham gia phát triển thiết bị đo tốc độ modem LTE cho một số nhà khai thác di động.

Kiểm tra tốc độ đồng thời trên một số modem LTE

Khách hàng muốn đánh giá tốc độ của các nhà khai thác viễn thông khác nhau ở các vị trí địa lý khác nhau để có thể hiểu nhà khai thác di động nào tối ưu nhất cho mình khi lắp đặt thiết bị sử dụng kết nối LTE, chẳng hạn như để phát video. Đồng thời, vấn đề phải được giải quyết một cách đơn giản và rẻ nhất có thể, không cần thiết bị đắt tiền.

Tôi sẽ nói ngay rằng nhiệm vụ này không đơn giản và đòi hỏi nhiều kiến ​​thức nhất, tôi sẽ cho bạn biết những vấn đề tôi gặp phải và cách tôi giải quyết chúng. Vì vậy, chúng ta hãy đi.

Ghi

Đo tốc độ kết nối LTE là một vấn đề rất phức tạp: bạn cần chọn thiết bị và kỹ thuật đo phù hợp, đồng thời hiểu rõ về cấu trúc liên kết và hoạt động của mạng di động. Ngoài ra, tốc độ có thể bị ảnh hưởng bởi một số yếu tố: số lượng người đăng ký trên một ô, điều kiện thời tiết, thậm chí từ ô này sang ô khác, tốc độ có thể thay đổi đáng kể do cấu trúc liên kết mạng. Nhìn chung, đây là một bài toán có rất nhiều ẩn số và chỉ có nhà khai thác viễn thông mới có thể giải quyết chính xác.

Ban đầu, khách hàng chỉ muốn lái xe chuyển phát nhanh bằng điện thoại của nhân viên vận hành, lấy số đo trực tiếp trên điện thoại rồi ghi kết quả đo tốc độ vào sổ. Giải pháp đo tốc độ mạng lte của tôi, mặc dù không lý tưởng nhưng đã giải quyết được vấn đề.

Do không có thời gian nên tôi đã đưa ra những quyết định không thiên về sự thuận tiện hay thiết thực mà thiên về tốc độ phát triển. Ví dụ: ssh ngược được sử dụng để truy cập từ xa, thay vì VPN thực tế hơn, nhằm tiết kiệm thời gian thiết lập máy chủ và từng máy khách riêng lẻ.

Nhiệm vụ kỹ thuật

Như đã nêu trong bài viết Không có thông số kỹ thuật: tại sao khách hàng không muốn nó: Đừng làm việc mà không có thông số kỹ thuật! Không bao giờ, ở bất cứ đâu!

Nhiệm vụ kỹ thuật khá đơn giản, tôi sẽ mở rộng nó một chút để người dùng cuối dễ hiểu. Việc lựa chọn giải pháp kỹ thuật và thiết bị do khách hàng quyết định. Vì vậy, bản thân thông số kỹ thuật, sau khi được phê duyệt:

Dựa trên một máy tính bảng đơn vim2 làm máy kiểm tra tốc độ kết nối lte qua modem Huawei e3372h - 153 một số nhà khai thác viễn thông (từ một đến n). Cũng cần phải nhận tọa độ từ máy thu GPS được kết nối qua UART. Thực hiện đo tốc độ bằng dịch vụ www.speedtest.net và đặt chúng vào một bảng như:

Kiểm tra tốc độ đồng thời trên một số modem LTE

Bảng ở định dạng csv. Sau đó gửi dấu hiệu này qua e-mail cứ sau 6 giờ. Trong trường hợp có lỗi, nhấp nháy đèn LED được kết nối với GPIO.

Tôi đã mô tả các thông số kỹ thuật ở dạng tự do sau nhiều lần phê duyệt. Nhưng ý nghĩa của nhiệm vụ đã rõ ràng rồi. Một tuần đã được đưa ra cho tất cả mọi thứ. Nhưng trên thực tế, nó kéo dài trong ba tuần. Điều này có tính đến thực tế là tôi chỉ làm việc này sau công việc chính của mình và vào cuối tuần.

Ở đây tôi muốn một lần nữa thu hút sự chú ý đến việc khách hàng đã đồng ý trước về việc sử dụng dịch vụ và phần cứng đo tốc độ, điều này đã hạn chế rất nhiều khả năng của tôi. Ngân sách cũng có hạn nên không có gì đặc biệt được mua. Vì thế chúng tôi phải chơi theo những luật này.

Kiến trúc và phát triển

Đề án này rất đơn giản và rõ ràng. Vì vậy, tôi sẽ để nó mà không có bất kỳ bình luận đặc biệt nào.

Kiểm tra tốc độ đồng thời trên một số modem LTE

Tôi quyết định triển khai toàn bộ dự án bằng python, mặc dù thực tế là tôi chưa có kinh nghiệm phát triển bằng ngôn ngữ này. Tôi chọn nó vì có rất nhiều ví dụ và giải pháp được tạo sẵn có thể tăng tốc độ phát triển. Vì vậy, tôi yêu cầu tất cả các lập trình viên chuyên nghiệp đừng la mắng trải nghiệm đầu tiên của tôi khi phát triển Python và tôi luôn vui vẻ nghe những lời chỉ trích mang tính xây dựng để cải thiện kỹ năng của mình.

Cũng trong quá trình đó tôi phát hiện ra rằng python có hai phiên bản đang chạy là 2 và 3 nên tôi đã quyết định sử dụng phiên bản thứ ba.

Nút phần cứng

Vim2 tấm đơn

Tôi đã được tặng một chiếc máy tính bảng đơn làm máy chính của mình vim2

Kiểm tra tốc độ đồng thời trên một số modem LTE

Một bộ xử lý đa phương tiện mạnh mẽ, tuyệt vời dành cho ngôi nhà thông minh và SMART-TV, nhưng cực kỳ không phù hợp cho nhiệm vụ này, hoặc có thể nói là kém phù hợp. Ví dụ: HĐH chính của nó là Android và Linux là HĐH phụ và do đó không ai đảm bảo hoạt động chất lượng cao của tất cả các nút và trình điều khiển trong Linux. Và tôi cho rằng một số vấn đề có liên quan đến trình điều khiển USB của nền tảng này nên các modem không hoạt động như mong đợi trên bo mạch này. Nó cũng có tài liệu rất nghèo nàn và rải rác nên mỗi hoạt động mất rất nhiều thời gian để đào bới khắp các bến cảng. Ngay cả công việc bình thường với GPIO cũng tốn rất nhiều máu. Ví dụ, tôi phải mất vài giờ để thiết lập đèn LED. Nhưng, khách quan mà nói, về cơ bản việc đó là loại bo mạch đơn nào không quan trọng, cái chính là nó hoạt động và có cổng USB.

Đầu tiên, tôi cần cài đặt Linux trên bo mạch này. Để không phải tìm kiếm vô số tài liệu cho tất cả mọi người và cho những người sẽ làm việc với hệ thống một bảng này, tôi viết chương này.

Có hai tùy chọn để cài đặt Linux: trên thẻ SD bên ngoài hoặc trên MMC bên trong. Tôi đã dành cả buổi tối để tìm cách làm cho nó hoạt động với thẻ, vì vậy tôi quyết định cài đặt nó trên MMC, mặc dù không nghi ngờ gì nữa, việc làm việc với thẻ bên ngoài sẽ dễ dàng hơn nhiều.

Về phần sụn kể quanh co ở đây. Tôi dịch từ lạ sang tiếng Nga. Để flash bảng, tôi cần kết nối UART phần cứng. Đã kết nối nó như sau

  • Chân công cụ GND: <—> Chân 17 của GPIO của VIMs
  • Tool Pin TXD: <—> Pin18 của GPIO của VIMs (Linux_Rx)
  • Chân công cụ RXD: <—> Chân 19 của GPIO của VIM (Linux_Tx)
  • Tool Pin VCC: <—> Pin20 của GPIO của VIMs

Kiểm tra tốc độ đồng thời trên một số modem LTE

Sau đó, tôi đã tải xuống phần mềm cơ sở do đó. Phiên bản phần mềm cụ thể VIM1_Ubuntu-server-bionic_Linux-4.9_arm64_EMMC_V20191231.

Để tải lên chương trình cơ sở này, tôi cần các tiện ích. Thêm chi tiết về điều này đây. Tôi chưa thử flash nó trong Windows, nhưng tôi cần nói với bạn vài lời về phần sụn trong Linux. Đầu tiên mình sẽ cài đặt các tiện ích theo hướng dẫn.

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

Aaand... Chẳng có tác dụng gì cả. Tôi đã dành vài giờ để chỉnh sửa các tập lệnh cài đặt để mọi thứ có thể cài đặt chính xác cho tôi. Tôi không nhớ mình đã làm gì ở đó, nhưng ở đó cũng có rạp xiếc có ngựa. Vì vậy hãy cẩn thận. Nhưng không có những tiện ích này thì việc tra tấn vim2 cũng chẳng ích gì. Tốt nhất là đừng gây rối với anh ấy chút nào!

Sau bảy vòng địa ngục, cấu hình và cài đặt tập lệnh, tôi đã nhận được một gói tiện ích hoạt động. Tôi đã kết nối bo mạch qua USB với máy tính Linux của mình và cũng kết nối UART theo sơ đồ trên.
Tôi đang thiết lập thiết bị đầu cuối minicom yêu thích của mình ở tốc độ 115200 mà không cần kiểm soát lỗi phần cứng và phần mềm. Và hãy bắt đầu.

Kiểm tra tốc độ đồng thời trên một số modem LTE

Khi tải VIM2 trong thiết bị đầu cuối UART, tôi nhấn một phím, chẳng hạn như phím cách, để dừng tải. Sau khi dòng xuất hiện

kvim2# 

Tôi nhập lệnh:

kvim2# run update

Trên máy chủ mà chúng tôi đang tải, tôi thực thi:

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

Thế đấy, phù. Tôi đã kiểm tra, có Linux trên bo mạch. Đăng nhập/mật khẩu khadas: khadas.

Sau đó, một số cài đặt ban đầu nhỏ. Để tiếp tục công việc, tôi vô hiệu hóa mật khẩu cho sudo (vâng, không an toàn, nhưng tiện lợi).

sudo visudo

Tôi chỉnh sửa dòng thành biểu mẫu và lưu

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

Sau đó tôi thay đổi ngôn ngữ hiện tại để thời gian ở Moscow, nếu không thì sẽ ở Greenwich.

sudo timedatectl set-timezone Europe/Moscow

hoặc

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

Nếu thấy khó thì không nên dùng board này; Raspberry Pi thì tốt hơn. Thành thật.

Modem Huawei e3372h – 153

Modem này là nguồn máu quan trọng đối với tôi và trên thực tế, nó đã trở thành điểm nghẽn của toàn bộ dự án. Nhìn chung, cái tên “modem” dành cho các thiết bị này hoàn toàn không phản ánh đúng bản chất của công việc: đây là một sự kết hợp mạnh mẽ, phần cứng này có một thiết bị tổng hợp giả dạng CD-ROM để cài đặt trình điều khiển, và sau đó chuyển sang chế độ card mạng.

Về mặt kiến ​​trúc, từ quan điểm của người dùng Linux, sau tất cả các cài đặt, nó trông như thế này: sau khi kết nối modem, tôi có giao diện mạng eth*, giao diện này thông qua dhcp nhận được địa chỉ IP 192.168.8.100 và cổng mặc định là 192.168.8.1.

Và thời điểm quan trọng nhất! Model modem này không thể hoạt động ở chế độ modem, được điều khiển bằng lệnh AT. Mọi thứ sẽ đơn giản hơn nhiều, hãy tạo kết nối PPP cho từng modem rồi thao tác với chúng. Nhưng trong trường hợp của tôi, “chính anh ấy” (chính xác hơn là một thợ lặn Linux theo quy tắc udev), tạo một giao diện eth và gán địa chỉ IP cho nó thông qua dhcp.

Để tránh nhầm lẫn thêm, tôi khuyên bạn nên quên từ “modem” và nói card mạng và cổng, vì về bản chất, nó giống như kết nối một card mạng mới với một cổng.
Khi có một modem, điều này không gây ra bất kỳ vấn đề đặc biệt nào, nhưng khi có nhiều hơn một, cụ thể là n mảnh, hình ảnh mạng sau đây sẽ xuất hiện.

Kiểm tra tốc độ đồng thời trên một số modem LTE

Nghĩa là, n card mạng, có cùng địa chỉ IP, mỗi card có cùng một cổng mặc định. Nhưng trên thực tế, mỗi cái đều được kết nối với nhà điều hành riêng.

Ban đầu, tôi có một giải pháp đơn giản: sử dụng lệnh ifconfig hoặc ip, tắt tất cả các giao diện và chỉ cần bật lần lượt một giao diện và kiểm tra nó. Giải pháp này tốt cho tất cả mọi người, ngoại trừ việc trong thời gian chuyển đổi, tôi không thể kết nối với thiết bị. Và vì việc chuyển đổi diễn ra thường xuyên và nhanh chóng nên tôi thực sự không có cơ hội kết nối nào cả.

Vì vậy, tôi đã chọn con đường thay đổi địa chỉ IP của modem theo cách thủ công và sau đó điều khiển lưu lượng truy cập bằng cài đặt định tuyến.

Kiểm tra tốc độ đồng thời trên một số modem LTE

Vấn đề của tôi với modem vẫn chưa kết thúc: trong trường hợp có sự cố về điện, chúng sẽ bị hỏng và cần phải có nguồn điện ổn định tốt cho bộ chia USB. Tôi đã giải quyết vấn đề này bằng cách hàn cứng nguồn điện trực tiếp vào trung tâm. Một vấn đề khác mà tôi gặp phải và làm hỏng toàn bộ dự án: sau khi khởi động lại hoặc khởi động nguội thiết bị, không phải tất cả các modem đều được phát hiện và không phải lúc nào cũng vậy, và tôi không thể xác định tại sao điều này lại xảy ra và bằng thuật toán nào. Nhưng điều đầu tiên trước tiên.

Để modem hoạt động chính xác, tôi đã cài đặt gói usb-modeswitch.

sudo apt update
sudo apt install -y usb-modeswitch

Sau đó, sau khi kết nối, modem sẽ được hệ thống con udev phát hiện và cấu hình chính xác. Tôi kiểm tra bằng cách chỉ cần kết nối modem và đảm bảo rằng mạng xuất hiện.
Một vấn đề khác mà tôi không thể giải quyết: làm cách nào để biết tên của nhà điều hành mà chúng tôi đang làm việc cùng từ modem này? Tên nhà điều hành có trong giao diện web của modem tại 192.168.8.1. Đây là một trang web động nhận dữ liệu thông qua các yêu cầu Ajax, do đó, chỉ cần quên trang và phân tích cú pháp tên sẽ không hoạt động. Vì vậy, tôi bắt đầu xem xét cách phát triển một trang web, v.v., và nhận ra rằng mình đang làm một điều vô nghĩa nào đó. Kết quả là anh ta nhổ nước bọt và người điều hành bắt đầu nhận được bằng chính API Speedtest.

Sẽ dễ dàng hơn nhiều nếu modem có quyền truy cập thông qua lệnh AT. Có thể cấu hình lại nó, tạo kết nối ppp, gán IP, nhận nhà điều hành viễn thông, v.v. Nhưng than ôi, tôi đang làm việc với những gì tôi được giao.

GPS

Bộ thu GPS tôi được tặng có giao diện và nguồn UART. Đó không phải là giải pháp tốt nhất nhưng nó vẫn khả thi và đơn giản. Người nhận trông giống như thế này.

Kiểm tra tốc độ đồng thời trên một số modem LTE

Thành thật mà nói, đây là lần đầu tiên tôi làm việc với máy thu GPS, nhưng đúng như tôi mong đợi, mọi thứ đã được chúng tôi nghĩ ra từ lâu. Vì vậy, chúng tôi chỉ sử dụng các giải pháp làm sẵn.

Đầu tiên mình kích hoạt uart_AO_B (UART_RX_AO_B, UART_TX_AO_B) để kết nối GPS.

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

Sau đó tôi kiểm tra sự thành công của hoạt động.

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

Lệnh này dường như chỉnh sửa cây phát triển một cách nhanh chóng, rất thuận tiện.

Sau thành công của thao tác này, hãy khởi động lại và cài đặt daemon GPS.

khadas@Khadas:~$ sudo reboot

Đang cài đặt daemon GPS. Tôi cài đặt mọi thứ và cắt nó ngay lập tức để cấu hình thêm.

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

Chỉnh sửa tập tin cài đặt.

sudo vim /etc/default/gpsd

Tôi đang cài đặt UART mà GPS sẽ treo trên đó.

DEVICES="/dev/ttyS4"

Và sau đó chúng tôi bật mọi thứ lên và bắt đầu.

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

Sau đó, tôi kết nối GPS.

Kiểm tra tốc độ đồng thời trên một số modem LTE

Dây GPS nằm trong tay tôi, dây gỡ lỗi UART hiện rõ dưới ngón tay tôi.

Tôi khởi động lại và kiểm tra hoạt động của GPS bằng chương trình gpsmon.

Kiểm tra tốc độ đồng thời trên một số modem LTE

Bạn không thể nhìn thấy các vệ tinh trong ảnh chụp màn hình này nhưng bạn có thể thấy giao tiếp với bộ thu GPS và điều này có nghĩa là mọi thứ đều ổn.

Trong python, tôi đã thử nhiều tùy chọn để làm việc với daemon này, nhưng tôi đã quyết định chọn một tùy chọn hoạt động chính xác với python 3.

Tôi cài đặt thư viện cần thiết.

sudo -H pip3 install gps3 

Và tôi điêu khắc mã công việc.

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

Nếu tôi cần lấy tọa độ, việc này được thực hiện bằng lệnh gọi sau:

longitude, latitude = getPositionData(agps_thread)

Và trong vòng 1-10 giây tôi sẽ có được tọa độ hoặc không. Vâng, tôi đã phải cố gắng mười lần để có được tọa độ. Không tối ưu, quanh co và lệch, nhưng nó hoạt động. Tôi quyết định làm điều này vì GPS có thể có khả năng thu tín hiệu kém và không phải lúc nào cũng nhận được dữ liệu. Nếu bạn chờ nhận dữ liệu thì nếu bạn làm việc ở phòng xa, chương trình sẽ bị treo ở nơi này. Vì vậy, tôi đã thực hiện tùy chọn không phù hợp này.

Về nguyên tắc, nếu có nhiều thời gian hơn, có thể nhận dữ liệu từ GPS trực tiếp qua UART, phân tích dữ liệu thành một luồng riêng biệt và làm việc với nó. Nhưng không có thời gian chút nào, do đó có đoạn mã xấu đến mức tàn nhẫn. Và vâng, tôi không xấu hổ.

Diode phát sáng

Việc kết nối đèn LED vừa đơn giản vừa khó khăn. Khó khăn chính là số pin trong hệ thống không khớp với số pin trên bảng và do tài liệu được viết ở phía bên trái. Để so sánh số chân phần cứng và số chân trong HĐH, bạn cần chạy lệnh:

gpio readall

Một bảng ghim tương ứng trong hệ thống và trên bảng sẽ được hiển thị. Sau đó, tôi đã có thể vận hành chốt trong chính hệ điều hành. Trong trường hợp của tôi, đèn LED được kết nối với GPIOH_5.

Kiểm tra tốc độ đồng thời trên một số modem LTE

Tôi chuyển chân GPIO sang chế độ đầu ra.

gpio -g mode 421 out

Tôi viết ra số không.

gpio -g write 421 0

Tôi viết ra một.

gpio -g write 421 1

Kiểm tra tốc độ đồng thời trên một số modem LTE
Mọi thứ đều sáng, sau khi viết “1”

#gpio subsistem
def gpio_init():
	os.system("gpio -g mode 421 out")
	os.system("gpio -g write 421 1")

def gpio_set(val):
	os.system("gpio -g write 421 %d" % val)
	
def error_blink():
	gpio_set(0)
	time.sleep(0.1)
	gpio_set(1)
	time.sleep(0.1)
	gpio_set(0)
	time.sleep(0.1)
	gpio_set(1)
	time.sleep(0.1)
	gpio_set(0)
	time.sleep(1.0)
	gpio_set(1)

def good_blink():
	gpio_set(1)

Bây giờ, trong trường hợp có lỗi, tôi gọi error_blink() và đèn LED sẽ nhấp nháy rất đẹp.

Nút phần mềm

API nhanh nhất

Thật vui khi dịch vụ speedtest.net có API python riêng, bạn có thể xem Github.

Điều tốt là có những mã nguồn có thể xem được. Bạn có thể tìm thấy cách làm việc với API này (ví dụ đơn giản) trong phần có liên quan.

Tôi cài đặt thư viện python bằng lệnh sau.

sudo -H pip3 install speedtest-cli

Ví dụ: bạn thậm chí có thể cài đặt trình kiểm tra tốc độ trong Ubuntu trực tiếp từ phần mềm. Đây là ứng dụng python tương tự, sau đó có thể khởi chạy trực tiếp từ bảng điều khiển.

sudo apt install speedtest-cli -y

Và đo tốc độ Internet của bạn.

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

Kết quả là, giống như tôi đã làm. Tôi đã phải truy cập vào mã nguồn của bài kiểm tra tốc độ này để triển khai chúng đầy đủ hơn vào dự án của mình. Một trong những nhiệm vụ quan trọng nhất là lấy tên của nhà khai thác viễn thông để thay thế vào biển số.

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

Ở đây, mọi thứ hóa ra không đơn giản như vậy, mặc dù nó có vẻ đơn giản hơn nhiều. Ban đầu, tham số máy chủ bằng [], họ nói, hãy chọn máy chủ tốt nhất. Kết quả là tôi có các máy chủ ngẫu nhiên và như bạn có thể đoán, có tốc độ thay đổi. Đây là một chủ đề khá phức tạp, sử dụng máy chủ cố định nếu có thì tĩnh hay động đều cần phải nghiên cứu. Nhưng đây là ví dụ về biểu đồ đo tốc độ dành cho người vận hành Beeline khi chọn động máy chủ thử nghiệm và máy chủ cố định tĩnh.

Kiểm tra tốc độ đồng thời trên một số modem LTE
Kết quả đo tốc độ khi chọn máy chủ động.

Kiểm tra tốc độ đồng thời trên một số modem LTE
Kết quả kiểm tra tốc độ, với một máy chủ được lựa chọn nghiêm ngặt.

Trong quá trình thử nghiệm, có “lông” ở cả hai nơi và cần phải loại bỏ bằng phương pháp toán học. Nhưng với máy chủ cố định thì ít hơn một chút và biên độ ổn định hơn.
Nói chung, đây là một nơi nghiên cứu tuyệt vời. Và tôi sẽ đo tốc độ máy chủ của mình bằng tiện ích iperf. Nhưng chúng tôi tuân thủ các thông số kỹ thuật.

Gửi thư và lỗi

Tôi đã thử hàng chục lựa chọn khác nhau để gửi thư, nhưng cuối cùng tôi quyết định chọn phương án sau. Tôi đã đăng ký một hộp thư trên Yandex và sau đó lấy Đây là một ví dụ về gửi thư. Tôi đã kiểm tra và triển khai nó vào chương trình. Ví dụ này xem xét các tùy chọn khác nhau, bao gồm gửi từ gmail, v.v. Tôi không muốn bận tâm đến việc thiết lập máy chủ thư của mình và không có thời gian cho việc đó, nhưng sau đó hóa ra, điều đó cũng vô ích.

Nhật ký được gửi theo lịch trình, nếu có kết nối, cứ 6 giờ một lần: vào lúc 00 giờ, 06 giờ sáng, 12 giờ trưa và 18 giờ tối. Đã gửi nó như sau.

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

Lỗi cũng đã được gửi ban đầu. Để bắt đầu, chúng được tích lũy trong danh sách và sau đó cũng được gửi bằng bộ lập lịch nếu có kết nối. Tuy nhiên, sau đó vấn đề nảy sinh là Yandex có giới hạn về số lượng tin nhắn gửi mỗi ngày (đây là nỗi đau, nỗi buồn và sự tủi nhục). Vì có thể có rất nhiều lỗi thậm chí trong mỗi phút nên chúng tôi đã phải từ bỏ việc gửi lỗi qua thư. Vì vậy, hãy lưu ý khi tự động gửi thông tin về sự cố như vậy thông qua dịch vụ Yandex.

Máy chủ phản hồi

Để có quyền truy cập vào một phần cứng từ xa cũng như có thể tùy chỉnh và cấu hình lại nó, tôi cần một máy chủ bên ngoài. Nói chung, công bằng mà nói, việc gửi tất cả dữ liệu đến máy chủ và xây dựng tất cả các biểu đồ đẹp mắt trong giao diện web là đúng. Nhưng không phải tất cả cùng một lúc.

Đối với VPS tôi đã chọn ruvds.com. Bạn có thể lấy máy chủ đơn giản nhất. Và nói chung, với mục đích của tôi thì điều này là đủ. Nhưng vì tôi không tự bỏ tiền túi trả tiền cho máy chủ nên tôi quyết định lấy nó với một khoản dự trữ nhỏ để đủ nếu chúng tôi triển khai giao diện web, máy chủ SMTP của riêng mình, VPN, v.v. Ngoài ra, có thể thiết lập bot Telegram và không gặp vấn đề gì với việc nó bị chặn. Vì vậy, tôi đã chọn Amsterdam và các thông số sau.

Kiểm tra tốc độ đồng thời trên một số modem LTE

Là một phương thức giao tiếp với phần cứng, vim2 đã chọn kết nối ssh ngược và như thực tế đã cho thấy, đó không phải là kết nối tốt nhất. Nếu kết nối bị mất, máy chủ sẽ giữ cổng và không thể kết nối qua cổng đó trong một thời gian. Vì vậy, tốt hơn hết bạn nên sử dụng các phương thức liên lạc khác, chẳng hạn như VPN. Trong tương lai tôi muốn chuyển sang VPN nhưng không có thời gian.

Tôi sẽ không đi sâu vào chi tiết về việc thiết lập tường lửa, hạn chế quyền, vô hiệu hóa các kết nối ssh gốc và những sự thật hiển nhiên khác khi thiết lập VPS. Tôi muốn tin rằng bạn đã biết tất cả mọi thứ. Để kết nối từ xa, tôi tạo một người dùng mới trên máy chủ.

adduser vimssh

Tôi tạo khóa kết nối ssh trên phần cứng của chúng tôi.

ssh-keygen

Và tôi sao chép chúng vào máy chủ của chúng tôi.

ssh-copy-id [email protected]

Trên phần cứng của chúng tôi, tôi tạo kết nối ssh đảo ngược tự động mỗi lần khởi động.

[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

Hãy chú ý đến cổng 8083: nó xác định cổng nào tôi sẽ sử dụng để kết nối qua ssh ngược. Thêm nó vào khởi động và bắt đầu.

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

Bạn thậm chí có thể thấy trạng thái:

sudo systemctl status autossh.service

Bây giờ, trên máy chủ VPS của chúng tôi, nếu chúng tôi chạy:

ssh -p 8083 khadas@localhost

Sau đó tôi đến phần thử nghiệm phần cứng của mình. Và từ phần cứng, tôi cũng có thể gửi nhật ký và bất kỳ dữ liệu nào qua ssh đến máy chủ của mình, điều này rất thuận tiện.

Đặt tất cả lại với nhau

Kiểm tra tốc độ đồng thời trên một số modem LTE
Đang bật, hãy bắt đầu phát triển và gỡ lỗi

Phù, vậy thôi, tôi đã mô tả tất cả các nút. Bây giờ là lúc để đặt tất cả lại với nhau. Bạn có thể xem mã ngay tại đây.

Một điểm quan trọng với mã: Dự án này có thể không bắt đầu như thế này vì nó được điều chỉnh cho một nhiệm vụ cụ thể, của một kiến ​​trúc cụ thể. Dù có đưa mã nguồn nhưng tôi vẫn giải thích những điều giá trị nhất ở đây, ngay trong văn bản, nếu không thì hoàn toàn không thể hiểu được.

Lúc đầu, tôi khởi tạo gps, gpio và khởi chạy một chuỗi lập lịch riêng.

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

Trình lên lịch khá đơn giản: nó sẽ xem đã đến lúc gửi tin nhắn chưa và trạng thái lỗi hiện tại là gì. Nếu có cờ lỗi thì chúng ta nháy đèn 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)

Phần khó khăn nhất của dự án này là duy trì kết nối ssh ngược cho mỗi lần kiểm tra. Mỗi thử nghiệm đều liên quan đến việc định cấu hình lại cổng mặc định và máy chủ DNS. Vì dù sao cũng không có ai đọc nên hãy biết rằng tàu không chạy trên đường ray bằng gỗ. Ai tìm thấy quả trứng Phục sinh sẽ nhận được một ít kẹo.

Để làm điều này, tôi tạo một bảng định tuyến riêng -set-mark 0x2 và một quy tắc để chuyển hướng lưu lượng truy cập.

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

Bạn có thể tìm hiểu thêm về cách hoạt động đọc trong bài báo này.

Sau đó, tôi đi vào một vòng lặp vô tận, trong đó mỗi lần chúng tôi nhận được danh sách các modem được kết nối (để tìm hiểu xem cấu hình mạng có thay đổi đột ngột hay không).

network_list = getNetworklist()

Việc lấy danh sách các giao diện mạng khá đơn giản.

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

Sau khi nhận được danh sách, tôi đặt địa chỉ IP cho tất cả các giao diện, như tôi đã trình bày trong hình ở chương về 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")

Sau đó, tôi chỉ cần đi qua từng giao diện trong một vòng lặp. Và tôi cấu hình từng giao diện.

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

Tôi kiểm tra chức năng của giao diện, nếu không có mạng thì tôi sẽ phát sinh lỗi. Nếu có mạng thì đã đến lúc hành động!

Ở đây tôi định cấu hình định tuyến ssh đến giao diện này (nếu chưa thực hiện), gửi lỗi đến máy chủ nếu đến lúc, gửi nhật ký và cuối cùng chạy speedtest và lưu nhật ký vào tệp 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()
#и далее тестируем скорость и сохраняем логи. 

Điều đáng nói là chức năng thiết lập ssh ngược.

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

Và tất nhiên, bạn cần thêm tất cả vẻ đẹp này vào quá trình khởi nghiệp. Để làm điều này tôi tạo một tập tin:

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

Và tôi viết trong đó:

[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

Tôi bật tính năng tự động tải và bắt đầu!

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

Bây giờ tôi có thể xem nhật ký những gì đang xảy ra bằng lệnh:

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

Những phát hiện

Bây giờ điều quan trọng nhất là, kết quả là chuyện gì đã xảy ra? Dưới đây là một số biểu đồ mà tôi đã ghi lại được trong quá trình phát triển và gỡ lỗi. Các biểu đồ được xây dựng bằng gnuplot với tập lệnh sau.

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

Trải nghiệm đầu tiên là với nhà điều hành Tele2 mà tôi đã thực hiện trong vài ngày.

Kiểm tra tốc độ đồng thời trên một số modem LTE

Ở đây tôi đã sử dụng một máy chủ đo lường động. Các phép đo tốc độ hoạt động nhưng dao động rất nhiều, nhưng một số giá trị trung bình vẫn hiển thị và điều này có thể thu được bằng cách lọc dữ liệu, chẳng hạn như với đường trung bình động.

Sau này tôi đã xây dựng một số biểu đồ cho các nhà khai thác viễn thông khác. Trong trường hợp này, đã có một máy chủ thử nghiệm và kết quả cũng rất thú vị.

Kiểm tra tốc độ đồng thời trên một số modem LTE

Kiểm tra tốc độ đồng thời trên một số modem LTE

Kiểm tra tốc độ đồng thời trên một số modem LTE

Kiểm tra tốc độ đồng thời trên một số modem LTE

Như bạn có thể thấy, chủ đề này rất rộng rãi để nghiên cứu và xử lý dữ liệu này và rõ ràng là không kéo dài trong vài tuần làm việc. Nhưng…

Kết quả công việc

Công việc được hoàn thành đột ngột do hoàn cảnh nằm ngoài tầm kiểm soát của tôi. Một trong những điểm yếu của dự án này, theo ý kiến ​​chủ quan của tôi, là modem không thực sự muốn hoạt động đồng thời với các modem khác và thực hiện những thủ thuật như vậy mỗi khi tải. Vì những mục đích này, có một số lượng lớn các mẫu modem khác, thông thường chúng đã ở định dạng Mini PCI-e và được cài đặt bên trong thiết bị và dễ cấu hình hơn nhiều. Nhưng đó là một câu chuyện hoàn toàn khác. Dự án rất thú vị và tôi rất vui vì có thể tham gia vào nó.

Kiểm tra tốc độ đồng thời trên một số modem LTE

Nguồn: www.habr.com

Thêm một lời nhận xét