Running Python CGI Scripts from Javascript and JQu

2020-08-01 07:32发布

问题:

The workflow I'm trying to accomplish is as follows.

  • There is a jQuery Mobile UI with a bunch of range slider elements. Each one is for controlling a different function.
  • When a user moves and releases any one of these sliders, a jQuery event should be triggered that makes an AJAX call (I don't care if it uses JSON, XML, POST, etc - fastest is best)
  • The Ajax call contains info about what slider was moved, and what its new value is (ex: id=slider1, value=215)
  • The Ajax executes a python script in the CGI bin that reads the ID and value and controls some hardware connected to my Raspberry Pi via Serial (the Raspberry pi also running the webserver).

I have a JQuery UI with a bunch of sliders. Each slider code looks like this:

<div data-role="fieldcontain">
    <fieldset data-role="controlgroup">
        <div class="rgbw_label"><label for="red_slider">
            Red:
        </label></div>
        <input type="range" id="red_slider" name="red_slider" value="0" min="0" max="255" data-highlight="true" />
    </fieldset>
</div>

There needs to be some accompanying JQuery that does something like this:

 $(document).ready(function () {
$.ajax({
    type: "POST",
    url: "cgi-bin/command.py",
    success: function (msg)
    {
        alert("Data Saved: " + msg);
    }

    });

});

Obviously two major things have to change about the JS. First, it needs to execute when the slider is released (not on page load), and second it needs to actually pass the value of the slider to the Python script some how. I set it up like this just to test. When I load the page, this tester python script is executed correctly, and some hardware connected to the Raspberry Pi is controlled properly. I know I should be using the slidestop event, but I can't get it to work. I'm also not sure of what is the BEST way to send some variables to the python script.

My python script looks like this, right now: #!/usr/bin/python

import cgi

import serial
ser = serial.Serial('/dev/ttyUSB0', 57600)
ser.write("Hello, this is a command!\n")      # write a string
ser.close()

So, it's not looking for any kind of incoming data, it just gets called and writes some Serial data. It should be able to receive data from the AJAX call, and adjust the Serial writing command based on the info it receives. I need help getting that info into variables that I can work with. I assume I should also pass back some kind of "I'm done" message back to the JavaScript calling function.

I'm looking forward to any insight that folks might have on either high level issues, or ways to solve more specific problems that I've listed here.

Thanks!

回答1:

How about the following:

...
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.css">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.js"></script>
...
<div data-role="fieldcontain">
    <fieldset data-role="controlgroup">
        <div class="rgbw_label"><label for="red_slider">
            Red:
        </label></div>
        <input type="range" id="red_slider" name="red_slider" class="posting-slider" data-slider-id="1" value="0" min="0" max="255" data-highlight="true" />
    </fieldset>
</div>

With the following Javascript:

$(document).ready(function() {
    $('.posting-slider').on('slidestop', function(e) {
        $.post('/server/script.py', { id: $(this).data('slider-id'), value: e.target.value }, function(data, textStatus, jqXHR) {
            console.log('POSTed: ' + textStatus);
        });
    });
});

and finally, the python:

import cgi
form = cgi.FieldStorage()

import json

import serial
ser = serial.Serial('/dev/ttyUSB0', 57600)
ser.write("Hello, this is a command for value %s from slider id %s!\n" % (form["id"], form["value"]))      # write a string
ser.close()

print "Content-type: application/json"
print
print(json.JSONEncoder().encode({"status":"ok"}))