diff --git a/config.ini.example b/config.ini.example index a99487a..7e86072 100644 --- a/config.ini.example +++ b/config.ini.example @@ -50,6 +50,11 @@ rate_limit_seconds = 10 # Prevents bot from overwhelming the mesh network bot_tx_rate_limit_seconds = 1.0 +# Transmission delay in milliseconds before sending messages +# Helps prevent message collisions on the mesh network +# Recommended: 100-500ms for busy networks, 0 for quiet networks +tx_delay_ms = 250 + # Timezone for bot operations # Use standard timezone names (e.g., "America/New_York", "Europe/London", "UTC") # Leave empty to use system timezone diff --git a/modules/command_manager.py b/modules/command_manager.py index 7d7d373..d56b6b2 100644 --- a/modules/command_manager.py +++ b/modules/command_manager.py @@ -6,6 +6,7 @@ Handles all bot commands, keyword matching, and response generation import re import time +import asyncio from typing import List, Dict, Tuple, Optional, Any from meshcore import EventType @@ -33,6 +34,12 @@ class CommandManager: self.logger.info(f"CommandManager initialized with {len(self.commands)} plugins") + async def _apply_tx_delay(self): + """Apply transmission delay to prevent message collisions""" + if self.bot.tx_delay_ms > 0: + self.logger.debug(f"Applying {self.bot.tx_delay_ms}ms transmission delay") + await asyncio.sleep(self.bot.tx_delay_ms / 1000.0) + def load_keywords(self) -> Dict[str, str]: """Load keywords from config""" keywords = {} @@ -176,6 +183,9 @@ class CommandManager: # Wait for bot TX rate limiter (prevents network overload) await self.bot.bot_tx_rate_limiter.wait_for_tx() + # Apply transmission delay to prevent message collisions + await self._apply_tx_delay() + try: # Find the contact by name (since recipient_id is the contact name) contact = self.bot.meshcore.get_contact_by_name(recipient_id) @@ -231,6 +241,9 @@ class CommandManager: # Wait for bot TX rate limiter (prevents network overload) await self.bot.bot_tx_rate_limiter.wait_for_tx() + # Apply transmission delay to prevent message collisions + await self._apply_tx_delay() + try: # Get channel number from channel name channel_num = self.bot.channel_manager.get_channel_number(channel) diff --git a/modules/core.py b/modules/core.py index 0c44da0..fb7b22c 100644 --- a/modules/core.py +++ b/modules/core.py @@ -64,6 +64,7 @@ class MeshCoreBot: self.bot_tx_rate_limiter = BotTxRateLimiter( self.config.getfloat('Bot', 'bot_tx_rate_limit_seconds', fallback=1.0) ) + self.tx_delay_ms = self.config.getint('Bot', 'tx_delay_ms', fallback=250) self.message_handler = MessageHandler(self) self.command_manager = CommandManager(self) self.channel_manager = ChannelManager(self) @@ -148,6 +149,11 @@ rate_limit_seconds = 2 # Prevents bot from overwhelming the mesh network bot_tx_rate_limit_seconds = 1.0 +# Transmission delay in milliseconds before sending messages +# Helps prevent message collisions on the mesh network +# Recommended: 100-500ms for busy networks, 0 for quiet networks +tx_delay_ms = 250 + # Timezone for bot operations # Use standard timezone names (e.g., "America/New_York", "Europe/London", "UTC") # Leave empty to use system timezone