# Módulo: logica/T1/trafficMeter.py import psutil import time import threading # Constante de conversión: 1 KB = 1024 bytes KB = 1024 class NetIOMonitor(threading.Thread): """ Hilo que monitorea y almacena el tráfico de red (bytes por segundo) convirtiéndolo a Kilobytes por segundo (KB/s), además de CPU y RAM. """ def __init__(self, intervalo=1): super().__init__() self._stop_event = threading.Event() self.intervalo = intervalo # Almacenamiento seguro para los últimos datos de tráfico self.lock = threading.Lock() self.data_in_kb = 0.0 self.data_out_kb = 0.0 self.cpu_percent = 0.0 self.ram_percent = 0.0 # Almacena el contador anterior para calcular la diferencia (tasa) self.last_counters = psutil.net_io_counters() # Inicializar la medición de CPU (sin intervalo) para la primera lectura. # Esto 'primea' el cálculo de psutil para la primera vez que se llama en run(). psutil.cpu_percent(interval=None) def run(self): """Método principal del hilo.""" try: # Esperar el intervalo antes de la primera lectura para tener una base # y que el cálculo de la tasa sea correcto desde el inicio. time.sleep(self.intervalo) while not self._stop_event.is_set(): self._actualizar_datos() # Pausa al final, simplifica la lógica de _actualizar_datos time.sleep(self.intervalo) except Exception as e: print(f"Error fatal en el hilo NetIOMonitor: {e}") self._stop_event.set() def stop(self): """Detiene el hilo de forma segura.""" self._stop_event.set() def _actualizar_datos(self): """Calcula el tráfico de red en KB/s y mide CPU/RAM.""" current_counters = psutil.net_io_counters() # 🎯 CORRECCIÓN: Llamar sin intervalo. psutil.cpu_percent() devolverá el uso # desde la última llamada (que fue hace 'self.intervalo' segundos). current_cpu = psutil.cpu_percent() current_ram = psutil.virtual_memory().percent # Calcular la diferencia de bytes recibidos y enviados desde la última lectura bytes_recv_diff = current_counters.bytes_recv - self.last_counters.bytes_recv bytes_sent_diff = current_counters.bytes_sent - self.last_counters.bytes_sent # Calcular la tasa (bytes/segundo) y convertir a KB/s rate_in_kb_s = (bytes_recv_diff / self.intervalo) / KB rate_out_kb_s = (bytes_sent_diff / self.intervalo) / KB # Actualizar el contador anterior self.last_counters = current_counters # Guardar los resultados de forma segura with self.lock: self.data_in_kb = rate_in_kb_s self.data_out_kb = rate_out_kb_s self.cpu_percent = current_cpu self.ram_percent = current_ram def get_io_data_kb(self): """Devuelve el tráfico de E/S, CPU y RAM actual.""" with self.lock: # Devuelve los 4 valores return self.data_in_kb, self.data_out_kb, self.cpu_percent, self.ram_percent # --- FUNCIÓN DE INICIO --- def iniciar_monitor_red(): """Inicializa y comienza el monitor de red.""" monitor = NetIOMonitor(intervalo=1) # 1 segundo de intervalo monitor.start() return monitor