Raspberry pi 控制Unraid/PC远程开机
需求
由于住的破地总断电,导致NAS断联。NAS机器是自己用普通电脑配件胡乱拼的,系统用的unraid
。最精彩的是主板BISO选项里有来电自启功能,但是经过测试,根本不好使,shit。
我的需求很简单,不管人在哪都能打开Unraid。
方案
最简洁的方案,使用WakeOnLan
,即网络唤醒技术,让被唤醒的电脑在不开机的情况下,通过网卡或路由器发送唤醒包,让主板或电脑开机。
OpenWrt里有一个wakeonlan插件,python有一个wakeonlan库,都可以直接使用。你猜到了,我的主板唤不醒啊,睡死了,Fuxk。其实,某宝有卖一种pci开机硬件,这种不用想了,直接淘汰。
简单的方法不行,只能杀鸡用牛刀了。树莓派是来电自启的,而且本博客跑在这上,常年开机。

翻箱倒柜找到几年前买的传感器大集合。
猜猜我这个大情种要用哪个?

你也许猜到了,没错,Relay,又叫继电器。
连接方式见图:

我这堆东西目前生存环境相当恶劣。开始在电脑房,而后去了洗衣房。为啥,吵死了,Shit,从没想过一个破铁盒子这么烦人。
PS. raspberry pi连接的那个野外露出硬盘是下载盘,为寂寞的夜晚。。。咳咳
继电器连线
继电器由树莓派供电,两个电源线,一根控制线。我忘了是哪两根了,也懒的看,后面都有+/-标记。树莓派用pinout命令。
出来的两根线接到主板的开机跳线上。我是把原有的跳线皮撸了,接了个三通。
当树莓派给信号的时候,继电器把输出端导通,相当于按下按钮。
最后上主菜,纯手撸代码,ChatGPT滚粗
俺做了一个简单网页,网页上就一个大按钮。当pi检测到机器没开机的时候,红色按钮可以点击;当pi检测到机器已开机,只显示绿色大按钮,就下图这样子。

pi_knockup_nas.py
import RPi.GPIO as GPIO
import time
import subprocess
from flask import Flask, request, jsonify, render_template
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
unraid_host = "unraid.lan"
GPIO_NUM = 18
def is_machine_powered_on():
try:
result = subprocess.check_output(["ping", "-c", "1", unraid_host])
return "1 packets transmitted, 1 received" in result.decode()
except subprocess.CalledProcessError:
return False
def poweron():
if is_machine_powered_on() == False:
GPIO.output(GPIO_NUM, 1)
time.sleep(1)
GPIO.output(GPIO_NUM, 0)
time.sleep(120)
if is_machine_powered_on():
return True
else:
return False
else:
return True
app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False
is_endpoint_enabled = True
@app.route('/unraid/poweron', methods=['GET'])
def unraid_poweron():
global is_endpoint_enabled
if is_endpoint_enabled == True:
is_endpoint_enabled = False
result = poweron()
is_endpoint_enabled = True
if result == True:
return jsonify({"state":"ok", "result":"开机完成!"})
else:
return jsonify({"state":"ok", "result":"开机失败!"})
else:
return jsonify({"state":"pending", "result":"正在开机..."})
@app.route('/unraid/powerstatus', methods=['GET'])
def unraid_powerstatus():
if is_machine_powered_on():
return jsonify({"state":"ok", "result":"on"})
else:
return jsonify({"state":"ok", "result":"off"})
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8999, debug=True)
templates/index.html
<!DOCTYPE html>
<html>
<head>
<title>Unraid 开机</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
<button id="p_button" class="power-button" onclick="powerOn()"></button>
<script>
var button = document.getElementById("p_button");
function powerOn() {
fetch("/unraid/poweron")
.then(response => {
if (!response.ok) {
throw new Error("Network response was not ok");
}
return response.json();
}).then(data => {
console.log(data);
}).catch(error => {
console.error("Fetch error:", error);
});
};
checkUnraidStatus()
function checkUnraidStatus() {
fetch("/unraid/powerstatus")
.then(response => {
if (!response.ok) {
throw new Error("Network response was not ok");
}
return response.json();
})
.then(data => {
if (data.result === "off") {
button.style.backgroundColor = "#df1648"
button.textContent = "开机"
}
if (data.result === "on") {
button.style.backgroundColor = "#44ed0c"
button.textContent = ""
}
})
.catch(error => {
console.error("Fetch error:", error);
});
}
setInterval(checkUnraidStatus, 5000)
</script>
</body>
static/css/style.css
.power-button {
width: 30vw;
height: 30vw;
min-width: 100px;
min-height: 100px;
background-color: #353834;
border: 2px solid #357934;
border-radius: 100%;
color: white;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 9px #999;
}
.power-button:active {
box-shadow: 0 5px #666;
transform: translate(-50%, -49%);
}
访问树莓派8999端口,网页出现脸大的红按钮。
当点击大大的红色按钮,听到继电器发出(哒。。。哒)两声,电脑开机,我不知道你,反正我飞升了。
有时间好好说说我这套Pi+unraid组合。经过一段时间折腾,这套系统对于我来说已经趋于完美。
PS. 还剩3T空间,还能挺俩月。硬盘最近涨价了,Fuxk。
外网访问Pi
这一条忘了,要想从任何地点访问pi,方法很多。一言以蔽之,本人借助魔法V屁N的魔力连接到的家庭内网。看下面这里有说。
One more thing
配置脚本为系统服务,实现自启动
/etc/systemd/system/unraid_api.service
[Unit]
Description=unraid api service
After=network.target
[Service]
ExecStart=/usr/bin/python -u /home/god/Documents/unraid/pi_knockup_nas.py
WorkingDirectory=/home/god/Documents/unraid
StandardOutput=inherit
StandardOutput=inherit
Restart=always
User=god
[Install]
WantedBy=multi-user.target
systemctl reload/enable
等命令使其生效。