NAS来电断电自动开关机脚本 发表于 2025-01-24 | 更新于 2025-03-05
| 总字数: 1.1k | 阅读时长: 5分钟 | 浏览量: |
前情回顾:博主已经买了个 UPS 来保证家里断电后,电脑还能有足够的时间来处理未完成的任务并关机,从而保证数据还有硬件的安全。来电断电报警器也是为此准备的:断电后报警器发出信息,接着我可以远程关机,但避免不了我没法及时操作的情况,于是便有了此文。
博主已有一台 x86 的电脑和一台 ARM 的机顶盒,机顶盒已装好 Armbian,不接 UPS;电脑装了 ArchLinux 且开启了 WOL,接UPS。于是就可以写个脚本,让电脑在发现了机顶盒不在线(即断电)的一定时间后自动关机;当电脑关机且来电后,机顶盒开机,然后通过 WOL 唤醒电脑。
2024.02.09 经过十多天的测试发现,开启 WOL 后似乎会造成电脑没法完全关机,受限于个人能力和精力,只好放弃 WOL,转用 USB 串口继电器。。。 继电器连接着电脑的开关机线,然后机顶盒控制 USB 串口继电器吸合/断开,以此来操控电脑的开关机,详情请看图片&脚本:
2024.03.05 额……现在发现似乎是新 bios 的问题来着,有空再回退 bios 版本试试了。不过好在现在有可以远程控制的继电器。
[{"url":"https://pic-lrc-bed.haf208.cc/img/extra/nas-auto-shutdown/01.webp","alt":"10.2RMB 的 USB 串口继电器模块","title":""},{"url":"https://pic-lrc-bed.haf208.cc/img/extra/nas-auto-shutdown/02.webp","alt":"模块控制参数","title":""},{"url":"https://pic-lrc-bed.haf208.cc/img/extra/nas-auto-shutdown/03.webp","alt":"USB 串口继电器模块","title":""}]
连接好后,Armbian里可以看到连接的 CH340:
然后接线
[{"url":"https://pic-lrc-bed.haf208.cc/img/extra/nas-auto-shutdown/04.webp","alt":"线已接好,同时也并联了机箱开关","title":""},{"url":"https://pic-lrc-bed.haf208.cc/img/extra/nas-auto-shutdown/05.webp","alt":"线已接好,同时也并联了机箱开关","title":""}]
机顶盒端脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 # systemd: /etc/systemd/system/wakeup-server.service [Unit] Description=Wake up server Wants=network-online.target After=network-online.target nss-lookup.target [Service] Type=exec User=root ExecStart=/usr/local/ping_wol_open.sh [Install] WantedBy=multi-user.target
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 #!/usr/bin/bash set -o nounsetset -o pipefailsleep 90server='192.168.1.5' retry_count=0 log_file='/var/log/wol_wake.log' function date_time () { date "+%Y/%m/%d %H:%M:%S" } function ping_server () { ping -c 2 $server > /dev/null } function open_server () { echo -ne '\xa0\x01\x01\xa2' > /dev/ttyUSB0 sleep 0.2 echo -ne '\xa0\x01\x00\xa1' > /dev/ttyUSB0 } function main_func () { ping_server if [ $? -ne 0 ]; then sleep 20 ping_server if [ $? -ne 0 ]; then open_server retry_count=1 echo "[`date_time`] Waking up server..." >> $log_file sleep 60 fi while true do ping_server if [ $? -ne 0 ]; then if [ $retry_count -eq 2 ]; then echo "[`date_time`] Server maybe stuck, try force shutdown..." >> $log_file echo -ne '\xa0\x01\x01\xa2' > /dev/ttyUSB0 sleep 5 echo -ne '\xa0\x01\x00\xa1' > /dev/ttyUSB0 sleep 10 fi if [ $retry_count -eq 3 ]; then echo "[`date_time`] Server maybe down..." >> $log_file exit fi open_server retry_count=`expr $retry_count + 1` echo "[`date_time`] Server maybe off, retrying...($retry_count )" >> $log_file sleep 60 else echo "[`date_time`] Server is stared." >> $log_file retry_count=0 break ; fi done else retry_count=0 fi } while true ; do main_func && sleep 300; done
服务器端脚本(机顶盒需开启 http 服务,然后 index.html 里的内容为 “status-ok”):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 #!/usr/bin/bash set -o nounsetset -o pipefailserver='192.168.1.6' retry_count=0 log_file='/var/log/http_shutdown.log' function date_time () { date "+%Y/%m/%d %H:%M:%S" } function get_status () { curl -A 'Manjaro' -s -m 1 $server } function main_func () { if [[ `get_status` == "status-ok" ]]; then retry_count=0 else sleep 30 if [[ `get_status` == "status-ok" ]]; then exit fi shutdown 10 echo "[`date_time`] If power not resume in 10 mintunes, server will shutdown!" >> $log_file while true do if [[ `get_status` != "status-ok" ]]; then retry_count=`expr $retry_count + 1` if [[ retry_count -gt 25 ]]; then poweroff && sleep 2 && break ; fi echo "[`date_time`] Power maybe off, retrying...($retry_count )" >> $log_file sleep 30 else shutdown -c echo "[`date_time`] Power resumed to OK! Shutdown Canceled." >> $log_file retry_count=0 break ; fi done fi } ps -aux > .pstmp if [[ `cat .pstmp | grep -c http_shutdown.sh` -gt 1 ]]; then rm -f .pstmp echo "Another one is running, exit." exit fi rm -f .pstmpmain_func