I'm working on a project to display data collected on a raspberry pi on a dashboard style screen.
I have been using flask, as it seemed like the most simple & lightweight framework for what I wanted to do. The system is built such that upon entering the LXDE, the flask web server is initialised, and chromium is opened in kiosk mode to display the data. When the page is requested, this triggers the measuring script which logs the data into a database using SQLAlchemy for flask. The view then queries the database, plots the data to 4 different charts using matplotlib then exports them as a PNG which is converted to a bytestream and passed into the HTML. There is then a section in the HTML template which triggers the view to reload after 30 seconds.
Having tested this, it runs well for maybe a dozen iterations, then the UI becomes increasingly slow with each iteration and ultimately freezing. I'm not sure what is causing this, whether it be filling a cache or something? Has anyone had any experience with this in the past? Any ideas what is causing it or how to fix it?
Running Flask 0.12 on Raspbian Jessie
Flask view (with just one plotting function:
def dayplot():
locations = ['Circuit 1', 'Circuit 2', 'Circuit 3']
fig, ax = plt.subplots()
now=datetime.datetime.now()
then=now + datetime.timedelta(days=-1)
for location in locations:
data = models.PowerLogging.query.filter(models.PowerLogging.loc==location).filter(models.PowerLogging.timestamp>then).all()
ts = [record.timestamp for record in data]
power = [record.power for record in data]
ax.plot_date(ts, power, '-', label=location)
plt.title('Energy use in the last 24 hours', {'fontsize': 24, 'horizontalalignment': 'center', 'verticalalignment': 'bottom'})
plt.ylabel('Power Consumption (kW)')
plt.legend()
plt.xlim([then, now])
fig.autofmt_xdate()
fig_img = fig_to_png(fig)
return fig_img
def fig_to_png(fig):
fig_stream = StringIO.StringIO()
fig.savefig(fig_stream, format='png')
fig_stream.seek(0)
return base64.b64encode(fig_stream.getvalue())
@app.route('/')
@app.route('/index')
def index():
measure()
plot1 = barplot()
plot2 = dayplot()
plot3 = weekplot()
plot4 = pieplot()
act1 = checkactive('Circuit 1')
act2 = checkactive('Circuit 2')
act3 = checkactive('Circuit 3')
now = datetime.datetime.now()
return render_template('index.html',
title='testpage',
plot1=plot1,
plot2=plot2,
plot3=plot3,
plot4=plot4,
act1=act1,
act2=act2,
act3=act3,
now=now)
JS autoreload:
<script>
<!--
function
timedRefresh(timeoutPeriod) {
setTimeout("location.reload(true);",timeoutPeriod);
}
window.onload =
timedRefresh(5000);
// -->
</script>
HTML:
<div class="container">
<div class="row">
<div class="col-sm-12">
<h1>Unit 15 Energy Use Dashboard</h1>
Last Updated: {{ now }}
</div>
<div class="row">
<div class="col-md-4 box">
<img class="image" src="data:image/png;base64,{{ plot1 }}">
</div>
<div class="col-md-4 box">
<img class="image" src="data:image/png;base64,{{ plot4 }}">
</div>
<div class="col-md-4">
<!--img src="data:image/png;base64,{{ plot3 }}" width="400"-->
<h1>Circuit 1: {{ act1 }}</h1>
<h1>Circuit 2: {{ act2 }}</h1>
<h1>Circuit 3: {{ act3 }}</h1>
</div>
</div>
<div class="row">
<div class="col-md-4 box">
<img class="image" src="data:image/png;base64,{{ plot2 }}">
</div>
<div class="col-md-4 box">
<img class="image" src="data:image/png;base64,{{ plot3 }}">
</div>
<div class="col-md-4 box">
</div>
</div>
</div>