Preliminary Linux Fan Control {A manual override method}

So the truth is Linux fan control sucks especially on laptops. So lets try to control the CPU fan with our own little bash script why dont we

Now I need to preface this with the fact that I will make continual refinements to this script.

This is mainly for people with laptops or people with no EFI Fan Control Curve overrides

This is a crude working version based on my asus controller in my laptop. It will absolutely vary from PC to PC. Now this was my approach

So what you have to realize is that the temp controller despite rounding has the ability to display up to three decimal places most engineers will just round to the nearest whole number which the ASUS people did. So temperature is in the thousands when you read the file on my PC and that is why you need this weird temperature value. Now keep in mind you can no longer monitor the RPM of the fan because setting a PWM value puts the controller in manual mode and disables all the nice stuff. I really hate controllers that do this with linux systems. Anways I made my curve as you can see. Scroll to the middle to see my values. They start at 45 and max the fan at 65

before we start get lm-sensors so we can at least view what controllers we have

sudo apt install lm-sensors && sensors

sensors output:

iwlwifi-virtual-0
Adapter: Virtual device
temp1:        +42.0°C  

pch_skylake-virtual-0
Adapter: Virtual device
temp1:        +61.5°C  

acpitz-virtual-0
Adapter: Virtual device
temp1:        +49.0°C  (crit = +103.0°C)

asus-isa-0000
Adapter: ISA adapter
cpu_fan:       -1 RPM
temp1:        +49.0°C  

coretemp-isa-0000
Adapter: ISA adapter
Package id 0:  +50.0°C  (high = +100.0°C, crit = +100.0°C)
Core 0:        +46.0°C  (high = +100.0°C, crit = +100.0°C)
Core 1:        +48.0°C  (high = +100.0°C, crit = +100.0°C)
Core 2:        +45.0°C  (high = +100.0°C, crit = +100.0°C)
Core 3:        +47.0°C  (high = +100.0°C, crit = +100.0°C)

heimdallr@WiFightWhenWeCanMakeLove:~$ 

Assigning PWM levels: CSV

    TEXT :: "Eric K Ayers Reverse Engineering Fan Control (ASUS GL502VT-DS74",,,,"Notes:"
    FORMAT :: "TEMP Celsius","PWM MAX","SCALE","PWM VAL",
    0000,255,0,0,"DONT operate below freezing"
    1000,255,0,0,
    2000,255,0,0,
    3000,255,0,0,
    4000,255,0,0,
    5000,255,0,0,
    6000,255,0.35,89,"Fan min operating speed 35 %"
    7000,255,0.35,89,
    8000,255,0.35,89,
    9000,255,0.35,89,
    10000,255,0.35,89,
    11000,255,0.35,89,
    12000,255,0.35,89,
    13000,255,0.35,89,
    14000,255,0.35,89,
    15000,255,0.35,89,
    16000,255,0.35,89,
    17000,255,0.35,89,
    18000,255,0.35,89,
    19000,255,0.35,89,
    20000,255,0.35,89,
    21000,255,0.35,89,
    22000,255,0.35,89,
    23000,255,0.35,89,
    24000,255,0.35,89,
    25000,255,0.35,89,
    26000,255,0.35,89,
    27000,255,0.35,89,
    28000,255,0.35,89,
    29000,255,0.35,89,
    30000,255,0.35,89,
    31000,255,0.35,89,
    32000,255,0.35,89,
    33000,255,0.35,89,
    34000,255,0.35,89,
    35000,255,0.35,89,
    36000,255,0.35,89,
    37000,255,0.35,89,
    38000,255,0.35,89,
    39000,255,0.35,89,
    40000,255,0.35,89,
    41000,255,0.35,89,
    42000,255,0.35,89,
    43000,255,0.35,89,
    44000,255,0.35,89,
    45000,255,35.00%,89,"Start Fan Curve Here"
    46000,255,38.25%,97,
    47000,255,41.50%,105,
    48000,255,44.75%,114,
    49000,255,48.00%,122,
    50000,255,51.25%,130,
    51000,255,54.50%,138,
    52000,255,57.75%,147,
    53000,255,61.00%,155,
    54000,255,64.25%,163,
    55000,255,67.50%,172,
    56000,255,70.75%,180,
    57000,255,74.00%,188,
    58000,255,77.25%,196,
    59000,255,80.50%,205,
    60000,255,83.75%,213,
    61000,255,87.00%,221,
    62000,255,90.25%,230,
    63000,255,93.50%,238,
    64000,255,96.75%,246,
    65000,255,100.00%000,255,"Max speed should occur at TJ Max"
    66000,255,100.00%000,255,"CPU’s do not like temps above this"
    67000,255,100.00%000,255,"Keep Maxed"
    68000,255,100.00%000,255,
    69000,255,100.00%000,255,
    70000,255,100.00%000,255,
    71000,255,100.00%000,255,
    72000,255,100.00%000,255,
    73000,255,100.00%000,255,
    74000,255,100.00%000,255,
    75000,255,100.00%000,255,
    76000,255,100.00%000,255,
    77000,255,100.00%000,255,
    78000,255,100.00%000,255,
    79000,255,100.00%000,255,
    80000,255,100.00%000,255,
    81000,255,100.00%000,255,
    82000,255,100.00%000,255,
    83000,255,100.00%000,255,
    84000,255,100.00%000,255,
    85000,255,100.00%000,255,
    86000,255,100.00%000,255,
    87000,255,100.00%000,255,
    88000,255,100.00%000,255,
    89000,255,100.00%000,255,
    90000,255,100.00%000,255,
    91000,255,100.00%000,255,
    92000,255,100.00%000,255,
    93000,255,100.00%000,255,
    94000,255,100.00%000,255,
    95000,255,100.00%000,255,
    96000,255,100.00%000,255,
    97000,255,100.00%000,255,
    98000,255,100.00%000,255,
    99000,255,100.00%000,255,
    100000,255,100.00%000,255,"TRIG HALT"

Code: (Bash Script ran as sudo)
Pay close attention to my methodology in setting the paths as they constantly vary boot to boot

#!/bin/bash

    # PURPOSE: Script runs fan control as per Eric's reverse engineering of the GL502VT Controllers
    # EXPLOIT TYPE: SHIM (Drivers remain proprietary so we must override the system and poll ourselves)
    # AUTHOR: Eric Ayers
    # Assumes asus temperature from sensors command is as follows matches cat file with approprive DIV:
    #
    # coretemp-isa-0000
    # Adapter: ISA adapter
    # Package id 0:  +47.0°C  (high = +100.0°C, crit = +100.0°C) << Temp of concern
    # Core 0:        +47.0°C  (high = +100.0°C, crit = +100.0°C)
    # Core 1:        +46.0°C  (high = +100.0°C, crit = +100.0°C)
    # Core 2:        +43.0°C  (high = +100.0°C, crit = +100.0°C)
    # Core 3:        +45.0°C  (high = +100.0°C, crit = +100.0°C)
    #
    #
    if [  $EUID -ne 0  ]; then
       echo "Eric mandates this script be run as root"
       exit 1
    fi
    echo "SCRIPT STARTED AT $(date)"
    echo "=========================================================="
    sensors
    pathPWM1=$(sudo find /sys/devices/platform/asus-nb-wmi/ -name pwm1)
    pathT1=$(sudo find /sys/devices/platform/asus-nb-wmi/ -name temp1_input)
    echo "Information for user above :: For monitoring purposes only"
    echo "=========================================================="
    echo ''
    echo ''
    stop=0
    while true;
    do
    sleep 0.1
    currTemp="$(cat $pathT1)"
    tempThresFreeze=5000
    tempThres45=45000
    tempThres46=46000
    tempThres47=47000
    tempThres48=48000
    tempThres49=49000
    tempThres50=50000
    tempThres51=51000
    tempThres52=52000
    tempThres53=53000
    tempThres54=54000
    tempThres55=55000
    tempThres56=56000
    tempThres57=57000
    tempThres58=58000
    tempThres59=59000
    tempThres60=60000
    tempThres61=61000
    tempThres62=62000
    tempThres63=63000
    tempThres64=64000
    tempThres65=65000
    tempThresHalt=105000

    if [ $currTemp -lt $tempThresFreeze ]
    then
      sudo echo "0" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres45 ]
    then
      sudo echo "130" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres46 ]
    then
      sudo echo "130" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres47 ]
    then
      sudo echo "130" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres48 ]
    then
      sudo echo "130" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres49 ]
    then
      sudo echo "130" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres50 ]
    then
      sudo echo "130" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres51 ]
    then
      sudo echo "138" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres52 ]
    then
      sudo echo "147" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres53 ]
    then
      sudo echo "155" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres54 ]
    then
      sudo echo "163" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres55 ]
    then
      sudo echo "172" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres56 ]
    then
      sudo echo "180" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres57 ]
    then
      sudo echo "188" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres58 ]
    then
      sudo echo "196" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres59 ]
    then
      sudo echo "205" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres60 ]
    then
      sudo echo "213" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres61 ]
    then
      sudo echo "221" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres62 ]
    then
      sudo echo "230" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres63 ]
    then
      sudo echo "238" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres64 ]
    then
      sudo echo "246" >> $pathPWM1
    fi

    if [ $currTemp -eq $tempThres65 ]
    then
      sudo echo "255" >> $pathPWM1
    fi

    if [ $currTemp -gt $tempThres65 ]
    then
      sudo echo "255" >> $pathPWM1
    fi


    echo "Information for user below :: States temp and fan speed"
    echo "CORE TEMP"
    echo "$(cat $pathT1)"
    echo "FAN PWM"
    echo "$(cat $pathPWM1)"

    done

This was my methodology. it could obviously be cleaned up but feel free to build on the idea. Its in my GIT but I think just posting it here should suffice.

This should work for most devices but you will have to do a bit of digging in your own systems

dependencies:
lm-sensors

Lets us all share ideas below and ways we can improve linux fan control! I know it can be done and we need to focus on making something robust that isnt based on the old fancontrol script wrapper. Its really not that great. It used to be but now things have changed!

Next Steps

Output in screen
Log Screen output
Automate – Create System D Service
Create interface for DC and PWM
Create GUI
Allow for hysterisis
Reverse Engineer NVIDIA SMI to expose laptop GPU fan control. (Its usually stuffed away in dev/null and unexposed)

4 Likes

What do if lm-sensors doesn’t detect any fans on the laptop?

2 Likes

It doesnt matter. We are overriding this. See the script you can still access fan control manually with sudo and the write file paths

It should be inside one of the platform folders

/sys/devices/platform/

This is the part of the guide I cant really write because its too variable It will require you doing some manual labor on your part to figure out where the fan control is hiding

2 Likes

I’ll bookmark this, coz this is a problem with my work laptop. Will check it on Monday.

Thanks.

2 Likes

Ill provide support below

should anybody want help with that labor. This comes free with no guarantee and also per my own schedule :grin:

3 Likes