Wednesday, 3 July 2013

Step 3 - Google App for my Arduino sketch

Googles documentation on creating apps is very good. The link to get you started is here.
To get you started you initially write the html as strings in the main python file but it is much cleaner to keep your html separate using templates and that's what I ended up doing.

My app folder looks like this:

-- temp_monitor
    -- stylesheets
        -- main.css
    -- templates
        -- new_temperature.html
    -- app.yaml
    -- favicon.ico
    -- monitor.py


Note. If you don't add a favicon.ico file every time you deploy your app you'll get an error in the log which is really annoying but harmless. DeGraeve is a great website to create your own icon.

I got the stylesheet from csstablegenerator.com. Just make sure that the CSS Class Name is the same as the class name in your div in the html.

The dates are read and written in UTC and I could not find a really easy way to change the timezone to e.g. 'Europe/London'. Because I use DateTimeProperty(auto_now_add=True) the date is effectively a created_at timestamp that I don't have to insert manually, which is exactly what I wanted. It would be nice to have something like DateTimeProperty(auto_now_add=True, time_zone='Europe/London') but I'm not sure it's possible or I don't know how to implement it. If anyone has any ideas I'd really like to know. So I'm happy for now to keep it simple. This is a useful blog about timezones.

app.yaml


application: temp-monitor
version: 1
runtime: python27
api_version: 1
threadsafe: true

handlers:
- url: /favicon\.ico
  static_files: favicon.ico
  upload: favicon\.ico

- url: /stylesheets
  static_dir: stylesheets

- url: /.*
  script: monitor.application

libraries:
- name: webapp2
  version: "2.5.1"
- name: jinja2
  version: latest

monitor.py


import webapp2
import cgi
import os
import jinja2
import datetime
from google.appengine.ext import db
from google.appengine.ext.webapp.util import run_wsgi_app


class Temperature(db.Model):
temperature_field = db.StringProperty(required=True)
date_field = db.DateTimeProperty(auto_now_add=True)

class PostFromArduino(webapp2.RequestHandler):
    def post(self):
        temperature = self.request.get("temperature")
        self.temperature = Temperature(temperature_field=temperature)
        self.temperature.put()
        self.redirect('/')

class MainPage(webapp2.RequestHandler):

    def get(self):
      jinja_environment = jinja2.Environment(autoescape = True,
        loader = jinja2.FileSystemLoader(os.path.join(
         os.path.dirname(__file__), 'templates')))
      template = jinja_environment.get_template('new_temperature.html')

      temp_query = Temperature.all()
      temp_query.order("-date_field")
      #temp = temp_query.fetch(10)

      template_values = {
        'temperatures': temp_query
      }

      self.response.out.write(template.render(template_values))


application = webapp2.WSGIApplication([
    ('/', MainPage),
    ('/post_from_arduino', PostFromArduino)
], debug=True)

def main():
    run_wsgi_app(application)
if __name__ == '__main__':
    main()


templates/new_temperature.html


<!doctype html>
<html lang="en">
  <head>
  <link type="text/css" rel="stylesheet" href="/stylesheets/main.css" />
    <meta charset="utf-8"/>
    <title>Room Temperature Application</title>
  </head>
  <body>
    <h1>Room Temperature Application</h1>
    <div class='css_table'>
      <table>
        <tr>
        <td>Temperature ˚C</td>
        <td>Date</td>
        </tr>
        {% for temperature in temperatures.run(limit=10): %}
        <tr>
          <td>{{ temperature.temperature_field }}</td>
          <td>{{ temperature.date_field.strftime("%Y-%m-%d %H:%M:%S") }}</td>
        </tr>
        {% endfor %}
      </table>
    </div>  
  </body>
</html>

No comments:

Post a Comment