Найточніший прогноз погоди: бот для Telegram на хмарних функціях.

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

Першою думкою було зібрати невелику DIY погодну станцію з датчиками та отримувати дані з неї. Але я не став «винаходити велосипед» і як джерело перевірених даних вибрав погодну інформацію, яка використовується в цивільній авіації, а саме METAR (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

Особливо звернемо увагу на рядки TEMPO и 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 можна не вказувати) та ендпойнт-функцію (у наведеному прикладі це основний).
  • У розділі Змінні оточення пишемо змінну ТОКЕН і привласнюємо їй токен потрібного телеграм-бота.
  • натискаємо Зберегти та розгорнути, після чого переходимо до розділу Тригери.
  • Ставимо перемикач HTTP-запит, щоб зробити запит публічним.

Найточніший прогноз погоди: бот для Telegram на хмарних функціях.
У нас з'явилася URL-адреса для публічного виклику функції. Залишилось лише налаштувати вебхук. Знайдіть нашого бота @SelectelServerless_bot у Telegram та зареєструйте свого бота командою:

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

Результат

Якщо все зроблено правильно, то ваш бот відразу почне працювати і відображати актуальне зведення авіаційної погоди прямо в месенджері.

Найточніший прогноз погоди: бот для Telegram на хмарних функціях.
Зрозуміло, код можна доопрацьовувати, проте навіть у поточному стані його достатньо, щоб дізнатися найточнішу погоду та прогноз із перевіреного джерела.

Повну версію коду ви знайдете в нашому репозиторії на GitHub.

Найточніший прогноз погоди: бот для Telegram на хмарних функціях.

Джерело: habr.com

Додати коментар або відгук