
Hay muchos servicios que proporcionan información sobre el clima, pero, ¿a cuál de ellos debemos creer? Cuando empecé a andar en bicicleta con frecuencia, quise tener la información más precisa sobre las condiciones climáticas en el lugar donde monto.
La primera idea fue construir una pequeña estación meteorológica DIY con sensores y obtener datos de ella. Pero no quise 'reinventar la rueda' y, como fuente de datos verificados, elegí la información meteorológica utilizada en la aviación civil, específicamente METAR (Informe Meteorológico de Aeródromo) y TAF (Pronóstico de Aeródromo Terminal). En aviación, el clima afecta la vida de cientos de personas, por lo que las previsiones son extremadamente precisas.
Esta información se transmite las 24 horas del día, en voz, en todos los aeródromos modernos en forma de ATIS (Servicio Automático de Información de Terminal) y VOLMET (del francés vol — vuelo y météo — clima). El primero proporciona información sobre el clima actual en el aeródromo, mientras que el segundo ofrece pronósticos para las próximas 24-30 horas, no solo para el aeródromo de transmisión, sino también para otros.
Ejemplo de funcionamiento de ATIS del aeropuerto de Vnukovo:
Ejemplo de funcionamiento de VOLMET del aeropuerto de Vnukovo
No es conveniente llevar siempre un escáner de radio o un transceptor en la banda correspondiente, y quise crear un bot en Telegram que permita obtener ese pronóstico al presionar un botón. No tiene sentido dedicar un servidor solo para esto, al igual que enviar solicitudes a un Raspberry Pi en casa.
Por lo tanto, decidí utilizar el servicio . La cantidad de solicitudes será prácticamente mínima, por lo que este servicio será prácticamente gratis (según mis cálculos, costará 22 rublos por 100,000 solicitudes).
Preparación del backend
Creación de la función
En el panel de control abrimos la vista Plataforma en la nube y creamos un nuevo proyecto:

Después de crear el proyecto, vamos a la sección Funciones:

Hacemos clic en el botón Crear función y le asignamos el nombre necesario:

Tras hacer clic en Crear función tendremos la vista de la función creada:

Antes de comenzar a escribir el código en Python, será necesario crear un bot en Telegram. No detallaré cómo hacerlo, ya que hay instrucciones detalladas disponibles . Lo principal para nosotros es el token del bot creado.
Preparar el código
Como fuente de datos confiables elegí la Administración Nacional Oceánica y Atmosférica de EE. UU. (en inglés National Oceanic and Atmospheric Administration, NOAA). Esta agencia científica actualiza en tiempo real los datos en su servidor en formato TXT.
Enlace para obtener datos METAR (presta atención a las mayúsculas):
https://tgftp.nws.noaa.gov/data/observations/metar/stations/.TXTEn mi caso, el aeropuerto más cercano es Vnúkovo, su código por ICAO es UUWW. Acceder a la URL generada dará como resultado lo siguiente:
2020/08/10 11:30
UUWW 101130Z 31004MPS 9999 SCT048 24/13 Q1014 R01/000070 NOSIG
La primera línea es el tiempo de vigencia de la predicción en horario de Greenwich. La segunda línea es un resumen del clima actual. Los pilotos de aviación civil entenderán perfectamente el significado de esta línea, sin embargo, necesitamos una explicación:
- [UUWW] — Vnúkovo, ciudad de Moscú (Rusia — RU);
- [101130Z] — día 10 del mes, 11 horas y 30 minutos en horario de Greenwich;
- [31004MPS] — dirección del viento 310 grados, velocidad 4 m/s;
- [9999] — visibilidad horizontal de 10 km o más;
- [SCT048] — nubes dispersas/fragmentadas a una altura de 4800 pies (~1584m);
- [24/13] — temperatura 24°C, punto de rocío 13°C;
- [Q1014] — presión (QNH) 1014 hectopascales (750 mmHg);
- [R01/000070] — coeficiente de fricción en la pista 01 — 0,70;
- [NOSIG] — sin cambios significativos.
Comencemos a escribir el código. Primero será necesario importar las funciones request y pytaf:
from urllib import request
import pytafDefinir variables y preparar la función de decodificación:
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()Pasemos al TAF (la mayúscula también es importante).
https://tgftp.nws.noaa.gov/data/forecasts/taf/stations/.TXTComo en el ejemplo anterior, veamos la predicción en el aeropuerto de Vnúkovo:
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
Prestar especial atención a las líneas TEMPO y BECMG. TEMPO significa que el clima real cambiará periódicamente durante el intervalo indicado. BECMG significa que el clima cambiará gradualmente durante el tiempo indicado.
Es decir, la línea:
TEMPO 1012/1020 -TSRA BKN020CBSignificará:
- [1012/1020] — en el intervalo de 12 a 20 horas (en horario de Greenwich);
- [-TSRA] — tormenta (TS = thunderstorm) con lluvia (RA = rain) de baja intensidad (el signo menos);
- [BKN020CB] — significativa (BKN = broken), nubosidad cúmulo-nimbos (CB = cumulonimbus) a una altura de 2000 pies (610 metros) sobre el nivel del mar.
Existen muchos términos que significan fenómenos meteorológicos, y es difícil recordarlos. El código para solicitar TAF se escribe de manera similar.
Subimos el código a la nube
Para no perder tiempo, tomemos una plantilla de bot de Telegram de nuestro repositorio . Ahí hay una estructura de directorios ya preparada. requirements.txt y setup.py с корректной структурой директорий.
Dado que en el código nos referiremos al módulo pytaf, su versión debe incluirse de inmediato en requirements.txt
pytaf~=1.2.1- Procedamos a editar bot/tele_bot.py. Eliminamos todo lo innecesario y agregamos nuestro código.
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 = "Hola. Este es un bot para obtener pronósticos meteorológicos para aviación "
"de los servidores de NOAA. El bot está configurado para el aeropuerto Vnukovo (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):
# Obtener información del servidor.
code = request.urlopen(URL_METAR).read().decode('utf-8')
# Enviar respuesta formateada.
bot.send_message(message.chat.id, parse_data(code), reply_markup=keyboard)
def get_taf(message):
# Obtener información del servidor.
code = request.urlopen(URL_TAF).read().decode('utf-8')
# Enviar respuesta formateada.
bot.send_message(message.chat.id, parse_data(code), reply_markup=keyboard)
def route_command(command, message):
"""
Enrutador de comandos.
"""
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):
"""
Punto de entrada del entorno sin servidor.
"""
print(f'Recibido: "{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'Eco en "{message.text}"')
route_command(message.text.lower(), message)
- Comprimimos todo el directorio en un archivo ZIP y vamos al panel de control para la función creada.
- Hacemos clic en Editar y subimos el archivo comprimido con el código.

- Llenamos la ruta relativa del archivo tele_bot (la extensión .py no es necesario especificarla) y el endpoint de función (en el ejemplo dado es main).
- En la sección Variables de entorno escribimos la variable TOKEN y le asignamos el token del bot de Telegram necesario.
- Hacemos clic en Guardar y desplegar, luego pasamos a la sección Desencadenadores.
- Activamos el conmutador Solicitud HTTP, para hacer la solicitud pública.

Ahora tenemos una URL para la llamada pública de la función. Solo queda . Encuentra nuestro bot en Telegram y registra tu bot con el comando:
/setwebhook <you bot token> <public URL of your function>Resultado
Si todo se ha hecho correctamente, tu bot comenzará a funcionar de inmediato y mostrará el resumen actual del clima aéreo directamente en el mensajero.

Por supuesto, se puede mejorar el código, sin embargo, incluso en su estado actual es suficiente para obtener el clima más preciso y el pronóstico de una fuente confiable.
Encontrarás la versión completa del código en nuestro .
Fuente: habr.com
