""" WiFi recovery module for handling server disconnection Monitors server connectivity and auto-restarts WiFi if connection is lost """ import subprocess import time import threading import logging from datetime import datetime from logger_module import log_with_server class WiFiRecoveryManager: """ Manages WiFi recovery when server connection is lost Restarts WiFi after 20 minutes of consecutive connection failures """ def __init__(self, hostname, device_ip, check_interval=60, failure_threshold=5): """ Initialize WiFi recovery manager Args: hostname: Device hostname device_ip: Device IP check_interval: Seconds between connectivity checks failure_threshold: Number of consecutive failures before WiFi restart """ self.hostname = hostname self.device_ip = device_ip self.check_interval = check_interval self.failure_threshold = failure_threshold self.consecutive_failures = 0 self.is_wifi_down = False self.monitor_thread = None self.is_running = False self.wifi_down_time = 1200 # 20 minutes in seconds logging.basicConfig(level=logging.INFO) self.logger = logging.getLogger(__name__) def get_wifi_interface(self): """Detect WiFi interface (wlan0 or wlan1)""" try: result = subprocess.run( ['ip', 'link', 'show'], capture_output=True, text=True, timeout=10 ) if 'wlan0' in result.stdout: return 'wlan0' elif 'wlan1' in result.stdout: return 'wlan1' else: self.logger.error("No WiFi interface found") return None except Exception as e: self.logger.error(f"Error detecting WiFi interface: {e}") return None def stop_wifi(self, interface): """Stop WiFi interface""" try: self.logger.info(f"Stopping WiFi interface: {interface}") log_with_server(f"Stopping WiFi interface {interface}", self.hostname, self.device_ip) subprocess.run( ['sudo', 'ip', 'link', 'set', interface, 'down'], check=True, timeout=10 ) self.is_wifi_down = True return True except Exception as e: self.logger.error(f"Failed to stop WiFi: {e}") log_with_server(f"ERROR: Failed to stop WiFi: {str(e)}", self.hostname, self.device_ip) return False def start_wifi(self, interface): """Start WiFi interface""" try: self.logger.info(f"Starting WiFi interface: {interface}") log_with_server(f"Starting WiFi interface {interface}", self.hostname, self.device_ip) subprocess.run( ['sudo', 'ip', 'link', 'set', interface, 'up'], check=True, timeout=10 ) self.is_wifi_down = False return True except Exception as e: self.logger.error(f"Failed to start WiFi: {e}") log_with_server(f"ERROR: Failed to start WiFi: {str(e)}", self.hostname, self.device_ip) return False def reconnect_wifi(self, interface, wifi_down_time=1200): """ Perform WiFi disconnect and reconnect cycle Args: interface: WiFi interface to reset wifi_down_time: Time to keep WiFi disabled (seconds) """ self.logger.info(f"WiFi recovery: Stopping for {wifi_down_time} seconds...") log_with_server( f"WiFi recovery initiated: WiFi down for {wifi_down_time} seconds", self.hostname, self.device_ip ) # Stop WiFi if not self.stop_wifi(interface): return False # Keep WiFi down for specified time wait_time = wifi_down_time while wait_time > 0: minutes = wait_time // 60 seconds = wait_time % 60 self.logger.info(f"WiFi will restart in {minutes}m {seconds}s") time.sleep(60) # Check every minute wait_time -= 60 # Restart WiFi if not self.start_wifi(interface): return False self.logger.info("WiFi has been restarted") log_with_server("WiFi successfully restarted", self.hostname, self.device_ip) # Reset failure counter self.consecutive_failures = 0 return True def check_server_connection(self, server_host): """ Check if server is reachable via ping Args: server_host: Server hostname or IP to ping Returns: bool: True if server is reachable, False otherwise """ try: result = subprocess.run( ['ping', '-c', '1', '-W', '5', server_host], capture_output=True, timeout=10 ) return result.returncode == 0 except Exception as e: self.logger.error(f"Ping check failed: {e}") return False def monitor_connection(self, server_host="10.76.140.17"): """ Continuously monitor server connection and manage WiFi Args: server_host: Server hostname/IP to monitor """ self.is_running = True wifi_interface = self.get_wifi_interface() if not wifi_interface: self.logger.error("Cannot monitor without WiFi interface") return self.logger.info(f"Starting connection monitor for {server_host} on {wifi_interface}") log_with_server( f"Connection monitor started for {server_host}", self.hostname, self.device_ip ) while self.is_running: try: # Check if server is reachable if self.check_server_connection(server_host): if self.consecutive_failures > 0: self.consecutive_failures = 0 self.logger.info("Server connection restored") log_with_server("Server connection restored", self.hostname, self.device_ip) else: self.consecutive_failures += 1 self.logger.warning( f"Connection lost: {self.consecutive_failures}/{self.failure_threshold} failures" ) # If threshold reached, do WiFi recovery if self.consecutive_failures >= self.failure_threshold: self.logger.error( f"Server unreachable for {self.failure_threshold} pings - initiating WiFi recovery" ) # Perform WiFi recovery if self.reconnect_wifi(wifi_interface, self.wifi_down_time): self.logger.info("WiFi recovery completed successfully") else: self.logger.error("WiFi recovery failed") time.sleep(self.check_interval) except Exception as e: self.logger.error(f"Error in connection monitor: {e}") time.sleep(self.check_interval) def start_monitoring(self, server_host="10.76.140.17"): """ Start background monitoring thread Args: server_host: Server to monitor """ self.monitor_thread = threading.Thread( target=self.monitor_connection, args=(server_host,), daemon=True ) self.monitor_thread.start() self.logger.info("WiFi recovery monitor thread started") def stop_monitoring(self): """Stop the monitoring thread""" self.is_running = False if self.monitor_thread: self.monitor_thread.join(timeout=5) self.logger.info("WiFi recovery monitor stopped") # Global WiFi recovery manager instance wifi_recovery_manager = None def initialize_wifi_recovery(hostname, device_ip, server_host="10.76.140.17"): """Initialize and start WiFi recovery monitoring""" global wifi_recovery_manager try: wifi_recovery_manager = WiFiRecoveryManager( hostname=hostname, device_ip=device_ip, check_interval=60, failure_threshold=5 ) wifi_recovery_manager.start_monitoring(server_host) logging.info("WiFi recovery initialized") return wifi_recovery_manager except Exception as e: logging.error(f"Failed to initialize WiFi recovery: {e}") return None