This post summarizes an effort to design a home automation system using Raspberry Pi 3. The goal was to turn on/off electrical appliances from any machine connected to wifi network.

There are various parts to this project

  1. Creating a local server and installing a database to store variables. Setting up virtual hosts and creating MySQL database entries for each light
  2. Php script to turn on/ off the lights
  3. Python script to toggle GPIO to turn on the relay.
  4. Wiring the lights via relays

Here is a working demo of the project

The source code for php, python code and the config settings for the virtual host is here

  1. Setting up NGINX server and MYSQL database on the Pi: This is a very good article to set up NGINX server, PHP and MySQL database on the Pi.
  2. Setting up your virtual host. I created a virtual host named Following are the steps to create and set up virtual host on the Pi.
    1. Create a directory in /var/www/ named and a directory public_html inside /var/www/ This is your root for the virtual host. All the html php and python files should reside in this directory.
    2. Go to /etc/nginx/sites-enabled and copy the “default” file. This file is created when you set up nginx. Rename this copied file as “”. This file will have all your config settings for the virtual host.
    3. In the file you created above, change the root to /var/www/ Change the server name to your wifi ip. (You can get this ip by using hostname -I command in the shell, or you can google “whats my ip”.)
    4. In the location {} section, also mention “allow ‘your wifi ip’; deny all;. This way you are allowing connections from any machine that is connected on your wifi. Other ips will be denied access. Read about restricting access on NGINX servers.
    5. Changing the host file on your pi: Then go to /etc/hosts file and add this virtual host in the file so that the server recognizes it.
  3. Creating entries for each light in MySQL database: Now that everything is set up, we will have to create two entries for “light1” and “light2” in the database, which will store the states of two lights we need to control. The python script (mentioned below) will query these states and toggle the lights accordingly. Good Article on Creating databases
    1. mysql -u root -p (Entering as a root)
    2. CREATE DATABASE home (Creating a database called home)
    3. USE home (Entering the database “home” for changing privileges etc.)

    4. create user ‘washingtonStreet’@’localhost’ identified by ‘washst’;

      create user ‘washingtonStreet’@’%’ identified by ‘washst’; (This creates a user with username washingtonStreet and password washst first for the localhost server. The second line make the user available to all the virtual servers (e.g here)

    5. grant all privileges on home.* to ‘washingtonStreet’@’localhost’ with grant option; 

      grant all privileges on home.* to ‘washingtonStreet’@’%’ with grant option;

      flush privileges;


      (This grants all the privileges to the created user for localhost anf all other virtual servers, flushes them and quits the database.)

    6. Now enter the database as the user and create your entries for light1 and light2
    7. mysql -u washingtonStreet -p (Entering as a user). It will prompt you for a password

    8. USE home (tell which database to use for this user)

    9. create table lights(name TEXT, value INT); (This will create a table named lights with two entries for each item: name and value. These values can be accessed by row[name], row[value] etc

    10. insert into lights values(‘light1’, 0); 

      insert into lights values(‘light2’, 0);


      (This will insert two entries for two lights and a default value of 0 (OFF) is assigned to them.

    11. Now your database home is set with user washingtonStreet and has a table with entries for two lights that you want to automate.
  4. Writing a PHP script: The php script will have two buttons, one for each light. I have used bootstrap to make it look beautiful and responsive. This script will open the database connection. When a button is pressed, it will query the database for the respective value of the light (light 1 or light 2 depending on which button is pressed). It will toggle the value and store the toggled value back into the database for future use. Then it will call a python script which ‘light1’ or ‘light2’ as the argument depending on which button is pressed.
  5. Writing the Python file: The python file will open the database connection and pull the value of the light whose argument is passed. (light1 or light2). Then it will set up the GPIOs and pass the value read to the GPIO pins. The Pi has a GPIO library which will turn the GPIO either high or low.
  6. Hardware wiring: I used 120V AC SainSmart relays for switching the lights on and off. These relays take a 5V and command signal from the Pi and turn on/off the switch accordingly. You can purchase the relay board on amazon which as all the amplifier circuits pre-built. The control signal (GPIO output) is amplified which triggers the switch. The relays are connected to the lights.
wiring diagram
Relay Wiring diagram
Mobile App To Control Lights


a) If PHP files are loading as blank, you will have to change a line in your conf file. Here is a good discussion on that: Blank PHP Files.

b) Always tail you error log while developing which tells you if there are any errors. to do that type sudo tail -f /var/log/nginx/error.log

c) To call python scripts from a webpage, correct permissions have to be given to www-data user. This is the user which executes the webpage. To give all the permisssions to this user add the following line to the sudoers file in /etc

cd /etc

sudo pico sudoers

 add … www-data ALL=(ALL) NOPASSWD: ALL. Save and exit

d) If you have not allowed ips of your wifi, you will not be able to access nginx server virtual hosts from anywhere except localhost.

e) In your conf file, if you give server_name as your virtual host (e.g then it will give error when accessing through external computer on the same wifi (even if you have allowed the ip of your external wifi). Instead you should mention server_name ‘your server ip’. Here it can ping the server, but unless the server_name is the ip (not the virtual host name, you wont be able to load the webpage.

server_name : server ip (

location / {allow client ip (; deny all;}

f) While loading the webpage, it won’t work if you load (even if that is your virtual host name and if you have correctly followed steps d and e). You will have to use your server ip to connect to the webpage. (e.g