黑群晖 DS918+ 风扇调速踩坑记:从主板温度不准到双风扇独立温控
前言
最近发现我的黑群晖(DS918+ / ITX-CS3主板)风扇有点不对劲:机箱风扇一直全速转很吵,CPU风扇又一直最低速不动。拆开一看,发现是主板温度传感器不准的问题,顺便折腾了一套完整的双风扇温控方案。记录一下过程。
一、问题发现
NAS 风扇接口情况:
| 接口 | 连接 | 问题 |
|---|---|---|
| 主板 4pin (CPU_FAN) | CPU 风扇 | DSM 自动调速,但读的是假温度 |
| 硬盘架 3pin | 机箱风扇 | 3pin 无法调速,一直全速 |
| 电源自带 | 电源风扇 | 无法控制 |
核心痛点 :DSM 读取的是 acpitz 温度传感器,永远显示 27°C / 29°C,导致风扇策略极其保守。即使 CPU 已经 50°C 了,风扇还在最低速。
二、温度传感器普查
SSH 进 NAS,逐个查看可用温度源:
bash
# CPU 核心温度(真实)
cat /sys/devices/platform/coretemp.0/hwmon/hwmon0/temp1_input
# 主板供电温度(it8613芯片)
cat /sys/devices/platform/it87.2624/hwmon/hwmon2/temp2_input
# 硬盘温度
smartctl -A /dev/sdX | grep Temperature_Celsius
# ACPI虚拟温度(假的,DSM用的这个)
cat /sys/class/thermal/thermal_zone0/temp
各温度源实测对比:
| 温度源 | 典型值 | 真实性 |
|---|---|---|
| coretemp CPU Physical id 0 | 43°C | ✅ 真实 |
| it8613 temp2 (主板供电) | 46°C | ✅ 真实 |
| 硬盘 smartctl | 40~47°C | ✅ 真实 |
| acpitz thermal_zone0 | 27°C | ❌ 假数据 |
三、硬件调整
机箱风扇原来插在硬盘架的 3pin 接口上,无法调速。解决方法:拔下来插到主板的空闲 4pin PWM 口上。
这样机箱风扇就变成 PWM 可控了,和 CPU 风扇一样由软件控制。
四、控制方案设计
4.1 控制逻辑
Delta = 设备温度 - 环境温度
条件 PWM值
Delta <= 15°C 0 (停转/最低)
15°C < Delta < 35°C (Delta - 15) × 12.75
Delta >= 35°C 255 (全速)
温度与转速的关系如下图所示:

4.2 双风扇分配
| 风扇 | PWM 通道 | 温度源 | 策略 |
|---|---|---|---|
| CPU 风扇 | pwm2 | CPU 核心温度 | CPU 温控 |
| 机箱风扇 | pwm3 | 主板 + 硬盘最高温度 | 机箱整体散热 |
4.3 环境温度补偿
通过 Home Assistant API 读取空气净化器的温度传感器(就在 NAS 旁边),作为环境温度基准。这样夏天 30°C 时风扇 45°C 才开始转,冬天 20°C 时 35°C 就开始转,自动适配季节。
4.4 平滑处理
每步 PWM 变化不超过 ±15,防止风扇转速突变产生噪音波动。
五、完整脚本
脚本路径:/volume1/Settings/fun-control/nas-fan-control.sh
bash
#!/bin/sh
PWM2="/sys/class/hwmon/hwmon2/pwm2"
PWM3="/sys/class/hwmon/hwmon2/pwm3"
PWM2_EN="/sys/class/hwmon/hwmon2/pwm2_enable"
PWM3_EN="/sys/class/hwmon/hwmon2/pwm3_enable"
CPU_TEMP="/sys/devices/platform/coretemp.0/hwmon/hwmon0/temp1_input"
MOBO_TEMP="/sys/devices/platform/it87.2624/hwmon/hwmon2/temp2_input"
HA_URL="http://127.0.0.1:8123"
HA_TOKEN="你的HA长期令牌"
HA_TEMP_ENTITY="sensor.zhimi_cn_315697705_ma2_temperature_p_3_3"
PWM_STEP=15
INTERVAL=10
calc_pwm() {
local delta=$1 offset=$2 max_ex=$3 pwm_min=$4 pwm_max=$5
local pwm=$pwm_min
if [ "$delta" -gt "$offset" ]; then
local r=$((max_ex - offset))
local o=$((delta - offset))
local pr=$((pwm_max - pwm_min))
pwm=$((pwm_min + o * pr / r))
[ "$pwm" -gt "$pwm_max" ] && pwm=$pwm_max
fi
echo $pwm
}
get_ambient_temp() {
local resp=$(curl -s --max-time 3 -H "Authorization: Bearer $HA_TOKEN" "$HA_URL/api/states/$HA_TEMP_ENTITY")
# ... 解析返回的温度值,单位千分之一°C
}
get_chassis_max() {
# 取主板供电温度 和 各硬盘温度 中的最大值
local mobo=$(cat "$MOBO_TEMP" 2>/dev/null)
# 通过 smartctl 读取各硬盘温度
# 返回较高的那个
}
smooth() {
local target=$1 cur=$2 step=$3
local d=$((target - cur))
if [ "$d" -gt "$step" ]; then echo $((cur + step))
elif [ "$d" -lt "$((-step))" ]; then echo $((cur - step))
else echo "$target"
fi
}
echo "1" > "$PWM2_EN" # 切为手动模式
echo "1" > "$PWM3_EN"
while true; do
amb=$(get_ambient_temp)
# CPU 风扇
cpu_raw=$(cat "$CPU_TEMP")
dcpu=$((cpu_raw - amb))
tcpu=$(calc_pwm "$dcpu" 15000 35000 0 255)
pcpu=$(smooth "$tcpu" "$last_cpu" 15)
echo "$pcpu" > "$PWM2"
# 机箱风扇
cmax=$(get_chassis_max)
dch=$((cmax - amb))
tch=$(calc_pwm "$dch" 15000 35000 0 255)
pch=$(smooth "$tch" "$last_chassis" 15)
echo "$pch" > "$PWM3"
sleep 10
done
六、设置开机自启
-
进 DSM → 控制面板 → 任务计划
-
新增 → 触发的任务 → 开机
-
任务名称:
风扇控制 -
用户:
root -
运行命令:
bashbash /volume1/Settings/fun-control/nas-fan-control.sh & -
确定保存
七、效果实测
脚本运行后的温控日志:
CPU=44C 机箱=47C 环境=27C pwm2=25 pwm3=63
CPU=45C 机箱=47C 环境=27C pwm2=38 pwm3=63
CPU=42C 机箱=47C 环境=27C pwm2=0 pwm3=63
温度稳定后,两个风扇都处于低速运转状态,噪音明显降低。
八、一些踩坑总结
- acpitz 温度是假的:DSM 自带风扇策略读的是这个假温度,不要用它
- 3pin 风扇无法调速:只有 4pin PWM 风扇才能用脚本控制转速
- PWM=0 不等于风扇完全停转:部分主板在 PWM=0 时仍保持最低转速(约 800 RPM)
- IT8613E 芯片:你的 NAS 风扇都挂在它下面,/sys/class/hwmon/hwmon2/ 路径
- Home Assistant 很方便:读取空气净化器的温度传感器作为环境基准,无需额外硬件
- 机箱风扇应该读最高温度:硬盘往往比 CPU 更热,机箱风扇应以最高设备温度为准
九、后续优化方向
- 换成静音电源,解决电源风扇 80dB 噪音
- 考虑将环境温度改为从 HA 读取多个传感器取平均
- 优化参数:T_OFFSET、T_MAXEXCESS 可根据季节自动调整
本文脚本适用于黑群晖 DS918+ 及使用 IT86x 系列芯片的主板,其他平台需根据实际硬件调整 sysfs 路径。