Skip to content

Commit 858b14d

Browse files
authored
Included CPU temperature monitoring
1 parent 7dce4b0 commit 858b14d

1 file changed

Lines changed: 37 additions & 31 deletions

File tree

dell-fan-control-nvidia.sh

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
#!/bin/bash
22

3-
# Define global functions
4-
# This function applies Dell's default dynamic fan control profile
3+
for cmd in ipmitool nvidia-smi sensors bc awk; do
4+
if ! command -v $cmd &>/dev/null; then
5+
echo "Error: $cmd is required but not installed."
6+
exit 1
7+
fi
8+
done
9+
510
function apply_automatic_fan_control () {
6-
# Use ipmitool to send the raw command to set fan control to Dell default
711
ipmitool -I $IDRAC_CONNECTION_STRING raw 0x30 0x30 0x01 0x01 > /dev/null
812
FAN_CONTROL_CURRENT_STATE=$FAN_CONTROL_STATE_AUTOMATIC
913
echo "Fan control set to automatic."
1014
}
1115

12-
# This function applies a user-specified static fan control profile
1316
function apply_manual_fan_control () {
14-
# Use ipmitool to send the raw command to set fan control to user-specified value
1517
ipmitool -I $IDRAC_CONNECTION_STRING raw 0x30 0x30 0x01 0x00 > /dev/null
1618
FAN_CONTROL_CURRENT_STATE=$FAN_CONTROL_STATE_MANUAL
1719
echo "Fan control set to manual."
1820
}
1921

2022
function apply_fan_speed () {
21-
# Convert the decimal value to hex
2223
local HEXADECIMAL_FAN_SPEED=$(printf '0x%02x' $1)
2324

2425
ipmitool -I $IDRAC_CONNECTION_STRING raw 0x30 0x30 0x02 0xff $HEXADECIMAL_FAN_SPEED > /dev/null
@@ -27,26 +28,36 @@ function apply_fan_speed () {
2728
echo "Fan speed set to $1% ($HEXADECIMAL_FAN_SPEED)."
2829
}
2930

30-
# Retrieve temperature sensors data using nvidia-smi (Edited for multi-gpu compatibility)
3131
function retrieve_temperatures () {
32+
#obtain gpu temp from nvidia-smi, select highest
3233
GPU_TEMP=$(nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader | awk 'BEGIN{max=0} {if($1>max) max=$1} END{print max}')
33-
echo "Current Highest GPU Temp: $GPU_TEMP °C"
34+
#obtain cpu temp from lm-sensors, select highest
35+
CPU_TEMP=$(sensors | grep -E 'Core [0-9]+' | awk '{print $3}' | cut -d'+' -f2 | cut -d'.' -f1 | awk 'BEGIN{max=0} {if($1>max) max=$1} END{print max}')
36+
#select highest temp between cpu and gpu
37+
if [ $CPU_TEMP -gt $GPU_TEMP ]; then
38+
HIGHEST_TEMP=$CPU_TEMP
39+
TEMP_SOURCE="CPU"
40+
else
41+
HIGHEST_TEMP=$GPU_TEMP
42+
TEMP_SOURCE="GPU"
43+
fi
44+
echo "Current Highest GPU Temp: $GPU_TEMP °C, Highest CPU Temp: $CPU_TEMP °C, Using $TEMP_SOURCE Temp: $HIGHEST_TEMP °C"
3445
}
3546

36-
# Prepare traps in case of script exit
3747
function gracefull_exit () {
3848
apply_automatic_fan_control
3949
echo "Script stopped, automatic fan speed restored for safety."
4050
exit 0
4151
}
4252

4353
function emergency_shutdown () {
44-
echo "Emergency termination triggered! GPU temperature (${GPU_TEMP}°C) exceeds the threshold (${EMRG_TERM_TEMP}°C)."
54+
echo "$(date): Emergency shutdown triggered due to $TEMP_SOURCE temp ${HIGHEST_TEMP}°C" >> /var/log/fan_control.log
4555
echo "Shutting down the system immediately!"
56+
sync
4657
shutdown -h now
4758
}
4859

49-
# Trap the signals for script exit and run gracefull_exit function
60+
#trap signal
5061
trap 'gracefull_exit' SIGQUIT SIGKILL SIGTERM EXIT
5162

5263
# --- User Configuration ---
@@ -58,62 +69,57 @@ FAN_CONTROL_STATE_AUTOMATIC="automatic"
5869
FAN_CONTROL_CURRENT_STATE=$FAN_CONTROL_STATE_AUTOMATIC
5970
FAN_CONTROL_MANUAL_PERCENTAGE=0
6071

61-
# Linear Fan Speed Algorithm Variables
72+
# Fan Speed Variables
6273
MIN_TEMP=65 # Temperature in Celsius to start increasing fan speed
6374
MAX_TEMP=90 # Temperature in Celsius at which fan speed reaches maximum
6475
MIN_FAN=20 # Minimum fan speed percentage
65-
MAX_FAN=100 # Maximum fan speed percentage
66-
67-
# Emegerency Termination
76+
MAX_FAN=100 # Maximum fan speed percentage
77+
INTERVAL=3 # Seconds, the interval between temp checks and adjustment
6878

79+
# Emergency Termination
6980
EMRG_TERM_STATE="enabled" # or "disabled". Enabled by default to prevent hw dmg
70-
EMRG_TERM_TEMP=100 #in deg celsius, when reached, system will shut down immediately if termination is enabled
81+
EMRG_TERM_TEMP=100 # in deg celsius, when reached, system will shut down immediately if termination is enabled
7182

7283
# --- End of User Configuration ---
84+
#do not touch below this point unless you know what you are doing
7385

74-
# Non-linear Fan Speed Algorithm
7586
while true; do
76-
sleep 2 &
87+
sleep $INTERVAL &
7788
SLEEP_PROCESS_PID=$!
7889

7990
retrieve_temperatures
8091

81-
if [[ "$EMRG_TERM_STATE" == "enabled" && $GPU_TEMP -ge $EMRG_TERM_TEMP ]]; then
92+
if [[ "$EMRG_TERM_STATE" == "enabled" && $HIGHEST_TEMP -ge $EMRG_TERM_TEMP ]]; then
8293
emergency_shutdown
8394
fi
8495

85-
if (($GPU_TEMP >= $MIN_TEMP)); then
96+
if (($HIGHEST_TEMP >= $MIN_TEMP)); then
8697
if [[ "$FAN_CONTROL_STATE_AUTOMATIC" == "$FAN_CONTROL_CURRENT_STATE" ]]; then
87-
echo "GPU temperature is getting high. Enabling manual fan control."
98+
echo "$TEMP_SOURCE temperature is getting high. Enabling manual fan control."
8899
apply_manual_fan_control
89100
fi
90101

91-
# Non-Linear Fan Speed Algorithm
92-
if (($GPU_TEMP <= $MAX_TEMP)); then
93-
# Calculate fan speed using a quadratic formula
94-
TEMP_RATIO=$(echo "scale=4; ($GPU_TEMP - $MIN_TEMP) / ($MAX_TEMP - $MIN_TEMP)" | bc)
102+
if (($HIGHEST_TEMP <= $MAX_TEMP)); then
103+
TEMP_RATIO=$(echo "scale=4; ($HIGHEST_TEMP - $MIN_TEMP) / ($MAX_TEMP - $MIN_TEMP)" | bc)
95104
FAN_SPEED=$(echo "$MIN_FAN + ($MAX_FAN - $MIN_FAN) * ($TEMP_RATIO ^ 2)" | bc | awk '{printf("%d\n", $1 + 0.5)}')
96105

97-
# Ensure fan speed is within bounds
106+
#ensure fan speed is sane
98107
if (($FAN_SPEED < $MIN_FAN)); then
99108
FAN_SPEED=$MIN_FAN
100109
elif (($FAN_SPEED > $MAX_FAN)); then
101110
FAN_SPEED=$MAX_FAN
102111
fi
103112
else
104-
# If temperature exceeds MAX_TEMP, set fan to MAX_FAN
105113
FAN_SPEED=$MAX_FAN
106114
fi
107115

108-
# Apply fan speed only if it's different from the current manual percentage
109116
if [[ "$FAN_CONTROL_MANUAL_PERCENTAGE" != "$FAN_SPEED" ]]; then
110-
echo "Setting fan speed to ${FAN_SPEED}% based on non-linear algorithm."
117+
echo "Setting fan speed to ${FAN_SPEED}% based on non-linear algorithm for $TEMP_SOURCE temperature."
111118
apply_fan_speed $FAN_SPEED
112119
fi
113120

114121
elif [[ "$FAN_CONTROL_STATE_MANUAL" == "$FAN_CONTROL_CURRENT_STATE" ]]; then
115-
# Reset automatic fan control if temperature is below MIN_TEMP and we are currently in manual mode
116-
echo "GPU temperature is calming down. Returning to automatic fan control."
122+
echo "$TEMP_SOURCE temperature is calming down. Returning to automatic fan control."
117123
apply_automatic_fan_control
118124
FAN_CONTROL_MANUAL_PERCENTAGE=0
119125
fi

0 commit comments

Comments
 (0)