Search code examples
pythonpython-3.xoperating-systemwmipsutil

Monitor CPU temperature in python on windows11


I have wrote a code to monitor ram memory usage, CPU memory usage, and CPU temperature I have used both psutil and WMI and I'm some kind of problem the code ran perfectly when I had windows 10 I updated to window 11 it is not working. I have checked python interpreter it is on 3.10

I get this my output/error message:

C:\Users\jeries\PycharmProjects\PP1\venv\Scripts\python.exe C:/Users/jeries/PycharmProjects/PP1/study.py
The CPU usage is:  47.1
RAM memory % used: 54.0
Traceback (most recent call last):
  File "C:\Users\jeries\PycharmProjects\PP1\venv\lib\site-packages\wmi.py", line 880, in query
    return self._namespace.query(wql, self, fields)
  File "C:\Users\jeries\PycharmProjects\PP1\venv\lib\site-packages\wmi.py", line 1072, in query
    return [ _wmi_object(obj, instance_of, fields) for obj in self._raw_query(wql) ]
  File "C:\Users\jeries\PycharmProjects\PP1\venv\lib\site-packages\wmi.py", line 1072, in <listcomp>
    return [ _wmi_object(obj, instance_of, fields) for obj in self._raw_query(wql) ]
  File "C:\Users\jeries\PycharmProjects\PP1\venv\lib\site-packages\win32com\client\dynamic.py", line 324, in __getitem__
    return self._get_good_object_(self._enum_.__getitem__(index))
  File "C:\Users\jeries\PycharmProjects\PP1\venv\lib\site-packages\win32com\client\util.py", line 41, in __getitem__
    return self.__GetIndex(index)
  File "C:\Users\jeries\PycharmProjects\PP1\venv\lib\site-packages\win32com\client\util.py", line 62, in __GetIndex
    result = self._oleobj_.Next(1)
pywintypes.com_error: (-2147217372, 'OLE error 0x80041024', None, None)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\jeries\PycharmProjects\PP1\study.py", line 30, in <module>
    temperature_infos = w.Sensor()
  File "C:\Users\jeries\PycharmProjects\PP1\venv\lib\site-packages\wmi.py", line 882, in query
    handle_com_error()
  File "C:\Users\jeries\PycharmProjects\PP1\venv\lib\site-packages\wmi.py", line 258, in handle_com_error
    raise klass(com_error=err)
wmi.x_wmi: <x_wmi: Unexpected COM Error (-2147217372, 'OLE error 0x80041024', None, None)>

Process finished with exit code 1
 

I have tried this:

w = wmi.WMI(namespace="root\openHardwareMonitor")
temperature_infos = w.Sensor()
for sensor in temperature_infos:
    if sensor.SensorType == u'Temperature':
        print(sensor.Name)
        print(sensor.Value)

not working it says that the w.Senosor() "no documentation found"

this is my current code:

import os
import psutil
import wmi


def avg(value_list):
    num = 0
    length = len(value_list)
    for val in value_list:
        num += val
    return num / length


# Calling psutil.cpu_precent() after 2 seconds
print('The CPU usage is: ', psutil.cpu_percent(2))

print('RAM memory % used:', psutil.virtual_memory()[2])
# have the open hardware monitor opened
w = wmi.WMI(namespace="root\\OpenHardwareMonitor")
sensors = w.Sensor()
cpu_temps = []
gpu_temp = 0
for sensor in sensors:
    if sensor.SensorType == u'Temperature' and not 'GPU' in sensor.Name:
        cpu_temps += [float(sensor.Value)]
    elif sensor.SensorType == u'Temperature' and 'GPU' in sensor.Name:
        gpu_temp = sensor.Value



print("Avg CPU: {}".format(avg(cpu_temps)))
print("GPU: {}".format(gpu_temp))

Solution

  • OpenHardwareMonitor can generate logs (options/log Sensors)

    The log is called OpenHardwareMonitorLog-YYYY-MM-DD.csv

    The idea is therefore to launch OpenHardwareMonitor beforehand (possible to execute via scheduled task + subprocess, or in automatic execution at startup), and to retrieve the correct column in the last line of the file:

    #Code
    from datetime import date
    while 1 == 1:
    
        #Génère le nom du log
        now = date.today()
        infile = r"C:\OpenHardwareMonitor\OpenHardwareMonitorLog-" + now.strftime("%Y-%m-%d") + ".csv"
        
        #Ouvre en lecture seule
        with open(infile, "r") as f:
    
            f = f.readlines()[-1]    #Lis la dernière ligne
            output = f.split(',')    # Sépare via les ","
            print(output[10])        # 10 = Colonne T°CPU Core #1
    

    edit:

    You will have to find your column number by looking at the log, it's 10 for me, but it must be able to change depending on your config...

    I'm just starting, the script should be able to be improved by scanning the first 2 lines and determining the correct column with its name ;-)