25

我需要一个在 python 中访问 CPU 温度的示例代码。

我正在运行 Windows 7,顺便说一句。

4

7 回答 7

19

使用此处描述的WMI 模块+打开硬件监视器 + 其 WMI 接口

示例代码:

import wmi
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)
于 2015-09-29T09:48:01.930 回答
16

下载http://openhardwaremonitor.org/downloads/http://www.cputhermometer.com/并提取 OpenHardwareMonitorLib.dll 和 CPUThermometerLib.dll 并将它们放在一个目录中。

然后,您可以使用 pythonnet 模块来处理 .dll 并提取这些程序提供的任何统计信息。cputhermometer 提供每核 CPU 温度,openhardwaremonitor 提供其他一切。无需使用要求程序在后台处于活动状态的 WMI。

我编写了一个小脚本(python 3.6.5)来显示系统上可用的每个温度传感器,您当然可以轻松地为其他传感器类型修改它。您必须以管理员身份运行它:

import clr #package pythonnet, not clr


openhardwaremonitor_hwtypes = ['Mainboard','SuperIO','CPU','RAM','GpuNvidia','GpuAti','TBalancer','Heatmaster','HDD']
cputhermometer_hwtypes = ['Mainboard','SuperIO','CPU','GpuNvidia','GpuAti','TBalancer','Heatmaster','HDD']
openhardwaremonitor_sensortypes = ['Voltage','Clock','Temperature','Load','Fan','Flow','Control','Level','Factor','Power','Data','SmallData']
cputhermometer_sensortypes = ['Voltage','Clock','Temperature','Load','Fan','Flow','Control','Level']


def initialize_openhardwaremonitor():
    file = 'OpenHardwareMonitorLib.dll'
    clr.AddReference(file)

    from OpenHardwareMonitor import Hardware

    handle = Hardware.Computer()
    handle.MainboardEnabled = True
    handle.CPUEnabled = True
    handle.RAMEnabled = True
    handle.GPUEnabled = True
    handle.HDDEnabled = True
    handle.Open()
    return handle

def initialize_cputhermometer():
    file = 'CPUThermometerLib.dll'
    clr.AddReference(file)

    from CPUThermometer import Hardware
    handle = Hardware.Computer()
    handle.CPUEnabled = True
    handle.Open()
    return handle

def fetch_stats(handle):
    for i in handle.Hardware:
        i.Update()
        for sensor in i.Sensors:
            parse_sensor(sensor)
        for j in i.SubHardware:
            j.Update()
            for subsensor in j.Sensors:
                parse_sensor(subsensor)


def parse_sensor(sensor):
        if sensor.Value is not None:
            if type(sensor).__module__ == 'CPUThermometer.Hardware':
                sensortypes = cputhermometer_sensortypes
                hardwaretypes = cputhermometer_hwtypes
            elif type(sensor).__module__ == 'OpenHardwareMonitor.Hardware':
                sensortypes = openhardwaremonitor_sensortypes
                hardwaretypes = openhardwaremonitor_hwtypes
            else:
                return

            if sensor.SensorType == sensortypes.index('Temperature'):
                print(u"%s %s Temperature Sensor #%i %s - %s\u00B0C" % (hardwaretypes[sensor.Hardware.HardwareType], sensor.Hardware.Name, sensor.Index, sensor.Name, sensor.Value))

if __name__ == "__main__":
    print("OpenHardwareMonitor:")
    HardwareHandle = initialize_openhardwaremonitor()
    fetch_stats(HardwareHandle)
    print("\nCPUMonitor:")
    CPUHandle = initialize_cputhermometer()
    fetch_stats(CPUHandle)

这是我系统上的输出:

OpenHardwareMonitor:
SuperIO Nuvoton NCT6791D Temperature Sensor #0 CPU Core - 42.0°C
SuperIO Nuvoton NCT6791D Temperature Sensor #1 Temperature #1 - 35.0°C
SuperIO Nuvoton NCT6791D Temperature Sensor #2 Temperature #2 - 34.0°C
SuperIO Nuvoton NCT6791D Temperature Sensor #3 Temperature #3 - 25.0°C
SuperIO Nuvoton NCT6791D Temperature Sensor #4 Temperature #4 - 101.0°C
SuperIO Nuvoton NCT6791D Temperature Sensor #5 Temperature #5 - 16.0°C
SuperIO Nuvoton NCT6791D Temperature Sensor #6 Temperature #6 - 14.0°C
GpuNvidia NVIDIA GeForce GTX 1070 Temperature Sensor #0 GPU Core - 60.0°C
HDD ST31000528AS Temperature Sensor #0 Temperature - 37.0°C
HDD WDC WD20EARX-00PASB0 Temperature Sensor #0 Temperature - 36.0°C
HDD WDC WDS100T2B0B-00YS70 Temperature Sensor #0 Temperature - 40.0°C
HDD WDC WD80EFZX-68UW8N0 Temperature Sensor #0 Temperature - 31.0°C
HDD WDC WD30EFRX-68EUZN0 Temperature Sensor #0 Temperature - 30.0°C
HDD WDC WD80EFZX-68UW8N0 Temperature Sensor #0 Temperature - 33.0°C
HDD Crucial_CT256MX100SSD1 Temperature Sensor #0 Temperature - 40.0°C

CPUMonitor:
CPU Intel Core i7-8700K Temperature Sensor #0 CPU Core #1 - 39.0°C
CPU Intel Core i7-8700K Temperature Sensor #1 CPU Core #2 - 38.0°C
CPU Intel Core i7-8700K Temperature Sensor #2 CPU Core #3 - 37.0°C
CPU Intel Core i7-8700K Temperature Sensor #3 CPU Core #4 - 41.0°C
CPU Intel Core i7-8700K Temperature Sensor #4 CPU Core #5 - 36.0°C
CPU Intel Core i7-8700K Temperature Sensor #5 CPU Core #6 - 47.0°C

更多文档(不过你应该能够从上面的代码中推断出你需要的一切),请参阅https://github.com/openhardwaremonitor/openhardwaremonitor/(或网站上的 cputhermometer)源代码、功能和方法当您将它们与 python 一起使用时,它们是相同的。

我没有在任何其他计算机上对此进行过测试,因此不同的处理器架构可能功能不同。

确保您Hardware[x].Update()在两次测量之间运行(SubHardware[x].Update()如果需要)。

于 2018-04-18T21:30:58.967 回答
6

您可以使用pywin32访问本机 Windows API。如果主板驱动程序的制造商通过他们的驱动程序注册了 WMI 数据提供程序,我相信应该可以查询 Windows API 的 CPU 温度。假设是这种情况,您可以下载 ars 回答中提到的pywin32 扩展Python WMI 模块,然后按以下步骤操作:

import wmi
w = wmi.WMI()
print w.Win32_TemperatureProbe()[0].CurrentReading

查看 ars 答案中的 IronPython 脚本,似乎还有另一种方法可以使用不同的 WMI 对象。使用相同的 API 和方法,您可以尝试接收温度值

w = wmi.WMI(namespace="root\wmi")
temperature_info = w.MSAcpi_ThermalZoneTemperature()[0]
print temperature_info.CurrentTemperature

这显然应该以十分之一开尔文返回温度值,因此要接收摄氏度,我猜你只需将该值除以 10 并减去〜273。

于 2010-07-16T11:20:05.320 回答
5

我从第 3 方收到了一个 C++ 项目,并找到了如何使用 C++ 获取 CPU 和 Board Temp。然后我发现了这个我用来帮助我用 ctypes 模仿 python 中的 C++ 函数的东西,很多代码都是直接从该存储库复制的。'\\.\AdvLmDev' 特定于我使用的 PC,应替换为 '\\.\PhysicalDrive0'。还有一个功能可以获取其他 CPU 功率测量值。我这样做是因为我不想使用 Open Hardware Monitor。您可能必须以管理员身份运行代码才能使其正常工作。

import ctypes
import ctypes.wintypes as wintypes
from ctypes import windll


LPDWORD = ctypes.POINTER(wintypes.DWORD)
LPOVERLAPPED = wintypes.LPVOID
LPSECURITY_ATTRIBUTES = wintypes.LPVOID

GENERIC_READ = 0x80000000
GENERIC_WRITE = 0x40000000
GENERIC_EXECUTE = 0x20000000
GENERIC_ALL = 0x10000000

FILE_SHARE_WRITE=0x00000004
ZERO=0x00000000

CREATE_NEW = 1
CREATE_ALWAYS = 2
OPEN_EXISTING = 3
OPEN_ALWAYS = 4
TRUNCATE_EXISTING = 5

FILE_ATTRIBUTE_NORMAL = 0x00000080

INVALID_HANDLE_VALUE = -1
FILE_DEVICE_UNKNOWN=0x00000022
METHOD_BUFFERED=0
FUNC=0x900
FILE_WRITE_ACCESS=0x002

NULL = 0
FALSE = wintypes.BOOL(0)
TRUE = wintypes.BOOL(1)


def CTL_CODE(DeviceType, Function, Method, Access): return (DeviceType << 16) | (Access << 14) | (Function <<2) | Method




def _CreateFile(filename, access, mode, creation, flags):
    """See: CreateFile function http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).asp """
    CreateFile_Fn = windll.kernel32.CreateFileW
    CreateFile_Fn.argtypes = [
            wintypes.LPWSTR,                    # _In_          LPCTSTR lpFileName
            wintypes.DWORD,                     # _In_          DWORD dwDesiredAccess
            wintypes.DWORD,                     # _In_          DWORD dwShareMode
            LPSECURITY_ATTRIBUTES,              # _In_opt_      LPSECURITY_ATTRIBUTES lpSecurityAttributes
            wintypes.DWORD,                     # _In_          DWORD dwCreationDisposition
            wintypes.DWORD,                     # _In_          DWORD dwFlagsAndAttributes
            wintypes.HANDLE]                    # _In_opt_      HANDLE hTemplateFile
    CreateFile_Fn.restype = wintypes.HANDLE

    return wintypes.HANDLE(CreateFile_Fn(filename,
                         access,
                         mode,
                         NULL,
                         creation,
                         flags,
                         NULL))


handle=_CreateFile('\\\\.\\AdvLmDev',GENERIC_WRITE,FILE_SHARE_WRITE,OPEN_EXISTING,ZERO)

def _DeviceIoControl(devhandle, ioctl, inbuf, inbufsiz, outbuf, outbufsiz):
    """See: DeviceIoControl function
http://msdn.microsoft.com/en-us/library/aa363216(v=vs.85).aspx
"""
    DeviceIoControl_Fn = windll.kernel32.DeviceIoControl
    DeviceIoControl_Fn.argtypes = [
            wintypes.HANDLE,                    # _In_          HANDLE hDevice
            wintypes.DWORD,                     # _In_          DWORD dwIoControlCode
            wintypes.LPVOID,                    # _In_opt_      LPVOID lpInBuffer
            wintypes.DWORD,                     # _In_          DWORD nInBufferSize
            wintypes.LPVOID,                    # _Out_opt_     LPVOID lpOutBuffer
            wintypes.DWORD,                     # _In_          DWORD nOutBufferSize
            LPDWORD,                            # _Out_opt_     LPDWORD lpBytesReturned
            LPOVERLAPPED]                       # _Inout_opt_   LPOVERLAPPED lpOverlapped
    DeviceIoControl_Fn.restype = wintypes.BOOL

    # allocate a DWORD, and take its reference
    dwBytesReturned = wintypes.DWORD(0)
    lpBytesReturned = ctypes.byref(dwBytesReturned)

    status = DeviceIoControl_Fn(devhandle,
                  ioctl,
                  inbuf,
                  inbufsiz,
                  outbuf,
                  outbufsiz,
                  lpBytesReturned,
                  NULL)

    return status, dwBytesReturned

class OUTPUT_temp(ctypes.Structure):
        """See: http://msdn.microsoft.com/en-us/library/aa363972(v=vs.85).aspx"""
        _fields_ = [
                ('Board Temp', wintypes.DWORD),
                ('CPU Temp', wintypes.DWORD),
                ('Board Temp2', wintypes.DWORD),
                ('temp4', wintypes.DWORD),
                ('temp5', wintypes.DWORD)
                ]

class OUTPUT_volt(ctypes.Structure):
        """See: http://msdn.microsoft.com/en-us/library/aa363972(v=vs.85).aspx"""
        _fields_ = [
                ('VCore', wintypes.DWORD),
                ('V(in2)', wintypes.DWORD),
                ('3.3V', wintypes.DWORD),
                ('5.0V', wintypes.DWORD),
                ('temp5', wintypes.DWORD)
                ]

def get_temperature():
    FUNC=0x900
    outDict={}

    ioclt=CTL_CODE(FILE_DEVICE_UNKNOWN, FUNC, METHOD_BUFFERED, FILE_WRITE_ACCESS)

    handle=_CreateFile('\\\\.\\AdvLmDev',GENERIC_WRITE,FILE_SHARE_WRITE,OPEN_EXISTING,ZERO)

    win_list = OUTPUT_temp()
    p_win_list = ctypes.pointer(win_list)
    SIZE=ctypes.sizeof(OUTPUT_temp)


    status, output = _DeviceIoControl(handle, ioclt , NULL, ZERO, p_win_list, SIZE)


    for field, typ in win_list._fields_:
                #print ('%s=%d' % (field, getattr(disk_geometry, field)))
                outDict[field]=getattr(win_list,field)
    return outDict

def get_voltages():
    FUNC=0x901
    outDict={}

    ioclt=CTL_CODE(FILE_DEVICE_UNKNOWN, FUNC, METHOD_BUFFERED, FILE_WRITE_ACCESS)

    handle=_CreateFile('\\\\.\\AdvLmDev',GENERIC_WRITE,FILE_SHARE_WRITE,OPEN_EXISTING,ZERO)

    win_list = OUTPUT_volt()
    p_win_list = ctypes.pointer(win_list)
    SIZE=ctypes.sizeof(OUTPUT_volt)


    status, output = _DeviceIoControl(handle, ioclt , NULL, ZERO, p_win_list, SIZE)


    for field, typ in win_list._fields_:
                #print ('%s=%d' % (field, getattr(disk_geometry, field)))
                outDict[field]=getattr(win_list,field)
    return outDict
于 2019-11-19T00:37:13.403 回答
3

查看cputemp库。

编辑:在 Windows 上,您可以使用 python WMI library转换这个使用 WMI 的IronPython 脚本

于 2010-07-16T07:03:40.397 回答
3

我使用了来自https://github.com/BennyCarbajal/PyTherm的实用程序

几乎可以使用以下命令安装 pythonnet:

pip install pythonnet

然后只需以管理员身份执行终端,最后执行文件:

python pytherm.py

如果您以普通用户身份运行它,它也可以工作,但不会输出尽可能多的数据。

由于它以 JSON 格式返回数据,因此您应该很容易获得您正在寻找的特定硬件的数据。

于 2020-01-11T23:01:57.467 回答
0

eadmaster 提供的代码可能适用于 OpenHardwareMonitor 已为其编程的旧 CPU,但我有一个 Skylake i7 6700K CPU。OpenHardwareMonitor 没有为我提供任何结果。但是,这个程序有一个分支,称为CPU Thermometer,它基于 OpenHardwareMonitor ,它可以识别我的 CPU。

在追查如何通过 Python 获取 CPU 温度时,我切换到 IronPython 以访问 .Net 框架并轻松访问其他性能数据,但应该很容易弄清楚如何将其改装为 vanilla Python 2.7(只需运行 CPU Thermometer 而不是 OpenHardwareMonitor 并将您的命名空间更改为“root\CPUThermometer”?就这么简单吗?)。

#
# CPU Temp --REQUIRES CPU TEMPERATURE TO BE RUNNING!--
#
import clr
clr.AddReference('System.Management')
from System.Management import (ManagementScope, ManagementObject, ManagementObjectSearcher, WqlObjectQuery)

scope = ManagementScope("root\CPUThermometer")

searcher = ManagementObjectSearcher(scope, 
    WqlObjectQuery("SELECT * FROM Sensor Where SensorType LIKE 'Temperature'"), None)

mo = ManagementObject()

print "\n"
print "              Temp      Min       Max"

strout = str(' ')

for mo in searcher.Get():
    strout = '{0}   {1} C    {2} C    {3} C\n{4}'.format(mo["Name"], mo["Value"], mo["Min"], mo["Max"], strout)

print strout

样本输出:

D:\IronPython 2.7>ipy64 c:\users\neamerjell\desktop\test.py


              Temp      Min       Max
CPU Core #1   21.0 C    20.0 C    37.0 C
CPU Core #2   23.0 C    21.0 C    39.0 C
CPU Core #3   21.0 C    20.0 C    32.0 C
CPU Core #4   21.0 C    20.0 C    36.0 C

我发现查询不是很标准的 SQL 并且不喜欢“Order By”子句的困难方式,所以我必须做一些花哨的字符串格式来获得正确的顺序,因为查询以相反的顺序返回核心。这让我有点困惑,直到我设计了这个方法。

于 2016-05-28T09:37:47.347 回答