Skip to content

Commit ac11278

Browse files
committed
Merge remote-tracking branch 'origin/main' into fix/473-gpu-and-fps-fan-error
2 parents 335a4d5 + 2a25630 commit ac11278

9 files changed

+251
-47
lines changed

Diff for: library/sensors/sensors.py

+5
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ def fps() -> int:
6666
def fan_percent() -> float:
6767
pass
6868

69+
@staticmethod
70+
@abstractmethod
71+
def frequency() -> float:
72+
pass
73+
6974
@staticmethod
7075
@abstractmethod
7176
def is_available() -> bool:

Diff for: library/sensors/sensors_librehardwaremonitor.py

+22-1
Original file line numberDiff line numberDiff line change
@@ -323,13 +323,34 @@ def fan_percent(cls) -> float:
323323
try:
324324
for sensor in gpu_to_use.Sensors:
325325
if sensor.SensorType == Hardware.SensorType.Control:
326-
return float(sensor.Value)
326+
if sensor.Value:
327+
return float(sensor.Value)
327328
except:
328329
pass
329330

330331
# No Fan Speed sensor for this GPU model
331332
return math.nan
332333

334+
@classmethod
335+
def frequency(cls) -> float:
336+
gpu_to_use = cls.get_gpu_to_use()
337+
if gpu_to_use is None:
338+
# GPU not supported
339+
return math.nan
340+
341+
try:
342+
for sensor in gpu_to_use.Sensors:
343+
if sensor.SensorType == Hardware.SensorType.Clock:
344+
# Keep only real core clocks, ignore effective core clocks
345+
if "Core" in str(sensor.Name) and "Effective" not in str(sensor.Name):
346+
if sensor.Value:
347+
return float(sensor.Value)
348+
except:
349+
pass
350+
351+
# No Frequency sensor for this GPU model
352+
return math.nan
353+
333354
@classmethod
334355
def is_available(cls) -> bool:
335356
cls.gpu_name = get_gpu_name()

Diff for: library/sensors/sensors_python.py

+40-18
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,16 @@ def fan_percent() -> float:
193193
else:
194194
return math.nan
195195

196+
@staticmethod
197+
def frequency() -> float:
198+
global DETECTED_GPU
199+
if DETECTED_GPU == GpuType.AMD:
200+
return GpuAmd.frequency()
201+
elif DETECTED_GPU == GpuType.NVIDIA:
202+
return GpuNvidia.frequency()
203+
else:
204+
return math.nan
205+
196206
@staticmethod
197207
def is_available() -> bool:
198208
global DETECTED_GPU
@@ -264,6 +274,11 @@ def fan_percent() -> float:
264274

265275
return math.nan
266276

277+
@staticmethod
278+
def frequency() -> float:
279+
# Not supported by Python libraries
280+
return math.nan
281+
267282
@staticmethod
268283
def is_available() -> bool:
269284
try:
@@ -277,52 +292,43 @@ class GpuAmd(sensors.Gpu):
277292
def stats() -> Tuple[float, float, float, float]: # load (%) / used mem (%) / used mem (Mb) / temp (°C)
278293
if pyamdgpuinfo:
279294
# Unlike other sensors, AMD GPU with pyamdgpuinfo pulls in all the stats at once
280-
i = 0
281-
amd_gpus = []
282-
while i < pyamdgpuinfo.detect_gpus():
283-
amd_gpus.append(pyamdgpuinfo.get_gpu(i))
284-
i = i + 1
295+
pyamdgpuinfo.detect_gpus()
296+
amd_gpu = pyamdgpuinfo.get_gpu(0)
285297

286298
try:
287-
memory_used_all = [item.query_vram_usage() for item in amd_gpus]
288-
memory_used_bytes = sum(memory_used_all) / len(memory_used_all)
299+
memory_used_bytes = amd_gpu.query_vram_usage()
289300
memory_used = memory_used_bytes / 1000000
290301
except:
291302
memory_used_bytes = math.nan
292303
memory_used = math.nan
293304

294305
try:
295-
memory_total_all = [item.memory_info["vram_size"] for item in amd_gpus]
296-
memory_total_bytes = sum(memory_total_all) / len(memory_total_all)
306+
memory_total_bytes = amd_gpu.memory_info["vram_size"]
297307
memory_percentage = (memory_used_bytes / memory_total_bytes) * 100
298308
except:
299309
memory_percentage = math.nan
300310

301311
try:
302-
load_all = [item.query_load() for item in amd_gpus]
303-
load = (sum(load_all) / len(load_all)) * 100
312+
load = amd_gpu.query_load()
304313
except:
305314
load = math.nan
306315

307316
try:
308-
temperature_all = [item.query_temperature() for item in amd_gpus]
309-
temperature = sum(temperature_all) / len(temperature_all)
317+
temperature = amd_gpu.query_temperature()
310318
except:
311319
temperature = math.nan
312320

313321
return load, memory_percentage, memory_used, temperature
314322
elif pyadl:
315-
amd_gpus = pyadl.ADLManager.getInstance().getDevices()
323+
amd_gpu = pyadl.ADLManager.getInstance().getDevices()[0]
316324

317325
try:
318-
load_all = [item.getCurrentUsage() for item in amd_gpus]
319-
load = (sum(load_all) / len(load_all))
326+
load = amd_gpu.getCurrentUsage()
320327
except:
321328
load = math.nan
322329

323330
try:
324-
temperature_all = [item.getCurrentTemperature() for item in amd_gpus]
325-
temperature = sum(temperature_all) / len(temperature_all)
331+
temperature = amd_gpu.getCurrentTemperature()
326332
except:
327333
temperature = math.nan
328334

@@ -337,17 +343,33 @@ def fps() -> int:
337343
@staticmethod
338344
def fan_percent() -> float:
339345
try:
346+
# Try with psutil fans
340347
fans = sensors_fans()
341348
if fans:
342349
for name, entries in fans.items():
343350
for entry in entries:
344351
if "gpu" in (entry.label or name):
345352
return entry.current
353+
354+
# Try with pyadl if psutil did not find GPU fan
355+
if pyadl:
356+
return pyadl.ADLManager.getInstance().getDevices()[0].getCurrentFanSpeed(
357+
pyadl.ADL_DEVICE_FAN_SPEED_TYPE_PERCENTAGE)
346358
except:
347359
pass
348360

349361
return math.nan
350362

363+
@staticmethod
364+
def frequency() -> float:
365+
if pyamdgpuinfo:
366+
pyamdgpuinfo.detect_gpus()
367+
return pyamdgpuinfo.get_gpu(0).query_sclk() / 1000000
368+
elif pyadl:
369+
return pyadl.ADLManager.getInstance().getDevices()[0].getCurrentEngineClock()
370+
else:
371+
return math.nan
372+
351373
@staticmethod
352374
def is_available() -> bool:
353375
try:

Diff for: library/sensors/sensors_stub_random.py

+4
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ def fps() -> int:
6060
def fan_percent() -> float:
6161
return random.uniform(0, 100)
6262

63+
@staticmethod
64+
def frequency() -> float:
65+
return random.uniform(800, 3400)
66+
6367
@staticmethod
6468
def is_available() -> bool:
6569
return True

Diff for: library/sensors/sensors_stub_static.py

+5
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
GPU_MEM_TOTAL_SIZE_GB = 32
3636
NETWORK_SPEED_BYTES = 1061000000
3737
GPU_FPS = 120
38+
GPU_FREQ_MHZ = 1500.0
3839

3940

4041
class Cpu(sensors.Cpu):
@@ -73,6 +74,10 @@ def fps() -> int:
7374
def fan_percent() -> float:
7475
return PERCENTAGE_SENSOR_VALUE
7576

77+
@staticmethod
78+
def frequency() -> float:
79+
return GPU_FREQ_MHZ
80+
7681
@staticmethod
7782
def is_available() -> bool:
7883
return True

Diff for: library/stats.py

+41-2
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ class CPU:
241241
last_values_cpu_percentage = []
242242
last_values_cpu_temperature = []
243243
last_values_cpu_fan_speed = []
244+
last_values_cpu_frequency = []
244245

245246
@classmethod
246247
def percentage(cls):
@@ -259,12 +260,26 @@ def percentage(cls):
259260

260261
@classmethod
261262
def frequency(cls):
263+
freq_ghz = sensors.Cpu.frequency() / 1000
264+
theme_data = config.THEME_DATA['STATS']['CPU']['FREQUENCY']
265+
266+
save_last_value(freq_ghz, cls.last_values_cpu_frequency,
267+
theme_data['LINE_GRAPH'].get("HISTORY_SIZE", DEFAULT_HISTORY_SIZE))
268+
262269
display_themed_value(
263-
theme_data=config.THEME_DATA['STATS']['CPU']['FREQUENCY']['TEXT'],
264-
value=f'{sensors.Cpu.frequency() / 1000:.2f}',
270+
theme_data=theme_data['TEXT'],
271+
value=f'{freq_ghz:.2f}',
272+
unit=" GHz",
273+
min_size=4
274+
)
275+
display_themed_progress_bar(theme_data['GRAPH'], freq_ghz)
276+
display_themed_radial_bar(
277+
theme_data=theme_data['RADIAL'],
278+
value=f'{freq_ghz:.2f}',
265279
unit=" GHz",
266280
min_size=4
267281
)
282+
display_themed_line_graph(theme_data['LINE_GRAPH'], cls.last_values_cpu_frequency)
268283

269284
@classmethod
270285
def load(cls):
@@ -344,12 +359,14 @@ class Gpu:
344359
last_values_gpu_temperature = []
345360
last_values_gpu_fps = []
346361
last_values_gpu_fan_speed = []
362+
last_values_gpu_frequency = []
347363

348364
@classmethod
349365
def stats(cls):
350366
load, memory_percentage, memory_used_mb, temperature = sensors.Gpu.stats()
351367
fps = sensors.Gpu.fps()
352368
fan_percent = sensors.Gpu.fan_percent()
369+
freq_ghz = sensors.Gpu.frequency() / 1000
353370

354371
theme_gpu_data = config.THEME_DATA['STATS']['GPU']
355372

@@ -363,6 +380,8 @@ def stats(cls):
363380
theme_gpu_data['FPS']['LINE_GRAPH'].get("HISTORY_SIZE", DEFAULT_HISTORY_SIZE))
364381
save_last_value(fan_percent, cls.last_values_gpu_fan_speed,
365382
theme_gpu_data['FAN_SPEED']['LINE_GRAPH'].get("HISTORY_SIZE", DEFAULT_HISTORY_SIZE))
383+
save_last_value(freq_ghz, cls.last_values_gpu_frequency,
384+
theme_gpu_data['FREQUENCY']['LINE_GRAPH'].get("HISTORY_SIZE", DEFAULT_HISTORY_SIZE))
366385

367386
################################ for backward compatibility only
368387
gpu_mem_graph_data = theme_gpu_data['MEMORY']['GRAPH']
@@ -520,6 +539,26 @@ def stats(cls):
520539
display_themed_percent_radial_bar(gpu_fan_radial_data, fan_percent)
521540
display_themed_line_graph(gpu_fan_line_graph_data, cls.last_values_gpu_fan_speed)
522541

542+
# GPU Frequency (Ghz)
543+
gpu_freq_text_data = theme_gpu_data['FREQUENCY']['TEXT']
544+
gpu_freq_radial_data = theme_gpu_data['FREQUENCY']['RADIAL']
545+
gpu_freq_graph_data = theme_gpu_data['FREQUENCY']['GRAPH']
546+
gpu_freq_line_graph_data = theme_gpu_data['FREQUENCY']['LINE_GRAPH']
547+
display_themed_value(
548+
theme_data=gpu_freq_text_data,
549+
value=f'{freq_ghz:.2f}',
550+
unit=" GHz",
551+
min_size=4
552+
)
553+
display_themed_progress_bar(gpu_freq_graph_data, freq_ghz)
554+
display_themed_radial_bar(
555+
theme_data=gpu_freq_radial_data,
556+
value=f'{freq_ghz:.2f}',
557+
unit=" GHz",
558+
min_size=4
559+
)
560+
display_themed_line_graph(gpu_freq_line_graph_data, cls.last_values_gpu_frequency)
561+
523562
@staticmethod
524563
def is_available():
525564
return sensors.Gpu.is_available()

Diff for: res/themes/Cyberdeck/theme.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ STATS:
185185
FPS:
186186
TEXT:
187187
SHOW: True
188+
SHOW_UNIT: False
188189
X: 46
189190
Y: 279
190191
MIN_SIZE: 4

0 commit comments

Comments
 (0)