黑群晖 DS918+ 风扇调速踩坑记:从主板温度不准到双风扇独立温控

黑群晖 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

六、设置开机自启

  1. 进 DSM → 控制面板任务计划

  2. 新增 → 触发的任务开机

  3. 任务名称:风扇控制

  4. 用户:root

  5. 运行命令:

    bash 复制代码
    bash /volume1/Settings/fun-control/nas-fan-control.sh &
  6. 确定保存

七、效果实测

脚本运行后的温控日志:

复制代码
CPU=44C 机箱=47C 环境=27C pwm2=25 pwm3=63
CPU=45C 机箱=47C 环境=27C pwm2=38 pwm3=63
CPU=42C 机箱=47C 环境=27C pwm2=0  pwm3=63

温度稳定后,两个风扇都处于低速运转状态,噪音明显降低。

八、一些踩坑总结

  1. acpitz 温度是假的:DSM 自带风扇策略读的是这个假温度,不要用它
  2. 3pin 风扇无法调速:只有 4pin PWM 风扇才能用脚本控制转速
  3. PWM=0 不等于风扇完全停转:部分主板在 PWM=0 时仍保持最低转速(约 800 RPM)
  4. IT8613E 芯片:你的 NAS 风扇都挂在它下面,/sys/class/hwmon/hwmon2/ 路径
  5. Home Assistant 很方便:读取空气净化器的温度传感器作为环境基准,无需额外硬件
  6. 机箱风扇应该读最高温度:硬盘往往比 CPU 更热,机箱风扇应以最高设备温度为准

九、后续优化方向

  • 换成静音电源,解决电源风扇 80dB 噪音
  • 考虑将环境温度改为从 HA 读取多个传感器取平均
  • 优化参数:T_OFFSET、T_MAXEXCESS 可根据季节自动调整

本文脚本适用于黑群晖 DS918+ 及使用 IT86x 系列芯片的主板,其他平台需根据实际硬件调整 sysfs 路径。