I’ve written this guide showing some tweaks that you can do to add Real-Time CPU Temperature to Proxmox Dashboard Summary.

Step 1: Open the Proxmox shell tab

Step 2: Type in the shell “apt install lm-sensors”.
apt install lm-sensors
To test if it’s working, type in “sensors” to the shell.
The output should look like this:
root@pve:~# sensors
coretemp-isa-0000
Adapter: ISA adapter
Package id 0: +42.0°C (high = +100.0°C, crit = +100.0°C)
Core 0: +42.0°C (high = +100.0°C, crit = +100.0°C)
Core 1: +41.0°C (high = +100.0°C, crit = +100.0°C)
Core 2: +42.0°C (high = +100.0°C, crit = +100.0°C)
Core 3: +43.0°C (high = +100.0°C, crit = +100.0°C)
acpitz-acpi-0
Adapter: ACPI interface
temp1: +27.8°C (crit = +119.0°C)
temp2: +29.8°C (crit = +119.0°C)
pch_skylake-virtual-0
Adapter: Virtual device
temp1: +40.0°C
Step 3: Adding the sensors, from the shell using Nano to edit Nodes.pm file. Type in “nano /usr/share/perl5/PVE/API2/Nodes.pm”.
nano /usr/share/perl5/PVE/API2/Nodes.pm
Step 4: Press F6 to search for “my $dinfo” and then press Enter, then look for the code it should look like this.
$res->{pveversion} = PVE::pvecfg::package() . "/" .
PVE::pvecfg::version_text();
my $dinfo = df('/', 1); # output is bytes
$res->{thermalstate} = \sensors\;
Add “$res->{thermalstate} = \sensors\;
” to the following line of code so the final result should look like this.
$res->{pveversion} = PVE::pvecfg::package() . "/" .
PVE::pvecfg::version_text();
$res->{thermalstate} = `sensors`;
my $dinfo = df('/', 1); # output is bytes
Save and exit.
Step 5: Adding the sensor’s information to the dashboard, from the shell type in “nano /usr/share/pve-manager/js/pvemanagerlib.js”
Step 6: Press F6 to search for my “widget.pveNodeStatus” and press Enter, then look for the snippet of code like this.
Ext.define('PVE.node.StatusView', {
extend: 'PVE.panel.StatusView',
alias: 'widget.pveNodeStatus',
height: 300,
bodyPadding: '15 5 15 5',
layout: {
type: 'table',
columns: 2,
tableAttrs: {
style: {
width: '100%'
}
}
},
Step 7: Next change the bodyPadding: '15 5 15 5',
to bodyPadding: '15 20 15 20',
As well as height: 300,
to height: 360,
so it looks like the section of code below.
Ext.define('PVE.node.StatusView', {
extend: 'PVE.panel.StatusView',
alias: 'widget.pveNodeStatus',
height: 360,
bodyPadding: '15 20 15 20',
layout: {
type: 'table',
columns: 2,
tableAttrs: {
style: {
width: '100%'
}
}
},
Step 8: Press F6 to search for “PVE Manager Version” and press Enter.
{
itemId: 'version',
colspan: 2,
printBar: false,
title: gettext('PVE Manager Version'),
textField: 'pveversion',
value: ''
}
Step 9: Add the code below after version item id,
{
itemId: 'thermal',
colspan: 2,
printBar: false,
title: gettext('CPU Thermal State'),
textField: 'thermalstate',
renderer:function(value){
const c0 = value.match(/Core 0.*?\+([\d\.]+)Â/)[1];
const c1 = value.match(/Core 1.*?\+([\d\.]+)Â/)[1];
const c2 = value.match(/Core 2.*?\+([\d\.]+)Â/)[1];
const c3 = value.match(/Core 3.*?\+([\d\.]+)Â/)[1];
return `Core 0: ${c0} ℃ | Core 1: ${c1} ℃ | Core 2: ${c2} ℃ | Core 3: ${c3} ℃`
}
}
The final result should look something like this.
{
itemId: 'version',
colspan: 2,
printBar: false,
title: gettext('PVE Manager Version'),
textField: 'pveversion',
value: ''
},
{
itemId: 'thermal',
colspan: 2,
printBar: false,
title: gettext('CPU Thermal State'),
textField: 'thermalstate',
renderer:function(value){
const c0 = value.match(/Core 0.*?\+([\d\.]+)Â/)[1];
const c1 = value.match(/Core 1.*?\+([\d\.]+)Â/)[1];
const c2 = value.match(/Core 2.*?\+([\d\.]+)Â/)[1];
const c3 = value.match(/Core 3.*?\+([\d\.]+)Â/)[1];
return `Core 0: ${c0} ℃ | Core 1: ${c1} ℃ | Core 2: ${c2} ℃ | Core 3: ${c3} ℃`
}
}
Save and exit.
Step 10: Restart the services by typing in the shell the following command: “systemctl restart pveproxy”, it may kick you out of the shell or freeze the webpage, don’t worry this is normal! Just refresh your web browser.
Credit to the Reddit posting on this topic by Agreeable-Clue83.