-
-
Save ChrisG661/a695041075eede68a38d3515b62aa809 to your computer and use it in GitHub Desktop.
i8kmon/i8kfan for Dell Optiplex 7050 SFF desktop
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
import re | |
import subprocess | |
import time | |
# On my Dell Precision desktop, the `i8kmon` controls the fan level according to the ambient temperature, not the CPU temperature. | |
# Maybe the i8kutils only works for laptop? I don't know. Luckily, the `i8kfan` CAN control the motherboard fan and CPU fan. | |
# It's usage is `i8kfan - -`, the first number is for motherboard, the second for CPU. You should test the sequence first. | |
# Modified to only change CPU fan level, works on my Dell Optiplex 7050 SFF | |
# What this script do is simple: get temperatures from `/sys/class/hwmon`, and change the fan levels with `i8kfan`. | |
# CPU temperature threshold, level 1 and level 2 | |
# ------------ 50 -------------- 65 ---------- | |
# ---- 45 ------------ 55 ------------ | |
# if temp is below L1_LOW, turn fan off. | |
# if temp is higher than L1_HIGH, turn fan on level 1, and last until temp drop to L1_LOW. | |
# same for L2. | |
CPU_L1_LOW = 45 | |
CPU_L1_HIGH = 55 | |
CPU_L2_LOW = 60 | |
CPU_L2_HIGH = 70 | |
CHECK_INTERVAL = 5 | |
DEBUG = False | |
CPU_L1_LAST = False | |
CPU_L2_LAST = False | |
def log(Msg='none'): | |
global DEBUG | |
if DEBUG: | |
print(time.strftime("%Y-%m-%d %H:%M:%S"), | |
Msg) | |
def get_temp(): | |
coretemp_dir = '/sys/class/hwmon/hwmon3/temp1_input' | |
try: | |
with open(coretemp_dir, 'r') as coretemp_temp: | |
CPUTemp = int(coretemp_temp.read().strip()) // 1000 | |
except: | |
log("Error getting temperature.") | |
return None | |
temp_output = f'CPU: {CPUTemp}°C' | |
log(temp_output) | |
return CPUTemp | |
def set_fan(CPULevel=2): | |
i8kfan_cmd = ['i8kfan', "-", str(CPULevel)] | |
log(i8kfan_cmd) | |
try: | |
subprocess.call(i8kfan_cmd) | |
except Exception as e: | |
log(e) | |
return None | |
else: | |
return True | |
def get_level(CPUTemp=80): | |
global CPU_L1_LAST | |
global CPU_L2_LAST | |
global CPU_L1_LOW | |
global CPU_L1_HIGH | |
global CPU_L2_LOW | |
global CPU_L2_HIGH | |
CPULevel = 2 | |
# for CPU, fan flag | |
if CPUTemp < CPU_L1_LOW: | |
CPU_L1_LAST = False | |
elif CPUTemp > CPU_L1_HIGH: | |
CPU_L1_LAST = True | |
if CPUTemp < CPU_L2_LOW: | |
CPU_L2_LAST = False | |
elif CPUTemp > CPU_L2_HIGH: | |
CPU_L2_LAST = True | |
# for CPU, fan level | |
if CPUTemp < CPU_L1_LOW: | |
CPULevel = 0 | |
elif CPUTemp < CPU_L1_HIGH: | |
if CPU_L1_LAST == True: | |
CPULevel = 1 | |
else: | |
CPULevel = 0 | |
elif CPUTemp < CPU_L2_LOW: | |
CPULevel = 1 | |
elif CPUTemp < CPU_L2_HIGH: | |
if CPU_L2_LAST == True: | |
CPULevel = 2 | |
else: | |
CPULevel = 1 | |
else: | |
CPULevel = 2 | |
return CPULevel | |
try: | |
LastLevel = int(subprocess.check_output("i8kfan", stderr=subprocess.STDOUT, | |
shell=True, universal_newlines=True).strip().split(' ')[1]) | |
except: | |
LastLevel = -1 | |
while True: | |
CPUTemp = get_temp() | |
if CPUTemp: | |
CPULevel = get_level(CPUTemp) | |
if CPULevel: | |
if CPULevel != LastLevel: | |
#r1 = set_fan(BoardLevel, CPULevel) | |
r1 = set_fan(CPULevel) | |
if not r1: | |
log('set fan error') | |
break | |
else: | |
log('fan level not change') | |
LastLevel = CPULevel | |
else: | |
continue | |
else: | |
log('error get_temp()') | |
continue | |
time.sleep(CHECK_INTERVAL) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment