最准确的天气预报:云端电报的自动程序



有很多提供天气信息的服务,但是哪一个值得相信?当我开始大量骑自行车时,我想获得有关所乘地区天气状况的最准确信息。



首先想到的是建立一个带有传感器的小型DIY气象站,并从中接收数据。但是我并没有重新发明轮子,而是选择了民航中使用的气象信息,即METAR(气象机场报告)和TAF(TAF-终端机场预报)作为验证数据的来源。在航空领域,数百人的生活取决于天气,因此预报尽可能准确。



该信息在每一个现代化机场的形式围绕语音时钟广播ATIS(自动终端信息服务)和VOLMET(法国第一卷-飞行和气象局-天气)。第一个提供有关机场实际天气的信息,第二个提供对未来24-30小时的预报,不仅包括广播机场,还包括其他时间。



伏努科沃机场的ATIS示例:




伏努科沃机场VOLMET的示例




每次都随身携带无线电扫描仪或收发器到相应范围是很不方便的,我想在Telegram中创建一个机器人,通过按一个按钮,可以使我得到相同的预测。为此分配一个单独的服务器至少是不切实际的,并且无法将请求驱动到家用Raspberry。



因此,我决定将Selectel Cloud Functions服务用作后端请求的数量可以忽略不计,因此该服务实际上是免费的(根据我的计算,每100,000个请求为22卢布)。



后端准备



功能创造



my.selectel.ru控制面板中,打开Cloud Platform视图并创建一个新项目:





创建项目后,转到“功能”部分





单击创建功能按钮,然后为其指定所需的名称:





点击Create function之后,我们将看到已创建函数的视图:





在开始创建Python代码之前,您需要在Telegram中创建一个机器人。我不会描述如何完成-详细说明可在我们的知识库中找到对我们来说,最主要的是创建的机器人的令牌。



编写代码



我选择了美国国家海洋和大气管理局(NOAA)作为可靠数据的来源。该科学机构以TXT格式实时更新其服务器上的数据。



获取METAR数据的链接(请注意情况):



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


就我而言,最近的机场是伏努科沃,其国际民航组织代码是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 m / s;
  • [9999] -水平能见度10公里或以上;
  • [SCT048] -海拔4800英尺(〜1584m)的零散/零散云;
  • [24/13] -温度24°C,露点13°C;
  • [Q1014] -压力(QNH)1014百帕斯卡(750毫米汞柱);
  • [R01 / 000070] -车道01上的附着系数-0.70
  • [NOSIG] -没有重大变化。


让我们开始编写程序代码。首先,您需要导入requestpytaf函数



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


特别注意TEMPOBECMG系列TEMPO表示指定期间的实际天气将定期更改。BECMG-天气将在指定的时间段内逐渐变化。



也就是说,该行:



TEMPO 1012/1020 -TSRA BKN020CB


表示:



  • [1012/1020]-12:00至20:00(GMT)之间;
  • [-TSRA] -低强度(负号)雨(RA =雨)的雷暴(TS =雷暴);
  • [BKN020CB]海拔2000英尺(610米)处的积雨云(BKN =破碎)(CB =积雨云)。


天气现象有很多术语,很难记住。TAF请求的代码以类似的方式编写。



将代码上传到云



为了不浪费时间,我们从cloud-telegram-bot存储库中获取一个电报bot模板已经预先准备好了具有正确目录结构的requirements.txtsetup.py



由于在代码中我们将引用pytaf模块,因此应立即将其版本添加到requirements.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存档中,然后转到控制面板中的所创建函数。
  • .




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




现在,我们有一个用于公共功能调用的URL。仅保留配置webhook在Telegram中找到我们的机器人@SelectelServerless_bot并使用以下命令注册您的机器人:



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


结果



如果一切正确完成,您的机器人将立即开始工作,并在Messenger上显示当前的航空天气报告。





当然,可以对代码进行修改,但是即使在当前状态下,也可以从受信任的来源中找到最准确的天气和天气预报。



您可以在GitHub存储库中找到完整的代码版本






All Articles