diff --git a/README.md b/README.md index 17c0d9a..4072695 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ Any messages that are over 160 characters are chunked into 160 message bytes to - `bbsdelete` delete a message example use: `bbsdelete #4` - Other functions - `whereami` returns the address of location of sender if known + - `whoami` returns some details of the node asking - `tide` returns the local tides, NOAA data source - `wx` and `wxc` returns local weather forecast, (wxc is metric value), NOAA or Open Meteo for weather forecasting. - `wxa` and `wxalert` return NOAA alerts. Short title or expanded details @@ -256,6 +257,6 @@ Games Ported from.. - https://github.com/Himan10/BlackJack - https://github.com/devtronvarma/Video-Poker-Terminal-Game -GitHub user mrpatrick1991 For Docker configs, PiDiBi looking at test functions and other suggestions like wxc, CPU use, and alerting ideas +GitHub user Nestpebble, for new ideas and enhancments, mrpatrick1991 For Docker configs, PiDiBi looking at test functions and other suggestions like wxc, CPU use, and alerting ideas Discord and Mesh user Cisien, and github Hailo1999, for testing and ideas! Lots of individuals on the Meshtastic discord who have tossed out ideas and tested code! diff --git a/config.template b/config.template index f13f463..35c7c8f 100644 --- a/config.template +++ b/config.template @@ -30,6 +30,8 @@ defaultChannel = 0 # motd is reset to this value on boot motd = Thanks for using MeshBOT! Have a good day! welcome_message = MeshBot, here for you like a friend who is not. Try sending: ping @foo or, cmd +# whoami +whoami = True # enable or disable the Joke module DadJokes = True # enable or disable the Solar module @@ -113,4 +115,9 @@ signalDetectionThreshold = -10 signalHoldTime = 10 # the following are combined to reset the monitor signalCooldown = 5 -signalCycleLimit = 5 \ No newline at end of file +signalCycleLimit = 5 + +[messagingSettings] +responseDelay = 0.7 # delay in seconds for response to avoid message collision +splitDelay = 0.7 # delay in seconds for splits in messages to avoid message collision +MESSAGE_CHUNK_SIZE = 160 # message chunk size for sending at high success rate diff --git a/mesh_bot.py b/mesh_bot.py index a82013b..b8b1c17 100755 --- a/mesh_bot.py +++ b/mesh_bot.py @@ -8,8 +8,6 @@ from pubsub import pub # pip install pubsub from modules.log import * from modules.system import * -responseDelay = 0.7 # delay in seconds for response to avoid message collision - def auto_response(message, snr, rssi, hop, message_from_id, channel_number, deviceID): #Auto response to messages message_lower = message.lower() @@ -18,7 +16,7 @@ def auto_response(message, snr, rssi, hop, message_from_id, channel_number, devi command_handler = { "ping": lambda: handle_ping(message, hop, snr, rssi), "pong": lambda: "🏓PING!!", - "motd": lambda: handle_motd(message), + "motd": lambda: handle_motd(message, message_from_id), "bbshelp": bbs_help, "wxalert": lambda: handle_wxalert(message_from_id, deviceID, message), "wxa": lambda: handle_wxalert(message_from_id, deviceID, message), @@ -50,8 +48,9 @@ def auto_response(message, snr, rssi, hop, message_from_id, channel_number, devi "tide": lambda: handle_tide(message_from_id, deviceID, channel_number), "moon": lambda: handle_moon(message_from_id, deviceID, channel_number), "ack": lambda: handle_ack(hop, snr, rssi), - "testing": lambda: handle_testing(hop, snr, rssi), - "test": lambda: handle_testing(hop, snr, rssi), + "testing": lambda: handle_testing(message, hop, snr, rssi), + "test": lambda: handle_testing(message, hop, snr, rssi), + "whoami": lambda: handle_whoami(message_from_id, deviceID), } cmds = [] # list to hold the commands found in the message for key in command_handler: @@ -73,23 +72,45 @@ def auto_response(message, snr, rssi, hop, message_from_id, channel_number, devi def handle_ping(message, hop, snr, rssi): if "@" in message: if hop == "Direct": - return "🏓PONG, " + f"SNR:{snr} RSSI:{rssi}" + " and copy: " + message.split("@")[1] + return "🏓PONG, " + f"SNR:{snr} RSSI:{rssi}" + " at: " + message.split("@")[1] else: - return "🏓PONG, " + hop + " and copy: " + message.split("@")[1] + return "🏓PONG, " + hop + " at: " + message.split("@")[1] + elif "#" in message: + if hop == "Direct": + return "🏓PONG, " + f"SNR:{snr} RSSI:{rssi}" + " #" + message.split("#")[1] + else: + return "🏓PONG, " + hop + " #" + message.split("#")[1] else: if hop == "Direct": return "🏓PONG, " + f"SNR:{snr} RSSI:{rssi}" else: return "🏓PONG, " + hop -def handle_motd(message): +def handle_motd(message, message_from_id): global MOTD - if "$" in message: + isAdmin = False + msg = "" + # check if the message_from_id is in the bbs_admin_list + if bbs_admin_list != ['']: + for admin in bbs_admin_list: + if str(message_from_id) == admin: + isAdmin = True + break + else: + isAdmin = True + + if "$" in message and isAdmin: motd = message.split("$")[1] MOTD = motd.rstrip() - return "MOTD Set to: " + MOTD + logger.debug(f"System: {message_from_id} changed MOTD: {MOTD}") + msg = "MOTD changed to: " + MOTD + elif "?" in message: + msg = "Message of the day, set with 'motd $ HelloWorld!'" else: - return MOTD + logger.debug(f"System: {message_from_id} requested MOTD: {MOTD} isAdmin: {isAdmin}") + msg = "MOTD: " + MOTD + + return msg def handle_wxalert(message_from_id, deviceID, message): if use_meteo_wxApi: @@ -446,15 +467,39 @@ def handle_moon(message_from_id, deviceID, channel_number): def handle_ack(hop, snr, rssi): if hop == "Direct": - return "🏓ACK-ACK! " + f"SNR:{snr} RSSI:{rssi}" + return "✋ACK-ACK! " + f"SNR:{snr} RSSI:{rssi}" else: - return "🏓ACK-ACK! " + hop + return "✋ACK-ACK! " + hop -def handle_testing(hop, snr, rssi): - if hop == "Direct": - return "🏓Testing 1,2,3 " + f"SNR:{snr} RSSI:{rssi}" +def handle_testing(message, hop, snr, rssi): + if "@" in message: + if hop == "Direct": + return "🎙Testing, " + f"SNR:{snr} RSSI:{rssi}" + " at: " + message.split("@")[1] + else: + return "🎙Testing, " + hop + " at: " + message.split("@")[1] + elif "#" in message: + if hop == "Direct": + return "🎙Testing " + f"SNR:{snr} RSSI:{rssi}" + " #" + message.split("#")[1] + else: + return "🎙Testing " + hop + " #" + message.split("#")[1] else: - return "🏓Testing 1,2,3 " + hop + if hop == "Direct": + return "🎙Testing 1,2,3 " + f"SNR:{snr} RSSI:{rssi}" + else: + return "🎙Testing 1,2,3 " + hop + +def handle_whoami(message_from_id, deviceID): + loc = [] + msg = "You are " + str(message_from_id) + " AKA " +\ + str(get_name_from_number(message_from_id, 'long', deviceID) + " AKA " +\ + str(get_name_from_number(message_from_id, 'short', deviceID)) + " AKA " +\ + str(decimal_to_hex(message_from_id)) + " AKA " +\ + str(message_from_id) + f"\n") + loc = get_node_location(message_from_id, deviceID) + if loc != [latitudeValue,longitudeValue]: + msg += f"You are at: lat:{loc[0]} lon:{loc[1]}\n" + return msg + def onDisconnect(interface): global retry_int1, retry_int2 diff --git a/modules/settings.py b/modules/settings.py index 9beeb63..83f3063 100644 --- a/modules/settings.py +++ b/modules/settings.py @@ -10,7 +10,6 @@ MOTD = 'Thanks for using MeshBOT! Have a good day!' NO_ALERTS = "No weather alerts found." # setup the global variables -MESSAGE_CHUNK_SIZE = 160 # message chunk size for sending at high success rate SITREP_NODE_COUNT = 3 # number of nodes to report in the sitrep msg_history = [] # message history for the store and forward feature bbs_ban_list = [] # list of banned users, imported from config @@ -66,6 +65,14 @@ if 'radioMon' not in config: config['radioMon'] = {'enabled': 'False', 'rigControlServerAddress': 'localhost:4532', 'sigWatchBrodcastCh': '2', 'signalDetectionThreshold': '-10', 'signalHoldTime': '10', 'signalCooldown': '5', 'signalCycleLimit': '5'} config.write(open(config_file, 'w')) +if 'games' not in config: + config['games'] = {'dopeWars': 'True', 'lemonade': 'True', 'blackjack': 'True', 'videoPoker': 'True'} + config.write(open(config_file, 'w')) + +if 'messagingSettings' not in config: + config['messagingSettings'] = {'responseDelay': '0.7', 'splitDelay': '0', 'MESSAGE_CHUNK_SIZE': '160'} + config.write(open(config_file, 'w')) + # interface1 settings interface1_type = config['interface'].get('type', 'serial') port1 = config['interface'].get('port', '') @@ -97,6 +104,7 @@ try: welcome_message = (f"{welcome_message}").replace('\\n', '\n') # allow for newlines in the welcome message motd_enabled = config['general'].getboolean('motdEnabled', True) MOTD = config['general'].get('motd', MOTD) + whoami_enabled = config['general'].getboolean('whoami', True) dad_jokes_enabled = config['general'].getboolean('DadJokes', False) solar_conditions_enabled = config['general'].getboolean('spaceWeather', True) wikipedia_enabled = config['general'].getboolean('wikipedia', False) @@ -145,6 +153,11 @@ try: blackjack_enabled = config['games'].getboolean('blackjack', True) videoPoker_enabled = config['games'].getboolean('videoPoker', True) + # messaging settings + responseDelay = config['messagingSettings'].getfloat('responseDelay', 0.7) # default 0.7 + splitDelay = config['messagingSettings'].getfloat('splitDelay', 0) # default 0 + MESSAGE_CHUNK_SIZE = config['messagingSettings'].getint('MESSAGE_CHUNK_SIZE', 160) # default 160 + except KeyError as e: print(f"System: Error reading config file: {e}") print(f"System: Check the config.ini against config.template file for missing sections or values.") diff --git a/modules/system.py b/modules/system.py index 4fe2184..9603b39 100644 --- a/modules/system.py +++ b/modules/system.py @@ -34,6 +34,12 @@ if motd_enabled: trap_list = trap_list + trap_list_motd help_message = help_message + ", motd" +# whoami Configuration +if whoami_enabled: + trap_list_whoami = ("whoami",) + trap_list = trap_list + trap_list_whoami + help_message = help_message + ", whoami" + # Solar Conditions Configuration if solar_conditions_enabled: from modules.solarconditions import * # from the spudgunman/meshing-around repo @@ -516,6 +522,7 @@ def send_message(message, ch, nodeid=0, nodeInt=1): interface1.sendText(text=m, channelIndex=ch, destinationId=nodeid) if nodeInt == 2: interface2.sendText(text=m, channelIndex=ch, destinationId=nodeid) + time.sleep(splitDelay) # wait an amout of time between sending each split message else: # message is less than MESSAGE_CHUNK_SIZE characters if nodeid == 0: # Send to channel diff --git a/pong_bot.py b/pong_bot.py index dffd044..bf47eaa 100755 --- a/pong_bot.py +++ b/pong_bot.py @@ -77,15 +77,15 @@ def handle_lheard(interface1, interface2_enabled, myNodeNum1, myNodeNum2): def handle_ack(hop, snr, rssi): if hop == "Direct": - return "🏓ACK-ACK! " + f"SNR:{snr} RSSI:{rssi}" + return "✋ACK-ACK! " + f"SNR:{snr} RSSI:{rssi}" else: - return "🏓ACK-ACK! " + hop + return "✋ACK-ACK! " + hop def handle_testing(hop, snr, rssi): if hop == "Direct": - return "🏓Testing 1,2,3 " + f"SNR:{snr} RSSI:{rssi}" + return "🎙Testing 1,2,3 " + f"SNR:{snr} RSSI:{rssi}" else: - return "🏓Testing 1,2,3 " + hop + return "🎙Testing 1,2,3 " + hop def onDisconnect(interface): global retry_int1, retry_int2