I think there’s a bug in autmatic.py
My output>
sudo python3 automatic.py --threshold 60 --hysteresis 10 --delay 1 --preempt --verbose
Current: 38.46 Target: 60.00 Freq 1.50 MaxFreq 1.50 Automatic: True On: False
Current: 38.46 Target: 60.00 Freq 0.60 MaxFreq 1.50 Automatic: True On: True
Current: 38.95 Target: 60.00 Freq 0.60 MaxFreq 1.50 Automatic: True On: True
Current: 37.97 Target: 60.00 Freq 0.60 MaxFreq 1.50 Automatic: True On: True
Current: 38.95 Target: 60.00 Freq 0.60 MaxFreq 1.50 Automatic: True On: True
Current: 37.97 Target: 60.00 Freq 0.60 MaxFreq 1.50 Automatic: True On: True
Current: 39.43 Target: 60.00 Freq 0.60 MaxFreq 1.50 Automatic: True On: True
Current: 37.97 Target: 60.00 Freq 0.60 MaxFreq 1.50 Automatic: True On: True
Current: 38.46 Target: 60.00 Freq 0.60 MaxFreq 1.50 Automatic: True On: True
Current: 38.46 Target: 60.00 Freq 0.60 MaxFreq 1.50 Automatic: True On: True
Current: 38.46 Target: 60.00 Freq 0.60 MaxFreq 1.50 Automatic: True On: True
Current: 38.46 Target: 60.00 Freq 0.60 MaxFreq 1.50 Automatic: True On: True
From code
try:
update_led(fanshim.get_fan())
while True:
t = get_cpu_temp()
f = get_cpu_freq()
if args.verbose:
print("Current: {:05.02f} Target: {:05.02f} Freq {: 5.02f} MaxFreq {: 5.02f} Automatic: {} On: {}".format(t, args.threshold, f.current / 1000.0, f.max / 1000.0, armed, enabled))
if abs(last_change - t) > args.hysteresis and armed:
enable = (t >= args.threshold)
if args.preempt:
enable = enable or (int(f.current) == int(f.max))
if set_fan(enable):
last_change = t
time.sleep(args.delay)
(this is your code, with one extra parameter for max frequency)
if abs(last_change - t) > args.hysteresis and armed:
must be true because enabled is evaluated so I presume
last_change is presumably 0, t is around 38, 0-38 is -38. Abs(-38) = 38. 38>10
Then
enable = (t >= args.threshold)
t=38, 38 is less than theshold (60), so enable is false.
preempt is true, so we move to this test
enable = enable or (int(f.current) == int(f.max))
enable is initially false on first pass. However initially there’s a processor surge when initially launching the program, so current frequency initially maxes max frequency.
enabled is turned on.
The fan switches on
last_change is set to current temp, around 38.
if abs(last_change - t) > args.hysteresis and armed:
will be never be true as the last temp and temp are around 38 and the difference will never exceed my hysteresis (10) so enabled will never re-evalute, so enabled will remain on for ever.
There is also a possibility that with a large hysteresis and a short interval, that the current code would never have a large enough temperature change to trigger a reevaluation of enabled.
I’ve taken the liberty to have a go at rewriting.
If preempt and running full speed, fan on.
If over temperature, fan on.
If under (temperature - hysteresis), fan off