Created
April 13, 2020 14:53
-
-
Save DrSpeedy/1c489c31dbf45575d4a3d7c21c6ea2da to your computer and use it in GitHub Desktop.
This file contains 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/local/bash | |
# cfan.sh | |
# Manaual control over fans in PfSense (FreeBSD) on a Dell PowerEdge R210 ii system | |
# Original script: https://www.garron.me/en/bits/specify-editor-crontab-file.html | |
# Install: | |
# sudo pkg install bash && sudo pkg install ipmitool | |
# Add ipmi_load="YES" to /boot/loader.conf | |
# Add this script to /usr/bin/ | |
# Add * * * * * /usr/local/bin/bash /usr/bin/cfan.sh to cron file with sudo crontab -e | |
# Reboot | |
temp_min=30 | |
temp_max=70 | |
fan_min=20 | |
fan_max=100 | |
# 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>&1 | |
while true; do | |
# Edit to work on BSD systems | |
CURRENT_TEMP=`sysctl dev.cpu | grep temperature | awk '{print $2}'` | |
AVERAGE_TEMP=0 | |
NUMBER_OF_CORES=0 | |
#Take the average temperature reading of all cores | |
for core_temp in $CURRENT_TEMP; do | |
# Remove "C" from the end of the readings | |
core_temp=`echo "$core_temp" | sed 's/.$//'` | |
AVERAGE_TEMP=`echo "$AVERAGE_TEMP + $core_temp" | bc -l` | |
NUMBER_OF_CORES=`echo "$NUMBER_OF_CORES + 1" | bc -l` | |
done | |
temp=`echo "scale=0; $AVERAGE_TEMP / $NUMBER_OF_CORES" | bc -l` | |
# End edit | |
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>&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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for this, however there is a problem.
You are sending the
$fan_speed
variable as decimal while the DELL IPMI needs hex. This is problematic with low fan speed values.I fixed it by modifying lines ~86-89: