With help of AI I created a script to control fan boost based on cpu/gpu temperatures:
#!/usr/bin/env bash
CONFIG="auto_fan.conf"
CHECK_INTERVAL=5
declare -a CPU_RULES GPU_RULES
LAST_CPU_BOOST=""
LAST_GPU_BOOST=""
HYSTERESIS=3
LAST_CPU_TEMP=""
LAST_GPU_TEMP=""
# Load config
load_config() {
local section=""
while IFS= read -r line; do
line=$(echo "$line" | sed 's/[[:space:]]//g')
[[ -z "$line" || "$line" =~ ^# ]] && continue
if [[ "$line" =~ ^\[(.*)\]$ ]]; then
section="${BASH_REMATCH[1]}"
continue
fi
if [[ "$line" =~ ^([0-9]+)-([0-9]+)=([0-9]+)$ ]]; then
rule="${BASH_REMATCH[1]}-${BASH_REMATCH[2]}=${BASH_REMATCH[3]}"
if [[ "$section" == "CPU" ]]; then
CPU_RULES+=("$rule")
elif [[ "$section" == "GPU" ]]; then
GPU_RULES+=("$rule")
fi
fi
done < "$CONFIG"
}
# Match temperature to a rule
match_boost() {
local TEMP=$1
local -n RULES=$2
for rule in "${RULES[@]}"; do
IFS='-=' read -r MIN MAX BOOST <<< "$rule"
if (( TEMP >= MIN && TEMP <= MAX )); then
echo "$BOOST"
return
fi
done
echo ""
}
check_g_mode() {
awcc qm 2>/dev/null | grep -iq 'G-Mode'
}
get_temp_cpu() {
sensors dell_ddv-virtual-0 | grep 'CPU:' | sed 's/\s\+/ /g' | cut -f 2 -d ' ' | tr -d '+' | sed 's/\..*//'
}
get_temp_gpu() {
sensors dell_ddv-virtual-0 | grep 'Video:' | sed 's/\s\+/ /g' | cut -f 2 -d ' ' | tr -d '+' | sed 's/\..*//'
}
load_config
CLEANED=''
# Cleanup function to reset fan boost
cleanup() {
[[ -z "$CLEANED" ]] || return
CLEANED="YES"
if ! check_g_mode; then
echo "Exiting: resetting fan boosts to 0"
awcc scb 0
awcc sgb 0
else
echo "Exiting in G-Mode: leaving boosts unchanged"
fi
exit 0
}
# Trap script termination signals
trap cleanup SIGINT SIGTERM EXIT
while true; do
if check_g_mode; then
LAST_CPU_BOOST=""
LAST_GPU_BOOST=""
sleep "$CHECK_INTERVAL"
continue
fi
CPU_TEMP=$(get_temp_cpu)
GPU_TEMP=$(get_temp_gpu)
[[ -z "$CPU_TEMP" || -z "$GPU_TEMP" ]] && sleep "$CHECK_INTERVAL" && continue
CPU_BOOST=$(match_boost "$CPU_TEMP" CPU_RULES)
GPU_BOOST=$(match_boost "$GPU_TEMP" GPU_RULES)
if [[ -n "$CPU_BOOST" && "$CPU_BOOST" != "$LAST_CPU_BOOST" ]]; then
if [[ -z "$LAST_CPU_TEMP" || $(( CPU_TEMP > LAST_CPU_TEMP + HYSTERESIS || CPU_TEMP < LAST_CPU_TEMP - HYSTERESIS )) -ne 0 ]]; then
echo cpu "$CPU_TEMP $CPU_BOOST"
awcc scb "$CPU_BOOST"
LAST_CPU_BOOST="$CPU_BOOST"
LAST_CPU_TEMP="$CPU_TEMP"
fi
fi
if [[ -n "$GPU_BOOST" && "$GPU_BOOST" != "$LAST_GPU_BOOST" ]]; then
if [[ -z "$LAST_GPU_TEMP" || $(( GPU_TEMP > LAST_GPU_TEMP + HYSTERESIS || GPU_TEMP < LAST_GPU_TEMP - HYSTERESIS )) -ne 0 ]]; then
echo gpu "$GPU_TEMP $GPU_BOOST"
awcc sgb "$GPU_BOOST"
LAST_GPU_BOOST="$GPU_BOOST"
LAST_GPU_TEMP="$GPU_TEMP"
fi
fi
sleep "$CHECK_INTERVAL"
done
auto_fan.conf:
[CPU]
0-39=0
40-49=20
50-59=40
60-69=60
70-79=80
80-100=100
[GPU]
0-39=0
40-49=20
50-59=40
60-69=60
70-79=80
80-100=100
I don't make a pull request because I want to write it in C, but have no enough time right now.
Just wanted to share this script, and maybe someone will have a time to rewrite in C or review the code 🙂.
Would be nice to have a systemd unit with fan management.
The ChatGPT conversation: https://chatgpt.com/share/6851194a-5000-8013-bfb7-a78ea86cdc30
With help of AI I created a script to control fan boost based on cpu/gpu temperatures:
auto_fan.conf:
I don't make a pull request because I want to write it in C, but have no enough time right now.
Just wanted to share this script, and maybe someone will have a time to rewrite in C or review the code 🙂.
Would be nice to have a systemd unit with fan management.
The ChatGPT conversation: https://chatgpt.com/share/6851194a-5000-8013-bfb7-a78ea86cdc30