我试图了解Flask的工作原理。我按照这个例子:example 我能够启用和禁用系统。文本是动态更改取决于系统状态,而不是按钮。
我想从GPIO按钮和网络启用和禁用系统。 现在,如果我从Web启用系统,并从GPIO按钮禁用它,则Web上的按钮保持打开状态,因此我必须再次禁用它,然后启用它。
是否可以自动将按钮更改为ON(不是“系统已武装/撤防”文本,而是实际按钮)
我的代码是:
的index.html:
<!doctype html>
<head>
<meta name="viewport" content="initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.min.js"></script>
</head>
<style>
h3, h4 {text-align: center;}
span {font-weight: bold;}
</style>
<script type=text/javascript>
$(
// When the LED button is pressed (change)
// do an ajax request to server to change LED state
function()
{
$('#flip-1').change(function()
{
$.getJSON('/_led', {state: $('#flip-1').val()});
});
}
);
$(
// periodically (500ms) do an ajax request to get the button state
// modify the span tag to reflect the state (pressed or not)
// the state text comes from the JSON string returned by the server
function button()
{
$.getJSON('/_button', function(data)
{
$("#buttonState").text(data.buttonState);
setTimeout(function(){button();},500);
});
}
);
</script>
<!-- Simple JQuery Mobile page that display the button state on the breadoard -->
<!-- You can also change the LED state with the slider switch -->
<!-- The Raspberry Pi uptime is displayed in the footer (Jinja2 expands the template tag) -->
<div data-role="page" data-theme="b">
<div data-role="header">
<div><h3>Raspberry Pi Web Control</h3></div>
</div>
<div data-role="content">
<form>
<p>The system is <span id="buttonState"></span></p>
<br>
<select name="flip-1" id="flip-1" data-role="slider" style="float: left;">
<option value="off">Sys off</option>
<option value="on">Sys on</option>
</select>
</form>
</div>
<div data-role="footer">
<div><h4>This Raspberry Pi has been {{uptime}}</h4></div>
</div>
</div>
web.py:
from flask import Flask, render_template, request, jsonify
import test
app = Flask(__name__)
# return index page when IP address of RPi is typed in the browser
@app.route("/")
def Index():
return render_template("index.html", uptime=GetUptime())
# ajax GET call this function to set led state
# depeding on the GET parameter sent
@app.route("/_led")
def _led():
state = request.args.get('state')
if state=="on":
test.arm()
test.write1()
print test.read()
else:
test.disarm()
test.write0()
print test.read()
return ""
# ajax GET call this function periodically to read button state
# the state is sent back as json data
@app.route("/_button")
def _button():
if (test.read() == "1"):
state = "armed"
else:
state = "disarmed"
return jsonify(buttonState=state)
def GetUptime():
# get uptime from the linux terminal command
from subprocess import check_output
output = check_output(["uptime"])
# return only uptime info
uptime = output[output.find("up"):output.find("user")-5]
return uptime
# run the webserver on standard port 80, requires sudo
if __name__ == "__main__":
test.initialize_Output()
app.run(host='0.0.0.0', port=80, debug=True)
答案 0 :(得分:0)
jQuery有一个val()方法,可以获取和设置一个控件(这并不总是正确但通常是 - 请参阅http://api.jquery.com/val/以获取更多信息)。因此,我认为只要从服务器获得按钮状态,就需要使用val()来更新flip-1的值。
val()方法使用的值需要匹配select元素(在HTML中)中的选项元素的值属性。如果HTML中的状态值与Flask代码中使用的状态值相同,那么您的代码将是最简单的,因此我刚刚更新了HTML并保留了Flask代码。
<!doctype html>
<html>
<head>
<meta name="viewport" content="initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.min.js"></script>
<style>
h3, h4 {text-align: center;}
span {font-weight: bold;}
</style>
<script type=text/javascript>
$(function() {
// When the LED button is pressed (change)
// do an ajax request to server to change LED state
$('#flip-1').change(function() {
$.getJSON('/_led', {state: $('#flip-1').val()});
});
// periodically (500ms) do an ajax request to get the button state
// modify the span tag to reflect the state (pressed or not)
// the state text comes from the JSON string returned by the server
function button(){
var data = ajax_button('/_button');
// New line to update button state; and refresh the jQuery mobile slider widget
$('#flip-1').val(data.buttonState).slider('refresh');
$("#buttonState").text(data.buttonState);
}
button(); // Update state on page load
setInterval(button,500); // And then update every 0.5 seconds after that
});
</script>
</head>
<body>
<!-- Simple JQuery Mobile page that display the button state on the breadoard -->
<!-- You can also change the LED state with the slider switch -->
<!-- The Raspberry Pi uptime is displayed in the footer (Jinja2 expands the template tag) -->
<div data-role="page" data-theme="b">
<div data-role="header">
<div><h3>Raspberry Pi Web Control</h3></div>
</div>
<div data-role="content">
<form>
<p>The system is <span id="buttonState"></span></p>
<br>
<!-- Changed these option values to match the values returned by Flask -->
<select name="flip-1" id="flip-1" data-role="slider" style="float: left;">
<option value="disarmed">Sys off - disarmed</option>
<option value="armed">Sys on - armed</option>
</select>
</form>
</div>
<div data-role="footer">
<div><h4>This Raspberry Pi has been {{uptime}}</h4></div>
</div>
</div>
</body>
</html>
我改变了一些事情:
答案 1 :(得分:0)
结合Ben的答案和另一条线。我设法得到了我正在寻找的结果。 html文件上的脚本应如下所示:
<style>
h3, h4 {text-align: center;}
span {font-weight: bold;}
</style>
<script type=text/javascript>
$(
// When the LED button is pressed (change)
// do an ajax request to server to change LED state
function()
{
$('#flip-1').change(function()
{
$.getJSON('/_led', {state: $('#flip-1').val()});
});
}
);
$(
// periodically (500ms) do an ajax request to get the button state
// modify the span tag to reflect the state (pressed or not)
// the state text comes from the JSON string returned by the server
function button()
{
$.getJSON('/_button', function(data)
{
//Ben's line in order to change the slider's state
$('#flip-1').val(data.buttonState);
//The new line that makes the slider work depending on the state's value
$('#flip-1').slider('refresh');
$("#buttonState").text(data.buttonState);
// New line to update button state
setTimeout(function(){button();},500);
});
}
);
</script>
我不确定新行的作用,但我想它只是刷新滑块状态,以获得新结果。 谢谢你的帮助。对此,我真的非常感激。现在,我有一个可靠的解决方案,我可以继续添加按钮以获得更多功能。