From 3407d145f9f67e4f191d97307d55988c0eac7e57 Mon Sep 17 00:00:00 2001 From: Tigerblue77 <37409593+tigerblue77@users.noreply.github.com> Date: Fri, 1 Mar 2024 21:54:39 +0100 Subject: [PATCH] Minor improvements and variables renaming --- Dell_iDRAC_fan_controller.sh | 76 ++++++++++++++++-------------------- Dockerfile | 5 +-- README.md | 44 ++++++++++----------- functions.sh | 14 ++++++- 4 files changed, 69 insertions(+), 70 deletions(-) diff --git a/Dell_iDRAC_fan_controller.sh b/Dell_iDRAC_fan_controller.sh index 2db5f49..2b94c2b 100755 --- a/Dell_iDRAC_fan_controller.sh +++ b/Dell_iDRAC_fan_controller.sh @@ -13,31 +13,26 @@ trap 'gracefull_exit' SIGQUIT SIGKILL SIGTERM # readonly DELL_FRESH_AIR_COMPLIANCE=45 -# Convert current fan value to hexadecimal -function convert_current_fan_value_to_hexadecimal_format () { - HEXADECIMAL_CURRENT_FAN_SPEED=$(printf '0x%02x' $CURRENT_FAN_SPEED) -} - -# Check if FAN_SPEED and HIGH_FAN_SPEED variable is in hexadecimal format. If not, convert it to hexadecimal +# Check if FAN_SPEED variable is in hexadecimal format. If not, convert it to hexadecimal if [[ $FAN_SPEED == 0x* ]] then DECIMAL_FAN_SPEED=$(printf '%d' $FAN_SPEED) HEXADECIMAL_FAN_SPEED=$FAN_SPEED else DECIMAL_FAN_SPEED=$FAN_SPEED - HEXADECIMAL_FAN_SPEED=$(printf '0x%02x' $FAN_SPEED) + HEXADECIMAL_FAN_SPEED=$(convert_decimal_value_to_hexadecimal $FAN_SPEED) fi -if $ENABLE_LINE_INTERPOLATION +# Check if HIGH_FAN_SPEED variable is in hexadecimal format. If not, convert it to hexadecimal +if [[ $HIGH_FAN_SPEED == 0x* ]] then - if [[ $HIGH_FAN_SPEED == 0x* ]] - then - DECIMAL_HIGH_FAN_SPEED=$(printf '%d' $HIGH_FAN_SPEED) - HEXADECIMAL_HIGH_FAN_SPEED=$HIGH_FAN_SPEED - else - DECIMAL_HIGH_FAN_SPEED=$HIGH_FAN_SPEED - HEXADECIMAL_HIGH_FAN_SPEED=$(printf '0x%02x' $HIGH_FAN_SPEED) - fi + readonly FAN_SPEED_INTERPOLATION_ENABLED=true + + DECIMAL_HIGH_FAN_SPEED=$(printf '%d' $HIGH_FAN_SPEED) + HEXADECIMAL_HIGH_FAN_SPEED=$HIGH_FAN_SPEED +else + DECIMAL_HIGH_FAN_SPEED=$HIGH_FAN_SPEED + HEXADECIMAL_HIGH_FAN_SPEED=$(convert_decimal_value_to_hexadecimal $HIGH_FAN_SPEED) fi # Check if the iDRAC host is set to 'local' or not then set the IDRAC_LOGIN_STRING accordingly @@ -68,21 +63,19 @@ echo "Server model: $SERVER_MANUFACTURER $SERVER_MODEL" echo "iDRAC/IPMI host: $IDRAC_HOST" # Log the fan speed objective, CPU temperature threshold and check interval -echo "Line interpolation enable: $ENABLE_LINE_INTERPOLATION" -if $ENABLE_LINE_INTERPOLATION +echo "Fan speed interpolation enabled: $FAN_SPEED_INTERPOLATION_ENABLED" +if $FAN_SPEED_INTERPOLATION_ENABLED then echo "Fan speed lower value: $DECIMAL_FAN_SPEED%" echo "Fan speed higher value: $DECIMAL_HIGH_FAN_SPEED%" - echo "CPU lower temperature threshold: $CPU_TEMPERATURE_FOR_START_LINE_INTERPOLATION°C" + echo "CPU lower temperature threshold: $CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION°C" echo "CPU higher temperature threshold: $CPU_TEMPERATURE_THRESHOLD°C" - echo "Check interval: ${CHECK_INTERVAL}s" - echo "" else echo "Fan speed objective: $DECIMAL_FAN_SPEED%" echo "CPU temperature threshold: $CPU_TEMPERATURE_THRESHOLD°C" - echo "Check interval: ${CHECK_INTERVAL}s" - echo "" fi +echo "Check interval: ${CHECK_INTERVAL}s" +echo "" # Define the interval for printing readonly TABLE_HEADER_PRINT_INTERVAL=10 @@ -156,46 +149,45 @@ while true; do COMMENT="CPU 2 temperature is too high, Dell default dynamic fan control profile applied for safety" fi else - if $ENABLE_LINE_INTERPOLATION + if $FAN_SPEED_INTERPOLATION_ENABLED then - CURRENT_FAN_SPEED=$DECIMAL_FAN_SPEED + DECIMAL_CURRENT_FAN_SPEED=$DECIMAL_FAN_SPEED - CPU_HIGHER_TEMP=$CPU1_TEMPERATURE + HIGHEST_CPU_TEMPERATURE=$CPU1_TEMPERATURE if $IS_CPU2_TEMPERATURE_SENSOR_PRESENT then if [ $CPU2_TEMPERATURE -gt $CPU1_TEMPERATURE ]; then - CPU_HIGHER_TEMP=$CPU2_TEMPERATURE + HIGHEST_CPU_TEMPERATURE=$CPU2_TEMPERATURE fi fi - if [ $CPU_HIGHER_TEMP -gt $CPU_TEMPERATURE_FOR_START_LINE_INTERPOLATION ]; + if [ $HIGHEST_CPU_TEMPERATURE -gt $CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION ]; then # # F1 - lower fan speed # F2 - higher fan speed - # T_CPU - higher temperature from both CPUs (if only one exist that will be CPU1 temp value) + # T_CPU - highest temperature of both CPUs (if only one exists that will be CPU1 temp value) # T1 - lower temperature threshold # T2 - higher temperature threshold # Fan speed = F1 + ( ( F2 - F1 ) * ( T_CPU - T1 ) / ( T2 - T1 ) ) # - # Difference between higher and lower temperature - TEMP_WINDOW="$((CPU_TEMPERATURE_THRESHOLD - CPU_TEMPERATURE_FOR_START_LINE_INTERPOLATION))" - # Temperature above lower value - TEMPERATURE_ABOVE_LOWER_THRESHOLD="$((CPU_HIGHER_TEMP - CPU_TEMPERATURE_FOR_START_LINE_INTERPOLATION))" - # Difference between higher and lower fan speed - FAN_WINDOW="$((DECIMAL_HIGH_FAN_SPEED - DECIMAL_FAN_SPEED))" + # Temperature interpolation activation range + TEMPERATURE_INTERPOLATION_ACTIVATION_RANGE="$((CPU_TEMPERATURE_THRESHOLD - CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION))" FAN_VALUE_TO_ADD=0 - # Check if TEMP_WINDOW is grater than 0 - if [ $TEMP_WINDOW -gt $FAN_VALUE_TO_ADD ]; + # Check if TEMPERATURE_INTERPOLATION_ACTIVATION_RANGE is > 0 + if [ $TEMPERATURE_INTERPOLATION_ACTIVATION_RANGE -gt $FAN_VALUE_TO_ADD ]; then - FAN_VALUE_TO_ADD="$((FAN_WINDOW * TEMPERATURE_ABOVE_LOWER_THRESHOLD / TEMP_WINDOW))" + # Temperature above lower value + TEMPERATURE_ABOVE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION="$((HIGHEST_CPU_TEMPERATURE - CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION))" + # Difference between higher and lower fan speed + FAN_WINDOW="$((DECIMAL_HIGH_FAN_SPEED - DECIMAL_FAN_SPEED))" + FAN_VALUE_TO_ADD="$((FAN_WINDOW * TEMPERATURE_ABOVE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION / TEMPERATURE_INTERPOLATION_ACTIVATION_RANGE))" fi - CURRENT_FAN_SPEED="$((DECIMAL_FAN_SPEED + FAN_VALUE_TO_ADD))" + DECIMAL_CURRENT_FAN_SPEED="$((DECIMAL_FAN_SPEED + FAN_VALUE_TO_ADD))" fi - # Convert decimal to hexadecimal value of fan speed - convert_current_fan_value_to_hexadecimal_format - apply_line_interpolation_fan_control_profile + $HEXADECIMAL_CURRENT_FAN_SPEED=$(convert_decimal_value_to_hexadecimal $DECIMAL_CURRENT_FAN_SPEED) + apply_fan_speed_interpolation_fan_control_profile else apply_user_fan_control_profile diff --git a/Dockerfile b/Dockerfile index b87e099..12591f5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,8 +26,7 @@ ENV CPU_TEMPERATURE_THRESHOLD 50 ENV CHECK_INTERVAL 60 ENV DISABLE_THIRD_PARTY_PCIE_CARD_DELL_DEFAULT_COOLING_RESPONSE false -ENV CPU_TEMPERATURE_FOR_START_LINE_INTERPOLATION 40 -ENV ENABLE_LINE_INTERPOLATION false -ENV HIGH_FAN_SPEED 45 +ENV CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION 40 +ENV HIGH_FAN_SPEED 40 CMD ["./Dell_iDRAC_fan_controller.sh"] diff --git a/README.md b/README.md index fc9a5df..e65ed5d 100644 --- a/README.md +++ b/README.md @@ -81,8 +81,7 @@ docker run -d \ -e CPU_TEMPERATURE_THRESHOLD= \ -e CHECK_INTERVAL= \ -e DISABLE_THIRD_PARTY_PCIE_CARD_DELL_DEFAULT_COOLING_RESPONSE= \ - -e ENABLE_LINE_INTERPOLATION= \ - -e CPU_TEMPERATURE_FOR_START_LINE_INTERPOLATION= \ + -e CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION= \ -e HIGH_FAN_SPEED= \ --device=/dev/ipmi0:/dev/ipmi0:rw \ tigerblue77/dell_idrac_fan_controller:latest @@ -101,8 +100,7 @@ docker run -d \ -e CPU_TEMPERATURE_THRESHOLD= \ -e CHECK_INTERVAL= \ -e DISABLE_THIRD_PARTY_PCIE_CARD_DELL_DEFAULT_COOLING_RESPONSE= \ - -e ENABLE_LINE_INTERPOLATION= \ - -e CPU_TEMPERATURE_FOR_START_LINE_INTERPOLATION= \ + -e CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION= \ -e HIGH_FAN_SPEED= \ tigerblue77/dell_idrac_fan_controller:latest ``` @@ -124,8 +122,7 @@ services: - CPU_TEMPERATURE_THRESHOLD= - CHECK_INTERVAL= - DISABLE_THIRD_PARTY_PCIE_CARD_DELL_DEFAULT_COOLING_RESPONSE= - - ENABLE_LINE_INTERPOLATION= - - CPU_TEMPERATURE_FOR_START_LINE_INTERPOLATION= + - CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION= - HIGH_FAN_SPEED= devices: - /dev/ipmi0:/dev/ipmi0:rw @@ -149,8 +146,7 @@ services: - CPU_TEMPERATURE_THRESHOLD= - CHECK_INTERVAL= - DISABLE_THIRD_PARTY_PCIE_CARD_DELL_DEFAULT_COOLING_RESPONSE= - - ENABLE_LINE_INTERPOLATION= - - CPU_TEMPERATURE_FOR_START_LINE_INTERPOLATION= + - CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION= - HIGH_FAN_SPEED= ``` @@ -168,26 +164,28 @@ All parameters are optional as they have default values (including default iDRAC - `CPU_TEMPERATURE_THRESHOLD` parameter is the T°junction (junction temperature) threshold beyond which the Dell fan mode defined in your BIOS will become active again (to protect the server hardware against overheat). **Default** value is 50(°C). - `CHECK_INTERVAL` parameter is the time (in seconds) between each temperature check and potential profile change. **Default** value is 60(s). - `DISABLE_THIRD_PARTY_PCIE_CARD_DELL_DEFAULT_COOLING_RESPONSE` parameter is a boolean that allows to disable third-party PCIe card Dell default cooling response. **Default** value is false. -- `ENABLE_LINE_INTERPOLATION` parameter is a boolean that allows to enable line interpolation. If temperature value going above **CPU_TEMPERATURE_FOR_START_LINE_INTERPOLATION** they will proportionally increase fan speed to **HIGH_FAN_SPEED** when **CPU_TEMPERATURE_THRESHOLD** will reached. **Default** value is false. -- `CPU_TEMPERATURE_FOR_START_LINE_INTERPOLATION` parameter is only necessary if you're using line interpolation. Must be lower than **CPU_TEMPERATURE_THRESHOLD**. **Default** value is 40(°C). -- `HIGH_FAN_SPEED` parameter is only necessary if you're using line interpolation. It defines maximum fan speed before swiching to dell temperature control. **Default** value is 45(%). -Example of how interpolation work: +If you want to enable fan speed interpolation, add the following parameters : +- `CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION` parameter enables fan speed interpolation once exceeded. Fan speed interpolation will increase your fan speed proportionally to **HIGH_FAN_SPEED** until **CPU_TEMPERATURE_THRESHOLD** is reached. This parameter must be lower than **CPU_TEMPERATURE_THRESHOLD**. **Default** value is 40(°C). +- `HIGH_FAN_SPEED` parameter is the fan speed that will be set at `CPU_TEMPERATURE_THRESHOLD`. In other words, it defines maximum fan speed before swiching to the Dell fan mode (see `CPU_TEMPERATURE_THRESHOLD` parameter). **Default** value is 40(%). + +Example of how interpolation works: - `FAN_SPEED` = 10 - `HIGH_FAN_SPEED` = 50 -- `CPU_TEMPERATURE_FOR_START_LINE_INTERPOLATION` = 30 +- `CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION` = 30 - `CPU_TEMPERATURE_THRESHOLD` = 70 -| CPU Temperature | Fan Speed | -| ------------- | ------------- | -| 15 °C | 10 % | -| 30 °C | 10 % | -| 35 °C | 15 % | -| 50 °C | 30 % | -| 69 °C | 49 % | -| 70 °C | Dell fan control | +| CPU temperature | Fan speed | +| --------------- | ---------------- | +| 15 °C | 10 % | +| 30 °C | 10 % | +| 35 °C | 15 % | +| 50 °C | 30 % | +| 69 °C | 49 % | +| 70 °C | Dell fan control | +| 80 °C | Dell fan control | -When using line interpolation it's recommended to lower **CHECK_INTERVAL** to value such as 3 seconds. +When using fan speed interpolation, we recommend decreasing **CHECK_INTERVAL**, for example "3" (seconds), to avoid the noise nuisance associated with a sudden increase in fan speed.

(back to top)

@@ -196,7 +194,7 @@ When using line interpolation it's recommended to lower **CHECK_INTERVAL** to va If your server frequently switches back to the default Dell fan mode: 1. Check `Tcase` (case temperature) of your CPU on Intel Ark website and then set `CPU_TEMPERATURE_THRESHOLD` to a slightly lower value. Example with my CPUs ([Intel Xeon E5-2630L v2](https://www.intel.com/content/www/us/en/products/sku/75791/intel-xeon-processor-e52630l-v2-15m-cache-2-40-ghz/specifications.html)) : Tcase = 63°C, I set `CPU_TEMPERATURE_THRESHOLD` to 60(°C). -2. If it's already good, adapt your `FAN_SPEED` value to increase the airflow and thus further decrease the temperature of your CPU(s) or enable and experiment with line interpolation +2. If it's already good, adapt your `FAN_SPEED` value to increase the airflow and thus further decrease the temperature of your CPU(s) or enable and experiment with fan speed interpolation 3. If neither increasing the fan speed nor increasing the threshold solves your problem, then it may be time to replace your thermal paste

(back to top)

diff --git a/functions.sh b/functions.sh index 81c1a4e..04ccbf1 100644 --- a/functions.sh +++ b/functions.sh @@ -14,10 +14,20 @@ function apply_user_fan_control_profile () { CURRENT_FAN_CONTROL_PROFILE="User static fan control profile ($DECIMAL_FAN_SPEED%)" } -function apply_line_interpolation_fan_control_profile () { +# This function applies a user-specified interpolated fan control profile +function apply_fan_speed_interpolation_fan_control_profile () { ipmitool -I $IDRAC_LOGIN_STRING raw 0x30 0x30 0x01 0x00 > /dev/null ipmitool -I $IDRAC_LOGIN_STRING raw 0x30 0x30 0x02 0xff $HEXADECIMAL_CURRENT_FAN_SPEED > /dev/null - CURRENT_FAN_CONTROL_PROFILE="Interpolated fan control profile ($CURRENT_FAN_SPEED%)" + CURRENT_FAN_CONTROL_PROFILE="Interpolated fan control profile ($DECIMAL_CURRENT_FAN_SPEED%)" +} + +# Convert DECIMAL_NUMBER to hexadecimal +# Usage : convert_decimal_value_to_hexadecimal $DECIMAL_NUMBER +# Returns : hexadecimal value of DECIMAL_NUMBER +function convert_decimal_value_to_hexadecimal () { + local DECIMAL_NUMBER=$1 + local HEXADECIMAL_NUMBER=$(printf '0x%02x' $DECIMAL_NUMBER) + return $HEXADECIMAL_NUMBER } # Retrieve temperature sensors data using ipmitool