Lab 4.3: Simple Smart Home

Overview

Smart house flat illustration conceptIn this lab we implement a simplified  home automation system  using  the Raspberry Pi  as a control unit that reads sensors data stream and control several units such as lighting, alarm system, door locks…etc. A realistic implementation would require multiple wireless sensors (connected to the controller using zigbee or wifi) that stream data from multiple locations to the Raspberry Pi server. However, due to the limited lab time, we sense the data directly from the Raspberry Pi through the GPI interface. More precisely, we will perform the following:

  • Connect an LED and DHT22 sensor (as we did in the previous lab) to the Raspberry Pi. The LED represents the lights in a smart home or an AC control unit.
  • Use a web server (Apache + CGI module)  as user interface through which users view sensor plots (namely, humidity and temperature) and switch on/off the LED.

The main emphasize in this lab is on using some very useful Linux tools and techniques  that can be used in many other situations as well.

We will mainly use the following linux tools.

  • Stream Editor (‘sed’ command): A command line tool that is used to edit text on the fly (either from a  stream through pipe or a file).
  • GNUPLOT: A command line tool that outputs professional plots in several formats. Many third party tools such as octave relay on gnuplot to output plots (Install gnuplot using apt-get in your Raspberry Pi).
  • Apache + cgi module to host a simple web page that show plots. (Install apache2 using apt-get).

We mention that there are better ways to present plots in a web, for instance, using Java script engine like AngularJS; however, the goal of most of lab series is to learn generic tools that can be used elsewhere.

Before starting, visit GNUPLOT site and run ‘man sed’ to have an overal idea about these tools.

Lab Objective

  1. We continue from the previous lab, where we wrote a loop that output Adafruit_DHT sensor readings. We append each reading to a file in a format  that is readable by GNUPLOT .  This procedure should run in background as a daemon (or server).
  2. GNUPOLOT is then reads the data and output two plots,  humidity and temperature, in PNG formats.
  3. Using cgi module in apache, whenever a user sends a GET request to  “http://127.0.0.1/index.cgi“,  a GNUPLOT script will generate the plots, and  then the cgi script prints some HTML that to view the PNG files properly; and an extra button that is used to toggle the LED.

Preparing Data for GNUPLOT using “sed” command

“sed” command, like many Linux commands, can read inputs either from a file or a  pipe “|”. The syntax of sed command is similar to that of the vim editor. We want to parse the output of :

which comprises of 3 lines; we want to output only the temperature and humidity values in one row separated by a tabulation (<tmp_val>\t<hum_val>).

To delete the first line,

Notice that we used a pipe to redirect the output of the first command to the input of the second. To delete the first and the second lines

Next, we  remove  “Temp =  ”

We use option ‘e’ when we have multiple  changes; “s” stands for Substitute ( ‘s/<pattern match>/<substituted text>/’ ).  The change order is captured by that of the sequence of  “-e” segments.  Space and special characters should be preceded by  backslash. You can continue with another expression until you obtain the desired format; Use  -e ‘s/\*C,\ Hum\ =/\t‘ to replace the match by a tabulation ‘\t’. Another way is using regex to remove  all spaces and unwanted characters first.

Remember that in Regex language, characters enclosed by square brackets are options  meaning that any of them is a match. Here ‘g’ stands for global. By default, the substitute rule is applied only to the first occurrence, using ‘g’ will continue until the end of the text. Try now to substitute ‘,’ by a tabulation to obtain the desired output.

Now that we got the desired output format, create a script file “gendata.sh” that comprises of an infinite loop and the previous command

Give the file execute permission and check the results of your script

To have a taste of how this will go run ‘gnuplot’ in another terminal. Within gnuplot command line interface (cli) execute:

“using 2”  means the second column which correspond to humidity (If nothing is showing up, run “apt-get install gnuplot-x11”).

Note: If you are using ssh to control your Raspberry Pi, make sure you use option “-X” (ssh -X pi@<ip address>), otherwise x11 windows won’t be redirected.
Remark: sed command is not the only command that achieves the task. For example, ‘perl’ can be also used in a similar fashion. Also you may use ‘awk’ command which has a nice way to print columns. Feel free to switch to any other tools that you feel comfortable (a python code that reads from the standard input can do).

Daemonizing gendata.sh script

So far, if we close the terminal which runs “sudo ./gendata.sh >> gnuplot_data” process, the process will stop because it is a child process of the terminals shell process. A simple way to make a process independent of the terminal is using ‘screen’ command (run “man screen” for details). Here is a quick tutorial on using screen. However, the standard way is to create an initrd script like any other servers (e.g., apache, mysql…etc).

Create a an intird file named ‘data_server’:

Try to understand the above script. ‘$( <command> )’ is used  to  group the sequence and ‘&’ makes them run in the background (otherwise it will freezes the boot process, which is ugly).
Give data_server execute permission and move it to “/etc/init.d/”.  Now, you can start/stop data server using the standard way

Finally, add the server to the default run levels using “update-rc.d” command

and start the server.

To view your gnuplot data file in a live fashion

Generating  PNG plots using GNUPLOT

We will add another column to gendata.sh script that correspond to time using ‘date’ command:

Next, create a gnuplot script file ‘plot.m’

The code should be self-explanatory. Now run gnuplot

and check the png files.

Final Step: Web Server

This part is similar to what we did in lab 2.2.

Enable CGI in “/var/www/” for files with .cgi extension. Open “/etc/apache2/sites-enabled/000-default” and append

Remark: If you use apt-get to install apache, the configuration is not only in ‘httpd.conf’ file, but rather scattered in several locations (perhaps, it is an over complication by debian developers).

Create “index.cgi” file that:

  1. execute
  2. echo some html that view the images and two buttons for on and off.
  3. Switches on/off the led according to buttons clicked.

Remarks:

  • Make sure “index.cgi” has execute permission. The user of all files in “/var/www” (including the directory) must be “www-data”.
  • User “www-data” must be added to group “gpio” to be able to toggle the LED (“useradd -G group-name username “).

Finally, Test your work by accessing the Raspberry Pi web server from your computer, and this was the last lab. Thank you for your patience and hard work.

Exercise

  1. Complete the lab.
  2. Bonus 1: write a script that generates data files organized by day. Extend Gnuplot code to show two curves per plot. One curve for the current day, and the other for the day before.
  3. Bonus 2: using Javascript, try to update the figures asynchronously using AJAX technique. To achieve this, gnuplot script should be called from another cgi file. This cgi file is then invoked from a javascript function in index.cgi.  For details, follow this tutorial.

Rules:

  • Create a directory named ‘lab-4.3′ in the your git server. Copy all script files to the directory. Create an additional README.md file to describe extra script files needed for bonus parts.
  • Commit and push the changes.