This post is the second part of a series of posts which detail building an Internet-of-Things (IoT) server with flask, Python and ESP8266 microcontrollers. In this post, we'll describe server setup and microcontroller hardware used in the project.
This flask IoT server project builds upon the ESP8266 WiFi weather station project and the flask app on Digital Ocean project. In the flask app on Digital Ocean project, a flask app pulled a measurement temperature down from ThingSpeak.com and displayed the temperature on a webpage. In the ESP8266 WiFi weather station project, an ESP8266 microcontroller (connected to a temperature sensor) posted the temperature up to ThingSpeak.com. The problem with using ThingSpeak.com as an IoT platform is there are limits to how often data can be posted. Building my own IoT server with flask is an exciting and interesting project and solves the "only one data post every 15 seconds" limitation imposed by ThingSpeak.
Previously, I built a single page flask app that displays the temperature measured by WiFi weather stations. That single page flask app is running on a Digital Ocean cloud server. The flask app pulls a temperature data point using the ThingSpeak.com web API and displays the temperature on a webpage using flask and a jinja template. See the flask app hosted on Digital Ocean post to see the starting point for this project's flask IoT server.
If you are starting from scratch, the prerequisites needed to build an Internet-of-Things server with flask, Python and ESP8266 microcontrollers are:
- A Digital Ocean cloud server (just called the server from here on out). See this post and part of this post.
- A domain name hooked up to the server. See part of this post.
- PuTTY or a terminal that can SSH into the server
- A non-root sudo user on the server. See part of this post.
- The following packages
apt-getinstalled on the server:
- A Python 3.6 virtual environment set up on the sever with
pip installed. See part of this post.
- uWSGI and NGINX installed on configured on the server. See part of this post.. The configuration files I used can be found on github: myproject.ini, wsgi.py, sites-avialable (nginx config)
- The flask app running as a system service. See this gist for the systemd flaskapp.service file.
- SSL attached to the domain name and NGINX instance. See part of this post and this post.
The final web page produced by the flask app is below:
The below is a list of hardware used to build the ESP8266-based WiFi weather stations. See this post and the Fritzing sketch below for hardware setup.
- Adafruit Feather Huzzah ESP8266
- MCP9808 temperature sensor, BMP280 temperature sensor
- jumper wires, breadboard
- microUSB cable.
- Micropython firmware for the ESP8266 loaded on the ESP8266 board. See this post.
- The following .py files (available on github) were loaded onto the board with ampy: BMP280.py, MCP9808, wifitools.py. See this post.
Note that as part of this project, I'm using two ESP8266 microcontrollers. One ESP8266 is connected to a BMP280 temperature sensor and the other ESP8266 is connected to an MCP9808 temperature sensor. These two temperature sensors are leftover from previous projects (I would have used two of the same sensor, but one BMP280 and one MCP9808 is what I have lying around).
One ESP8266-tempsensor combo is used to measure the temperature outside, the other ESP8266-tempsensor combo is used to measure the temperature inside.
The starting place
The flask app I built was relatively basic and mainly comprised of 2 files: flaskapp.py and index.html. The file structure on the Digital Ocean server looks like this:
~/ └── flaskapp ├── flaskapp.ini ├── flaskapp.py ├── flaskapp.sock ├── flaskappenv ├── templates │ ├── index.html └── wsgi.py
The main file to run the flask app is flaskapp.py
# flaskapp.py from flask import Flask, render_template import requests app = Flask(__name__) @app.route("/") def index(): r = requests.get('https://api.thingspeak.com/channels/254616/fields/1/last.txt') temp_c_in = r.text temp_f = str(round(((9.0 / 5.0) * float(temp_c_in) + 32), 1)) + ' F' return render_template("index.html", temp=temp_f) if __name__ == "__main__": app.run(host='0.0.0.0')
The only jinja template used by the flask app to build web pages was in the
/templates directory and named index.html:
With the flask app created and the domain name, nginx, uWSGI, systemd and SSL configured- the app is started on the server with:
$ sudo systemctl start flaskapp $ sudo systemctl status flaskapp # [ctrl-c] to exit.
The resulting web page looks like this:
This post detailed the server setup and microcontroller hardware used in our IoT server with flask and Python project. The server running on Digital Ocean has a domain name connected to it and is running a nginx → uWSGI → flask web stack. The flask app currently returns a webpage with a temperature pulled from ThingSpeak.com. The hardware includes two Adafruit Feather Huzzah ESP8266 microcontrollers connected to temperature sensors.
In the next post, we'll build a web API with flask and push temperature values up to our very own IoT server.