有很多提供天气信息的服务,但是哪一个值得相信?当我开始大量骑自行车时,我想获得有关所乘地区天气状况的最准确信息。
首先想到的是建立一个带有传感器的小型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] -没有重大变化。
让我们开始编写程序代码。首先,您需要导入request和pytaf函数:
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
请 特别注意TEMPO和BECMG系列。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.txt和setup.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的存储库中找到完整的代码版本。