Dell Poweredge R210 II manual fan control

Some weeks ago I got an old Dell Poweredge R210 II server. When I got it it had an E3-1220 V2 cpu in, which worked just fine. However, I needed a bit more processing power, so I swapped in an E3-1230 V2.

While the cpu was working just fine, the cooling for some reason didn’t.

At idle the cpu would be around 35-40c, and the fans running at around 3300 rpm. When the cpu then got loaded, the temperature would start to go up, and the fans would start to ramp up too. So far it sounds pretty normal, but this is also where it ends… When the cpu hit 65c, the fans would throttle down to 3300 rpm again, and there they would stay. I did one test where I let the cpu get very hot, and at 95c the fans were still at 3300 rpm, and I aborted the test.

After this, I have been struggling with a bios not wanting to update, where it turns out it didn’t like to go from 2.0.5 to 2.1.2, which is only one version up, instead I had to make it go a few versions up, and then I ended up being able to bring it all the way up to 2.10.0, which is currently the newest version there is.

With the bios updated, I tried to test again, and the fans were still staying at 3300 rpm. I then worked on getting the BMC updated, still no change. Now I have been trying to update the server, and get the fans working for almost two weeks, with almost all solutions pointing at using iDRAC6, which my server does not have yet. So now, I have written a bash script to handle the fans.

This script will need to have “sensors” and “ipmitool” installed. On unraid this can be done with nerdtools from Community Applications, and then User Scripts can be used to start it every minute, using * * * * * as custom schedule.

When running, the script will calculate the fan setting, depending on min and max temperature, and min and max fan speed. If the change of speed is less than 15, it will use averaging, where the force of the old reading is 75%, to give a more smooth and less annoying sound of the fan speed jumping, but still if the temperature change is going up faster than the averaging allow, it will jump up and averaging will continue there.

From my tests, the values in the script handle the transision from idle to full load fairly fast, and also works with a varying load which makes the temperature creep up slowly. At full load, temperature now stay stable around 65-70c.

#!/bin/bash

temp_min=50
temp_max=95

fan_min=10
fan_max=64

# Percentage of the old reading which will be used to calculate the new fan speed
force=75

# Seconds between each reading
delay=3

# Average only when difference is less than
avg_skip=15

echo "Fan control started"

fan_speed_old=64

if [ -f "/tmp/last_speed" ]; then
    fan_speed_old=$(sed -n '1p' < "/tmp/last_speed")
	echo "Last speed was $fan_speed_old"
fi

# Enable manual control
ipmitool raw 0x30 0x30 0x01 0x00 > /dev/null 2>&amp;1

while true; do
	temp=`sensors | grep "CPU Temp" | sed 's/.*:\s*+\(.*\)  .*(.*/\1/'`
	temp=${temp::-4}
	
	echo "CPU Temp: $temp" 
	
	fan_speed=$((($temp-$temp_min)*($fan_max-$fan_min)/($temp_max-$temp_min)+$fan_min))
	
	res=$(echo "$fan_speed-$fan_speed_old" | bc)
	
	if [[ "$res" -lt 0 ]] ; then
		res=$(echo `expr 0 - $res`)
	fi
	
	if [[ $res -lt $avg_skip ]]; then
		echo " Averaging:"
		cforce=$(echo "scale=2;$force/100" | bc)
		old=$(echo "scale=2;$fan_speed_old*$cforce" | bc -l)
		echo -e "  Old speed $old"
		
		cforce=$(echo "scale=2;1-$cforce" | bc)
		new=$(echo "scale=2;$fan_speed*$cforce" | bc -l)
		echo -e "  New speed $new"
		
		fan_speed=$(echo "scale=0;$old+$new" | bc)
		fan_speed=$(echo "($fan_speed+0.5)/1" | bc )
		echo -e "  Fan speed: $fan_speed"
	fi
	
	fan_speed_old=$fan_speed
	
	if [[ $fan_speed -lt $fan_min ]]; then
		fan_speed=$fan_min
	elif [[ $fan_speed -gt $fan_max ]]; then
		fan_speed=$fan_max
	fi
	
	cmd="0x30 0x30 0x02 0xff 0x$fan_speed"
	echo "Command: $cmd"

	# Set fan speed
	ipmitool raw $cmd > /dev/null 2>&amp;1
	
	current=$(date +"%S")
	current=$(echo $current | sed 's/^0*//')
	if [[ $current -gt 51 ]]; then
		echo $fan_speed_old > /tmp/last_speed
		sleep 1
		exit
	fi
	
	echo -e ""
	
	sleep $delay
done

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.