working windows module

This commit is contained in:
ske087
2026-07-31 15:40:59 +03:00
parent d0ea94447a
commit 5c2b3f545f
4 changed files with 556 additions and 181 deletions
+166 -97
View File
@@ -6,11 +6,16 @@ Checks server connectivity and manages WiFi restart on connection failure
import subprocess
import time
import random
import platform
import requests
from datetime import datetime
from kivy.logger import Logger
from kivy.clock import Clock
# Detect platform once so the ping / WiFi-restart commands below can
# pick the correct syntax (Linux vs Windows).
IS_WINDOWS = platform.system() == 'Windows'
class NetworkMonitor:
"""Monitor network connectivity and manage WiFi restart"""
@@ -99,9 +104,15 @@ class NetworkMonitor:
Logger.info(f"NetworkMonitor: Pinging server: {hostname}")
# Ping the server hostname with 3 attempts
# Ping the server hostname with 3 attempts.
# Windows ping uses -n for count and -w for timeout (ms),
# while Linux uses -c and -W.
if IS_WINDOWS:
cmd = ['ping', '-n', '3', '-w', '3000', hostname]
else:
cmd = ['ping', '-c', '3', '-W', '3', hostname]
result = subprocess.run(
['ping', '-c', '3', '-W', '3', hostname],
cmd,
capture_output=True,
text=True,
timeout=10
@@ -123,113 +134,171 @@ class NetworkMonitor:
def _restart_wifi(self):
"""
Restart WiFi by turning it off for a specified duration then back on
This runs in a separate thread to not block the main application
Restart WiFi by turning it off for a specified duration then back on.
Uses the platform-appropriate commands:
- Linux (Raspberry Pi): sudo rfkill / ifconfig / dhclient
- Windows: netsh wlan disconnect / connect
This runs in a separate thread to not block the main application.
"""
def wifi_restart_thread():
try:
Logger.info("NetworkMonitor: ====================================")
Logger.info("NetworkMonitor: INITIATING WIFI RESTART SEQUENCE")
Logger.info("NetworkMonitor: ====================================")
# Turn off WiFi using rfkill (more reliable on Raspberry Pi)
Logger.info("NetworkMonitor: Turning WiFi OFF using rfkill...")
result = subprocess.run(
['sudo', 'rfkill', 'block', 'wifi'],
capture_output=True,
text=True,
timeout=10
)
if result.returncode == 0:
Logger.info("NetworkMonitor: ✓ WiFi turned OFF successfully (rfkill)")
Logger.info("NetworkMonitor: WiFi is now DISABLED and will remain OFF")
if IS_WINDOWS:
self._restart_wifi_windows()
else:
Logger.error(f"NetworkMonitor: rfkill failed, trying ifconfig...")
Logger.error(f"NetworkMonitor: rfkill error: {result.stderr}")
# Fallback to ifconfig
result2 = subprocess.run(
['sudo', 'ifconfig', 'wlan0', 'down'],
capture_output=True,
text=True,
timeout=10
)
if result2.returncode == 0:
Logger.info("NetworkMonitor: ✓ WiFi turned OFF successfully (ifconfig)")
else:
Logger.error(f"NetworkMonitor: Failed to turn WiFi off: {result2.stderr}")
Logger.error(f"NetworkMonitor: Return code: {result2.returncode}")
Logger.error(f"NetworkMonitor: STDOUT: {result2.stdout}")
return
# Wait for the specified duration with WiFi OFF
wait_minutes = self.wifi_restart_duration / 60
Logger.info(f"NetworkMonitor: ====================================")
Logger.info(f"NetworkMonitor: WiFi will remain OFF for {wait_minutes:.0f} minutes")
Logger.info(f"NetworkMonitor: Waiting period started at: {datetime.now().strftime('%H:%M:%S')}")
Logger.info(f"NetworkMonitor: ====================================")
# Sleep while WiFi is OFF
time.sleep(self.wifi_restart_duration)
Logger.info(f"NetworkMonitor: Wait period completed at: {datetime.now().strftime('%H:%M:%S')}")
# Turn WiFi back on after the wait period
Logger.info("NetworkMonitor: ====================================")
Logger.info("NetworkMonitor: Now turning WiFi back ON...")
Logger.info("NetworkMonitor: ====================================")
# Unblock WiFi using rfkill
result = subprocess.run(
['sudo', 'rfkill', 'unblock', 'wifi'],
capture_output=True,
text=True,
timeout=10
)
if result.returncode == 0:
Logger.info("NetworkMonitor: ✓ WiFi unblocked successfully (rfkill)")
else:
Logger.error(f"NetworkMonitor: rfkill unblock failed: {result.stderr}")
# Also bring interface up
result2 = subprocess.run(
['sudo', 'ifconfig', 'wlan0', 'up'],
capture_output=True,
text=True,
timeout=10
)
if result2.returncode == 0:
Logger.info("NetworkMonitor: ✓ WiFi interface brought UP successfully")
# Wait a bit for connection to establish
Logger.info("NetworkMonitor: Waiting 10 seconds for WiFi to initialize...")
time.sleep(10)
# Try to restart DHCP
Logger.info("NetworkMonitor: Requesting IP address...")
subprocess.run(
['sudo', 'dhclient', 'wlan0'],
capture_output=True,
text=True,
timeout=15
)
Logger.info("NetworkMonitor: ====================================")
Logger.info("NetworkMonitor: WIFI RESTART SEQUENCE COMPLETED")
Logger.info("NetworkMonitor: ====================================")
else:
Logger.error(f"NetworkMonitor: Failed to turn WiFi on: {result.stderr}")
self._restart_wifi_linux()
except subprocess.TimeoutExpired:
Logger.error("NetworkMonitor: WiFi restart command timeout")
except Exception as e:
Logger.error(f"NetworkMonitor: Error during WiFi restart: {e}")
# Run in separate thread to not block the application
import threading
thread = threading.Thread(target=wifi_restart_thread, daemon=True)
thread.start()
def _restart_wifi_windows(self):
"""Windows WiFi restart using netsh. Turn off for the wait period,
then turn back on so Windows reconnects to the preferred network."""
wait_minutes = self.wifi_restart_duration / 60
Logger.info(
f"NetworkMonitor: Windows WiFi restart — off for {wait_minutes:.0f} min"
)
# Turn WiFi OFF
off = subprocess.run(
['netsh', 'wlan', 'disconnect'],
capture_output=True, text=True, timeout=10
)
if off.returncode == 0:
Logger.info("NetworkMonitor: ✓ WiFi turned OFF (netsh wlan disconnect)")
else:
Logger.warning(
f"NetworkMonitor: netsh wlan disconnect failed: {off.stderr.strip()}"
)
# Wait with WiFi OFF
Logger.info(
f"NetworkMonitor: WiFi will remain OFF for {wait_minutes:.0f} minutes "
f"(started {datetime.now().strftime('%H:%M:%S')})"
)
time.sleep(self.wifi_restart_duration)
Logger.info(
f"NetworkMonitor: Wait period completed at {datetime.now().strftime('%H:%M:%S')}"
)
# Turn WiFi back ON — Windows reconnects to the preferred network
on = subprocess.run(
['netsh', 'wlan', 'connect'],
capture_output=True, text=True, timeout=10
)
if on.returncode == 0:
Logger.info("NetworkMonitor: ✓ WiFi re-enabled (netsh wlan connect)")
else:
# 'netsh wlan connect' without a profile may return non-zero even
# though the radio comes back on; log it but don't fail hard.
Logger.warning(
f"NetworkMonitor: netsh wlan connect returned {on.returncode}: "
f"{on.stderr.strip()} (may reconnect automatically)"
)
Logger.info("NetworkMonitor: ====================================")
Logger.info("NetworkMonitor: WIFI RESTART SEQUENCE COMPLETED")
Logger.info("NetworkMonitor: ====================================")
def _restart_wifi_linux(self):
"""Linux (Raspberry Pi) WiFi restart using rfkill/ifconfig/dhclient."""
# Turn off WiFi using rfkill (more reliable on Raspberry Pi)
Logger.info("NetworkMonitor: Turning WiFi OFF using rfkill...")
result = subprocess.run(
['sudo', 'rfkill', 'block', 'wifi'],
capture_output=True,
text=True,
timeout=10
)
if result.returncode == 0:
Logger.info("NetworkMonitor: ✓ WiFi turned OFF successfully (rfkill)")
else:
Logger.error(f"NetworkMonitor: rfkill failed, trying ifconfig...")
Logger.error(f"NetworkMonitor: rfkill error: {result.stderr}")
# Fallback to ifconfig
result2 = subprocess.run(
['sudo', 'ifconfig', 'wlan0', 'down'],
capture_output=True,
text=True,
timeout=10
)
if result2.returncode == 0:
Logger.info("NetworkMonitor: ✓ WiFi turned OFF successfully (ifconfig)")
else:
Logger.error(f"NetworkMonitor: Failed to turn WiFi off: {result2.stderr}")
Logger.error(f"NetworkMonitor: Return code: {result2.returncode}")
Logger.error(f"NetworkMonitor: STDOUT: {result2.stdout}")
return
# Wait for the specified duration with WiFi OFF
wait_minutes = self.wifi_restart_duration / 60
Logger.info(f"NetworkMonitor: ====================================")
Logger.info(f"NetworkMonitor: WiFi will remain OFF for {wait_minutes:.0f} minutes")
Logger.info(f"NetworkMonitor: Waiting period started at: {datetime.now().strftime('%H:%M:%S')}")
Logger.info(f"NetworkMonitor: ====================================")
# Sleep while WiFi is OFF
time.sleep(self.wifi_restart_duration)
Logger.info(f"NetworkMonitor: Wait period completed at: {datetime.now().strftime('%H:%M:%S')}")
# Turn WiFi back on after the wait period
Logger.info("NetworkMonitor: ====================================")
Logger.info("NetworkMonitor: Now turning WiFi back ON...")
Logger.info("NetworkMonitor: ====================================")
# Unblock WiFi using rfkill
result = subprocess.run(
['sudo', 'rfkill', 'unblock', 'wifi'],
capture_output=True,
text=True,
timeout=10
)
if result.returncode == 0:
Logger.info("NetworkMonitor: ✓ WiFi unblocked successfully (rfkill)")
else:
Logger.error(f"NetworkMonitor: rfkill unblock failed: {result.stderr}")
# Also bring interface up
result2 = subprocess.run(
['sudo', 'ifconfig', 'wlan0', 'up'],
capture_output=True,
text=True,
timeout=10
)
if result2.returncode == 0:
Logger.info("NetworkMonitor: ✓ WiFi interface brought UP successfully")
# Wait a bit for connection to establish
Logger.info("NetworkMonitor: Waiting 10 seconds for WiFi to initialize...")
time.sleep(10)
# Try to restart DHCP
Logger.info("NetworkMonitor: Requesting IP address...")
subprocess.run(
['sudo', 'dhclient', 'wlan0'],
capture_output=True,
text=True,
timeout=15
)
Logger.info("NetworkMonitor: ====================================")
Logger.info("NetworkMonitor: WIFI RESTART SEQUENCE COMPLETED")
Logger.info("NetworkMonitor: ====================================")
else:
Logger.error(f"NetworkMonitor: Failed to turn WiFi on: {result.stderr}")