Skip to content

DF-wu/iDRACFanSpeedControl

Repository files navigation

iDRAC Fan Speed Control

Tests Container License

這是一個給 Dell PowerEdge 使用的風扇控制器。它透過 iDRAC 的 IPMI OEM raw command 設定 fan duty cycle,再用 ESXi NVMe SMART、iDRAC temperature sensor、NVIDIA GPU 中任一個或多個來源決定風扇曲線。

Caution

這個程式會暫時覆寫 Dell 原廠風扇控制。第一次設定請保留 iDRAC Web UI 或實體主控台,先用 manualrestorediagnose 驗證,再讓 auto 長時間執行。任何過熱、讀值不可信或行為異常時,立即執行 restore 並停止容器。

先看懂它如何工作

flowchart LR
    TUI[make tui\n互動式設定] --> ENV[.env\n600 permissions]
    ENV --> COMPOSE[Docker Compose]
    COMPOSE --> CTRL[fan-control.sh]
    CTRL --> IPMI[iDRAC / IPMI\nfan raw command]
    CTRL --> ESXI[ESXi\nesxcli SMART]
    CTRL --> SDR[iDRAC\nTemperature SDR]
    CTRL --> GPU[NVIDIA\nnvidia-smi]
    CTRL --> LOG[logs/fan_control.log\nhealthcheck]
Loading

控制器只會對 iDRAC 發送風扇命令;溫度來源全部是讀取。多來源時採用最高的有效決策溫度,GPU 會先減去 GPU_TEMP_OFFSET,避免 GPU 的封裝溫度直接把機箱風扇推到不必要的高轉速。

iDRAC IPMI over LAN 設定畫面

圖 1:在 iDRAC Web UI 開啟 IPMI over LAN;實際選項名稱會依 iDRAC 韌體版本略有不同。

快速開始:用 TUI 完成安全的第一次設定

建議在 Docker 主機上操作。TUI 不需要 dialog、Python 或其他額外套件;它使用純 Bash,會保留 .env.example 的註解、以原子方式更新檔案,並將檔案權限設為 600

git clone https://github.com/DF-wu/iDRACFanSpeedControl.git
cd iDRACFanSpeedControl
make tui

主畫面如下(每次進入子頁都會寫回 .env,離開時會再次顯示檔案位置):

╭────────────────────────────────────────────────────────────╮
│              iDRAC Fan Control · Setup TUI                │
╰────────────────────────────────────────────────────────────╯

  1) Quick setup wizard       6) Safety, timing, and logging
  2) iDRAC / IPMI settings    7) Review redacted configuration
  3) Temperature source       8) Validate configuration
  4) ESXi NVMe source         9) Run read-only diagnostics
  5) Fan curve                0) Save and exit

第一次建議選 iDRAC sensors only,先不要把 ESXi 或 GPU 加入決策。TUI 完成後,依序執行:

make validate
docker compose run --rm idrac-fan-control diagnose
docker compose up -d
docker logs -f idrac-fan-control

diagnose 是唯讀檢查,不會送出風扇 raw command。它會逐項顯示 iDRAC、每個溫度來源、可寫 log 路徑與「如果現在控制會選哪一檔」的 preview。若某個來源不用,從 TUI 的 source preset 移除它,而不是忽略錯誤後繼續運行。

若要編輯另一份設定檔:

src/fan-control-tui.sh --config /path/to/staging.env

手動建立 .env(不用 TUI 也可以)

cp .env.example .env
chmod 600 .env
$EDITOR .env

最小的 iDRAC-only 範例:

IDRAC_IP=192.0.2.10
IDRAC_ID=root
IDRAC_PASSWORD=change-me
OPERATION_MODE=auto
TEMPERATURE_SOURCES=idrac

先將 IDRAC_PASSWORD、IP 與管理網路換成真實值。.env.example192.0.2.*change-mereplace_with_* 都是故意放的 placeholder,validate 會拒絕它們。

命令速查

命令 作用 是否改變風扇
auto 持續依曲線控制,離開時依設定還原自動模式
once 讀取一次並套用一個決策後離開
manual 35 設定 35% duty cycle;未帶數字時讀 MANUAL_FAN_SPEED
restore 發送 Dell 自動風扇控制命令 是(還原)
status 顯示 chassis 與原始 temperature SDR
config 顯示有效設定摘要,密碼只顯示「set/長度」
validate 檢查數值、placeholder、依賴命令與來源條件
diagnose 逐項連線與溫度讀值探測,含決策 preview
healthcheck 檢查設定與 auto 控制 log 是否在合理時間內更新

Docker Compose 用法:

docker compose run --rm idrac-fan-control config
docker compose run --rm idrac-fan-control validate
docker compose run --rm idrac-fan-control diagnose
docker compose run --rm idrac-fan-control status
docker compose run --rm idrac-fan-control once
docker compose run --rm idrac-fan-control manual 35
docker compose run --rm idrac-fan-control restore

本機腳本可直接使用相同命令:

src/FanControlWithEsxiSmart.sh diagnose
src/FanControlWithEsxiSmart.sh config

本機執行需要 bashcoreutilsipmitooltimeout,ESXi password 模式另需 sshpass;Docker image 已包含這些依賴。

安全啟動順序

sequenceDiagram
    participant U as 操作者
    participant C as Controller
    participant D as iDRAC
    U->>C: validate
    C-->>U: 靜態設定與依賴結果
    U->>C: diagnose
    C->>D: mc info / SDR (read-only)
    D-->>C: 連線與溫度
    C-->>U: source checks + decision preview
    U->>C: manual 30
    C->>D: set fan duty (受控測試)
    U->>C: restore
    C->>D: Dell automatic fan control
    U->>C: auto
Loading

正式開始前逐項確認:

  1. iDRAC Web UI 的 IPMI over LAN 已開啟,管理網路可達。
  2. iDRAC 帳號具備必要權限,密碼不再是 placeholder。
  3. manual 30 能設定低速,manual 70 能設定保守速度,restore 能回到 Dell 自動模式。
  4. diagnose 的每一個已啟用來源都是 [PASS];不用的來源請停用。
  5. 先以較保守的 FAILSAFE_FAN_SPEEDRESTORE_AUTO_ON_EXIT=true 運行。

溫度來源與控制決策

TEMPERATURE_SOURCES 使用逗號分隔,可填 esxiidracgpu。來源可以混合;控制器會保留每個來源的 label 供 log 與診斷追蹤。

來源 讀取內容 必要條件 失敗時的行為
idrac ipmitool sdr type Temperature 中可讀的 sensor iDRAC IPMI 該來源標記失敗
esxi 指定 NVMe 的 esxcli storage core device smart get SSH、DRIVE_DEVICE 該來源標記失敗
gpu nvidia-smi 的每張 GPU 溫度 NVIDIA Container Toolkit/驅動 該來源標記失敗
flowchart TD
    R[所有有效 readings] --> M{取最高 adjusted temperature}
    M --> L[temperature_level]
    L --> H{比上一檔更低?}
    H -- 否 --> S[立即升檔或維持]
    H -- 是 --> X{低於前一檔 threshold - HYSTERESIS?}
    X -- 否 --> S2[維持上一檔]
    X -- 是 --> S3[降到新檔]
    S --> F[套用 fan speed]
    S2 --> F
    S3 --> F
    R -. 全部失敗 .-> FS[FAILSAFE_FAN_SPEED]
Loading

預設曲線如下;validate 會確保 threshold 嚴格遞增、fan speed 不遞減,且 fail-safe 不低於 critical speed。

Level 決策溫度 預設風扇
idle <65°C 25%
low 65–69°C 30%
medium 70–74°C 40%
high 75–79°C 50%
critical >=80°C 60%
failsafe 所有來源失敗 70%

降檔會等待 HYSTERESIS 度,避免溫度在閾值附近來回跳速;升檔不延遲。GPU 的 adjusted 值為 GPU_TEMP - GPU_TEMP_OFFSET,最低不會小於 0°C。

設定參考

連線與模式

變數 預設 說明
IDRAC_IP iDRAC hostname 或 IP;所有 fan 命令必要
IDRAC_ID root iDRAC 使用者
IDRAC_PASSWORD IPMI_PASSWORD environment 傳給 ipmitool -E,不出現在 argv
IPMI_INTERFACE lanplus 通常保持不變
IPMI_TIMEOUT / IPMI_RETRIES 5 / 2 單次 timeout 與 retry
OPERATION_MODE manual autooncemanual
DRY_RUN false 只在測試命令組合時使用;不會產生真實讀值
COMMAND_TIMEOUT 20 SSH、IPMI、GPU 外部命令上限(秒)
CHECK_INTERVAL 60 auto 每個 cycle 間隔(秒)
RESTORE_AUTO_ON_EXIT true auto 收到 SIGTERM/離開時還原

溫度來源

變數 預設 說明
TEMPERATURE_SOURCES esxi esxi,idrac,gpu 的逗號清單
WITH_GPU_TEMP false 舊版相容開關;true 會附加 gpu
GPU_TEMP_OFFSET 15 GPU 溫度的補償度數
ESXI_HOST / ESXI_USERNAME 空 / root ESXi SSH 目標
ESXI_PASSWORD 沒有 key 時使用;TUI 不會回顯
ESXI_SSH_KEY 設定後優先使用 key authentication
ESXI_SSH_PORT 22 SSH port(1–65535)
SSH_CONNECT_TIMEOUT 10 SSH 建立連線上限(秒)
SSH_STRICT_HOST_KEY_CHECKING accept-new yesnoaskaccept-new
DRIVE_DEVICE esxcli storage core device list 找到的完整 ID
IDRAC_SENSOR_INCLUDE_REGEX 只保留符合 sensor 名稱的 awk regex
IDRAC_SENSOR_EXCLUDE_REGEX no reading|disabled|not readable 排除無效 SDR

風扇曲線、安全與診斷

變數 預設 說明
TEMP_LOW/MEDIUM/HIGH/CRITICAL 65/70/75/80 嚴格遞增的°C threshold
FAN_SPEED_IDLE/LOW/MEDIUM/HIGH/CRITICAL 25/30/40/50/60 1–100%,不可遞減
HYSTERESIS 2 降檔所需低於前 threshold 的°C
FAILSAFE_ON_ERROR true 所有來源失敗時使用保守速度
FAILSAFE_FAN_SPEED 70 必須 >= critical speed
MANUAL_FAN_SPEED 35 manual 未帶參數時使用
LOG_DIR / LOG_FILE /var/log/fan-control / fan_control.log 持久化狀態 log
LOG_LEVEL INFO DEBUG 會增加命令與來源細節,絕不列密碼
HEALTHCHECK_MAX_AGE 0 0 代表 CHECK_INTERVAL*3 + COMMAND_TIMEOUT

Docker 部署與 GPU

Compose 預設使用 GHCR image、host network 與 ./logs volume:

docker compose pull
docker compose up -d
docker compose ps
docker inspect --format '{{.State.Health.Status}}' idrac-fan-control

healthcheck 不只驗證 env;在 OPERATION_MODE=auto 時也會確認 fan_control.logHEALTHCHECK_MAX_AGE 內更新。若資料來源全部失敗且 FAILSAFE_ON_ERROR=false,控制 cycle 不會寫成功紀錄,容器會變成 unhealthy,這是刻意的安全訊號。

GPU 模式需要 NVIDIA Container Toolkit。編輯 docker-compose.yml,取消 gpus: all 註解,再設定:

TEMPERATURE_SOURCES=idrac,gpu
GPU_TEMP_OFFSET=15

驗證:

docker run --rm --gpus all nvidia/cuda:12.9.0-runtime-ubuntu24.04 nvidia-smi
docker compose run --rm idrac-fan-control diagnose

若不需要 GPU,使用不含 CUDA 的本機 build 可降低 image 大小:

docker build --build-arg BASE_IMAGE=ubuntu:24.04 -t idrac-fan-control:local .

Debug、log 與故障排除

正常 log 範例:

2026-07-18 03:12:10 [INFO] Control temp 68C -> low (30%). Sources: idrac:Inlet Temp=68C

需要更多上下文時暫時設定:

LOG_LEVEL=DEBUG

再觀察:

docker logs -f idrac-fan-control
tail -f logs/fan_control.log
docker compose run --rm idrac-fan-control diagnose

DEBUG 只會印目標、命令種類、來源選擇與失敗階段;密碼不會放在 argv,也不會寫入 config summary。完整的症狀→檢查→修復表請看 docs/TROUBLESHOOTING.md。日常與緊急操作請看 USAGE_GUIDE.md

常見最短修復路徑:

# 任何不確定的風險先還原 Dell 自動控制
docker compose run --rm idrac-fan-control restore

# 看目前有效設定與依賴狀態
docker compose run --rm idrac-fan-control config
docker compose run --rm idrac-fan-control diagnose

安全與備份

  • .envlogs/、私鑰與 incident dump 都不應提交到 Git;TUI 會將設定檔權限設為 600
  • Compose 會以 read-only 掛載 gitignored 的 ./secrets/run/secrets;ESXi key 請使用容器內路徑(例如 /run/secrets/esxi_ed25519)。
  • 優先使用 ESXI_SSH_KEY;若必須用 password,控制器會以 SSHPASS environment 搭配 sshpass -e,不把密碼放進 argv。
  • iDRAC 密碼透過 IPMI_PASSWORD environment 搭配 ipmitool -Econfig/TUI review 只顯示 set 與字元數。
  • iDRAC/ESXi 應位於隔離管理網路,避免把 IPMI over LAN 暴露到公網。
  • 每次變更 .env 前保留一份 chmod 600 的離線備份,並測試 restore

從哪裡取得 ESXi drive identifier

ssh root@ESXI_HOST
esxcli storage core device list
esxcli storage core device smart get -d 't10.NVMe____完整識別字串'

把完整 identifier 放到 DRIVE_DEVICE,不要自行縮短。若 SMART 輸出沒有 Drive Temperature 數值,diagnose 會將 ESXi source 標成 FAIL,而不會偷偷把錯誤當成 0°C。

測試與品質門檻

make test             # bash -n + 37 個核心 assertions + 10 個 TUI assertions
make validate         # 以 Docker 依賴檢查目前的 .env(不改變風扇)
make validate-example # 不需要 .env 的 DRY_RUN smoke test
make docker-build

測試涵蓋 source normalization、SDR parsing、GPU offset、hysteresis、fail-safe、曲線/port/regex 驗證、credential redaction、health freshness、診斷 preview,以及 TUI 設定檔的安全 round-trip。真實硬體、ESXi SSH 和 GPU 仍須在你的管理網路上以 diagnose 驗證。

專案結構

.
├── src/
│   ├── FanControlWithEsxiSmart.sh   # 控制器、validate、diagnose、healthcheck
│   ├── fan-control-tui.sh           # 純 Bash 設定 TUI
│   └── setIdracFanSpeed.sh          # 舊腳本相容 wrapper
├── tests/
│   ├── fan-control.test.sh          # 核心邏輯與安全測試
│   └── tui.test.sh                  # .env parser / writer 測試
├── docs/
│   └── TROUBLESHOOTING.md           # 症狀導向除錯手冊
├── images/image.png                 # iDRAC IPMI 設定畫面
├── .env.example                     # 帶完整註解的設定模板
├── docker-compose.yml
├── Dockerfile
├── Makefile
├── README.md
└── USAGE_GUIDE.md

相容性與限制

專案以 Dell PowerEdge R730/R730xd、iDRAC 8 類機型的 OEM fan raw command 為主要驗證目標。其他世代可能相容,但不能假設相同;請在無人值守前完成 manualrestorediagnose。iDRAC、ESXi、GPU 的實際 sensor 名稱與權限會依韌體和驅動改變,應以你自己的 diagnostic output 為準。

授權

MIT,詳見 LICENSE

文件最後檢視:2026-07-18。

About

This interactive prompt script is to set idrac fan speed to manual control and give a fixed value .

Topics

Resources

License

Stars

10 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors