From dc731ae2371d3c4ac9b763bf03e1ec6029fa4c4b Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Thu, 27 Mar 2025 16:11:21 -0700 Subject: [PATCH] USGS Volcano Alerts --- config.template | 4 ++++ mesh_bot.py | 2 ++ modules/locationdata.py | 40 ++++++++++++++++++++++++++++++++++++++++ modules/settings.py | 2 ++ modules/system.py | 20 +++++++++++++++++--- 5 files changed, 65 insertions(+), 3 deletions(-) diff --git a/config.template b/config.template index 82ae222..3c33779 100644 --- a/config.template +++ b/config.template @@ -158,6 +158,10 @@ ignoreFEMAwords = test,exercise # find your SAME https://www.weather.gov/nwr/counties mySAME = 053029,053073 +# USGS Volcano alerts Enable USGS Volcano Alert Broadcast +volcanoAlertBroadcastEnabled = False +volcanoAlertBroadcastChannel = 2 + # Use DE Alert Broadcast Data enableDEalerts = False # comma separated list of regional codes trigger local alert. diff --git a/mesh_bot.py b/mesh_bot.py index 35696a4..5d70dc1 100755 --- a/mesh_bot.py +++ b/mesh_bot.py @@ -1419,6 +1419,8 @@ async def start_rx(): logger.debug(f"System: Emergency Alert Broadcast Enabled on channels {emergencyAlertBroadcastCh}") if emergency_responder_enabled: logger.debug(f"System: Emergency Responder Enabled on channels {emergency_responder_alert_channel} for interface {emergency_responder_alert_interface}") + if volcanoAlertBroadcastEnabled: + logger.debug(f"System: Volcano Alert Broadcast Enabled on channels {volcanoAlertBroadcastChannel}") if qrz_hello_enabled and train_qrz: logger.debug(f"System: QRZ Welcome/Hello Enabled with training mode") if qrz_hello_enabled and not train_qrz: diff --git a/modules/locationdata.py b/modules/locationdata.py index 62f5dd6..ead54ee 100644 --- a/modules/locationdata.py +++ b/modules/locationdata.py @@ -615,3 +615,43 @@ def get_flood_noaa(lat=0, lon=0, uid=0): return flood_data +def get_volcano_usgs(lat=0, lon=0): + alerts = '' + if lat == 0 and lon == 0: + lat = latitudeValue + lon = longitudeValue + # get the latest volcano alert from USGS from CAP feed + usgs_volcano_url = "https://volcanoes.usgs.gov/hans-public/api/volcano/getCapElevated" + try: + volcano_data = requests.get(usgs_volcano_url, timeout=urlTimeoutSeconds) + if not volcano_data.ok: + logger.warning("System: USGS fetching volcano alerts from USGS") + return ERROR_FETCHING_DATA + except (requests.exceptions.RequestException): + logger.warning("System: USGS fetching volcano alerts from USGS") + return ERROR_FETCHING_DATA + volcano_json = volcano_data.json() + # extract alerts from main feed + for alert in volcano_json: + # check if the alert lat long is within the range of bot latitudeValue and longitudeValue + if (alert['latitude'] >= latitudeValue - 10 and alert['latitude'] <= latitudeValue + 10) and (alert['longitude'] >= longitudeValue - 10 and alert['longitude'] <= longitudeValue + 10): + volcano_name = alert['volcano_name_appended'] + alert_level = alert['alert_level'] + color_code = alert['color_code'] + cap_severity = alert['cap_severity'] + synopsis = alert['synopsis'] + # format Alert + alerts += f"🌋🚨: {volcano_name} {alert_level} {color_code} {cap_severity}\n{synopsis}\n" + else: + logger.debug(f"System: USGS volcano alert not in range: {alert['volcano_name_appended']}") + continue + if alerts == "": + return NO_ALERTS + # trim off last newline + if alerts[-1] == "\n": + alerts = alerts[:-1] + # return the alerts + alerts = abbreviate_noaa(alerts) + return alerts + + diff --git a/modules/settings.py b/modules/settings.py index a29747e..cb6fe46 100644 --- a/modules/settings.py +++ b/modules/settings.py @@ -262,6 +262,8 @@ try: ignoreFEMAwords = config['location'].get('ignoreFEMAwords', 'test,exercise').split(',') # default test,exercise wxAlertBroadcastChannel = config['location'].get('wxAlertBroadcastCh', '2').split(',') # default Channel 2 emergencyAlertBroadcastCh = config['location'].get('eAlertBroadcastCh', '2').split(',') # default Channel 2 + volcanoAlertBroadcastEnabled = config['location'].getboolean('volcanoAlertBroadcastEnabled', False) # default False + volcanoAlertBroadcastChannel = config['location'].get('volcanoAlertBroadcastCh', '2').split(',') # default Channel 2 # bbs bbs_enabled = config['bbs'].getboolean('enabled', False) diff --git a/modules/system.py b/modules/system.py index 191a7c5..09c5e66 100644 --- a/modules/system.py +++ b/modules/system.py @@ -729,6 +729,7 @@ def handleAlertBroadcast(deviceID=1): alertDe = NO_ALERTS alertFema = NO_ALERTS wxAlert = NO_ALERTS + volcanoAlert = NO_ALERTS alertWx = False # only allow API call every 20 minutes # the watchdog will call this function 3 times, seeing possible throttling on the API @@ -785,8 +786,8 @@ def handleAlertBroadcast(deviceID=1): send_message(ukAlert, emergencyAlertBroadcastCh, 0, deviceID) return True - # pause for 10 seconds - time.sleep(10) + # pause for traffic + time.sleep(5) if wxAlertBroadcastEnabled: if wxAlert: @@ -796,6 +797,19 @@ def handleAlertBroadcast(deviceID=1): else: send_message(wxAlert, wxAlertBroadcastChannel, 0, deviceID) return True + + # pause for traffic + time.sleep(5) + + if volcanoAlertBroadcastEnabled: + volcanoAlert = get_volcano_usgs(latitudeValue, longitudeValue) + if volcanoAlert and NO_ALERTS not in volcanoAlert: + if isinstance(volcanoAlertBroadcastChannel, list): + for channel in volcanoAlertBroadcastChannel: + send_message(volcanoAlert, int(channel), 0, deviceID) + else: + send_message(volcanoAlert, volcanoAlertBroadcastChannel, 0, deviceID) + return True def onDisconnect(interface): global retry_int1, retry_int2, retry_int3, retry_int4, retry_int5, retry_int6, retry_int7, retry_int8, retry_int9 @@ -1210,7 +1224,7 @@ async def watchdog(): handleMultiPing(0, i) - if wxAlertBroadcastEnabled or emergencyAlertBrodcastEnabled: + if wxAlertBroadcastEnabled or emergencyAlertBrodcastEnabled or volcanoAlertBroadcastEnabled: handleAlertBroadcast(i) intData = displayNodeTelemetry(0, i)