forked from Keralots/SmallOLED-PCMonitor
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpc_stats_monitor.py
More file actions
152 lines (125 loc) · 5.01 KB
/
Copy pathpc_stats_monitor.py
File metadata and controls
152 lines (125 loc) · 5.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
"""
PC Stats Monitor - Ultra Optimized Version
Uses sensor identifiers for direct access - minimal CPU usage
"""
import psutil
import socket
import time
import json
from datetime import datetime
# Configuration
ESP32_IP = "192.168.0.163" # Change to your ESP32 IP address
UDP_PORT = 4210
BROADCAST_INTERVAL = 3 # Increased to 3 seconds for even less CPU usage
# Sensor identifiers (will be populated at startup)
sensor_ids = {
'fan': None, # Can be pump, case fan, CPU fan, etc.
'cpu_temp': None,
'gpu_temp': None
}
def initialize_sensors():
"""Find sensor identifiers once at startup
CUSTOMIZE THESE SENSOR NAMES FOR YOUR SYSTEM:
- Change 'Pump Fan' to match your fan name (e.g., 'Fan #1', 'CPU Fan', 'Case Fan')
- Change 'CPU Package' to match your CPU temp sensor
- Change 'GPU Core' to match your GPU temp sensor
Open LibreHardwareMonitor to see available sensor names for your system.
"""
print("Scanning for sensors...")
try:
import wmi
w = wmi.WMI(namespace="root\\LibreHardwareMonitor")
sensors = w.Sensor()
# Find our specific sensors and save their identifiers
for sensor in sensors:
# Fan/Pump sensor - CUSTOMIZE THIS NAME FOR YOUR SYSTEM
if sensor.SensorType == 'Fan' and sensor.Name == 'Pump Fan':
sensor_ids['fan'] = sensor.Identifier
print(f"✓ Fan/Pump ID: {sensor.Identifier}")
# CPU Temperature - CUSTOMIZE THIS NAME FOR YOUR SYSTEM
elif sensor.SensorType == 'Temperature' and sensor.Name == 'CPU Package':
sensor_ids['cpu_temp'] = sensor.Identifier
print(f"✓ CPU Temp ID: {sensor.Identifier}")
# GPU Temperature - CUSTOMIZE THIS NAME FOR YOUR SYSTEM
elif sensor.SensorType == 'Temperature' and sensor.Name == 'GPU Core':
sensor_ids['gpu_temp'] = sensor.Identifier
print(f"✓ GPU Temp ID: {sensor.Identifier}")
return True
except Exception as e:
print(f"✗ Error: {e}")
return False
def get_sensor_value(w, identifier):
"""Get single sensor value by identifier - very fast!"""
try:
# Query only the specific sensor we want
sensor = w.Sensor(Identifier=identifier)[0]
return int(sensor.Value)
except:
return None
def get_sensor_values():
"""Get values from specific sensors only - minimal WMI queries"""
try:
import wmi
w = wmi.WMI(namespace="root\\LibreHardwareMonitor")
# Get only the sensors we need - no iteration through hundreds
fan_speed = get_sensor_value(w, sensor_ids['fan']) if sensor_ids['fan'] else None
cpu_temp = get_sensor_value(w, sensor_ids['cpu_temp']) if sensor_ids['cpu_temp'] else None
gpu_temp = get_sensor_value(w, sensor_ids['gpu_temp']) if sensor_ids['gpu_temp'] else None
return fan_speed, cpu_temp, gpu_temp
except Exception as e:
return None, None, None
def get_system_stats():
"""Collect system statistics"""
# Get hardware sensors
fan_speed, cpu_temp, gpu_temp = get_sensor_values()
# Get system stats (minimal CPU usage)
stats = {
'timestamp': datetime.now().strftime('%H:%M'),
'cpu_percent': round(psutil.cpu_percent(interval=0), 1), # Non-blocking
'ram_percent': round(psutil.virtual_memory().percent, 1),
'ram_used_gb': round(psutil.virtual_memory().used / (1024**3), 1),
'ram_total_gb': round(psutil.virtual_memory().total / (1024**3), 1),
'disk_percent': round(psutil.disk_usage('C:\\').percent, 1),
'cpu_temp': cpu_temp,
'gpu_temp': gpu_temp,
'fan_speed': fan_speed, # Can be pump, case fan, CPU fan, etc.
'status': 'online'
}
return stats
def send_stats(sock, stats):
"""Send stats to ESP32 via UDP"""
try:
message = json.dumps(stats).encode('utf-8')
sock.sendto(message, (ESP32_IP, UDP_PORT))
print(f"[{stats['timestamp']}] CPU {stats['cpu_percent']}% | RAM {stats['ram_percent']}% | Fan {stats['fan_speed'] or 'N/A'} RPM")
except Exception as e:
print(f"Error: {e}")
def main():
"""Main loop"""
print("=" * 60)
print("PC Stats Monitor - Ultra Optimized")
print("=" * 60)
print(f"ESP32: {ESP32_IP}:{UDP_PORT}")
print(f"Update: Every {BROADCAST_INTERVAL}s")
print("-" * 60)
if not initialize_sensors():
print("⚠ Sensor initialization failed")
input("Press Enter to exit...")
return
print("-" * 60)
print("Monitoring... (Ctrl+C to stop)")
print("-" * 60)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Initial CPU reading to warm up psutil
psutil.cpu_percent(interval=1)
try:
while True:
stats = get_system_stats()
send_stats(sock, stats)
time.sleep(BROADCAST_INTERVAL)
except KeyboardInterrupt:
print("\n\nStopped.")
finally:
sock.close()
if __name__ == "__main__":
main()