Dynamic display of temperatures for all CPU cores, NVMe drives and HDD/SSDs (#2)
* Dynamic temperatures display for all CPU cores and NVMe drives. * Panel height made adjustable. * Degree sign added. * Vertical alignment set to 'top' for all rows in the panel. * Support for HDD/SSD temparatures added (requires kernel module drivetemp). * Move sensor config to beginning of script. * Warn user if drivetemp kernal module is not installed * Save sensor -j reading into a single variable that all temps are read from * Update readme to new changes
This commit is contained in:
parent
f3fcec1a44
commit
1469e64ba7
@ -7,6 +7,14 @@ nodespm="/usr/share/perl5/PVE/API2/Nodes.pm"
|
|||||||
backuplocation="/root/backup"
|
backuplocation="/root/backup"
|
||||||
timestamp=$(date '+%Y-%m-%d_%H-%M-%S')
|
timestamp=$(date '+%Y-%m-%d_%H-%M-%S')
|
||||||
|
|
||||||
|
# Sensor configuration
|
||||||
|
# CPU. See tempN_in put for "Core 0" using sensor -j
|
||||||
|
CPUtempInputOffset="2";
|
||||||
|
|
||||||
|
# Display configuration for HDD, NVME, CPU
|
||||||
|
CPUPerRow="4";
|
||||||
|
HDDPerRow="4";
|
||||||
|
NVMEPerRow="4";
|
||||||
|
|
||||||
################### code below #############
|
################### code below #############
|
||||||
echo ""
|
echo ""
|
||||||
@ -44,12 +52,18 @@ install_packages () {
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Check if kernal module drivetemp is installed
|
||||||
|
if (lsmod | grep -wq "drivetemp"); then
|
||||||
|
echo "The drivetemp kernel module is installed."
|
||||||
|
else
|
||||||
|
echo "Warning: The drivetemp kernel module is not installed. HDD temps will not be available"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Call the 'install_packages' function to check if lm-sensors is installed and install it if necessary
|
# Call the 'install_packages' function to check if lm-sensors is installed and install it if necessary
|
||||||
install_packages
|
install_packages
|
||||||
|
|
||||||
|
|
||||||
# Function to install the modification
|
# Function to install the modification
|
||||||
function install_mod {
|
function install_mod {
|
||||||
# Create backup of original files
|
# Create backup of original files
|
||||||
@ -61,7 +75,7 @@ function install_mod {
|
|||||||
cp "$nodespm" "$backuplocation/Nodes.pm.$timestamp"
|
cp "$nodespm" "$backuplocation/Nodes.pm.$timestamp"
|
||||||
echo "Backup of $nodespm saved to $backuplocation/Nodes.pm.$timestamp"
|
echo "Backup of $nodespm saved to $backuplocation/Nodes.pm.$timestamp"
|
||||||
|
|
||||||
sed -i '/my $dinfo = df('\''\/'\'', 1);/i\'$'\t''$res->{thermalstate} = `sensors -j`;\n'$'\t''$res->{thermalstate2} = `sensors -j`;\n' "$nodespm"
|
sed -i '/my $dinfo = df('\''\/'\'', 1);/i\'$'\t''$res->{thermalstate} = `sensors -j`;\n' "$nodespm"
|
||||||
echo "Added thermalstate to $nodespm"
|
echo "Added thermalstate to $nodespm"
|
||||||
else
|
else
|
||||||
echo "Thermalstate already added to $nodespm"
|
echo "Thermalstate already added to $nodespm"
|
||||||
@ -72,11 +86,12 @@ function install_mod {
|
|||||||
# Create backup of original file
|
# Create backup of original file
|
||||||
cp "$pvemanagerlib" "$backuplocation/pvemanagerlib.js.$timestamp"
|
cp "$pvemanagerlib" "$backuplocation/pvemanagerlib.js.$timestamp"
|
||||||
echo "Backup of $pvemanagerlib saved to $backuplocation/pvemanagerlib.js.$timestamp"
|
echo "Backup of $pvemanagerlib saved to $backuplocation/pvemanagerlib.js.$timestamp"
|
||||||
|
|
||||||
# Expand space in StatusView
|
# Expand space in StatusView
|
||||||
sed -i "/Ext.define('PVE\.node\.StatusView'/,/\},/ {
|
sed -i "/Ext.define('PVE\.node\.StatusView'/,/\},/ {
|
||||||
s/\(bodyPadding:\) '[^']*'/\1 '20 15 20 15'/
|
s/\(bodyPadding:\) '[^']*'/\1 '20 15 20 15'/
|
||||||
s/\(height:\) [0-9]\+/\1 360/}" "$pvemanagerlib"
|
s/height: [0-9]\+/minHeight: 360,\n\tflex: 1/
|
||||||
|
s/\(tableAttrs:.*$\)/trAttrs: \{ valign: 'top' \},\n\t\1/}" "$pvemanagerlib"
|
||||||
|
|
||||||
echo "Expanded space in $pvemanagerlib"
|
echo "Expanded space in $pvemanagerlib"
|
||||||
|
|
||||||
@ -95,12 +110,29 @@ function install_mod {
|
|||||||
iconCls: 'fa fa-fw fa-thermometer-half',\n\
|
iconCls: 'fa fa-fw fa-thermometer-half',\n\
|
||||||
textField: 'thermalstate',\n\
|
textField: 'thermalstate',\n\
|
||||||
renderer: function(value){\n\
|
renderer: function(value){\n\
|
||||||
let objValue = JSON.parse(value);\n\
|
// sensors configuration\n\
|
||||||
let core0 = objValue[\"coretemp-isa-0000\"][\"Core 0\"][\"temp2_input\"];\n\
|
const address = \"coretemp-isa-0000\",\n\
|
||||||
let core1 = objValue[\"coretemp-isa-0000\"][\"Core 1\"][\"temp3_input\"];\n\
|
itemPrefix = \"Core \",\n\
|
||||||
let core2 = objValue[\"coretemp-isa-0000\"][\"Core 2\"][\"temp4_input\"];\n\
|
tempInputOffset = $CPUtempInputOffset; // see tempN_input for \"Core 0\"\n\
|
||||||
let core3 = objValue[\"coretemp-isa-0000\"][\"Core 3\"][\"temp5_input\"];\n\
|
// display configuration\n\
|
||||||
return \`Core 0: \$\{core0\} C | Core 1: \$\{core1\} C | Core 2: \$\{core2\} C | Core 3: \$\{core3\} C\`\n\
|
const coresPerRow = $CPUPerRow;\n\
|
||||||
|
\n\
|
||||||
|
const objValue = JSON.parse(value);\n\
|
||||||
|
if(objValue.hasOwnProperty(address)) \{\n\
|
||||||
|
const items = objValue[address],\n\
|
||||||
|
coreKeys = Object.keys(items).filter(item => \{ return String(item).startsWith(itemPrefix); \}).sort();\n\
|
||||||
|
\n\
|
||||||
|
let temps = [];\n\
|
||||||
|
coreKeys.forEach((coreKey, index) => \{\n\
|
||||||
|
try \{\n\
|
||||||
|
let temp = items[itemPrefix + index][\`temp\$\{tempInputOffset + index\}_input\`];\n\
|
||||||
|
temps.push(\`Core \$\{index\}: \$\{temp\}°C\`);\n\
|
||||||
|
\} catch(e) \{ /*_*/ \}\n\
|
||||||
|
});\n\
|
||||||
|
\n\
|
||||||
|
const result = temps.map((strTemp, index, arr) => { return strTemp + (index + 1 < arr.length ? ((index + 1) % coresPerRow === 0 ? '<br>' : ' | ') : '')});\n\
|
||||||
|
return result.length > 0 ? result.join('') : 'N/A';\n\
|
||||||
|
\}\n\
|
||||||
}\n\
|
}\n\
|
||||||
},\n\
|
},\n\
|
||||||
{\n\
|
{\n\
|
||||||
@ -109,11 +141,63 @@ function install_mod {
|
|||||||
printBar: false,\n\
|
printBar: false,\n\
|
||||||
title: gettext('NVME Thermal State'),\n\
|
title: gettext('NVME Thermal State'),\n\
|
||||||
iconCls: 'fa fa-fw fa-thermometer-half',\n\
|
iconCls: 'fa fa-fw fa-thermometer-half',\n\
|
||||||
textField: 'thermalstate2',\n\
|
textField: 'thermalstate',\n\
|
||||||
renderer: function(value){\n\
|
renderer: function(value){\n\
|
||||||
let objValue = JSON.parse(value);\n\
|
// sensors configuration\n\
|
||||||
let temp0 = objValue[\"nvme-pci-0100\"][\"Composite\"][\"temp1_input\"];\n\
|
const addressPrefix = \"nvme-pci-\",\n\
|
||||||
return \`NVME: \$\{temp0\} C\`\n\
|
sensorName = \"Composite\",\n\
|
||||||
|
tempInputNo = 1;\n\
|
||||||
|
// display configuration\n\
|
||||||
|
const drivesPerRow = $NVMEPerRow;\n\
|
||||||
|
\n\
|
||||||
|
const objValue = JSON.parse(value),\n\
|
||||||
|
nvmeKeys = Object.keys(objValue).filter(item => \{ return String(item).startsWith(addressPrefix); \}).sort();\n\
|
||||||
|
\n\
|
||||||
|
let temps = [];\n\
|
||||||
|
nvmeKeys.forEach((nvmeKey, index) => \{\n\
|
||||||
|
try \{\n\
|
||||||
|
let temp = objValue[nvmeKey][sensorName][\`temp\$\{tempInputNo\}_input\`];\n\
|
||||||
|
temps.push(\`Drive \$\{index\}: \$\{temp\}°C\`);\n\
|
||||||
|
\} catch(e) \{ /*_*/ \}\n\
|
||||||
|
\});\n\
|
||||||
|
\n\
|
||||||
|
const result = temps.map((strTemp, index, arr) => \{ return strTemp + (index + 1 < arr.length ? ((index + 1) % drivesPerRow === 0 ? '<br>' : ' | ') : '')\});\n\
|
||||||
|
return result.length > 0 ? result.join('') : 'N/A';\n\
|
||||||
|
\}\n\
|
||||||
|
},\n\
|
||||||
|
{\n\
|
||||||
|
xtype: 'box',\n\
|
||||||
|
colspan: 1,\n\
|
||||||
|
padding: '0 0 20 0',\n\
|
||||||
|
},\n\
|
||||||
|
{\n\
|
||||||
|
itemId: 'thermal3',\n\
|
||||||
|
colspan: 1,\n\
|
||||||
|
printBar: false,\n\
|
||||||
|
title: gettext('HDD/SSD Thermal State'),\n\
|
||||||
|
iconCls: 'fa fa-fw fa-thermometer-half',\n\
|
||||||
|
textField: 'thermalstate',\n\
|
||||||
|
renderer: function(value){\n\
|
||||||
|
// sensors configuration\n\
|
||||||
|
const addressPrefix = \"drivetemp-scsi-\",\n\
|
||||||
|
sensorName = \"temp1\",\n\
|
||||||
|
tempInputNo = 1;\n\
|
||||||
|
// display configuration\n\
|
||||||
|
const drivesPerRow = $HDDPerRow;\n\
|
||||||
|
\n\
|
||||||
|
const objValue = JSON.parse(value),\n\
|
||||||
|
drvKeys = Object.keys(objValue).filter(item => { return String(item).startsWith(addressPrefix); }).sort();\n\
|
||||||
|
\n\
|
||||||
|
let temps = [];\n\
|
||||||
|
drvKeys.forEach((drvKey, index) => {\n\
|
||||||
|
try {\n\
|
||||||
|
let temp = objValue[drvKey][sensorName][\`temp\${tempInputNo}_input\`];\n\
|
||||||
|
temps.push(\`Drive \${index}: \${temp}°C\`);\n\
|
||||||
|
} catch(e) { /*_*/ }\n\
|
||||||
|
});\n\
|
||||||
|
\n\
|
||||||
|
const result = temps.map((strTemp, index, arr) => { return strTemp + (index + 1 < arr.length ? ((index + 1) % drivesPerRow === 0 ? '<br>' : ' | ') : '')});\n\
|
||||||
|
return result.length > 0 ? result.join('') : 'N/A';\n\
|
||||||
}\n\
|
}\n\
|
||||||
},
|
},
|
||||||
}" $pvemanagerlib
|
}" $pvemanagerlib
|
||||||
|
|||||||
14
readme.md
14
readme.md
@ -4,17 +4,19 @@ A small collection of script and mods for Proxmox
|
|||||||
If you find this helpful, a small donation is appreciated, [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=K8XPMSEBERH3W).
|
If you find this helpful, a small donation is appreciated, [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=K8XPMSEBERH3W).
|
||||||
|
|
||||||
## Node temperature view
|
## Node temperature view
|
||||||
(compatible with at least version 7.4-3)
|
(Test compatibility against 7.x & 8.0)
|
||||||
|
|
||||||
This bash script installs a modification to the Proxmox Virtual Environment (PVE) web user interface (UI) to display temperature information. Currently for a 4 core CPU and NVME. The modification includes three main steps:
|
This bash script installs a modification to the Proxmox Virtual Environment (PVE) web user interface (UI) to display temperature information in a flexible manner for CPU, NVME and HDDs/SSDs.
|
||||||
|
|
||||||
|
The modification includes three main steps:
|
||||||
|
|
||||||
1. Create backups of the original files located at `/usr/share/pve-manager/js/pvemanagerlib.js` and `/usr/share/perl5/PVE/API2/Nodes.pm` in the `/root/backup` directory.
|
1. Create backups of the original files located at `/usr/share/pve-manager/js/pvemanagerlib.js` and `/usr/share/perl5/PVE/API2/Nodes.pm` in the `/root/backup` directory.
|
||||||
2. Add a new line to the `Nodes.pm` file that reads the thermal state information of the host using the `sensors` command.
|
2. Add a new line to the `Nodes.pm` file that reads the thermal state information of the host using the `sensors` command.
|
||||||
3. Modify the `pvemanagerlib.js` file to expand the space in the StatusView and add a new item to the items array that displays the temperature information in Celsius for the CPU cores and the NVME drive.
|
3. Modify the `pvemanagerlib.js` file to expand the space in the StatusView and add a new item to the items array that displays the temperature information in Celsius for CPU, NVME and HDDs/SSDs.
|
||||||
|
|
||||||
The script provides two options: `install` and `uninstall`. The `install` option installs the modification, while the `uninstall` option removes it by copying the backup files to their original location. The script also restarts the `pveproxy` service to apply the changes.
|
The script provides two options: `install` and `uninstall`. The `install` option installs the modification, while the `uninstall` option removes it by copying the backup files to their original location. The script also restarts the `pveproxy` service to apply the changes.
|
||||||
|
|
||||||
Adjust the code to accommondate fewer/more cores withe the output of ```sensor -j``` and the parsing/posting of information in the code ```sed -i "/^Ext.define('PVE.node.StatusView'```
|
For HDDs/SSDs readings to work, the kernal module drivetemp must be installed.
|
||||||
|
|
||||||
### Install
|
### Install
|
||||||
```
|
```
|
||||||
@ -24,6 +26,8 @@ wget https://github.com/Meliox/PVE-mods/blob/main/pve-mod-gui-temp.sh
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
Adjustments are available in the first part of the script, where paths can be edited, cpucore offset and display information.
|
||||||
|
|
||||||
## Scrip to update all containers
|
## Scrip to update all containers
|
||||||
(compatible with all)
|
(compatible with all)
|
||||||
|
|
||||||
@ -35,4 +39,4 @@ Each container's log file is stored in $log_path and the main script log file is
|
|||||||
```
|
```
|
||||||
wget https://github.com/Meliox/PVE-mods/blob/main/updateallcontainers.sh
|
wget https://github.com/Meliox/PVE-mods/blob/main/updateallcontainers.sh
|
||||||
```
|
```
|
||||||
Can be added to cron for e.g. monthly update: ```0 6 1 * * /root/scripts/updateallcontainers.sh```
|
Can be added to cron for e.g. monthly update: ```0 6 1 * * /root/scripts/updateallcontainers.sh```
|
||||||
Loading…
Reference in New Issue
Block a user