Skip to content

Instantly share code, notes, and snippets.

@fonic
Last active June 24, 2023 12:43
Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save fonic/8f38e5e3ce5c8693ae3a23aa1af21fb9 to your computer and use it in GitHub Desktop.
Save fonic/8f38e5e3ce5c8693ae3a23aa1af21fb9 to your computer and use it in GitHub Desktop.
KDE KSysGuard NVIDIA GPU Sensors - see comments below for usage information
#!/usr/bin/env bash
# -------------------------------------------------------------------------
# -
# Created by Fonic (https://github.com/fonic) -
# Date: 12/29/19 - 02/12/20 -
# -
# Created for and tested on single-GPU system equipped with NVIDIA -
# GeForce RTX 2060 SUPER. For other systems, modifications might be -
# required. -
# -
# Based on: -
# https://gist.github.com/frantic1048/41f56fd6328fa83ce6ad5acb3a4c0336 -
# https://gist.github.com/hacker1024/c01a773f50769bd8216fa01ea0a1ef33 -
# https://techbase.kde.org/Development/Tutorials/Sensors -
# -
# -------------------------------------------------------------------------
# Globals
MAX_GPU_TEMP=100 # maximum GPU temperature in °C
MAX_MEM_USED=8192 # maximum memory used in MB
MAX_GPU_CLOCK=2100 # maximum GPU clock in MHz
MAX_MEM_CLOCK=7000 # maximum memory clock in MHz
MAX_FAN_RPM=3000 # maximum fan speed in RPM
# Main loop
echo "ksysguardd 1.2.0"
echo -n "ksysguardd> "
last_update=$((${SECONDS} - 1))
while read -r input; do
# Update monitor data just in time, but not more often than once per second
# NOTE:
# nvidia-settings will stop printing data on the first error it encounters.
# Thus, queries for [fan:1] have to be placed at the end of the list for the
# script to work on systems with only one fan
if (( ${SECONDS} < ${last_update} || ${SECONDS} - ${last_update} >= 1 )); then
readarray -t lines < <(nvidia-settings -t \
-q [gpu:0]/GPUCoreTemp \
-q [gpu:0]/UsedDedicatedGPUMemory \
-q [gpu:0]/GPUCurrentClockFreqs \
-q [gpu:0]/GPUUtilization \
-q [fan:0]/GPUCurrentFanSpeed \
-q [fan:0]/GPUCurrentFanSpeedRPM \
-q [fan:1]/GPUCurrentFanSpeed \
-q [fan:1]/GPUCurrentFanSpeedRPM \
)
gpu_temp="${lines[0]}"
mem_used="${lines[1]}"
gpu_clock="${lines[2]%,*}"
mem_clock="${lines[2]#*,}"
re="^graphics=([0-9]+), memory=([0-9]+), video=([0-9]+), PCIe=([0-9]+)$"
if [[ "${lines[3]}" =~ ${re} ]]; then
gpu_load="${BASH_REMATCH[1]}"
mem_load="${BASH_REMATCH[2]}"
vpu_load="${BASH_REMATCH[3]}"
pcie_load="${BASH_REMATCH[4]}"
fi
fan0_load="${lines[4]}"
fan0_rpm="${lines[5]}"
fan1_load="${lines[6]}"
fan1_rpm="${lines[7]}"
last_update=${SECONDS}
fi
# Evaluate input, generate output
case "${input}" in
# List of monitors (format: '<id>\t<data-type>')
"monitors")
echo -e "gpu_temp\tinteger"
echo -e "mem_used\tinteger"
echo -e "gpu_clock\tinteger"
echo -e "mem_clock\tinteger"
echo -e "gpu_load\tinteger"
echo -e "mem_load\tinteger"
echo -e "vpu_load\tinteger"
echo -e "pcie_load\tinteger"
echo -e "fan0_load\tinteger"
echo -e "fan0_rpm\tinteger"
echo -e "fan1_load\tinteger"
echo -e "fan1_rpm\tinteger"
;;
# Monitor info (format: '<label>\t<min-value>\t<max-value>\t<unit>')
"gpu_temp?") echo -e "GPU\t0\t${MAX_GPU_TEMP}\t°C"; ;;
"mem_used?") echo -e "MEM\t0\t${MAX_MEM_USED}\tMB"; ;;
"gpu_clock?") echo -e "GPU\t0\t${MAX_GPU_CLOCK}\tMHz"; ;;
"mem_clock?") echo -e "MEM\t0\t${MAX_MEM_CLOCK}\tMHz"; ;;
"gpu_load?") echo -e "GPU\t0\t100\t%"; ;;
"mem_load?") echo -e "MEM\t0\t100\t%"; ;;
"vpu_load?") echo -e "VPU\t0\t100\t%"; ;;
"pcie_load?") echo -e "PCIe\t0\t100\t%"; ;;
"fan0_load?") echo -e "FAN1\t0\t100\t%"; ;;
"fan0_rpm?") echo -e "FAN1\t0\t${MAX_FAN_RPM}\tRPM"; ;;
"fan1_load?") echo -e "FAN2\t0\t100\t%"; ;;
"fan1_rpm?") echo -e "FAN2\t0\t${MAX_FAN_RPM}\tRPM"; ;;
# Monitor data (format: '<value>')
"gpu_temp") echo "${gpu_temp}"; ;;
"mem_used") echo "${mem_used}"; ;;
"gpu_clock") echo "${gpu_clock}"; ;;
"mem_clock") echo "${mem_clock}"; ;;
"gpu_load") echo "${gpu_load}"; ;;
"mem_load") echo "${mem_load}"; ;;
"vpu_load") echo "${vpu_load}"; ;;
"pcie_load") echo "${pcie_load}"; ;;
"fan0_load") echo "${fan0_load}"; ;;
"fan0_rpm") echo "${fan0_rpm}"; ;;
"fan1_load") echo "${fan1_load}"; ;;
"fan1_rpm") echo "${fan1_rpm}"; ;;
"exit"|"quit") break; ;;
esac
# Renew prompt
echo -n "ksysguardd> "
done
@fubarhouse
Copy link

This is seriously cool, thank you!
I wish System Monitor was this extensive, but I might have to switch back for detailed metrics now!

@fonic
Copy link
Author

fonic commented Nov 30, 2022

@fubarhouse Thanks, glad you like it. I'm actually still using KSysGuard and this script myself - last time I checked System Monitor wasn't really to my liking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment