The most accurate weather forecast: a bot for Telegram on cloud functions

The most accurate weather forecast: a bot for Telegram on cloud functions
There are a lot of services that provide information about the weather, but which one to trust? When I began to ride a bike often, I wanted to have the most accurate information about the weather conditions in the place where I ride.

My first thought was to assemble a small DIY weather station with sensors and receive data from it. But I did not “reinvent the wheel” and chose weather information that is used in civil aviation as a source of verified data, namely METAR (METeorological Aerodrome Report) and TAF (TAF - Terminal Aerodrome Forecast). In aviation, the lives of hundreds of people depend on the weather, so the forecasts are as accurate as possible.

This information is broadcast around the clock by voice at every modern airfield in the form ATIS (Automatic Terminal Information Service) and VOLMET (from the French vol - flight and weather forecasts - weather). The first provides information about the actual weather at the airfield, and the second - the forecast for the next 24-30 hours, not only at the broadcast airfield, but also at others.

An example of the operation of ATIS at Vnukovo Airport:

An example of VOLMET operation at Vnukovo Airport

Each time it is inconvenient to carry a radio scanner or transceiver with you to the appropriate range, and I wanted to create a bot in Telegram, which, at the touch of a button, allows you to get the same forecast. Dedicating a separate server for this is at least inexpedient, as well as sending requests to the home Raspberry.

Therefore, as a backend, I decided to use the service Selectel Cloud Functions. The number of requests will be negligible, so such a service will actually cost free (according to my calculations, it will be 22 rubles for 100 requests).

Preparing the backend

Create a function

In the control panel my.selectel.com open view Cloud platform and create a new project:

The most accurate weather forecast: a bot for Telegram on cloud functions
After the project is created, go to the section Functions:

The most accurate weather forecast: a bot for Telegram on cloud functions
Push the button Create a function and give it the desired name:

The most accurate weather forecast: a bot for Telegram on cloud functions
After clicking Create a function we will have a representation of the created function:

The most accurate weather forecast: a bot for Telegram on cloud functions
Before you start creating Python code, you need to create a bot in Telegram. I won’t describe how this is done - there are detailed instructions in our knowledge base. The main thing for us is the token of the created bot.

Cooking code

I chose the National Oceanic and Atmospheric Administration (NOAA) as a source of reliable data. This scientific agency updates data in real time on its server in TXT format.

Link to get METAR data (note the register):

https://tgftp.nws.noaa.gov/data/observations/metar/stations/<код аэропорта по ICAO>.TXT

In my case, the nearest airport is Vnukovo, its ICAO code is UUWW. Navigating to the generated URL will produce the following:

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

The first line is the GMT time of relevance of the forecast. The second line is a summary of the actual weather. Civil aviation pilots will have no problem understanding what this line means, but we need a transcript:

  • [UUWW] — Vnukovo, Moscow (Russia — RU);
  • [101130Z] — 10th day of the month, 11:30 GMT;
  • [31004MPS] — wind direction 310 degrees, speed 4 m/s;
  • [9999] — horizontal visibility of 10 km or more;
  • [SCT048] — scattered/scattered clouds at 4800 feet (~1584m);
  • [24/13] — temperature 24°C, dew point 13°C;
  • [Q1014] - pressure (QNH) 1014 hectopascals (750 mm Hg);
  • [R01/000070] — adhesion coefficient on the lane 01 — 0,70;
  • [NOSIG] - without significant changes.

Let's start writing code. First you need to import the functions request и pytaf:

from urllib import request
import pytaf

Specify variables and prepare the decoding function:

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

Let's move on to TAF (case is also important).

https://tgftp.nws.noaa.gov/data/forecasts/taf/stations/<код аэропорта по ICAO>.TXT

As in the previous example, let's see the forecast at Vnukovo airport:

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

Pay special attention to the lines TIME и BECMG. TEMPO means that the actual weather in the specified period will change periodically. BECMG - the weather will gradually change over the specified time interval.

That is the line:

TEMPO 1012/1020 -TSRA BKN020CB

Will mean:

  • [1012/1020] - in the period from 12 to 20 hours (Greenwich Mean Time);
  • [-TSRA] — thunderstorm (TS = thunderstorm) with rain (RA = rain) of low intensity (minus sign);
  • [BKN020CB] - significant (BKN = broken), cumulonimbus (CB = cumulonimbus) cloud cover at an altitude of 2000 feet (610 meters) above sea level.

There are a lot of terms that mean weather phenomena, and it is difficult to remember them. The code for a TAF request is written in a similar way.

Upload code to the cloud

In order not to waste time, let's take a telegram bot template from our repository cloud-telegram-bot. There is a pre-prepared requirements.txt и setup.py with the correct directory structure.

Since in the code we will refer to the module pytaf, then its version should immediately be added to requirements.txt

pytaf~=1.2.1

  • Let's move on to editing bot/tele_bot.py. We remove all unnecessary and add our code.

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)

  • We pack the entire directory into a ZIP archive and go to the control panel to the created function.
  • Click here Edit and download the archive with the code.

The most accurate weather forecast: a bot for Telegram on cloud functions

  • Fill in the relative path in the file tele_bot (extension py can be omitted) and an endpoint function (in the above example, this main).
  • In section Environment variables write a variable TOKEN and assign it the token of the desired telegram bot.
  • Click here Save and Expand, then go to the section Triggers.
  • We put the switch HTTP requestto make the request public.

The most accurate weather forecast: a bot for Telegram on cloud functions
We have a URL for a public function call. All that's left is set up a webhook. Find our bot @SelectelServerless_bot in Telegram and register your bot with the command:

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

Experience the Power of Effective Results

If everything is done correctly, then your bot will immediately start working and display the current aviation weather report directly in the messenger.

The most accurate weather forecast: a bot for Telegram on cloud functions
Of course, the code can be improved, but even in its current state it is enough to find out the most accurate weather and forecast from a trusted source.

You can find the full version of the code in our repositories on GitHub.

The most accurate weather forecast: a bot for Telegram on cloud functions

Source: habr.com

Add a comment