From fefb626c9744952a91fcb3b02640d9dbd228df6b Mon Sep 17 00:00:00 2001 From: Hemna Date: Wed, 20 Jan 2021 19:51:59 -0500 Subject: [PATCH] Fixed extracting lat/lon This patch fixes an issue when aprs.fi returns a non error, but doesn't have any real entries as the response --- aprsd/plugins/location.py | 86 +++++++++++++++++++-------------------- aprsd/plugins/weather.py | 74 +++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 43 deletions(-) diff --git a/aprsd/plugins/location.py b/aprsd/plugins/location.py index 60a5c19..d8bd5d7 100644 --- a/aprsd/plugins/location.py +++ b/aprsd/plugins/location.py @@ -24,53 +24,53 @@ class LocationPlugin(plugin.APRSDPluginBase): return "No aprs.fi apikey found" api_key = self.config["aprs.fi"]["apiKey"] + # optional second argument is a callsign to search + a = re.search(r"^.*\s+(.*)", message) + if a is not None: + searchcall = a.group(1) + searchcall = searchcall.upper() + else: + # if no second argument, search for calling station + searchcall = fromcall + try: - # optional second argument is a callsign to search - a = re.search(r"^.*\s+(.*)", message) - if a is not None: - searchcall = a.group(1) - searchcall = searchcall.upper() - else: - # if no second argument, search for calling station - searchcall = fromcall + aprs_data = plugin_utils.get_aprs_fi(api_key, searchcall) + except Exception as ex: + LOG.error("Failed to fetch aprs.fi '{}'".format(ex)) + return "Failed to fetch aprs.fi location" - try: - aprs_data = plugin_utils.get_aprs_fi(api_key, searchcall) - except Exception as ex: - LOG.error("Failed to fetch aprs.fi '{}'".format(ex)) - return "Failed to fetch aprs.fi location" + LOG.debug("LocationPlugin: aprs_data = {}".format(aprs_data)) + if not len(aprs_data["entries"]): + LOG.error("Didn't get any entries from aprs.fi") + return "Failed to fetch aprs.fi location" - LOG.debug("LocationPlugin: aprs_data = {}".format(aprs_data)) - lat = aprs_data["entries"][0]["lat"] - lon = aprs_data["entries"][0]["lng"] - try: # altitude not always provided - alt = aprs_data["entries"][0]["altitude"] - except Exception: - alt = 0 - altfeet = int(alt * 3.28084) - aprs_lasttime_seconds = aprs_data["entries"][0]["lasttime"] - # aprs_lasttime_seconds = aprs_lasttime_seconds.encode( - # "ascii", errors="ignore" - # ) # unicode to ascii - delta_seconds = time.time() - int(aprs_lasttime_seconds) - delta_hours = delta_seconds / 60 / 60 + lat = aprs_data["entries"][0]["lat"] + lon = aprs_data["entries"][0]["lng"] + try: # altitude not always provided + alt = aprs_data["entries"][0]["altitude"] + except Exception: + alt = 0 + altfeet = int(alt * 3.28084) + aprs_lasttime_seconds = aprs_data["entries"][0]["lasttime"] + # aprs_lasttime_seconds = aprs_lasttime_seconds.encode( + # "ascii", errors="ignore" + # ) # unicode to ascii + delta_seconds = time.time() - int(aprs_lasttime_seconds) + delta_hours = delta_seconds / 60 / 60 - try: - wx_data = plugin_utils.get_weather_gov_for_gps(lat, lon) - except Exception as ex: - LOG.error("Couldn't fetch forecast.weather.gov '{}'".format(ex)) - wx_data["location"]["areaDescription"] = "Unkown Location" + try: + wx_data = plugin_utils.get_weather_gov_for_gps(lat, lon) + except Exception as ex: + LOG.error("Couldn't fetch forecast.weather.gov '{}'".format(ex)) + wx_data = {"location": {"areaDescription": "Unknown Location"}} - reply = "{}: {} {}' {},{} {}h ago".format( - searchcall, - wx_data["location"]["areaDescription"], - str(altfeet), - str(lat), - str(lon), - str("%.1f" % round(delta_hours, 1)), - ).rstrip() - except Exception as e: - LOG.debug("Locate failed with: " + "%s" % str(e)) - reply = "Unable to find station " + searchcall + ". Sending beacons?" + reply = "{}: {} {}' {},{} {}h ago".format( + searchcall, + wx_data["location"]["areaDescription"], + str(altfeet), + str(lat), + str(lon), + str("%.1f" % round(delta_hours, 1)), + ).rstrip() return reply diff --git a/aprsd/plugins/weather.py b/aprsd/plugins/weather.py index 6b4fd62..cf5cdab 100644 --- a/aprsd/plugins/weather.py +++ b/aprsd/plugins/weather.py @@ -3,6 +3,7 @@ import logging import re from aprsd import plugin, plugin_utils, utils +import requests LOG = logging.getLogger("APRSD") @@ -83,6 +84,10 @@ class USMetarPlugin(plugin.APRSDPluginBase): return "Failed to fetch location" # LOG.debug("LocationPlugin: aprs_data = {}".format(aprs_data)) + if not len(aprs_data["entries"]): + LOG.error("Found no entries from aprs.fi!") + return "Failed to fetch location" + lat = aprs_data["entries"][0]["lat"] lon = aprs_data["entries"][0]["lng"] @@ -133,6 +138,10 @@ class OWMWeatherPlugin(plugin.APRSDPluginBase): return "Failed to fetch location" # LOG.debug("LocationPlugin: aprs_data = {}".format(aprs_data)) + if not len(aprs_data["entries"]): + LOG.error("Found no entries from aprs.fi!") + return "Failed to fetch location" + lat = aprs_data["entries"][0]["lat"] lon = aprs_data["entries"][0]["lng"] @@ -194,3 +203,68 @@ class OWMWeatherPlugin(plugin.APRSDPluginBase): ) return reply + + +class AVWXWeatherPlugin(plugin.APRSDPluginBase): + """AVWXWeatherMap Weather Command""" + + version = "1.0" + command_regex = "^[wW]" + command_name = "Weather" + + def command(self, fromcall, message, ack): + LOG.info("OWMWeather Plugin '{}'".format(message)) + a = re.search(r"^.*\s+(.*)", message) + if a is not None: + searchcall = a.group(1) + searchcall = searchcall.upper() + else: + searchcall = fromcall + + api_key = self.config["aprs.fi"]["apiKey"] + try: + aprs_data = plugin_utils.get_aprs_fi(api_key, searchcall) + except Exception as ex: + LOG.error("Failed to fetch aprs.fi data {}".format(ex)) + return "Failed to fetch location" + + # LOG.debug("LocationPlugin: aprs_data = {}".format(aprs_data)) + if not len(aprs_data["entries"]): + LOG.error("Found no entries from aprs.fi!") + return "Failed to fetch location" + + lat = aprs_data["entries"][0]["lat"] + lon = aprs_data["entries"][0]["lng"] + + try: + utils.check_config_option(self.config, "avwx", "apiKey") + except Exception as ex: + LOG.error("Failed to find config avwx:apiKey {}".format(ex)) + return "No avwx apiKey found" + + try: + utils.check_config_option(self.config, "avwx", "base_url") + except Exception as ex: + LOG.debut("Didn't find avwx:base_url {}".format(ex)) + base_url = "https://avwx.rest" + else: + base_url = self.config["avwx"]["base_url"] + + api_key = self.config["avwx"]["apiKey"] + token = "TOKEN {}".format(api_key) + try: + coord = "{},{}".format(lat, lon) + url = ( + "{}/api/station/near/{}?" + "n=1&airport=true&reporting=true&format=json".format(base_url, coord) + ) + + LOG.debug("Get stations near me '{}'".format(url)) + response = requests.get(url, headers={"Authorization": token}) + except Exception as ex: + LOG.error(ex) + raise Exception("Failed to get the weather '{}'".format(ex)) + else: + wx_data = json.loads(response.text) + + LOG.debug(wx_data)