--- /dev/null
+#!/usr/bin/env python
+
+import os
+import sys
+import signal
+import time
+
+class daemon:
+ def __init__(self):
+ self.pid_filename='/var/run/amdtempd.pid'
+ self.go_auto_temp=x=5000 #under this we switch back to auto mode
+ self.gpu_temp_path='/sys/class/hwmon/hwmon0/temp1_input'
+ self.fan_mode_path='/sys/class/hwmon/hwmon0/pwm1_enable'
+ self.fan_speed_path='/sys/class/hwmon/hwmon0/pwm1'
+ self.fan_rpm_path='/sys/class/hwmon/hwmon0/fan1_input'
+ self.modes={0:'None',1:'Manual',2:'Auto'}
+ self.default_mode=2
+ self.default_fan_speed=90
+ self.fan_off_temp=40
+ self.curve={}
+ while x <= 120000:
+ #self.curve.update({x:(((x-9000)/28538)**6)+102}) #should be +102
+ #self.curve.update({x:(((x-17500)/16403)**4)+104}) #should be +104
+ self.curve.update({x:(((x-10000)/21609)**5)+90}) #should be +90
+ if self.curve[x]>255:self.curve.update({x:255})
+ if x<(self.fan_off_temp*1000):self.curve.update({x:0})
+ x+=1000
+
+ def exit(self,sig,*_):
+ sig_name=str(signal.Signals(sig))[8:]
+ print('AMDTempd: Received %s, stopping gracefully ...' %sig_name)
+ if self.default_mode != 2:self.set_fan_speed(self.default_fan_speed)
+ self.set_mode(self.default_mode)
+ try:os.remove(self.pid_filename)
+ except:sys.exit(1)
+ sys.exit(0)
+
+ def start(self):
+ self.default_mode=self.read_file(self.fan_mode_path)
+ self.default_fan_speed=self.read_file(self.fan_speed_path)
+ self.get_mode()
+ try:
+ pid_file = open(self.pid_filename,'x')
+ except FileExistsError as error:
+ pid=self.read_file(self.pid_filename)
+ if not os.system('ps -A|awk \'{print $1}\'|grep -qw "%s"'%pid):
+ print('AMDTempd: PID file already exists and daemon is running. Exiting...')
+ sys.exit(1)
+ else:
+ print('AMDTempd: Removing stale PID file:')
+ os.remove(self.pid_filename)
+ self.start()
+ except OSError as error:
+ print(error)
+ sys.exit(1)
+ #endtry
+ pid_file.write(str(os.getpid()))
+ pid_file.close()
+ signal.signal(signal.SIGINT, self.exit)#from ctrl-c
+ signal.signal(signal.SIGUSR1, self.exit)#from main script stop()
+ signal.signal(signal.SIGTERM, self.exit)#from start-stop-daemon
+ while True:
+ time.sleep(1)
+ self.check_temp()
+
+ def check_temp(self):
+ gpu_temp=self.read_file(self.gpu_temp_path)
+ if gpu_temp <= self.go_auto_temp:
+ if self.current_mode != 'Auto':
+ self.set_mode(2)
+ return
+ self.set_fan_speed(self.curve[gpu_temp])
+
+ def set_mode(self,mode):
+ mode_file=open(self.fan_mode_path,'w')
+ mode_file.write(str(mode))
+ mode_file.close()
+ self.current_mode=self.modes[int(mode)]
+
+ def set_fan_speed(self,Pspeed):
+ if self.current_mode != 'Manual':
+ self.set_mode(1)
+ speed=str(int(Pspeed))
+ speed_file=open(self.fan_speed_path,'w')
+ speed_file.write(speed)
+ speed_file.close()
+
+ def get_mode(self):
+ mode=self.read_file(self.fan_mode_path)
+ self.current_mode=self.modes[mode]
+
+ def read_file(self,path):
+ try:
+ ret_file=open(path,'r')
+ ret_val=ret_file.read()
+ ret_file.close()
+ return int(ret_val)
+ except:
+ os.system ('ogg123 ~/GPU_fan_error.ogg')
+ self.exit(signal.SIGUSR1)
+
+ def simple_exit(self,sig,*frame):
+ sys.exit(0)
+
+ def force_stop(self,pid):
+ if pid:print('AMDTempd: Daemon refused to exit cleanly, killing PID:%s with SIGKILL and cleaning up'%pid)
+ try: os.remove(self.pid_filename)
+ except: pass
+ if pid:
+ print ('AMDTempd: %s'%os.system('/bin/kill -SIGKILL %s'%pid))
+ else:
+ os.system('ps aux|sed -n "/python %s start/p"|awk \'{print $2}\'|xargs /bin/kill -SIGKILL >/dev/null 2>&1'%(sys.argv[0].replace('/','\/')))
+ sys.exit(0)
+
+ def stop(self):
+ pid=0
+ try:
+ pid=self.read_file(self.pid_filename)
+ os.remove(self.pid_filename)
+ except:
+ self.force_stop(pid)
+ os.system('/bin/kill -SIGUSR1 %s'%pid)
+ timer=60
+ while timer > 0 and not os.system('ps -A|grep -qw "%s"'%pid):
+ time.sleep(0.1)
+ timer-=1
+ if not os.system('ps -A|grep -q "%s"'%pid):force_stop(pid)
+ sys.exit(0)
+
+ def status(self):
+ signal.signal(signal.SIGINT,self.simple_exit)
+ try: interval=sys.argv[2]
+ except:interval=0
+ run=True
+ while run:
+ if os.system('ps aux|grep -v grep 2>/dev/null|grep -q "python %s start"'%sys.argv[0]):
+ isRunning='Not running'
+ else:
+ isRunning='Yes, PID:%s'%self.read_file(self.pid_filename)
+ maxx=self.read_file(self.fan_speed_path)
+ curr=self.read_file(self.fan_rpm_path)
+ temp=self.read_file(self.gpu_temp_path)
+ mode=self.read_file(self.fan_mode_path)
+ print('###############################')
+ print(' Running : %s'%isRunning)
+ print(' Temp : %s°C'%int(temp/1000))
+ print(' Current RPM : %s'%curr)
+ print(' Current Fan : %s %s%%'%(maxx,int(curr/35)))
+ print(' Current Mode : %s'%self.modes[mode])
+ print('###############################')
+ time.sleep(int(interval))
+ run=interval
+
+try:
+ action=sys.argv[1]
+ if action == 'start':
+ main=daemon()
+ fork_ret=os.fork()
+ if fork_ret == 0:
+ main.start()
+ else:
+ sys.exit(0)
+ elif action == 'stop':
+ main=daemon()
+ main.stop()
+ elif action == 'status':
+ main=daemon()
+ main.status()
+ else:
+ print('Usage: %s start|stop'%sys.argv[0][sys.argv[0].rfind('/')+1:])
+except IndexError:
+ print('Usage: %s start|stop'%sys.argv[0][sys.argv[0].rfind('/')+1:])
+#endtry