Reputation: 481
I am trying to send realtime data from a sensor through flask to the front-end through jquery. Right now my script uses setInterval(..., 1000);
to update the data through a ajax request.
However, I would like to update the jquery request when new sensordata is received from flask, as the framerate from the sensor differ and its hard to set a specific interval to make it realtime.
Is it possible to use some kind of signal in the jquery code when new data is sent through @app.route('/data')
?
Python script:
from flask import Flask,render_template,url_for,request,redirect, make_response, session
import json
from bluepy import btle
from bluepy.btle import Scanner, DefaultDelegate
app = Flask(__name__)
@app.route('/', methods=["GET", "POST"])
def main():
return render_template('index.html')
@app.route('/data', methods=["GET", "POST"])
def data():
# Connect to sensor and get current data value (Bluepy stuff)
bluetooth_addresses = "d4:ca:3d:32:52"
periph = btle.Peripheral(bluetooth_addresses)
periph.writeCharacteristic(44, b"\x01\x00", withResponse=True)
data = periph.getData() # data is a single value (e.g 0.23)
# Keep receiving data from sensor when ready
# while True:
# if periph.waitForNotifications(1.0):
# data = periph.getData() # data is a single value (e.g 0.23)
response = make_response(json.dumps(data))
response.content_type = 'application/json'
return response
if __name__ == "__main__":
app.run(debug=True)
html:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Flask App </title>
<!-- Bootstraps Java Scipts Links -->
<link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap4.4.1.min.css') }}">
<script src="{{ url_for('static', filename='js/jquery3.4.1.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/popper1.16.0.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/bootstrap4.4.1.min.js') }}"></script>
</head>
<body>
<button type="button" class="btn btn-primary" onclick="start_button()" id="start_button">Start</button>
<script>
var start_button = function(){
$.get('/start',
function(){
function log_data() {
$.ajax({
type: "GET",
url:'/data',
dataType: 'json',
success: function (result) {
console.log(result);
}
});
}
timer = setInterval(log_data, 1000/15);
}
)
}
</script>
</body>
</html>
Upvotes: 2
Views: 268
Reputation: 611
For realtime data, use 'text/event-stream' MIME type
return Response(generate_random_data(), mimetype='text/event-stream')
or yield a server-side event (i used this type with the below snippet)
Here is part of a front-end snippet i used:
const source = new EventSource("/data");
source.onmessage = function (event) {
const data = JSON.parse(event.data);
// data.value is the realtime value
}
Upvotes: 1