本文将介绍如何在PVE7.2-7后台管理面板,展示CPU、主板、NVME的温度。
在 PVE 中安装温度检测控件
在 PVE 后台选择 PVE 节点,并选择“Shell”。
CPU 及主板温度检测控件:lm-sensors
apt-get install lm-sensors
安装完成后执行命令 sensors-detect 识别温度传感器,一直按Enter选择默认即可。
识别后再执行命令 sensors 获取温度信息。返回信息大概如下:
root@pve:~# sensors
coretemp-isa-0000
Adapter: ISA adapter
Package id 0:  +34.0°C  (high = +105.0°C, crit = +105.0°C)
Core 0:        +29.0°C  (high = +105.0°C, crit = +105.0°C)
Core 1:        +29.0°C  (high = +105.0°C, crit = +105.0°C)
Core 2:        +29.0°C  (high = +105.0°C, crit = +105.0°C)
Core 3:        +29.0°C  (high = +105.0°C, crit = +105.0°C)
acpitz-acpi-0
Adapter: ACPI interface
temp1:        +27.8°C  (crit = +119.0°C)
nvme-pci-0100
Adapter: PCI adapter
Composite:    +36.9°C  (low  =  -5.2°C, high = +79.8°C)
                       (crit = +84.8°C)
“coretemp-isa-0000”是 CPU 温度,如果是多核CPU则会分别展示每个核心的温度。“acpitz-acpi-0”是主板温度。“nvme-pci-0100”是NVME的温度。
硬盘温度检测控件:hddtemp
apt-get install hddtemp
安装完成后再执行命令 hddtemp /dev/sd? 获取温度信息。返回信息大概如下:
root@pve:~# hddtemp /dev/sd? /dev/sda: XXX: 29°C /dev/sdb: XXX: 26°C
需要修改下 hddtemp 命令的权限,否则PVE的后台面板无法正常获取温度信息。
chmod +s /usr/sbin/hddtemp
编辑 PVE 后台面板界面文件
第一个文件:Nodes.pm
首先备份下,方便恢复:
cp /usr/share/perl5/PVE/API2/Nodes.pm /usr/share/perl5/PVE/API2/Nodes.pm.bak
编辑 Nodes.pm 文件:
nano /usr/share/perl5/PVE/API2/Nodes.pm
在 PVE::pvecfg::version_text(); 后增加如下行:
$res->{temperatures} = `sensors`;  # 添加此行以获取 CPU 与主板温度
$res->{hdd_temperatures} = `hddtemp /dev/sd?`;  # 添加此行以获取硬盘温度
第二个文件:pvemanagerlib.js
首先备份下,方便恢复:
cp /usr/share/pve-manager/js/pvemanagerlib.js /usr/share/pve-manager/js/pvemanagerlib.js.bak
编辑 pvemanagerlib.js 文件:
nano /usr/share/pve-manager/js/pvemanagerlib.js
在 Ext.window.Window 下找到 height ,将高度改为500。在 pveNodeStatus 下找到 height ,将高度改为400(可能会稍高,有些留白)。这两个 height 的需要按实际情况修改,每多一行数据高度需要增加 20。
接着在 PVE Manager Version 后增加如下行:
{
  itemId: 'temperatures',
  colspan: 2,
  printBar: false,
  title: gettext('Temperatures'),
  textField: 'temperatures',
  renderer: function(value) {
      value = value.replace(/Â/g, '');
      let data = [];
      let cpus = value.matchAll(/^coretemp-isa-(\d{4})$\n.*?\n((?:Package|Core)[\s\S]*?^\n)+/gm);
      for (const cpu of cpus) {
          let cpuNumber = parseInt(cpu[1], 10);
          data[cpuNumber] = {
              packages: [],
              cores: []
          };
          let packages = cpu[2].matchAll(/^Package id \d+:\s*([^°]+).*$/gm);
          for (const package of packages) {
              data[cpuNumber]['packages'].push(package[1]);
          }
          let cores = cpu[2].matchAll(/^Core \d+:\s*([^°]+).*$/gm);
          for (const core of cores) {
              data[cpuNumber]['cores'].push(core[1]);
          }
      }
      let output = '';
      for (const [i, cpu] of data.entries()) {
          output += `CPU ${i}: `;
          if (cpu.packages.length > 0) {
              for (const packageTemp of cpu.packages) {
                  output += `${packageTemp}°C `;
              }
          }
          if (cpu.cores.length > 0) {
              output += '(';
              for (const coreTemp of cpu.cores) {
                  output += `${coreTemp}, `;
              }
              output = output.slice(0, -2);
              output += ')°C';
          }
          output += ' | ';
      }
      let boardTemp = value.match(/^acpitz-acpi-\d+$\n.*?\n^temp1:\s*([^°]+).*$/m);
      if (boardTemp.length > 0) {
          output += `Board: ${boardTemp[1]}°C | `
      }
      // output = output.slice(0, -3);
      let nvmeTemp = value.match(/^nvme-pci-\d+$\n.*?\n^Composite:\s*([^°]+).*$/m);
      if (nvmeTemp.length > 0) {
          output += `NVME: ${nvmeTemp[1]}°C | `
      }
      output = output.slice(0, -3);
      return output;
  }
},
{
    itemId: 'hdd-temperatures',
    colspan: 2,
    printBar: false,
    title: gettext('HDD Temperatures'),
    textField: 'hdd_temperatures',
    renderer: function(value) {
        value = value.replace(/Â/g, '');
        return value.replace(/\n/g, '<br>')
    }
},
完成
执行命令重启 PVE 后台管理面板服务:
systemctl restart pveproxy