I have vibe coded this bash script for inreasing fans speed (auto) on high host cpu usage and dropping to low fans speed when cpu usage is low
enjoy! just run some hungry VM or change HIGH_THRESHOLD=85 like to 45 (becase hyperthreading for example)
you can also remove extra logging for purpose of less SSD wear, anyway it probably cache it in slc or ssd dram cache
enjoy! just run some hungry VM or change HIGH_THRESHOLD=85 like to 45 (becase hyperthreading for example)
you can also remove extra logging for purpose of less SSD wear, anyway it probably cache it in slc or ssd dram cache
nano /usr/local/bin/cpu-automation.sh
Bash:
#!/usr/bin/env bash
# ==============================================================================
# CONFIGURATION
# ==============================================================================
HIGH_THRESHOLD=85 # Trigger high command if CPU is above this %
LOW_THRESHOLD=15 # Trigger low command if CPU falls below this %
STATE_FILE="/tmp/cpu_high_triggered.state"
LOG_FILE="/var/log/cpu-automation.log"
# ==============================================================================
# ACCURATE CPU PERCENTAGE CALCULATION (1-second sample delta)
# ==============================================================================
read -r _ user nice system idle iowait irq softirq steal _ < /proc/stat
prev_total=$((user + nice + system + idle + iowait + irq + softirq + steal))
prev_idle=$((idle + iowait))
sleep 1
read -r _ user nice system idle iowait irq softirq steal _ < /proc/stat
total=$((user + nice + system + idle + iowait + irq + softirq + steal))
idle=$((idle + iowait))
total_delta=$((total - prev_total))
idle_delta=$((idle - prev_idle))
used_delta=$((total_delta - idle_delta))
# Guard against dividing by zero if metrics fail to update
if [ "$total_delta" -le 0 ]; then
echo "$(date): Error calculating CPU metrics. Skipping run." >> "$LOG_FILE"
exit 1
fi
CPU_INT=$(( 100 * used_delta / total_delta ))
# ==============================================================================
# AUTOMATION LOGIC
# ==============================================================================
if [ "$CPU_INT" -gt "$HIGH_THRESHOLD" ]; then
echo "$(date): High CPU detected at ${CPU_INT}%." >> "$LOG_FILE"
# ----------------------------------------------------------------------
# COMMAND A: RUNS ON HIGH CPU SPIKE
# Replace the echo line below with your actual high CPU command.
# ----------------------------------------------------------------------
echo "Executing High CPU action..." >> "$LOG_FILE"
# ---- DELL commands for ipmitool for auto fans DEPENDS ON PLATFORM this is DELL 13 GEN ------
#ipmitool -I lanplus -H ipaddress -U user -P password raw 0x30 0x30 0x01 0x01
# Flag that the high command ran so the low command is unlocked
touch "$STATE_FILE"
elif [ "$CPU_INT" -lt "$LOW_THRESHOLD" ]; then
# Only run if Command A (High CPU) has run previously
if [ -f "$STATE_FILE" ]; then
echo "$(date): Low CPU detected at ${CPU_INT}% and High CPU ran previously." >> "$LOG_FILE"
# ------------------------------------------------------------------
# COMMAND B: RUNS ONLY IF CPU DROPS LOW AFTER A SPIKE
# Replace the echo line below with your actual low CPU command.
# ------------------------------------------------------------------
echo "Executing Low CPU action..." >> "$LOG_FILE"
#### -- ipmi fans 25 percent DEPENDS ON PLATFORM this is DELL 13 GEN ---
#ipmitool -I lanplus -H ipaddress -U user -P password raw 0x30 0x30 0x01 0x00
#ipmitool -I lanplus -H ipaddress -U user -P password raw 0x30 0x30 0x02 0xff 0x19
# Clear the state file to reset the cycle and prevent loops
rm -f "$STATE_FILE"
else
# System is idle, but no previous spike occurred. Do nothing.
# you can comment next line and put : (colon) on next line
echo "$(date): Idle at ${CPU_INT}%, skipping action (Waiting for High CPU trigger)." >> "$LOG_FILE"
fi
else
# Optional: Log baseline steady-state activity
echo "$(date): CPU steady at ${CPU_INT}%." >> "$LOG_FILE"
fi
Bash:
crontab -e
* * * * * /usr/local/bin/cpu-automation.sh >/dev/null 2>&1
Last edited: