Най-точната прогноза за времето: бот за Telegram на облачни функции

Най-точната прогноза за времето: бот за Telegram на облачни функции
Има много услуги, предоставящи информация за времето, но на коя от тях да вярвам? Когато започнах често да карам велосипед, исках да разполагам с най-точната информация за метеорологичните условия на мястото, където карам.

Първата ми идея беше да събера малка DIY метеорологична станция с сензори и да получавам данни от нея. Но не исках да „изобретявам колелото“ и като източник на проверени данни избрах метеорологичната информация, която се използва в гражданската авиация, а именно METAR (METeorological Aerodrome Report) и TAF (TAF — Terminal Aerodrome Forecast). В авиацията от времето зависят lives на стотици хора, така че прогнозите са максимално точни.

Тази информация се предава в реално време с глас на всяко модерно летище под формата на ATIS (Automatic Terminal Information Service) и VOLMET (от френски, vol — полет и météo — време). Първият предоставя информация за актуалните метеорологични условия на летището, а вторият — прогноза за следващите 24-30 часа, не само за летището, от което се предава, а и за други.

Пример за работа на ATIS на летище Внуково:

Пример за работа на VOLMET на летище Внуково

Всеки път е неудобно да нося с мен радиоприемник или трансивер на съответната честота, и исках да създам бот в Telegram, който с натискане на бутон да предоставя същата прогноза. Не е целесъобразно да се отделя собствен сървър за това, нито да се изпращат заявки на домашната Raspberry.

Затова реших да използвам услугата Облачни функции Selectel. Броят на заявките ще бъде нищожен, така че такова обслужване ще излезе практически безплатно (според моите изчисления, ще бъде 22 рубли за 100 000 заявки).

Подготовка на бекенда

Създаване на функция

В контролния панел my.selectel.ru отваряме изгледа Облачна платформа и създаваме нов проект:

Най-точната прогноза за времето: бот за Telegram на облачни функции
След като проектът е създаден, преминаваме в раздел Функции:

Най-точната прогноза за времето: бот за Telegram на облачни функции
Натискаме бутона Създайте функция и задаваме необходимото име:

Най-точната прогноза за времето: бот за Telegram на облачни функции
След натискане на Създайте функция ще се появи изглед на създадената функция:

Най-точната прогноза за времето: бот за Telegram на облачни функции
Преди да започна с написването на кода на Python, ще трябва да създам бот в Telegram. Няма да описвам как се прави това — подробна инструкция има в нашата база знания. Най-важното за нас е токенът на създадения бот.

Подготвяме кода

Като източник на надеждни данни избрах Националната администрация за океанични и атмосферни изследвания на САЩ (англ. National Oceanic and Atmospheric Administration, NOAA). Тази научна агенция обновява данните си в режим на реално време на сървъра си в TXT формат.

Линк за извличане на данни METAR (обърнете внимание на регистъра):

https://tgftp.nws.noaa.gov/data/observations/metar/stations/.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] — без съществени промени.

Приступваме към написването на програмния код. Първо ще трябва да импортираме функциите request и 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/.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

Особено ще обърнем внимание на редовете TEMPO и BECMG. TEMPO означава, че действителната време в указания интервал периодично ще се променя. BECMG — времето постепенно ще се промени в указания интервал време.

Тоест редът:

TEMPO 1012/1020 -TSRA BKN020CB

Ще означава:

  • [1012/1020] — в периода от 12 до 20 часа (по Гринуич);
  • [-TSRA] — гръмотевична буря (TS = thunderstorms) с дъжд (RA = rain) с малка интензивност (знак минус);
  • [BKN020CB] — значителна (BKN = broken), купесто-дъждовна (CB = cumulonimbus) облачност на 2000 фута (610 метра) над морското равнище.

С термините, означаващи метеорологични явления, има много, и е трудно да ги запомним. Кодът за заявка TAF се пише по аналогия.

Зареждаме кода в облака

За да не губим време, ще вземем шаблон на телеграм-бота от нашия репозиторий cloud-telegram-bot. Там има предварително подготвен requirements.txt и setup.py с правилна структура на директориите.

Тъй като в кода ще се обръщаме към модула pytaf, версията му трябва веднага да бъде добавена в requirements.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):
    # Извличане на информация от сървъра.
    code = request.urlopen(URL_METAR).read().decode('utf-8')
    # Изпращане на форматиран отговор.
    bot.send_message(message.chat.id, parse_data(code), reply_markup=keyboard)
 
def get_taf(message):
    # Извличане на информация от сървъра.
    code = request.urlopen(URL_TAF).read().decode('utf-8')
    # Изпращане на форматиран отговор.
    bot.send_message(message.chat.id, parse_data(code), reply_markup=keyboard)
 
def route_command(command, message):
    """
    Рутер на командите.
    """
    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):
    """
    Точка за влизане в безсървърната среда.
    """
    print(f'Получено: "{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'Ехото на "{message.text}"')
        route_command(message.text.lower(), message)

  • Опаковаме цялата директория в ZIP архив и преминаваме в панела за управление към създадената функция.
  • Натиснете Редактирайте и качете архива с кода.

Най-точната прогноза за времето: бот за Telegram на облачни функции

  • Попълнете относителния път до файла tele_bot (разширението .py може да не бъде посочено) и функцията на крайна точка (в посочения пример това е main).
  • В секцията Променливите на средата пишем променливата TOKEN и задаваме нейното значение на токена на необходимия телеграм-бот.
  • Натиснете Запазете и разгръщайте, след което преминаваме в раздела Тригери.
  • Поставяме превключвателя HTTP-запитване, за да направим запитването публично.

Най-точната прогноза за времето: бот за Telegram на облачни функции
Имаме URL за публично извикване на функцията. Остава само да настроим уебхука. Намерете нашия бот @SelectelServerless_bot в Telegram и регистрирайте своя бот с командата:

/setwebhook <you bot token> <public URL of your function>

Резултат

Ако всичко е направено правилно, вашият бот веднага ще започне да работи и ще показва актуален обзор на авиационната прогноза директно в мессенджъра.

Най-точната прогноза за времето: бот за Telegram на облачни функции
Разбира се, кода може да бъде доразвиван, но дори и в сегашното си състояние е достатъчен, за да получите най-точната прогноза за времето от проверен източник.

Пълната версия на кода ще намерите в нашия репозитория на GitHub.

Най-точната прогноза за времето: бот за Telegram на облачни функции

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster