Frederik Petri
Frederik Petri

Reputation: 481

Updating jquery with realtime sensor data through flask

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

Answers (1)

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

Related Questions