From e95902ef98a8410d70d63fa7255c546e75d07d9f Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Tue, 15 Jul 2025 15:22:53 -0700 Subject: [PATCH] fix Excessive queries to FEMA issue raised https://github.com/SpudGunMan/meshing-around/issues/165 Co-Authored-By: DEVAFRS <180097515+devafrs@users.noreply.github.com> --- config.template | 9 ++--- modules/locationdata.py | 73 +++++++++++++++++++++-------------------- modules/settings.py | 3 +- 3 files changed, 41 insertions(+), 44 deletions(-) diff --git a/config.template b/config.template index 89a2fe7..496e2ca 100644 --- a/config.template +++ b/config.template @@ -161,16 +161,13 @@ enableExtraLocationWx = False # Goverment Alert Broadcast defaults to FEMA IPAWS eAlertBroadcastEnabled = False +# comma separated list of FIPS codes to trigger local alert. find your FIPS codes at https://en.wikipedia.org/wiki/Federal_Information_Processing_Standard_state_code +myFIPSList = 57,58,53 # Goverment Alert Broadcast Channels eAlertBroadcastCh = 2 - -# FEMA Alert Broadcast Settings -# Enable Ignore any headline that includes following word list +# Enable Ignore, headline that includes following word list ignoreFEMAenable = True ignoreFEMAwords = test,exercise -# comma separated list of codes (e.g., SAME,FIPS,ZIP) trigger local alert. -# find your SAME https://www.weather.gov/nwr/counties -mySAME = 053029,053073 # USGS Volcano alerts Enable USGS Volcano Alert Broadcast volcanoAlertBroadcastEnabled = False diff --git a/modules/locationdata.py b/modules/locationdata.py index 4802486..9da299f 100644 --- a/modules/locationdata.py +++ b/modules/locationdata.py @@ -472,8 +472,6 @@ def getIpawsAlert(lat=0, lon=0, shortAlerts = False): # set the API URL for IPAWS namespace = "urn:oasis:names:tc:emergency:cap:1.2" alert_url = "https://apps.fema.gov/IPAWSOPEN_EAS_SERVICE/rest/feed" - if ipawsPIN != "000000": - alert_url += "?pin=" + ipawsPIN # get the alerts from FEMA try: @@ -491,10 +489,25 @@ def getIpawsAlert(lat=0, lon=0, shortAlerts = False): # extract alerts from main feed for entry in alertxml.getElementsByTagName("entry"): link = entry.getElementsByTagName("link")[0].getAttribute("href") + + ## state FIPS + ## This logic is being added to reduce load on FEMA server. + stateFips = None + for cat in entry.getElementsByTagName("category"): + if cat.getAttribute("label") == "statefips": + stateFips = cat.getAttribute("term") + break + + if stateFips is None: + # no stateFIPS found — skip + continue + + # check if it matches your list + if stateFips not in myStateFIPSList: + #logger.debug(f"Skipping FEMA record link {link} with stateFIPS code of: {stateFips} because it doesn't match our StateFIPSList {myStateFIPSList}") + continue # skip to next entry + try: - #pin check - if ipawsPIN != "000000": - link += "?pin=" + ipawsPIN # get the linked alert data from FEMA linked_data = requests.get(link, timeout=urlTimeoutSeconds) if not linked_data.ok or not linked_data.text.strip(): @@ -533,44 +546,32 @@ def getIpawsAlert(lat=0, lon=0, shortAlerts = False): area_table = info.getElementsByTagName("area")[0] areaDesc = area_table.getElementsByTagName("areaDesc")[0].childNodes[0].nodeValue - geocode_table = area_table.getElementsByTagName("geocode")[0] - geocode_type = geocode_table.getElementsByTagName("valueName")[0].childNodes[0].nodeValue - geocode_value = geocode_table.getElementsByTagName("value")[0].childNodes[0].nodeValue - if geocode_type == "SAME": - sameVal = geocode_value except Exception as e: logger.debug(f"System: iPAWS Error extracting alert data: {link}") #print(f"DEBUG: {info.toprettyxml()}") continue - # check if the alert is for the current location, if wanted keep alert - if (sameVal in mySAME) or (geocode_value in mySAME): - # ignore the FEMA test alerts - if ignoreFEMAenable: - ignore_alert = False - for word in ignoreFEMAwords: - if word.lower() in headline.lower(): - logger.debug(f"System: Ignoring FEMA Alert: {headline} containing {word} at {areaDesc}") - ignore_alert = True - break + # ignore the FEMA test alerts + if ignoreFEMAenable: + ignore_alert = False + for word in ignoreFEMAwords: + if word.lower() in headline.lower(): + logger.debug(f"System: Ignoring FEMA Alert: {headline} containing {word} at {areaDesc}") + ignore_alert = True + break - if ignore_alert: - continue + if ignore_alert: + continue + + # add to alerts list + alerts.append({ + 'alertType': alertType, + 'alertCode': alertCode, + 'headline': headline, + 'areaDesc': areaDesc, + 'description': description + }) - # add to alerts list - alerts.append({ - 'alertType': alertType, - 'alertCode': alertCode, - 'headline': headline, - 'areaDesc': areaDesc, - 'geocode_type': geocode_type, - 'geocode_value': geocode_value, - 'description': description - }) - # else: - # # these are discarded some day but logged for debugging currently - # logger.debug(f"Debug iPAWS: Type:{alertType} Code:{alertCode} Desc:{areaDesc} GeoType:{geocode_type} GeoVal:{geocode_value}, Headline:{headline}") - # return the numWxAlerts of alerts if len(alerts) > 0: for alertItem in alerts[:numWxAlerts]: diff --git a/modules/settings.py b/modules/settings.py index e1c43f8..9e97e06 100644 --- a/modules/settings.py +++ b/modules/settings.py @@ -259,12 +259,11 @@ try: wxAlertsEnabled = config['location'].getboolean('NOAAalertsEnabled', True) # default True ignoreEASenable = config['location'].getboolean('ignoreEASenable', False) # default False ignoreEASwords = config['location'].get('ignoreEASwords', 'test,advisory').split(',') # default test,advisory - mySAME = config['location'].get('mySAME', '').split(',') # default empty myRegionalKeysDE = config['location'].get('myRegionalKeysDE', '110000000000').split(',') # default city Berlin forecastDuration = config['location'].getint('NOAAforecastDuration', 4) # NOAA forcast days numWxAlerts = config['location'].getint('NOAAalertCount', 2) # default 2 alerts enableExtraLocationWx = config['location'].getboolean('enableExtraLocationWx', False) # default False - ipawsPIN = config['location'].get('ipawsPIN', '000000') # default 000000 + myStateFIPSList = config['location'].get('myFIPSList', '').split(',') # default empty ignoreFEMAenable = config['location'].getboolean('ignoreFEMAenable', True) # default True ignoreFEMAwords = config['location'].get('ignoreFEMAwords', 'test,exercise').split(',') # default test,exercise wxAlertBroadcastChannel = config['location'].get('wxAlertBroadcastCh', '2').split(',') # default Channel 2