1

I'm new to JavaScript and HTML in general so I may have some silly questions...

I'm using Flask to display a graph with some values from a sensor on a Raspberry pi3. The sensor is connected through a serial port. I want to pass the values I'm reading from the serial port to the index.html, that is the template where I have the javascript code for the graph (made with Rgraph).

This is the main.py with flask and the port reading.

from flask import Flask,render_template
import serial

app = Flask(__name__)
ser = serial.Serial('/dev/ttyACM0', 9600)

@app.route('/')
def hello_world():
return render_template("index.html")

#here I read one value from the serial port
@app.route('/getdata')
def test():
    return ser.readline()

if __name__ == '__main__':
    app.run()

The index.html template that I'm trying to use is this here (on github). The javascript generates some random number (from line 66 to 72) but I want it to read a number from the page '/getdata' instead and push that in the data array.

I thought about using the GET-POST methods but it gets quite complicated. Maybe there's an easier solution? Or, maybe (but I think it's impossible), I could read the serial port directly from the javascript? Or, maybe, I'm doing everything wrong and I need to throw everything out of the window?

mx0
  • 6,445
  • 12
  • 49
  • 54
  • If I get you correctly, hello_world() displays the page and test() returns the value you want to display? If that is the case, why don't you call the test() function directly (and collect the result) from within the hello_world() function? – Lukáš Říha May 17 '17 at 16:16
  • If you're fetching a number via GET or POST and then getting RGraph to display a chart using it - make sure you convert the string that you fetch to a real number before giving it to RGraph. eg var myNumber = parseFloat(myString); Though now that I mention it I think I've added auto-conversion - so it may not matter. – Richard May 17 '17 at 16:24
  • @LukášŘíha yes it's exacly what I'm trying to do but I cant' just call the function test from the index.html beacause it needs some parameters that are in my pc, not in the client side. – Asia Bergamini May 18 '17 at 14:10

2 Answers2

1

Once flask renders the template there is not much you can do. It doesn't really support push requests (at least not as far I can tell) but doing an Ajax request isn't hard

ajax_params = {
        url: '/getdata',
        type: 'GET',
        cache: false,
        dataType: 'json',
        error: function(jqXHR, status, error) {
            console.log("Ajax error " + error);
            console.log("status " + status);
            console.log(jqXHR);
        },
        success: datacb
    };

function datacb (resp, status, jqXHR) {
     /* update code here */
     console.log(resp);

     /* you may want to sleep here */

     $.ajax(ajax_params);
}

$.ajax(ajax_params);
dabhand
  • 517
  • 3
  • 10
  • But the problem is not with flask (kind of)... I want my index.html (that's basically just javascript) to read the value that test() is returning. The problem is that i cant just a ser.readline() from my script, so I need to read it from the main.py... I just don't know how to make themo communicate. – Asia Bergamini May 18 '17 at 14:15
  • in the axaj request above you will see that I sent it to the route that runs test, note the url. in the callback that is run after the request inside the "resp" variable will be whatever the server returned. in this case the contents of "ser.readline()" where I put the comment you can update the site and then make the same request again. I've editted the answer a bit to help with that – dabhand May 19 '17 at 15:24
1

Unless you want to update the data without reloading the index.html page, you might try something like the following:

from flask import Flask,render_template
import serial

app = Flask(__name__)
ser = serial.Serial('/dev/ttyACM0', 9600)

@app.route('/')
def hello_world():
    servalue = test();
    return render_template("index.html", value=servalue)

#here I read one value from the serial port
@app.route('/getdata')
def test():
    return ser.readline()

if __name__ == '__main__':
    app.run()

If you want to update the data without reloading the index page, you'll probably have to use AJAX, as @debhand suggested.

  • The problem is, I don't want to reload the page. The graph in Rgraph redraws itself every 0.5 second, so i just want it to read the value I'm printing from test() instead of a random number (as it is right now). – Asia Bergamini May 18 '17 at 14:07
  • @AsiaBergamini Then go with the solution by dabhand, that should work. – Lukáš Říha May 18 '17 at 14:47