R710-Fan-Control/poweredge-fand.conf

116 lines
6.4 KiB
Perl
Executable file

#!/usr/bin/perl
$static_speed_low=0x02;
$static_speed_high=0x12; # this is the speed value at 100% demand
# ie what we consider the point we don't
# really want to get hotter but still
# tolerate
$ipmi_inlet_sensorname ="Inlet Temp";
$ipmi_exhaust_sensorname="Exhaust Temp";
$default_exhaust_threshold=50; # the ambient temperature we use above
# which we fail back to letting the drac
# control the fans
$base_temp = 24; # no fans when below this temp
$desired_temp1 = 34; # aim to keep the temperature below this
$desired_temp2 = 42; # really ramp up fans above this
$desired_temp3 = 50; # really ramp up fans above this
$demand1 = 5; # prescaled (not taking into effect static_speed_low/high) demand at temp1
$demand2 = 40; # prescaled (not taking into effect static_speed_low/high) demand at temp2
$demand3 = 200; # prescaled (not taking into effect static_speed_low/high) demand at temp3
$hysteresis = 2; # don't ramp up velocity unless demand
# difference is greater than this. Ramp
# down ASAP however, to bias quietness, and
# thus end up removing noise changes for
# just small changes in computing
# we can optionally just tell all fans to stick to the one speed:
# @daemons=(0xff);
@daemons=qw(0 1 2 3 4 5);
sub custom_temperature_calculation {
# FIXME: it would be good to share memory between the 6 daemons and
# not call ipmitool 6 times in parallel just to discard the value of
# 4 of them
my $gpu = $sensors_ref->{"amdgpu-pci-0400"}->{"edge"}->{"temp1_input"}; # 0.2*fan3 + 0.5*fan4 + 0.3*fan5
my $raid_card = raid_controller_temp(); # fan4+fan5;
my $left_cpu = $sensors_ref->{"coretemp-isa-0000"}->{"Package id 0"}->{"temp1_input"}; # fan2;
my $right_cpu = $sensors_ref->{"coretemp-isa-0001"}->{"Package id 1"}->{"temp1_input"}; # fan4;
# you might want to factor in NVME drives too, that might appear
# through sensors structure as eg:
# $sensors_ref->{"nvme-pci-0100"}->{"temp composite Samsung-EVO-970-1TB"}->{"temp1_input"}
# check with manual invocation of `sensors -j`. You might find
# "temp sensor 2 Samsung-EVO-970-1TB" is uncomfortably higher than
# "temp composite Samsung-EVO-970-1TB" but the composite (heatsink)
# is the bit you're cooling. So monitor that hotter sensor instead
# to add more fan demand
my $left_outside_drives =
average(hddtemp("/dev/disk/by-path/pci-0000:02:00.0-scsi-0:0:0:0"), # front top SSD
hddtemp("/dev/disk/by-path/pci-0000:02:00.0-scsi-0:0:1:0"), # front middle SSD
hddtemp("/dev/disk/by-path/pci-0000:02:00.0-scsi-0:0:2:0")); # front bottom HDD
my $left_middle_drives =
average(hddtemp("/dev/disk/by-path/pci-0000:02:00.0-scsi-0:0:3:0"), # front top SSD
hddtemp("/dev/disk/by-path/pci-0000:02:00.0-scsi-0:0:4:0"), # front middle HDD
hddtemp("/dev/disk/by-path/pci-0000:02:00.0-scsi-0:0:5:0")); # front bottom HDD
my $right_middle_drives =
average(hddtemp("/dev/disk/by-path/pci-0000:02:00.0-scsi-0:0:6:0"), # front top HDD
hddtemp("/dev/disk/by-path/pci-0000:02:00.0-scsi-0:0:7:0"), # front middle HDD
hddtemp("/dev/disk/by-path/pci-0000:02:00.0-scsi-0:0:8:0")); # front bottom HDD
my $right_outside_drives =
average(hddtemp("/dev/disk/by-path/pci-0000:02:00.0-scsi-0:0:9:0"), # front top HDD
hddtemp("/dev/disk/by-path/pci-0000:02:00.0-scsi-0:0:10:0"), # front middle HDD
hddtemp("/dev/disk/by-path/pci-0000:02:00.0-scsi-0:0:11:0")); # front bottom HDD
my $rear_drives =
average(hddtemp("/dev/disk/by-path/pci-0000:02:00.0-scsi-0:0:12:0"), # rear SSD (left or right? Dunno, just average over both
hddtemp("/dev/disk/by-path/pci-0000:02:00.0-scsi-0:0:13:0")); # of them, and contribute both to both fan 1 and fan 2)
if (print_stats_once()) {
print "gpu=$gpu, raid_card=$raid_card, cpus=$left_cpu, $right_cpu\n";
print "drives = $left_outside_drives, $left_middle_drives, $right_middle_drives, $right_outside_drives ; $rear_drives\n";
}
# Two thirds weighted CPU temps vs hdd temps, but if the HDD temps
# creep above this value, use them exclusively (more important to
# keep them cool than the CPUs):
# weighted_temp = max(
# average(average(@cputemps), average(@coretemps), average(@hddtemps)),
# average(@hddtemps));
# FIXME: probably want to take into account ambient temperature - if
# the difference between weighted_temp and ambient_temp is small
# because ambient_temp is large, then less need to run the fans
# because there's still low power demands, to a point, but
# eventually we have to keep all components under a threshold
# FIXME: hysteresis
# It is more important to keep hdds cool than CPUs. We should put
# different offsets or multipliers on them. As it is, we weight
# drives 3 times more important than CPU in the final weighting
# contribution from drives alone:
my $fan0_drive_weighted_temp = average($left_outside_drives, $rear_drives);
my $fan1_drive_weighted_temp = average($left_outside_drives, $left_middle_drives, $rear_drives);
my $fan2_drive_weighted_temp = $left_middle_drives;
my $fan3_drive_weighted_temp = $right_middle_drives;
my $fan4_drive_weighted_temp = average($right_middle_drives, $right_outside_drives);
my $fan5_drive_weighted_temp = $right_outside_drives;
my @fan_weighted_temp;
# contribution from drives, CPUs, raid controller, GPU:
$fan_weighted_temp[0] = $fan0_drive_weighted_temp;
$fan_weighted_temp[1] = $fan1_drive_weighted_temp;
$fan_weighted_temp[2] = weighted_average(3,$fan2_drive_weighted_temp, 2,$left_cpu);
$fan_weighted_temp[3] = weighted_average(3,$fan3_drive_weighted_temp, 1,$gpu);
$fan_weighted_temp[4] = weighted_average(3,$fan4_drive_weighted_temp, 1,$gpu, 1,$raid_card, 2,$right_cpu);
$fan_weighted_temp[5] = weighted_average(3,$fan5_drive_weighted_temp, 1,$gpu, 1,$raid_card);
# which fans are being controlled by this daemon? 0xff = all fans,
# 0x00 to 0x05 for individual fans from left to right viewing from the
# front
return $fan_weighted_temp[$fans];
}