From 93cfbc823081253523164bdb08f6c7f599395810 Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Sun, 6 Oct 2024 20:34:32 -0700 Subject: [PATCH] repeaterlist --- mesh_bot.py | 83 ++++++++++++++++++++++------------------- modules/locationdata.py | 55 ++++++++++++++++++++++++++- 2 files changed, 97 insertions(+), 41 deletions(-) diff --git a/mesh_bot.py b/mesh_bot.py index fd1f8d4..f73a658 100755 --- a/mesh_bot.py +++ b/mesh_bot.py @@ -25,52 +25,53 @@ def auto_response(message, snr, rssi, hop, pkiStatus, message_from_id, channel_n # Command List default_commands = { - "ping": lambda: handle_ping(message_from_id, deviceID, message, hop, snr, rssi, isDM), - "pong": lambda: "πŸ“PING!!", - "motd": lambda: handle_motd(message, message_from_id, isDM), - "bbshelp": bbs_help, - "wxalert": lambda: handle_wxalert(message_from_id, deviceID, message), - "wxa": lambda: handle_wxalert(message_from_id, deviceID, message), - "wxc": lambda: handle_wxc(message_from_id, deviceID, 'wxc'), - "wx": lambda: handle_wxc(message_from_id, deviceID, 'wx'), - "wiki:": lambda: handle_wiki(message, isDM), - "wiki?": lambda: handle_wiki(message, isDM), - "games": lambda: gamesCmdList, - "dopewars": lambda: handleDopeWars(message_from_id, message, deviceID), - "lemonstand": lambda: handleLemonade(message_from_id, message), - "blackjack": lambda: handleBlackJack(message_from_id, message), - "videopoker": lambda: handleVideoPoker(message_from_id, message), - "mastermind": lambda: handleMmind(message_from_id, deviceID, message), - "golfsim": lambda: handleGolf(message_from_id, message), - "playuno": lambda: handleUno(message_from_id, deviceID, message), - "globalthermonuclearwar": lambda: handle_gTnW(), + "ack": lambda: handle_ping(message_from_id, deviceID, message, hop, snr, rssi, isDM), "ask:": lambda: handle_llm(message_from_id, channel_number, deviceID, message, publicChannel), "askai": lambda: handle_llm(message_from_id, channel_number, deviceID, message, publicChannel), - "joke": tell_joke, + "bbsdelete": lambda: handle_bbsdelete(message, message_from_id), + "bbshelp": bbs_help, + "bbsinfo": lambda: get_bbs_stats(), "bbslist": bbs_list_messages, "bbspost": lambda: handle_bbspost(message, message_from_id, deviceID), "bbsread": lambda: handle_bbsread(message), - "bbsdelete": lambda: handle_bbsdelete(message, message_from_id), - "bbsinfo": lambda: get_bbs_stats(), - "messages": lambda: handle_messages(message, deviceID, channel_number, msg_history, publicChannel, isDM), - "cmd": lambda: help_message, - "history": lambda: handle_history(message, message_from_id, deviceID, isDM), - "sun": lambda: handle_sun(message_from_id, deviceID, channel_number), - "hfcond": hf_band_conditions, - "solar": lambda: drap_xray_conditions() + "\n" + solar_conditions(), - "lheard": lambda: handle_lheard(message, message_from_id, deviceID, isDM), - "sitrep": lambda: handle_lheard(message, message_from_id, deviceID, isDM), - "whereami": lambda: handle_whereami(message_from_id, deviceID, channel_number), - "tide": lambda: handle_tide(message_from_id, deviceID, channel_number), - "moon": lambda: handle_moon(message_from_id, deviceID, channel_number), - "ack": lambda: handle_ping(message_from_id, deviceID, message, hop, snr, rssi, isDM), - "testing": lambda: handle_ping(message_from_id, deviceID, message, hop, snr, rssi, isDM), - "test": lambda: handle_ping(message_from_id, deviceID, message, hop, snr, rssi, isDM), - "whoami": lambda: handle_whoami(message_from_id, deviceID, hop, snr, rssi, pkiStatus), - "πŸ“": lambda: handle_whoami(message_from_id, deviceID, hop, snr, rssi, pkiStatus), - "πŸ””": lambda: handle_alertBell(message_from_id, deviceID, message), + "blackjack": lambda: handleBlackJack(message_from_id, message), "CQCQ": lambda: handle_cq(message_from_id, deviceID, channel_number), "CQCQCQ": lambda: handle_cq(message_from_id, deviceID, channel_number), + "cmd": lambda: help_message, + "dopewars": lambda: handleDopeWars(message_from_id, message, deviceID), + "games": lambda: gamesCmdList, + "globalthermonuclearwar": lambda: handle_gTnW(), + "golfsim": lambda: handleGolf(message_from_id, message), + "hfcond": hf_band_conditions, + "history": lambda: handle_history(message, message_from_id, deviceID, isDM), + "joke": tell_joke, + "lemonstand": lambda: handleLemonade(message_from_id, message), + "lheard": lambda: handle_lheard(message, message_from_id, deviceID, isDM), + "mastermind": lambda: handleMmind(message_from_id, deviceID, message), + "messages": lambda: handle_messages(message, deviceID, channel_number, msg_history, publicChannel, isDM), + "moon": lambda: handle_moon(message_from_id, deviceID, channel_number), + "motd": lambda: handle_motd(message, message_from_id, isDM), + "ping": lambda: handle_ping(message_from_id, deviceID, message, hop, snr, rssi, isDM), + "playuno": lambda: handleUno(message_from_id, deviceID, message), + "pong": lambda: "πŸ“PING!!", + "repeaterlist": lambda: handle_repeaterQuery(message_from_id, deviceID, channel_number), + "sitrep": lambda: handle_lheard(message, message_from_id, deviceID, isDM), + "solar": lambda: drap_xray_conditions() + "\n" + solar_conditions(), + "sun": lambda: handle_sun(message_from_id, deviceID, channel_number), + "test": lambda: handle_ping(message_from_id, deviceID, message, hop, snr, rssi, isDM), + "testing": lambda: handle_ping(message_from_id, deviceID, message, hop, snr, rssi, isDM), + "tide": lambda: handle_tide(message_from_id, deviceID, channel_number), + "videopoker": lambda: handleVideoPoker(message_from_id, message), + "whereami": lambda: handle_whereami(message_from_id, deviceID, channel_number), + "whoami": lambda: handle_whoami(message_from_id, deviceID, hop, snr, rssi, pkiStatus), + "wiki:": lambda: handle_wiki(message, isDM), + "wiki?": lambda: handle_wiki(message, isDM), + "wx": lambda: handle_wxc(message_from_id, deviceID, 'wx'), + "wxalert": lambda: handle_wxalert(message_from_id, deviceID, message), + "wxa": lambda: handle_wxalert(message_from_id, deviceID, message), + "wxc": lambda: handle_wxc(message_from_id, deviceID, 'wxc'), + "πŸ“": lambda: handle_whoami(message_from_id, deviceID, hop, snr, rssi, pkiStatus), + "πŸ””": lambda: handle_alertBell(message_from_id, deviceID, message), } # set the command handler @@ -724,6 +725,10 @@ def handle_whereami(message_from_id, deviceID, channel_number): location = get_node_location(message_from_id, deviceID, channel_number) return where_am_i(str(location[0]), str(location[1])) +def handle_repeaterQuery(message_from_id, deviceID, channel_number): + location = get_node_location(message_from_id, deviceID, channel_number) + return getArtSciRepeaters(str(location[0]), str(location[1])) + def handle_tide(message_from_id, deviceID, channel_number): location = get_node_location(message_from_id, deviceID, channel_number) return get_tide(str(location[0]), str(location[1])) diff --git a/modules/locationdata.py b/modules/locationdata.py index 0a9c917..9c96584 100644 --- a/modules/locationdata.py +++ b/modules/locationdata.py @@ -9,9 +9,9 @@ import bs4 as bs # pip install beautifulsoup4 import xml.dom.minidom from modules.log import * -trap_list_location = ("whereami", "tide", "moon", "wx", "wxc", "wxa", "wxalert") +trap_list_location = ("whereami", "tide", "moon", "wx", "wxc", "wxa", "wxalert", "repeaterlist") -def where_am_i(lat=0, lon=0, short=False): +def where_am_i(lat=0, lon=0, short=False, zip=False): whereIam = "" grid = mh.to_maiden(float(lat), float(lon)) @@ -31,6 +31,12 @@ def where_am_i(lat=0, lon=0, short=False): whereIam = f"City: {address.get('city', '')}. State: {address.get('state', '')}. County: {address.get('county', '')}. Country: {address.get('country', '')}." return whereIam + if zip: + # return a string with zip code only + location = geolocator.reverse(str(lat) + ", " + str(lon)) + whereIam = location.raw['address'].get('postcode', '') + return whereIam + if float(lat) == latitudeValue and float(lon) == longitudeValue: # redacted address when no GPS and using default location location = geolocator.reverse(str(lat) + ", " + str(lon)) @@ -62,6 +68,51 @@ def where_am_i(lat=0, lon=0, short=False): logger.debug("Location:Error fetching location data with whereami, likely network error") return ERROR_FETCHING_DATA +def getArtSciRepeaters(lat=0, lon=0): + # UK api_url = "https://api-beta.rsgb.online/all/systems" + #grid = mh.to_maiden(float(lat), float(lon)) + repeaters = [] + zipCode = where_am_i(lat, lon, zip=True) + if zipCode == NO_DATA_NOGPS or zipCode == ERROR_FETCHING_DATA: + return zipCode + + if zipCode.isnumeric(): + try: + artsci_url = f"http://www.artscipub.com/mobile/showstate.asp?zip={zipCode}" + response = requests.get(artsci_url) + soup = bs.BeautifulSoup(response.text, 'html.parser') + # results needed xpath is /html/body/table[2]/tbody/tr/td/table/tbody/tr[2]/td/table + table = soup.find_all('table')[1] + rows = table.find_all('tr') + for row in rows: + cols = row.find_all('td') + cols = [ele.text.strip() for ele in cols] + # if no elements have the word 'located' then append + if not any('located' in ele for ele in cols): + if not any('Location' in ele for ele in cols): + repeaters.append([ele for ele in cols if ele]) + except Exception as e: + logger.error(f"Error fetching data from {artsci_url}: {e}") + + if repeaters != []: + msg = f"Found:{len(repeaters)} in {zipCode}\n" + for repeater in repeaters: + # format is ['City', 'Frequency', 'Offset', 'PL', 'Call', 'Notes'] + # there might be missing elements or only one element + if len(repeater) == 2: + msg += f"Freq:{repeater[1]}\n" + elif len(repeater) == 3: + msg += f"Freq:{repeater[1]}, PL:{repeater[2]}\n" + elif len(repeater) == 4: + msg += f"Freq:{repeater[1]}, PL:{repeater[2]}, ID: {repeater[3]}\n" + elif len(repeater) == 5: + msg += f"Freq:{repeater[1]}, PL:{repeater[2]}, ID:{repeater[3]}, Dist:{repeater[4]}\n" + elif len(repeater) == 6: + msg += f"Freq:{repeater[1]}, PL:{repeater[2]}, ID:{repeater[3]}, Dist:{repeater[4]}. {repeater[5]}\n" + else: + msg = f"no results.. sorry" + return msg + def get_tide(lat=0, lon=0): station_id = ""