Skip to content

Instantly share code, notes, and snippets.

@c2h2
Created December 8, 2023 09:09
Show Gist options
  • Save c2h2/c40c6e826e80a338f95be27bd6574075 to your computer and use it in GitHub Desktop.
Save c2h2/c40c6e826e80a338f95be27bd6574075 to your computer and use it in GitHub Desktop.
pid_fan_control.py
import json
import subprocess
import datetime
import time
MAX_SPD=80
MIN_SPD=22
ipmi_host="192.168.2.145"
ipmi_pass="xxxxxx"
target_temp=43
def get_temp():
cmd = "sensors -j"
x=subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
temps=json.loads(x)
temp0=(temps['coretemp-isa-0000']['Package id 0']['temp1_input'])
temp1=(temps['coretemp-isa-0000']['Package id 0']['temp1_input']) #only 1 cpu
#temp1=(temps['coretemp-isa-0001']['Package id 1']['temp1_input'])
cpu_temp=(temp0+ temp1)/2
print("AVG CPU temp:" + str(cpu_temp))
return cpu_temp
def set_fan(pct_spd):
cmd_fan="ipmitool -H " + ipmi_host + " -U root -P "+ ipmi_pass + " -I lanplus raw 0x30 0x30 0x01 0x00; sleep 1; ipmitool -H "+ ipmi_host +" -U root -P "+ ipmi_pass +" -I lanplus raw 0x30 0x30 0x02 0xff "
if pct_spd < MIN_SPD:
pct_spd = MIN_SPD
if pct_spd > MAX_SPD:
pct_spd = MAX_SPD
x=subprocess.check_output(cmd_fan + hex(pct_spd), shell=True, stderr=subprocess.STDOUT)
def calculate():
global target_temp
last_time = datetime.datetime.now()
err_sum = 0
last_err_temp = -1
last_spd = 0
kp = 2
ki = 3
kd = 0.1
while True:
ts = str(datetime.datetime.now().strftime("%Y-%m-%d_%H:%M:%S"))
cpu_temp = get_temp()
now_time = datetime.datetime.now()
time_diff = (now_time - last_time ).microseconds / 1000000
err_temp = cpu_temp - target_temp
err_sum = err_sum+err_temp * time_diff
if last_err_temp == -1:
d_err = 0
else:
d_err = (err_temp - last_err_temp) / time_diff
set_spd = round(kp * err_temp + ki * err_sum + kd * d_err)
if set_spd<MIN_SPD:
set_spd=MIN_SPD
if set_spd>MAX_SPD:
set_spd=MAX_SPD
print(str(set_spd) + "% PID: ", err_temp, err_sum, d_err, " | ", kp *err_temp, ki * err_temp, kd * d_err)
last_err_temp = err_temp
last_time = now_time
if abs(set_spd - last_spd)<=1:
_print=(str(cpu_temp)+" keep "+ str(last_spd)+"%")
else:
set_fan(int(set_spd))
last_spd = set_spd
_print=(str(cpu_temp)+" set to "+ str(set_spd)+"%")
_print= ts + " " +_print
print(_print)
f=open("/root/last_fanspd.txt", "a")
f.write(_print + "\n")
f.close()
time.sleep(30)
calculate()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment