2015-08-14 3 views
2

Я использую MongoDB для хранения сенсордат (1 измерение/сек.), И я хотел бы использовать флягу и боке для построения данных в реальном времени в веб-браузере. К сожалению, мои знания в отношении веб-фреймворков не так уж хороши. До сих пор мне удалось создать статический график, который считывает данные из базы данных (см. Пример ниже) Что было бы лучшим способом обновить сюжет в реальном времени?Нанесение данных в реальном времени с помощью фляжки и боке

from flask import Flask 

import datetime 
from pymongo import MongoClient 
from bokeh.templates import RESOURCES 

from bokeh.plotting import figure 
from bokeh.resources import CDN 
from bokeh.embed import file_html 

app = Flask(__name__) 

@app.route('/') 
def index(): 
    client = MongoClient() 

    db = client.test 
    sdata = db.sensordata 

    output = list(sdata.find()) 

    temp = [x['temperature'] for x in output] 

    get_time = lambda x: datetime.datetime.strptime(x['time'], '%Y-%m-%d %H:%M:%S') 
    time = [get_time(x) for x in output] 

    humidity = [x['humidity'] for x in output] 
    plot = figure(x_axis_type = "datetime") 
    plot.line(time, temp) 
    plot.line(time, humidity) 

    html = file_html(plot, CDN, "my plot") 

    return html 

if __name__=='__main__': 
    app.run(host='localhost', debug=True) 

EDIT:

Я думаю, что решение с колбой-socketio было бы хорошо, но им еще не знает, как это сделать. Чтобы вставить график, мне нужно создать скрипт и div с script, div = components(plot) (http://bokeh.pydata.org/en/latest/docs/user_guide/embed.html) Итак, скрипт помещается в заголовок html, когда div помещается в тело. Я не вижу, как обновлять данные, поскольку он хранится внутри файла сценария в заголовке, а не в div. Моя идея в том, чтобы изменить HTML в DIV с:

<script type="text/javascript" charset="utf-8"> 
    $(document).ready(function(){ 
     //connect to the socket server. 
     var socket = io.connect('http://' + document.domain + ':' + location.port + '/'); 

     socket.on('plotupdate', function(msg) { 
      $('#plot').html(msg.plot); 
     }); 

    }); 
</script> 

Но это не работает в этом случае.

ответ

3

Вы можете использовать setInterval javascript, используя вызов ajax, чтобы обновить только div, содержащий сюжет. Измените свой маршрут на что-то вроде «/ plotIt». Отображение кода с помощью JQuery для повторного вызова Ajax освежающего DIV с идентификатором = атрибутом «myPlot»:

setInterval(function() { 
     $.ajax({ 
     url: "/plotit", 
     type: "GET", 
     dataType: "html", 
     success: function (data) {$('#myPlot').html(data);}, 
    }); 
}, 60*1000); // Repeat interval is in milliseconds 

Не проверял этот код, но он должен работать нормально или с небольшой настройкой.

Я обычно не большой поклонник повторных заданий, подобных этому, и предпочитаю более ориентированный на события подход. А именно, используя прослушиватель событий для новых данных датчика (прослушивание на mongodb) и нажатие нового графика (используя, например, flask-socketio) при создании нового графика. Выберите подходящий для вас подход. Выше код должен, по крайней мере, начать.

+1

если ответ выше удовлетворительный-принимаем. Вы можете опубликовать новый вопрос, связанный с приложением socketio/real-time, вместо того, чтобы редактировать этот вопрос, чтобы предотвратить путаницу со стороны будущих читателей. –

Смежные вопросы