Repository navigation
Expand file tree
/
Copy pathfanctrl
More file actions
136 lines (109 loc) · 3.08 KB
/
Copy pathfanctrl
File metadata and controls
136 lines (109 loc) · 3.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/bin/sh
set -e
# $1: temperature in tenths of a degree (e.g. 282 = 28.2°C)
# returns rounded interpolated int
lerp_fan_speed()
{
temp=$1
low_temp=
high_temp=
low_speed=
high_speed=
while IFS='=' read -r t speed # get proper range
do
[ -n "$t" ] || continue
# Curve temperatures are specified in whole degrees.
t=$((t * 10))
if [ "$t" -le "$temp" ] &&
{ [ -z "$low_temp" ] || [ "$t" -gt "$low_temp" ]; }; then
low_temp=$t
low_speed=$speed
fi
if [ "$t" -ge "$temp" ] &&
{ [ -z "$high_temp" ] || [ "$t" -lt "$high_temp" ]; }; then
high_temp=$t
high_speed=$speed
fi
done <<EOF
$FAN_CURVE
EOF
if [ -z "$low_temp" ]; then # Below the lowest curve point.
echo "$high_speed"
elif [ -z "$high_temp" ] || [ "$high_temp" -eq "$low_temp" ]; then # At or above the highest curve point, or exact curve point.
echo "$low_speed"
else # Linear interpolation rounded to the nearest integer.
numerator=$(( (high_speed - low_speed) * (temp - low_temp) ))
denominator=$(( high_temp - low_temp ))
speed=$(( (numerator + denominator / 2) / denominator ))
echo $((low_speed + speed))
fi
}
evl()
{
# echo "evl: [$*]" >&2
exec "$AWK" "BEGIN { print $* }"
}
SET_FAN_SPEED_CMD="$SCRIPT_DIR/commands/set-fan-speed"
if [ ! -x "$SET_FAN_SPEED_CMD" ]; then
echo "Error: $SET_FAN_SPEED_CMD is not present. Try creating it or use existing one with use.sh"
exit 1
fi
for f in "$SCRIPT_DIR"/includes/* "$SCRIPT_DIR"/includes/.*; do
# shellcheck source=/dev/null
[ -f "$f" ] && . "$f"
done
cd "$SCRIPT_DIR"
prev_speed=0
for fan in "$SCRIPT_DIR"/fans/*
do
fan_name=${fan##*/}
if [ "$fan_name" != "${fan_name#_}" ] || [ ! -f "$fan" ]; then # skip disabled fans (_ prefix) and anything that isn't an actual fan config file
continue
fi
# shellcheck source=/dev/null
. "$fan"
# echo "$SENSOR_CMD" "$FAN_CURVE"
if [ -z "$SENSOR_CMD" ]; then
echo "Error: SENSOR_CMD is not specified for fan '$fan_name', skipping..."
continue
fi
if [ -z "$FAN_CURVE" ]; then
echo "Error: FAN_CURVE is not specified for fan '$fan_name', skipping..."
continue
fi
temp=$(eval "$SENSOR_CMD")
if [ -z "$temp" ]; then
continue
fi
# Convert sensor temperature to tenths of a degree.
int_part=${temp%%.*}
frac_part=${temp#*.}
if [ "$frac_part" = "$temp" ]; then
frac_part=0
else
frac_part=${frac_part%?}
fi
int_temp=$((int_part * 10 + frac_part))
speed=$(lerp_fan_speed "$int_temp")
if [ -n "$NEIGHBOR_FAN_OFFSET" ] && [ "$prev_speed" -eq "$speed" ]; then
speed="$((speed + NEIGHBOR_FAN_OFFSET))"
fi
cache_file="$CACHE_DIR/$fan_name"
if [ -f "$cache_file" ]; then
read -r cached_speed < "$cache_file"
if [ "$cached_speed" -eq "$speed" ]; then
prev_speed=$speed
continue
fi
fi
# clamp for safety, in case the curve is misconfigured
if [ "$speed" -lt "${DEFAULT_MIN_SPEED:-5}" ]; then
speed=${DEFAULT_MIN_SPEED:-5}
elif [ "$speed" -gt "${DEFAULT_MAX_SPEED:-100}" ]; then
speed=${DEFAULT_MAX_SPEED:-100}
fi
# echo "Set fan '$fan_name' to $speed% ($SENSOR_CMD: $temp)"
"$SET_FAN_SPEED_CMD" "$fan_name" "$speed"
echo "$speed" > "$cache_file"
prev_speed=$speed
done