Skip to content

Instantly share code, notes, and snippets.

@ChrisG661
Forked from goophile/i8kmon.py
Last active March 17, 2024 03:05
Show Gist options
  • Save ChrisG661/a695041075eede68a38d3515b62aa809 to your computer and use it in GitHub Desktop.
Save ChrisG661/a695041075eede68a38d3515b62aa809 to your computer and use it in GitHub Desktop.
i8kmon/i8kfan for Dell Optiplex 7050 SFF desktop
#!/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