This guide explains how to add sensor temperatures to the Proxmox GUI, including all the necessary steps and code.
In this guide, you will learn how to add the CPU core temperatures, motherboard temperature, and NVMe drive temperatures to the Proxmox GUI.
Ensure you have the following:
First, you need to install lm-sensors if they are not already installed.
apt-get update
apt-get install lm-sensors
Modify the /usr/share/perl5/PVE/API2/Nodes.pm file to gather sensor data.
Open the file with a text editor:
`nano /usr/share/perl5/PVE/API2/Nodes.pm
Find the section with version_text and add the following code to collect sensor data:
$res->{thermalstate} = `sensors -j`;
Next, update the /usr/share/pve-manager/js/pvemanagerlib.js file to parse and display the sensor data.
Open the file with a text editor:
nano /usr/share/pve-manager/js/pvemanagerlib.js
Add the following code to create new entries for the sensor temperatures:
{
itemId: 'coreTemps',
colspan: 2,
printBar: false,
title: gettext('CPU Core Temps'),
textField: 'thermalstate',
renderer: function(value) {
if (!value) return 'N/A';
let objValue = JSON.parse(value);
let cores = objValue["coretemp-isa-0000"];
let coreItems = Object.keys(cores).filter(item => /Core/.test(item));
let coreTemps = '';
coreItems.forEach((core) => {
let tempKey = Object.keys(cores[core]).filter(key => key.includes('temp'))[0];
coreTemps += '<b>' + cores[core][tempKey] + ' °C</b> ';
});
return coreTemps.trim();
}
},
{
itemId: 'mbNvmeTemps',
colspan: 2,
printBar: false,
title: gettext('Motherboard and NVMe Temps'),
textField: 'thermalstate',
renderer: function(value) {
if (!value) return 'N/A';
let objValue = JSON.parse(value);
let temps = '';
// Motherboard Temp
if (objValue["acpitz-acpi-0"] && objValue["acpitz-acpi-0"].temp1) {
temps += 'Motherboard: <b>' + objValue["acpitz-acpi-0"].temp1.temp1_input + ' °C</b> ';
} else {
temps += 'Motherboard: N/A ';
}
// NVMe Drive 1 Temps
if (objValue["nvme-pci-0100"]) {
temps += '|| NVMe1: ';
let nvme1Temps = [];
for (let key in objValue["nvme-pci-0100"]) {
if (objValue["nvme-pci-0100"][key].hasOwnProperty('temp1_input')) {
nvme1Temps.push('<b>' + objValue["nvme-pci-0100"][key]['temp1_input'] + ' °C</b>');
}
if (objValue["nvme-pci-0100"][key].hasOwnProperty('temp2_input')) {
nvme1Temps.push('<b>' + objValue["nvme-pci-0100"][key]['temp2_input'] + ' °C</b>');
}
if (objValue["nvme-pci-0100"][key].hasOwnProperty('temp3_input')) {
nvme1Temps.push('<b>' + objValue["nvme-pci-0100"][key]['temp3_input'] + ' °C</b>');
}
}
temps += nvme1Temps.join(' - ');
} else {
temps += '|| NVMe1: N/A ';
}
// NVMe Drive 2 Temps
if (objValue["nvme-pci-0200"]) {
temps += '|| NVMe2: ';
let nvme2Temps = [];
for (let key in objValue["nvme-pci-0200"]) {
if (objValue["nvme-pci-0200"][key].hasOwnProperty('temp1_input')) {
nvme2Temps.push('<b>' + objValue["nvme-pci-0200"][key]['temp1_input'] + ' °C</b>');
}
if (objValue["nvme-pci-0200"][key].hasOwnProperty('temp2_input')) {
nvme2Temps.push('<b>' + objValue["nvme-pci-0200"][key]['temp2_input'] + ' °C</b>');
}
if (objValue["nvme-pci-0200"][key].hasOwnProperty('temp3_input')) {
nvme2Temps.push('<b>' + objValue["nvme-pci-0200"][key]['temp3_input'] + ' °C</b>');
}
}
temps += nvme2Temps.join(' - ');
} else {
temps += '|| NVMe2: N/A ';
}
return temps.trim();
}
}
After making these changes, restart the pveproxy service to apply the updates.
systemctl restart pveproxy
{
itemId: 'coreTemps',
colspan: 2,
printBar: false,
title: gettext('CPU Core Temps'),
textField: 'thermalstate',
renderer: function(value) {
if (!value) return 'N/A';
let objValue = JSON.parse(value);
let cores = objValue["coretemp-isa-0000"];
let coreItems = Object.keys(cores).filter(item => /Core/.test(item));
let coreTemps = '';
coreItems.forEach((core) => {
let tempKey = Object.keys(cores[core]).filter(key => key.includes('temp'))[0];
coreTemps += '<b>' + cores[core][tempKey] + ' °C</b> ';
});
return coreTemps.trim();
}
},
{
itemId: 'mbNvmeTemps',
colspan: 2,
printBar: false,
title: gettext('Motherboard and NVMe Temps'),
textField: 'thermalstate',
renderer: function(value) {
if (!value) return 'N/A';
let objValue = JSON.parse(value);
let temps = '';
// Motherboard Temp
if (objValue["acpitz-acpi-0"] && objValue["acpitz-acpi-0"].temp1) {
temps += 'Motherboard: <b>' + objValue["acpitz-acpi-0"].temp1.temp1_input + ' °C</b> ';
} else {
temps += 'Motherboard: N/A ';
}
// NVMe Drive 1 Temps
if (objValue["nvme-pci-0100"]) {
temps += '|| NVMe1: ';
let nvme1Temps = [];
for (let key in objValue["nvme-pci-0100"]) {
if (objValue["nvme-pci-0100"][key].hasOwnProperty('temp1_input')) {
nvme1Temps.push('<b>' + objValue["nvme-pci-0100"][key]['temp1_input'] + ' °C</b>');
}
if (objValue["nvme-pci-0100"][key].hasOwnProperty('temp2_input')) {
nvme1Temps.push('<b>' + objValue["nvme-pci-0100"][key]['temp2_input'] + ' °C</b>');
}
if (objValue["nvme-pci-0100"][key].hasOwnProperty('temp3_input')) {
nvme1Temps.push('<b>' + objValue["nvme-pci-0100"][key]['temp3_input'] + ' °C</b>');
}
}
temps += nvme1Temps.join(' - ');
} else