64 lines
1.9 KiB
Nix
64 lines
1.9 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
{
|
|
systemd.timers."fancontrol" = {
|
|
wantedBy = [ "timers.target" ];
|
|
timerConfig = {
|
|
OnCalendar="*:0/3";
|
|
Unit = "fancontrol.service";
|
|
};
|
|
};
|
|
|
|
systemd.services."fancontrol" = {
|
|
environment = {
|
|
TEMP_MIN_FALLING = "50";
|
|
TEMP_MAX_RISING = "56";
|
|
TEMP_CRIT = "70";
|
|
|
|
LOW_FAN_SPEED = "0x10";
|
|
};
|
|
|
|
script = ''
|
|
SET_FAN_MANUAL="0x30 0x30 0x01 0x00" # Enable manual control
|
|
SET_FAN_AUTO="0x30 0x30 0x01 0x01" # Disable manual control
|
|
|
|
SET_FAN_LOW="0x30 0x30 0x02 0xff $LOW_FAN_SPEED"
|
|
SET_FAN_MAX="0x30 0x30 0x02 0xff 0x64" # force 100%
|
|
|
|
|
|
# Get all temperatures readings starting with "Temp ", find all two digit numbers followed by spaces, find the largest one, trim the trailing space
|
|
maxcoretemp=$(${pkgs.ipmitool}/bin/ipmitool sdr type temperature | grep '^Temp ' | grep -Po '\d{2} ' | sort -nr | head -n1 | xargs)
|
|
|
|
# Verify that we read a valid number
|
|
ISNUMBER='^[0-9]+$'
|
|
if ! [[ $maxcoretemp =~ $ISNUMBER ]] ; then
|
|
echo "Error: could not read temperature" >&2
|
|
exit 2
|
|
fi
|
|
|
|
echo "Highest measured CPU temperature: '$maxcoretemp'"
|
|
|
|
if [ "$maxcoretemp" -gt "$TEMP_CRIT" ]; then
|
|
echo "TOO HOT, CRITICAL CPU TEMP"
|
|
${pkgs.ipmitool}/bin/ipmitool raw $SET_FAN_MANUAL
|
|
${pkgs.ipmitool}/bin/ipmitool raw $SET_FAN_MAX
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$maxcoretemp" -gt "$TEMP_MAX_RISING" ]; then
|
|
echo "TOO HOT, switching to IDRAC fan controL"
|
|
${pkgs.ipmitool}/bin/ipmitool raw $SET_FAN_AUTO
|
|
exit 0
|
|
fi
|
|
|
|
if [ "$maxcoretemp" -lt "$TEMP_MIN_FALLING" ]; then
|
|
echo "Sufficiently cooled, stepping down fans"
|
|
${pkgs.ipmitool}/bin/ipmitool raw $SET_FAN_MANUAL
|
|
${pkgs.ipmitool}/bin/ipmitool raw $SET_FAN_LOW
|
|
exit 0
|
|
fi
|
|
|
|
echo "Temperature is between limits, doing nothing..."
|
|
'';
|
|
};
|
|
}
|