一、核心需求
python程序读取电脑硬件信息,包括主板
、CPU
、内存
、GPU
、风扇
、硬盘
二、实现思路
使用pythonnet
调用Open Hardware MonitorLib.dll
,通过该dll提供的接口读取硬件信息
- pythonnet:使用该库调用C#的dll
- OpenHardwareMonitorLib.dll:OpenHardwareMonitor开源项目是用来监测硬件信息的,巨硬出品,该项目里有两个项目,将OpenHardwareMonitorLib编译为dll,后续方便python调用
三、核心代码
import clr #package pythonnet, not clr
from datamap import data
class HardWareReader():
def __init__(self,path_dll:str,conf:dict) -> None:
self.dll = path_dll
self.conf = conf
self.hwtypes = ['Mainboard','SuperIO','CPU','RAM','GpuNvidia','GpuAti','TBalancer','Heatmaster','HDD']
self.sensortypes = ['Voltage','Clock','Temperature','Load','Fan','Flow','Control','Level','Factor','Power','Data','SmallData','Throughput']
def init(self):
clr.AddReference(self.dll)
from OpenHardwareMonitor import Hardware
handle = Hardware.Computer()
handle.MainboardEnabled = self.conf['MainboardEnabled']
handle.CPUEnabled = self.conf['CPUEnabled']
handle.RAMEnabled = self.conf['RAMEnabled']
handle.GPUEnabled = self.conf['GPUEnabled']
handle.HDDEnabled = self.conf['HDDEnabled']
handle.Open()
return handle
def fetch_stats(self,handle):
hardware_ls = []
for i in handle.Hardware:
i.Update()
for sensor in i.Sensors:
res = self.parse_sensor(sensor)
hardware_ls.append(res)
for j in i.SubHardware:
j.Update()
for subsensor in j.Sensors:
res = self.parse_sensor(subsensor)
hardware_ls.append(res)
return hardware_ls
def parse_sensor(self,sensor):
if sensor.Value is not None:
sensortypes = self.sensortypes
hardwaretypes = self.hwtypes
else:
return None
if sensor.SensorType == sensortypes.index('Temperature'):
return u"hardwareType:{},hardwareName:{},sensorIndex:{},senserName:{} sensorValue{:.2f}".format(hardwaretypes[sensor.Hardware.HardwareType], sensor.Hardware.Name, sensor.Index, sensor.Name, sensor.Value)
elif sensor.SensorType == sensortypes.index('Voltage'):
return u"hardwareType:{},hardwareName:{},sensorIndex:{},senserName:{} sensorValue{:.2f}".format(hardwaretypes[sensor.Hardware.HardwareType], sensor.Hardware.Name, sensor.Index, sensor.Name, sensor.Value)
elif sensor.SensorType == sensortypes.index('Clock'):
return u"hardwareType:{},hardwareName:{},sensorIndex:{},senserName:{} sensorValue{:.2f}".format(hardwaretypes[sensor.Hardware.HardwareType], sensor.Hardware.Name, sensor.Index, sensor.Name, sensor.Value)
elif sensor.SensorType == sensortypes.index('Load'):
return u"hardwareType:{},hardwareName:{},sensorIndex:{},senserName:{} sensorValue{:.2f}".format(hardwaretypes[sensor.Hardware.HardwareType], sensor.Hardware.Name, sensor.Index, sensor.Name, sensor.Value)
elif sensor.SensorType == sensortypes.index('Fan'):
return u"hardwareType:{},hardwareName:{},sensorIndex:{},senserName:{} sensorValue{:.2f}".format(hardwaretypes[sensor.Hardware.HardwareType], sensor.Hardware.Name, sensor.Index, sensor.Name, sensor.Value)
elif sensor.SensorType == sensortypes.index('Flow'):
return u"hardwareType:{},hardwareName:{},sensorIndex:{},senserName:{} sensorValue{:.2f}".format(hardwaretypes[sensor.Hardware.HardwareType], sensor.Hardware.Name, sensor.Index, sensor.Name, sensor.Value)
elif sensor.SensorType == sensortypes.index('Control'):
return u"hardwareType:{},hardwareName:{},sensorIndex:{},senserName:{} sensorValue{:.2f}".format(hardwaretypes[sensor.Hardware.HardwareType], sensor.Hardware.Name, sensor.Index, sensor.Name, sensor.Value)
elif sensor.SensorType == sensortypes.index('Level'):
return u"hardwareType:{},hardwareName:{},sensorIndex:{},senserName:{} sensorValue{:.2f}".format(hardwaretypes[sensor.Hardware.HardwareType], sensor.Hardware.Name, sensor.Index, sensor.Name, sensor.Value)
elif sensor.SensorType == sensortypes.index('Factor'):
return u"hardwareType:{},hardwareName:{},sensorIndex:{},senserName:{} sensorValue{:.2f}".format(hardwaretypes[sensor.Hardware.HardwareType], sensor.Hardware.Name, sensor.Index, sensor.Name, sensor.Value)
elif sensor.SensorType == sensortypes.index('Power'):
return u"hardwareType:{},hardwareName:{},sensorIndex:{},senserName:{} sensorValue{:.2f}".format(hardwaretypes[sensor.Hardware.HardwareType], sensor.Hardware.Name, sensor.Index, sensor.Name, sensor.Value)
elif sensor.SensorType == sensortypes.index('Data'):
return u"hardwareType:{},hardwareName:{},sensorIndex:{},senserName:{} sensorValue{:.2f}".format(hardwaretypes[sensor.Hardware.HardwareType], sensor.Hardware.Name, sensor.Index, sensor.Name, sensor.Value)
elif sensor.SensorType == sensortypes.index('SmallData'):
return u"hardwareType:{},hardwareName:{},sensorIndex:{},senserName:{} sensorValue{:.2f}".format(hardwaretypes[sensor.Hardware.HardwareType], sensor.Hardware.Name, sensor.Index, sensor.Name, sensor.Value)
elif sensor.SensorType == sensortypes.index('Throughput'):
return u"hardwareType:{},hardwareName:{},sensorIndex:{},senserName:{} sensorValue{:.2f}".format(hardwaretypes[sensor.Hardware.HardwareType], sensor.Hardware.Name, sensor.Index, sensor.Name, sensor.Value)
else:
return None
if __name__ == "__main__":
print("OpenHardwareMonitor:")
# 伪代码,按需修改
# HardwareHandle = init(OpenHardwareMonitor.dll路径,conf配置文件,字典格式)
# fetch_stats(HardwareHandle)
# input('关闭窗口')
# 以下是我的系统的输出:
# 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
# datamap.py
def data():
data = {
'CPU':{
'Clocks':{},
'Temperatures':{},
'Load':{},
'Powers':{}
},
'GPU':{
'Voltages':{},
'Clocks':{},
'Temperatures':{},
'Load':{},
'Fans':{},
'Controls':{},
'Powers':{}
},
'IO':{
'Voltages':{},
'Temperatures':{},
'Fans':{},
'Controls':{}
},
'HDD':{
'one':{
'Temperatures':{},
'Load':{}
},
'two':{}
},
'RAM':{
'Load':{},
'Data':{}
}
}
return data
# conf.py
# coding:utf-8
import yaml
class Yaml():
def yamlRead(self,yaml_path:str):
f = open(yaml_path, 'r', encoding='utf-8')
cfg = f.read()
d = yaml.load(cfg,Loader=yaml.FullLoader) # 用load方法转字典
return d
# conf.yaml
SERVER:
host:
'127.0.0.1'
port:
8266
HARDWARE:
CPUEnabled:
true
GPUEnabled:
true
RAMEnabled:
true
HDDEnabled:
true
MainboardEnabled:
true
FanControllerEnabled:
true
SIGN: 'wdx845o'
四、Open Hardware Monitor
1、读取过程
-
先设置要检测的项目:
MainboardEnabled
,CPUEnabled
,RAMEnabled
,GPUEnabled
,FanControllerEnabled
,HDDEnabled
my_computer = Computer() #实例这这个类 my_computer.CPUEnabled = True #监测CPU,其他同理
-
读取Hardware的参数
# 这个顺序按下边的枚举的顺序 my_computer.Hardware[0].Identifier # 0表示 CPU
-
读取Sensors的参数
# 这个顺序按下边的枚举的顺序 my_computer.Hardware[0].Sensors[0].Identifier
2、OpenHardwareMonitorLib中重要概念
一共三层概念,从高到低层次依次是:Computer>HardWare > Sensors >
2.1、Hardware
Value type | Name | Description | Example |
---|---|---|---|
string | Name | Typically a combination of make and model | Intel Core 2 Duo E8400 |
string | Identifier | A unique identifier for this piece of hardware | /intelcpu/0 |
string | HardwareType | 下边定义的硬件类型(HardwareType) | CPU |
string | Parent | The identifier of its parent Hardware; if any. | “/mainboard” or “” |
public enum HardwareType
{
Mainboard = 0,
SuperIO = 1,
CPU = 2,
GpuNvidia = 3,
GpuAti = 4,
TBalancer = 5,
Heatmaster = 6,
HDD = 7,
}
2.2、SenorType
Sensor Type | Unit used | Recommended display format |
---|---|---|
Voltage | Volt(电压) | «value» V |
Clock | Megahertz | «value» MHz |
Temperature | Celsius(摄氏度) | «value» °C |
Load | Percentage(百分比) | «value»% |
Fan | Revolutions per minute(转每分) | «value» RPM |
Flow | Liters per hour | «value» L/h |
Control | Percentage(百分比) | «value»% |
Level | Percentage(百分比) | «value»% |
public enum SensorType {
Voltage, // V
Clock, // MHz
Temperature, // °C
Load, // %
Fan, // RPM
Flow, // L/h
Control, // %
Level, // %
Factor, // 1
Power, // W
Data, // GB = 2^30 Bytes
SmallData, // MB = 2^20 Bytes
Throughput, // MB/s = 2^20 Bytes/s
}
负载、控制和级别类型的每种类型都使用百分比作为其单位,但有明显不同的用途。
-
Load(负载):表示一块硬件上的负载,其中100%表示一个完全加载的组件。
-
Control(控制): 通常与风扇控制器一起使用,用于表示占空比。
-
Level(级别):这是一个通用的基于%的级别度量,当上述两者都不适用时使用
参考
orcode上 一篇《在python中访问CPU温度》的问答,但是原地址我找不到了