#!/usr/bin/env python # # Daemon wrapper script downloaded from http://code.activestate.com/recipes/66012/ # # A daemon to start and stop the fan on a thinkpad R61i running linux. import sys, os '''This module is used to fork the current process into a daemon. Almost none of this is necessary (or advisable) if your daemon is being started by inetd. In that case, stdin, stdout and stderr are all set up for you to refer to the network connection, and the fork()s and session manipulation should not be done (to avoid confusing inetd). Only the chdir() and umask() steps remain as useful. References: UNIX Programming FAQ 1.7 How do I get my program to act like a daemon? http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 Advanced Programming in the Unix Environment W. Richard Stevens, 1992, Addison-Wesley, ISBN 0-201-56317-7. ''' def daemonize (stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): '''This forks the current process into a daemon. The stdin, stdout, and stderr arguments are file names that will be opened and be used to replace the standard file descriptors in sys.stdin, sys.stdout, and sys.stderr. These arguments are optional and default to /dev/null. Note that stderr is opened unbuffered, so if it shares a file with stdout then interleaved output may not appear in the order that you expect. ''' # Do first fork. try: pid = os.fork() if pid > 0: sys.exit(0) # Exit first parent. except OSError, e: sys.stderr.write ('fork #1 failed: (%d) %s\n' % (e.errno, e.strerror) ) sys.exit(1) # Decouple from parent environment. os.chdir('/') os.umask(0) os.setsid() # Do second fork. try: pid = os.fork() if pid > 0: sys.exit(0) # Exit second parent. except OSError, e: sys.stderr.write ('fork #2 failed: (%d) %s\n' % (e.errno, e.strerror) ) sys.exit(1) # Now I am a daemon! # Redirect standard file descriptors. si = file(stdin, 'r') so = file(stdout, 'a+') se = file(stderr, 'a+', 0) os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(se.fileno(), sys.stderr.fileno()) def setfan(level): ''' Set the fan speed ''' # FIXME - Check the given value is the correct type and within range. procfile = open('/proc/acpi/ibm/fan','w') procfile.write('level %d' % ( level ) ) procfile.close() def main (): ''' Start the fan if the machine is too hot, stop it when it's cool. ''' # Setup cooltemp, min temp for each fan level, and time between checks. l1temp = 55 l2temp = 70 l4temp = 75 l7temp = 80 const_sleeptime = 20 # Initially set the fan speed to level 1 setfan(1) import time import re while True: f = open('/proc/acpi/thermal_zone/THM0/temperature','r') temp = f.read() f.close() match = re.search("([0-9]*) C",temp) temp = int(match.group(1)) sleeptime = const_sleeptime if temp >= l7temp: setfan(7) elif temp >= l4temp: setfan(4) elif temp >= l2temp: setfan(2) elif temp >= l1temp: setfan(1) sleeptime = sleeptime + 300 # Avoid switching between fan speed 0 and 1 each cycle. elif temp < l1temp: setfan(0) else: setfan(1) # Default to level 1 time.sleep(sleeptime) if __name__ == '__main__': daemonize('/dev/null','/var/log/fancontrold.log','/var/log/fancontrold.log') main()