https://psutil.readthedocs.io/en/latest/

psutil.sensors_temperatures()不提供在Windows下获取CPU温度的功能。原因是操作系统并未内置,而CPU/GPU/主板等传感器各厂商实现方法不统一(所以诸如HWInfo之类的软件做了更多的工作才得以实现)。

查了网上的资料,简单的实现方法是安装三方监控软件,再通过python调用该监控软件的方式来实现获取温度。

  • Open Hardware Monitor,然而可惜的是,该软件已经5年没更新了。
  • LibreHardwareMonitor(以下简称LHM),它是前者的fork并且一直在维护中。Python使用它有几种方案:
    • DLL调用:反应很慢,好几秒才能得到返回值,且必须以管理员运行;
    • 解析其Web Server页面,但也不是最优解;
    • 另有其他方案若干,抄来抄去的,有的甚至跑不通。
    • 经过探索验证,找到一种较好的方法。当然,这个方法吃相也不太好看(但解决了问题)。

      在Options –> Remote Web Server –> Run打勾后,访问上述URL可访问网页版的硬件监控数据,如图所示:
      页面数据示例

      有了它,自然想到抓网页,这对Python来说也容易。当然它不漂亮。有聪明人发现这个Web服务其实有一个JSON格式的入口:

      http://localhost:8085/data.json

      数据返回如下:
      data.json数据示例

      太好了!解析JSON结构就可以得到我们想要的数据。
      然而,这个/data.json返回了很多数据,而不仅仅是传感器温度。
      这份数据量也不小,解析速度还是不够理想。
      有没有更好的方式呢?

      经查看LHM的源码,发现它有另外一个未公布的URL:

      http://localhost:8085/Sensor?action=Get&id={xxx}

      它的返回值也是JSON数据,且是/data.json服务的子集。
      传入id,它只返回最精简的数据,如下图:
      Sensor数据示例

      是不是很棒了?!其中{xxx}就是/data.json中已经给出的对应SensorId,如下图:
      结果示例

      所以,对于某台固定的电脑,先访问/data.json,找到想要的那一条温度,记下它的SensorId,接下来就简单了。示例代码如下:

      import psutil,requests class ExHWInfo: def __init__(self, web_addr="http://localhost:8085/Sensor?action=Get",cpu_node_id="/intelcpu/0/temperature/1"): self.web_addr=web_addr self.cpu_node_id=cpu_node_id def cpu_temperature(self): if hasattr(psutil, "sensors_temperatures"): # May be Linux temps = psutil.sensors_temperatures() if not temps: return None return temps[0].current else: # May be windows, let's read info from http via LibreHardwareMonitor url = '{}&id={}'.format(self.web_addr,self.cpu_node_id) response = requests.get(url) response.raise_for_status() ret=response.json() return int(ret["value"]) except requests.exceptions.HTTPError as err: print(err) return None
    • 缺点:每台机器都要提前找到SensorId并且hardcode,另外LHM像是外挂,不够优雅。
    • P.S. /Sensor这个服务不要传错参数,一旦id不存在或者其他参数有误,会直接导致LHM软件崩溃。若有生产环境需求,建议修改LHW源码,加上判断逻辑,以提升稳定性。

      参考资料
      https://github.com/LibreHardwareMonitor/LibreHardwareMonitor/discussions/677
      https://github.com/snip3rnick/PyHardwareMonitor
      https://github.com/Cyril-Meyer/PyHardwareMonitor

  •