From a35cb04ca725eacda5473dd38c0760934ca5957c Mon Sep 17 00:00:00 2001 From: Hemna Date: Thu, 21 Jan 2021 10:05:49 -0500 Subject: [PATCH] Updated documentation and config output This patch reformats the sample-config output for more informative comments for the 3 external services: openweathermap opencagedata avwx-api --- aprsd/plugin.py | 3 +- aprsd/plugins/weather.py | 98 ++++++++++++++++++++++++++++++++++++---- aprsd/utils.py | 25 ++++++++-- docs/apidoc/aprsd.rst | 16 +++++++ 4 files changed, 128 insertions(+), 14 deletions(-) diff --git a/aprsd/plugin.py b/aprsd/plugin.py index 4b3aff3..bd7182a 100644 --- a/aprsd/plugin.py +++ b/aprsd/plugin.py @@ -23,8 +23,7 @@ CORE_PLUGINS = [ "aprsd.plugins.ping.PingPlugin", "aprsd.plugins.query.QueryPlugin", "aprsd.plugins.time.TimePlugin", - "aprsd.plugins.weather.WeatherPlugin", - "aprsd.plugins.weather.WxPlugin", + "aprsd.plugins.weather.USWeatherPlugin", "aprsd.plugins.version.VersionPlugin", ] diff --git a/aprsd/plugins/weather.py b/aprsd/plugins/weather.py index cf5cdab..048ca6d 100644 --- a/aprsd/plugins/weather.py +++ b/aprsd/plugins/weather.py @@ -8,8 +8,18 @@ import requests LOG = logging.getLogger("APRSD") -class WeatherPlugin(plugin.APRSDPluginBase): - """Weather Command""" +class USWeatherPlugin(plugin.APRSDPluginBase): + """USWeather Command + + Returns a weather report for the calling weather station + inside the United States only. This uses the + forecast.weather.gov API to fetch the weather. + + This service does not require an apiKey. + + How to Call: Send a message to aprsd + "weather" - returns weather near the calling callsign + """ version = "1.0" command_regex = "^[wW]" @@ -50,7 +60,19 @@ class WeatherPlugin(plugin.APRSDPluginBase): class USMetarPlugin(plugin.APRSDPluginBase): - """METAR Command""" + """METAR Command + + This provides a METAR weather report from a station near the caller + or callsign using the forecast.weather.gov api. This only works + for stations inside the United States. + + This service does not require an apiKey. + + How to Call: Send a message to aprsd + "metar" - returns metar report near the calling callsign + "metar CALLSIGN" - returns metar report near CALLSIGN + + """ version = "1.0" command_regex = "^[metar]" @@ -115,7 +137,23 @@ class USMetarPlugin(plugin.APRSDPluginBase): class OWMWeatherPlugin(plugin.APRSDPluginBase): - """OpenWeatherMap Weather Command""" + """OpenWeatherMap Weather Command + + This provides weather near the caller or callsign. + + How to Call: Send a message to aprsd + "weather" - returns the weather near the calling callsign + "weather CALLSIGN" - returns the weather near CALLSIGN + + This plugin uses the openweathermap API to fetch + location and weather information. + + To use this plugin you need to get an openweathermap + account and apikey. + + https://home.openweathermap.org/api_keys + + """ version = "1.0" command_regex = "^[wW]" @@ -206,10 +244,30 @@ class OWMWeatherPlugin(plugin.APRSDPluginBase): class AVWXWeatherPlugin(plugin.APRSDPluginBase): - """AVWXWeatherMap Weather Command""" + """AVWXWeatherMap Weather Command + + Fetches a METAR weather report for the nearest + weather station from the callsign + Can be called with: + metar - fetches metar for caller + metar - fetches metar for + + This plugin requires the avwx-api service + to provide the metar for a station near + the callsign. + + avwx-api is an opensource project that has + a hosted service here: https://avwx.rest/ + + You can launch your own avwx-api in a container + by cloning the githug repo here: https://github.com/avwx-rest/AVWX-API + + Then build the docker container with: + docker build -f Dockerfile -t avwx-api:master . + """ version = "1.0" - command_regex = "^[wW]" + command_regex = "^[metar]" command_name = "Weather" def command(self, fromcall, message, ack): @@ -252,19 +310,41 @@ class AVWXWeatherPlugin(plugin.APRSDPluginBase): api_key = self.config["avwx"]["apiKey"] token = "TOKEN {}".format(api_key) + headers = {"Authorization": token} try: coord = "{},{}".format(lat, lon) url = ( "{}/api/station/near/{}?" - "n=1&airport=true&reporting=true&format=json".format(base_url, coord) + "n=1&airport=false&reporting=true&format=json".format(base_url, coord) ) LOG.debug("Get stations near me '{}'".format(url)) - response = requests.get(url, headers={"Authorization": token}) + response = requests.get(url, headers=headers) 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) + # LOG.debug(wx_data) + station = wx_data[0]["station"]["icao"] + + try: + url = ( + "{}/api/metar/{}?options=info,translate,summary" + "&airport=true&reporting=true&format=json&onfail=cache".format( + base_url, + station, + ) + ) + + LOG.debug("Get METAR '{}'".format(url)) + response = requests.get(url, headers=headers) + except Exception as ex: + LOG.error(ex) + raise Exception("Failed to get metar {}".format(ex)) + else: + metar_data = json.loads(response.text) + + # LOG.debug(metar_data) + return metar_data["raw"] diff --git a/aprsd/utils.py b/aprsd/utils.py index 9c81b17..d088657 100644 --- a/aprsd/utils.py +++ b/aprsd/utils.py @@ -24,6 +24,7 @@ DEFAULT_CONFIG_DICT = { "aprs.fi": {"apiKey": "set me"}, "openweathermap": {"apiKey": "set me"}, "opencagedata": {"apiKey": "set me"}, + "avwx": {"base_url": "http://host:port", "apiKey": "set me"}, "shortcuts": { "aa": "5551239999@vtext.com", "cl": "craiglamparter@somedomain.org", @@ -110,7 +111,8 @@ def add_config_comments(raw_yaml): # lets insert a comment raw_yaml = insert_str( raw_yaml, - "\n # Get the apiKey from your aprs.fi account here: http://aprs.fi/account", + "\n # Get the apiKey from your aprs.fi account here: " + "\n # http://aprs.fi/account", end_idx, ) @@ -119,7 +121,9 @@ def add_config_comments(raw_yaml): # lets insert a comment raw_yaml = insert_str( raw_yaml, - "\n # Get the apiKey from your opencagedata account here: https://opencagedata.com/dashboard#api-keys", + "\n # (Optional for TimeOpenCageDataPlugin) " + "\n # Get the apiKey from your opencagedata account here: " + "\n # https://opencagedata.com/dashboard#api-keys", end_idx, ) @@ -128,7 +132,22 @@ def add_config_comments(raw_yaml): # lets insert a comment raw_yaml = insert_str( raw_yaml, - "\n # Get the apiKey from your openweathermap account here: https://home.openweathermap.org/api_keys", + "\n # (Optional for OWMWeatherPlugin) " + "\n # Get the apiKey from your " + "\n # openweathermap account here: " + "\n # https://home.openweathermap.org/api_keys", + end_idx, + ) + + end_idx = end_substr(raw_yaml, "avwx:") + if end_idx != -1: + # lets insert a comment + raw_yaml = insert_str( + raw_yaml, + "\n # (Optional for AVWXWeatherPlugin) " + "\n # Use hosted avwx-api here: https://avwx.rest " + "\n # or deploy your own from here: " + "\n # https://github.com/avwx-rest/avwx-api", end_idx, ) diff --git a/docs/apidoc/aprsd.rst b/docs/apidoc/aprsd.rst index 2056c90..d3c74fa 100644 --- a/docs/apidoc/aprsd.rst +++ b/docs/apidoc/aprsd.rst @@ -20,6 +20,14 @@ aprsd.client module :undoc-members: :show-inheritance: +aprsd.dev module +---------------- + +.. automodule:: aprsd.dev + :members: + :undoc-members: + :show-inheritance: + aprsd.email module ------------------ @@ -68,6 +76,14 @@ aprsd.plugin module :undoc-members: :show-inheritance: +aprsd.plugin\_utils module +-------------------------- + +.. automodule:: aprsd.plugin_utils + :members: + :undoc-members: + :show-inheritance: + aprsd.threads module --------------------