Skip to content

Commit 1f5abca

Browse files
committed
Add LHM robustness for sensors None values
1 parent 20ef2d3 commit 1f5abca

File tree

1 file changed

+64
-58
lines changed

1 file changed

+64
-58
lines changed

library/sensors/sensors_librehardwaremonitor.py

Lines changed: 64 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ class Cpu(sensors.Cpu):
176176
def percentage(interval: float) -> float:
177177
cpu = get_hw_and_update(Hardware.HardwareType.Cpu)
178178
for sensor in cpu.Sensors:
179-
if sensor.SensorType == Hardware.SensorType.Load and str(sensor.Name).startswith("CPU Total"):
179+
if sensor.SensorType == Hardware.SensorType.Load and str(sensor.Name).startswith("CPU Total") and sensor.Value is not None:
180180
return float(sensor.Value)
181181

182182
logger.error("CPU load cannot be read")
@@ -186,19 +186,21 @@ def percentage(interval: float) -> float:
186186
def frequency() -> float:
187187
frequencies = []
188188
cpu = get_hw_and_update(Hardware.HardwareType.Cpu)
189-
for sensor in cpu.Sensors:
190-
if sensor.SensorType == Hardware.SensorType.Clock:
191-
# Keep only real core clocks, ignore effective core clocks
192-
if "Core #" in str(sensor.Name) and "Effective" not in str(sensor.Name):
193-
if sensor.Value:
189+
try:
190+
for sensor in cpu.Sensors:
191+
if sensor.SensorType == Hardware.SensorType.Clock:
192+
# Keep only real core clocks, ignore effective core clocks
193+
if "Core #" in str(sensor.Name) and "Effective" not in str(sensor.Name) and sensor.Value is not None:
194194
frequencies.append(float(sensor.Value))
195195

196-
if frequencies:
197-
# Take mean of all core clock as "CPU clock" (as it is done in Windows Task Manager Performance tab)
198-
return mean(frequencies)
199-
else:
200-
# Frequencies reading is not supported on this CPU
201-
return math.nan
196+
if frequencies:
197+
# Take mean of all core clock as "CPU clock" (as it is done in Windows Task Manager Performance tab)
198+
return mean(frequencies)
199+
except:
200+
pass
201+
202+
# Frequencies reading is not supported on this CPU
203+
return math.nan
202204

203205
@staticmethod
204206
def load() -> Tuple[float, float, float]: # 1 / 5 / 15min avg (%):
@@ -208,22 +210,25 @@ def load() -> Tuple[float, float, float]: # 1 / 5 / 15min avg (%):
208210
@staticmethod
209211
def temperature() -> float:
210212
cpu = get_hw_and_update(Hardware.HardwareType.Cpu)
211-
# By default, the average temperature of all CPU cores will be used
212-
for sensor in cpu.Sensors:
213-
if sensor.SensorType == Hardware.SensorType.Temperature and str(sensor.Name).startswith("Core Average"):
214-
return float(sensor.Value)
215-
# If not available, the max core temperature will be used
216-
for sensor in cpu.Sensors:
217-
if sensor.SensorType == Hardware.SensorType.Temperature and str(sensor.Name).startswith("Core Max"):
218-
return float(sensor.Value)
219-
# If not available, the CPU Package temperature (usually same as max core temperature) will be used
220-
for sensor in cpu.Sensors:
221-
if sensor.SensorType == Hardware.SensorType.Temperature and str(sensor.Name).startswith("CPU Package"):
222-
return float(sensor.Value)
223-
# Otherwise any sensor named "Core..." will be used
224-
for sensor in cpu.Sensors:
225-
if sensor.SensorType == Hardware.SensorType.Temperature and str(sensor.Name).startswith("Core"):
226-
return float(sensor.Value)
213+
try:
214+
# By default, the average temperature of all CPU cores will be used
215+
for sensor in cpu.Sensors:
216+
if sensor.SensorType == Hardware.SensorType.Temperature and str(sensor.Name).startswith("Core Average") and sensor.Value is not None:
217+
return float(sensor.Value)
218+
# If not available, the max core temperature will be used
219+
for sensor in cpu.Sensors:
220+
if sensor.SensorType == Hardware.SensorType.Temperature and str(sensor.Name).startswith("Core Max") and sensor.Value is not None:
221+
return float(sensor.Value)
222+
# If not available, the CPU Package temperature (usually same as max core temperature) will be used
223+
for sensor in cpu.Sensors:
224+
if sensor.SensorType == Hardware.SensorType.Temperature and str(sensor.Name).startswith("CPU Package") and sensor.Value is not None:
225+
return float(sensor.Value)
226+
# Otherwise any sensor named "Core..." will be used
227+
for sensor in cpu.Sensors:
228+
if sensor.SensorType == Hardware.SensorType.Temperature and str(sensor.Name).startswith("Core") and sensor.Value is not None:
229+
return float(sensor.Value)
230+
except:
231+
pass
227232

228233
return math.nan
229234

@@ -235,7 +240,7 @@ def fan_percent() -> float:
235240
sh.Update()
236241
for sensor in sh.Sensors:
237242
if sensor.SensorType == Hardware.SensorType.Control and "#2" in str(
238-
sensor.Name): # Is Motherboard #2 Fan always the CPU Fan ?
243+
sensor.Name) and sensor.Value is not None: # Is Motherboard #2 Fan always the CPU Fan ?
239244
return float(sensor.Value)
240245
except:
241246
pass
@@ -275,23 +280,23 @@ def stats(cls) -> Tuple[float, float, float, float]: # load (%) / used mem (%)
275280
temp = math.nan
276281

277282
for sensor in gpu_to_use.Sensors:
278-
if sensor.SensorType == Hardware.SensorType.Load and str(sensor.Name).startswith("GPU Core"):
283+
if sensor.SensorType == Hardware.SensorType.Load and str(sensor.Name).startswith("GPU Core") and sensor.Value is not None:
279284
load = float(sensor.Value)
280285
elif sensor.SensorType == Hardware.SensorType.Load and str(sensor.Name).startswith("D3D 3D") and math.isnan(
281-
load):
286+
load) and sensor.Value is not None:
282287
# Only use D3D usage if global "GPU Core" sensor is not available, because it is less
283288
# precise and does not cover the entire GPU: https://www.hwinfo.com/forum/threads/what-is-d3d-usage.759/
284289
load = float(sensor.Value)
285-
elif sensor.SensorType == Hardware.SensorType.SmallData and str(sensor.Name).startswith("GPU Memory Used"):
290+
elif sensor.SensorType == Hardware.SensorType.SmallData and str(sensor.Name).startswith("GPU Memory Used") and sensor.Value is not None:
286291
used_mem = float(sensor.Value)
287292
elif sensor.SensorType == Hardware.SensorType.SmallData and str(sensor.Name).startswith(
288-
"D3D") and str(sensor.Name).endswith("Memory Used") and math.isnan(used_mem):
293+
"D3D") and str(sensor.Name).endswith("Memory Used") and math.isnan(used_mem) and sensor.Value is not None:
289294
# Only use D3D memory usage if global "GPU Memory Used" sensor is not available, because it is less
290295
# precise and does not cover the entire GPU: https://www.hwinfo.com/forum/threads/what-is-d3d-usage.759/
291296
used_mem = float(sensor.Value)
292-
elif sensor.SensorType == Hardware.SensorType.SmallData and str(sensor.Name).startswith("GPU Memory Total"):
297+
elif sensor.SensorType == Hardware.SensorType.SmallData and str(sensor.Name).startswith("GPU Memory Total") and sensor.Value is not None:
293298
total_mem = float(sensor.Value)
294-
elif sensor.SensorType == Hardware.SensorType.Temperature and str(sensor.Name).startswith("GPU Core"):
299+
elif sensor.SensorType == Hardware.SensorType.Temperature and str(sensor.Name).startswith("GPU Core") and sensor.Value is not None:
295300
temp = float(sensor.Value)
296301

297302
return load, (used_mem / total_mem * 100.0), used_mem, temp
@@ -303,12 +308,15 @@ def fps(cls) -> int:
303308
# GPU not supported
304309
return -1
305310

306-
for sensor in gpu_to_use.Sensors:
307-
if sensor.SensorType == Hardware.SensorType.Factor and "FPS" in str(sensor.Name):
308-
# If a reading returns a value <= 0, returns old value instead
309-
if int(sensor.Value) > 0:
310-
cls.prev_fps = int(sensor.Value)
311-
return cls.prev_fps
311+
try:
312+
for sensor in gpu_to_use.Sensors:
313+
if sensor.SensorType == Hardware.SensorType.Factor and "FPS" in str(sensor.Name) and sensor.Value is not None:
314+
# If a reading returns a value <= 0, returns old value instead
315+
if int(sensor.Value) > 0:
316+
cls.prev_fps = int(sensor.Value)
317+
return cls.prev_fps
318+
except:
319+
pass
312320

313321
# No FPS sensor for this GPU model
314322
return -1
@@ -322,9 +330,8 @@ def fan_percent(cls) -> float:
322330

323331
try:
324332
for sensor in gpu_to_use.Sensors:
325-
if sensor.SensorType == Hardware.SensorType.Control:
326-
if sensor.Value:
327-
return float(sensor.Value)
333+
if sensor.SensorType == Hardware.SensorType.Control and sensor.Value is not None:
334+
return float(sensor.Value)
328335
except:
329336
pass
330337

@@ -342,9 +349,8 @@ def frequency(cls) -> float:
342349
for sensor in gpu_to_use.Sensors:
343350
if sensor.SensorType == Hardware.SensorType.Clock:
344351
# 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)
352+
if "Core" in str(sensor.Name) and "Effective" not in str(sensor.Name) and sensor.Value is not None:
353+
return float(sensor.Value)
348354
except:
349355
pass
350356

@@ -369,14 +375,14 @@ def swap_percent() -> float:
369375

370376
# Get virtual / physical memory stats
371377
for sensor in memory.Sensors:
372-
if sensor.SensorType == Hardware.SensorType.Data and str(sensor.Name).startswith("Virtual Memory Used"):
378+
if sensor.SensorType == Hardware.SensorType.Data and str(sensor.Name).startswith("Virtual Memory Used") and sensor.Value is not None:
373379
virtual_mem_used = int(sensor.Value)
374-
elif sensor.SensorType == Hardware.SensorType.Data and str(sensor.Name).startswith("Memory Used"):
380+
elif sensor.SensorType == Hardware.SensorType.Data and str(sensor.Name).startswith("Memory Used") and sensor.Value is not None:
375381
mem_used = int(sensor.Value)
376382
elif sensor.SensorType == Hardware.SensorType.Data and str(sensor.Name).startswith(
377-
"Virtual Memory Available"):
383+
"Virtual Memory Available") and sensor.Value is not None:
378384
virtual_mem_available = int(sensor.Value)
379-
elif sensor.SensorType == Hardware.SensorType.Data and str(sensor.Name).startswith("Memory Available"):
385+
elif sensor.SensorType == Hardware.SensorType.Data and str(sensor.Name).startswith("Memory Available") and sensor.Value is not None:
380386
mem_available = int(sensor.Value)
381387

382388
# Compute swap stats from virtual / physical memory stats
@@ -395,7 +401,7 @@ def swap_percent() -> float:
395401
def virtual_percent() -> float:
396402
memory = get_hw_and_update(Hardware.HardwareType.Memory)
397403
for sensor in memory.Sensors:
398-
if sensor.SensorType == Hardware.SensorType.Load and str(sensor.Name).startswith("Memory"):
404+
if sensor.SensorType == Hardware.SensorType.Load and str(sensor.Name).startswith("Memory") and sensor.Value is not None:
399405
return float(sensor.Value)
400406

401407
return math.nan
@@ -404,7 +410,7 @@ def virtual_percent() -> float:
404410
def virtual_used() -> int: # In bytes
405411
memory = get_hw_and_update(Hardware.HardwareType.Memory)
406412
for sensor in memory.Sensors:
407-
if sensor.SensorType == Hardware.SensorType.Data and str(sensor.Name).startswith("Memory Used"):
413+
if sensor.SensorType == Hardware.SensorType.Data and str(sensor.Name).startswith("Memory Used") and sensor.Value is not None:
408414
return int(sensor.Value * 1000000000.0)
409415

410416
return 0
@@ -413,7 +419,7 @@ def virtual_used() -> int: # In bytes
413419
def virtual_free() -> int: # In bytes
414420
memory = get_hw_and_update(Hardware.HardwareType.Memory)
415421
for sensor in memory.Sensors:
416-
if sensor.SensorType == Hardware.SensorType.Data and str(sensor.Name).startswith("Memory Available"):
422+
if sensor.SensorType == Hardware.SensorType.Data and str(sensor.Name).startswith("Memory Available") and sensor.Value is not None:
417423
return int(sensor.Value * 1000000000.0)
418424

419425
return 0
@@ -449,16 +455,16 @@ def stats(if_name, interval) -> Tuple[
449455
net_if = get_net_interface_and_update(if_name)
450456
if net_if is not None:
451457
for sensor in net_if.Sensors:
452-
if sensor.SensorType == Hardware.SensorType.Data and str(sensor.Name).startswith("Data Uploaded"):
458+
if sensor.SensorType == Hardware.SensorType.Data and str(sensor.Name).startswith("Data Uploaded") and sensor.Value is not None:
453459
uploaded = int(sensor.Value * 1000000000.0)
454460
elif sensor.SensorType == Hardware.SensorType.Data and str(sensor.Name).startswith(
455-
"Data Downloaded"):
461+
"Data Downloaded") and sensor.Value is not None:
456462
downloaded = int(sensor.Value * 1000000000.0)
457463
elif sensor.SensorType == Hardware.SensorType.Throughput and str(sensor.Name).startswith(
458-
"Upload Speed"):
464+
"Upload Speed") and sensor.Value is not None:
459465
upload_rate = int(sensor.Value)
460466
elif sensor.SensorType == Hardware.SensorType.Throughput and str(sensor.Name).startswith(
461-
"Download Speed"):
467+
"Download Speed") and sensor.Value is not None:
462468
download_rate = int(sensor.Value)
463469

464470
return upload_rate, uploaded, download_rate, downloaded

0 commit comments

Comments
 (0)