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



There are a lot of services providing weather information, but which one to believe? When I started cycling a lot, I wanted to have the most accurate information about the weather conditions in the place where I ride.



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



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



An example of ATIS at Vnukovo airport:




Example of VOLMET at Vnukovo airport




It is inconvenient to carry a radio scanner or transceiver with me to the corresponding range every time, and I wanted to create a bot in Telegram, which, by pressing a button, allows me to get the same forecast. Allocating a separate server for this is at least impractical, as well as driving requests to the home Raspberry.



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



Backend preparation



Function creation



In the my.selectel.ru control panel, open the Cloud Platform view and create a new project:





After the project is created, go to the Functions section :





Click the Create function button and give it the desired name:





After clicking Create function , we will have a view of the created function:





Before you start creating Python code, you need to create a bot in Telegram. I will not describe how this is done - detailed instructions are available in our knowledge base . The main thing for us is the token of the created bot.



Cooking the code



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



Link for getting METAR data (note the case):



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


In my case, the closest airport is Vnukovo, its ICAO code is UUWW . Going to the generated URL will give the following:



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


The first line is the time when the forecast is up-to-date by Greenwich Mean Time. The second line is a summary of the actual weather. Civil aviation pilots will easily understand what this line means, but we need a decryption:



  • [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 10 km or more;
  • [SCT048] - scattered / scattered clouds at an altitude of 4800 feet (~ 1584m);
  • [24/13] - temperature 24 ° C, dew point 13 ° C;
  • [Q1014] - pressure (QNH) 1014 hectopascals (750 mm Hg);
  • [R01 / 000070] - coefficient of adhesion on lane 01 - 0.70;
  • [NOSIG] - no significant changes.


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



from urllib import request
import pytaf


Specify variables and prepare 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 (register 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 particular attention to the TEMPO and BECMG lines . TEMPO means that the actual weather during the specified period will periodically change. BECMG - the weather will gradually change during the specified period of time.



That is, the line:



TEMPO 1012/1020 -TSRA BKN020CB


Will mean:



  • [1012/1020] - between 12:00 and 20:00 (GMT);
  • [-TSRA] - thunderstorm (TS = thunderstorm) with rain (RA = rain) of low intensity (minus sign);
  • [BKN020CB] Significant (BKN = broken) cumulonimbus (CB = cumulonimbus) clouds at 2000 feet (610 meters) above sea level.


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



Uploading the code to the cloud



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



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



pytaf~=1.2.1


  • Let's go 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)


  • Pack the entire directory into a ZIP archive and go to the control panel to the created function.
  • .




  • tele_bot ( .py ) - ( main).
  • TOKEN -.
  • , .
  • HTTP-, .




We now have a URL for a public function call. It remains only to configure the webhook . Find our bot @SelectelServerless_bot in Telegram and register your bot with the command:



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


Result



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





Of course, the code can be modified, 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 repository on GitHub .






All Articles