Najdokładniejsza prognoza pogody: bot dla Telegramu na funkcjach chmurowych

Najdokładniejsza prognoza pogody: bot dla Telegramu na funkcjach chmurowych
Jest wiele serwisów dostarczających informacje o pogodzie, ale któremu z nich można zaufać? Gdy zacząłem często jeździć na rowerze, chciałem mieć najbardziej precyzyjne informacje o warunkach pogodowych w miejscu, w którym jeżdżę.

Pierwszą myślą było zbudowanie małej stacji pogodowej DIY z czujnikami i uzyskiwanie danych z niej. Ale nie chciałem „wynajdywać koła na nowo” i jako źródło sprawdzonych danych wybrałem informacje pogodowe używane w cywilnej aviacji, a mianowicie METAR (METeorological Aerodrome Report) i TAF (TAF — Terminal Aerodrome Forecast). W lotnictwie życie setek ludzi zależy od pogody, dlatego prognozy są maksymalnie precyzyjne.

Te informacje są w trybie ciągłym przekazywane głosem na każdym nowoczesnym lotnisku w formie ATIS (Automatic Terminal Information Service) i VOLMET (od franc. vol — lot i météo — pogoda). Pierwszy dostarcza informacje o rzeczywistej pogodzie na lotnisku, a drugi — prognozę na najbliższe 24-30 godzin, przy czym nie tylko na lotnisku nadającym, ale także na innych.

Przykład pracy ATIS w porcie lotniczym Wnukowo:

Przykład pracy VOLMET w porcie lotniczym Wnukowo

Niewygodnie jest za każdym razem nosić ze sobą skanery radiowe lub transiwery na odpowiednim paśmie, dlatego chciałem stworzyć bota w Telegramie, który na naciśnięcie przycisku pozwala uzyskać taką samą prognozę. Niecelowe jest wydzielanie do tego osobnego serwera, jak i kierowanie zapytań na domową Raspberry.

Dlatego jako backend postanowiłem użyć usługi Funkcje chmurowe Selectel. Liczba zapytań będzie znikoma, dlatego taka usługa praktycznie nic nie kosztuje (wg moich obliczeń wyniesie 22 rubli za 100 000 zapytań).

Przygotowanie backendu

Tworzenie funkcji

W panelu sterowania my.selectel.ru otwieramy widok Platforma chmurowa i tworzymy nowy projekt:

Najdokładniejsza prognoza pogody: bot dla Telegramu na funkcjach chmurowych
Po utworzeniu projektu przechodzimy do sekcji Funkcje:

Najdokładniejsza prognoza pogody: bot dla Telegramu na funkcjach chmurowych
Klikamy przycisk Utwórz funkcję i nadajemy jej odpowiednią nazwę:

Najdokładniejsza prognoza pogody: bot dla Telegramu na funkcjach chmurowych
Po naciśnięciu Utwórz funkcję pojawi się widok utworzonej funkcji:

Najdokładniejsza prognoza pogody: bot dla Telegramu na funkcjach chmurowych
Zanim przystąpimy do tworzenia kodu w Pythonie, należy stworzyć bota w Telegramie. Nie będę opisywał, jak się to robi — szczegółowa instrukcja jest w naszej bazie wiedzy. Najważniejsze dla nas — token utworzonego bota.

Przygotowujemy kod

Jako źródło wiarygodnych danych wybrałem Narodową Administrację Oceaniczną i Atmosferyczną USA (ang. National Oceanic and Atmospheric Administration, NOAA). Ta agencja naukowa aktualizuje dane na swoim serwerze w formacie TXT w czasie rzeczywistym.

Link do uzyskania danych METAR (zwróć uwagę na wielkość liter):

https://tgftp.nws.noaa.gov/data/observations/metar/stations/.TXT

W moim przypadku najbliższym lotniskiem jest Wnukowo, jego kod według ICAO to UUWW. Przejście na wygenerowany URL zwróci następujące:

2020/08/10 11:30
UUWW 101130Z 31004MPS 9999 SCT048 24/13 Q1014 R01/000070 NOSIG

Pierwszy wiersz to czas obowiązywania prognozy według Greenwich. Drugi wiersz to podsumowanie faktycznej pogody. Piloci cywilni bez problemu zrozumieją, co oznacza ten wiersz, ale potrzebujemy jego wyjaśnienia:

  • [UUWW] — Wnukowo, miasto Moskwa (Rosja — RU);
  • [101130Z] — 10. dzień miesiąca, godzina 11:30 według Greenwich;
  • [31004MPS] — kierunek wiatru 310 stopni, prędkość 4 m/s;
  • [9999] — widoczność pozioma 10 km i więcej;
  • [SCT048] — rozproszone chmury na wysokości 4800 stóp (~1584m);
  • [24/13] — temperatura 24°C, punkt rosy 13°C;
  • [Q1014] — ciśnienie (QNH) 1014 hektopaskali (750 mm rt. czt.);
  • [R01/000070] — współczynnik tarcia na pasie 01 to 0,70;
  • [NOSIG] — bez znaczących zmian.

Przechodzimy do pisania kodu. Najpierw trzeba zaimportować funkcje request i pytaf:

from urllib import request
import pytaf

Należy określić zmienne i przygotować funkcję dekodowania:

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()

Przechodzimy do TAF (wielkość liter jest również ważna).

https://tgftp.nws.noaa.gov/data/forecasts/taf/stations/.TXT

Jak w poprzednim przykładzie, przyjrzymy się prognozie w porcie lotniczym Wnukowo:

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

Szczególnie zwrócimy uwagę na wiersze TEMPO i BECMG. TEMPO oznacza, że faktyczna pogoda w podanym okresie będzie się okresowo zmieniać. BECMG — pogoda stopniowo zmieni się w podanym czasie.

Oznacza to, że wiersz:

TEMPO 1012/1020 -TSRA BKN020CB

Będzie oznaczać:

  • [1012/1020] — w okresie od 12 do 20 godzin (według Greenwich);
  • [-TSRA] — burza (TS = thunderstorm) z deszczem (RA = rain) o niewielkiej intensywności (znak minus);
  • [BKN020CB] — znaczne (BKN = broken), chmurowo-deszczowe (CB = cumulonimbus) zachmurzenie na wysokości 2000 stóp (610 metrów) nad poziomem morza.

Terminów oznaczających zjawiska pogodowe jest dość dużo i trudno jest je zapamiętać. Kod do zapytania TAF pisze się w podobny sposób.

Wgrywamy kod do chmury.

Aby nie tracić czasu, weźmy szablon bota telegramowego z naszego repozytorium. cloud-telegram-bot. Jest tam wstępnie przygotowany requirements.txt i setup.py z poprawną strukturą katalogów.

Ponieważ w kodzie będziemy odnosić się do modułu pytaf, jego wersję należy od razu dodać w requirements.txt

pytaf~=1.2.1

  • Przechodzimy do edytowania bot/tele_bot.py. Usuwamy wszystko zbędne i dopisujemy nasz kod.

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 = "Cześć. To bot do uzyskiwania prognozy pogody dla lotnictwa " 
          "z serwerów NOAA. Bot jest ustawiony na lotnisko Wnukowo (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):
    # Pobierz informacje z serwera.
    code = request.urlopen(URL_METAR).read().decode('utf-8')
    # Wyślij sformatowaną odpowiedź.
    bot.send_message(message.chat.id, parse_data(code), reply_markup=keyboard)
 
def get_taf(message):
    # Pobierz informacje z serwera.
    code = request.urlopen(URL_TAF).read().decode('utf-8')
    # Wyślij sformatowaną odpowiedź.
    bot.send_message(message.chat.id, parse_data(code), reply_markup=keyboard)
 
def route_command(command, message):
    """
    Router poleceń.
    """
    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):
    """
    Punkt wejścia do środowiska bezserwerowego.
    """
    print(f'Otrzymano: "{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 na "{message.text}"')
        route_command(message.text.lower(), message)

  • Pakujemy cały katalog w archiwum ZIP i przechodzimy do panelu sterowania do stworzonej funkcji.
  • Klikamy Edytować i ładujemy archiwum z kodem.

Najdokładniejsza prognoza pogody: bot dla Telegramu na funkcjach chmurowych

  • Wypełniamy względną ścieżkę do pliku tele_bot (rozszerzenie .py nie jest konieczne) i funkcję end-point (w podanym przykładzie jest to main).
  • W sekcji Zmienna środowiskowa piszemy zmienną TOKEN i przypisujemy jej token odpowiedniego bota telegramowego.
  • Klikamy Zapisz i uruchom, po czym przechodzimy do sekcji Wyzwalacze.
  • Ustawiamy przełącznik HTTP-Żądanie, aby uczynić zapytanie publicznym.

Najdokładniejsza prognoza pogody: bot dla Telegramu na funkcjach chmurowych
Mamy już adres URL do publicznego wywołania funkcji. Teraz wystarczy skonfigurować webhook. Znajdź naszego bota @SelectelServerless_bot na Telegramie i zarejestruj swojego bota komendą:

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

Wynik

Jeśli wszystko zostało zrobione poprawnie, twój bot od razu zacznie działać i wyświetlać aktualne podsumowanie prognozy pogody lotniczej bezpośrednio w komunikatorze.

Najdokładniejsza prognoza pogody: bot dla Telegramu na funkcjach chmurowych
Oczywiście, kod można rozwijać, jednak nawet w obecnym stanie jest wystarczający, aby uzyskać najdokładniejszą pogodę i prognozę z zaufanego źródła.

Pełną wersję kodu znajdziesz w naszym repozytorium na GitHubie.

Najdokładniejsza prognoza pogody: bot dla Telegramu na funkcjach chmurowych

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster