Skip to content

Commit

Permalink
Minor improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
tigerblue77 committed Dec 29, 2024
1 parent 3894c16 commit 8e684c4
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 49 deletions.
18 changes: 9 additions & 9 deletions Dell_iDRAC_fan_controller.sh
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ if [[ $HIGH_FAN_SPEED == 0x* ]]; then
else
readonly DECIMAL_HIGH_FAN_SPEED=$HIGH_FAN_SPEED
# Unused
# readonly HEXADECIMAL_HIGH_FAN_SPEED=$(convert_decimal_value_to_hexadecimal $HIGH_FAN_SPEED)
# readonly 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
Expand All @@ -69,13 +69,13 @@ fi

# If server model is Gen 14 (*40) or newer
if [[ $SERVER_MODEL =~ .*[RT][[:space:]]?[0-9][4-9]0.* ]]; then
DELL_POWEREDGE_GEN_14_OR_NEWER=true
CPU1_TEMPERATURE_INDEX=2
CPU2_TEMPERATURE_INDEX=4
readonly DELL_POWEREDGE_GEN_14_OR_NEWER=true
readonly CPU1_TEMPERATURE_INDEX=2
readonly CPU2_TEMPERATURE_INDEX=4
else
DELL_POWEREDGE_GEN_14_OR_NEWER=false
CPU1_TEMPERATURE_INDEX=1
CPU2_TEMPERATURE_INDEX=2
readonly DELL_POWEREDGE_GEN_14_OR_NEWER=false
readonly CPU1_TEMPERATURE_INDEX=1
readonly CPU2_TEMPERATURE_INDEX=2
fi

# Log main informations
Expand Down Expand Up @@ -108,7 +108,7 @@ IS_DELL_FAN_CONTROL_PROFILE_APPLIED=true
# Check present sensors
IS_EXHAUST_TEMPERATURE_SENSOR_PRESENT=true
IS_CPU2_TEMPERATURE_SENSOR_PRESENT=true
retrieve_temperatures $IS_EXHAUST_TEMPERATURE_SENSOR_PRESENT $IS_CPU2_TEMPERATURE_SENSOR_PRESENT
retrieve_temperatures "$IS_EXHAUST_TEMPERATURE_SENSOR_PRESENT" "$IS_CPU2_TEMPERATURE_SENSOR_PRESENT"
if [ -z "$EXHAUST_TEMPERATURE" ]; then
echo "No exhaust temperature sensor detected."
IS_EXHAUST_TEMPERATURE_SENSOR_PRESENT=false
Expand All @@ -128,7 +128,7 @@ while true; do
sleep $CHECK_INTERVAL &
SLEEP_PROCESS_PID=$!

retrieve_temperatures $IS_EXHAUST_TEMPERATURE_SENSOR_PRESENT $IS_CPU2_TEMPERATURE_SENSOR_PRESENT
retrieve_temperatures "$IS_EXHAUST_TEMPERATURE_SENSOR_PRESENT" "$IS_CPU2_TEMPERATURE_SENSOR_PRESENT"

# Initialize a variable to store the comments displayed when the fan control profile changed
COMMENT=" -"
Expand Down
7 changes: 3 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,11 @@ ENV IDRAC_HOST local
# ENV IDRAC_USERNAME root
# ENV IDRAC_PASSWORD calvin
ENV FAN_SPEED 5
ENV CPU_TEMPERATURE_THRESHOLD 50
ENV HIGH_FAN_SPEED 40
ENV CPU_TEMPERATURE_THRESHOLD 60
ENV CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION 50
ENV CHECK_INTERVAL 60
ENV DISABLE_THIRD_PARTY_PCIE_CARD_DELL_DEFAULT_COOLING_RESPONSE false
ENV KEEP_THIRD_PARTY_PCIE_CARD_COOLING_RESPONSE_STATE_ON_EXIT false

ENV CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION 40
ENV HIGH_FAN_SPEED 40

ENTRYPOINT ["./Dell_iDRAC_fan_controller.sh"]
44 changes: 23 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ docker run -d \
-e CPU_TEMPERATURE_THRESHOLD=<decimal temperature threshold> \
-e CHECK_INTERVAL=<seconds between each check> \
-e DISABLE_THIRD_PARTY_PCIE_CARD_DELL_DEFAULT_COOLING_RESPONSE=<true or false> \
-e CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION=<decimal temperature lower threshold, olny when interpolation enabled> \
-e HIGH_FAN_SPEED=<decimal or hexadecimal fan speed, only when interpolation enabled> \
-e CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION=<decimal temperature lower threshold> \
-e HIGH_FAN_SPEED=<decimal or hexadecimal fan speed> \
-e KEEP_THIRD_PARTY_PCIE_CARD_COOLING_RESPONSE_STATE_ON_EXIT=<true or false> \
--device=/dev/ipmi0:/dev/ipmi0:rw \
tigerblue77/dell_idrac_fan_controller:latest
Expand All @@ -104,8 +104,8 @@ docker run -d \
-e CPU_TEMPERATURE_THRESHOLD=<decimal temperature threshold> \
-e CHECK_INTERVAL=<seconds between each check> \
-e DISABLE_THIRD_PARTY_PCIE_CARD_DELL_DEFAULT_COOLING_RESPONSE=<true or false> \
-e CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION=<decimal temperature lower threshold, only when interpolation enabled> \
-e HIGH_FAN_SPEED=<decimal or hexadecimal fan speed, only when interpolation enabled> \
-e CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION=<decimal temperature lower threshold> \
-e HIGH_FAN_SPEED=<decimal or hexadecimal fan speed> \
-e KEEP_THIRD_PARTY_PCIE_CARD_COOLING_RESPONSE_STATE_ON_EXIT=<true or false> \
tigerblue77/dell_idrac_fan_controller:latest
```
Expand All @@ -128,8 +128,8 @@ services:
- CPU_TEMPERATURE_THRESHOLD=<decimal temperature threshold>
- CHECK_INTERVAL=<seconds between each check>
- DISABLE_THIRD_PARTY_PCIE_CARD_DELL_DEFAULT_COOLING_RESPONSE=<true or false>
- CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION=<decimal temperature lower threshold, only when interpolation enabled>
- HIGH_FAN_SPEED=<decimal or hexadecimal fan speed when interpolation enabled>
- CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION=<decimal temperature lower threshold>
- HIGH_FAN_SPEED=<decimal or hexadecimal fan speed>
- KEEP_THIRD_PARTY_PCIE_CARD_COOLING_RESPONSE_STATE_ON_EXIT=<true or false>
devices:
- /dev/ipmi0:/dev/ipmi0:rw
Expand All @@ -153,7 +153,7 @@ services:
- CPU_TEMPERATURE_THRESHOLD=<decimal temperature threshold>
- CHECK_INTERVAL=<seconds between each check>
- DISABLE_THIRD_PARTY_PCIE_CARD_DELL_DEFAULT_COOLING_RESPONSE=<true or false>
- CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION=<decimal temperature lower threshold, only when interpolation enabled>
- CPU_TEMPERATURE_THRESHOLD_FOR_FAN_SPEED_INTERPOLATION=<decimal temperature lower threshold>
- HIGH_FAN_SPEED=<decimal or hexadecimal fan speed when interpolation enabled>
- KEEP_THIRD_PARTY_PCIE_CARD_COOLING_RESPONSE_STATE_ON_EXIT=<true or false>
```
Expand All @@ -169,29 +169,29 @@ All parameters are optional as they have default values (including default iDRAC
- `IDRAC_USERNAME` parameter is only necessary if you're adressing a distant iDRAC. **Default** value is "root".
- `IDRAC_PASSWORD` parameter is only necessary if you're adressing a distant iDRAC. **Default** value is "calvin".
- `FAN_SPEED` parameter can be set as a decimal (from 0 to 100%) or hexadecimaladecimal value (from 0x00 to 0x64) you want to set the fans to. **Default** value is 5(%).
- `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).
- `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 60(°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.

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(%).
- `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 less or equal to **CPU_TEMPERATURE_THRESHOLD**. **Default** value is 50(°C).
- `HIGH_FAN_SPEED` parameter is the fan speed that will be set at `CPU_TEMPERATURE_THRESHOLD` when interpolation mode is enabled. In other words, it defines maximum fan speed before swiching back to the Dell default dynamic fan control profile (see `CPU_TEMPERATURE_THRESHOLD` parameter). **Default** value is 40(%).

Example of how interpolation works:
- `FAN_SPEED` = 10
- `HIGH_FAN_SPEED` = 50
- `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 |
| 80 °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 default dynamic fan control profile |
| 80 °C | Dell default dynamic fan control profile |

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.
- `KEEP_THIRD_PARTY_PCIE_CARD_COOLING_RESPONSE_STATE_ON_EXIT` parameter is a boolean that allows to keep the third-party PCIe card Dell default cooling response state upon exit. **Default** value is false, so that it resets the third-party PCIe card Dell default cooling response to Dell default.
Expand All @@ -201,9 +201,11 @@ When using fan speed interpolation, we recommend decreasing **CHECK_INTERVAL**,
<!-- TROUBLESHOOTING -->
## Troubleshooting

If your server frequently switches back to the default Dell fan mode:
If your server frequently switches back to the default Dell default dynamic fan control profile:
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 fan speed interpolation
2. If it's already good, either :
- adapt your `FAN_SPEED` value to increase the airflow and thus further decrease the temperature of your CPU(s)
- enable and experiment fan speed interpolation mode
3. If neither increasing the fan speed nor increasing the threshold solves your problem, then it may be time to replace your thermal paste

<p align="right">(<a href="#top">back to top</a>)</p>
Expand Down
30 changes: 15 additions & 15 deletions functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ function apply_Dell_fan_control_profile() {
# The function then applies the fan control and updates the current fan control profile.
#
# Parameters:
# $1 (MODE): The fan control mode.
# 1 for static fan speed, 2 for dynamic (interpolated) fan control.
# $1 (FAN_CONTROL_PROFILE): The fan control mode.
# 1 for static fan speed, 2 for dynamic (interpolated) fan control.
# $2 (LOCAL_FAN_SPEED): The desired fan speed. Can be in decimal (0-100) or hexadecimal (0x00-0x64) format.
#
# Global variables used:
Expand All @@ -23,24 +23,24 @@ function apply_Dell_fan_control_profile() {
# Returns:
# None. In case of an invalid mode, it calls graceful_exit().
function apply_user_fan_control_profile() {
local MODE=$1
local FAN_CONTROL_PROFILE=$1
local LOCAL_FAN_SPEED=$2

if [[ $LOCAL_FAN_SPEED == 0x* ]]; then
local LOCAL_DECIMAL_FAN_SPEED=$(printf '%d' "$LOCAL_FAN_SPEED")
local LOCAL_DECIMAL_FAN_SPEED=$(convert_hexadecimal_value_to_decimal "$LOCAL_FAN_SPEED")
local LOCAL_HEXADECIMAL_FAN_SPEED=$LOCAL_FAN_SPEED
else
local LOCAL_DECIMAL_FAN_SPEED=$LOCAL_FAN_SPEED
local LOCAL_HEXADECIMAL_FAN_SPEED=$(convert_decimal_value_to_hexadecimal "$LOCAL_FAN_SPEED")
fi

case $MODE in
case $FAN_CONTROL_PROFILE in
1)
apply_fan_control_to_specified_value "$LOCAL_HEXADECIMAL_FAN_SPEED"
set_fans_speed "$LOCAL_HEXADECIMAL_FAN_SPEED"
CURRENT_FAN_CONTROL_PROFILE="User static fan control profile ($LOCAL_DECIMAL_FAN_SPEED%)"
;;
2)
apply_fan_control_to_specified_value "$LOCAL_HEXADECIMAL_FAN_SPEED"
set_fans_speed "$LOCAL_HEXADECIMAL_FAN_SPEED"
CURRENT_FAN_CONTROL_PROFILE="Interpolated fan control profile ($LOCAL_DECIMAL_FAN_SPEED%)"
;;
*)
Expand All @@ -50,7 +50,7 @@ function apply_user_fan_control_profile() {
esac
}

# Apply fan control to a specified value
# Set fans speed to a specified value
#
# This function sets the fan speed to a user-specified value using ipmitool.
# It first checks if the input value is in hexadecimal format, and converts it
Expand All @@ -65,17 +65,17 @@ function apply_user_fan_control_profile() {
#
# Note:
# This function uses the global variable $IDRAC_LOGIN_STRING for iDRAC login.
function apply_fan_control_to_specified_value() {
local VALUE=$1
function set_fans_speed() {
local FAN_SPEED_TO_APPLY=$1

# Check if the input value is a hexadecimal number, if not, convert it to hexadecimal
if [[ $VALUE != 0x* ]]; then
VALUE=$(convert_decimal_value_to_hexadecimal "$VALUE")
if [[ $FAN_SPEED_TO_APPLY != 0x* ]]; then
FAN_SPEED_TO_APPLY=$(convert_decimal_value_to_hexadecimal "$FAN_SPEED_TO_APPLY")
fi

# Use ipmitool to send the raw command to set fan control to user-specified value
ipmitool -I $IDRAC_LOGIN_STRING raw 0x30 0x30 0x01 0x00 > /dev/null
ipmitool -I $IDRAC_LOGIN_STRING raw 0x30 0x30 0x02 0xff "$VALUE" > /dev/null
ipmitool -I $IDRAC_LOGIN_STRING raw 0x30 0x30 0x02 0xff "$FAN_SPEED_TO_APPLY" > /dev/null
}

# Calculate the interpolated fan speed based on CPU temperature
Expand Down Expand Up @@ -141,7 +141,7 @@ function calculate_interpolated_fan_speed() {
}

# Convert first parameter given ($DECIMAL_NUMBER) to hexadecimal
# Usage : convert_decimal_value_to_hexadecimal $DECIMAL_NUMBER
# Usage : convert_decimal_value_to_hexadecimal "$DECIMAL_NUMBER"
# Returns : hexadecimal value of DECIMAL_NUMBER
function convert_decimal_value_to_hexadecimal() {
local DECIMAL_NUMBER=$1
Expand All @@ -159,7 +159,7 @@ function convert_hexadecimal_value_to_decimal() {
}

# Retrieve temperature sensors data using ipmitool
# Usage : retrieve_temperatures $IS_EXHAUST_TEMPERATURE_SENSOR_PRESENT $IS_CPU2_TEMPERATURE_SENSOR_PRESENT
# Usage : retrieve_temperatures "$IS_EXHAUST_TEMPERATURE_SENSOR_PRESENT" "$IS_CPU2_TEMPERATURE_SENSOR_PRESENT"
function retrieve_temperatures() {
if (( $# != 2 )); then
printf "Illegal number of parameters.\nUsage: retrieve_temperatures \$IS_EXHAUST_TEMPERATURE_SENSOR_PRESENT \$IS_CPU2_TEMPERATURE_SENSOR_PRESENT" >&2
Expand Down

0 comments on commit 8e684c4

Please sign in to comment.