Temperature based fan speed control?


xamindar

Recommended Posts

I'm running beta12 and have a Gigabyte K8N Ultra-SLI motherboard with 3x 3-pin fans attached. In the past I've been able to control the fan speeds on windows by using the program speedfan. Can the script provided here be used to control my fan speeds?

Yes, but it only does it based on the temperature of the hard drives you specify in the script if that is what you want.

I read about PWM but that's 4-pin fans. Or should I start a new topic?

Linux calls it PWM no matter which type you have, 3 or 4 pin. I'm using the script with 3 pin fans.

I already did sensors-detect which in the end gave me below results. I don't know if I have to do the copy and service start what is displays. Do I? Newbie here :)

No you don't have to start the service, just make sure the modules it found are loaded on boot up.

Link to comment

I'm running beta12 and have a Gigabyte K8N Ultra-SLI motherboard with 3x 3-pin fans attached. In the past I've been able to control the fan speeds on windows by using the program speedfan. Can the script provided here be used to control my fan speeds?

Yes, but it only does it based on the temperature of the hard drives you specify in the script if that is what you want.

I read about PWM but that's 4-pin fans. Or should I start a new topic?

Linux calls it PWM no matter which type you have, 3 or 4 pin. I'm using the script with 3 pin fans.

I already did sensors-detect which in the end gave me below results. I don't know if I have to do the copy and service start what is displays. Do I? Newbie here :)

No you don't have to start the service, just make sure the modules it found are loaded on boot up.

Thank you very much for the clarification. and how do I load the modules on boot?

It generated "/etc/sysconfig/lm_sensors" but what is it for?

 

To get them running at boot time, I should do what it says?;

Copy prog/init/lm_sensors.init to /etc/init.d/lm_sensors

 

Also, spending more and more time now on the forums I discover all kinds of neat things to do. But you definitely need at least moderate linux knowledge. However I know nothing about linux since I'm only windows orientated. I've always wanted to get into linux and now unraid is forcing me :) Do you perhaps have any tips on where to get a good start. There are so many tuts on the inet but as with everything I assume the really good ones you just need to know. Just asking...

Link to comment
  • 5 weeks later...

Hello,

I am interested in getting this working, however when i run pwmconfig i get the following

root@SERVO:~# pwmconfig                                                                                                                       

# pwmconfig revision 5770 (2009-09-16)                                                                                                       

This program will search your sensors for pulse width modulation (pwm)                                                                       

controls, and test each one to see if it controls a fan on                                                                                   

your motherboard. Note that many motherboards do not have pwm                                                                                 

circuitry installed, even if your sensor chip supports pwm.                                                                                   

                                                                                                                                             

We will attempt to briefly stop each fan using the pwm controls.                                                                             

The program will attempt to restore each fan to full speed                                                                                   

after testing. However, it is ** very important ** that you                                                                                   

physically verify that the fans have been to full speed                                                                                       

after the program has completed.                                                                                                             

                                                                                                                                             

/usr/sbin/pwmconfig: There are no pwm-capable sensor modules installed                                                                       

root@SERVO:~#                           

 

My motherboard is a Gigabyte ep43-ud3L

 

Does this mean that I cannot use this for fan control?

Link to comment
  • 10 months later...

Is anybody running this under 5.0?  I upgraded from 4.7 (where it was working perfectly), to 5.0-rc6-r8168-test2, and now its not working.

 

PWMCONFIG doesnt find any devices.

root@nas:/sys/class/hwmon/hwmon0/device# pwmconfig
# pwmconfig revision 5770 (2009-09-16)
This program will search your sensors for pulse width modulation (pwm)
controls, and test each one to see if it controls a fan on
your motherboard. Note that many motherboards do not have pwm
circuitry installed, even if your sensor chip supports pwm.

We will attempt to briefly stop each fan using the pwm controls.
The program will attempt to restore each fan to full speed
after testing. However, it is ** very important ** that you
physically verify that the fans have been to full speed
after the program has completed.

/usr/sbin/pwmconfig: There are no pwm-capable sensor modules installed

 

/sys/class/hwmon/hwmon0/device doesn't list any PWM devices either

lrwxrwxrwx 1 root root    0 2012-09-01 12:57 driver -> ../../../bus/platform/drivers/coretemp/
drwxr-xr-x 3 root root    0 2012-09-01 12:57 hwmon/
-r--r--r-- 1 root root 4096 2012-09-02 12:41 modalias
-r--r--r-- 1 root root 4096 2012-09-01 12:58 name
drwxr-xr-x 2 root root    0 2012-09-02 12:41 power/
lrwxrwxrwx 1 root root    0 2012-09-01 12:57 subsystem -> ../../../bus/platform/
-r--r--r-- 1 root root 4096 2012-09-01 12:58 temp2_crit
-r--r--r-- 1 root root 4096 2012-09-01 12:58 temp2_crit_alarm
-r--r--r-- 1 root root 4096 2012-09-01 12:58 temp2_input
-r--r--r-- 1 root root 4096 2012-09-02 12:41 temp2_label
-r--r--r-- 1 root root 4096 2012-09-01 12:58 temp2_max
-r--r--r-- 1 root root 4096 2012-09-01 12:58 temp3_crit
-r--r--r-- 1 root root 4096 2012-09-01 12:58 temp3_crit_alarm
-r--r--r-- 1 root root 4096 2012-09-01 12:58 temp3_input
-r--r--r-- 1 root root 4096 2012-09-02 12:41 temp3_label
-r--r--r-- 1 root root 4096 2012-09-01 12:58 temp3_max
-r--r--r-- 1 root root 4096 2012-09-01 12:58 temp4_crit
-r--r--r-- 1 root root 4096 2012-09-01 12:58 temp4_crit_alarm
-r--r--r-- 1 root root 4096 2012-09-01 12:58 temp4_input
-r--r--r-- 1 root root 4096 2012-09-02 12:41 temp4_label
-r--r--r-- 1 root root 4096 2012-09-01 12:58 temp4_max
-r--r--r-- 1 root root 4096 2012-09-01 12:58 temp5_crit
-r--r--r-- 1 root root 4096 2012-09-01 12:58 temp5_crit_alarm
-r--r--r-- 1 root root 4096 2012-09-01 12:58 temp5_input
-r--r--r-- 1 root root 4096 2012-09-02 12:41 temp5_label
-r--r--r-- 1 root root 4096 2012-09-01 12:58 temp5_max
-rw-r--r-- 1 root root 4096 2012-09-01 12:57 uevent

 

ls -l of /sys/class/hwmon only lists hwmon0

root@nas:/sys/class/hwmon# ls -l
total 0
lrwxrwxrwx 1 root root 0 2012-09-01 12:58 hwmon0 -> ../../devices/platform/coretemp.0/hwmon/hwmon0/

 

Output of unraid-fan-speed.sh:

root@nas:/boot/custom/bin# unraid-fan-speed.sh
Highest temp is: 35
./unraid-fan-speed.sh: line 74: /sys/class/hwmon/hwmon0/device/pwm2_enable: No such file or directory
cat: /sys/class/hwmon/hwmon0/device/pwm2: No such file or directory
./unraid-fan-speed.sh: line 89: [: : integer expression expected
./unraid-fan-speed.sh: line 93: /sys/class/hwmon/hwmon0/device/pwm2: No such file or directory
Setting pwm to: 120

 

 

Any ideas???  Thanks.

 

Link to comment
  • 9 months later...

NEW VERSION OF THE unraid-fan-speed.sh SCRIPT!

 

EDIT: v0.2: Made a small change so the fan speed on low doesn't fluctuate every time the script is run.

EDIT: v0.3: It will now enable fan speed change before trying to change it. I missed it at first because pwmconfig was doing it for me while I was testing the fan.

EDIT: v0.4: Corrected temp reading to "Temperature_Celsius" as my new Seagate drive was returning two numbers with just "Temperature".

NEW v0.5: By Pauven:  Added linear PWM logic to slowly ramp speed when fan is between HIGH and OFF.

 

I'm picking up where xamindar left off - thank you xamindar for an excellent script!

 

When I first used the script, I was surprised when the fans instantly changed from the Low speed value to the High speed value when there was only a single degree temperature increase.  Looking at the code, I did not see any linear speed ramping logic... so I added it!

 

Here's an example of the new logic, based upon the current values in the script posted below:

 

With an FAN_OFF_TEMP of 30 and a FAN_HIGH_TEMP OF 40, and with a FAN_LOW_PWM of 80 and a FAN_HIGH_PWM of 255, the new logic will perform some math and figure out that there are 9 PWM increments of 19 between 80 and 255, corresponding to temps 31-39.

 

Using the above values, the fan speed would ramp as follows:

 

  • 31 degrees = 80 PWM
  • 32 degrees = 99 PWM
  • 33 degrees = 118 PWM
  • 34 degrees = 137 PWM
  • 35 degrees = 156 PWM
  • 36 degrees = 175 PWM
  • 37 degrees = 194 PWM
  • 38 degrees = 213 PWM
  • 39 degrees = 232 PWM
  • 40 degrees = 255 PWM

 

The math is automatic, you just need to set the user variables the same as before.  Enjoy!

 

-Paul

 

unraid-fan-speed.sh

#!/bin/bash
# unraid_array_fan.sh v0.5 
# v0.1: By xamindar: First try at it.
# v0.2: Made a small change so the fan speed on low doesn't fluctuate every time the script is run.
# v0.3: It will now enable fan speed change before trying to change it. I missed 
#        it at first because pwmconfig was doing it for me while I was testing the fan.
# v0.4: Corrected temp reading to "Temperature_Celsius" as my new Seagate drive
#        was returning two numbers with just "Temperature".
# v0.5: By Pauven:  Added linear PWM logic to slowly ramp speed when fan is between HIGH and OFF.
# A simple script to check for the highest hard disk temperatures in an array
# or backplane and then set the fan to an apropriate speed. Fan needs to be connected
# to motherboard with pwm support, not array.
# DEPENDS ON:grep,awk,smartctl,hdparm

### VARIABLES FOR USER TO SET ###
# Amount of drives in the array. Make sure it matches the amount you filled out below.
NUM_OF_DRIVES=15

# unRAID drives that are in the array/backplane of the fan we need to control
HD[1]=/dev/sdb
HD[2]=/dev/sdc
HD[3]=/dev/sdd
HD[4]=/dev/sde
HD[5]=/dev/sdf
HD[6]=/dev/sdg
HD[7]=/dev/sdh
HD[8]=/dev/sdi
HD[9]=/dev/sdj
HD[10]=/dev/sdk
HD[11]=/dev/sdl
HD[12]=/dev/sdm
HD[13]=/dev/sdn
HD[14]=/dev/sdo
HD[15]=/dev/sdp
#HD[16]=/dev/sdq
#HD[17]=/dev/sdr
#HD[18]=/dev/sds
#HD[19]=/dev/sdt
#HD[20]=/dev/sdu
#HD[21]=/dev/sdv
#HD[22]=/dev/sdw
#HD[23]=/dev/sdx
#HD[24]=/dev/sdy

# Temperatures to change fan speed at
# Any temp between OFF and HIGH will cause fan to run on low speed setting 
FAN_OFF_TEMP=30     # Anything this number and below - fan is off
FAN_HIGH_TEMP=40    # Anything this number or above - fan is high speed

# Fan speed settings. Run pwmconfig (part of the lm_sensors package) to determine 
# what numbers you want to use for your fan pwm settings. Should not need to
# change the OFF variable, only the LOW and maybe also HIGH to what you desire.
# Any real number between 0 and 255.
#
# FAN_OFF_PWM=100
# FAN_LOW_PWM=150
# FAN_HIGH_PWM=255
FAN_OFF_PWM=70
FAN_LOW_PWM=80
FAN_HIGH_PWM=255


# Fan device. Depends on your system. pwmconfig can help with finding this out. 
# pwm1 is usually the cpu fan. You can "cat /sys/class/hwmon/hwmon0/device/fan1_input"
# or fan2_input and so on to see the current rpm of the fan. If 0 then fan is off or 
# there is no fan connected or motherboard can't read rpm of fan.
# ARRAY_FAN=/sys/class/hwmon/hwmon1/device/pwm2
ARRAY_FAN=/sys/class/hwmon/hwmon1/device/pwm2

### END USER SET VARIABLES ###


# Program variables - do not modify
HIGHEST_TEMP=0
CURRENT_DRIVE=1
CURRENT_TEMP=0

# Linear PWM Logic Variables - do not modify
NUM_STEPS=$((FAN_HIGH_TEMP - FAN_OFF_TEMP - 1))
PWM_INCREMENT=$(( (FAN_HIGH_PWM - FAN_LOW_PWM) / NUM_STEPS))
echo "Linear PWM Range is "$FAN_LOW_PWM" to "$FAN_HIGH_PWM" in "$NUM_STEPS" increments of "$PWM_INCREMENT


# while loop to get the highest temperature of active drives. 
# If all are spun down then high temp will be set to 0.
while [ "$CURRENT_DRIVE" -le "$NUM_OF_DRIVES" ]
do
  SLEEPING=`hdparm -C ${HD[$CURRENT_DRIVE]} | grep -c standby`
  if [ "$SLEEPING" == "0" ]; then
    CURRENT_TEMP=`smartctl -d ata -A ${HD[$CURRENT_DRIVE]} | grep -m 1 -i Temperature_Celsius | awk '{print $10}'`
    if [ "$HIGHEST_TEMP" -le "$CURRENT_TEMP" ]; then
      HIGHEST_TEMP=$CURRENT_TEMP
    fi
  fi
#echo $CURRENT_TEMP
  let "CURRENT_DRIVE+=1"
done
echo "Highest temp is: "$HIGHEST_TEMP

# Enable speed change on this fan if not already
if [ "$ARRAY_FAN" != "1" ]; then
  echo 1 > "${ARRAY_FAN}_enable"
fi

# Set the fan speed based on highest temperature
if [ "$HIGHEST_TEMP" -le "$FAN_OFF_TEMP" ]; then
  # set fan to off
  echo $FAN_OFF_PWM  > $ARRAY_FAN
  echo "Setting pwm to: "$FAN_OFF_PWM
  elif [ "$HIGHEST_TEMP" -ge "$FAN_HIGH_TEMP" ]; then
    # set fan to full speed
    echo $FAN_HIGH_PWM > $ARRAY_FAN
    echo "Setting pwm to: "$FAN_HIGH_PWM
  else
    CURRENT_SPEED=`cat $ARRAY_FAN`
    # set fan to full speed first to make sure it spins up then change it to low setting.
    if [ "$CURRENT_SPEED" -lt "$FAN_LOW_PWM" ]; then
      echo $FAN_HIGH_PWM > $ARRAY_FAN
      sleep 2
    fi
    # Calculate target fan PWM speed as a linear value between FAN_HIGH_PWM and FAN_LOW_PWM
    FAN_LINEAR_PWM=$(( ((HIGHEST_TEMP - FAN_OFF_TEMP - 1) * PWM_INCREMENT) + FAN_LOW_PWM))
    echo $FAN_LINEAR_PWM > $ARRAY_FAN
    echo "Setting pwm to: "$FAN_LINEAR_PWM
fi

 

Link to comment

Hi Pauven, thanks for your contribution.

Just as a note: There is another fan control script "somewhere" on the forum (can't remember where, but I am using it since a long time), that does automatically detect the number of drives in array and also sets the pwm speed in steps between off,min,max plus support for command lines and can be run from go script, not requiring a cron entry) - I attach it here if you're interested to look into it - all credits go to the authors

fancontrol.sh.txt

Link to comment

Thanks Guzzi and aiden, I didn't find that script in my searching.

 

Setting up a cron job in my go script wasn't too hard, but obviously not a one-liner. 

 

I looked at the code, and it seems both scripts have a common origin, as many of the variable names are exactly the same, though your script does appear to be newer, more polished and user friendly.  Wish I had found it earlier.

Link to comment

yeah, those script versions are spread around the forum - and hard to find ;-).

As aiden said, script has evolved over time by several contributors - and the one I posted above was "the best" to my knowledge - mostly, because I

a) do not need to change something, if drives are added or removed from array and

b) for the continuous rpm regulation (that you also implemented).

iirc, JoeL just recently improved unmenu to adaptively use -D ata parameters when checking drives - that might be worth to include, if it can be automated without causing regression - didn't check what he did for that - but would make the script more universal for to old hw and e.g. newer sas controllers (usage with or without "-D ata" param)

Link to comment
  • 2 months later...

I attach it here if you're interested to look into it - all credits go to the authors

 

Hi Guzzi,

 

Thanks for posting that updated fan control script! I was using the one where you had to state how many drives you had and I much prefer not needing to maintain it when I make changes to my array.

 

One small oversight: The version info of the script states that you removed -d ata in the smartctl command, but in the version you attached, it was still in place (line 201).

 

I switched the line to reflect the updated code, and now I no longer get  "integer expression expected" errors (and a failure to read the temp of those drives) on the drives attached to my m1015s

 

It took me an embarrassing amount of time to figure out the problem  :-[ (That'll teach me to not read the version info!!), so in case anyone else is also getting the error on a m1015 controller using this script (or likely other sas controllers as well), that is the solution!

Link to comment

Hi DoeBoye, sorry for the trouble you had - 1015 controller was the exact reason, WHY I removed that ata option from the script for myself ...

 

No Problem! My fault for not reading your updated version info! :). Mostly I wanted to post so you could update the script in your previous post. If you don't have it handy, I can attach it to my post :)

Link to comment
  • 1 month later...

NEW VERSION OF THE unraid-fan-speed.sh SCRIPT!

 

What are the commands you added to the go script to get this running on cron?

 

I don't remember where I found this, but I'm using the following in my go script:

 

# Load adapter drivers:
modprobe ipmi-si

# Load chip drivers:
modprobe coretemp
modprobe w83627ehf

# Insert unraid-fan-speed.sh into crontab 
chmod +x /boot/scripts/unraid-fan-speed.sh
crontab -l >/tmp/crontab
grep -q "unraid-fan-speed.sh" /tmp/crontab 1>/dev/null 2>&1
if [ "$?" = "1" ]
then
    crontab -l | egrep -v "control unRAID fan speed based on temperature:|unraid-fan-speed.sh" >/tmp/crontab
    echo "#" >>/tmp/crontab
    echo "# control unRAID fan speed based on temperature" >>/tmp/crontab
    echo "*/2 * * * * /boot/scripts/unraid-fan-speed.sh 1>/dev/null 2>&1" >>/tmp/crontab
    cp /tmp/crontab /var/spool/cron/crontabs/root-
    crontab /tmp/crontab
fi

 

The problem is unRAID 5 is choking on this line "/tmp/crontab /var/spool/cron/crontabs/root-" (specifically, something to do with the root account) and reports this constantly in the syslog.  So I'm trying to understand the logic behind this copy command followed by the crontab command in order to modify it to work under unRAID 5, though even with these errors, the script appears to still be running in a timely fashion and correctly adjusting my fans.

Link to comment
  • 3 years later...

Hey folks - I know this is a long-dead thread, but I found it very useful in getting my unRAID server setup.

 

Because I had to piece together instructions from all over the place, I wrote up the full instructions in a blog post here:

http://kmwoley.com/blog/controlling-case-fans-based-on-hard-drive-temperature/

 

Since I made modifications to the script to reduce the logging output and set a fan starting speed (different from the fan low speed), I posted it up on GitHub here for others to see & contribute to.

 

Given the age of this thread, I suspect most folks are using a plugin to control their fans - I found that the Dynamix fan control plugin didn't work for me, so I went this route instead.

 

Thanks for all of your help!

 

-kmwoley

  • Upvote 1
Link to comment
  • 4 months later...
On 25/05/2017 at 2:06 AM, kmwoley said:

Hey folks - I know this is a long-dead thread, but I found it very useful in getting my unRAID server setup.

 

Because I had to piece together instructions from all over the place, I wrote up the full instructions in a blog post here:

http://kmwoley.com/blog/controlling-case-fans-based-on-hard-drive-temperature/

 

Since I made modifications to the script to reduce the logging output and set a fan starting speed (different from the fan low speed), I posted it up on GitHub here for others to see & contribute to.

 

Given the age of this thread, I suspect most folks are using a plugin to control their fans - I found that the Dynamix fan control plugin didn't work for me, so I went this route instead.

 

Thanks for all of your help!

 

-kmwoley


Hey thank you for your tutorial, you just did a small error when you refer to the file in the "mycrontab.txt" file the name of your script is "fan_control.sh" but in the tutorial we refer at "unraid_array_fan.sh".

Link to comment
  • 4 years later...
On 3/12/2010 at 1:22 AM, xamindar said:

Well, I figured out that my little mini itx board that unraid is using has pwm fan speed control on all three fan ports so I can just use that. I spent some time and wrote a very simple script to check the temperatures of the drives, pick the highest one, then set the speed of the fan accordingly between three speed settings. I am still waiting for a fan to come in the mail that I will use with the 5 in 3 backplane (norco ss-500) but I have tested this script on the cpu fan and it works great. I am definitely open to criticism as this is only the second bash script I have ever written.

 

It's not very smart so you have to edit it and be sure to set all the user variables correctly. Then just add a cron entry to run this script every 5 minutes or so and it should work.

 

Also one more thing. I don't know if smartctl will reset the spindown timer so it may cause the drives to never spin down. Anyone know if this is the case? I do know that running the smartctl on a drive in standby does NOT cause it to spin up so this is probably not an issue.

 

 

#!/bin/bash
# unraid_array_fan.sh v0.4
# v0.1  First try at it.
# v0.2: Made a small change so the fan speed on low doesn't fluctuate every time the script is run.
# v0.3: It will now enable fan speed change before trying to change it. I missed 
#	it at first because pwmconfig was doing it for me while I was testing the fan.
# v0.4: Corrected temp reading to "Temperature_Celsius" as my new Seagate drive
#	was returning two numbers with just "Temperature".
# A simple script to check for the highest hard disk temperatures in an array
# or backplane and then set the fan to an apropriate speed. Fan needs to be connected
# to motherboard with pwm support, not array.
# DEPENDS ON:grep,awk,smartctl,hdparm

### VARIABLES FOR USER TO SET ###
# Amount of drives in the array. Make sure it matches the amount you filled out below.
NUM_OF_DRIVES=3

# unRAID drives that are in the array/backplane of the fan we need to control
HD[1]=/dev/sdb
HD[2]=/dev/sdc
HD[3]=/dev/sde
HD[4]=/dev/
HD[5]=/dev/

# Temperatures to change fan speed at
# Any temp between OFF and HIGH will cause fan to run on low speed setting 
FAN_OFF_TEMP=30		# Anything this number and below - fan is off
FAN_HIGH_TEMP=36	# Anything this number or above - fan is high speed

# Fan speed settings. Run pwmconfig (part of the lm_sensors package) to determine 
# what numbers you want to use for your fan pwm settings. Should not need to
# change the OFF variable, only the LOW and maybe also HIGH to what you desire.
# Any real number between 0 and 255.
FAN_OFF_PWM=100
FAN_LOW_PWM=120
FAN_HIGH_PWM=255

# Fan device. Depends on your system. pwmconfig can help with finding this out. 
# pwm1 is usually the cpu fan. You can "cat /sys/class/hwmon/hwmon0/device/fan1_input"
# or fan2_input and so on to see the current rpm of the fan. If 0 then fan is off or 
# there is no fan connected or motherboard can't read rpm of fan.
ARRAY_FAN=/sys/class/hwmon/hwmon1/device/pwm2

### END USER SET VARIABLES ###

# Program variables - do not modify
HIGHEST_TEMP=0
CURRENT_DRIVE=1
CURRENT_TEMP=0

# while loop to get the highest temperature of active drives. 
# If all are spun down then high temp will be set to 0.
while [ "$CURRENT_DRIVE" -le "$NUM_OF_DRIVES" ]
do
 SLEEPING=`hdparm -C ${HD[$CURRENT_DRIVE]} | grep -c standby`
 if [ "$SLEEPING" == "0" ]; then
   CURRENT_TEMP=`smartctl -d ata -A ${HD[$CURRENT_DRIVE]} | grep -m 1 -i Temperature_Celsius | awk '{print $10}'`
   if [ "$HIGHEST_TEMP" -le "$CURRENT_TEMP" ]; then
     HIGHEST_TEMP=$CURRENT_TEMP
   fi
 fi
#echo $CURRENT_TEMP
 let "CURRENT_DRIVE+=1"
done
echo "Highest temp is: "$HIGHEST_TEMP

# Enable speed change on this fan if not already
if [ "$ARRAY_FAN" != "1" ]; then
 echo 1 > "${ARRAY_FAN}_enable"
fi

# Set the fan speed based on highest temperature
if [ "$HIGHEST_TEMP" -le "$FAN_OFF_TEMP" ]; then
 # set fan to off
 echo $FAN_OFF_PWM > $ARRAY_FAN
 echo "Setting pwm to: "$FAN_OFF_PWM
 elif [ "$HIGHEST_TEMP" -ge "$FAN_HIGH_TEMP" ]; then
   # set fan to full speed
   echo $FAN_HIGH_PWM > $ARRAY_FAN
   echo "Setting pwm to: "$FAN_HIGH_PWM
 else
   CURRENT_SPEED=`cat $ARRAY_FAN`
   # set fan to full speed first to make sure it spins up then change it to low setting.
   if [ "$CURRENT_SPEED" -lt "$FAN_LOW_PWM" ]; then
     echo $FAN_HIGH_PWM > $ARRAY_FAN
     sleep 2
   fi
   echo $FAN_LOW_PWM > $ARRAY_FAN
   echo "Setting pwm to: "$FAN_LOW_PWM
fi
 

 

 

EDIT: v0.2: Made a small change so the fan speed on low doesn't fluctuate every time the script is run.

EDIT: v0.3: It will now enable fan speed change before trying to change it. I missed it at first because pwmconfig was doing it for me while I was testing the fan.

EDIT: v0.4: Corrected temp reading to "Temperature_Celsius" as my new Seagate drive was returning two numbers with just "Temperature".

unraid-fan-speed.sh.zip 1.68 kB · 317 downloads

 

Can you add multiple fans to be controlled under ARRAY_FAN and not just one? I have 4 fans that is used to control temp for my hdd and would like to control all of them using this script

Edited by ProphetSe7en
Link to comment
  • 1 year later...
On 3/11/2010 at 6:22 PM, xamindar said:

Well, I figured out that my little mini itx board that unraid is using has pwm fan speed control on all three fan ports so I can just use that. I spent some time and wrote a very simple script to check the temperatures of the drives, pick the highest one, then set the speed of the fan accordingly between three speed settings. I am still waiting for a fan to come in the mail that I will use with the 5 in 3 backplane (norco ss-500) but I have tested this script on the cpu fan and it works great. I am definitely open to criticism as this is only the second bash script I have ever written.

 

It's not very smart so you have to edit it and be sure to set all the user variables correctly. Then just add a cron entry to run this script every 5 minutes or so and it should work.

 

Also one more thing. I don't know if smartctl will reset the spindown timer so it may cause the drives to never spin down. Anyone know if this is the case? I do know that running the smartctl on a drive in standby does NOT cause it to spin up so this is probably not an issue.

 

 

#!/bin/bash
# unraid_array_fan.sh v0.4
# v0.1  First try at it.
# v0.2: Made a small change so the fan speed on low doesn't fluctuate every time the script is run.
# v0.3: It will now enable fan speed change before trying to change it. I missed 
#	it at first because pwmconfig was doing it for me while I was testing the fan.
# v0.4: Corrected temp reading to "Temperature_Celsius" as my new Seagate drive
#	was returning two numbers with just "Temperature".
# A simple script to check for the highest hard disk temperatures in an array
# or backplane and then set the fan to an apropriate speed. Fan needs to be connected
# to motherboard with pwm support, not array.
# DEPENDS ON:grep,awk,smartctl,hdparm

### VARIABLES FOR USER TO SET ###
# Amount of drives in the array. Make sure it matches the amount you filled out below.
NUM_OF_DRIVES=3

# unRAID drives that are in the array/backplane of the fan we need to control
HD[1]=/dev/sdb
HD[2]=/dev/sdc
HD[3]=/dev/sde
HD[4]=/dev/
HD[5]=/dev/

# Temperatures to change fan speed at
# Any temp between OFF and HIGH will cause fan to run on low speed setting 
FAN_OFF_TEMP=30		# Anything this number and below - fan is off
FAN_HIGH_TEMP=36	# Anything this number or above - fan is high speed

# Fan speed settings. Run pwmconfig (part of the lm_sensors package) to determine 
# what numbers you want to use for your fan pwm settings. Should not need to
# change the OFF variable, only the LOW and maybe also HIGH to what you desire.
# Any real number between 0 and 255.
FAN_OFF_PWM=100
FAN_LOW_PWM=120
FAN_HIGH_PWM=255

# Fan device. Depends on your system. pwmconfig can help with finding this out. 
# pwm1 is usually the cpu fan. You can "cat /sys/class/hwmon/hwmon0/device/fan1_input"
# or fan2_input and so on to see the current rpm of the fan. If 0 then fan is off or 
# there is no fan connected or motherboard can't read rpm of fan.
ARRAY_FAN=/sys/class/hwmon/hwmon1/device/pwm2

### END USER SET VARIABLES ###

# Program variables - do not modify
HIGHEST_TEMP=0
CURRENT_DRIVE=1
CURRENT_TEMP=0

# while loop to get the highest temperature of active drives. 
# If all are spun down then high temp will be set to 0.
while [ "$CURRENT_DRIVE" -le "$NUM_OF_DRIVES" ]
do
 SLEEPING=`hdparm -C ${HD[$CURRENT_DRIVE]} | grep -c standby`
 if [ "$SLEEPING" == "0" ]; then
   CURRENT_TEMP=`smartctl -d ata -A ${HD[$CURRENT_DRIVE]} | grep -m 1 -i Temperature_Celsius | awk '{print $10}'`
   if [ "$HIGHEST_TEMP" -le "$CURRENT_TEMP" ]; then
     HIGHEST_TEMP=$CURRENT_TEMP
   fi
 fi
#echo $CURRENT_TEMP
 let "CURRENT_DRIVE+=1"
done
echo "Highest temp is: "$HIGHEST_TEMP

# Enable speed change on this fan if not already
if [ "$ARRAY_FAN" != "1" ]; then
 echo 1 > "${ARRAY_FAN}_enable"
fi

# Set the fan speed based on highest temperature
if [ "$HIGHEST_TEMP" -le "$FAN_OFF_TEMP" ]; then
 # set fan to off
 echo $FAN_OFF_PWM > $ARRAY_FAN
 echo "Setting pwm to: "$FAN_OFF_PWM
 elif [ "$HIGHEST_TEMP" -ge "$FAN_HIGH_TEMP" ]; then
   # set fan to full speed
   echo $FAN_HIGH_PWM > $ARRAY_FAN
   echo "Setting pwm to: "$FAN_HIGH_PWM
 else
   CURRENT_SPEED=`cat $ARRAY_FAN`
   # set fan to full speed first to make sure it spins up then change it to low setting.
   if [ "$CURRENT_SPEED" -lt "$FAN_LOW_PWM" ]; then
     echo $FAN_HIGH_PWM > $ARRAY_FAN
     sleep 2
   fi
   echo $FAN_LOW_PWM > $ARRAY_FAN
   echo "Setting pwm to: "$FAN_LOW_PWM
fi
 

 

 

EDIT: v0.2: Made a small change so the fan speed on low doesn't fluctuate every time the script is run.

EDIT: v0.3: It will now enable fan speed change before trying to change it. I missed it at first because pwmconfig was doing it for me while I was testing the fan.

EDIT: v0.4: Corrected temp reading to "Temperature_Celsius" as my new Seagate drive was returning two numbers with just "Temperature".

unraid-fan-speed.sh.zip 1.68 kB · 324 downloads

 

 

Thank you very much for this script, I used it as a basis for one of my own scripts.   I made an enhancement that you might like in yours as well, to allow more steps in fan speed depending on temperature.  This has the added benefit of being less code!

 

    TEMPS=(0 40 65 75 80)

    #Note, speeds are reversed here because my fan uses inverted PMV
    SPEEDS=(255 200 150 100 0)

 

<do work to get HDD/CPU Temps here and figure out which is the highest, per your prior script>

 

    for i in ${!TEMPS[@]}; do 
        CHECKTEMP=${TEMPS[$i]}                
        if [ "$HIGHEST_TEMP" -le "$CHECKTEMP" ]; then
            break
        fi
        LASTTEMP=${TEMPS[$i]}
        FANSET=${SPEEDS[$i]}
    done
    echo "Temp " $HIGHEST_TEMP " >= " $LASTTEMP "Setting fan to " $FANSET
    echo $FANSET > $ARRAY_FAN

Edited by Terebi
  • Like 1
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.