Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b0d6bd4
first
Jan 3, 2026
092d155
add monitor to close collection, not fully working.
Jan 3, 2026
7b78e2a
Switchable debugger, consistent debug messages, refactor startup process
Jan 3, 2026
ea76402
next snapshot
Jan 3, 2026
e698160
first working copy collecting script
Jan 3, 2026
d6a6257
Another udpate
Jan 4, 2026
4020402
change gpu name
Jan 4, 2026
e661259
first step to update bash script
Jan 4, 2026
5893aae
Implement: get_nvidia_gpu_devices, parse_nvidia_gpu_line
Jan 5, 2026
f65d9d7
refactor _check_executable
Jan 5, 2026
5d7be36
implement sensors, incl. pretty names for cpu, hdd, nvme, ssd. Make u…
Jan 10, 2026
0d608ab
add pvemanagerlib.js for tracking changes
Jan 10, 2026
db653e4
Add UPS support. Refactor file namings
Jan 10, 2026
8b2609e
fix naming of pve mod worker
Jan 10, 2026
d0069f3
fix uniquenss of nvida and pid matching of collector processes
Jan 10, 2026
fb1cd27
adjustable data pull interval
Jan 10, 2026
a559fa5
refactor collector start
Jan 10, 2026
447f352
name process type
Jan 10, 2026
5a8ecfa
Refactor so that **`pve_mod_worker` alone spawns, tracks, and manages…
Jan 10, 2026
87a925a
prettify process names
Jan 10, 2026
80e7308
rename pve mod perl script
Jan 10, 2026
e860220
fix ups not working
Jan 10, 2026
25389e0
finalise NVIDA implementation as a combined call
Jan 11, 2026
5855e8b
update gui
Jan 11, 2026
f76a4c2
refactor read_sysfs
Jan 11, 2026
e19f917
rework gui
Jan 11, 2026
6fb9e1c
refactor nvidia collection and cleanup
Jan 11, 2026
7fdc556
implement filebased lm-sensors output
Jan 11, 2026
d751c58
refactor check_executable
Jan 11, 2026
4e7396d
refactor code
Jan 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 138 additions & 1 deletion pve-mod-gui-sensors.sh
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ function configure {
#endregion sensors collection

#### CPU ####
#region cpu setup
#region CPU setup
msgb "\n=== Detecting CPU temperature sensors ==="
ENABLE_CPU=false
local cpuList=""
Expand Down Expand Up @@ -195,6 +195,59 @@ function configure {
warn "No CPU temperature sensors found."
fi
#endregion cpu setup

#### Graphics ####
#region Graphics setup
msgb "\n=== Detecting Graphics information ==="

#region intel GPU setup
# Check for Intel GPU - ensure intel_gpu_top is installed
if command -v intel_gpu_top &>/dev/null; then
# detect all intel cards using intel_gpu_top -L. Show them line by line
local intelCards

# Get the output from intel_gpu_top -L, skip empty lines
intelCards=$(intel_gpu_top -L 2>/dev/null | grep -E '^card[0-9]+' || true)

if [[ -n "$intelCards" ]]; then
local cardCount=$(echo "$intelCards" | wc -l)
echo "Intel GPU(s) detected ($cardCount):"
echo "$intelCards" | while IFS= read -r line; do
# Extract card name, GPU model, and PCI info
if [[ $line =~ ^(card[0-9]+)[[:space:]]+(.+)[[:space:]]+pci:(.+)$ ]]; then
local cardName="${BASH_REMATCH[1]}"
local gpuModel="${BASH_REMATCH[2]}"
local pciInfo="${BASH_REMATCH[3]}"

echo " - Card: $cardName"
echo " Model: $gpuModel"
echo " PCI: $pciInfo"
else
# Fallback: just show the line as-is
echo " $line"
fi
done
ENABLE_INTEL_GPU_INFO=true
ENABLE_GPU_INFO=true
else
warn "No Intel GPUs detected by intel_gpu_top."
ENABLE_INTEL_GPU_INFO=false
fi
else
warn "intel_gpu_top command not found. Skipping Intel GPU information detection."
ENABLE_INTEL_GPU_INFO=false
fi
#endregion intel GPU setup

#region NVIDIA GPU setup
# not implemented yet
#endregion NVIDIA GPU setup

#region AMD GPU setup
# not implemented yet
#endregion AMD GPU setup

#endregion Graphics setup

#### RAM ####
#region ram setup
Expand Down Expand Up @@ -407,6 +460,7 @@ function install_mod {

generate_and_insert_widget "$ENABLE_SYSTEM_INFO" "generate_system_info" "system_info"
generate_and_insert_widget "$ENABLE_UPS" "generate_ups_widget" "ups"
generate_and_insert_widget "$ENABLE_GPU_INFO" "generate_gpu_widget" "gpu"
generate_and_insert_widget "$ENABLE_HDD_TEMP" "generate_hdd_widget" "hdd"
generate_and_insert_widget "$ENABLE_NVME_TEMP" "generate_nvme_widget" "nvme"

Expand Down Expand Up @@ -549,6 +603,10 @@ collect_ups_output() {
info "UPS retriever added to \"$output_file\"."
}

collect_graphics_intel_output() {


}

# Collect system information
collect_system_info() {
Expand Down Expand Up @@ -700,6 +758,8 @@ add_visual_separator() {

if [ "$ENABLE_UPS" = true ]; then
lastItemId="upsc"
elif [ "$ENABLE_GPU" = true ]; then
lastItemId="gpuInfo"
elif [ "$ENABLE_HDD_TEMP" = true ]; then
lastItemId="thermalHdd"
elif [ "$ENABLE_NVME_TEMP" = true ]; then
Expand Down Expand Up @@ -1557,6 +1617,83 @@ EOF
fi
}

# Function to generate GPU widget
generate_gpu_widget() {
#region gpu widget heredoc
# use subshell to allow variable expansion
(
export CPU_ITEMS_PER_ROW
export CPU_TEMP_TARGET
export HELPERCTORPARAMS

cat <<'EOF' | envsubst '$CPU_ITEMS_PER_ROW $CPU_TEMP_TARGET $HELPERCTORPARAMS' > "$1"
{
itemId: 'gpu',
colspan: 2,
iconCls: 'fa fa-desktop',
title: gettext('GPU(s)'),
printBar: false,
textField: 'gpuStats',
renderer: function(gpuStats) {
console.log(gpuStats);
if (!gpuStats || !gpuStats.Graphics || !gpuStats.Graphics.Intel) {
return 'N/A';
}

let html = '';

Object.keys(gpuStats.Graphics.Intel).forEach(key => {
const gpuData = gpuStats.Graphics.Intel[key];
console.log("here1");
html += `<div style="display: flex; justify-content: space-between; align-items: center; margin-left: 28px;">`;
html += `<div style="text-align: left; flex: 1;">${gpuData.name}</div>`;
html += `<div style="text-align: right; flex: 1;">`;

if (gpuData.stats.engines) {
console.log("here2");
// Render/3D
if (gpuData.stats.engines['Render/3D']) {
html += `Render/3D: ${gpuData.stats.engines['Render/3D'].busy}% | `;
}

// Video
if (gpuData.stats.engines['Video']) {
html += `Video: ${gpuData.stats.engines['Video'].busy}% | `;
}

// Blitter
if (gpuData.stats.engines['Blitter']) {
html += `Blitter: ${gpuData.stats.engines['Blitter'].busy}% | `;
}

// VideoEnhance
if (gpuData.stats.engines['VideoEnhance']) {
html += `VideoEnhance: ${gpuData.stats.engines['VideoEnhance'].busy}% | `;
}
}

// Power and Frequency info
html += `Power: ${gpuData.stats.power?.GPU ?? 'N/A'} / ${gpuData.stats.power?.Package ?? 'N/A'} ${gpuData.stats.power?.unit || 'W'}`;
html += ` | Freq: ${gpuData.stats.frequency?.actual ?? 'N/A'}/${gpuData.stats.frequency?.requested ?? 'N/A'} ${gpuData.frequency?.unit || 'MHz'}`;

html += `</div></div>`;
});

// todo add NVIDIA

// todo add NVIDIA

return html;
},
},
EOF
)
#endregion cpu widget heredoc
if [[ $? -ne 0 ]]; then
echo "Error: Failed to generate cpu widget code" >&2
exit 1
fi
}
#endregion widget generation functions

# Function to uninstall the modification
Expand Down
Loading