3

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>
  • you might want to add some code - sounds to me like you are flooding the DOM with dynamic content – Gotschi Mar 29 '17 at 8:42
  • Frankly, I don't see how someone can remotely debug your system for you. – Dmitry Grigoryev Mar 29 '17 at 11:19
  • What process consume increasing amount of some system resources? browser? Server? Something different? – Misaz Jul 22 '17 at 20:24
1

This is just a WAG (Wild-A**-Guess) based on seeing resource consumption issues in the past that behave similar to your description...

The following code looks like it is used to generate PNG images, but I never see any type of cleanup to release the memory/resources used by those images:

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())

Maybe this is a memory or other resources starvation issue? The app runs fine until memory is used up, then it has to start swapping (which is REALLY slow)?

Just something to look at - could be this, or a bunch of other stuff. You might want to start by checking the memory utilization on the device while it runs your code. If it shoots up fast, that may be the issue.

Good Luck, and if it is a memory use issue, please reply to let us know!

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.