Сэрвісаў, якія прадстаўляюць інфармацыю аб надвор'і, дастаткова шмат, вось толькі якому з іх верыць? Калі я стаў часта ездзіць на ровары, мне захацелася валодаць найболей дакладнай інфармацыяй аб пагодных умовах у тым месцы, дзе я катаюся.
Першай думкай было сабраць невялікую DIY пагодную станцыю з датчыкамі і атрымліваць дадзеныя з яе. Але я не стаў «вынаходзіць ровар» і ў якасці крыніцы правераных дадзеных абраў пагодную інфармацыю, якая выкарыстоўваецца ў грамадзянскай авіяцыі, а менавіта МЕТРА (METeorological Aerodrome Report) і TAF (TAF – Terminal Aerodrome Forecast). У авіяцыі ад надвор'я залежаць жыцці соцень людзей, таму прагнозы максімальна дакладныя.
Гэтая інфармацыя ў кругласутачным рэжыме транслюецца голасам на кожным сучасным аэрадроме ў выглядзе АТІС (Automatic Terminal Information Service) і VOLMET (Ад франц. аб - палёт і метэа - надвор'е). Першы дае інфармацыю аб фактычным надвор'і на аэрадроме, а другі - прагноз на бліжэйшыя 24-30 гадзін, прычым не толькі на аэрадроме трансляцыі, але і на іншых.
Прыклад працы ATIS аэрапорта Унукава:
Прыклад працы VOLMET аэрапорта Унукава
Кожны раз цягаць з сабой радыёсканар або трансівер на адпаведны дыяпазон няёмка, і мне захацелася стварыць робата ў Telegram, які па націску кнопкі дазваляе атрымаць такі ж прагноз. Вылучаць пад гэта асобны сервер прынамсі немэтазгодна, роўна як і ганяць запыты на хатнюю Raspberry.
Таму ў якасці бэкэнда я вырашыў выкарыстоўваць сэрвіс
Падрыхтоўка бэкэнду
Стварэнне функцыі
У панэлі кіравання
Пасля таго як праект створаны, пераходзім у падзел функцыі:
Націскаем кнопку Стварыць функцыю і задаём ёй патрэбнае імя:
пасля націску Стварыць функцыю у нас з'явіцца ўяўленне створанай функцыі:
Перад тым, як прыступіць да стварэння кода на Python, запатрабуецца стварыць робата ў Telegram. Распісваць, як гэта робіцца, я не буду - дэталёвая інструкцыя ёсць
Рыхтуем код
У якасці крыніцы надзейных дадзеных я абраў Нацыянальнае кіраванне акіянічных і атмасферных даследаванняў ЗША (ангел. National Oceanic and Atmospheric Administration, NOAA). Гэтае навуковае агенцтва ў рэальным часе абнаўляе дадзеныя на сваім серверы ў фармаце TXT.
Спасылка для атрымання дадзеных METAR (звярніце ўвагу на рэгістр):
https://tgftp.nws.noaa.gov/data/observations/metar/stations/<код аэропорта по ICAO>.TXT
У маім выпадку бліжэйшым аэрапортам з'яўляецца Унукава, яго код па ICAO. UUWW. Пераход на сфарміраваны URL выдасць наступнае:
2020/08/10 11:30
UUWW 101130Z 31004MPS 9999 SCT048 24/13 Q1014 R01/000070 NOSIG
Першы радок - час актуальнасці прагнозу па Грынвічы. Другі радок - зводка аб фактычным надвор'і. Пілоты грамадзянскай авіяцыі без праблем зразумеюць, што азначае гэты радок, аднак нам патрэбная расшыфроўка:
- [UUWW] - Унукава, горад Масква (Расія - RU);
- [101130Z] - 10-ы дзень месяца, 11 гадзін 30 хвілін па Грынвічы;
- [31004MPS] - Напрамак ветру 310 градусаў, хуткасць 4 м / с;
- [9999] - гарызантальная бачнасць 10 км і больш;
- [SCT048] - рассеяныя / раскіданыя аблокі на вышыні 4800 футаў (~1584м);
- [24 / 13] - тэмпература 24 ° C, кропка расы 13 ° C;
- [Q1014] - ціск (QNH) 1014 гектапаскаляў (750 мм рт. Арт.);
- [R01/000070] - Каэфіцыент счаплення на паласе 01 - 0,70;
- [NOSIG] - Без істотных змен.
Прыступаем да напісання праграмнага кода. Для пачатку спатрэбіцца імпартаваць функцыі запыт и pytaf:
from urllib import request
import pytaf
пазначыць зменныя і падрыхтаваць функцыю дэкадавання:
URL_METAR = "https://tgftp.nws.noaa.gov/data/observations/metar/stations/UUWW.TXT"
URL_TAF = "https://tgftp.nws.noaa.gov/data/forecasts/taf/stations/UUWW.TXT"
def parse_data(code):
code = code.split('n')[1]
return pytaf.Decoder(pytaf.TAF(code)).decode_taf()
Пяройдзем да TAF (рэгістр таксама важны).
https://tgftp.nws.noaa.gov/data/forecasts/taf/stations/<код аэропорта по ICAO>.TXT
Як і ў папярэднім прыкладзе, паглядзім прагноз у аэрапорце Унукава:
2020/08/10 12:21
TAF UUWW 101050Z 1012/1112 28003G10MPS 9999 SCT030 TX25/1012Z TN15/1103Z
TEMPO 1012/1020 -TSRA BKN020CB
BECMG 1020/1021 FEW007 BKN016
TEMPO 1021/1106 -SHRA BKN020CB PROB40
TEMPO 1021/1106 -TSRA BKN020CB
BECMG 1101/1103 34006G13MPS
Асабліва звернем увагу на радкі ЧАС и BECMG. TEMPO азначае тое, што фактычнае надвор'е ва ўказаны прамежак будзе перыядычна мяняцца. BECMG - надвор'е паступова зменіцца ў паказаны прамежак часу.
Гэта значыць радок:
TEMPO 1012/1020 -TSRA BKN020CB
Будзе азначаць:
- [1012 / 1020] - У прамежак з 12 да 20 гадзін (па Грынвічы);
- [-TSRA] - навальніца (TS = thunderstorm) з дажджом (RA = rain) невялікай інтэнсіўнасці (знак мінус);
- [BKN020CB] - Значная (BKN = broken), кучавыя-дажджавая (CB = cumulonimbus) воблачнасць на вышыні 2000 футаў (610 метраў) над узроўнем мора.
Тэрмінаў, якія азначаюць з'явы надвор'я, дастаткова шмат, і запомніць іх цяжкавата. Код для запыту TAF пішацца аналагічнай выявай.
Заліваем код у воблака
Каб не марнаваць дарма час, возьмем шаблон тэлеграм-бота з нашага рэпазітара
Паколькі ў кодзе мы будзем звяртацца да модуля pytaf, то яго версію варта адразу дадаць у патрабаванні.txt
pytaf~=1.2.1
- Пераходзім да рэдагавання bot/tele_bot.py. Прыбіраем усё лішняе і дапісваем наш код.
import os
from urllib import request
import telebot
import pytaf
TOKEN = os.environ.get('TOKEN')
URL_METAR = "https://tgftp.nws.noaa.gov/data/observations/metar/stations/UUWW.TXT"
URL_TAF = "https://tgftp.nws.noaa.gov/data/forecasts/taf/stations/UUWW.TXT"
bot = telebot.TeleBot(token=TOKEN, threaded=False)
keyboard = telebot.types.ReplyKeyboardMarkup(resize_keyboard=True)
keyboard.row('/start', '/get_metar', '/get_taf')
def start(message):
msg = "Привет. Это бот для получения авиационного прогноза погоды "
"с серверов NOAA. Бот настроен на аэропорт Внуково (UUWW)."
bot.send_message(message.chat.id, msg, reply_markup=keyboard)
def parse_data(code):
code = code.split('n')[1]
return pytaf.Decoder(pytaf.TAF(code)).decode_taf()
def get_metar(message):
# Fetch info from server.
code = request.urlopen(URL_METAR).read().decode('utf-8')
# Send formatted answer.
bot.send_message(message.chat.id, parse_data(code), reply_markup=keyboard)
def get_taf(message):
# Fetch info from server.
code = request.urlopen(URL_TAF).read().decode('utf-8')
# Send formatted answer.
bot.send_message(message.chat.id, parse_data(code), reply_markup=keyboard)
def route_command(command, message):
"""
Commands router.
"""
if command == '/start':
return start(message)
elif command == '/get_metar':
return get_metar(message)
elif command == '/get_taf':
return get_taf(message)
def main(**kwargs):
"""
Serverless environment entry point.
"""
print(f'Received: "{kwargs}"')
message = telebot.types.Update.de_json(kwargs)
message = message.message or message.edited_message
if message and message.text and message.text[0] == '/':
print(f'Echo on "{message.text}"')
route_command(message.text.lower(), message)
- Які спакуецца ўсю дырэкторыю ў ZIP-архіў і пераходзім у панэль кіравання да створанай функцыі.
- Націскаем Рэдагаваць і загружаем архіў з кодам.
- Запаўняем адносны шлях у файле tele_bot (пашырэнне .py можна не паказваць) і эндпойнт-функцыю (у прыведзеным прыкладзе гэта асноўнай).
- У раздзеле Пераменныя асяроддзі пішам зменную TOKEN і прысвойваем ёй токен патрэбнага тэлеграм-бота.
- Націскаем Захаваць і разгарнуць, пасля чаго пераходзім у раздзел трыгеры.
- Ставім перамыкач HTTP-запыт, каб зрабіць запыт публічным.
У нас з'явіўся URL для публічнага выкліку функцыі. Засталося толькі
/setwebhook <you bot token> <public URL of your function>
Вынік
Калі ўсё зроблена правільна, то ваш робат адразу пачне працаваць і адлюстроўваць актуальную зводку авіяцыйнага надвор'я прама ў мэсэнджэры.
Зразумела, код можна дапрацоўваць, аднак нават у бягучым стане яго дастаткова, каб даведацца самае дакладнае надвор'е і прагноз з праверанай крыніцы.
Поўную версію кода вы знойдзеце ў нашым
Крыніца: habr.com