Raspberry Pi Setup – Part II: IoT API Platform

Intro

This is the second part in a series of posts on setting up a Raspberry Pi to fully utilize the Software & Hardware functionality of this platform to build interesting internet of things (IOT) applications.

Part-I is here https://techiecook.wordpress.com/2016/10/10/raspberry-pi-ssh-headless-access-from-mac-and-installing-node-processing/ … this covered the following:

  • Enable SSH service on the Pi
  • Connect to Pi without a display or router – headless access via Mac

 

Part II: is this blog and it covers the following goals:

  • Install Node, Express on the Pi
  • Write a simple HTTP service
  • Write an API to access static content ( under some /public folder)
  • Write an API to POST data to the Pi
  • Write an API to read GPIO pin information

So lets jump in ….

 

Install Node.js

Be it a static webserver or a complex API – you need this framework on the PI (unless you like doing things in Python and not Javascript)

How do I install this on the Pi?

wget https://nodejs.org/download/release/v0.10.0/node-v0.10.0-linux-arm-pi.tar.gz
cd /usr/local
sudo tar xzvf ~/node-v0.10.0-linux-arm-pi.tar.gz --strip=1
node -v 
npm -v

 

Install Express

Easy to build APIs using the Express Framework

How do I install this on the Pi?

npm install express --save

Testing Node + Express

Write your first simple express HTTP API

I modified the code from here http://expressjs.com/en/starter/hello-world.html as shown below to provide a /health endpoint and a JSON response

  • Create a folder called ‘simple-http’
    • Mine is under /projects/node/
  • Initialize your Node Application with
    npm init
  • Install express
    npm install express --save
  • Write the application
    • 2 endpoints – ‘/’ and ‘/health’
      var express = require('express');
      var app = express();
      
      app.get('/', function (req, res) {
       res.send('API Running');
      });
      
      app.get('/health', function (req, res) {
       res.send('{"status":"ok"}');
      });
      
      app.listen(8080, function () {
       console.log('API Running ...');
      });

Screen Shot 2016-10-10 at 3.27.31 PM.png

GET Static Content

  • Create a “public” folder and put some content in itScreen Shot 2016-10-10 at 3.48.07 PM.png
  • Setup the Node/Express app to use “express.static()”
    var express = require('express');
    var app = express();
    var path = require('path');
    app.use('/static', express.static(path.join('/home/pi/projects' + '/public')));
    app.get('/health', function (req, res) {
      res.send('{"status":"ok"}');
    });
    app.listen(8080, function () {
      console.log('API Running ...');
    });
  • Test by accessing the “/static” endpointScreen Shot 2016-10-10 at 3.52.04 PM.png

POST data

Install body-parser

npm install body-parser --save

Use the body-parser

var bodyParser = require('body-parser');
app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({ extended: true })); 

Write the POST function … in my case I want to be able to do POST /api/readings

app.post('/api/readings', function(req, res) {
    var d = new Date();
    var value = req.body.value;
    var type = req.body.type;
    res.send('{ "status":"updated"}');
    console.log('Reading | '+d.toLocaleDateString()+'|'+d.toLocaleTimeString()+' | value='+value+' | type='+type);
});

Test It!

To test it we can issue a curl command from a computer connected to the same network as the Raspberry Pi….

curl -X POST -H "Content-Type: application/json"  -d '{
 "value":7.5,
 "type":""
}' "http://192.168.3.2:8080/api/readings"

Screen Shot 2016-10-11 at 10.39.39 AM.png

Note: In the example above, I run the command from the terminal and later in Postman from the Mac hosting the Raspberry Pi … remember the IP for my Pi was obtained via the following command

netstat -rn -finet

 

Read GPIO Pin Information

What are GPIO Pins?

The Raspberry Pi comes with a input/output pins that let you connect to electronic components and read from them or write to them … these general purpose input output pins vary in number based on the model of your Pi – A, B, B+ etc

See  http://pinout.xyz/ for how pins are labelled …

Screen Shot 2016-10-11 at 10.53.54 AM.png

Our Goal: API for accessing GPIO pins

Once we know which pins we want to read/write to, we need to be able to access this from our application … in our example this would be the Node.js application we are writing.

So we would like to be able to something like

  • GET /api/gpio/pins and list all the pin details (id, type etc)
  • GET /api/gpio/pins/{pinId}  and get the value of a pin
  • PUT /api/gpio/pins/{pinId} and set it to high/low or on/off

Setup Javascript Libraries for GPIO access

  1. Install “gpio-admin” so that you do not have to run your Node application as root to read / write to the gpio pins (Read https://github.com/rakeshpai/pi-gpio)
    git clone git://github.com/quick2wire/quick2wire-gpio-admin.git
    cd quick2wire-gpio-admin
    make
    sudo make install
    sudo adduser $USER gpio
  2. Install the npm gpio package (Read https://www.npmjs.com/package/rpi-gpio )
    npm install rpi-gpio
  3. Use this in your application
    1. Watchout:  The gpio operations are Async … this means that capturing ‘value’ of a pin, for instance, cannot be done like ‘var value  = readInput()’ in Node.js we need to use “Promises” (Readhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise – Thanks Alvonn!)
    2. “ReferenceError: Promise is not defined”: It appears the version of Node for the Pi (v0.10.0) does not have this library … ouch! Luckily other have hit this problem at some point with node and have posted the following solution which worked  …
      1. Install the “es6-promise” library manually
        npm install es6-promise@3.1.2
      2.  Declare Promise as the following in your application

        var Promise = require('es6-promise').Promise;
    3. Finally make the GPIO call
      1. Declare a ‘gpio’ variable and setup (attach to a pin)
        var gpio = require('rpi-gpio');
        gpio.setup(7, gpio.DIR_IN, readInput);
        function readInput() {
           gpio.read(7, function handleGPIORead(err, value) {
             console.log('Read pin 7, value=' + value);
           });
        }
      2. Read from it Async in a HTTP GET /api/gpio/pins/{pinId} call
        var Promise = require('es6-promise').Promise;
        app.get('/api/gpio/pins/:pinId', function (req, res) {
           var pinId = req.params.pinId; 
           var value = "";
           var p1 = new Promise(function(resolve, reject) {
                   gpio.read(7, function handleGPIORead(err, value) {
                   console.log('GET /api/gipio/pins/:pinId | Pin 7 | value=' + value);
                   resolve(value);
                  });
                 });
        
        p1.then(function(val) {
         console.log('Fulfillment value from promise is ' + val);
         res.send('{"pinId": '+pinId+', "value":'+val+'}');
         }, function(err) {
           console.log('Result from promise is', err);
           res.send('{"pinId": '+pinId+', "value":"Error"}');
         });
        
        });
      3. OutputScreen Shot 2016-10-11 at 4.21.42 PM.png

Show me the code

You can find the code for this project here:

git@bitbucket.org:arshimkola/raspi-gpio-demo-app.git

 

Summary

So by now we should have a platform primed to be used as a IOT device with a simple API running. We could have of course done all of the above in python.

Also we could have written a scheduled-service and “pushed” data from the Pi to some public API … in the next part of the series, we will talk about organizing IOT sensors in a distributed network

 

 

 

References

[1] https://scotch.io/tutorials/use-expressjs-to-get-url-and-post-parameters

[2] https://www.npmjs.com/package/rpi-gpio

[3] https://github.com/rakeshpai/pi-gpio

[4] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

 

 

 

Raspberry Pi Setup – Part I : Boot, SSH and Headless access

Intro

Part I : Documenting the workflow/steps to setup my Raspberry Pi (2 B) – from Installing Raspbian to installing Node, Processing etc

Goals:

  • Enable SSH service on the Pi
  • Connect to Pi without a display or router – headless access via Mac
Box 1.jpg
Raspberry Pi with GPIO Ribbon cable

Steps

  1. Install Raspbian
  2. Boot your Pi
  3. Setup SSH
  4. Connect to Mac
  5. Troubleshoot Connection to Mac
  6. Install Node
  7. Install Processing

Install Raspbian

You can download it here https://www.raspberrypi.org/downloads/raspbian/

Screen Shot 2016-10-10 at 1.11.28 PM.png

Boot Pi

Use the Raspbian image to boot-up the pi and you should see a command shell (once you have connected your pi to a display ofcourse!)

Setup SSH

Start with typing the following command in your shell

sudo raspi-config

screen-shot-2016-10-10-at-1-17-24-pm

This launches the Config Tool UI, follow the screenshots below

Screen Shot 2016-10-10 at 1.16.15 PM.png

Screen Shot 2016-10-10 at 1.19.27 PM.png

Screen Shot 2016-10-10 at 1.16.26 PM.png

Test by SSH’ing into the pi from the pi

ssh pi@localhost

Screen Shot 2016-10-10 at 2.06.22 PM.png

Copy Network Card’s Address

Do an “ifconfig” in the Pi’s shell and note down the “HWaddr” … we will use this later to search for the IP assigned by Mac

ifconfig

screen-shot-2016-10-10-at-1-37-48-pm

Connect to Mac Headless

Next we will connect the Pi to the in “headless” mode using the Mac to assign an IP to the Pi and then SSH into the Pi from a terminal in Mac …

  1. Ensure your Mac is connected to the network (wifi)
  2. On the Mac goto System Preferences -> SharingScreen Shot 2016-10-10 at 1.29.40 PM.png
  3. Connect Pi to Mac via Ethernet Cable and then power it up
  4. Wait until the “green lights” on the Pi have stopped blinking
  5. Check connection using the following command
    1. See Routing Table with the following command
      netstat -rn -finet
    2. Your Pi’s IP should be in the 1st column, next to the “HWaddr” in the 2nd column Screen Shot 2016-10-10 at 1.37.30 PM.png
    3. If you do not see your “HWAddr” listed then there is some connection issue …  goto “Troubleshoot Connection to Mac” in the next section
    4. Once you can see your IP, setup X11 forwarding with XQuartzScreen Shot 2016-10-10 at 1.34.13 PM.pngscreen-shot-2016-10-10-at-1-44-39-pm  Screen Shot 2016-10-10 at 1.44.49 PM.png
    5. Finally SSH in with the following command
      ssh -X pi@192.168.3.2
      1. If prompted for a password enter “raspberry” (which is your default password and you should change it at some point)
      2. You can setup passwordless login using the tutorial here https://www.raspberrypi.org/documentation/remote-access/ssh/passwordless.md
    6.  … finally this is what it looks likescreen-shot-2016-10-10-at-1-36-57-pm

 

Troubleshoot Connection to Mac

If you are unable to see an IP assigned to your Pi or unable to Ping it or SSH then there could be several reasons for this

  • Check your ethernet cable – I was using a bad cable when connecting to the Mac and a a good one when connecting to the router (when testing standalone), this cost me a lot of time!
  • Check your Mac Settings
    • I did not change the System Preferences -> Network -> Ethernet
    • Mac by default assigns 192.168.2.2 IP to your Pi, this may not get used if your Pi has “static” IP setup … validate by doing the followin
      • cat /etc/network/interfaces
      • ensure you use “dhcp” instead of “static” as shown belowScreen Shot 2016-10-10 at 1.59.01 PM.png
  • Check your Pi
    • while hardware issues are rare, you could have a problem there. Compare with another Pi
    • is it powered on? are the ethernet lights on when you connect the cable?

Software Install

… after you are done setting up the SSH / headless pi access, you can finally start building a usable platform

see Part II of the journey to build services over the PI to send out and read in data!

 

 

Oracle Webcenter and Enterprise 2.0

So we just completed a week of Webcenter PS3 training and tell you what … a week is just not enough. Over the next month I will be playing more with Webcenter, UCM and ADF and hope to answer a few important questions around the product and what it has to offer.

The buzz word is Enterprise 2.0 and the availability of “social” applications to Intranet and Extranet users. The word social here applies to the enterprise context the same way it applies to the general internet – use the power of community and the collective to get better! (We will avoid philosophical discussions around if that is a good thing or bad thing or if it pans out the way we hope it would, and instead focus on what all this means of application architecture in the enterprise).


[Image Source: Oracle]

Some of the questions I have been asked are:
Q. Where does SOA come into all this?
A. Enterprise Services built in a Service Oriented Architecture can be surfaced on Webcenter. Use SCA based services in SOA Suite to build enterprise services, compose complex services from simple ones and then expose these in Webcenter just the same way we could do this in a regular ADF app.

Q. Why should the Application Architects for COTS (off the shelf software like EBS, SEIBEL etc) and custom applications (like your home-grown rating/pricing apps) care about Webcenter?
A. The availability of a portal-framework, security along with webservice and data-controls based service integration allows us to pull everything together in a single visual area for an improved user experience. So if you have webcenter available, think about how your application can be made available in there.


[Source: Oracle]


Coming up ….

1) How to import an ADF Datasource into Webcenter

2) Setting up Webcenter spaces, users and roles

3) SOA and Webcenter – consume a SOAP service, surface a BPEL worklist

4) Spaces and ECM/UCM

 

 

Webcenter Spaces - Data Control


Webcenter Spaces

Weblogic Application Deployment Error – “Changing the source location…”

Stack Trace:

[01:41:48 PM] Weblogic Server Exception: weblogic.management.ManagementException: [Deployer:149007]New source location, '\JDeveloper\system11.1.1.4.37.59.23\o.j2ee\app\.ear', cannot be deployed to configured application, ''. The application source is at 'JDeveloper\system11.1.1.4.37.59.23\o.j2ee\drs\'. Changing the source location is not allowed for a previously attempted deployment. Try deploying without specifying the source.
[01:41:48 PM]   See server logs or server console for more details.
[01:41:48 PM] weblogic.management.ManagementException: [Deployer:149007]New source location, '\JDeveloper\system11.1.1.4.37.59.23\o.j2ee\app\.ear', cannot be deployed to configured application, ''. The application source is at 'JDeveloper\system11.1.1.4.37.59.23\o.j2ee\drs\'. Changing the source location is not allowed for a previously attempted deployment. Try deploying without specifying the source.
[01:41:48 PM] ####  Deployment incomplete.  ####
[01:41:48 PM] Remote deployment failed (oracle.jdevimpl.deploy.common.Jsr88RemoteDeployer)

Reason:

I got this error when I did the following:
– first deployed the application to the embedded weblogic server by right-clicking on a JSF/JSP file
– then deployed the same WAR (and later the EAR) to the server by right-clicking on the Project

So instead of starting the embedded server using Run -> StartServerInstance in JDev, I had tried to start it by launching a JSF/JSP page and then tried to deploy the app onto it (why? I was testing a portlet deployment) …which apparently is bad because you are trying to deploy the same WAR/EAR to the two location using two different ways.

Workaround:

– Shutdown the embedded server
– Start it back up using Run -> StartServerInstance
– Deploy the WAR by right clicking on the project

Define/Assign Custom Paylod for your BPEL Human Task

When you create a BPEL Human Task, the payload type is not specified by default. You can specify a simple type from the drop down on the “Data” menu item on the BPEL Task Editor page.

In a BPEL Task, see which menu item to select ("Data") to change the payload type

By default if you have not assigned a menu item then your “payload” element is not defined in your BPEL Task’s Schema. The BPEL Human Task references the “ApproveTaskWorkflowTask” schema, which has an element called “Payload” which is imported from “ApproveTaskPayload.xsd” schema definition file.


When the payload is not defined the structure is show below in the subsequent images…. so in the “ApproveTaskWorkflowTask.xsd” we have an empty payload

…and in the “ApproveTaskPayload.xsd” we have

I created a simple schema for my Approval Process where the top-level element is “TimeSheet” (which as a list of TimeSheetDays, which have details in them).  I wanted to use this schema as a payload….

I will use this in the BPEL Human Task by choosing “Other Payload” in my “Data” menu item

Select the schema you want …

Assign a name to refer to this payload type by … you should see the Task -> Payload -> <name-you-gave> as the structure.

End result … your Task has your user defined type for a payload. Now you can add data to this from a BPEL flow or an external call (convert your Human Task to an invoke-able “Composite with Service Bindings” by selecting that option when creating the task).

To use the data you do the following:

Stuff to read

Must read up more on these – download, test, play