Hold fan speed unless the change is worth making
The setpoint was a continuous function of instantaneous temperature and was pushed to the BMC every pass, so ~1% of fan per degree of CPU noise meant the fans never settled. Measured on iz-pve0: stock iDRAC held one speed for 5 minutes through 57-59c jitter while this script made 7 changes in 16 minutes off the same signal. Adds a 5% deadband around the applied speed, with full-speed requests never held back and a periodic re-assert in case the BMC forgets. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
29
fan_speed.sh
29
fan_speed.sh
@@ -82,6 +82,17 @@ selftest() {
|
||||
echo "0,50,0,38,20" >> "$TREND_FILE"
|
||||
check "partial window stays silent" 0 "$(rise_over_window 4)"
|
||||
|
||||
echo "fan speed deadband (hold unless the change is worth making):"
|
||||
local now; now=$(date +%s)
|
||||
HIGH_FAN_SPEED=50
|
||||
should_apply_fan_speed 21 20 "$now" && check "1% drift holds" hold apply || check "1% drift holds" hold hold
|
||||
should_apply_fan_speed 23 20 "$now" && check "3% drift holds" hold apply || check "3% drift holds" hold hold
|
||||
should_apply_fan_speed 25 20 "$now" && check "5% rise applies" apply apply || check "5% rise applies" apply hold
|
||||
should_apply_fan_speed 15 20 "$now" && check "5% fall applies" apply apply || check "5% fall applies" apply hold
|
||||
should_apply_fan_speed 50 20 "$now" && check "full speed always applies" apply apply || check "full speed always applies" apply hold
|
||||
should_apply_fan_speed 21 "" "$now" && check "first pass always applies" apply apply || check "first pass always applies" apply hold
|
||||
should_apply_fan_speed 21 20 $((now - 400)) && check "stale setpoint is reasserted" apply apply || check "stale setpoint is reasserted" apply hold
|
||||
|
||||
echo "alert rate limiting:"
|
||||
local out
|
||||
out=$( { raise_alert testkey "first" "body"; raise_alert testkey "second" "body"; } | grep -c '^MAIL\[' )
|
||||
@@ -180,6 +191,8 @@ fi
|
||||
cache_disk_limits
|
||||
echo "Monitoring $DISK_COUNT_EXPECTED disk(s)."
|
||||
LAST_SMART_CHECK=0
|
||||
APPLIED_FAN_SPEED=""
|
||||
APPLIED_FAN_SPEED_AT=0
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
@@ -232,11 +245,21 @@ one_pass() {
|
||||
FAN_SPEED_DRIVER="disk"
|
||||
fi
|
||||
|
||||
apply_user_fan_control "$DECIMAL_CURRENT_FAN_SPEED"
|
||||
# Hold the current speed unless the change is worth making - see the deadband
|
||||
# note in monitor.sh. Chasing every degree is what made this louder than stock.
|
||||
local held=""
|
||||
if should_apply_fan_speed "$DECIMAL_CURRENT_FAN_SPEED" "$APPLIED_FAN_SPEED" "$APPLIED_FAN_SPEED_AT"; then
|
||||
apply_user_fan_control "$DECIMAL_CURRENT_FAN_SPEED"
|
||||
APPLIED_FAN_SPEED=$DECIMAL_CURRENT_FAN_SPEED
|
||||
APPLIED_FAN_SPEED_AT=$(date +%s)
|
||||
else
|
||||
held=" held, want $DECIMAL_CURRENT_FAN_SPEED"
|
||||
fi
|
||||
|
||||
COMMENT="CPU1:$CPU1_TEMPERATURE | CPU2:$CPU2_TEMPERATURE | GPU:$GPU_TEMPERATURE | Inlet:$INLET_TEMPERATURE | Exhaust:$EXHAUST_TEMPERATURE | Disk:$HOTTEST_DISK_TEMPERATURE/$HOTTEST_DISK_LIMIT($(basename $HOTTEST_DISK_DEVICE)) | Fan Speed:$DECIMAL_CURRENT_FAN_SPEED($FAN_SPEED_DRIVER)"
|
||||
COMMENT="CPU1:$CPU1_TEMPERATURE | CPU2:$CPU2_TEMPERATURE | GPU:$GPU_TEMPERATURE | Inlet:$INLET_TEMPERATURE | Exhaust:$EXHAUST_TEMPERATURE | Disk:$HOTTEST_DISK_TEMPERATURE/$HOTTEST_DISK_LIMIT($(basename $HOTTEST_DISK_DEVICE)) | Fan Speed:$APPLIED_FAN_SPEED($FAN_SPEED_DRIVER$held)"
|
||||
|
||||
record_sample "$HIGHEST_CPU_TEMPERATURE" "$GPU_TEMPERATURE" "$HOTTEST_DISK_TEMPERATURE" "$DECIMAL_CURRENT_FAN_SPEED"
|
||||
# Record what the fans are actually doing, not what was merely requested.
|
||||
record_sample "$HIGHEST_CPU_TEMPERATURE" "$GPU_TEMPERATURE" "$HOTTEST_DISK_TEMPERATURE" "$APPLIED_FAN_SPEED"
|
||||
check_alarms
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user