Skip to content

Commit

Permalink
Initial release based on DB4BIN's latest requirements. Includes:
Browse files Browse the repository at this point in the history
- bug fix to predict.habhub.org's parser (negative lat/lon was not detected)
- adds support for parsing radiosondy.info data
- improved output formatting
  • Loading branch information
joergschultzelutter committed May 28, 2021
1 parent 8d89ad0 commit c2a7f06
Show file tree
Hide file tree
Showing 4 changed files with 250 additions and 60 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
radiosonde.cfg
.idea
venv
33 changes: 31 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,35 @@
# radiosonde-telegram-bot
Radiosonde landing prediction Telegram bot

Scavenges multiple MPAD functions in order to provide an easier testing access for DB4BIN. "radiosonde_modules.py" is 100% identical with MPAD's source

TEST PURPOSES ONLY :-)
## Usage
Use the command ```/sonde [radiosonde]``` for running your prediction on a specific radiosonde. The bot will use the given radiosonde ID and run queries on the following web sites:

- predict.habhub.org
- radiosondy.info

Each site gets queried individually.

## Dependencies

### Python packages

- [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot)
- [activesoup](https://github.com/jelford/activesoup) required: version 0.2.3 or greater
- [beautifulsoup4](https://www.crummy.com/software/BeautifulSoup/)
- [geopy](https://github.com/geopy/geopy)
- [requests](https://github.com/psf/requests)
- [xmltodict](https://github.com/martinblech/xmltodict)

### Web sites

- predict.habhub.org
- radiosondy.info
- aprs.fi

### API access keys

- aprs.fi API access key
- your own telegram API access key

(both need to be stored in the ```radiosonde.cfg``` file)
209 changes: 186 additions & 23 deletions radiobot.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# Telegram Bot zum Testen der Radiosonde Landing Prediction für DB4BIN
# (jede Menge recycelter Code aus MPAD)
# "radiosonde_modules" ist dabei 1:1 austauschbar
#
# Ziel: besseres Testen für Ingo :-)
#!/opt/local/bin/python
#
# Telegram Bot "Radiosonde Landing Prediction"
# Uses "radiosonde_modules" from the MPAD project
# (file is 100% identical).
#
# This is mainly a web site scraper which uses predict.habhub.org
# and radiosondy.info as data sources
#
# Author: Joerg Schultze-Lutter, 2020
#
# This program is free software; you can redistribute it and/or modify
Expand All @@ -20,21 +24,23 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#

import requests
import json
import logging
from telegram.ext import Updater
from telegram.ext import CommandHandler
from telegram import ParseMode
from telegram.ext import MessageHandler, Filters
from utility_modules import read_program_config
from radiosonde_modules import get_radiosonde_landing_prediction
from radiosonde_modules import get_radiosonde_landing_prediction, get_radiosondy_data
from geopy_modules import get_reverse_geopy_data
import sys
import signal

logging.basicConfig(level=logging.INFO, format="%(asctime)s %(module)s -%(levelname)s- %(message)s")
logging.basicConfig(
level=logging.INFO, format="%(asctime)s %(module)s -%(levelname)s- %(message)s"
)
logger = logging.getLogger(__name__)


def signal_term_handler(signal_number, frame):
"""
Signal handler for SIGTERM signals. Ensures that the program
Expand All @@ -55,25 +61,184 @@ def signal_term_handler(signal_number, frame):
logger.info(msg="Received SIGTERM; forcing clean program exit")
sys.exit(0)


def start(update, context):
context.bot.send_message(chat_id=update.effective_chat.id, text="Ich bin ein Testbot für DB4BIN")
context.bot.send_message(
chat_id=update.effective_chat.id,
text="73 de DF1JSL's/DB4BIN's Telegram radiosonde landing prediction bot",
)
context.bot.send_message(
chat_id=update.effective_chat.id,
text="Use command <pre>/sonde [radiosonde-id]</pre> for requesting the landing prediction information",
parse_mode=ParseMode.HTML,
)
context.bot.send_message(
chat_id=update.effective_chat.id,
text="Source code & further info: https://www.github.com/joergschultzelutter/radiosonde-telegram-bot",
parse_mode=ParseMode.HTML,
disable_web_page_preview=True,
)


def sonde(update, context):
for sonde in context.args:
sonde = sonde.upper()
if len(sonde) > 0:
success, lat, lon, timestamp = get_radiosonde_landing_prediction(aprsfi_callsign=sonde,aprsdotfi_api_key=aprsdotfi_api_key)
found_something = False
# Run the query on habhub.org
context.bot.send_message(
chat_id=update.effective_chat.id,
text=f"<i>Querying position data for '{sonde}' on <pre>habhub.org</pre></i>",
parse_mode=ParseMode.HTML,
disable_web_page_preview=True,
)
(
success,
lat,
lon,
timestamp,
landing_url,
) = get_radiosonde_landing_prediction(
aprsfi_callsign=sonde, aprsdotfi_api_key=aprsdotfi_api_key
)
if success:
context.bot.send_message(chat_id=update.effective_chat.id, text=f"Landevorhersage: Latitude = {lat}, Longitude={lon}, Landezeit ={timestamp.strftime('%d-%b-%Y %H:%M:%S')} UTC")
context.bot.send_message(chat_id=update.effective_chat.id, text=f"https://maps.google.com/?q={lat},{lon}")
success, address = get_reverse_geopy_data(latitude=lat,longitude=lon,language="de")
if success:
context.bot.send_message(chat_id=update.effective_chat.id, text=address)
found_something = True
context.bot.send_message(
chat_id=update.effective_chat.id,
text=f"<b><u>Habhub information for <i>{sonde}</i></u></b>",
parse_mode=ParseMode.HTML,
)
context.bot.send_message(
chat_id=update.effective_chat.id,
text=f"<b>Landing prediction:</b> landing time ={timestamp.strftime('%d-%b-%Y %H:%M:%S')} UTC, latitude = {lat}, longitude={lon} <a href=\"https://maps.google.com/?q={lat},{lon}\">(Google Maps link)</a>",
parse_mode=ParseMode.HTML,
disable_web_page_preview=True,
)
success, address = get_reverse_geopy_data(latitude=lat, longitude=lon)
if success and address:
context.bot.send_message(
chat_id=update.effective_chat.id,
text=f"<b>Address:</b> {address}",
parse_mode=ParseMode.HTML,
)
else:
context.bot.send_message(chat_id=update.effective_chat.id, text=f"Sorry, nix gefunden zu '{sonde}'")
context.bot.send_message(
chat_id=update.effective_chat.id,
text=f"`<i>Habhub did not provide any data for '{sonde}'`</i>",
parse_mode=ParseMode.HTML,
)
# Run the query on radiosondy.info
context.bot.send_message(
chat_id=update.effective_chat.id,
text=f"<i>Querying position data for '{sonde}' on <pre>radiosondy.info</pre> - this might take a while</i>",
parse_mode=ParseMode.HTML,
disable_web_page_preview=True,
)
success, radiosondy_response_data = get_radiosondy_data(sonde_id=sonde)
if success:
found_something = True
context.bot.send_message(
chat_id=update.effective_chat.id,
text=f"<b><u>Radiosondy information for '{sonde}'</u></b>",
parse_mode=ParseMode.HTML,
)
launch_site = radiosondy_response_data["launch_site"]
if launch_site:
context.bot.send_message(
chat_id=update.effective_chat.id,
text=f"<b>Launch Site:</b> {launch_site}",
parse_mode=ParseMode.HTML,
)
probe_status = radiosondy_response_data["probe_status"]
if probe_status:
context.bot.send_message(
chat_id=update.effective_chat.id,
text=f"<b>Probe Status:</b> {probe_status}",
parse_mode=ParseMode.HTML,
)
landing_point_latitude = radiosondy_response_data[
"landing_point_latitude"
]
landing_point_longitude = radiosondy_response_data[
"landing_point_longitude"
]
if landing_point_latitude != 0.0 and landing_point_longitude != 0.0:
context.bot.send_message(
chat_id=update.effective_chat.id,
text=f'<b>Landing point:</b> Lat {landing_point_latitude} / Lon {landing_point_longitude} <a href="https://maps.google.com/?q={landing_point_latitude},{landing_point_longitude}">(Google Maps link)</a>',
parse_mode=ParseMode.HTML,
disable_web_page_preview=True,
)
success, address = get_reverse_geopy_data(
latitude=landing_point_latitude,
longitude=landing_point_longitude,
)
if success and address:
context.bot.send_message(
chat_id=update.effective_chat.id,
text=f"<b>Landing point address data:</b> {address}",
parse_mode=ParseMode.HTML,
)
else:
landing_point = radiosondy_response_data["landing_point"]
if landing_point:
context.bot.send_message(
chat_id=update.effective_chat.id,
text=f"<b>Landing Point raw coordinates:</b> {landing_point}",
parse_mode=ParseMode.HTML,
)
landing_description = radiosondy_response_data["landing_description"]
if landing_description:
context.bot.send_message(
chat_id=update.effective_chat.id,
text=f"<b>Landing description:</b> {landing_description}",
parse_mode=ParseMode.HTML,
)
latitude = radiosondy_response_data["latitude"]
longitude = radiosondy_response_data["longitude"]
if latitude and longitude:
context.bot.send_message(
chat_id=update.effective_chat.id,
text=f'<b>Last coordinates on <pre>aprs.fi</pre></b>: Lat {latitude} / Lon {longitude} <a href="https://maps.google.com/?q={latitude},{longitude}">(Google Maps link)</a>',
parse_mode=ParseMode.HTML,
disable_web_page_preview=True,
)
success, address = get_reverse_geopy_data(
latitude=latitude, longitude=longitude
)
if success and address:
context.bot.send_message(
chat_id=update.effective_chat.id,
text=f"<b><pre>aprs.fi</pre> address data:</b> {address}",
parse_mode=ParseMode.HTML,
)
else:
context.bot.send_message(
chat_id=update.effective_chat.id,
text=f"<i><pre>Radiosondy.info</pre> did not provide any data for '{sonde}'</i>",
parse_mode=ParseMode.HTML,
)
if not found_something:
context.bot.send_message(
chat_id=update.effective_chat.id,
text=f"Didn't find anything on radiosonde '{sonde}'",
)


def unknown(update, context):
context.bot.send_message(chat_id=update.effective_chat.id, text="Nuschel nicht so. Ich verstehe Dich nicht")
context.bot.send_message(chat_id=update.effective_chat.id, text="Unknown command.")
context.bot.send_message(
chat_id=update.effective_chat.id,
text="Use command <pre>/sonde [radiosonde-id]</pre> for requesting the landing prediction information",
parse_mode=ParseMode.HTML,
)
context.bot.send_message(
chat_id=update.effective_chat.id,
text="Source code & further info: https://www.github.com/joergschultzelutter/radiosonde-telegram-bot",
parse_mode=ParseMode.HTML,
disable_web_page_preview=True,
)


if __name__ == "__main__":
success, aprsdotfi_api_key, telegram_token = read_program_config()
Expand All @@ -88,10 +253,10 @@ def unknown(update, context):
updater = Updater(token=telegram_token, use_context=True)
dispatcher = updater.dispatcher

start_handler = CommandHandler('start', start)
start_handler = CommandHandler("start", start)
dispatcher.add_handler(start_handler)

sonde_handler = CommandHandler('sonde', sonde)
sonde_handler = CommandHandler("sonde", sonde)
dispatcher.add_handler(sonde_handler)

# must be last handler prior to polling start
Expand All @@ -105,6 +270,4 @@ def unknown(update, context):
msg="KeyboardInterrupt or SystemExit in progress; shutting down ..."
)
updater.stop()
logger.info(
msg="Have terminated the updater"
)
logger.info(msg="Have terminated the updater")
Loading

0 comments on commit c2a7f06

Please sign in to comment.