From cefe3e30e764e6d4293cd7a0485aac39f0412527 Mon Sep 17 00:00:00 2001 From: Walter Boring Date: Wed, 21 Jan 2026 16:27:14 -0500 Subject: [PATCH] Removed AVWX plugin. The AVWX Based weather plugin requires a subscription to the AVWX API, or to self host a running AVWX API. So this plugin has been moved to it's own external plugin here: aprsd-avwx-plugin: https://github.com/hemna/aprsd-avwx-plugin --- aprsd/conf/plugin_common.py | 24 -------- aprsd/plugins/weather.py | 120 ------------------------------------ 2 files changed, 144 deletions(-) diff --git a/aprsd/conf/plugin_common.py b/aprsd/conf/plugin_common.py index b9a531d..82b80f1 100644 --- a/aprsd/conf/plugin_common.py +++ b/aprsd/conf/plugin_common.py @@ -4,10 +4,6 @@ aprsfi_group = cfg.OptGroup( name='aprs_fi', title='APRS.FI website settings', ) -avwx_group = cfg.OptGroup( - name='avwx_plugin', - title='Options for the AVWXWeatherPlugin', -) aprsfi_opts = [ cfg.StrOpt( @@ -16,33 +12,13 @@ aprsfi_opts = [ ), ] -avwx_opts = [ - cfg.StrOpt( - 'apiKey', - help='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', - ), - cfg.StrOpt( - 'base_url', - default='https://avwx.rest', - help='The base url for the avwx API. If you are hosting your own' - 'Here is where you change the url to point to yours.', - ), -] - def register_opts(config): config.register_group(aprsfi_group) config.register_opts(aprsfi_opts, group=aprsfi_group) - config.register_group(avwx_group) - config.register_opts(avwx_opts, group=avwx_group) def list_opts(): return { aprsfi_group.name: aprsfi_opts, - avwx_group.name: avwx_opts, } diff --git a/aprsd/plugins/weather.py b/aprsd/plugins/weather.py index 2532358..879c3b5 100644 --- a/aprsd/plugins/weather.py +++ b/aprsd/plugins/weather.py @@ -2,7 +2,6 @@ import json import logging import re -import requests from oslo_config import cfg from aprsd import plugin, plugin_utils @@ -168,122 +167,3 @@ class USMetarPlugin(plugin.APRSDRegexCommandPluginBase, plugin.APRSFIKEYMixin): reply = 'No Metar station found' return reply - - -class AVWXWeatherPlugin(plugin.APRSDRegexCommandPluginBase): - """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 . - """ - - command_regex = r'^([m]|[m]|[m]\s|metar)' - command_name = 'AVWXWeather' - short_description = 'AVWX weather of GPS Beacon location' - - def setup(self): - if not CONF.avwx_plugin.base_url: - LOG.error('Config avwx_plugin.base_url not specified. Disabling') - return False - elif not CONF.avwx_plugin.apiKey: - LOG.error('Config avwx_plugin.apiKey not specified. Disabling') - return False - - self.enabled = True - - def help(self): - _help = [ - 'avwxweather: Send {} to get weather from your location'.format( - self.command_regex - ), - 'avwxweather: Send {} to get weather from '.format( - self.command_regex - ), - ] - return _help - - @trace.trace - def process(self, packet): - fromcall = packet.get('from') - message = packet.get('message_text', None) - # ack = packet.get("msgNo", "0") - LOG.info(f"AVWXWeather Plugin '{message}'") - a = re.search(r'^.*\s+(.*)', message) - if a is not None: - searchcall = a.group(1) - searchcall = searchcall.upper() - else: - searchcall = fromcall - - api_key = CONF.aprs_fi.apiKey - try: - aprs_data = plugin_utils.get_aprs_fi(api_key, searchcall) - except Exception as ex: - LOG.error(f'Failed to fetch aprs.fi data {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'] - - api_key = CONF.avwx_plugin.apiKey - base_url = CONF.avwx_plugin.base_url - token = f'TOKEN {api_key}' - headers = {'Authorization': token} - try: - coord = f'{lat},{lon}' - url = ( - '{}/api/station/near/{}?' - 'n=1&airport=false&reporting=true&format=json'.format(base_url, coord) - ) - - LOG.debug(f"Get stations near me '{url}'") - response = requests.get(url, headers=headers) - except Exception as ex: - LOG.error(ex) - raise Exception(f"Failed to get the weather '{ex}'") from ex - else: - wx_data = json.loads(response.text) - - # 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(f"Get METAR '{url}'") - response = requests.get(url, headers=headers) - except Exception as ex: - LOG.error(ex) - raise Exception(f'Failed to get metar {ex}') from ex - else: - metar_data = json.loads(response.text) - - # LOG.debug(metar_data) - return metar_data['raw']