找回密码
 加入我们
搜索
      
查看: 11616|回复: 14

[NAS] 自组2.5g NAS系统组建第二篇:添加温度监控篇

[复制链接]
发表于 2023-2-20 00:33 | 显示全部楼层 |阅读模式
本帖最后由 lk_yeah 于 2024-7-26 10:28 编辑

这一贴的内容是在PVE的监控页面上添加CPU温度、芯片组温度、CPU频率、硬盘温度。做这项工作其实跟运行的虚拟机无关,不喜欢可以不做。

先放效果
01.png

这是PVE节点概要的页面,其中“PVE管理版本”和“存储库状态”之间的内容是我添加的,显示的数字是可以动态更新的。
下面就给出实现方法。

安装温度显示软件lm-sensors
命令行运行
  1. apt install lm-sensors
复制代码
根据提示,按下Y键,等一下就可以了。
然后运行
  1. sensors-detect
复制代码
这条命令的作用是检测该主机上的硬件探测器,并将检测结果添加到/etc/modules中。执行过程会不断询问是否检测某种硬件,基本上一路Y键就可以了。
注意,这条命令中,-之前没有空格,sensors-detect是一个可执行文件,不是某条命令加选项。
检测完成后运行lm-sensors的基本命令就可以输出它监控到的各种硬件数值了。
  1. sensors
复制代码

02.png
以上就是我执行sensors命令后显示出的信息,最上面就是CPU温度,然后是主板芯片组的温度,再往下还有各种温度、电压、风扇转速等等,信息相当多。

配置页面
配置页面一共需要修改两个文件:
/usr/share/perl5/PVE/API2/Nodes.pm——这个文件定义变量名
/usr/share/pve-manager/js/pvemanagerlib.js——这个文件是页面代码
温馨提示,修改前备份一下原文件,预防改出问题。
命令行运行
  1. cp /usr/share/perl5/PVE/API2/Nodes.pm /usr/share/perl5/PVE/API2/Nodes.pm.bak
  2. cp /usr/share/pve-manager/js/pvemanagerlib.js /usr/share/pve-manager/js/pvemanagerlib.js.bak
复制代码

首先以显示CPU温度为例,讲解下实现原理。
Nodes.pm中搜索shared => $meminfo->{memshared}
添加:
  1.     $res->{cpu_temperatures} = `sensors`;
复制代码
pvemanagerlib.js中搜索textField: 'pveversion'
添加:
  1.     {
  2.         itemId: 'cpu-temperatures',
  3.         colspan: 2,
  4.         printBar: false,
  5.         title: gettext('CPU温度'),
  6.         textField: 'cpu_temperatures',
  7.         renderer:function(value){
  8.             const c0 = value.match(/Core 0.*?\+([\d\.]+)?/)[1];
  9.             const c1 = value.match(/Core 1.*?\+([\d\.]+)?/)[1];
  10.             const c2 = value.match(/Core 2.*?\+([\d\.]+)?/)[1];
  11.             const c3 = value.match(/Core 3.*?\+([\d\.]+)?/)[1];
  12.             const c4 = value.match(/Core 4.*?\+([\d\.]+)?/)[1];
  13.             const c5 = value.match(/Core 5.*?\+([\d\.]+)?/)[1];
  14.             const p0 = value.match(/Package id 0.*?\+([\d\.]+)?/)[1];
  15.             return `Package: ${p0}℃; Core 0: ${c0}℃; Core 1: ${c1}℃; Core 2: ${c2}℃; Core 3: ${c3}℃; Core 4: ${c4}℃; Core 5: ${c5}℃`
  16.         }
  17.     },
复制代码

解释一下:
第一段中
cpu_temperatures为变量名;sensors为可执行命令,就是可以运行于Linux命令行的命令。
第二段中
itemId随便定义,只要在这个文件中不重复就行;title中的汉字就是页面左侧显示的文字;textField要跟第一段中变量名一致;后面的函数中,Core 0、Core 1之类的,是sensors命令执行后获取到的内容中,CPU核心温度的键名,具体请参看我上面的贴图,return句是显示输出的结果。
总结一下,两段代码就是从第一段的可执行命令中获取到的内容中,取相应的值按第二段返回语句显示出来。
温馨提示,每段代码最后的逗号分号一定不要忘记,缺了就报错了。
显示CPU温度的代码用到了lm-sensors。大家不要原样抄我的,我的CPU是8700,6核的,请根据自己的实际情况修改。
同理,大家可以根据自己的需要,把lm-sensors显示出的其他信息,比如电压、风扇转速等添加进来。

明白了原理后,我下面再给出显示CPU频率、固态盘温度、机械盘温度的代码。当然了,这些代码都是我从网上白嫖来的。
Nodes.pm添加:
  1.     $res->{cpu_frequency} = `lscpu|grep MHz`;
  2.     $res->{nvme_ssd_temperatures} = `smartctl -a /dev/nvme?|grep -E "Model Number|Total NVM Capacity|Temperature:|Percentage|Data Unit|Power On Hours"`;
  3.     $res->{hdd_temperatures} = `smartctl -a /dev/sd?|grep -E "Model|Capacity|Power_On_Hours|Temperature"`;
复制代码
pvemanagerlib.js添加:
  1.     {
  2.         itemId: 'cpu-frequency',
  3.         colspan: 2,
  4.         printBar: false,
  5.         title: gettext('CPU频率'),
  6.         textField: 'cpu_frequency',
  7.         renderer:function(value){
  8.             const f0 = value.match(/CPU MHz.*?([\d]+)/)[1];
  9.             const f1 = value.match(/CPU min MHz.*?([\d]+)/)[1];
  10.             const f2 = value.match(/CPU max MHz.*?([\d]+)/)[1];
  11.             return `实时: ${f0} MHz; 最小: ${f1} MHz; 最大: ${f2} MHz`
  12.         }
  13.     },

  14.     {
  15.         itemId: 'nvme_ssd-temperatures',
  16.         colspan: 2,
  17.         printBar: false,
  18.         title: gettext('NVME硬盘'),
  19.         textField: 'nvme_ssd_temperatures',
  20.         renderer:function(value){
  21.             if (value.length > 0) {
  22.                 let nvmedevices = value.matchAll(/^Model.*:\s*([\s\S]*?)(\n^Total.*\[[\s\S]*?\]$|\s{0}$)\n^Temperature:\s*([\d]+)\s*Celsius\n^Percentage.*([\d]+\%)\n^Data Units.*\[([\s\S]*?)\]\n^Data Units.*\[([\s\S]*?)\]\n^Power.*:\s*([\s\S]*?)\n/gm);
  23.                 for (const nvmedevice of nvmedevices) {
  24.                     for (var i=5; i<8; i++) {
  25.                     nvmedevice = nvmedevice.replace(/ |,/gm, '');
  26.                     }
  27.                     if (nvmedevice[2].length > 0) {
  28.                         let nvmecapacity = nvmedevice[2].match(/.*\[([\s\S]*?)\]/);
  29.                         nvmecapacity = nvmecapacity[1].replace(/ /, '');
  30.                         value = `${nvmedevice[1]} | 已使用寿命: ${nvmedevice[4]} (累计读取: ${nvmedevice[5]}, 累计写入: ${nvmedevice[6]}) | 容量: ${nvmecapacity} | 已通电: ${nvmedevice[7]}小时 | 温度: ${nvmedevice[3]}°C\n`;
  31.                     }
  32.                     else {
  33.                         value = `${nvmedevice[1]} | 已使用寿命: ${nvmedevice[4]} (累计读取: ${nvmedevice[5]}, 累计写入: ${nvmedevice[6]}) | 已通电: ${nvmedevice[7]}小时 | 温度: ${nvmedevice[3]}°C\n`;
  34.                     }
  35.                 }
  36.             return value.replace(/\n/g, '<br>');
  37.             }
  38.             {
  39.             return `提示: 未安装硬盘或已直通硬盘控制器`;
  40.             }
  41.         }
  42.     },
  43.    
  44.     {
  45.         itemId: 'hdd-temperatures',
  46.         colspan: 2,
  47.         printBar: false,
  48.         title: gettext('SATA硬盘'),
  49.         textField: 'hdd_temperatures',
  50.         renderer:function(value){
  51.             if (value.length > 0) {
  52.                 let devices = value.matchAll(/(\s*Model.*:\s*[\s\S]*?\n){1,2}^User.*\[([\s\S]*?)\]\n^\s*9[\s\S]*?\-\s*([\d]+)[\s\S]*?(\n(^19[0,4][\s\S]*?$){1,2}|\s{0}$)/gm);
  53.                 for (const device of devices) {
  54.                     if(device[1].indexOf("Family") !== -1){
  55.                         devicemodel = device[1].replace(/.*Model Family:\s*([\s\S]*?)\n^Device Model:\s*([\s\S]*?)\n/m, '$1 - $2');
  56.                         }
  57.                         else {
  58.                         devicemodel = device[1].replace(/.*Model:\s*([\s\S]*?)\n/m, '$1');
  59.                         }
  60.                     device[2] = device[2].replace(/ |,/gm, '');
  61.                     if(value.indexOf("Min/Max") !== -1){
  62.                         let devicetemps = device[5].matchAll(/19[0,4][\s\S]*?\-\s*(\d+)(\s\(Min\/Max\s(\d+)\/(\d+)\)$|\s{0}$)/gm);
  63.                         for (const devicetemp of devicetemps) {
  64.                             value = `${devicemodel} | 容量: ${device[2]} | 已通电: ${device[3]}小时 | 温度: ${devicetemp[1]}°C\n`;
  65.                         }
  66.                     }
  67.                     else if (value.indexOf("Temperature") !== -1){
  68.                         let devicetemps = device[5].matchAll(/19[0,4][\s\S]*?\-\s*(\d+)/gm);
  69.                         for (const devicetemp of devicetemps) {
  70.                             value = `${devicemodel} | 容量: ${device[2]} | 已通电: ${device[3]}小时 | 温度: ${devicetemp[1]}°C\n`;
  71.                         }
  72.                     }
  73.                     else {
  74.                         value = `${devicemodel} | 容量: ${device[2]} | 已通电: ${device[3]}小时 | 提示: 未检测到温度传感器\n`;
  75.                     }
  76.                 }
  77.                 return value.replace(/\n/g, '<br>');
  78.             }
  79.             else {
  80.                 return `提示: 未安装硬盘或已直通硬盘控制器`;
  81.             }
  82.         }
  83.     },
复制代码
经过测试,主机中安装的每个硬盘,都需要一段单独的代码,注意修改响应的设备名称,就是类似“/dev/sda”、“/dev/nvme0n1”这样的名称,可以通过lsblk命令查看。

差点忘了,还要在命令行执行一下提权命令,不然也会出问题。
  1. chmod +s /usr/sbin/smartctl
复制代码

还需要调整下页面高度,不然会显示不完全。
pvemanagerlib.js中搜索widget.pveNodeStatus
  1. height: 300,
复制代码
这个高度值请大家自己根据自己的情况进行调整。
搜索gettext('Status') + ': ' + zpool
  1. height: 600,
复制代码
这个高度值网上很多教程都提到了需要改,但我测试的结果改了没用,所以我没改。大家可以自己尝试。


修改了Nodes.pm文件,需要使用命令行运行下面命令重启API代理守护进程使修改生效,仅修改js文件,无需运行。
  1. systemctl restart pveproxy
复制代码
温馨提示,浏览器测试修改效果别忘了Ctrl+F5。




评分

参与人数 1邪恶指数 +10 收起 理由
kpchan + 10 666

查看全部评分

 楼主| 发表于 2023-2-20 00:35 | 显示全部楼层
我再提供另一种显示温度方案,这个方案是将可执行命令获取的信息以json格式显示出来。我测试过这个方案是OK的。注意,代码中某些地方需要根据自己的情况修改。机械盘同样需要每块盘添加一段代码。
  1.      $res->{sensors_json} = `sensors -j`;
  2.      $res->{smartctl_nvme_json} = `smartctl -a -j /dev/nvme?`;
  3.      $res->{smartctl_sda_json} = `smartctl -i -n standby /dev/sda|grep "STANDBY" || smartctl -i -n standby /dev/sda|grep "No such device" || smartctl -a -j /dev/sda`;
  4.      $res->{smartctl_sdb_json} = `smartctl -i -n standby /dev/sdb|grep "STANDBY" || smartctl -i -n standby /dev/sdb|grep "No such device" || smartctl -a -j /dev/sdb`;
复制代码
  1.     {
  2.     itemId: 'thermal',
  3.     colspan: 2,
  4.     printBar: false,
  5.     title: gettext('温度'),
  6.     textField: 'sensors_json',
  7.     renderer: function(value) {
  8.         value = JSON.parse(value);
  9.         const cpu0 = value['coretemp-isa-0000']['Package id 0']['temp1_input'].toFixed(1);
  10.         const PECI0 = value['nct6798-isa-0290']['PECI Agent 0']['temp7_input'].toFixed(1);
  11.         const pch = value['pch_cometlake-virtual-0']['temp1']['temp1_input'].toFixed(1);
  12.         return `CPU: ${cpu0}°C || 南桥: ${pch} ℃ | 网卡: ${PECI0} ℃`;
  13.     }
  14. },
  15. {
  16.     itemId: 'thermal',
  17.     colspan: 2,
  18.     printBar: false,
  19.     title: gettext('温度'),
  20.     textField: 'sensors_json',
  21.     renderer: function(value) {
  22.         value = value.replace(/temp([0-9]{1,})_input/g,'input');
  23.         // Intel
  24.         if (value.indexOf("coretemp-isa") != -1 ) {
  25.             value = value.replace(/coretemp-isa-(.{4})/g,'coretemp-isa');
  26.             value = value.replace(/nct6798-isa-(.{4})/g,'nct6798-isa');
  27.             value = JSON.parse(value);
  28.             try {var cpu_Intel = 'CPU: ' + value['coretemp-isa']['Package id 0']['input'].toFixed(1) + '°C';} catch(e) {var cpu_Intel = '';}
  29.             try {var acpi = ' || 主板:  ' + value['acpitz-acpi-0']['temp1']['input'].toFixed(1) + '°C';} catch(e) {var acpi = '';}
  30.             try {var pch = ' || 南桥:  ' + value['pch_cometlake-virtual-0']['temp1']['input'].toFixed(1) + '°C';} catch(e) {var pch = '';}
  31.             try {var pci0 = ' || 网卡:  ' + value['nct6798-isa']['PECI Agent 0']['input'].toFixed(1) + '°C';} catch(e) {var pci0 = '';}
  32.             if (cpu_Intel.length > 0 && pch.length + acpi.length + pci0.length > 0) {
  33.                 return `${cpu_Intel}${acpi}${pch}${pci0}`;
  34.             } else if (cpu_Intel.length > 0) {
  35.                 try {var cpu0 = ' || 核心 0 : ' + value['coretemp-isa']['Core 0']['input'].toFixed(1) + '°C';} catch(e) {var cpu0 = '';}
  36.                 try {var cpu1 = ' | 核心 1 : ' + value['coretemp-isa']['Core 1']['input'].toFixed(1) + '°C';} catch(e) {var cpu1 = '';}
  37.                 try {var cpu2 = ' | 核心 2 : ' + value['coretemp-isa']['Core 2']['input'].toFixed(1) + '°C';} catch(e) {var cpu2 = '';}
  38.                 try {var cpu3 = ' | 核心 3 : ' + value['coretemp-isa']['Core 3']['input'].toFixed(1) + '°C';} catch(e) {var cpu3 = '';}
  39.                 try {var cpu4 = ' | 核心 4 : ' + value['coretemp-isa']['Core 4']['input'].toFixed(1) + '°C';} catch(e) {var cpu4 = '';}
  40.                 try {var cpu5 = ' | 核心 5 : ' + value['coretemp-isa']['Core 5']['input'].toFixed(1) + '°C';} catch(e) {var cpu5 = '';}
  41.                 try {var cpu6 = ' | 核心 6 : ' + value['coretemp-isa']['Core 6']['input'].toFixed(1) + '°C';} catch(e) {var cpu6 = '';}
  42.                 try {var cpu7 = ' | 核心 7 : ' + value['coretemp-isa']['Core 7']['input'].toFixed(1) + '°C';} catch(e) {var cpu7 = '';}
  43.                 return `${cpu_Intel}${cpu0}${cpu1}${cpu2}${cpu3}${cpu4}${cpu5}${cpu6}${cpu7}`;
  44.             }
  45.         // AMD
  46.         } else if (value.indexOf("amdgpu-pci") != -1 ) {
  47.             value = value.replace(/k10temp-pci-(.{4})/g,'k10temp-pci');
  48.             value = value.replace(/zenpower-pci-(.{4})/g,'zenpower-pci');
  49.             value = value.replace(/amdgpu-pci-(.{4})/g,'amdgpu-pci');
  50.             value = JSON.parse(value);
  51.             try {var cpu_amd_k10 = 'CPU: ' + value['k10temp-pci']['Tctl']['input'].toFixed(1) + '°C';} catch(e) {var cpu_amd_k10 = '';}
  52.             try {var cpu_amd_zen = 'CPU: ' + value['zenpower-pci']['Tctl']['input'].toFixed(1) + '°C';} catch(e) {var cpu_amd_zen = '';}
  53.             try {var amdgpu = ' | GPU:  ' + value['amdgpu-pci']['edge']['input'].toFixed(1) + '°C';} catch(e) {var amdgpu = '';}
  54.             return `${cpu_amd_k10}${cpu_amd_zen}${amdgpu}`;
  55.         } else {
  56.             return `提示: CPU 及 主板 温度读取异常`;
  57.         }
  58.     }
  59. },
  60. {        
  61.     itemId: 'nvme_ssd',
  62.     colspan: 2,
  63.     printBar: false,
  64.     title: gettext('NVME'),
  65.     textField: 'smartctl_nvme_json',
  66.     renderer: function(value) {
  67.         value = JSON.parse(value);
  68.         if (value['model_name']) {
  69.             try {var model_name = value['model_name'];} catch(e) {var model_name = '';}
  70.             try {var percentage_used = ' | 使用寿命: ' + value['nvme_smart_health_information_log']['percentage_used'].toFixed(0) + '% ';} catch(e) {var percentage_used = '';}
  71.             try {var data_units_read = value['nvme_smart_health_information_log']['data_units_read']*512/1024/1024/1024;var data_units_read = '(读: ' + data_units_read.toFixed(2) + 'TB, ';} catch(e) {var data_units_read = '';}
  72.             try {var data_units_written = value['nvme_smart_health_information_log']['data_units_written']*512/1024/1024/1024;var data_units_written = '写: ' + data_units_written.toFixed(2) + 'TB)';} catch(e) {var data_units_written = '';}
  73.             try {var power_on_time = ' | 通电: ' + value['power_on_time']['hours'].toFixed(0) + '小时';} catch(e) {var power_on_time = '';}
  74.             try {var temperature = ' | 温度: ' + value['temperature']['current'].toFixed(1) + '°C';} catch(e) {var temperature = '';}
  75.             return `${model_name}${percentage_used}${data_units_read}${data_units_written}${power_on_time}${temperature}`;
  76.         } else {
  77.             return `提示: 未安装硬盘或已直通硬盘控制器`;
  78.         }
  79.     }
  80. },
  81. {
  82.     itemId: 'SATA_sda',
  83.     colspan: 2,
  84.     printBar: false,
  85.     title: gettext('SATA_sda'),
  86.     textField: 'smartctl_sda_json',
  87.     renderer: function(value) {
  88.         if (value.indexOf("Device is in STANDBY mode") != -1 ) {
  89.             return `提示: 磁盘休眠中`;
  90.         } else if (value.indexOf("No such device") != -1 ) {
  91.             return `提示: 未安装硬盘或已直通硬盘控制器`;
  92.         } else {
  93.         value = JSON.parse(value);
  94.             try {var model_name = value['model_name'];} catch(e) {var model_name = '';}
  95.             try {var user_capacity = value['user_capacity']['bytes']/1024/1024/1024;var user_capacity = ' | 容量: ' + user_capacity.toFixed(2) + ' GB';} catch(e) {var user_capacity = '';}
  96.             try {var power_on_time = ' | 已通电: ' + value['power_on_time']['hours'].toFixed(0) + ' 小时';} catch(e) {var power_on_time = '';}
  97.             try {var error_count = value['ata_smart_error_log']['summary']['count'].toFixed(0);if (error_count != 0){error_count = ' | 磁盘错误: ' + error_count;} else {var error_count = '';} } catch(e) {var error_count = '';}
  98.             try {var self_count = value['ata_smart_self_test_log']['standard']['count'].toFixed(0);if (self_count != 0){self_count = ' | 自检错误: ' + self_count;} else {var self_count = '';} } catch(e) {var self_count = '';}
  99.             try {var temperature = ' | 温度: ' + value['temperature']['current'].toFixed(1) + '°C';} catch(e) {var temperature = '';}
  100.             return `${model_name}${user_capacity}${power_on_time}${error_count}${self_count}${temperature}`;
  101.         }
  102.     }
  103. },
  104. {
  105.     itemId: 'SATA_sdb',
  106.     colspan: 2,
  107.     printBar: false,
  108.     title: gettext('SATA_sdb'),
  109.     textField: 'smartctl_sdb_json',
  110.     renderer: function(value) {
  111.         if (value.indexOf("Device is in STANDBY mode") != -1 ) {
  112.             return `提示: 磁盘休眠中`;
  113.         } else if (value.indexOf("No such device") != -1 ) {
  114.             return `提示: 未安装硬盘或已直通硬盘控制器`;
  115.         } else {
  116.         value = JSON.parse(value);
  117.             try {var model_name = value['model_name'];} catch(e) {var model_name = '';}
  118.             try {var user_capacity = value['user_capacity']['bytes']/1024/1024/1024;var user_capacity = ' | 容量: ' + user_capacity.toFixed(2) + ' GB';} catch(e) {var user_capacity = '';}
  119.             try {var power_on_time = ' | 已通电: ' + value['power_on_time']['hours'].toFixed(0) + ' 小时';} catch(e) {var power_on_time = '';}
  120.             try {var error_count = value['ata_smart_error_log']['summary']['count'].toFixed(0);if (error_count != 0){error_count = ' | 磁盘错误: ' + error_count;} else {var error_count = '';} } catch(e) {var error_count = '';}
  121.             try {var self_count = value['ata_smart_self_test_log']['standard']['count'].toFixed(0);if (self_count != 0){self_count = ' | 自检错误: ' + self_count;} else {var self_count = '';} } catch(e) {var self_count = '';}
  122.             try {var temperature = ' | 温度: ' + value['temperature']['current'].toFixed(1) + '°C';} catch(e) {var temperature = '';}
  123.             return `${model_name}${user_capacity}${power_on_time}${error_count}${self_count}${temperature}`;
  124.         }
  125.     }
  126. },
复制代码

评分

参与人数 1邪恶指数 +10 收起 理由
kpchan + 10 666

查看全部评分

 楼主| 发表于 2023-2-20 00:37 | 显示全部楼层
发表于 2023-2-20 00:43 来自手机 | 显示全部楼层
我觉得你可以多写一些网上比较少的东西。譬如显卡虚化,sriov,ceph,core affinity之类的。pve的网页管理,其实你用一段时间之后,就很少登陆了。用ssh敲命令更快。
 楼主| 发表于 2023-2-20 01:17 | 显示全部楼层
summerq 发表于 2023-2-20 00:43
我觉得你可以多写一些网上比较少的东西。譬如显卡虚化,sriov,ceph,core affinity之类的。pve的网页管理 ...

我这些帖子是我折腾NAS的一个总结。这些内容看似网上很多,但实际上大多数帖子同质化相当严重,讲述的内容存在不讲原理,方案不合理、过时等问题,经过我的实践,会有很多问题。比如硬盘温度的显示,网上的帖子都是推荐使用一个hdtemp的软件,获取的信息非常少,远不如我帖子里的方案,而我这些方案虽然也是搜到的,但得到这些相当不容易。另外对于小白用户,命令行绝对不如界面方便。硬件直通等内容我后续会发。总之我不会单纯的发些网上很容易就找到的东西。

评分

参与人数 1邪恶指数 +5 收起 理由
summerq + 5 谢谢您的辛苦努力

查看全部评分

发表于 2023-2-20 10:23 | 显示全部楼层
lk_yeah 发表于 2023-2-20 01:17
我这些帖子是我折腾NAS的一个总结。这些内容看似网上很多,但实际上大多数帖子同质化相当严重,讲述的内 ...


确实这样  碎片化太严重了


建议按需求 按习惯的步骤 自己写一个笔记,方便后期维护
发表于 2023-2-20 11:22 | 显示全部楼层
牛逼就是牛逼
发表于 2023-2-20 11:46 | 显示全部楼层
我记得好像有推荐使用pve tool这款工具的
发表于 2023-2-20 12:02 | 显示全部楼层
Snipaste_2023-02-20_12-01-44.jpg
我是黑群晖 为什么只显示了CPU的参数啊,请教大佬
 楼主| 发表于 2023-2-21 00:27 | 显示全部楼层
本帖最后由 lk_yeah 于 2023-2-21 00:37 编辑
wangluowl 发表于 2023-2-20 12:02
我是黑群晖 为什么只显示了CPU的参数啊,请教大佬


运行一遍sensors-detect,如果还是检测不出其他硬件,那么应该是没有加载相应驱动。群晖本身并不是个完整的Linux,缺少驱动也很正常吧。
发表于 2023-2-21 13:44 | 显示全部楼层
我也是用的pvetools 这款软件(脚本) 装的传感器和vim, 不过只能显示CPU core的温度
发表于 2023-2-24 15:59 | 显示全部楼层
这个温度啥的显示的确是最麻烦的,需要按个人不同设置。不明白原理错一步都不行,这玩意真觉得pve应该内置
发表于 2023-2-26 10:26 | 显示全部楼层
跟着大佬学了不少东西。自己也在组PVE的系统,非常有帮助。
发表于 2023-7-27 09:48 | 显示全部楼层
牛逼就是牛逼
发表于 2023-7-27 10:58 | 显示全部楼层
看不懂
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

Archiver|手机版|小黑屋|Chiphell ( 沪ICP备12027953号-5 )沪公网备310112100042806 上海市互联网违法与不良信息举报中心

GMT+8, 2024-11-28 06:33 , Processed in 0.012926 second(s), 7 queries , Gzip On, Redis On.

Powered by Discuz! X3.5 Licensed

© 2007-2024 Chiphell.com All rights reserved.

快速回复 返回顶部 返回列表