root/lm-sensors/trunk/prog/pwm/pwmconfig @ 5855

Revision 5855, 22.9 KB (checked in by khali, 3 years ago)

When looking for pwm/fan correlations, sample all fans before returning
a given PWM output to full speed. The code used to only sample the first
fan before doing so, so correlation with other fans could be missed.
Problem reported by Charles Pillar. This closes ticket #2380.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1#!/bin/bash
2#
3# pwmconfig
4# Tests the pwm outputs of sensors and configures fancontrol
5# Supported Linux kernel versions: 2.6.5 and later
6#
7#    Warning!!! This program will stop your fans, one at a time,
8#    for approximately 5 seconds each!!!
9#    This may cause your processor temperature to rise!!!
10#    Verify that all fans are running at normal speed after this
11#    program has exited!!!
12#
13#    Copyright (C) 2007-2009 Jean Delvare <khali@linux-fr.org>
14#
15#    This program is free software; you can redistribute it and/or modify
16#    it under the terms of the GNU General Public License as published by
17#    the Free Software Foundation; either version 2 of the License, or
18#    (at your option) any later version.
19#
20#    This program is distributed in the hope that it will be useful,
21#    but WITHOUT ANY WARRANTY; without even the implied warranty of
22#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23#    GNU General Public License for more details.
24#
25#    You should have received a copy of the GNU General Public License
26#    along with this program; if not, write to the Free Software
27#    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
28#    MA 02110-1301 USA.
29#
30#
31
32REVISION=$(echo '$Revision$' | cut -d' ' -f2)
33REVDATE=$(echo '$Date$' | cut -d' ' -f2)
34PIDFILE="/var/run/fancontrol.pid"
35
36if [ -f "$PIDFILE" ]
37then
38        echo "File $PIDFILE exists. This typically means that the"
39        echo "fancontrol deamon is running. You should stop it before running pwmconfig."
40        echo "If you are certain that fancontrol is not running, then you can delete"
41        echo "$PIDFILE manually."
42        exit 1
43fi
44
45if [ "`id -u`" != "0" ]
46then
47        echo "You need to be root to run this script."
48        exit 1
49fi
50
51echo "# pwmconfig revision $REVISION ($REVDATE)"
52echo 'This program will search your sensors for pulse width modulation (pwm)'
53echo 'controls, and test each one to see if it controls a fan on'
54echo 'your motherboard. Note that many motherboards do not have pwm'
55echo 'circuitry installed, even if your sensor chip supports pwm.'
56echo
57echo 'We will attempt to briefly stop each fan using the pwm controls.'
58echo 'The program will attempt to restore each fan to full speed'
59echo 'after testing. However, it is ** very important ** that you'
60echo 'physically verify that the fans have been to full speed'
61echo 'after the program has completed.'
62echo
63
64DELAY=5 # 3 seconds delay is too short for large fans, thus I increased it to 5
65MAX=255
66
67if [ -d "/sys/class/hwmon" ]
68then
69        SYSFS=2
70        DIR="/sys/class/hwmon"
71        PREFIX='hwmon*'
72elif [ -d "/sys/bus/i2c/devices" ]
73then
74        SYSFS=1
75        DIR="/sys/bus/i2c/devices"
76        PREFIX='*-*'
77else
78        echo $0: 'No sensors found! (modprobe sensor modules?)'
79        exit 1
80fi
81
82cd $DIR
83DEVICES=`echo $PREFIX`
84if [ "$PREFIX" = "$DEVICES" ]
85then
86        echo $0: 'No sensors found! (modprobe sensor modules?)'
87        exit 1
88fi
89
90# We may need to adjust the device path
91if [ "$SYSFS" = "2" ]
92then
93        OLD_DEVICES="$DEVICES"
94        DEVICES=""
95
96        for device in $OLD_DEVICES
97        do
98                if [ ! -r "$device/name" ]
99                then
100                        device="$device/device"
101                fi
102               
103                DEVICES="$DEVICES $device"
104        done
105fi
106
107
108for device in $DEVICES
109do
110        # Find available fan control outputs
111        MATCH=$device/'pwm[1-9]'
112        device_pwm=`echo $MATCH`
113        if [ "$SYSFS" = "1" -a "$MATCH" = "$device_pwm" ]
114        then
115                # Deprecated naming scheme (used in kernels 2.6.5 to 2.6.9)
116                MATCH=$device/'fan[1-9]_pwm'
117                device_pwm=`echo $MATCH`
118        fi
119        if [ "$MATCH" != "$device_pwm" ]
120        then
121                PWM="$PWM $device_pwm"
122        fi
123
124        # Find available fan monitoring inputs
125        MATCH=$device/'fan[1-9]_input'
126        device_fan=`echo $MATCH`
127        if [ "$MATCH" != "$device_fan" ]
128        then
129                FAN="$FAN $device_fan"
130        fi
131done
132
133if [ -z "$PWM" ]
134then
135        echo $0: 'There are no pwm-capable sensor modules installed'
136        exit 1
137fi
138if [ -z "$FAN" ]
139then
140        echo $0: 'There are no fan-capable sensor modules installed'
141        exit 1
142fi
143
144# $1 = padding
145function print_devices()
146{
147        local name
148
149        for device in $DEVICES
150        do
151                name=`cat $device/name 2> /dev/null`
152                [ -z "$name" ] && name="unknown (no name attribute)"
153                echo "$1$device is $name"
154        done
155}
156
157# $1 = pwm file name
158function is_pwm_auto()
159{
160        ENABLE=${1}_enable
161        if [ -f $ENABLE ]
162        then
163                if [ "`cat $ENABLE`" -gt 1 ]
164                then
165                        return 0
166                fi
167        fi
168
169        return 1
170}
171
172# $1 = pwm file name
173function pwmdisable()
174{
175        ENABLE=${1}_enable
176        # No enable file? Just set to max
177        if [ ! -f $ENABLE ]
178        then
179                echo $MAX > $1
180                return 0
181        fi
182
183        # Try pwmN_enable=0
184        echo 0 2>/dev/null > $ENABLE
185        if [ "`cat $ENABLE`" -eq 0 ]
186        then
187                # Success
188                return 0
189        fi
190
191        # It didn't work, try pwmN_enable=1 pwmN=255
192        echo 1 2>/dev/null > $ENABLE
193        if [ "`cat $ENABLE`" -ne 1 ]
194        then
195                echo "$ENABLE stuck to `cat $ENABLE`" >&2
196                return 1
197        fi
198
199        echo $MAX > $1
200        if [ "`cat $1`" -ge 190 ]
201        then
202                # Success
203                return 0
204        fi
205
206        # Nothing worked
207        echo "$1 stuck to `cat $1`" >&2
208        return 1
209}
210
211# $1 = pwm file name
212function pwmenable()
213{
214        ENABLE=${1}_enable
215        if [ -w $ENABLE ]
216        then
217                echo 1 2>/dev/null > $ENABLE
218                if [ $? -ne 0 ]
219                then
220                        return 1
221                fi
222        fi
223        echo $MAX > $1
224}
225
226# $1 = pwm file name; $2 = pwm value 0-255
227function pwmset()
228{
229        echo $2 > $1
230}
231
232echo 'Found the following devices:'
233print_devices "   "
234echo
235
236echo 'Found the following PWM controls:'
237for i in $PWM
238do
239        echo "   $i"
240        if [ -w $i ]
241        then
242                # First check if PWM output is in automatic mode
243                if is_pwm_auto $i
244                then
245                        echo "$i is currently setup for automatic speed control."
246                        echo 'In general, automatic mode is preferred over manual mode, as'
247                        echo 'it is more efficient and it reacts faster. Are you sure that'
248                        echo -n 'you want to setup this output for manual control? (n) '
249                        read X
250                        if [ "$X" = "" -o "$X" != "y" -a "$X" != "Y" ]
251                        then
252                                continue
253                        fi
254                fi
255
256                pwmdisable $i
257                if [ $? -ne 0 ]
258                then
259                        echo "Manual control mode not supported, skipping $i."
260                elif [ "$GOODPWM" = "" ]
261                then
262                        GOODPWM=$i
263                else
264                        GOODPWM="$GOODPWM $i"
265                fi
266        else
267                echo "Can't write to $i, skipping."
268        fi
269done
270
271if [ "$GOODPWM" = "" ]
272then
273        echo 'There are no usable PWM outputs.'
274        exit 1
275fi
276
277echo
278echo "Giving the fans some time to reach full speed..."
279sleep $DELAY
280echo 'Found the following fan sensors:'
281for i in $FAN
282do
283        # this will return the first field if there's only one (sysfs)
284        S=`cat $i | cut -d' ' -f2`
285        if [ "$S" = "0" -o "$S" = "-1" ]
286        then
287                echo "   $i     current speed: 0 ... skipping!"
288        else
289                echo "   $i     current speed: $S RPM"
290                if [ "$GOODFAN" = "" ]
291                then
292                        GOODFAN=$i
293                        SPEEDS=$S
294                else
295                        GOODFAN="$GOODFAN $i"
296                        SPEEDS="$SPEEDS $S"
297                fi
298        fi
299done
300echo
301
302if [ "$GOODFAN" = "" ]
303then
304        echo 'There are no working fan sensors, all readings are 0.'
305        echo 'Make sure you have a 3-wire fan connected.'
306        echo 'You may also need to increase the fan divisors.'
307        echo 'See doc/fan-divisors for more information.'
308        exit 1
309fi
310
311echo 'Warning!!! This program will stop your fans, one at a time,'
312echo "for approximately $DELAY seconds each!!!"
313echo 'This may cause your processor temperature to rise!!!'
314echo 'If you do not want to do this hit control-C now!!!'
315echo -n 'Hit return to continue: '
316read X
317echo
318
319PLOTTER=gnuplot
320STEP=15
321PDELAY=2
322# Use a smaller step for low PWM values as this is typically where the
323# more important fan speed changes are happening.
324STEP2=2
325STEP2_BELOW=31
326
327function pwmdetail()
328{
329        P=$1
330        F=$2
331        PLOT=
332
333        type $PLOTTER > /dev/null 2>&1
334        if [ $? -eq 0 ]
335        then
336                echo -n "Would you like to generate a graphical plot using $PLOTTER (y)? "
337                read X
338                if [ "$X" = "y" -o "$X" = "Y" -o "$X" = "" ]
339                then
340                        PLOT=y
341                fi
342        else
343                if [ -n "$DISPLAY" ]
344                then
345                        echo "Note: If you had $PLOTTER installed, I could generate a graphical plot."
346                fi
347        fi
348
349        if [ "$PLOT" = "y" ]
350        then
351                TMP1=`mktemp -t pwmtest1.XXXXXXXXXX` || { echo "$0: Cannot create temporary file" >&2; exit 1; }
352                TMP2=`mktemp -t pwmtest2.XXXXXXXXXX` || { rm -f $TMP1 ; echo "$0: Cannot create temporary file" >&2; exit 1; }
353                echo "set xlabel \"PWM: $P\"" > $TMP1
354                echo "set ylabel \"FAN: $F (RPM)\"" >> $TMP1
355                echo 'set nokey' >> $TMP1
356                echo 'set xrange [0:255]' >> $TMP1
357                echo "plot \"$TMP2\" with lines" >> $TMP1
358                echo 'pause -1 "    Hit return to continue..."' >> $TMP1
359                > $TMP2
360        fi
361
362        local threshold=100000
363        let pwm=$MAX
364        pwmenable $P
365        while [ $pwm -ge 0 ]
366        do
367                pwmset $P $pwm
368                sleep $PDELAY
369                if [ $? -ne 0 ]
370                then
371                        pwmdisable $P
372                        echo '^C received, aborting...'
373                        rm -f $TMP1 $TMP2
374                        exit 1
375                fi
376                # this will return the first field if there's only one (sysfs)
377                S=`cat $F | cut -d' ' -f2`
378                # Fan speed should never increase significantly
379                if [ $S -gt $threshold ]
380                then
381                        echo "    PWM $pwm FAN $S (probably incorrect)"
382                else
383                        echo "    PWM $pwm FAN $S"
384                        let threshold=S*6/5
385                fi
386
387                if [ "$PLOT" = "y" ]
388                then
389                        echo "$pwm $S" >> $TMP2
390                fi
391                if [ "$S" = "0" -o "$S" = "-1" ]
392                then
393                        pwmdisable $P
394                        echo "    Fan Stopped at PWM = $pwm"
395                        if [ $pwm -eq $MAX ]
396                        then
397                                echo "    This fan appears to stop when the PWM is enabled;"
398                                echo "    perhaps the fan input shares a pin with the PWM output"
399                                echo "    on the sensor chip."
400                                echo "    You cannot control this fan with this PWM output."
401                                rm -f $TMP1 $TMP2
402                                echo
403                                return 0
404                        fi
405                        break
406                fi
407                if [ $pwm -lt $STEP2_BELOW ]
408                then
409                        let pwm=$pwm-$STEP2
410                else
411                        let pwm=$pwm-$STEP
412                fi
413        done
414        pwmdisable $P
415        if [ "$PLOT" = "y" ]
416        then
417                $PLOTTER  $TMP1
418                rm -f $TMP1 $TMP2
419        fi
420        echo
421}
422
423for i in $GOODPWM
424do
425        echo Testing pwm control $i ...
426        pwmenable $i
427        if [ $? -ne 0 ]
428        then
429                echo "Manual control mode not supported, skipping."
430                continue
431        fi
432        pwmset $i 0
433        sleep $DELAY
434        if [ $? -ne 0 ]
435        then
436                pwmdisable $i
437                echo '^C received, restoring PWM and aborting...'
438                exit 1
439        fi
440
441        # Sample all current fan speeds at once, so that we can quickly
442        # disable PWM and return all fans to full speed
443        CURRENT_SPEEDS="`cat $GOODFAN`"
444        pwmdisable $i
445
446        let pwmactivecount=0
447        let count=1
448        for j in $GOODFAN
449        do
450                OS=`echo $SPEEDS | cut -d' ' -f$count`
451                S=`echo $CURRENT_SPEEDS | cut -d' ' -f$count`
452                echo "  $j ... speed was $OS now $S"
453                let threshold=2*$OS/3
454                if [ $S -lt $threshold ]
455                then
456                        echo "    It appears that fan $j"
457                        echo "    is controlled by pwm $i"
458#
459# a PWM can control more than one fan....
460#
461                        if [ $pwmactivecount -eq 0 ]
462                        then
463                                let pwmactivecount=1
464                                pwmactive="$i ${pwmactive}"
465                                fanactive="$j ${fanactive}"
466                                fanactive_min="$S ${fanactive_min}"
467                        else
468                                fanactive="$j+${fanactive}" #not supported yet by fancontrol
469                                fanactive_min="$S+${fanactive_min}"
470                        fi
471                        sleep $DELAY
472                        if [ $? -ne 0 ]
473                        then
474                                echo '^C received, aborting...'
475                                exit 1
476                        fi
477                        # this will return the first field if there's only one (sysfs)
478                        S=`cat $j | cut -d' ' -f2`
479                        if [ $S -lt $threshold ]
480                        then
481                                echo "    Fan $j has not returned to speed, please investigate!"
482                        else
483                                echo -n "Would you like to generate a detailed correlation (y)? "
484                                read X
485                                if [ "$X" = "y" -o "$X" = "Y" -o "$X" = "" ]
486                                then
487                                        pwmdetail $i $j
488                                fi
489                        fi
490                else
491                        echo "    no correlation"
492                fi
493                let count=count+1
494        done
495        echo
496        if [ "$pwmactivecount" = "0" ]
497        then
498                echo "No correlations were detected."
499                echo "There is either no fan connected to the output of $i,"
500                echo "or the connected fan has no rpm-signal connected to one of"
501                echo "the tested fan sensors. (Note: not all motherboards have"
502                echo "the pwm outputs connected to the fan connectors,"
503                echo "check out the hardware database on http://www.almico.com/forumindex.php)"
504                echo
505                echo -n "Did you see/hear a fan stopping during the above test (n)? "
506                read X
507                if [ "$X" = "y" -o "$X" = "Y" ]
508                then
509                        pwmactive="$i ${pwmactive}"
510                fi
511                echo
512        fi
513done
514
515
516echo 'Testing is complete.'
517echo 'Please verify that all fans have returned to their normal speed.'
518echo
519echo 'The fancontrol script can automatically respond to temperature changes'
520echo 'of your system by changing fanspeeds.'
521echo -n 'Do you want to set up its configuration file now (y)? '
522
523read X
524if [ "$X" = "n" -o "$X" = "N" ]
525then
526        exit
527fi
528
529for device in $DEVICES
530do
531        # Find available temperature monitoring inputs
532        MATCH=$device/'temp[1-9]_input'
533        device_temp=`echo $MATCH`
534        if [ "$MATCH" != "$device_temp" ]
535        then
536                TEMPS="$TEMPS $device_temp"
537        fi
538done
539
540if [ -z "$TEMPS" ]
541then
542        echo $0: 'There are no temperature-capable sensor modules installed'
543        exit 1
544fi
545
546function DevicePath()
547{
548        if [ -h "$1/device" ]
549        then
550                readlink -f "$1/device" | sed -e 's/^\/sys\///'
551        fi
552}
553
554function DeviceName()
555{
556        if [ -r "$1/name" ]
557        then
558                cat "$1/name" | sed -e 's/[[:space:]=]/_/g'
559        elif [ -r "$1/device/name" ]
560        then
561                cat "$1/device/name" | sed -e 's/[[:space:]=]/_/g'
562        fi
563}
564
565function ValidateDevices()
566{
567        local OLD_DEVPATH="$1" OLD_DEVNAME="$2" outdated=0
568        local entry device name path
569
570        for entry in $OLD_DEVPATH
571        do
572                device=`echo "$entry" | sed -e 's/=[^=]*$//'`
573                path=`echo "$entry" | sed -e 's/^[^=]*=//'`
574
575                if [ "`DevicePath "$device"`" != "$path" ]
576                then
577                        echo "Device path of $device has changed"
578                        outdated=1
579                fi
580        done
581
582        for entry in $OLD_DEVNAME
583        do
584                device=`echo "$entry" | sed -e 's/=[^=]*$//'`
585                name=`echo "$entry" | sed -e 's/^[^=]*=//'`
586
587                if [ "`DeviceName "$device"`" != "$name" ]
588                then
589                        echo "Device name of $device has changed"
590                        outdated=1
591                fi
592        done
593
594        return $outdated
595}
596
597function AskPath()
598{
599        echo -n 'What should be the path to your fancontrol config file (/etc/fancontrol)? '
600
601        read FCCONFIG
602        if [ "$FCCONFIG" = "" ]
603        then
604                FCCONFIG="/etc/fancontrol"
605        fi
606}
607
608AskPath
609
610function ClearConfig()
611{
612        FCTEMPS=""
613        FCFANS=""
614        MINTEMP=""
615        MAXTEMP=""
616        MINSTART=""
617        MINSTOP=""
618        MINPWM=""
619        MAXPWM=""
620}
621
622function LoadConfig()
623{
624        local OLD_DEVPATH OLD_DEVNAME
625
626        # Nothing to do
627        if [ ! -f "$1" ]
628        then
629                ClearConfig
630                return 0
631        fi
632
633        echo "Loading configuration from $1 ..."
634        INTERVAL=`egrep '^INTERVAL=.*$' $1 | sed -e 's/INTERVAL= *//g'`
635        OLD_DEVPATH=`egrep '^DEVPATH=.*$' $1 | sed -e 's/DEVPATH= *//g'`
636        OLD_DEVNAME=`egrep '^DEVNAME=.*$' $1 | sed -e 's/DEVNAME= *//g'`
637        FCTEMPS=`egrep '^FCTEMPS=.*$' $1 | sed -e 's/FCTEMPS= *//g'`
638        FCFANS=`egrep '^FCFANS=.*$' $1 | sed -e 's/FCFANS= *//g'`
639        MINTEMP=`egrep '^MINTEMP=.*$' $1 | sed -e 's/MINTEMP= *//g'`
640        MAXTEMP=`egrep '^MAXTEMP=.*$' $1 | sed -e 's/MAXTEMP= *//g'`
641        MINSTART=`egrep '^MINSTART=.*$' $1 | sed -e 's/MINSTART= *//g'`
642        MINSTOP=`egrep '^MINSTOP=.*$' $1 | sed -e 's/MINSTOP= *//g'`
643        MINPWM=`egrep '^MINPWM=.*$' $1 | sed -e 's/MINPWM= *//g'`
644        MAXPWM=`egrep '^MAXPWM=.*$' $1 | sed -e 's/MAXPWM= *//g'`
645
646        # Check for configuration change
647        if ! ValidateDevices "$OLD_DEVPATH" "$OLD_DEVNAME"
648        then
649                echo "Configuration appears to be outdated, discarded"
650                ClearConfig
651                return 0
652        fi
653}
654
655LoadConfig $FCCONFIG
656
657# $1 = pwm value below which the fan is stopped
658function TestMinStart()
659{
660        echo
661        echo 'Now we increase the PWM value in 10-unit-steps.'
662        echo 'Let the fan stop completely, then press return until the'
663        echo "fan starts spinning. Then enter 'y'."
664        echo 'We will use this value +20 as the starting speed.'
665        let fanok=0
666        let fanval="$1"
667
668        pwmenable $pwms
669        until [ "$fanok" = "1" ]
670        do
671                if [ $fanval -gt 240 ] ; then let fanval=$MAX ; let fanok=1 ; fi
672                echo -n "Setting $pwms to $fanval..."
673                pwmset $pwms $fanval
674                read FANTEST
675                if [ "$FANTEST" != "" ] ; then let fanok=1 ; fi
676                let fanval=fanval+10
677        done
678        pwmdisable $pwms
679
680        let fanval=fanval+20
681        if [ $fanval -gt 240 ] ; then let fanval=$MAX ; fi
682        echo "OK, using $fanval"
683}
684
685# $1 = fan input to read the fan speed from
686function TestMinStop()
687{
688        local faninput=$1
689        local threshold=100000
690        local fanspeed
691
692        echo
693        echo 'Now we decrease the PWM value to figure out the lowest usable value.'
694        echo 'We will use a slightly greater value as the minimum speed.'
695        let fanval=$MAX
696
697        pwmenable $pwms
698        while [ $fanval -ge 0 ]
699        do
700                pwmset $pwms $fanval
701                sleep $PDELAY
702                fanspeed=`cat $faninput | cut -d' ' -f2`
703                if [ $fanspeed -gt $threshold ]
704                then
705                        echo "    PWM $fanval -> $fanspeed RPM (probably incorrect)"
706                        break
707                else
708                        echo "    PWM $fanval -> $fanspeed RPM"
709                        if [ $fanspeed = "0" -o $fanspeed = "-1" ]
710                        then
711                                break
712                        fi
713                        let threshold=fanspeed*6/5
714                fi
715                if [ $fanval -lt $STEP2_BELOW ]
716                then
717                        let fanval=$fanval-$STEP2
718                else
719                        let fanval=$fanval-$STEP
720                fi
721        done
722        pwmdisable $pwms
723
724        if [ $fanval -lt $STEP2_BELOW ]
725        then
726                let 'fanval=fanval+2*STEP2'
727        else
728                let 'fanval=fanval+STEP'
729        fi
730        echo "OK, using $fanval"
731}
732
733# Remember the path and name of each device with at least one
734# reference (pwm, temp or fan) in the configuration file.
735# This function sets globals DEVPATH and DEVNAME as a side effect.
736function RememberDevices()
737{
738        local used entry device name path tempfandev pwmdev
739        DEVPATH=""
740        DEVNAME=""
741
742        for device in $DEVICES
743        do
744                device=`echo "$device" | sed -e 's/\/.*$//'`
745
746                used=0
747                for entry in $1 $2
748                do
749                        pwmdev=`echo "$entry" | sed -e 's/\/.*$//'`
750                        tempfandev=`echo "$entry" | sed -e 's/^[^=]*=//' -e 's/\/.*$//'`
751
752                        if [ "$device" = "$pwmdev" -o "$device" = "$tempfandev" ]
753                        then
754                                used=1
755                        fi
756                done
757                if [ "$used" -eq 0 ]
758                then
759                        continue
760                fi
761
762                # Record the device path and name. This lets the fancontrol
763                # script check that they didn't change. If they did, then the
764                # configuration file can no longer be trusted.
765                path=`DevicePath "$device"`
766                if [ -z "$DEVPATH" ]
767                then
768                        DEVPATH="$device=$path"
769                else
770                        DEVPATH="$DEVPATH $device=$path"
771                fi
772
773                name=`DeviceName "$device"`
774                if [ -z "$DEVNAME" ]
775                then
776                        DEVNAME="$device=$name"
777                else
778                        DEVNAME="$DEVNAME $device=$name"
779                fi
780        done
781}
782
783function SaveConfig()
784{
785        RememberDevices "$FCTEMPS" "$FCFANS"
786
787        echo
788        echo "Saving configuration to $FCCONFIG..."
789        tmpfile=`mktemp -t pwmcfg.XXXXXXXXXX` || { echo "$0: Cannot create temporary file" >&2; exit 1;  }
790        trap " [ -f \"$tmpfile\" ] && /bin/rm -f -- \"$tmpfile\"" 0 1 2 3 13 15
791        echo "# Configuration file generated by pwmconfig, changes will be lost" >$tmpfile
792        echo "INTERVAL=$INTERVAL" >>$tmpfile
793        echo "DEVPATH=$DEVPATH" >>$tmpfile
794        echo "DEVNAME=$DEVNAME" >>$tmpfile
795        echo "FCTEMPS=$FCTEMPS" >>$tmpfile
796        echo "FCFANS=$FCFANS" >>$tmpfile
797        echo "MINTEMP=$MINTEMP" >>$tmpfile
798        echo "MAXTEMP=$MAXTEMP" >>$tmpfile
799        echo "MINSTART=$MINSTART" >>$tmpfile
800        echo "MINSTOP=$MINSTOP" >>$tmpfile
801        [ -n "$MINPWM" ] && echo "MINPWM=$MINPWM" >>$tmpfile
802        [ -n "$MAXPWM" ] && echo "MAXPWM=$MAXPWM" >>$tmpfile
803        mv $tmpfile $FCCONFIG
804        chmod +r $FCCONFIG
805        #check if file was written correctly
806        echo 'Configuration saved'
807}
808
809INTERVAL=10
810PS3='select (1-n): '
811DEFMINTEMP=20
812DEFMAXTEMP=60
813DEFMINSTART=150
814DEFMINSTOP=100
815
816function filter_cfgvar()
817{
818        echo "$1" | sed -e 's/ /\n/g' \
819                  | egrep "$2" \
820                  | sed -e 's/.*=//g'
821}
822
823# "select" won't repeat the list of options, so we enclose it in a
824# never-ending loop so that it starts over again with each iteration.
825# I admit it's not exactly nice, but I do not have a better idea to
826# keep usability at an acceptable level.
827while [ 1 ] ; do
828echo
829echo 'Select fan output to configure, or other action:'
830select pwms in $pwmactive "Change INTERVAL" "Just quit" "Save and quit" "Show configuration"; do
831        case $pwms in
832        "Change INTERVAL")
833                echo
834                echo "Current interval is $INTERVAL seconds."
835                echo -n "Enter the interval at which fancontrol should update PWM values (in s): "
836                read INTERVAL #check user input here
837                break ;;
838        "Just quit")
839                exit ;;
840        "Save and quit")
841                SaveConfig
842                exit ;;
843        "Show configuration")
844                echo
845                echo "Common Settings:"
846                echo "INTERVAL=$INTERVAL"
847                for pwmo in $pwmactive
848                do
849                        echo
850                        echo "Settings of ${pwmo}:"
851                        echo "  Depends on `filter_cfgvar "$FCTEMPS" "$pwmo"`"
852                        echo "  Controls `filter_cfgvar "$FCFANS" "$pwmo"`"
853                        echo "  MINTEMP=`filter_cfgvar "$MINTEMP" $pwmo`"
854                        echo "  MAXTEMP=`filter_cfgvar "$MAXTEMP" "$pwmo"`"
855                        echo "  MINSTART=`filter_cfgvar "$MINSTART" "$pwmo"`"
856                        echo "  MINSTOP=`filter_cfgvar "$MINSTOP" "$pwmo"`"
857                        XMINP=`filter_cfgvar "$MINPWM" "$pwmo"`
858                        [ -n "$XMINP" ] && echo "  MINPWM=$XMINP"
859                        XMAXP=`filter_cfgvar "$MAXPWM" "$pwmo"`
860                        [ -n "$XMAXP" ] && echo "  MAXPWM=$XMAXP"
861                done
862                echo
863                break ;;
864
865        "`echo ${pwmactive} |sed -e 's/ /\n/g' | egrep "${pwms}"`" )
866                pwmsed=`echo ${pwms} | sed -e 's/\//\\\\\//g'` #escape / for sed
867                echo
868
869                echo 'Devices:'
870                print_devices ""
871                echo
872
873                echo 'Current temperature readings are as follows:'
874                for j in $TEMPS
875                do
876                        S=`cat $j`
877                        let S="$S / 1000"
878                        echo "$j        $S"
879                done
880                FAN=`echo $fanactive|cut -d' ' -f$REPLY`
881                FAN_MIN=`echo $fanactive_min|cut -d' ' -f$REPLY`
882                FCFANS="`echo $FCFANS | sed -e "s/${pwmsed}[^ ]* *//g"` ${pwms}=$FAN"
883                echo
884                echo "Select a temperature sensor as source for ${pwms}:"
885                select tempss in $TEMPS "None (Do not affect this PWM output)"; do
886                        if [ "$tempss" = "None (Do not affect this PWM output)" ]
887                        then
888
889                                break;
890                        else
891                                if [ "$FCTEMPS" = "" ]
892                                then
893                                        FCTEMPS="${pwms}=${tempss}"
894                                else
895                                        FCTEMPS="`echo $FCTEMPS | sed -e "s/${pwmsed}[^ ]* *//g"` ${pwms}=${tempss}"
896                                fi
897                        fi
898                        echo
899                        echo 'Enter the low temperature (degree C)'
900                        echo -n "below which the fan should spin at minimum speed ($DEFMINTEMP): "
901                        read XMT
902                        if [ "$XMT" = "" ]
903                        then
904                                XMT=$DEFMINTEMP
905                        fi
906                        if [ "$MINTEMP" = "" ]
907                        then
908                                MINTEMP="${pwms}=${XMT}"
909                        else
910                                MINTEMP="`echo $MINTEMP | sed -e "s/${pwmsed}[^ ]* *//g"` ${pwms}=${XMT}"
911                        fi
912                        echo
913                        echo 'Enter the high temperature (degree C)'
914                        echo -n "over which the fan should spin at maximum speed ($DEFMAXTEMP): "
915                        read XMT
916                        if [ "$XMT" = "" ]
917                        then
918                                XMT=$DEFMAXTEMP
919                        fi
920                        if [ "$MAXTEMP" = "" ]
921                        then
922                                MAXTEMP="${pwms}=${XMT}"
923                        else
924                                MAXTEMP="`echo $MAXTEMP | sed -e "s/${pwmsed}[^ ]* *//g"` ${pwms}=${XMT}"
925                        fi
926
927                        if [ $FAN_MIN -eq 0 ]
928                        then
929                                echo
930                                echo "Enter the minimum PWM value (0-$MAX)"
931                                echo -n "at which the fan STOPS spinning (press t to test) ($DEFMINSTOP): "
932                                read XMSTOP
933
934                                if [ "$XMSTOP" = "" ]
935                                then
936                                        XMSTOP=$DEFMINSTOP
937                                fi
938                                if [ "$XMSTOP" = "t" -o "$XMSTOP" = "T" ]
939                                then
940                                        TestMinStop $FAN
941                                        XMSTOP=$fanval
942                                fi
943                        else
944                                XMSTOP=0
945                        fi
946                        if [ "$MINSTOP" = "" ]
947                        then
948                                MINSTOP="${pwms}=${XMSTOP}"
949                        else
950                                MINSTOP="`echo $MINSTOP | sed -e "s/${pwmsed}[^ ]* *//g"` ${pwms}=${XMSTOP}"
951                        fi
952
953                        if [ $FAN_MIN -eq 0 ]
954                        then
955                                echo
956                                echo "Enter the minimum PWM value ($XMSTOP-$MAX)"
957                                echo -n "at which the fan STARTS spinning (press t to test) ($DEFMINSTART): "
958                                read XMSTART
959
960                                if [ "$XMSTART" = "" ]
961                                then
962                                        XMSTART=$DEFMINSTART
963                                fi
964                                if [ "$XMSTART" = "t" -o "$XMSTART" = "T" ]
965                                then
966                                        TestMinStart $XMSTOP
967                                        XMSTART=$fanval
968                                fi
969                        else
970                                XMSTART=$DEFMINSTART
971                        fi
972                        if [ "$MINSTART" = "" ]
973                        then
974                                MINSTART="${pwms}=${XMSTART}"
975                        else
976                                MINSTART="`echo $MINSTART | sed -e "s/${pwmsed}[^ ]* *//g"` ${pwms}=${XMSTART}"
977                        fi
978
979                        if [ $XMSTOP -gt 0 ]
980                        then
981                                echo
982                                echo "Enter the PWM value (0-$XMSTOP) to use when the temperature"
983                                echo -n "is below the low temperature limit (0): "
984                                read XMINP
985                        else
986                                XMINP=""
987                        fi
988                        if [ -n "$XMINP" ]
989                        then
990                                if [ "$MINPWM" = "" ]
991                                then
992                                        MINPWM="${pwms}=${XMINP}"
993                                else
994                                        MINPWM="`echo $MINPWM | sed -e "s/${pwmsed}[^ ]* *//g"` ${pwms}=${XMINP}"
995                                fi
996                        fi
997                        echo
998                        echo "Enter the PWM value ($XMSTOP-$MAX) to use when the temperature"
999                        echo -n "is over the high temperature limit ($MAX): "
1000                        read XMAXP
1001                        if [ -n "$XMAXP" ]
1002                        then
1003                                if [ "$MAXPWM" = "" ]
1004                                then
1005                                        MAXPWM="${pwms}=${XMAXP}"
1006                                else
1007                                        MAXPWM="`echo $MAXPWM | sed -e "s/${pwmsed}[^ ]* *//g"` ${pwms}=${XMAXP}"
1008                                fi
1009                        fi
1010                        echo
1011                        break;
1012                done
1013                break ;;
1014
1015        *)
1016                echo "No such option. Enter a number."
1017                break ;;
1018        esac
1019done
1020done
Note: See TracBrowser for help on using the browser.