最准确的天气预报:云功能上的 Telegram 机器人

最准确的天气预报:云功能上的 Telegram 机器人
提供天气信息的服务有很多,但您应该信任哪一个呢? 当我开始经常骑自行车时,我想获得有关我骑行地点的天气状况的最准确信息。

我的第一个想法是建造一个带有传感器的小型 DIY 气象站并从中接收数据。 但我并没有“白费力气”,而是选择了民航使用的天气信息作为验证数据的来源,即 METAR (机场气象报告)和 TAF (TAF - 航站楼机场预报)。 在航空业,数百人的生命取决于天气,因此预报尽可能准确。

该信息在每个现代机场以以下形式 XNUMX/XNUMX 通过语音广播: 信息系统 (自动终端信息服务)和 伏尔梅特 (来自法语。 第一卷 - 飞行和 天气 - 天气)。 第一个提供有关机场实际天气的信息,第二个提供未来 24-30 小时的天气预报,不仅在广播机场,而且在其他机场。

ATIS 在伏努科沃机场的操作示例:

VOLMET 在伏努科沃机场工作的示例

每次在相应的范围内携带无线电扫描仪或收发器很不方便,我想在 Telegram 中创建一个机器人,只需单击一个按钮,您就可以获得相同的预测。 为此分配一个单独的服务器以及向您的家庭 Raspberry 发送请求至少是不切实际的。

因此,我决定使用该服务作为后端 Selectel 云功能。 请求的数量可以忽略不计,因此这样的服务实际上是免费的(根据我的计算,22 个请求将需要 100 卢布)。

后端准备

创建函数

在控制面板中 my.selectel.ru 打开视图 云平台 并创建一个新项目:

最准确的天气预报:云功能上的 Telegram 机器人
项目创建完成后,进入 功能:

最准确的天气预报:云功能上的 Telegram 机器人
按下按钮 创建函数 并为其指定所需的名称:

最准确的天气预报:云功能上的 Telegram 机器人
按下后 创建函数 我们将得到所创建函数的表示:

最准确的天气预报:云功能上的 Telegram 机器人
在开始使用 Python 创建代码之前,您需要在 Telegram 中创建一个机器人。 我不会描述这是如何完成的 - 有详细的说明 在我们的知识库中。 对我们来说最重要的是创建的机器人的令牌。

准备代码

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

获取METAR数据的链接(注意大小写):

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

就我而言,最近的机场是伏努科沃,其 ICAO 代码是 联合会。 转到生成的 URL 将显示以下内容:

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

第一行是格林威治标准时间预报的当前时间。 第二行是对实际天气的总结。 民航飞行员很容易理解这条线的含义,但我们需要一个解释:

  • [UUWW] — 伏努科沃,莫斯科(俄罗斯 — RU);
  • [101130Z] — 每月 10 日,上午 11:30 GMT;
  • [31004MPS] ——风向310度,风速4m/s;
  • [9999] ——水平能见度10公里或以上;
  • [SCT048] — 4800 英尺(~1584m)处的分散云;
  • [24 / 13] — 温度24°C,露点13°C;
  • [问题一] — 压力 (QNH) 1014 百帕斯卡 (750 毫米汞柱);
  • [R01/000070] — 车道 01 上的附着系数 — 0,70;
  • [诺西格] - 没有重大变化。

让我们开始编写程序代码。 首先需要导入函数 请求 и 皮塔夫:

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

让我们特别注意线条 TIME и 脑电图。 TEMPO 是指指定时间段内的实际天气会周期性变化。 BECMG - 天气将在指定的时间内逐渐变化。

也就是说,该行:

TEMPO 1012/1020 -TSRA BKN020CB

将意味着:

  • [1012 / 1020] — 12 至 20 小时(格林威治标准时间);
  • [-TSRA] — 雷暴(TS = 雷暴),伴有低强度降雨(RA = 降雨)(负号);
  • [BKN020CB] - 海拔 2000 英尺(610 米)处的显着(BKN = 破碎)积雨云(CB = 积雨云)。

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

上传代码到云端

为了不浪费时间,让我们从我们的存储库中获取一个电报机器人模板 云电报机器人。 有一个预先准备好的 requirements.txt и 设置文件 具有正确的目录结构。

因为在代码中我们将访问该模块 皮塔夫,那么它的版本应该立即添加到 requirements.txt

pytaf~=1.2.1

  • 让我们继续编辑 机器人/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 机器人

  • 填写文件中的相对路径 远程机器人 (扩大 的.py 可能未指定)和端点函数(在给出的示例中是 ).
  • 在第 环境变量 写一个变量 TOKEN 并为其分配所需电报机器人的令牌。
  • 点击这里 保存并展开,之后我们进入该部分 触发器.
  • 我们把开关 HTTP请求公开该请求。

最准确的天气预报:云功能上的 Telegram 机器人
现在我们有了一个用于公开调用该函数的 URL。 剩下的就是 配置网络钩子。 找到我们的机器人 @SelectelServerless_bot 在 Telegram 中并使用以下命令注册您的机器人:

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

导致

如果一切都正确完成,您的机器人将立即开始工作并直接在消息中显示最新的航空天气预报。

最准确的天气预报:云功能上的 Telegram 机器人
当然,代码可以改进,但即使在当前状态下,也足以从可信来源找到最准确的天气和预报。

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

最准确的天气预报:云功能上的 Telegram 机器人

来源: habr.com

添加评论