The objective of this post is to explain how to serve HTML content from the MicroPython file system, on a Picoweb app. The tests were performed using a DFRobot’s ESP-WROOM-32 device integrated in a ESP32 FireBeetle board.
The objective of this post is to explain how to serve HTML content from the MicroPython file system, on a Picoweb app. You can check how to install Picoweb on the ESP32 and how to get started with it on this previous post. The present tutorial will be easier to follow if you have a previous knowledge about how Picoweb works.
For an explanation on how to read a file from the file system with MicroPython, check this post.
The successful execution of this tutorial assumes that the ESP32 was previously connected to a WiFi network, so we can later make requests using a web browser. You can check here how to do it.
The tests were performed using uPyCraft, a MicroPython IDE. You can check how to use uPyCraft in this previous post. Note that uPyCraft greatly simplifies the process of both running scripts and, in our case, uploading files to the file system.
The HTML code
As explained in the introductory section, we are going to serve some HTML content from a file in the MicroPython file system. Thus, we are going to create a very simple file called tables.html (you can name it how you like, as long as you use the correct name in the following section) and put there some simple HTML to render a table.
Note that this is just some very basic HTML code and thus, for simplicity, we are not respecting all the good practices of a well formatted HTML document.
<table> <tr> <th>sensor</th> <th>value</th> <th>timestamp</th> </tr> <tr> <td>temperature</td> <td>10</td> <td>10:00</td> </tr> <tr> <td>temperature</td> <td>11</td> <td>11:00</td> </tr> <tr> <td>luminosity</td> <td>11</td> <td>11:00</td> </tr> </table>
Note that if you are using uPyCraft, you can upload the HTML file the same way you would upload a script. The only difference is that uPyCraft will not try to run it afterwards. Don’t forget to use the correct .html extension when saving the file before uploading.
The MicroPython code
We start our code by importing the Picoweb module. Then, as usual, we create our app instance, passing as input a string with the name we want to give it.
import picoweb app = picoweb.WebApp("app")
For simplicity, we will just set one route to serve the HTML content. We will use the index route, which corresponds to “/”. On the handling function, we will then call the start_response method, passing as input the StreamWriter object that we received as second argument of the route handling function.
Although this is the default value, we will specify the content-type parameter as “text/html”, since this is the content-type we are going to serve. For more on how to specify the content-type returned in the response on a Picoweb app, please consult this previous tutorial.
@app.route("/") def index(req, resp): yield from picoweb.start_response(resp, content_type = "text/html") (...)
Next we will open the file in reading mode with a call to the open function, which receives as input the file name and the reading mode. We should use the name of the HTML file we previously uploaded which, in my case, was called tables.html. To specify the reading mode, we pass a ‘r’ string to the second parameter of the function.
htmlFile = open('tables.html', 'r')
After this we will then start reading the file from the file system line by line in a for in loop. For each line, we send its content to the client with a call to the awrite method of the StreamWriter object that our route handling function received.
for line in htmlFile: yield from resp.awrite(line)
To finalize, we call the run method for starting our app, passing as input the IP address we obtained when connecting to the WiFi network. You can check the final code below, which already includes this call.
import picoweb app = picoweb.WebApp("app") @app.route("/") def index(req, resp): yield from picoweb.start_response(resp, content_type = "text/html") htmlFile = open('tables.html', 'r') for line in htmlFile: yield from resp.awrite(line) app.run(debug=True, host = "192.168.1.87")
Testing the code
To test the code, simply upload the previous script for your ESP32 board and run it. If you are using uPyCraft, the script will run automatically. Then, access the URL that is printed on the MicroPython prompt. You should get an output similar to figure 1, which shows the webpage with our HTML rendered.
Figure 1 – Result of accessing the index route, displaying the HTML content of the file from the file system.
- ESP32 MicroPython: Changing the HTTP response content-type of Picoweb route
- ESP32 MicroPython: HTTP Webserver with Picoweb