Last active
March 8, 2026 20:00
-
-
Save mredig/1303b564766be0f740d0f72dfd3fd40e to your computer and use it in GitHub Desktop.
iDrac 7 r720 ipmi fan control
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # | |
| # Dell R720 dual-CPU fan control script | |
| # Based on https://wiki.joeplaa.com/tutorials/how-to-control-dell-server-fanspeeds-with-ipmitool | |
| # (which is itself based on https://github.com/brezlord/iDRAC7_fan_control) | |
| # | |
| # Monitors both CPU temps and controls fans based on the higher of the two. | |
| # Falls back to iDRAC automatic control if temp exceeds threshold. | |
| # | |
| # Setup: | |
| # 1. echo 'yourpassword' > ~/.ipmi_password && chmod 600 ~/.ipmi_password | |
| # 2. chmod +x /usr/local/bin/fan-control.sh | |
| # 3. Add to cron: */3 * * * * /usr/local/bin/fan-control.sh >> /var/log/fan-control.log 2>&1 | |
| IDRAC_IP="${IDRAC_IP:-169.254.0.1}" | |
| IDRAC_USER="${IDRAC_USER:-"fan-op"}" | |
| IDRAC_PASS_FILE="${IDRAC_PASS_FILE:-$HOME/.ipmi_password}" | |
| # Temperature threshold above which iDRAC automatic control is re-enabled (°C) | |
| TEMP_THRESHOLD=55 | |
| # Fan speed hex values (percent) | |
| SPEED15="0x0f" | |
| SPEED20="0x14" | |
| SPEED25="0x19" | |
| SPEED30="0x1e" | |
| SPEED35="0x23" | |
| SPEED40="0x28" | |
| SPEED45="0x2d" | |
| SPEED50="0x32" | |
| SPEED55="0x37" | |
| IPMI="ipmitool -I lanplus -H $IDRAC_IP -U $IDRAC_USER -f $IDRAC_PASS_FILE" | |
| enable_auto() { | |
| echo "Restoring automatic fan control" | |
| $IPMI raw 0x30 0x30 0x01 0x01 | |
| } | |
| trap enable_auto ERR TERM INT | |
| echo "=== $(date '+%Y-%m-%d %H:%M:%S') ===" | |
| # Read all temps in a single IPMI call, then parse each CPU from the result | |
| TEMPS=$($IPMI sdr type temperature 2>/dev/null) | |
| T1=$(echo "$TEMPS" | grep "0Eh" | cut -d"|" -f5 | cut -d" " -f2) | |
| T2=$(echo "$TEMPS" | grep "0Fh" | cut -d"|" -f5 | cut -d" " -f2) | |
| # Validate readings | |
| if [[ -z "$T1" || -z "$T2" ]]; then | |
| echo "ERROR: Could not read CPU temps (T1='$T1' T2='$T2'). Falling back to automatic control." | |
| $IPMI raw 0x30 0x30 0x01 0x01 | |
| exit 1 | |
| fi | |
| echo "CPU1: ${T1}°C CPU2: ${T2}°C" | |
| # Use the higher of the two temps as the control variable | |
| if [ "$T1" -ge "$T2" ]; then | |
| T=$T1 | |
| else | |
| T=$T2 | |
| fi | |
| echo "Controlling on: ${T}°C" | |
| # If temp exceeds threshold, hand control back to iDRAC | |
| if [ "$T" -ge "$TEMP_THRESHOLD" ]; then | |
| echo "Above ${TEMP_THRESHOLD}°C threshold — enabling automatic fan control" | |
| $IPMI raw 0x30 0x30 0x01 0x01 | |
| exit 0 | |
| fi | |
| # Enable manual fan control | |
| $IPMI raw 0x30 0x30 0x01 0x00 | |
| # Set fan speed based on temperature curve | |
| if [ "$T" -le 25 ]; then | |
| echo "Setting fans to 15%" | |
| $IPMI raw 0x30 0x30 0x02 0xff $SPEED15 | |
| elif [ "$T" -le 30 ]; then | |
| echo "Setting fans to 20%" | |
| $IPMI raw 0x30 0x30 0x02 0xff $SPEED20 | |
| elif [ "$T" -le 35 ]; then | |
| echo "Setting fans to 25%" | |
| $IPMI raw 0x30 0x30 0x02 0xff $SPEED25 | |
| elif [ "$T" -le 39 ]; then | |
| echo "Setting fans to 30%" | |
| $IPMI raw 0x30 0x30 0x02 0xff $SPEED30 | |
| elif [ "$T" -le 42 ]; then | |
| echo "Setting fans to 35%" | |
| $IPMI raw 0x30 0x30 0x02 0xff $SPEED35 | |
| elif [ "$T" -le 45 ]; then | |
| echo "Setting fans to 40%" | |
| $IPMI raw 0x30 0x30 0x02 0xff $SPEED40 | |
| elif [ "$T" -le 47 ]; then | |
| echo "Setting fans to 45%" | |
| $IPMI raw 0x30 0x30 0x02 0xff $SPEED45 | |
| elif [ "$T" -le 51 ]; then | |
| echo "Setting fans to 50%" | |
| $IPMI raw 0x30 0x30 0x02 0xff $SPEED50 | |
| else | |
| # 43–44°C, just under threshold | |
| echo "Setting fans to 55%" | |
| $IPMI raw 0x30 0x30 0x02 0xff $SPEED55 | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment