绿联 UGREEN DX及DXP系列 NAS 黑群晖 面板LED 控制 V2.0
DoLizUju
编辑于 2026年03月14日 19:59
收录于文集
共2篇

更新日志: [2025.08.23] 1.简化操作流程,适配绿联DX及DXP系NAS; 2.执行命令增加条件检测; 3.解决盘位顺序与HCTL顺序不关联,导致指示灯错位的问题; 4.硬盘状态检测改为smartctl查看smart信息; [2026.03.14] 1.优化 HCTL 提取 2.增加自定义颜色 3.自动识别DT/非DT机型规则 4.优化硬盘扫描规则,增加休眠非唤醒检测

RR版本需要24.6.9及以上,脚本使用root权限运行

命令工具支持以下设备:

  • UGREEN DX4600 Pro

  • UGREEN DX4700+

  • UGREEN DXP2800

  • UGREEN DXP4800

  • UGREEN DXP4800 Plus

  • UGREEN DXP6800 Pro

  • UGREEN DXP8800 Plus

示范设备及版本:

RR版本 v25.9.7

型号:     SA6400(epyc7002)

版本:     7.2(69057u4)

内核:     official

LKM:      prod

DMI:      UGREEN DX4600 Pro/To be filled by O.E.M, BIOS 5.19 05/10/2023

CPU:      Intel(R) Pentium(R) Silver N6005 @ 2.00GHz

MEM:      15844 MB


一、前置条件:

1.RR引导中

1.1模块modules:

如果没设置过模块,默认是全选,跳过这一步。 确保在模块列表中,选择了如下模块:

新版本RR要选上check_signature: https://github.com/RROrg/rr/issues/14461

1.2插件addons:

插件:sensors,用于监视 CPU 温度(可选)

编译引导后,启动进入DSM。

2.检查准备

SSH登陆NAS,并切换到root帐号:

代码块
Shell
自动换行
复制代码
sudo -i   # 输入你帐户密码
复制成功

确认加载了i2c模块:

代码块
Shell
自动换行
复制代码
root@NAS:~# lsmod | grep i2c
regmap_i2c             16384  2 adm9240,lm75
i2c_i801               28672  0 
check_signature        16384  1 i2c_i801
i2c_smbus              16384  1 i2c_i801
i2c_algo_bit           16384  1 i915
复制成功

整合包Download: https://wwcv.lanzn.com/b00ef8cs3c 密码:3rg8 下载整合包,解压上传到DSM,例如在:/volume1/homes/xxxx/ugreen_leds/

代码块
PlainText
自动换行
复制代码
/volume1/homes/xxxx/ugreen_leds/
├── i2cdetect      #(调试用) 扫描 I2C 总线,查看有哪些设备连接在上面。
├── i2cdump        #(调试用) 一次性读取并显示某个设备的所有**寄存器(Register)**数值
├── i2cget         #(调试用) 读取指定设备、指定寄存器的 **单个数值**
├── i2cset         #(调试用) 向指定设备、指定寄存器 **写入一个数值**。
├── i2ctransfer    #(调试用) 在一个事务中同时发送和接收多个字节的数据。
├── paomadeng.sh   # 测试用跑马灯脚本
├── ugreen_leds.sh   # 主要功能脚本
└── ugreen_leds_cli  # 实现上面脚本要用到的命令行工具
复制成功

然后:

代码块
PlainText
自动换行
复制代码
# 进入放脚本目录
cd /volume1/homes/xxxx/ugreen_leds

# 给脚本和工具赋予执行权限 
chmod +x ./paomadeng.sh ./i2cdetect ./ugreen_leds.sh ./ugreen_leds_cli
复制成功

用i2cdetect检查 SMBus I801 在i2c通道0

代码块
Shell
自动换行
复制代码
root@NAS:/volume1/homes/xxxx/ugreen_leds/# ./i2cdetect -l
i2c-0   smbus           SMBus I801 adapter at efa0              SMBus adapter
i2c-1   i2c             i915 gmbus dpa                          I2C adapter
i2c-2   i2c             i915 gmbus dpb                          I2C adapter
i2c-3   i2c             i915 gmbus dpc                          I2C adapter
i2c-4   i2c             i915 gmbus tc1                          I2C adapter
i2c-5   i2c             i915 gmbus tc2                          I2C adapter
i2c-6   i2c             i915 gmbus tc3                          I2C adapter
i2c-7   i2c             i915 gmbus tc4                          I2C adapter
i2c-8   i2c             i915 gmbus tc5                          I2C adapter
i2c-9   i2c             i915 gmbus tc6                          I2C adapter
复制成功

检查位于 SMBus I801适配器 地址0x3a的设备是否可见

代码块
Shell
自动换行
复制代码
root@NAS:/volume1/homes/xxxx/ugreen_leds/# ./i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         08 -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: 30 31 -- 33 34 35 36 -- -- -- 3a -- -- -- -- -- 
40: -- -- -- -- 44 -- -- -- -- -- -- -- -- -- -- -- 
50: 50 -- 52 -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
复制成功


二、部署

在群晖 「控制面板-计划任务-新增-计划中的任务-用户自定义的脚本」 任务名称:ugreen_led 用户账号: root 计划中勾选 在同一天内继续运行,第5分钟重复一次。(自己改运行频率)

任务设置-运行命令 中粘贴以下脚本:

代码块
Shell
自动换行
复制代码
cd /volume1/homes/xxxx/ugreen_leds  #你刚才放脚本的文件夹目录
bash ugreen_leds.sh
复制成功

灯位颜色意思:

power:默认白色,CPU温度高于90°C橙色闪烁(rr引导中需要加上sensors插件);

netdev:能ping通网关为蓝色,否则为红色

disk[1-8]:测量S.M.A.R.T.信息正常为绿色,异常为红色,温度高于50°C黄色闪烁;硬盘休眠为低亮度绿色

部分SSD不支持 smartctl -H 查看健康状态,默认为OK不代表健康,已跳过检测,请用厂商提供工具细看,HDD正常为PASSED,仅提供简单的健康评估结果,详细的 SMART 属性请使用 smartctl -a 查看。

ugreen_leds.sh:

代码块
Shell
自动换行
复制代码
#!/bin/bash

# ==========================================================
# 脚本名称: ugreen_led.sh
# 适用机型: 绿联 UGREEN DX及DXP系列
# 更新日期: 2026.03.14
# 更新记录:
#    - 2026.03.14:
#       增加自动识别DT/非DT机型规则
#       增加自定义颜色
#       增加休眠微光(Brightness Sleep)模式
#       优化硬盘扫描规则,增加休眠非唤醒检测
#       优化 HCTL 提取
#       优化温度提取逻辑

# ==========================================================

SCRIPTPATH=$(dirname "${0}")
CLI="${SCRIPTPATH}/ugreen_leds_cli"

# --- 1. 自定义颜色及亮度配置 (RGB和亮度范围: 0-255) ---
# 你可以在这里填写喜欢的颜色
COLOR_POWER="255 255 255"       # 电源灯: 白色
COLOR_CPU_HOT="255 165 0"       # CPU超过90°C电源灯:橙色
COLOR_NET_OK="0 0 255"          # 网关正常: 蓝色
COLOR_NET_ERR="255 0 0"         # 网关异常: 红色
COLOR_DISK_OK="0 255 0"         # 硬盘正常: 绿色
COLOR_DISK_ERR="255 0 0"        # 硬盘故障: 红色
COLOR_HOT="255 165 0"           # 硬盘超过50°C预警: 橙色

BRIGHTNESS="64"                 # 工作时灯光亮度
BRIGHTNESS_SLEEP="10"           # 硬盘休眠时的微光亮度

# --- 2. LED 到 HCTL 的物理映射 ---
# https://github.com/miskcoo/ugreen_leds_controller?tab=readme-ov-file#disk-mapping
# 对于 DX4600 Pro 和 DXP8800 Plus,映射为 X:0:0:0 -> diskX。
# 对于 DXP6800 Pro,0:0:0:0 和 1:0:0:0 映射到 disk5 和 disk6,2:0:0:0 到 6:0:0:0 映射到 disk1 到 disk4。
# 其它机型或宿主机中虚拟群晖DSM请自行看看盘位 HCTL,根据实际盘位顺序,填写HCTL值
# ["disk*"] 是面板灯位,不要改动,物理机上有几个灯就留几个,其它灯注释掉。
declare -A led_map=(
    ["disk1"]="0:0:0:0"
    ["disk2"]="1:0:0:0"
    ["disk3"]="2:0:0:0"
    ["disk4"]="3:0:0:0"
#    ["disk5"]="4:0:0:0"
#    ["disk6"]="5:0:0:0"
#    ["disk7"]="6:0:0:0"
#    ["disk8"]="7:0:0:0"
)

# 检查控制工具是否存在
if ! [[ -f "$CLI" ]]; then
    echo "错误: 未找到 ugreen_leds_cli,请确保它在脚本同级目录下。"
    exit 1
fi

# --- 3. 自动检测机型硬盘命名规则 (DT vs 非 DT) ---
if ls /dev/sata* >/dev/null 2>&1; then
    # DT 机型规则 (如 SA6400, DS923+, DS920+)
    DISK_DEV_PATH="/dev/sata*"
    DISK_REGEX="^sata[0-9]+$"
    # echo "检测到 DT 规则系统,匹配 /dev/sataX"
else
    # 非 DT 机型规则 (如 DS3622xs+, DS918+)
    DISK_DEV_PATH="/dev/sd*"
    DISK_REGEX="^sd[a-z]+$"
    # echo "检测到非 DT 规则系统,匹配 /dev/sdX"
fi

# 映射以保持所需的 LED 颜色和状态
declare -A led_status

# 检查网络连通性函数
check_network() {
    local gw=$(ip route | awk '/default/ { print $3 }')
    [[ -n "$gw" ]] && ping -q -c 1 -W 1 "$gw" >/dev/null 2>&1
}

# --- 4. 扫描活动硬盘并获取 HCTL ---
active_disks=$(
    for dev in $DISK_DEV_PATH; do
        disk_name=$(basename "$dev")
        # 排除分区,仅匹配主盘名
        if [ -e "$dev" ] && [[ "$disk_name" =~ $DISK_REGEX ]]; then
            # 使用 basename + readlink 提取 HCTL 地址
            hctl=$(basename $(readlink "/sys/class/block/$disk_name/device" 2>/dev/null))
            echo "$disk_name $hctl"
        fi
    done
)

# --- 5. 状态计算: 电源、CPU 与网络 ---

# --- 电源灯默认状态--- 
led_status["power"]="-color $COLOR_POWER -on -brightness $BRIGHTNESS"

# --- CPU 温度检查 ---
if command -v sensors >/dev/null 2>&1; then
    ADAPTER=$(sensors | grep "coretemp" | head -n 1 | awk -F: '{print $1}')

    if [ -n "$ADAPTER" ]; then
        # 如果是 Intel,只用这个精准方案
        cpu_temp=$(sensors "$ADAPTER" | grep -E 'Package id 0|Core 0' | grep -oP '\+\K\d+' | head -n 1)
    else
        # 只有找不到 Intel 适配器时,才用通用的模糊方案
        cpu_temp=$(sensors | grep -E 'Package id 0|Core 0|Tctl' | grep -oP '\d+' | head -n 1)
    fi

    # 逻辑判断 (90度报警)
    if [[ -n "$cpu_temp" && "$cpu_temp" -gt 90 ]]; then
        led_status["power"]="-color $COLOR_CPU_HOT -on -blink 400 600 -brightness $BRIGHTNESS"
    fi
fi

# 网络灯状态
if check_network; then
    led_status["netdev"]="-color $COLOR_NET_OK -on -brightness $BRIGHTNESS"
else
    led_status["netdev"]="-color $COLOR_NET_ERR -on -brightness $BRIGHTNESS"
fi

# --- 6. 状态计算: 硬盘健康与温度 ---
# 先将所有定义的硬盘灯设为关闭
for key in "${!led_map[@]}"; do led_status[$key]="-off"; done

while read -r disk_name hctl; do
    [[ -z "$disk_name" ]] && continue
    
    # 查找物理灯位
    led_name=""
    for key in "${!led_map[@]}"; do
        [[ "${led_map[$key]}" == "$hctl" ]] && led_name="$key" && break
    done

    if [[ -n "$led_name" ]]; then
        # 1. SMART 健康检查 (增加 -n standby 参数)
        # 如果硬盘处于休眠状态,smartctl 会返回特定的退出状态码而不唤醒硬盘
        smart_out=$(smartctl -n standby -H "/dev/$disk_name")
        
        if echo "$smart_out" | grep -qE "PASSED|OK"; then
            # 健康状态良好
            led_status[$led_name]="-color $COLOR_DISK_OK -on -brightness $BRIGHTNESS"
        elif echo "$smart_out" | grep -q "Device is in Standby mode"; then
            # 硬盘正在休眠:保持绿色,但可以降低亮度,代表它正在休息
            led_status[$led_name]="-color $COLOR_DISK_OK -on -brightness $BRIGHTNESS_SLEEP"
        else
            # 确定是 SMART 失败或其他异常:红色闪烁告警
            led_status[$led_name]="-color $COLOR_DISK_ERR -on -blink 400 600 -brightness $BRIGHTNESS"
        fi

        # 2. 硬盘温度监控 (继续使用系统缓存,不唤醒硬盘)
        real_name=$(readlink -f "/dev/$disk_name" | xargs basename)
        temp_file="/run/synostorage/disks/${real_name}/temperature"
        
        if [[ -f "$temp_file" ]]; then
            temp=$(cat "$temp_file" 2>/dev/null)
            # 如果温度超过 50°C 且硬盘不是在休眠(休眠时 temp 通常为空或很低)
            if [[ -n "$temp" && "$temp" -gt 50 ]]; then
                led_status[$led_name]="-color $COLOR_HOT -on -blink 400 600 -brightness $BRIGHTNESS"
            fi
        fi
    fi
done <<< "$active_disks"

# --- 7. 应用 LED 设置 ---
for led in "${!led_status[@]}"; do
    $CLI $led ${led_status[$led]} >/dev/null 2>&1
done
复制成功


三、可能会遇到的问题问题

1.灯位显示与实际不一致

复制到ssh中运行,查看硬盘型号与HCTL地址。

代码块
Shell
自动换行
复制代码
#!/bin/bash

# ==========================================================
# 脚本名称: HCTL_cheak.sh
# 脚本作用:检查硬盘型号与HCTL地址
# 更新日期: 2026.03.14
# ==========================================================

# 注意:循环应该是 /dev/sata* 而不是 /dev/sata
for dev in /dev/sata*; do
    # 确保是主盘名(如 sata1)而不是分区(如 sata1p1)
    disk_name=$(basename "$dev")
    if [ -e "$dev" ] && [[ "$disk_name" =~ ^sata[0-9]+$ ]]; then
        
        # 1. 优化信息获取:一次性调用 smartctl 存入变量,避免反复读盘(防止硬盘反复启停)
        smart_info=$(smartctl -i "$dev")
        
        # 使用 grep 匹配关键字比直接用行号(sed -n '5p')更稳,因为不同品牌的硬盘输出行数可能不同
        vendor=$(echo "$smart_info" | grep -i "Vendor" | awk '{print $NF}')
        [ -z "$vendor" ] && vendor=$(echo "$smart_info" | grep -i "Model Family" | awk '{print $NF}')
        
        product=$(echo "$smart_info" | grep -i "Device Model" | awk '{print $NF}')
        capacity=$(echo "$smart_info" | grep -i "User Capacity" | sed -n 's/.*\[\(.*\)\].*/\1/p')

        # 2. 优化 HCTL 获取:使用 basename + readlink
        # 这里的路径用 /sys/class/block/ 更简洁
        hctl=$(basename $(readlink "/sys/class/block/$disk_name/device" 2>/dev/null))

        # 输出结果
        echo "盘符: $disk_name | 品牌: ${vendor:-未知} | 型号: ${product:-未知} | 容量: $capacity | HCTL: $hctl"
    fi
done
复制成功

例子:

代码块
Shell
自动换行
复制代码
盘符: sata1 | 品牌: A | 型号: 未知 | 容量: 8.00 TB | HCTL: 5:0:0:0
盘符: sata2 | 品牌: 未知 | 型号: B | 容量: 4.00 TB | HCTL: 9:0:0:0
复制成功

假如一个四盘位机型,对应disk1-4灯位,插入两块盘,A插在第二槽,B在第四槽。

改动disk2和disik4后面的HCTL,其它没插硬盘就可以注释掉: 物理机 disk2 这个灯位对应是 【盘符: sata1 | 品牌: A | 型号: 未知 | 容量: 8.00 TB | HCTL: 5:0:0:0 】这块硬盘,就是 ["disk2"]="5:0:0:0" ["disk1-8"] 是面板灯位名称,不要改动

代码块
Shell
自动换行
复制代码
declare -A led_map=(
#    ["disk1"]="0:0:0:0"
    ["disk2"]="5:0:0:0"
#    ["disk3"]="2:0:0:0"
    ["disk4"]="9:0:0:0"
#    ["disk5"]="4:0:0:0"
#    ["disk6"]="5:0:0:0"
#    ["disk7"]="6:0:0:0"
#    ["disk8"]="7:0:0:0"
)
复制成功

2.我的/dev里没有sata* 设备(2026.03.14已更新到脚本自动判断)

如果你使用的是DT(Device tree)机型,如DS920+,DS923+, DS1520+, DS1621+, DS1821+, DS2422+,DVA1622, FS2500, SA6400等,则硬盘是以sata* 样式,不用修改。 如果你使用的是非DT机型,如DS918+,DS1621xs+,DS3622xs+,DS3617xs+,DS3615xs+等,则所有内容的 sata* 要替换为 sd* , ^sata[0-9]+$ 替换成 ^sd[a-z]$ 


四、扩展

1.常用颜色

2.LED控制器命令说明:

代码块
Shell
自动换行
复制代码
ugreen_leds_cli  [LED-NAME...] [-on] [-off] [-(blink|breath) T_ON T_OFF]
                    [-color R G B] [-brightness BRIGHTNESS] [-status]

       LED-NAME:    用空格分隔,可能的值为
                    { power, netdev, disk[1-8], all }。
       -on / -off:  打开/关闭对应的LED。
       -blink / -breath:  将LED设置为闪烁/呼吸模式。此模式下,LED会亮T_ON毫秒,然后
                    熄灭T_OFF毫秒。
                    T_ON 和 T_OFF 的取值范围是 [0, 65535]。
       -color:      设置对应LED的颜色。
                    R, G 和 B 的取值范围是 [0, 255]。
       -brightness: 设置对应LED的亮度。
                    BRIGHTNESS 的取值范围是 [0, 255]。
       -status:     显示对应LED的状态。
复制成功


参考

https://github.com/miskcoo/ugreen_leds_controller

https://blog.miskcoo.com/2024/05/ugreen-dx4600-pro-led-controller

https://gist.github.com/Kerryliu/c380bb6b3b69be5671105fc23e19b7e8

https://imnks.com/10101.html

https://github.com/RROrg/rr/issues/14461

结尾

感谢您花时间阅读这篇教程,咱是个萌新小白,对linux也是一知半解,就喜欢瞎折腾,请大佬轻喷。由于群晖没有lsblk,获取hctl得用其它方法,反而复杂了,如果是Debian、TrueNAS、unRAID、PVE在参考里面GitHub上有大佬写脚本直接用就可以。

希望这篇教程能对您有所帮助,我尽我所能地提供了详细的步骤和解释,但如果你发现任何错误或不清楚的地方,请务必在评论告诉我,欢迎随时交流,我们可以一起进步。