离目标越来越近了,这次使用flask在树莓派部署一个网站服务器,用户通过访问网页的形式,点击按钮向服务器发送点灯或者关灯的请求。
局域网模式
后端程序:
from flask import Flask, render_template, request, url_for, flash, redirect,abort
import json
import RPi.GPIO as GPIO
app = Flask(__name__)
def led(a):
if a=='Light The LED':
GPIO.output(40,GPIO.HIGH)
elif a=='Turn off The LED':
GPIO.output(40,GPIO.LOW)
return a
@app.route('/')
def index():
return render_template('index.html')
@app.route("/dataFromAjax",methods=['POST'])
def recv():
data = request.get_data()
json_data = json.loads(data)
print(json_data)
username = json_data.get("username")
print(led(username))
return render_template("index.html")
if __name__ == '__main__':
GPIO.setmode(GPIO.BOARD)
GPIO.setup(40,GPIO.OUT)
app.run(host='127.0.0.1',port=5000,debug=True)
前端部分关键程序:
<button id="showBtn" class="theme-btn dark" href="#" title="">Control The Raspberry</button>
<div id="popup">
<form action="/dataFromAjax" method="post"></form>
<button id="light_led" href="#" title="" value="light">Light The LED</button>
</form>
</div>
<script type="text/javascript">
function SendAjax(){
var username = led_Btn.textContent;
$.ajax({
url:"./dataFromAjax",
type: "POST",
contentType: "application/json;charset=utf-8",
data: JSON.stringify({"username":username}),
success:function(result){
alert(username);
},
error:function(){
alert("执行失败了...");
}
});
}
</script>
<style>
#popup {
width: 230px;
height: 230px;
text-align: center;
background-color: #f5d3d3;
/* 其他样式属性 */
display: none;
}
#light_led{
top: 50%!;
transform: translateY(50%);
background-color: grey;
}
</style>
<script>
function showPopup() {
var popup = document.getElementById('popup');
popup.style.display = 'block';
}
function hidePopup() {
var popup = document.getElementById('popup');
popup.style.display = 'none';
}
function showorhide(){
var popup = document.getElementById('popup');
if(getComputedStyle(popup,null)['display']=='none'){
popup.style.display = "block";
socket_onopen();
}
else if(getComputedStyle(popup,null)['display']=='block'){
popup.style.display = "none";
}
}
function led(){
var led_stats=1;
var light_led = document.getElementById('light_led');
console.log(light_led.textContent)
if(light_led.textContent=='Light The LED'){
light_led.textContent = "Turn off The LED";
light_led.style.backgroundColor = 'yellow';
light_led.value='off'
}
else if(light_led.textContent=='Turn off The LED'){
light_led.textContent= "Light The LED";
light_led.style.backgroundColor = 'grey';
light_led.value='light'
}
}
</script>
<script>
var showBtn = document.getElementById('showBtn');
showBtn.addEventListener('click', showorhide);
var led_Btn = document.getElementById('light_led');
led_Btn.addEventListener('click',SendAjax);
led_Btn.addEventListener('click',led);
</script>
应用post和AJAX方法,按钮按下以后使用json给后端传送数据,如果发送失败,会有弹窗反馈执行失败。由于前端相关知识浩如烟海,后面将单独讲解,本教程不再赘述。后端程序中,点灯操作与return至主界面,都为flask的常规操作,程序中的usrname与前端程序中的usrname(按钮的键值)对应,按钮按下后前端会使用post方法将键值传递给后端,后端通过判断,决定是点灯还是关灯。
内网穿透模式
终于到了最后一步,这一步我们需要提前准备一个云端服务器,我使用的是cpolar(极点云)。按照极点云提供的Linux部署教程一步步安装,安装完毕后,使用vnc viewer,打开树莓派的浏览器,输入127.0.01:9200,打开cpolar的WEB UI管理界面。
输入自己注册时候的账号密码
点击左侧仪表盘的隧道管理——创建隧道:
- 隧道名称:可自定义,注意不要重复
- 协议:http
- 本地地址:
- 端口类型:随机域名
- 地区:China vip
注意,这里的端口,还记得前面后端部分的端口吗?
这里的端口必须与flask的启动端口一致!比如我用的是5000端口,那么这边也必须填写5000。多说一句,内网穿透环节,flask的启动IP必须设置为‘127.0.0.1’。填写完毕后点击创建,隧道创建成功后,点击左侧的状态——在线隧道列表,可以看到刚刚创建的隧道已经有生成了相应的公网地址,将其复制下来,接下来测试访问一下。
将这个地址复制下来发给远方的朋友,他就可以控制你桌面上的LED灯了。本教程到此结束,纰漏之处还请大佬指导。