Sunday, August 24, 2014

Creating REST based Web Service using Javascript on the BeagleBone Black

Right after I published the Taking the Temperature with theBeagleBone Black and Javascript, I started thinking about creating a REST based Web Service using Javascript that I could use to read the temperature from a remote device.  For this project I will be using the node.js restify module to create the REST service. 

The TMP36GZ temperature sensor is wired to the Beaglebone Black as show in this diagram.



I always hate running services from within an IDE so I will not use Cloud 9 for this project and instead I will be running the service from the command line using node.js.  So the first thing we need to do is to setup a directory structure that contains the node.js modules needed to run the service.  I used the following steps to get the structure/modules set up (this is based off of the latest Debian image 2014-05-14):

1.  Start off within our home directory.  In Linux the ~ directory is the users home directory.
cd ~

2.  Create a work directory and change to that directory
mkdir temperature
cd temperature

3.  Install the restify module
npm install restify

4.  Copy the bonescript module to our working structure
mkdir node_modules/bonescript
cp /var/lib/cloud9/static/bonescript.js node_modules/bonescript/

At this point you should still be in the temperature directory and both the restify and bonescript modules should be located in the ~/temperature/node_modules directory.   This will let our application use these two modules.

From the ~/temperature directory, create a file called tempServer.js and put the following code in it.

var b = require('bonescript');
var rest = require('restify');

var ip = '0.0.0.0'
var port = '18080'
var path = 'temperature'
var tempPin = 'P9_40';
var currentTemp = 0.0;

b.analogRead(tempPin, readTemperature);
setInterval(function() {b.analogRead(tempPin, readTemperature)},30000);

var server = rest.createServer({
     name : "Temperature"
});

server.get({path : path , version : '0.1'}, getTemperature);

server.listen(port,ip, function() {
     console.log('%s listening at %s ',server.name, server.url);
});

function getTemperature(req, res, next) {
     var tempResponse = {"temperature":currentTemp};
     res.send(200, tempResponse);
}

function readTemperature (aRead) {
     console.log("Geting Temp");
    var x = (aRead.value * 1800/1024);
    var cel = 100*x -50;
    var fah = (cel *9/5)+32;
     currentTemp = fah;
}

This code begins by loading both the bonescript and restify modules that are needed for this application.  We then set the following variables:

ip:  The IP address of the interface to bind too.  By using 0.0.0.0 the server will bind to all available interfaces (this is what we want).
port:  The port to bind too.  Typically web servers bind to port 80 but we do not want to take up that privileged port (and it also requires root access to bind to ports below 1024) so we will use 18080 for our service.
path:  The URL path for our service. 
tempPin:  The pin that will be connected to the TMP36GZ temperature sensor.
CurrentTemp:  Will contain the current temperature.  This will be updated every 30 seconds.

After we set the variables, we then read the temperature using the analogRead function from the bonescript module.  This function will read the voltage from the tempPin and then call the readTemperature function when it has the voltage.  The readTemperature function calculates the current temperature based on the voltage of the pin and stores that temperature into the currentTemp variable.

We use the Javascript setInterval function to call the readTemperature function every 30 seconds to update the currentTemp variable.

Now that we have the temperature and updating it every 30 seconds, we need to create our web service that will respond to our requests.  We start off by creating a server object using restify’s createServer function. 

Next we define what services we wish to offer though this server object.  In this case we only have one service.  This service will respond to HTTP GET requests so the get function from our server object is used to define the service.  This service will listen on the path defined in our path variable and when a request comes in it will call the getTemperature function.

Finally we till the server to listen on the port and interface that we defined in the variables earlier.

The getTemperature function simply creates a JSON object that contains the current temperature and uses the send function from the res response object to send the object back to the client that requested it. 

You can run this application using the following command:

Node tempServer.js

Once it is running you can test it from the Beaglebone black command line using curl like this:

curl localhost:18080/temperature

You can also access the service from a remote machine by using the external IP address of your Beaglebone Black like this (remember to change the IP address to the IP address of your Beaglebone Black):




2 comments:

  1. You can information about internet marketing that are published on reputed sites. He has a very nice understanding about Web development company delhi 

    ReplyDelete
  2. Hey Jon! Thanks for the article. Works nice. I had 2 minor issues, though:
    1. Node tempServer.js
    For me it's node with a small 'n':
    node tempServer.js


    2. In the following line:
    server.get({path : path , version : '0.1'}, getTemperature);
    the version needs to be separated into 3 parts. I typed in '0.0.1'. Otherwise the script throws an exception saying
    throw new TypeError('Invalid Version: ' + version);
    I use restify 1.3.10.

    Thank you and bye

    Philipp

    ReplyDelete