Quad SATA HAT Fan Control

Hi Akgnah

In misc.py, I think the function fan_temp2dc should be

def fan_temp2dc(t):
for lv, dc in lv2dc.items():
if t >= conf[‘fan’][lv]:
return dc
return 0

This way the fans are off until lv0 is reached then they start up and step up though lv1, lv2, lv3 etc. I also (for a pi4) default them in /etc/rockpi-sata.conf to 55, 60, 65, & 70 (as my pi4 seems to idle at around 50c) so all is quiet until some stress is applied

Hello awauk,

Thank you for reviewing the code.

Interestingly, this is exactly what I wrote before, and you can see it in this commit (fix temp2dc ).

This is a rookie error and the return dc just breaks the loop and will not return from the function.

1 Like

Hi

I think this demonstrates the problem, I want the fan to start only when the lv0 temp is reached.
Breaking out of the loop and doing “return dc” will always return the last value dc held (i.e. 25)
(in my opinion dc should be out of scope at this point and throw an error but that is python!!)
'return’ing a value from within a loop within a function is fine? (though it obviously ends the loop)

Anyway this demonstrates that the existing function will always return 25 and therefore that the fan will
always be running - perhaps that is by design? but in my case I am happy with it remaining off until
lv0 (55c for me) is reached)

Just to add - my kit built and worked perfectly without any problems, it has a mix of SSD and
HDD drives and idles at about 52c (with the fan off)

My wish for a v2 board would be to have it powered on at start (without needing GPIO) so that the Pi
could USB boot but that is not a big issue as I might have kept all software on the SD card anyway
for easy recovery.

/A

from collections import defaultdict, OrderedDict

conf = defaultdict(dict)

lv2dc = OrderedDict({‘lv3’: 100, ‘lv2’: 75, ‘lv1’: 50, ‘lv0’: 25})

conf[‘fan’][‘lv0’] = 55;
conf[‘fan’][‘lv1’] = 60;
conf[‘fan’][‘lv2’] = 65;
conf[‘fan’][‘lv3’] = 70;

def fan_temp2dc(t):
for lv, dc in lv2dc.items():
if t >= conf[‘fan’][lv]:
break
return dc

def new_fan_temp2dc(t):
for lv, dc in lv2dc.items():
if t >= conf[‘fan’][lv]:
return dc
return 0

def test(t):
print(“temp {:03}c - {:03}% vs {:03}%”.format(t, fan_temp2dc(t), new_fan_temp2dc(t)));

fan off

test(1);
test(50);
test(51);
test(52);
test(53);
test(54);

fan on at 25%

test(55);

fan on at 50%

test(60);

fan on at 75%

test(65);

fan on at 100%

test(70);
test(100);

You’re right. The “return” will return the value correctly. I don’t remember the real reason why I changed it, so I’ll think back.