Control a lamp with a Raspberry PI using a Webpage

If you landed here, this is part two of a three parts tutorial on how to control a lamp using a Raspberry PI and a relay – this part uses Flask (a web framework for Python) to control the lamp (by controlling the relay).

Here are the other parts of the tutorial:

Web Server

Having a loop to activate or deactivate a relay is neat (Part one of the tutorial), but not very functional. What we want is something that lets us turn on or off the light when we wanted.

Lets create a very basic web app that will allow us to do just that.  Because of processing power constrains, we’re going with Flask for the web pages and Nginx for the web server.

Install the necessary software

We’re going to install this in a virtual environment. It’s has a lot of benefits and allows us to keep everything separated (you later can use this Raspberry PI to create another web app in a different environment and no harm will come to this one).

For Python3

NOTE: If you check out the code on my github account, the following steps are not necessary, EXCEPT CREATING THE VIRTUAL ENVIRONMENT. After that, you can go straight to Configure Nginx.

If you downloaded the code from, just see if everything is working with:

If you get something along the following lines:

and can browse to http://<RPi_ip>:8080 and see a light, then everything is working fine. Go to configure Nginx

Now, let’s create the web application.  Create a directory where we’re going to put all the files (don’t need if you checked out the code – directory is already created).

Now, let’s create the virtual environment and activate it. Let’s create it in a directory called venv (you can named anything you want)

Our virtual environment will be in a directory called venv. Everything will be separated – virtual environment and Flask app

For Python3

Activate it

Once inside the virtual environment (you notice because the word (venv) is preceded of the current path:

( venv ) pi@raspberrypi:~/lightup

If you ever want to get out of the virtual environment, just type deactivate and it will exit.

If you ever mess things up with the virtual environment, just delete the venv directory (or the name you gave it) and start all over again

We need to install the necessary libraries. Even if already installed on the system, we need them in our virtual environment. And, we don’t need sudo 🙂

NOTE: Installing uwsgi will take some time, because it is being compiled on the PI and pip will download any dependencies for flask

Now, let’s create the application. For starters, just a typical Hello World to see if everything works. Open your favorite editor (I do love Vim) and start typing.


Close and save the file.

To run it:

In a browser, just type your RPi IP address and specified port (in this case 8080):

Great, it works !

Now, let’s add some functionality and turn on and off the llight

Change the code and add some routes

Now, run it again:

In a browser, put the following URL to turn the light on


and to turn the light off


Flask CODE

What’s happening in the code is, very short version:

We start by importing the Flask class.

Next, we create an instance of the class. First argument is the name of the application. Since we’re using a single module, we’re using __name__.

Next, we use the route() decorator so Flask will know what URL will trigger the application.

The function is given a name which is also used to generate URLs for that particular function and returns a message to the user.

Add some functionality

Now that we now that it works, let’s make it more user friendly using some templates and some buttons.

Create a directory to hold the template for our webpage

Put the following code in int:

Now, return to the root of the application and change the file

What we’ve done was to add some dynamic content to our web server.

Run the application with:

Open a browser and put the url of the pi:


Hurray ! We got our self’s a neat web application to control a light…

Flash code

We now started to render templates with flask.  Flask uses Jinja2 for that.

To render a template, we use the render_template() method. Just give the name of the template and any variable we wish to pass to the template – we do and it is called pin.

Flask will look for the template in the templates directory (that we’ve created above).

Inside the template, we use {% %} to put some Python code within and check the pin value, to change the button value accordingly.


Now, we have a beginning of a web application, only that… it’s ugly.. Let’s make it hansom !

Skeleton is a CSS boilerplate with support for desktop and mobile layouts. We’re going to use it to give a great face to our webpage.

Go to and download a copy.

Create a folder named static in the root of the application folder.  The result should be this:

Copy the file (at this date, the file is  to the Raspberry PI and move it to the folder static.

Unzip the file. It should have been created a Skeleton-2.0.4 folder with other folders inside.

We need now to move those folders to the static folder and remove the Skeleton-2.0.4 folder.

Now, remove the and the Skeleton-2.0.4 folder. We’re going to have two folders and our lights.html

We’re going to create a html file to be used as a header for our lights.html as well others that we might create.

create a file, named header.html and put the following code in there

Now, edit the file lightup.html and change the code to be:

Now, if we execute the application and check the browser, we’re already going to see some differences.


What we’ve used here is something called Template Inheritance. We’ve build a base skeleton (header.html) that contains all the common elements. If we had more than one page (we only have lights.html) putting the common things in the same place will save code and make things more clean.

The {% extends %} tag is key. It tells the template engine that it will extend another template, in this case  header.html.

{% block content %} in the header.html will be replaced by our code between {% block content %} inside the lights.html file.

Now, let’s add a last fancy detail.

Go to the static folder.  Create a new folder named js. We’re going to add a bit of javascript to the page using jquery.

Now, go to the templates folder

Edit the header.html file and add the following lines:

The lines above are needed for Flask to load jQuery. More info here.

The complete file should be:

What we’re going to do is to show a light bulb image lit when LED on and Off when LED off, removing the message.

Now, just edit the lights.html file and change the code:

Start the application with Python3 and refresh the browser page



Nginx to serve Flask using uwsgi

Now that we have the application terminated, let’s configure Nginx to serve a Flask application

Configure nginx

Before serving anything, Nginx must be installed and configured.

Install Nginx

Because this is a Raspberry PI and we don’t need a lot of things, let’s install the light version of Nginx

sudo apt-get install nginx-light

First, we need to remove the default configuration of sites-enabled (because we’re going to write our own). This is just a symlink, so, remove it:

Now, create a new configuration for nginx. In the directory of our application, create a new config file for nginx:

vi lightup_nginx.conf

Create the symlink for this configuration at nginx

Restart nginx to make the configuration effective:

Now, create the uwsgi configuration file.

vi lightup_uwsgi.ini

Some things to notice:

the app name must match the file name of our application, in this case

Now, let’s try to start the uwsgi daemon:

Now, type the address in the browser (without the port this time)

If you run into problems, check the log files (you have from nginx in /var/log/nginx/error.log and the one from the lightup_uwsgi.log in the app directory).

Now that everything is working, we just need to start the uwsgi instance at boot. Since the latest versions of Raspbian use systemd, let’s create a unit

Go to /etc/systemd/system and create a new unit file, ending in .service

sudo vi lightup.service

Now, save and start the unit

You can check if it’s running, by issuing

Just open your browser and type the Raspberry PI URL and see everything is working.

Now, to make it start at every reboot, just enable it

And see if Nginx is also starting on boot

Reboot your PI and after a while, refresh your browser and see if it loads the page

Here’s the setup, with a LAMP instead of the LED

NOTE: Working with electricity is very dangerous and you must know what are you doing.  Always disconnect the lamp from the mains power before doing something in the relay..

Don’t touch the relay when the lamp is connected to the mains power. You’re the sole responsible if something goes wrong…

Just for information, the wire that’s connected to the relay is the phase, the brown one – at least here in Europe.



Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.