Արագության միաժամանակյա փորձարկում մի քանի LTE մոդեմների վրա
Կարանտինի ժամանակ ինձ առաջարկեցին մասնակցել մի քանի բջջային օպերատորների համար LTE մոդեմների արագությունը չափող սարքի մշակմանը։
Հաճախորդը ցանկանում էր գնահատել հեռահաղորդակցության տարբեր օպերատորների արագությունը տարբեր աշխարհագրական վայրերում, որպեսզի կարողանար հասկանալ, թե որ բջջային օպերատորն է իր համար ամենաօպտիմալը LTE կապի միջոցով սարքավորումներ տեղադրելիս, օրինակ, տեսահեռարձակումների համար: Ընդ որում, խնդիրը պետք է լուծվեր հնարավորինս պարզ և էժան՝ առանց թանկարժեք սարքավորումների։
Անմիջապես կասեմ, որ առաջադրանքն ամենապարզն ու գիտելիքատարը չէ, ես ձեզ կասեմ, թե ինչ խնդիրների եմ հանդիպել և ինչպես եմ դրանք լուծել: Այսպիսով, եկեք գնանք:
Նշում
LTE կապի արագությունը չափելը շատ բարդ խնդիր է. անհրաժեշտ է ընտրել ճիշտ սարքավորում և չափման տեխնիկա, ինչպես նաև լավ պատկերացում ունենալ բջջային ցանցի տոպոլոգիայի և աշխատանքի մասին: Բացի այդ, արագության վրա կարող են ազդել մի քանի գործոններ՝ բջջի բաժանորդների թիվը, եղանակային պայմանները, նույնիսկ բջիջից բջիջ արագությունը կարող է կտրուկ տարբերվել ցանցի տոպոլոգիայի պատճառով: Ընդհանուր առմամբ, սա հսկայական թվով անհայտների խնդիր է, և միայն հեռահաղորդակցության օպերատորը կարող է այն ճիշտ լուծել:
Սկզբում հաճախորդը պարզապես ցանկանում էր սուրհանդակը վարել օպերատորների հեռախոսներով, չափումներ անել անմիջապես հեռախոսով, ապա արագության չափման արդյունքները գրել նոթատետրում: lte ցանցերի արագությունը չափելու իմ լուծումը, թեև իդեալական չէ, բայց լուծում է խնդիրը։
Ժամանակի սղության պատճառով որոշումներ եմ կայացրել ոչ թե հարմարության կամ գործնականության, այլ զարգացման արագության օգտին։ Օրինակ, հակադարձ ssh-ն օգտագործվել է հեռավոր մուտքի համար, ավելի գործնական VPN-ի փոխարեն՝ սերվերի և յուրաքանչյուր առանձին հաճախորդի տեղադրման վրա ժամանակ խնայելու համար:
Տեխնիկական առաջադրանքը բավականին պարզ էր, ես մի փոքր կընդլայնեմ այն վերջնական օգտագործողի հասկանալու համար: Տեխնիկական լուծումների և սարքավորումների ընտրությունը թելադրել է հաճախորդը։ Այսպիսով, տեխնիկական բնութագրումն ինքնին, բոլոր հաստատումներից հետո.
Հիմնված է մեկ տախտակային համակարգչի վրա vim2 H մոդեմների միջոցով lte միացումների արագության ստուգիչ սարքեքuawei e3372h - 153 մի քանի հեռահաղորդակցության օպերատորներ (մեկից մինչև n): Անհրաժեշտ է նաև կոորդինատներ ստանալ UART-ի միջոցով միացված GPS ընդունիչից։ Կատարեք արագության չափումներ՝ օգտագործելով ծառայությունը www.speedtest.net և դրանք դնել աղյուսակի մեջ, ինչպիսին է.
Աղյուսակ csv ձևաչափով: Այնուհետև 6 ժամը մեկ ուղարկեք այս նշանը էլեկտրոնային փոստով: Սխալների դեպքում թարթեք LED-ը, որը միացված է GPIO-ին:
Ես նկարագրեցի տեխնիկական բնութագրերը անվճար ձևով, բազմաթիվ հաստատումներից հետո: Բայց առաջադրանքի իմաստն արդեն տեսանելի է։ Ամեն ինչի համար մեկ շաբաթ է տրվել։ Բայց իրականում դա տեւեց երեք շաբաթ։ Սա հաշվի առնելով այն հանգամանքը, որ ես դա արել եմ միայն իմ հիմնական աշխատանքից հետո և հանգստյան օրերին։
Այստեղ ես ուզում եմ ևս մեկ անգամ ուշադրություն հրավիրել այն փաստի վրա, որ հաճախորդը նախապես պայմանավորվել է արագության չափման ծառայության և սարքավորումների օգտագործման վերաբերյալ, ինչը մեծապես սահմանափակել է իմ հնարավորությունները: Բյուջեն նույնպես սահմանափակ էր, ուստի առանձնահատուկ ոչինչ չգնվեց։ Այսպիսով, մենք պետք է խաղայինք այս կանոններով:
Ճարտարապետություն և զարգացում
Սխեման պարզ է և ակնհայտ: Ուստի կթողնեմ առանց հատուկ մեկնաբանությունների։
Ես որոշեցի ամբողջ նախագիծն իրականացնել python-ով, չնայած այն հանգամանքին, որ ընդհանրապես այս լեզվով զարգացնելու փորձ չունեի։ Ես ընտրեցի այն, քանի որ կային պատրաստի օրինակներ և լուծումներ, որոնք կարող էին արագացնել զարգացումը: Ուստի բոլոր պրոֆեսիոնալ ծրագրավորողներին խնդրում եմ չշտկել python-ում զարգանալու իմ առաջին փորձը, և ես միշտ ուրախ եմ լսել կառուցողական քննադատություն՝ իմ հմտությունները բարելավելու համար:
Ընթացքում ես նաև հայտնաբերեցի, որ python-ն ունի երկու գործող 2 և 3 տարբերակներ, արդյունքում ես կանգ առա երրորդի վրա:
Սարքավորման հանգույցներ
Մեկ ափսե vim2
Ինձ տրվեց մեկ տախտակով համակարգիչ՝ որպես հիմնական մեքենա vim2
Գերազանց, հզոր մեդիա պրոցեսոր խելացի տան և SMART-TV-ի համար, բայց չափազանց անհամապատասխան այս առաջադրանքի համար, կամ, ասենք, վատ պիտանի: Օրինակ, նրա հիմնական ՕՀ-ն Android-ն է, իսկ Linux-ը երկրորդական ՕՀ է, և համապատասխանաբար ոչ ոք չի երաշխավորում Linux-ի տակ գտնվող բոլոր հանգույցների և դրայվերների բարձրորակ աշխատանքը։ Եվ ես ենթադրում եմ, որ որոշ խնդիրներ կապված են եղել այս հարթակի USB դրայվերների հետ, ուստի մոդեմները չեն աշխատել այնպես, ինչպես սպասվում էր այս տախտակի վրա: Այն նաև ունի շատ վատ և ցրված փաստաթղթեր, ուստի յուրաքանչյուր գործողություն շատ ժամանակ էր պահանջում նավահանգիստները փորելու համար: Նույնիսկ սովորական աշխատանքը GPIO-ի հետ շատ արյուն խլեց։ Օրինակ, ինձանից մի քանի ժամ պահանջվեց LED-ը տեղադրելու համար: Բայց օբյեկտիվ լինելու համար սկզբունքորեն կարեւոր չէր, թե դա ինչ սինգլ տախտակ էր, գլխավորն այն էր, որ աշխատում էր, ու USB պորտեր կային։
Նախ, ես պետք է տեղադրեմ Linux-ը այս տախտակի վրա: Որպեսզի բոլորի, ինչպես նաև նրանց համար, ովքեր կզբաղվեն այս մեկ տախտակային համակարգով, չփչացնեմ փաստաթղթերի մոլուցքը, ես գրում եմ այս գլուխը:
Linux-ը տեղադրելու երկու տարբերակ կա՝ արտաքին SD քարտի կամ ներքին MMC-ի վրա: Ես մի երեկո անցկացրի՝ փորձելով պարզել, թե ինչպես այն աշխատի քարտի հետ, ուստի որոշեցի տեղադրել այն MMC-ի վրա, չնայած, անկասկած, շատ ավելի հեշտ կլիներ աշխատել արտաքին քարտի հետ:
Որոնվածի մասին այստեղ ծուռ ասվեց. Թարգմանում եմ տարօրինակից ռուսերեն։ Տախտակը բռնկելու համար պետք է միացնեմ ապարատային UART-ը։ Միացրեց այն հետեւյալ կերպ.
Այս որոնվածը վերբեռնելու համար ինձ անհրաժեշտ են կոմունալ ծառայություններ: Այս մասին ավելի մանրամասն այստեղ. Ես չեմ փորձել այն թարթել Windows-ի տակ, բայց պետք է մի քանի խոսք ասեմ Linux-ի տակ որոնվածի մասին: Նախ, ես կտեղադրեմ կոմունալ ծառայությունները հրահանգների համաձայն:
git clone https://github.com/khadas/utils
cd /path/to/utils
sudo ./INSTALL
Աաաանդ... Ոչինչ չի ստացվում: Ես մի քանի ժամ ծախսեցի տեղադրման սկրիպտները խմբագրելու վրա, որպեսզի ինձ մոտ ամեն ինչ ճիշտ տեղադրվի։ Ես չեմ հիշում, թե ինչ եմ արել այնտեղ, բայց կար նաև այդ կրկեսը ձիերով։ Ուստի զգույշ եղեք։ Բայց առանց այս կոմունալ ծառայությունների իմաստ չկա ավելի խոշտանգել vim2-ին: Ավելի լավ է ընդհանրապես չխառնվեք նրա հետ։
Դժոխքի յոթ շրջանակներից, սցենարի կազմաձևումից և տեղադրումից հետո ես ստացա աշխատանքային կոմունալ ծառայությունների փաթեթ: Ես USB-ի միջոցով միացրի տախտակը իմ Linux համակարգչին, ինչպես նաև միացրի UART-ը վերը նշված գծապատկերի համաձայն:
Ես տեղադրում եմ իմ սիրելի minicom տերմինալը 115200 արագությամբ, առանց ապարատային և ծրագրային սխալների վերահսկման: Եվ եկեք սկսենք:
VIM2-ը UART տերմինալում բեռնելիս ես սեղմում եմ ստեղն, օրինակ՝ բացատ, բեռնումը դադարեցնելու համար: Գիծը հայտնվելուց հետո
kvim2#
Ես մուտքագրում եմ հրամանը.
kvim2# run update
Հոսթի վրա, որից մենք բեռնում ենք, ես կատարում եմ.
burn-tool -v aml -b VIM2 -i VIM2_Ubuntu-server-bionic_Linux-4.9_arm64_EMMC_V20191231.img
Վերջ, ֆու: Ստուգեցի, տախտակի վրա Linux կա։ Մուտք/գաղտնաբառ khadas:khadas.
Դրանից հետո որոշ աննշան նախնական պարամետրեր: Հետագա աշխատանքի համար ես անջատում եմ sudo-ի գաղտնաբառը (այո, ոչ անվտանգ, բայց հարմար):
sudo visudo
Ես խմբագրում եմ տողը ձևի մեջ և պահում
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) NOPASSWD: ALL
Հետո փոխում եմ ներկայիս լոկալը, որ ժամը լինի Մոսկվայում, հակառակ դեպքում՝ Գրինվիչում։
Եթե դժվարանում եք, ապա մի օգտագործեք այս տախտակը, Raspberry Pi-ն ավելի լավն է: Անկեղծ ասած.
Huawei e3372h մոդեմ – 153
Այս մոդեմն ինձ համար արյան զգալի աղբյուր էր, և, փաստորեն, դարձավ ամբողջ նախագծի խցանումը: Ընդհանուր առմամբ, այս սարքերի «մոդեմ» անվանումը բացարձակապես չի արտացոլում աշխատանքի էությունը. սա հզոր կոմբինատ է, այս սարքաշարն ունի կոմպոզիտային սարք, որը ձևացնում է որպես CD-ROM՝ դրայվերներ տեղադրելու համար, այնուհետև անցնում է ցանցային քարտի ռեժիմին:
Ճարտարապետական տեսանկյունից Linux օգտատիրոջ տեսանկյունից բոլոր կարգավորումներից հետո այն կարծես այսպիսին է՝ մոդեմը միացնելուց հետո ես ունեմ eth* ցանցային ինտերֆեյս, որը dhcp-ի միջոցով ստանում է IP հասցեն 192.168.8.100 և լռելյայն gateway։ կազմում է 192.168.8.1:
Եվ ամենակարևոր պահը. Մոդեմի այս մոդելը չի կարող աշխատել մոդեմի ռեժիմում, որը կառավարվում է AT հրամաններով. Ամեն ինչ շատ ավելի պարզ կլիներ, յուրաքանչյուր մոդեմի համար ստեղծեք PPP կապեր և աշխատեք դրանցով: Բայց իմ դեպքում «ինքն» (ավելի ճիշտ՝ Linux-ի սուզորդը udev կանոնների համաձայն), ստեղծում է eth ինտերֆեյս և dhcp-ի միջոցով դրան IP հասցե է հատկացնում։
Հետագա շփոթությունից խուսափելու համար առաջարկում եմ մոռանալ «մոդեմ» բառը և ասել ցանցային քարտ և դարպաս, քանի որ, ըստ էության, դա նման է նոր ցանցային քարտը դարպասի հետ կապելուն:
Երբ կա մեկ մոդեմ, դա որևէ հատուկ խնդիր չի առաջացնում, բայց երբ կա մեկից ավելի, այն է՝ n-հատ, առաջանում է ցանցի հետևյալ պատկերը.
Այսինքն՝ n ցանցային քարտեր՝ նույն IP հասցեով, յուրաքանչյուրը՝ նույն լռելյայն դարպասով։ Բայց իրականում նրանցից յուրաքանչյուրը միացված է իր օպերատորին։
Սկզբում ես ունեի մի պարզ լուծում՝ օգտագործելով ifconfig կամ ip հրամանը, անջատեք բոլոր ինտերֆեյսները և պարզապես հերթով միացրեք մեկը և փորձարկեք այն: Լուծումը լավ էր բոլորի համար, միայն թե միացման պահերին չէի կարողանում միանալ սարքին։ Եվ քանի որ անցումը հաճախակի է և արագ, ես իրականում ընդհանրապես հնարավորություն չունեի միանալու:
Հետևաբար, ես ընտրեցի մոդեմների IP հասցեները ձեռքով փոխելու և այնուհետև երթևեկության կարգավորումների միջոցով երթևեկությունը վարելու ուղին:
Սրանով մոդեմների հետ կապված իմ խնդիրները չավարտվեցին՝ հոսանքի հետ կապված խնդիրների դեպքում դրանք թափվում էին, և USB հանգույցի լավ կայուն սնուցում էր պահանջվում։ Ես լուծեցի այս խնդիրը՝ հզորությունը կոշտ զոդելով անմիջապես հանգույցին: Մեկ այլ խնդիր, որը ես հանդիպեցի, և որը փչացրեց ամբողջ նախագիծը. սարքի վերագործարկումից կամ սառը գործարկումից հետո ոչ բոլոր մոդեմները հայտնաբերվեցին և ոչ միշտ, և ես չկարողացա որոշել, թե ինչու դա տեղի ունեցավ և ինչ ալգորիթմով: Բայց առաջին հերթին առաջինը:
Որպեսզի մոդեմը ճիշտ աշխատի, ես տեղադրել եմ usb-modeswitch փաթեթը։
Որից հետո միանալուց հետո մոդեմը ճիշտ կհայտնաբերվի և կկարգավորվի udev ենթահամակարգի կողմից։ Ստուգում եմ՝ ուղղակի միացնելով մոդեմը և համոզվելով, որ ցանցը հայտնվում է։
Մեկ այլ խնդիր, որը ես չկարողացա լուծել՝ ինչպե՞ս կարող եմ այս մոդեմից ստանալ օպերատորի անունը, որի հետ մենք աշխատում ենք: Օպերատորի անունը պարունակվում է մոդեմի վեբ ինտերֆեյսում 192.168.8.1 հասցեում: Սա դինամիկ վեբ էջ է, որը տվյալներ է ստանում Ajax-ի հարցումների միջոցով, ուստի էջը պարզեցնելը և անունը վերլուծելը չի աշխատի: Այսպիսով, ես սկսեցի նայել, թե ինչպես զարգացնել վեբ էջ և այլն, և հասկացա, որ ինչ-որ անհեթեթություն եմ անում: Արդյունքում նա թքեց, և օպերատորը սկսեց ստանալ՝ օգտագործելով Speedtest API-ն:
Շատ ավելի հեշտ կլիներ, եթե մոդեմը մուտք ունենար AT հրամանների միջոցով: Հնարավոր կլինի վերակարգավորել այն, ստեղծել ppp կապ, նշանակել IP, ստանալ հեռահաղորդակցության օպերատոր և այլն: Բայց ավաղ, ես աշխատում եմ նրանով, ինչ ինձ տրվել է:
GPS
Ինձ տրված GPS ընդունիչն ուներ UART ինտերֆեյս և հզորություն: Դա լավագույն լուծումը չէր, բայց այն դեռ գործունակ էր և պարզ: Ընդունիչն այսպիսի տեսք ուներ.
Ճիշտն ասած, ես առաջին անգամ էի աշխատում GPS ընդունիչով, բայց ինչպես սպասում էի, մեզ համար ամեն ինչ վաղուց էր մտածված։ Այսպիսով, մենք պարզապես օգտագործում ենք պատրաստի լուծումներ:
Նախ, ես միացնում եմ uart_AO_B (UART_RX_AO_B, UART_TX_AO_B) GPS-ը միացնելու համար:
khadas@Khadas:~$ sudo fdtput -t s /dtb.img /serial@c81004e0 status okay
Այնուհետև ես ստուգում եմ վիրահատության հաջողությունը:
khadas@Khadas:~$ fdtget /dtb.img /serial@c81004e0 status
okay
Այս հրամանը, ըստ երևույթին, խմբագրում է devtree-ն անմիջապես, ինչը շատ հարմար է:
Այս գործողության հաջող ավարտից հետո վերագործարկեք և տեղադրեք GPS դեյմոնը:
khadas@Khadas:~$ sudo reboot
GPS դեյմոնի տեղադրում: Ես տեղադրում եմ ամեն ինչ և անմիջապես կտրում այն հետագա կոնֆիգուրացիայի համար:
GPS լարը ձեռքումս է, UART կարգաբերող լարերը՝ մատներիս տակ։
Ես վերաբեռնում և ստուգում եմ GPS-ի աշխատանքը gpsmon ծրագրի միջոցով:
Դուք չեք կարող տեսնել արբանյակները այս սքրինշոթում, բայց դուք կարող եք տեսնել կապը GPS ընդունիչի հետ, և դա նշանակում է, որ ամեն ինչ լավ է:
Python-ում ես փորձեցի այս դեյմոնի հետ աշխատելու բազմաթիվ տարբերակներ, բայց որոշեցի այն մեկը, որը ճիշտ էր աշխատում python 3-ի հետ:
Տեղադրում եմ անհրաժեշտ գրադարանը։
sudo -H pip3 install gps3
Եվ ես քանդակում եմ աշխատանքային ծածկագիրը։
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
Եթե ինձ անհրաժեշտ է կոորդինատներ ստանալ, դա արվում է հետևյալ զանգով.
longitude, latitude = getPositionData(agps_thread)
Իսկ 1-10 վայրկյանի ընթացքում ես կամ կստանամ կոորդինատը, կամ ոչ։ Այո, կոորդինատներ ստանալու տասը փորձ եմ ունեցել։ Ոչ օպտիմալ, ծուռ և թեքված, բայց աշխատում է: Ես որոշեցի դա անել, քանի որ GPS-ը կարող է վատ ընդունելություն ունենալ և ոչ միշտ ստանալ տվյալներ: Եթե դուք սպասում եք տվյալների ստանալուն, ապա եթե աշխատում եք հեռավոր սենյակում, ծրագիրը կսառչի այս վայրում: Ուստի ես իրագործեցի այս ոչ էլեգանտ տարբերակը։
Սկզբունքորեն, եթե ավելի շատ ժամանակ լիներ, հնարավոր կլիներ GPS-ից տվյալներ ստանալ անմիջապես UART-ի միջոցով, վերլուծել դրանք առանձին թեմայում և աշխատել դրա հետ։ Բայց ընդհանրապես ժամանակ չկար, այստեղից էլ՝ դաժանորեն տգեղ օրենսգիրքը։ Եվ այո, ես չեմ ամաչում։
Լույս արտանետող դիոդ
LED-ի միացումը պարզ էր և միևնույն ժամանակ դժվար: Հիմնական դժվարությունն այն է, որ համակարգում PIN համարը չի համապատասխանում գրատախտակի վրա նշված PIN համարին և քանի որ փաստաթուղթը գրված է ձախ կողմում: ՕՀ-ում ապարատային կապի համարը և փին համարը համեմատելու համար հարկավոր է գործարկել հրամանը.
gpio readall
Համակարգում և տախտակի վրա կցուցադրվի փին համապատասխանության աղյուսակ: Որից հետո ես արդեն կարող եմ գործարկել քորոցը հենց ՕՀ-ում: Իմ դեպքում LED-ը միացված է GPIOH_5.
Հիմա սխալների դեպքում զանգում եմ error_blink()-ն ու լուսադիոդը գեղեցիկ կթարթի։
Ծրագրային հանգույցներ
Speedtest API
Մեծ ուրախություն է, որ speedtest.net ծառայությունն ունի իր սեփական python-API-ն, կարող եք նայել Github.
Լավն այն է, որ կան սկզբնաղբյուրներ, որոնք նույնպես կարելի է դիտել: Ինչպես աշխատել այս API-ի հետ (պարզ օրինակներ) կարելի է գտնել այստեղ համապատասխան բաժինը.
Ես տեղադրում եմ python գրադարանը հետևյալ հրամանով.
sudo -H pip3 install speedtest-cli
Օրինակ, դուք կարող եք նույնիսկ արագության ստուգիչ տեղադրել Ubuntu-ում անմիջապես ծրագրաշարից: Սա նույն python հավելվածն է, որն այնուհետև կարող է գործարկվել անմիջապես վահանակից:
sudo apt install speedtest-cli -y
Եվ չափեք ձեր ինտերնետի արագությունը:
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
Արդյունքում, ճիշտ այնպես, ինչպես ես արեցի: Ես ստիպված էի մտնել այս արագության թեստի սկզբնական կոդերը, որպեսզի դրանք ավելի լիարժեք կիրառեի իմ նախագծում: Ամենակարևոր խնդիրներից մեկը հեռահաղորդակցության օպերատորի անունը ստանալն է, որպեսզի այն փոխարինվի ափսեի մեջ:
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"
#тут идет запись в файл логов
Այստեղ նույնպես ամեն ինչ պարզվեց, որ այնքան էլ պարզ չէր, թեև շատ ավելի պարզ կթվա։ Սկզբում սերվերների պարամետրը հավասար էր [], ասում են, ընտրիր լավագույն սերվերը։ Արդյունքում ես ունեի պատահական սերվերներ և, ինչպես կարող եք կռահել, փոփոխական արագություն: Սա բավականին բարդ թեմա է, ֆիքսված սերվերի օգտագործումը, եթե այո, ստատիկ կամ դինամիկ, պահանջում է հետազոտություն: Բայց ահա արագության չափման գրաֆիկների օրինակ Beeline օպերատորի համար, երբ դինամիկ կերպով ընտրում է թեստային սերվեր և ստատիկորեն ամրագրված:
Արագության փորձարկման արդյունք՝ մեկ խիստ ընտրված մեկ սերվերով։
Թեստավորման ժամանակ երկու տեղում էլ «մորթի» է, և այն պետք է հեռացնել մաթեմատիկական մեթոդներով։ Բայց ֆիքսված սերվերի դեպքում այն մի փոքր ավելի քիչ է, և ամպլիտուդան ավելի կայուն է:
Ընդհանրապես, սա մեծ հետազոտության վայր է։ Եվ ես կչափեի իմ սերվերի արագությունը՝ օգտագործելով iperf կոմունալը: Բայց մենք մնում ենք տեխնիկական բնութագրերին:
Փոստի ուղարկում և սխալներ
Փոստ ուղարկելու համար ես փորձեցի մի քանի տասնյակ տարբեր տարբերակներ, բայց ի վերջո կանգ առա հետևյալի վրա. Ես գրանցեցի փոստարկղ Yandex-ում, հետո վերցրեցի Սա նամակ ուղարկելու օրինակ է. Ես ստուգեցի այն և ներդրեցի ծրագրում: Այս օրինակը ուսումնասիրում է տարբեր տարբերակներ, այդ թվում՝ ուղարկելը gmail-ից և այլն: Ես չէի ուզում անհանգստանալ իմ փոստի սերվերի տեղադրմամբ և ժամանակ չունեի դրա համար, բայց ինչպես պարզվեց ավելի ուշ, դա նույնպես ապարդյուն էր:
Տեղեկամատյաններն ուղարկվել են ըստ ժամանակացույցի, եթե կա կապ, յուրաքանչյուր 6 ժամը՝ ժամը 00-ին, 06-ին, 12-ին և 18-ին։ Ուղարկեց այն հետևյալ կերպ.
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
Ի սկզբանե ուղարկվել են նաև սխալներ: Սկզբից դրանք կուտակվում էին ցուցակում, այնուհետև ուղարկվում էին նաև ժամանակացույցի միջոցով, եթե կապ կար: Այնուամենայնիվ, այնուհետև խնդիրներ առաջացան այն բանի հետ, որ Yandex-ը սահմանափակում է օրական ուղարկվող հաղորդագրությունների քանակը (սա ցավ է, տխրություն և նվաստացում): Քանի որ նույնիսկ րոպեում կարող էին լինել հսկայական քանակությամբ սխալներ, մենք ստիպված եղանք հրաժարվել փոստով սխալներ ուղարկելուց: Ուստի նկատի ունեցեք Yandex ծառայությունների միջոցով նման խնդրի մասին տեղեկատվություն ավտոմատ կերպով ուղարկելիս:
Հետադարձ կապի սերվեր
Որպեսզի կարողանայի մուտք ունենալ դեպի հեռավոր սարքաշար և այն հարմարեցնել և վերակազմավորել, ինձ արտաքին սերվեր էր անհրաժեշտ: Ընդհանուր առմամբ, արդարության համար, ճիշտ կլինի ուղարկել բոլոր տվյալները սերվերին և կառուցել բոլոր գեղեցիկ գրաֆիկները վեբ ինտերֆեյսի մեջ։ Բայց ոչ միանգամից։
VPS-ի համար ես ընտրեցի ruvds.com. Դուք կարող եք վերցնել ամենապարզ սերվերը: Եվ ընդհանրապես, իմ նպատակների համար սա բավական կլիներ։ Բայց քանի որ ես չեմ վճարել սերվերի համար իմ գրպանից, ես որոշեցի վերցնել այն փոքր պահուստով, որպեսզի բավական լինի, եթե մենք տեղադրենք վեբ ինտերֆեյս, մեր սեփական SMTP սերվեր, VPN և այլն: Բացի այդ, կարող եք ստեղծել Telegram բոտ և խնդիրներ չունենալ դրա արգելափակման հետ: Հետեւաբար, ես ընտրեցի Ամստերդամը եւ հետեւյալ պարամետրերը.
Որպես սարքաշարի հետ կապի մեթոդ, vim2-ն ընտրեց հակադարձ ssh կապը և, ինչպես ցույց տվեց պրակտիկան, դա լավագույնը չէ: Եթե կապը կորչում է, սերվերը պահում է պորտը և որոշ ժամանակ հնարավոր չէ միանալ դրա միջոցով: Հետևաբար, դեռ ավելի լավ է օգտագործել հաղորդակցման այլ մեթոդներ, օրինակ՝ VPN: Ապագայում ես ուզում էի անցնել VPN, բայց ժամանակ չունեի.
Ես չեմ խորանա firewall-ի տեղադրման, իրավունքների սահմանափակման, root ssh կապերի անջատման և VPS-ի ստեղծման այլ ճշմարտությունների մասին: Ես կցանկանայի հավատալ, որ դուք արդեն ամեն ինչ գիտեք։ Հեռակա կապի համար ես սերվերի վրա նոր օգտվող եմ ստեղծում:
adduser vimssh
Ես ստեղծում եմ ssh կապի բանալիներ մեր սարքավորման վրա:
Այնուհետև ես հասնում եմ սարքավորման իմ փորձարկմանը: Իսկ ապարատայինից կարող եմ նաև logs և ցանկացած տվյալ ուղարկել իմ սերվերին ssh-ի միջոցով, ինչը շատ հարմար է։
Բոլորը միասին դնելով
Միացնելով, եկեք սկսենք մշակումը և վրիպազերծումը
Ֆու, դե, վերջ, ես նկարագրեցի բոլոր հանգույցները: Հիմա ժամանակն է ամեն ինչ ի մի բերելու: Դուք կարող եք տեսնել կոդը այստեղ.
Կոդի հետ կապված կարևոր կետ. Այս նախագիծը կարող է չսկսվել այսպես, քանի որ այն հարմարեցված էր կոնկրետ առաջադրանքի, կոնկրետ ճարտարապետության համար: Թեև ես տալիս եմ սկզբնաղբյուրը, ես դեռ կբացատրեմ ամենաարժեքավոր բաները այստեղ, հենց տեքստում, հակառակ դեպքում դա բոլորովին անհասկանալի է:
Սկզբում ես սկզբնավորում եմ gps-ը, gpio-ն և գործարկում եմ առանձին ժամանակացույցի թեմա:
Ժամանակացույցը բավականին պարզ է. այն տեսնում է, թե արդյոք եկել է հաղորդագրություններ ուղարկելու ժամանակը և որն է ներկայիս սխալի կարգավիճակը: Եթե կա սխալի դրոշ, ապա մենք թարթում ենք 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)
Այս նախագծի ամենադժվար մասը յուրաքանչյուր թեստի համար հակադարձ ssh կապի պահպանումն է: Յուրաքանչյուր թեստ ներառում է կանխադրված դարպասի և DNS սերվերի վերակազմավորում: Քանի որ ամեն դեպքում ոչ ոք չի կարդում, իմացեք, որ գնացքը փայտե ռելսերի վրա չի նստում։ Ով գտնում է Զատկի ձուն, ստանում է կոնֆետ:
Դա անելու համար ես ստեղծում եմ առանձին երթուղային աղյուսակ՝ set-mark 0x2 և տրաֆիկի վերահղման կանոն:
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")
Դուք կարող եք ավելին իմանալ այն մասին, թե ինչպես է այն աշխատում կարդալ այս հոդվածում.
Որից հետո ես անցնում եմ անվերջ հանգույց, որտեղ ամեն անգամ մենք ստանում ենք միացված մոդեմների ցուցակը (պարզելու համար, թե արդյոք ցանցի կոնֆիգուրացիան հանկարծակի փոխվել է):
network_list = getNetworklist()
Ցանցային ինտերֆեյսների ցուցակ ստանալը բավականին պարզ է:
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
Ցուցակը ստանալուց հետո ես բոլոր ինտերֆեյսերի վրա դրեցի IP հասցեներ, ինչպես ցույց տվեցի մոդեմի մասին գլխի նկարում։
Այնուհետև ես պարզապես անցնում եմ յուրաքանչյուր ինտերֆեյսի միջով մի օղակով: Եվ ես կարգավորում եմ յուրաքանչյուր ինտերֆեյս:
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'")
Ես ստուգում եմ ինտերֆեյսը ֆունկցիոնալության համար, եթե ցանց չկա, ապա ես առաջացնում եմ սխալներ: Եթե կա ցանց, ապա ժամանակն է գործելու:
Այստեղ ես կարգավորում եմ ssh-ի երթուղավորումը այս ինտերֆեյսի վրա (եթե դա չի արվել), ուղարկում եմ սխալներ սերվերին, եթե ժամանակը եկել է, ուղարկում եմ տեղեկամատյաններ և վերջապես գործարկում արագության թեստ և պահում տեղեկամատյանները 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()
#и далее тестируем скорость и сохраняем логи.
Հարկ է նշել հակադարձ 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")
Եվ իհարկե, դուք պետք է ավելացնեք այս ամբողջ գեղեցկությունը ստարտափին: Դա անելու համար ես ստեղծում եմ ֆայլ.
sudo vim /etc/systemd/system/modems_speedtest.service
Դե, հիմա ամենակարևորը, ի՞նչ եղավ արդյունքում։ Ահա մի քանի գրաֆիկներ, որոնք ես կարողացա նկարել մշակման և վրիպազերծման գործընթացում: Գրաֆիկները կառուցվել են gnuplot-ի միջոցով՝ հետևյալ սցենարով.
#! /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"
Առաջին փորձը Tele2 օպերատորի հետ էր, որը ես վարեցի մի քանի օր։
Այստեղ ես օգտագործեցի դինամիկ չափիչ սերվեր: Արագության չափումները գործում են, բայց շատ են տատանվում, բայց որոշ միջին արժեք դեռ տեսանելի է, և դա կարելի է ստանալ՝ զտելով տվյալները, օրինակ՝ շարժվող միջինով:
Հետագայում ես կառուցեցի մի շարք գրաֆիկներ հեռահաղորդակցության այլ օպերատորների համար: Այս դեպքում արդեն կար մեկ թեստավորման սերվեր, և արդյունքները նույնպես շատ հետաքրքիր էին։
Ինչպես տեսնում եք, թեման շատ ծավալուն է այս տվյալների հետազոտության և մշակման համար, և ակնհայտորեն չի տևում մի քանի շաբաթվա աշխատանք: Բայց…
Աշխատանքի արդյունք
Աշխատանքն անսպասելիորեն ավարտվեց իմ կամքից անկախ հանգամանքների պատճառով։ Այս նախագծի թույլ կողմերից մեկը, իմ սուբյեկտիվ կարծիքով, մոդեմն էր, որն իրականում չէր ցանկանում միաժամանակ աշխատել այլ մոդեմների հետ և ամեն անգամ բեռնվելիս նման հնարքներ էր անում։ Այս նպատակների համար կան հսկայական թվով այլ մոդեմների մոդելներ, սովորաբար դրանք արդեն Mini PCI-e ձևաչափով են և տեղադրված են սարքի ներսում և շատ ավելի հեշտ է կարգավորել: Բայց դա բոլորովին այլ պատմություն է: Նախագիծը հետաքրքիր էր, և ես շատ ուրախ էի, որ կարողացա մասնակցել դրան։