PythonでCPU温度にアクセスするためのサンプルコードが必要です。
ところで、私はWindows7を実行しています。
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)
ダウンロード 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/ (またはWebサイトのcputhermometer)を参照してください。ソースコード、関数、メソッドは、Pythonでこれらを使用する場合と同じです。
私はこれを他のコンピュータでテストしていないので、異なるプロセッサアーキテクチャが同じように機能しない可能性があります。
測定の合間にHardware[x].Update()
を実行するようにしてください(必要に応じてSubHardware[x].Update()
を実行してください)。
pywin32 を使用して、ネイティブWindowsAPIにアクセスできます。メインボードドライバーの製造元がドライバーを介してWMIデータプロバイダーを登録している場合は、WindowsAPIに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分の1で温度値を返すはずなので、摂氏で次数を取得するには、この値を10で割り、〜273を引くだけだと思います。
cputemp ライブラリをチェックしてください。
編集:Windowsでは、これを変換できる可能性があります IronPythonスクリプト python WMIライブラリ を使用してWMIを使用します。
サードパーティからC++プロジェクトを受け取り、C++を使用してCPUとボード温度を取得する方法を見つけました。次に、 this を見つけました。これは、ctypesを使用してpythonで、C++関数を模倣するのに役立ちました。このコードの多くはそのリポジトリから直接コピーされます。 '\ \。\ AdvLmDev 'は使用していたPCに固有であり、' \\。\ PhysicalDrive0 'に置き換える必要があります。他のCPUパワー測定値を取得する関数もあります。使用したくなかったため、これを実行しました。ハードウェアモニターを開きます。コードを機能させるには、管理者としてコードを実行する必要がある場合があります。
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
https://github.com/BennyCarbajal/PyTherm のユーティリティを使用しました
Pythonnetを次のようにインストールします。
pip install pythonnet
次に、ターミナルを管理者として実行し、最後にファイルを実行します。
python pytherm.py
通常のユーザーとして実行した場合にも機能しますが、それほど多くのデータは出力されません。
データをJSON形式で返すため、探している特定のハードウェアのデータを取得するのは簡単です。
Eadmasterが提供するコードは、OpenHardwareMonitorがプログラムされている古いCPUでも機能する可能性がありますが、Skylake i7 6700KCPUを使用しています。 OpenHardwareMonitorは私に結果を提供しませんでした。ただし、このプログラムには CPU Thermometer というフォークがあります。これはOpenHardwareMonitorに基づいており、は私のCPUを認識します。
Pythonを介してCPU温度を取得する方法を追跡する際に、.Netフレームワークにアクセスし、他のパフォーマンスデータに簡単にアクセスできるようにするために、IronPythonに切り替えましたが、Vanillaにレトロフィットする方法を理解するのはかなり簡単です。 Python 2.7(OpenHardwareMonitorの代わりにCPU温度計を実行し、名前空間を「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」句が好きではないという難しい方法を見つけたので、クエリがコアを逆の順序で返すため、順序を正しくするためにいくつかの凝った文字列フォーマットを行う必要がありました。私がそれを回避する方法を考案するまで、これは私を少し困惑させました。