Flask更改按钮状态动态

时间:2014-06-12 17:12:54

标签: jquery python flask

我试图了解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)

2 个答案:

答案 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>

我改变了一些事情:

  • 选择元素选项值从开/关更改为布防/撤防以匹配Flask状态值
  • 在html和body元素中添加到html
  • 将脚本和样式移动到head元素
  • 添加了.val()方法,根据从Flask通过AJAX传递的状态设置select元素的值
  • 将两个JavaScript $()函数合并为一个函数。 $()是一个jQuery简写,&#34;一旦加载了DOM就执行此代码&#34;
  • 使用setInterval()而不是setTimeout()https://developer.mozilla.org/en-US/docs/Web/API/window.setInterval

如果你想比较http://jsfiddle.net/LcBQ7/4/

,这是jsfiddle

答案 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>

我不确定新行的作用,但我想它只是刷新滑块状态,以获得新结果。 谢谢你的帮助。对此,我真的非常感激。现在,我有一个可靠的解决方案,我可以继续添加按钮以获得更多功能。