You are not logged in.
Hi guys,
I have an ASUS U30JC for which lm_sensors is unable to detect my fan and that I can control it. After research I found a guy who solved the fan problem for an ASUS Zenbook with ACPI (http://forum.notebookreview.com/asus/70 … x32vd.html). I ported the approach with ACPI to my laptop, because it is fairly general.
You may need to modify the ACPI commands (probably the namespace of the actual command) for another device. For example I needed to replace "\_SB.PCI0.LPCB.EC0.SFNV" with "\_SB.PCI0.SBRG.EC0.SFNV".
You can get the ACPI specification (https://wiki.archlinux.org/index.php/DSDT) by:
1.) Extract ACPI tables (as root): # cat /sys/firmware/acpi/tables/DSDT > dsdt.dat
2.) Decompile: iasl -d dsdt.dat
Search for e.g. SFNV and adapt the "namespace/path".
# fancontrol.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time, os, sys, signal, setproctitle, traceback
MIN_TEMP = 70 # fan starts to cool
MAX_TEMP = 95 # fan cooling full power
def call_acpi(command):
acpi_call = open('/proc/acpi/call', 'w')
acpi_call.write(command)
acpi_call.close()
# Response
acpi_call = open('/proc/acpi/call')
response = acpi_call.read()
acpi_call.close()
return response
def set_fan(speed, fan=1):
if speed < 0:
speed = 0
elif speed > 100:
speed = 100
raw_speed = round(speed * 2.55)
call_acpi('\_SB.PCI0.SBRG.EC0.SFNV %d %s' % (fan, raw_speed))
print('Set fan speed to %d %%' % speed)
def get_cpu_temp():
return int(call_acpi('\_SB.PCI0.SBRG.EC0.ECPU')[:4], 16)
# you can adjust the fan behavior with any mathematic function
# for example you can use a square function "return temp**2* or cubic "return temp**3"
def scale_temp(temp):
return temp
def handle_fan(current_temp):
temp_range = MAX_TEMP - MIN_TEMP
norm_temp = current_temp - MIN_TEMP if (current_temp - MIN_TEMP) > 0 else 0
scaled_temp = scale_temp(norm_temp)
scaled_border = scale_temp(temp_range)
fan_speed = 100/scaled_border * scaled_temp # in percent
print("Current CPU temperature %d°" % current_temp)
set_fan(fan_speed)
def cleanup(signal=None, frame=None):
call_acpi('\_SB.PCI0.SBRG.EC0.SFNV 0 0')
call_acpi('\_SB.ATKD.QMOD 0x02')
print('\nReset fan control to automatic. Exiting...')
sys.exit(0)
def main():
signal.signal(signal.SIGTERM, cleanup)
try:
while True:
handle_fan(get_cpu_temp())
time.sleep(2)
except:
traceback.print_exc()
finally:
cleanup()
if __name__=='__main__':
# TODO: only one instance
setproctitle.setproctitle('fancontrol')
main()
You need acpi_call and python-setproctitle (AUR, optional).
setproctitle and traceback is optional for better handling/debugging you can comment it if you want to.
It's more a proof of concept but it works for me and I am very happy now
Important think about minimum and maximum temperature!
You can change the fan behavior in "scale_temp(temp)": linear, square, cubic, ... whatever you want.
On exiting or terminating the automatic mode is activated again (which does not work SIGKILL of course).
Hope it works for you and I think it should work on other laptops with small modifications (ACPI commands).
Feel free to modify and adjust my script
Best regards,
fishman
Offline
Thanks a lot it works on my UX501JW
Offline