Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import ctypes
- import os
- import sys
- import time
- import serial
- import serial.tools.list_ports
- import psutil
- import subprocess
- from ctypes import wintypes, windll, c_size_t
- def is_admin():
- try:
- return ctypes.windll.shell32.IsUserAnAdmin()
- except:
- return False
- class MSIAfterburner:
- def __init__(self):
- self.PROCESS_VM_READ = 0x0010
- self.INVALID_HANDLE_VALUE = -1
- self.kernel32 = windll.kernel32
- self.process_handle = None
- self.find_afterburner()
- def find_afterburner(self):
- try:
- for proc in psutil.process_iter(['pid', 'name']):
- if 'MSIAfterburner.exe' in proc.info['name']:
- self.process_handle = self.kernel32.OpenProcess(
- self.PROCESS_VM_READ,
- False,
- proc.info['pid']
- )
- if self.process_handle:
- print("Successfully connected to MSI Afterburner")
- return
- print("MSI Afterburner process not found")
- except Exception as e:
- print(f"Error finding MSI Afterburner: {e}")
- def read_memory(self, address, size):
- buffer = ctypes.create_string_buffer(size)
- bytes_read = c_size_t()
- if self.kernel32.ReadProcessMemory(
- self.process_handle,
- address,
- buffer,
- size,
- ctypes.byref(bytes_read)
- ):
- return buffer.raw
- return None
- def get_fps(self):
- try:
- if not self.process_handle:
- return 0
- potential_offsets = [0x1234, 0x2345, 0x3456] # Example offsets
- for base_offset in potential_offsets:
- data = self.read_memory(base_offset, 4)
- if data:
- value = struct.unpack('f', data)[0]
- if 0 <= value <= 1000: # Valid FPS range
- return value
- return 0
- except Exception as e:
- print(f"Error reading FPS: {e}")
- return 0
- def close(self):
- if self.process_handle:
- self.kernel32.CloseHandle(self.process_handle)
- class GPUMonitor:
- def __init__(self):
- try:
- result = subprocess.run(['nvidia-smi', '--query-gpu=temperature.gpu,utilization.gpu', '--format=csv,noheader,nounits'],
- capture_output=True, text=True)
- print("GPU monitoring initialized")
- self.has_gpu = True
- except Exception as e:
- print(f"Error initializing GPU monitoring: {e}")
- self.has_gpu = False
- def get_gpu_stats(self):
- try:
- if not self.has_gpu:
- return 0.0, 0.0
- result = subprocess.run(['nvidia-smi',
- '--query-gpu=temperature.gpu,utilization.gpu',
- '--format=csv,noheader,nounits'],
- capture_output=True, text=True)
- if result.returncode == 0:
- temp, usage = map(float, result.stdout.strip().split(', '))
- return float(temp), float(usage)
- except Exception as e:
- print(f"Error reading GPU stats: {e}")
- return 0.0, 0.0
- def find_esp32_port():
- ports = list(serial.tools.list_ports.comports())
- for port in ports:
- if "Silicon Labs" in port.description or "CP210x" in port.description:
- return port.device
- return None
- def main():
- print("Initializing monitoring...")
- print("Please ensure MSI Afterburner is running and showing FPS")
- gpu_monitor = GPUMonitor()
- msi = MSIAfterburner()
- port = find_esp32_port()
- if not port:
- print("Could not find ESP32 port automatically.")
- port = input("Please enter COM port manually (e.g., COM3): ")
- ser = None
- try:
- ser = serial.Serial(port, 115200, timeout=1)
- print("Monitoring started. Press Ctrl+C to exit.")
- fps_values = []
- while True:
- try:
- gpu_temp, gpu_usage = gpu_monitor.get_gpu_stats()
- ram_used = psutil.virtual_memory().used / (1024 * 1024)
- cpu_usage = psutil.cpu_percent()
- current_fps = float(msi.get_fps())
- # Update FPS averaging
- fps_values.append(current_fps)
- fps_values = fps_values[-5:] # Keep last 5 FPS values
- avg_fps = sum(fps_values) / len(fps_values) if fps_values else 0.0
- # Format and display
- print("\nCurrent PC Performance:")
- print("-----------------------")
- print(f"3070TI Temperature: {gpu_temp:.1f}°C")
- print(f"3070TI Usage: {gpu_usage:.1f}%")
- print(f"RAM Usage: {ram_used:.0f}MB")
- print(f"CPU Usage: {cpu_usage:.1f}%")
- print(f"Framerate: {int(avg_fps)}FPS")
- # Send to ESP32
- data_str = f"{gpu_temp:.1f},{gpu_usage:.1f},{ram_used:.0f},{cpu_usage:.1f},{int(avg_fps)}\n"
- ser.write(data_str.encode())
- time.sleep(1)
- except KeyboardInterrupt:
- print("\nExiting...")
- break
- except Exception as e:
- print(f"Error: {e}")
- time.sleep(1)
- except serial.SerialException as e:
- print(f"\nSerial port error: {e}")
- print("1. Make sure the Arduino IDE Serial Monitor is closed")
- print("2. Verify the correct COM port is selected")
- finally:
- if ser is not None and ser.is_open:
- ser.close()
- msi.close()
- if __name__ == "__main__":
- if not is_admin():
- ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
- sys.exit(0)
- main()
Advertisement
Add Comment
Please, Sign In to add comment