猫盘折腾记:Debian下的LED、风扇自动控制脚本
一、背景
按照 猫盘 (ARMADA A3720) 刷机教程 给猫盘刷了Debian系统(顺便说一下:用SATA接口的硬盘安装不成功,必须用U盘),感觉良好。只是风扇呼呼转个不停,LED成了摆设,虽然可以用命令行控制风扇和LED,但作为一个有追求的人,显然不满足于玩具式的手动控制,必须得榨干猫盘的硬件潜力,为我服务!
二、目标与设计
经过一番搜索调研后,摸清技术方案后,设立了如下基本目标:
- 温度达到预设高值时,风扇启动;
温度降至预设低值时,风扇停转;
温度达到危险温度时,立即关机。 - 用LED指示系统的状态:
- 红色LED:指示风扇状态(可理解为温度)。点亮表示正在转动。
- 绿色LED:指示主硬盘工作状态。点亮表示工作状态,呼吸表示处于待机状态;
- 蓝色LED:未使用;
猫盘的红绿蓝三色LED,每个都可以独立设定启用0-255级亮度的常亮方式或呼吸方式。如果同时点亮则是混色效果,理论上可以产生非常多的组合(挺好玩的),不过颜色太多的话,混色后不好辨认,就失去指示的意义了。
三、准备工作
0.(已废弃,用下面的CPU温度取代)探测硬盘温度
因为smartmontools会干扰我的WD蓝盘进入休眠状态,故不再使用。
为了检测硬盘的温度,需要安装smartmontools:
apt-get install smartmontools
安装后,测试一下:
root@catdrive:~# smartctl -a -d ata /dev/sda | grep -m 1 Temperature | awk '{print $10}'
41
root@catdrive:~# smartctl -i -n standby /dev/sda | grep "mode"|awk '{print $4}'
ACTIVE
通过上面两行命令,查询到硬盘为41度,Active模式(即运转中)。
即使不安装smartmontools,也可以直接运行
hdparm -C /dev/sda
查询硬盘运行状态,但没有找到查询硬盘温度的方法。
1. 获取CPU温度
需要安装lm-sensors
来获取CPU温度:
root@catdrive:~# apt-get install lm-sensors
Reading package lists... Done
Building dependency tree
Reading state information... Done
...
安装完成后,通过sensors
命令查询温度:
root@catdrive:~# sensors
d0032004mdiomii00-mdio-0
Adapter: MDIO adapter
temp1: +41.0°C (crit = +100.0°C)
gpio_fan-isa-0000
Adapter: ISA adapter
fan1: 1000 RPM (min = 0 RPM, max = 1000 RPM)
上面的temp1就是CPU的温度,在后面的脚本中我们会使用代码把其中的数字抠出来。
刷机教程的作者libgcc指出这里读取到的是以太网phy的温度,猫盘的CPU似乎不带温度传感器。仔细一看,的确写的是MDIO adapter的温度,查了一下啥意思,果然如他所说。不过因为我没有更好的办法,将错就错继续用这个吧。作为一个linux入门水平者,感谢他的纠错!
2. 风扇控制
风扇的状态可以用下面的方式获得:
root@catdrive:~# cat /sys/class/thermal/cooling_device0/cur_state
1
返回1表示风扇处于运转状态,0表示停止状态。
向风扇设备输出1或0,就是控制风扇启停。
root@catdrive:~# echo 1 > /sys/class/thermal/cooling_device0/cur_state
root@catdrive:~# echo 0 > /sys/class/thermal/cooling_device0/cur_state
3. LED控制
LED控制方法在刷机教程中已经写的很清楚,这里不再赘述。只补充一点,brightness和blink只能有一个生效,后执行的生效。换句话说,要指定亮度就一定是常亮,要呼吸效果就不需要指定亮度。
4. 设置硬盘的待机参数
硬盘在无读写多久后进入待机状态,这是需要在操作系统中配置的。在这一点上花了大量的时间
才终于大致弄清楚我的WD蓝盘的电源管理机制,并正确配置待机参数。
简单说,你可以在下面两个地方配置,任选其一:
- 按照刷机教程所说,配置在
/etc/udev/rules.d/99-hdparm.rules
中最后的hdparm
命令中。需要注意的是,如果你发现没有效果,请在-S
参数前再加一个-B127
参数。 - 删除上面的
99-hdparm.rules
文件,改为编辑/etc/hdparm.conf
,在后面加入下面的配置:
/dev/sda {
apm = 127
spindown_time = 120
write_cache = off
}
这里面的127和120分别对应第一种方法中的-B、-S参数值。其中120的每1个单位代表5秒钟,120就是10分钟,如果想要15分钟,则改为180,以此类推。在我的硬盘上,设置小于10分钟的结果仍然是10分钟。
四、脚本
根据调研所知的技术基础,确定脚本的主要逻辑是:
- 查询CPU的温度、硬盘的休眠状态;
- 如果温度高于危险值则直接关机;
- 如果温度高于高值则打开风扇,LED变为红色;
- 否则,
(1)如果温度低于下限值则关闭风扇,关闭红色LED;
(2)如果硬盘是待机状态,则LED变为绿色呼吸,否则为绿色常亮 - 定时循环执行上述逻辑
现在,在用户目录下新建文件cat.sh。当然别忘了用chmod +x cat.sh
赋予可执行属性。
root@catdrive:~#touch cat.sh
root@catdrive:~#chmod +x cat.sh
root@catdrive:~#nano cat.sh
把下面的脚本拷贝进去:
#! /bin/bash
DISK="/dev/sda"
FAN_DEVICE=/sys/class/thermal/cooling_device0/cur_state
LOOP_TIME=30
# CPU temperature alert level
T_SHUTDOWN=65
T_HIGH=50
T_LOW=45
# command
LOG=/usr/bin/logger
funExec(){
# Detect CPU temperature
CPU_TEMP=$(sensors | grep temp | awk '{print $2}')
CPU_TEMP=${CPU_TEMP:1:2}
# Detect disk standby status
DISK_STATUS=$(hdparm -C $DISK | grep 'drive state' | awk '{print $4}' | tr [a-z] [A-Z] )
# Detect fan status
FAN_STATUS=$(cat $FAN_DEVICE)
#echo $(date) CPU temperature:$CPU_TEMP, Disk Status:$DISK_STATUS, Fan:$FAN_STATUS
# shutdown if temperature is too high
if [ $CPU_TEMP -ge $T_SHUTDOWN ]
then
$LOG "$DISK temperature $CPU_TEMP°C crossed its limit, will shutdown"
#echo shutdown
sync;sync
shutdown -h now
return
fi
# cross temperature limit, open fan
if [ $CPU_TEMP -ge $T_HIGH ]
then
if [ $FAN_STATUS -eq 0 ]
then
$LOG "CPU temperature $CPU_TEMP°C crossed its limit, will open fan"
#echo open fan
echo 1 > $FAN_DEVICE
fi
#echo "turn on red LED"
echo 255 > /sys/class/leds/red/brightness
return
fi
if [ $CPU_TEMP -le $T_LOW -a $FAN_STATUS -eq 1 ]
then
$LOG "$DISK temperature $CPU_TEMP°C back to normal"
if [ $FAN_STATUS -eq 1 ]
then
#echo close fan
echo 0 > $FAN_DEVICE
fi
#echo "turn off red led"
echo 0 > /sys/class/leds/red/brightness
fi
if [ $DISK_STATUS = "STANDBY" -o $DISK_STATUS = "SLEEP" ]
then
#echo "LED -> blink green"
echo 2 > /sys/class/leds/green/blink
else
#echo "LED -> green"
echo 255 > /sys/class/leds/green/brightness
fi
} #end function
while true
do
funExec
# wait N seconds
sleep $LOOP_TIME
done
脚本的前几行是基本参数,其中:
- DISK:硬盘设备符,如有不同请自行修改
- T_SHUTDOWN:关机温度
- T_HIGH:风扇启动温度
- T_LOW:风扇关闭温度。应该比风扇启动温度低几度,否则风扇可能会频繁启动/关闭。
- LOOP_TIME:循环检查时间,默认是30秒。
五、运行效果
通过实测,程序运行效果达到目标,每30秒检查一次CPU温度、硬盘工作状态,并相应地控制风扇和LED。
LED灯的显示效果用下表说明:
状态 | 风扇不转(无红灯) | 风扇转动(红灯) |
---|---|---|
硬盘转动中(绿色) | 绿色 | 黄色 |
硬盘待机中(绿色呼吸) | 绿色呼吸 | 黄-红呼吸 |
*黄色是绿色和红色混合后的颜色。
受我的交互设计能力所限,这个颜色指示方案可能有点让人困惑...网友们有更好的方案可以告诉我。
六、开机自动启动
编辑/etc/rc.local
,在exit前加入一行:
/root/cat.sh &
这样就可以了。如果有强迫症,可以再多花点功夫把这个脚本包装成系统服务。我就懒得动手了。
七、调试的Tips
调试中需要频繁让硬盘来回切换工作/待机状态,需要快速升降CPU温度。可以使用下面的方法:
- 让硬盘进入待机: 执行命令
hdparm -y /dev/sda
。 - 唤醒硬盘:执行命令
hdparm -S 120 /dev/sda
。 - 让CPU温度升高:电吹风暖风挡
- 让CPU温度降低:电吹风冷风档
好吧,我承认后面两个是臆想的,实际我是通过设置较低的温度阈值加开盖人工吹气降温来测试的...因为我宁愿坐在桌子前码几小时的字,也懒得走几步路去拿电吹风...惭愧
参考资料
猫盘 (ARMADA A3720) 刷机教程
Monitor Hard Disk Temperature in Ubuntu/Debian