Самы дакладны прагноз надвор'я: бот для Telegram на хмарных функцыях

Самы дакладны прагноз надвор'я: бот для Telegram на хмарных функцыях
Сэрвісаў, якія прадстаўляюць інфармацыю аб надвор'і, дастаткова шмат, вось толькі якому з іх верыць? Калі я стаў часта ездзіць на ровары, мне захацелася валодаць найболей дакладнай інфармацыяй аб пагодных умовах у тым месцы, дзе я катаюся.

Першай думкай было сабраць невялікую DIY пагодную станцыю з датчыкамі і атрымліваць дадзеныя з яе. Але я не стаў «вынаходзіць ровар» і ў якасці крыніцы правераных дадзеных абраў пагодную інфармацыю, якая выкарыстоўваецца ў грамадзянскай авіяцыі, а менавіта МЕТРА (METeorological Aerodrome Report) і TAF (TAF – Terminal Aerodrome Forecast). У авіяцыі ад надвор'я залежаць жыцці соцень людзей, таму прагнозы максімальна дакладныя.

Гэтая інфармацыя ў кругласутачным рэжыме транслюецца голасам на кожным сучасным аэрадроме ў выглядзе АТІС (Automatic Terminal Information Service) і VOLMET (Ад франц. аб - палёт і метэа - надвор'е). Першы дае інфармацыю аб фактычным надвор'і на аэрадроме, а другі - прагноз на бліжэйшыя 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/<код аэропорта по 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 пішацца аналагічнай выявай.

Заліваем код у воблака

Каб не марнаваць дарма час, возьмем шаблон тэлеграм-бота з нашага рэпазітара cloud-telegram-bot. Там ёсць папярэдне падрыхтаваны патрабаванні.txt и setup.py з карэктнай структурай дырэкторый.

Паколькі ў кодзе мы будзем звяртацца да модуля 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-архіў і пераходзім у панэль кіравання да створанай функцыі.
  • Націскаем Рэдагаваць і загружаем архіў з кодам.

Самы дакладны прагноз надвор'я: бот для Telegram на хмарных функцыях

  • Запаўняем адносны шлях у файле tele_bot (пашырэнне .py можна не паказваць) і эндпойнт-функцыю (у прыведзеным прыкладзе гэта асноўнай).
  • У раздзеле Пераменныя асяроддзі пішам зменную TOKEN і прысвойваем ёй токен патрэбнага тэлеграм-бота.
  • Націскаем Захаваць і разгарнуць, пасля чаго пераходзім у раздзел трыгеры.
  • Ставім перамыкач HTTP-запыт, каб зрабіць запыт публічным.

Самы дакладны прагноз надвор'я: бот для Telegram на хмарных функцыях
У нас з'явіўся URL для публічнага выкліку функцыі. Засталося толькі наладзіць вебхук. Знайдзіце нашага бота @SelectelServerless_bot у Telegram і зарэгіструйце свайго бота камандай:

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

Вынік

Калі ўсё зроблена правільна, то ваш робат адразу пачне працаваць і адлюстроўваць актуальную зводку авіяцыйнага надвор'я прама ў мэсэнджэры.

Самы дакладны прагноз надвор'я: бот для Telegram на хмарных функцыях
Зразумела, код можна дапрацоўваць, аднак нават у бягучым стане яго дастаткова, каб даведацца самае дакладнае надвор'е і прагноз з праверанай крыніцы.

Поўную версію кода вы знойдзеце ў нашым рэпазітары на GitHub.

Самы дакладны прагноз надвор'я: бот для Telegram на хмарных функцыях

Крыніца: habr.com

Дадаць каментар