@@ -176,7 +176,8 @@ 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 (
180+ "CPU Total" ) and sensor .Value is not None :
180181 return float (sensor .Value )
181182
182183 logger .error ("CPU load cannot be read" )
@@ -186,19 +187,22 @@ def percentage(interval: float) -> float:
186187 def frequency () -> float :
187188 frequencies = []
188189 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 :
190+ try :
191+ for sensor in cpu .Sensors :
192+ if sensor .SensorType == Hardware .SensorType .Clock :
193+ # Keep only real core clocks, ignore effective core clocks
194+ if "Core #" in str (sensor .Name ) and "Effective" not in str (
195+ sensor .Name ) and sensor .Value is not None :
194196 frequencies .append (float (sensor .Value ))
195197
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
198+ if frequencies :
199+ # Take mean of all core clock as "CPU clock" (as it is done in Windows Task Manager Performance tab)
200+ return mean (frequencies )
201+ except :
202+ pass
203+
204+ # Frequencies reading is not supported on this CPU
205+ return math .nan
202206
203207 @staticmethod
204208 def load () -> Tuple [float , float , float ]: # 1 / 5 / 15min avg (%):
@@ -208,22 +212,29 @@ def load() -> Tuple[float, float, float]: # 1 / 5 / 15min avg (%):
208212 @staticmethod
209213 def temperature () -> float :
210214 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 )
215+ try :
216+ # By default, the average temperature of all CPU cores will be used
217+ for sensor in cpu .Sensors :
218+ if sensor .SensorType == Hardware .SensorType .Temperature and str (sensor .Name ).startswith (
219+ "Core Average" ) and sensor .Value is not None :
220+ return float (sensor .Value )
221+ # If not available, the max core temperature will be used
222+ for sensor in cpu .Sensors :
223+ if sensor .SensorType == Hardware .SensorType .Temperature and str (sensor .Name ).startswith (
224+ "Core Max" ) and sensor .Value is not None :
225+ return float (sensor .Value )
226+ # If not available, the CPU Package temperature (usually same as max core temperature) will be used
227+ for sensor in cpu .Sensors :
228+ if sensor .SensorType == Hardware .SensorType .Temperature and str (sensor .Name ).startswith (
229+ "CPU Package" ) and sensor .Value is not None :
230+ return float (sensor .Value )
231+ # Otherwise any sensor named "Core..." will be used
232+ for sensor in cpu .Sensors :
233+ if sensor .SensorType == Hardware .SensorType .Temperature and str (sensor .Name ).startswith (
234+ "Core" ) and sensor .Value is not None :
235+ return float (sensor .Value )
236+ except :
237+ pass
227238
228239 return math .nan
229240
@@ -235,7 +246,7 @@ def fan_percent() -> float:
235246 sh .Update ()
236247 for sensor in sh .Sensors :
237248 if sensor .SensorType == Hardware .SensorType .Control and "#2" in str (
238- sensor .Name ): # Is Motherboard #2 Fan always the CPU Fan ?
249+ sensor .Name ) and sensor . Value is not None : # Is Motherboard #2 Fan always the CPU Fan ?
239250 return float (sensor .Value )
240251 except :
241252 pass
@@ -275,23 +286,28 @@ def stats(cls) -> Tuple[float, float, float, float]: # load (%) / used mem (%)
275286 temp = math .nan
276287
277288 for sensor in gpu_to_use .Sensors :
278- if sensor .SensorType == Hardware .SensorType .Load and str (sensor .Name ).startswith ("GPU Core" ):
289+ if sensor .SensorType == Hardware .SensorType .Load and str (sensor .Name ).startswith (
290+ "GPU Core" ) and sensor .Value is not None :
279291 load = float (sensor .Value )
280292 elif sensor .SensorType == Hardware .SensorType .Load and str (sensor .Name ).startswith ("D3D 3D" ) and math .isnan (
281- load ):
293+ load ) and sensor . Value is not None :
282294 # Only use D3D usage if global "GPU Core" sensor is not available, because it is less
283295 # precise and does not cover the entire GPU: https://www.hwinfo.com/forum/threads/what-is-d3d-usage.759/
284296 load = float (sensor .Value )
285- elif sensor .SensorType == Hardware .SensorType .SmallData and str (sensor .Name ).startswith ("GPU Memory Used" ):
297+ elif sensor .SensorType == Hardware .SensorType .SmallData and str (sensor .Name ).startswith (
298+ "GPU Memory Used" ) and sensor .Value is not None :
286299 used_mem = float (sensor .Value )
287300 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 ):
301+ "D3D" ) and str (sensor .Name ).endswith ("Memory Used" ) and math .isnan (
302+ used_mem ) and sensor .Value is not None :
289303 # Only use D3D memory usage if global "GPU Memory Used" sensor is not available, because it is less
290304 # precise and does not cover the entire GPU: https://www.hwinfo.com/forum/threads/what-is-d3d-usage.759/
291305 used_mem = float (sensor .Value )
292- elif sensor .SensorType == Hardware .SensorType .SmallData and str (sensor .Name ).startswith ("GPU Memory Total" ):
306+ elif sensor .SensorType == Hardware .SensorType .SmallData and str (sensor .Name ).startswith (
307+ "GPU Memory Total" ) and sensor .Value is not None :
293308 total_mem = float (sensor .Value )
294- elif sensor .SensorType == Hardware .SensorType .Temperature and str (sensor .Name ).startswith ("GPU Core" ):
309+ elif sensor .SensorType == Hardware .SensorType .Temperature and str (sensor .Name ).startswith (
310+ "GPU Core" ) and sensor .Value is not None :
295311 temp = float (sensor .Value )
296312
297313 return load , (used_mem / total_mem * 100.0 ), used_mem , temp
@@ -303,12 +319,16 @@ def fps(cls) -> int:
303319 # GPU not supported
304320 return - 1
305321
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
322+ try :
323+ for sensor in gpu_to_use .Sensors :
324+ if sensor .SensorType == Hardware .SensorType .Factor and "FPS" in str (
325+ sensor .Name ) and sensor .Value is not None :
326+ # If a reading returns a value <= 0, returns old value instead
327+ if int (sensor .Value ) > 0 :
328+ cls .prev_fps = int (sensor .Value )
329+ return cls .prev_fps
330+ except :
331+ pass
312332
313333 # No FPS sensor for this GPU model
314334 return - 1
@@ -322,9 +342,8 @@ def fan_percent(cls) -> float:
322342
323343 try :
324344 for sensor in gpu_to_use .Sensors :
325- if sensor .SensorType == Hardware .SensorType .Control :
326- if sensor .Value :
327- return float (sensor .Value )
345+ if sensor .SensorType == Hardware .SensorType .Control and sensor .Value is not None :
346+ return float (sensor .Value )
328347 except :
329348 pass
330349
@@ -342,9 +361,8 @@ def frequency(cls) -> float:
342361 for sensor in gpu_to_use .Sensors :
343362 if sensor .SensorType == Hardware .SensorType .Clock :
344363 # 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 )
364+ if "Core" in str (sensor .Name ) and "Effective" not in str (sensor .Name ) and sensor .Value is not None :
365+ return float (sensor .Value )
348366 except :
349367 pass
350368
@@ -369,14 +387,17 @@ def swap_percent() -> float:
369387
370388 # Get virtual / physical memory stats
371389 for sensor in memory .Sensors :
372- if sensor .SensorType == Hardware .SensorType .Data and str (sensor .Name ).startswith ("Virtual Memory Used" ):
390+ if sensor .SensorType == Hardware .SensorType .Data and str (sensor .Name ).startswith (
391+ "Virtual Memory Used" ) and sensor .Value is not None :
373392 virtual_mem_used = int (sensor .Value )
374- elif sensor .SensorType == Hardware .SensorType .Data and str (sensor .Name ).startswith ("Memory Used" ):
393+ elif sensor .SensorType == Hardware .SensorType .Data and str (sensor .Name ).startswith (
394+ "Memory Used" ) and sensor .Value is not None :
375395 mem_used = int (sensor .Value )
376396 elif sensor .SensorType == Hardware .SensorType .Data and str (sensor .Name ).startswith (
377- "Virtual Memory Available" ):
397+ "Virtual Memory Available" ) and sensor . Value is not None :
378398 virtual_mem_available = int (sensor .Value )
379- elif sensor .SensorType == Hardware .SensorType .Data and str (sensor .Name ).startswith ("Memory Available" ):
399+ elif sensor .SensorType == Hardware .SensorType .Data and str (sensor .Name ).startswith (
400+ "Memory Available" ) and sensor .Value is not None :
380401 mem_available = int (sensor .Value )
381402
382403 # Compute swap stats from virtual / physical memory stats
@@ -395,7 +416,8 @@ def swap_percent() -> float:
395416 def virtual_percent () -> float :
396417 memory = get_hw_and_update (Hardware .HardwareType .Memory )
397418 for sensor in memory .Sensors :
398- if sensor .SensorType == Hardware .SensorType .Load and str (sensor .Name ).startswith ("Memory" ):
419+ if sensor .SensorType == Hardware .SensorType .Load and str (sensor .Name ).startswith (
420+ "Memory" ) and sensor .Value is not None :
399421 return float (sensor .Value )
400422
401423 return math .nan
@@ -404,7 +426,8 @@ def virtual_percent() -> float:
404426 def virtual_used () -> int : # In bytes
405427 memory = get_hw_and_update (Hardware .HardwareType .Memory )
406428 for sensor in memory .Sensors :
407- if sensor .SensorType == Hardware .SensorType .Data and str (sensor .Name ).startswith ("Memory Used" ):
429+ if sensor .SensorType == Hardware .SensorType .Data and str (sensor .Name ).startswith (
430+ "Memory Used" ) and sensor .Value is not None :
408431 return int (sensor .Value * 1000000000.0 )
409432
410433 return 0
@@ -413,7 +436,8 @@ def virtual_used() -> int: # In bytes
413436 def virtual_free () -> int : # In bytes
414437 memory = get_hw_and_update (Hardware .HardwareType .Memory )
415438 for sensor in memory .Sensors :
416- if sensor .SensorType == Hardware .SensorType .Data and str (sensor .Name ).startswith ("Memory Available" ):
439+ if sensor .SensorType == Hardware .SensorType .Data and str (sensor .Name ).startswith (
440+ "Memory Available" ) and sensor .Value is not None :
417441 return int (sensor .Value * 1000000000.0 )
418442
419443 return 0
@@ -449,16 +473,17 @@ def stats(if_name, interval) -> Tuple[
449473 net_if = get_net_interface_and_update (if_name )
450474 if net_if is not None :
451475 for sensor in net_if .Sensors :
452- if sensor .SensorType == Hardware .SensorType .Data and str (sensor .Name ).startswith ("Data Uploaded" ):
476+ if sensor .SensorType == Hardware .SensorType .Data and str (sensor .Name ).startswith (
477+ "Data Uploaded" ) and sensor .Value is not None :
453478 uploaded = int (sensor .Value * 1000000000.0 )
454479 elif sensor .SensorType == Hardware .SensorType .Data and str (sensor .Name ).startswith (
455- "Data Downloaded" ):
480+ "Data Downloaded" ) and sensor . Value is not None :
456481 downloaded = int (sensor .Value * 1000000000.0 )
457482 elif sensor .SensorType == Hardware .SensorType .Throughput and str (sensor .Name ).startswith (
458- "Upload Speed" ):
483+ "Upload Speed" ) and sensor . Value is not None :
459484 upload_rate = int (sensor .Value )
460485 elif sensor .SensorType == Hardware .SensorType .Throughput and str (sensor .Name ).startswith (
461- "Download Speed" ):
486+ "Download Speed" ) and sensor . Value is not None :
462487 download_rate = int (sensor .Value )
463488
464489 return upload_rate , uploaded , download_rate , downloaded
0 commit comments