Creating the server side

We now have the base ready and can continue with implementing the project-specific parts. The Raspberry Pi that is connected with the circuit and the lamp will act as a server. It will run a tiny web server that can be reached through a client of your choice using a web browser.

For the server side, we will adapt and evolve the server example used in Chapter 9, Making a Media Hub on the Raspberry Pi,  and combine it with an updated version of the gpio-packt recipe from Chapter 5, Creating, Developing, and Deploying on the Raspberry Pi, . To start with, we need to add the meta-packt_rpi layer used in earlier chapters of the book. We have already ensured that our newly created layer has a higher priority then meta-packt_rpi, but let's also add it in a dependency order in bblayers.conf. Here is the complete bblayers.conf file that will be used in this project:

# LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
POKY_BBLAYERS_CONF_VERSION = "1"
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS ?= " 
  /path/to/poky/meta 
  /path/to/poky/meta-poky 
  /path/to/poky/meta-yocto-bsp 
  /path/to/meta-raspberrypi 
  /path/to/meta-openembedded/meta-oe 
  /path/to/meta-packt_rpi 
  /path/to/meta-packt-iot 
  "
BBLAYERS_NON_REMOVABLE ?= " 
  /home/path/to/git/poky/meta 
  /home/path/to/git/poky/meta-yocto 
  "

Next, we should make some minor changes to gpio-packt in order to make it more suitable for our project. These changes will be made as a integration patch. The original code uses GPIO4, which is one of the pins that are set high by default. We will instead use GPIO17, which is one of the pins that defaults to low.

To change the gpio_example code to use GPIO17 instead, we can create a new integration patch that changes the behavior only when we apply the meta-packt-iot layer. The minor changes required are as follows:

--- gpio_example.c.orig 2016-03-10 16:55:04.334832221 +0100
+++ gpio_example.c      2016-03-10 16:54:13.400537071 +0100
@@ -39,7 +39,7 @@
/*=================================================*/
#define        LENGTH          128
#define        SYSFS_GPIO_DIR  "/sys/class/gpio/"
-#define        GPIO_PIN        4
+#define        GPIO_PIN        17
#define        BUFFER_SIZE       255
#define          DEBUG           1
#define          VERSION         1.00

The patch can be generated by using the diff command. This will result in a difference between the original version of gpio_example.c and the updated version.

$ diff -Naur gpio_example.c.orig gpio_example.c > use_gpio17.patch

Next, we must add the patch to meta-packt-iot. Start by creating the structure for appending gpio_example in meta-packt-iot:

./recipes-custom
./recipes-custom/gpio-packt
./recipes-custom/gpio-packt/gpio-packt
./recipes-custom/gpio-packt/gpio-packt/use_gpio17.patch
./recipes-custom/gpio-packt/gpio-packt_0.1.bbappend

The content of the bbappend will be very small and will only be required to apply the patch:

FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
SRC_URI += " 
file://use_gpio17.patch;striplevel=0 
"

Time to start with the web server. We need to make some modifications to our project for the server part as well. Most of the basic setup can be kept as is for the webserver-packt recipe. However, the server JavaScript (server.js) and the main webpage (index.html) need new logic and content. Since the new content is not really suitable to add to the existing code, we will create a new bbappend file for the web server and then override the package with new versions of the index.html and server.js files that are suitable for this specific project. Start by creating a new structure within meta-packt-iot that looks like this (index.html, server.js, and webserver-packt_0.1.bbappend can be empty for now):

./recipes-custom
./recipes-custom/webserver-packt
./recipes-custom/webserver-packt/webserver-packt_0.1.bbappend
./recipes-custom/webserver-packt/webserver-packt
./recipes-custom/webserver-packt/webserver-packt/index.html
./recipes-custom/webserver-packt/webserver-packt/server.js

When the new structure is in place, we can start with adding content to the bbappend file:

DESCRIPTION = "Remote lighting control" 
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" 
SRC_URI += "  
    file://server.js  
    file://index.html  
    " 
do_install_append() { 
    install -d ${D}${datadir}/server-packt/server 
    install -m 0755 ${WORKDIR}/index.html ${D}${datadir}/server-packt/server/public/index.html 
    install -m 0755 ${WORKDIR}/server.js ${D}${datadir}/server-packt/server/server.js 
} 

The logic in webserver-packt_0.1.bbappend is quite simple. It appends the SRC_URI variable with our new versions of index.html and server.js and then overrides the old files in the install stage.

Let's take a deeper look at the code modifications needed for our project. Just like in the media hub example in Chapter 9, Making a Media Hub on the Raspberry Pi we will continue to serve an HTML file that will act as the client. We will also continue to listen on the same port (3344) to avoid confusion. The functional logic in the server code lies within the io.on() {...} function. Here, we will receive a message from the client (index.html) and execute it on the server. In our example, the command to execute is either gpio_example --led=1 or gpio_example --led=0, which will cause the light to turn on and off, respectively. The complete code for server.js looks like this:

var express = require('express') 
    , app = express() 
    , server = require('http').createServer(app) 
    , path = require('path'), 
    fs = require('fs'), 
    sys = require('util'), 
    exec = require('child_process').exec, 
    child, child1; 
http://192.168.1.13:3344/light.html 
io = require('socket.io').listen(server), 
                io.set('log level', 1); /* DEBUG MODE */ 
app.use(express.static(path.join(__dirname, 'public'))); 
app.get('/', function(req, res) { 
    res.sendFile(__dirname + '/public/index.html'); 
}); 
io.on('connection', function(socket) { 
    socket.on('light', function(msg) { 
        child = exec(msg, function (error, stdout, stderr) { 
            if (error !== null) { 
                console.log('exec error: ' + error); 
            } 
        }); 
    }); 
}); 
 
server.listen(3344, function() { 
    console.log('listening on *:3344'); 
}); 

To get the whole picture of the solution, we also need to look at the client, index.html. The look and feel of the web page from Chapter 9, Making a Media Hub on the Raspberry Pi is kept, but the CPU monitoring has been replaced by a green/red button, used to turn the light on or off. Depending on which button is pushed, a socket message using socket.emit is used. The message contains the exact Unix command required to turn the light on or off:

<body> 
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation"> 
<div class="container-fluid"> 
<div class="navbar-header"> 
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> 
<span class="sr-only">Toggle navigation</span> 
<span class="icon-bar"></span> 
<span class="icon-bar"></span> 
<span class="icon-bar"></span> 
</button> 
 <ul class="nav navbar-nav"> 
    <li class="active"> <a href="EB9781785281952_3.html">HOME</a> </li> 
  </ul> 
</div> 
</div> 
</div> 
</nav>' 
<hr> 
<div class="container-fluid"> 
<div class="well well-lg text-center"> 
<h1><b>Raspberry-Pi</b><b></b></h1> 
<p><b>Remote lighting</b> control</p> 
<h4><span class="label label-info"></span></h4> 
</div> 
<button class="button buttonON" onclick="lighton()">ON </button> 
<button class="button buttonOFF" onclick="lightoff()">OFF</button> 
<script src="/socket.io/socket.io.js"></script>          
<script>        
    var socket = io.connect('http://'+ location.host);              
    function lighton()       
    { 
        socket.emit('light', 'gpio_example --led=1'); 
        return false; 
    } 
    function lightoff() 
    { 
        socket.emit('light', 'gpio_example --led=0'); 
        return false; 
}                       
</script> 
</body> 

If you look at index.html in a web browser, it should look like this:

Creating the server side
The look of the client (index.html) when displayed in a web browser

Lastly, we must not forget to add gpio-packt and webserver-packt to our image:

$ cat recipes-core/images/packt-iot-image.bb
# Base this image on rpi-basic-image
include recipes-core/images/rpi-basic-image.bb
SPLASH = "psplash-raspberrypi"
IMAGE_FEATURES += "ssh-server-dropbear splash"
IMAGE_INSTALL_append = " rpi-gpio gpio-packt webserver-packt"
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.19.29.89