0

I have a route in Flask which serves an event-stream:

@app.route('/input/<string:blah>')
def index(blah):
    def generate_random_data():
        while True:
            r = random.random() * 100
            yield "~ %s\n" % r
            time.sleep(1)
    return Response(generate_random_data(), mimetype='text/event-stream')

Every second this streams a line like ~ 12.1293192 to the ESP8266 which I wish to display on the dot matrix screen`. However when using the following loop to update the display:

while(client.available()){
  String line = client.readString();
  Serial.print(line);
  //
  // PRINT TO DISPLAY
  //
  if (line.startsWith("~"))
  {
    display.setCursor(0,0);
    display.clearDisplay();
    display.print(line);
    display.display();   
  }
}

The serial monitor and display are never updated. Until I kill the flask server when the received data is output to the serial monitor in one go:

Requesting URL: /input/....................?private_key=....................&value=1
HTTP/1.0 200 OK
Content-Type: text/event-stream; charset=utf-8
Connection: close
Server: Werkzeug/0.15.6 Python/3.7.4
Date: Wed, 18 Sep 2019 15:14:08 GMT

~ 79.09144618182799
~ 20.39490758170851
~ 23.013417973706563
...

I'm convinced I'm missing a simple modification to the C code block which would support this. Perhaps my lack of C experience means I can't picture how to put this in a loop to constantly 'refresh' line based on data coming from the stream. Here is the full C program: gist link.

The display update code works, except for in this while loop. (earlier in code Display inited! is written to the screen).

I can provide more info if requested, as I am eager to get this working, and will post an answer if I solve it in the meantime :)


EDIT: I'm a bit further forward, having updated my flask function to send a more useful message to the ESP; I want everything between ~ and * to be echoed on the dot matrix screen, so the yield line becomes:

yield "~%s*\n" %  r

I found out it was easier to read individual characters and then build a line which can be echoed to the screen when the * char is received. Here is the updated C:

String line;
bool in_message=false;

  while(client.available()){
    char ch = client.read();

    if (ch == '~'){
      // We are in a message block
      in_message=true;
    }

    if (in_message == true && ch !='*' && ch !='~'){
      // if we're in the message and not a start/stop char:
      line += ch;
    }

    if (ch =='*'){
      // This is the end char, so print line to display
      // and clear the contents of line, until next * is 
      // received.
      display.setCursor(0,0);
      display.clearDisplay();
      display.print(line);
      String line; // clear the line
      display.display();
    }
  }

This code also ensures my control characters ~ and * aren't echoed to the screen.

(updated gist)

This works, however it is still making a new request to the server, every time the loop function finishes. I wish for a way to have this make the request once, and continuously read the stream, untill the server dies or there's another network problem at which point it will start making a new requests to the server.

  • 1
    I have no idea what this "flask" thing is you're talking about, or what that block of text at the top is supposed to mean - but if you want to do this kind of thing in PHP it's important to flush the output to force it to be sent to the client. Otherwise it just does it in one block when the output channel is closed. – Majenko Sep 18 at 15:44
  • @Majenko Flask is a python webframework, similar to PHP in this context. The stream is leaving flask, I can curl it, and it reaches the ESP. That's not the problem. If you check my update the actual problem is the C code makes many requests to the server, rather than making one request and continuously reading the stream. – v25 Sep 18 at 18:33
  • use websockets to "stream" data in discrete message events. or mqtt, but sockets is simpler... – dandavis Sep 18 at 19:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.