diff --git a/README.md b/README.md index 14aa7f1..e9417f0 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ Welcome to the Mesh Bot project! This feature-rich bot is designed to enhance yo ### Network Tools - **Build, Test Local Mesh**: Ping allow for message delivery testing with more realistic packets vs. telemetry - **Test Node Hardware**: `test` will send incremental sized data into the radio buffer for overall length of message testing +- **Network Monitoring**: Alert on noisy nodes, node locations, and best placment for relay nodes. ### Multi Radio/Node Support - **Simultaneous Monitoring**: Monitor up to nine networks at the same time. @@ -155,7 +156,7 @@ git clone https://github.com/spudgunman/meshing-around | `golfsim` | Plays a 9-hole Golf Simulator | ✅ | | `hamtest` | FCC/ARRL Quiz `hamtest general` or `hamtest extra` and `score` | ✅ | | `hangman` | Plays the classic word guess game | ✅ | -| `joke` | Tells a joke | ✅ | +| `joke` | Tells a joke | | | `lemonstand` | Plays the classic Lemonade Stand finance game | ✅ | | `mastermind` | Plays the classic code-breaking game | ✅ | | `videopoker` | Plays basic 5-card hold Video Poker | ✅ | @@ -320,10 +321,9 @@ myRegionalKeysDE = 110000000000,120510000000 This uses the defined lat-long of the bot for collecting of data from the API. see [File-Monitoring](#File-Monitoring) for ideas to collect EAS alerts from a RTL-SDR. ```ini -# EAS Alert Broadcast -wxAlertBroadcastEnabled = True -# EAS Alert Broadcast Channels -wxAlertBroadcastCh = 2,4 + +wxAlertBroadcastEnabled = True # EAS Alert Broadcast +wxAlertBroadcastCh = 2,4 # EAS Alert Broadcast Channels ignoreEASenable = True # Ignore any headline that includes followig word list ignoreEASwords = test,advisory ``` @@ -440,19 +440,13 @@ training = True # Training mode will not send the hello message to new nodes, us In the config.ini enable the module ```ini [scheduler] -# enable or disable the scheduler module -enabled = False -# interface to send the message to -interface = 1 -# channel to send the message to +enabled = False # enable or disable the scheduler module +interface = 1 # channel to send the message to channel = 2 message = "MeshBot says Hello! DM for more info." -# value can be min,hour,day,mon,tue,wed,thu,fri,sat,sun -value = -# interval to use when time is not set (e.g. every 2 days) -interval = -# time of day in 24:00 hour format when value is 'day' and interval is not set -time = +value = # value can be min,hour,day,mon,tue,wed,thu,fri,sat,sun +interval = # interval to use when time is not set (e.g. every 2 days) +time = # time of day in 24:00 hour format when value is 'day' and interval is not set ``` The basic brodcast message can be setup in condig.ini. For advanced, See mesh_bot.py around the bottom of file, line [1491](https://github.com/SpudGunMan/meshing-around/blob/e94581936530c76ea43500eebb43f32ba7ed5e19/mesh_bot.py#L1491) to edit the schedule. See [schedule documentation](https://schedule.readthedocs.io/en/stable/) for more. Recomend to backup changes so they dont get lost. diff --git a/config.template b/config.template index 7afd545..f8674ec 100644 --- a/config.template +++ b/config.template @@ -327,5 +327,8 @@ wantAck = False maxBuffer = 200 #Enable Extra logging of Hop count data enableHopLogs = False +# Noisy Node Telemetry Logging and packet threshold +noisyNodeLogging = False +noisyTelemetryLimit = 5 diff --git a/mesh_bot.py b/mesh_bot.py index 6077d44..0f741f2 100755 --- a/mesh_bot.py +++ b/mesh_bot.py @@ -1488,6 +1488,8 @@ async def start_rx(): logger.debug(f"System: CheckList Module Enabled") if ignoreChannels != []: logger.debug(f"System: Ignoring Channels: {ignoreChannels}") + if noisyNodeLogging: + logger.debug(f"System: Noisy Node Logging Enabled") if enableSMTP: if enableImap: logger.debug(f"System: SMTP Email Alerting Enabled using IMAP") diff --git a/modules/settings.py b/modules/settings.py index b500a7d..060e4de 100644 --- a/modules/settings.py +++ b/modules/settings.py @@ -368,7 +368,8 @@ try: wantAck = config['messagingSettings'].getboolean('wantAck', False) # default False maxBuffer = config['messagingSettings'].getint('maxBuffer', 200) # default 200 enableHopLogs = config['messagingSettings'].getboolean('enableHopLogs', False) # default False - + noisyNodeLogging = config['messagingSettings'].getboolean('noisyNodeLogging', False) # default False + noisyTelemetryLimit = config['messagingSettings'].getint('noisyTelemetryLimit', 5) # default 5 packets 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 a982c45..5f89be8 100644 --- a/modules/system.py +++ b/modules/system.py @@ -1025,6 +1025,13 @@ def consumeMetadata(packet, rxNode=0): # Remove the oldest entry oldest_nodeID = next(iter(positionMetadata)) del positionMetadata[oldest_nodeID] + + # add a packet count to the positionMetadata for the node + if 'packetCount' in positionMetadata[nodeID]: + positionMetadata[nodeID]['packetCount'] += 1 + else: + positionMetadata[nodeID]['packetCount'] = 1 + except Exception as e: logger.debug(f"System: POSITION_APP decode error: {e} packet {packet}") @@ -1067,6 +1074,19 @@ def consumeMetadata(packet, rxNode=0): logger.critical(f"System: Error consuming metadata: {e} Device:{rxNode}") logger.debug(f"System: Error Packet = {packet}") +def noisyTelemetryCheck(): + global positionMetadata + if len(positionMetadata) == 0: + return + # sort the positionMetadata by packetCount + sorted_positionMetadata = dict(sorted(positionMetadata.items(), key=lambda item: item[1].get('packetCount', 0), reverse=True)) + top_three = list(sorted_positionMetadata.items())[:3] + for nodeID, data in top_three: + if data.get('packetCount', 0) > noisyTelemetryLimit: + logger.warning(f"System: Noisy Telemetry Detected from NodeID:{nodeID} ShortName:{get_name_from_number(nodeID, 'short', 1)} Packets:{data.get('packetCount', 0)}") + # reset the packet count for the node + positionMetadata[nodeID]['packetCount'] = 0 + def get_sysinfo(nodeID=0, deviceID=1): # Get the system telemetry data for return on the sysinfo command sysinfo = '' @@ -1289,6 +1309,10 @@ async def watchdog(): await retry_interface(i) except Exception as e: logger.error(f"System: retrying interface{i}: {e}") + + # check for noisy telemetry + if noisyNodeLogging: + noisyTelemetryCheck() def exit_handler(): # Close the interface and save the BBS messages