-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfanctl.sh
176 lines (155 loc) · 5.84 KB
/
fanctl.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#!/bin/bash
# IPMI iDrac Settings
IPMI_HOST="idrac.lab.local" # Your iDrac IP Address or FQDN
IPMI_USER="root" # iDrac Username
IPMI_PASS="calvin" # iDrac Password
# Fan Speed Thresholds
TEMP_THRESHOLD_1=50
TEMP_THRESHOLD_2=60
TEMP_THRESHOLD_3=65
TEMP_THRESHOLD_4=70
TEMP_THRESHOLD_5=75
TEMP_THRESHOLD_6=80
TEMP_THRESHOLD_7=85
TEMP_THRESHOLD_8=90
# Time Between Checks (in seconds)
CHECK_INTERVAL=60
# Log Path
LOG_FILE="/var/log/fanctrl.log"
# Danger Zone Temperature Threshold (in Celsius)
TEMP_MAX=90
# Init Current Fan Speed
current_fan_speed=""
# Logging
log() {
level=$1
message=$2
timestamp=$(date +"%d-%m-%Y %H:%M:%S")
log_message="[$timestamp] [$level] $message"
echo "$log_message"
echo "$log_message" >>"$LOG_FILE"
}
# Check Deps
check_dependencies() {
dependencies=("ipmitool" "bc")
for dep in "${dependencies[@]}"; do
if ! command -v $dep &>/dev/null; then
log "ERROR" "Required dependency '$dep' is not installed. Exiting."
exit 1
fi
done
}
# Get CPU Temps and Parse Out Inlet & Exhaust
get_cpu_temperatures() {
temps=$(ipmitool -I lanplus -H $IPMI_HOST -U $IPMI_USER -P $IPMI_PASS sdr type temperature | grep -E '^\s*Temp\s+\|' | awk -F'|' '{print $5}' | awk '{print $1}')
if [ $? -ne 0 ]; then
log "ERROR" "Failed to retrieve temperatures from IPMI. Error: $temps"
echo ""
else
echo "$temps"
fi
}
# Calculate Average CPU Temps From Both Procs
get_avg_cpu_temperature() {
temps=$(get_cpu_temperatures)
if [ -z "$temps" ]; then
echo ""
else
echo "$temps" | awk '{sum+=$1} END {if (NR>0) print sum/NR; else print ""}' | awk '{printf "%.1f", $0}'
fi
}
# Set The Fan Speed
set_fan_speed() {
speed=$1
if [ "$speed" != "$current_fan_speed" ]; then
output=$(ipmitool -I lanplus -H $IPMI_HOST -U $IPMI_USER -P $IPMI_PASS raw 0x30 0x30 0x02 0xff $speed 2>&1)
if [ $? -ne 0 ]; then
log "ERROR" "Failed to set fan speed via IPMI. Error: $output"
else
log "INFO" "Fan speed set to $speed."
current_fan_speed=$speed
fi
else
log "INFO" "Fan speed unchanged at $speed."
fi
}
# Manual Fan Control Mode
enable_manual_fan_control() {
output=$(ipmitool -I lanplus -H $IPMI_HOST -U $IPMI_USER -P $IPMI_PASS raw 0x30 0x30 0x01 0x00 2>&1)
if [ $? -ne 0 ]; then
log "ERROR" "Failed to enable manual fan control via IPMI. Error: $output"
exit 1
else
log "INFO" "Manual fan control enabled."
fi
}
# Disable Fan Control Mode
disable_manual_fan_control() {
output=$(ipmitool -I lanplus -H $IPMI_HOST -U $IPMI_USER -P $IPMI_PASS raw 0x30 0x30 0x01 0x01 2>&1)
if [ $? -ne 0 ]; then
log "ERROR" "Failed to disable manual fan control via IPMI. Error: $output"
else
log "INFO" "Manual fan control disabled. Returning to automatic control."
fi
}
# If Script Exit Or Crash, Reset To Auto Fan Control
trap 'disable_manual_fan_control; log "INFO" "Script terminated."; exit 0' SIGINT SIGTERM
# Check For Required Deps
check_dependencies
# Takeover Fan Control On Launch
enable_manual_fan_control
# Main Loop
while true; do
# Get CPU Temperatures
cpu_temps=$(get_cpu_temperatures)
log "INFO" "CPU temperatures:"
i=0
echo "$cpu_temps" | while read -r temp; do
i=$((i + 1))
log "INFO" " CPU$i: $temp°C"
done
# Calculate Average Temp
avg_temp=$(get_avg_cpu_temperature)
if [ -z "$avg_temp" ]; then
log "WARNING" "Unable to retrieve CPU temperatures. Skipping fan speed adjustment."
else
log "INFO" "Average CPU temperature: $avg_temp°C"
# Check If The Temperature Exceeds The Max Threshold
if (($(echo "$avg_temp >= $TEMP_MAX" | bc -l))); then
log "WARNING" "Temperature reached or exceeded max threshold ($TEMP_MAX°C). Switching to automatic fan control."
disable_manual_fan_control
log "INFO" "Exiting script due to max temperature reached."
exit 1
# Step Up Fan Speed As Temp Goes Up
elif (($(echo "$avg_temp >= $TEMP_THRESHOLD_8" | bc -l))); then
log "WARNING" "Temperature above $TEMP_THRESHOLD_8°C. Setting fan speed to 90%."
set_fan_speed 0x5A # 90%
elif (($(echo "$avg_temp >= $TEMP_THRESHOLD_7" | bc -l))); then
log "WARNING" "Temperature above $TEMP_THRESHOLD_7°C. Setting fan speed to 80%."
set_fan_speed 0x50 # 80%
elif (($(echo "$avg_temp >= $TEMP_THRESHOLD_6" | bc -l))); then
log "INFO" "Temperature above $TEMP_THRESHOLD_6°C. Setting fan speed to 70%."
set_fan_speed 0x46 # 70%
elif (($(echo "$avg_temp >= $TEMP_THRESHOLD_5" | bc -l))); then
log "INFO" "Temperature above $TEMP_THRESHOLD_5°C. Setting fan speed to 60%."
set_fan_speed 0x3C # 60%
elif (($(echo "$avg_temp >= $TEMP_THRESHOLD_4" | bc -l))); then
log "INFO" "Temperature above $TEMP_THRESHOLD_4°C. Setting fan speed to 50%."
set_fan_speed 0x32 # 50%
elif (($(echo "$avg_temp >= $TEMP_THRESHOLD_3" | bc -l))); then
log "INFO" "Temperature above $TEMP_THRESHOLD_3°C. Setting fan speed to 40%."
set_fan_speed 0x28 # 40%
elif (($(echo "$avg_temp >= $TEMP_THRESHOLD_2" | bc -l))); then
log "INFO" "Temperature above $TEMP_THRESHOLD_2°C. Setting fan speed to 30%."
set_fan_speed 0x1E # 30%
elif (($(echo "$avg_temp >= $TEMP_THRESHOLD_1" | bc -l))); then
log "INFO" "Temperature above $TEMP_THRESHOLD_1°C. Setting fan speed to 20%."
set_fan_speed 0x14 # 20%
else
log "INFO" "Temperature normal. Setting fan speed to 10%."
set_fan_speed 0xA # 10%
fi
fi
# Wait A Set Time Before Rechecking
sleep $CHECK_INTERVAL
done