Herb Zhao Herb Zhao - 6 months ago 30
Ajax Question

Run command only once when request with .getJSON in Flask

I am trying to make a web interface which display the serial output from my Arduino using Pyserial. I am using Ajax ($.getJSON) to update my HTML string.

The problem I have now is that every time I request my JSON data, it also initialise my

ser = serial.Serial('/dev/cu.wchusbserialfa140',9600)
, which makes the query slow and prohibit real-time update of serial outputs.

my code are as following:

I am trying my best to only execute
serial.Serial()
once.

@app.before_request
def before_request():
g.status = False


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


@app.route('/result')
def serial_monitor():
#connect to serial port for once
if g.status == False:
ser = serial.Serial('/dev/cu.wchusbserialfa140',9600)
g.status = True
result = str(ser.readline())
voltage = {'value':result}
else:
result = str(ser.readline())
voltage = {'value':result}
return jsonify(voltage)


My javascript:
I am using
setInterval
to repeat it automatically.

$.getJSON($SCRIPT_ROOT + '/result', function(data)
{$('#voltage').text(data.value);});


I have been trying to learn to make my little web interface and Stackoverflow has been great help to me. I have searched and tried hard to solve this problem, but I think it is worth reaching out now.
Thank you all in advance !!




Edited:

I have hacked it a bit to make it do what I want to do for now.
However, I am planning to use a form to get the port value from user before running
serial.Serial
line. I am still looking at
session/global variable
route.

global ser
ser = serial.Serial('port',9600)


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


@app.route('/result')
def serial_monitor():
result = str(ser.readline())
voltage = {'value':result}
return jsonify(voltage)

Answer

The following was the solution I found.

By setting the global variable status correctly (inside the function), I can now run any code for once only.

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

status = False
@app.route('/result')
def serial_monitor():   
    global status
    #connect to serial port for once
    if status== False:
        ser = serial.Serial('/dev/cu.wchusbserialfa140',9600)
        status = True

    result = str(ser.readline())
    voltage = {'value':result}
    return jsonify(voltage)