Skip to content

Instantly share code, notes, and snippets.

@alvesvaren
Forked from fragtion/fanspeeds.sh
Last active November 4, 2023 18:20
Show Gist options
  • Save alvesvaren/85c8dd14077dee98925631425cad606f to your computer and use it in GitHub Desktop.
Save alvesvaren/85c8dd14077dee98925631425cad606f to your computer and use it in GitHub Desktop.
Dell R710 (and possibly other) temperature-based fan speeds script
#!/bin/bash
# Script for checking the temperature reported by the ambient temperature sensor,
# and if deemed too high send the raw IPMI command to enable dynamic fan control.
#
# Also get CPU temps from lm-sensors and adjust fan speeds according to defined
# speed % which should be set according to your needs (each CPU model will vary)
#
# Requires:
# ipmitool – apt install ipmitool
# sensors - apt install lm-sensors
# bc - apt install bc
LASTSPEED=$(cat /tmp/lastspeed 2>/dev/null || echo 0)
function setfans () {
speed=$1
if [[ $speed == "auto" ]]; then
# Enable automatic fan speed control
ipmitool raw 0x30 0x30 0x01 0x01 >/dev/null 2>&1 &
LASTSPEED=${speed}
echo "[$(date)] $(hostname) FANS: AUTO (SYS: ${SYSTEMP}C, CPU: ${CPUTEMP}C)"
echo "AUTO (SYS: ${SYSTEMP}C, CPU: ${CPUTEMP}C)" | systemd-cat -t updatefans
else
speedhex=$(echo "obase=16; $speed" | bc)
# Enable manual fan speed control
if [[ "$LASTSPEED" == "auto" ]] || [[ "$LASTSPEED" == "0" ]]; then
ipmitool raw 0x30 0x30 0x01 0x00 >/dev/null 2>&1 # &
fi
ipmitool raw 0x30 0x30 0x02 0xff 0x${speedhex} >/dev/null 2>&1 &
LASTSPEED=${speed}
echo "[$(date)] $(hostname) FANS: ${speed}% (0x${speedhex}) (SYS: ${SYSTEMP}C, CPU: ${CPUTEMP}C)"
echo "${speed}% (0x${speedhex}) (SYS: ${SYSTEMP}C, CPU: ${CPUTEMP}C)" | systemd-cat -t updatefans
fi
}
# This variable sends a IPMI command to get the temperature, and outputs it as two digits.
SYSTEMP=$(ipmitool sdr type temperature | grep Ambient | grep degrees | grep -Po '\d{2}' | tail -1)
#highest of all core temps
CPUTEMP=$(sensors | grep high | cut -d "+" -f2 | cut -d "." -f1 | sort -n | tail -1)
# Use the cpu temperature to calculate an optimal fan speed compared to the temperature using the formula x^2/50
let "SPEED=$CPUTEMP**2/50"
# Ceil the value
SPEED=$(echo $SPEED | awk '{print int($1+0.5)}')
if [[ $SYSTEMP > 32 || $CPUTEMP > 65 ]]; then
echo "Warning: SysTemp or CpuTemp too high! Activating dynamic fan control! ($SYSTEMP C)"
echo "Warning: SysTemp or CpuTemp too high! Activating dynamic fan control! ($SYSTEMP C)" | systemd-cat -p "warning" -t updatefans
setfans auto
else
setfans $SPEED
fi
echo $LASTSPEED > /tmp/lastspeed
@alvesvaren
Copy link
Author

alvesvaren commented Jun 8, 2021

To install:

  • Make sure all dependencies are installed (see the top of the script file) and make sure the script works on your hardware before making it automatically.

  • Run sudo curl -o /usr/bin/updatefans.sh https://gist.githubusercontent.com/alvesvaren/85c8dd14077dee98925631425cad606f/raw && sudo chmod +x /usr/bin/updatefans.sh

  • Test the script out by running /usr/bin/updatefans.sh

    • If you want to revert to automatic control: run sudo ipmitool raw 0x30 0x30 0x01 0x01

    • If everything works correctly, then just run sudo crontab -e and add this line to the file:

      * * * * * /usr/bin/updatefans.sh > /dev/null 2>&1

      This will run the script every 60 seconds, updating the fan speed each time

To view the log:

Run sudo journalctl -rt updatefans

To uninstall:

If you do not like it for any reason, you can delete the file at /usr/bin/updatefans.sh, remove it from the crontab and run sudo ipmitool raw 0x30 0x30 0x01 0x01 to enable the automatic fan bios based fancontrol.

@alvesvaren
Copy link
Author

This script is tested on R710 and R410 and seems to work fine on both

@memorex258
Copy link

Thank you, i like your optimal fan speed calc

@Samg381
Copy link

Samg381 commented Nov 4, 2023

FYI, I had to run sudo chmod -t /tmp in order to get $LASTSPEED to save

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment