Part 6: Enabling Push Notifications

This is part of a series of posts related to My Internet of Things and MobileFirst adventure.  An index to all posts can be found at the end of the first post.

When we left of in the last post, I had a Raspberry Pi that is capable of taking a picture using its camera and storing that picture in a file.  It can also sense that a physical pushbutton has been pressed – a doorbell.  I also have my Bluemix services configured to manage Push notification requests and to broker IoT messages.  Let’s start wiring things together by configuring Push notifications.

Build an iOS app that can receive push notifications

Note: This app evolved and changed a lot as I kept changing my mind on how I wanted to do things.  Again, you may not see why I decided to implement things the way I did until later.  Just play along for now.

I’m writing a Native iOS app in Swift.  I’ll share the entire app in GitHub at the end of this series, but for now I will just show you code snippets of the relevant parts.

To receive remote push notifications, mobile apps must register to receive them. There are really two parts to this, registering with the Apple Push Notification Service to enable the app to receive notifications and registering with IBM Push Notifications service to enable it to send the requests on behalf of the Raspberry Pi app.

Register for remote notifications with APNS

The following code defines two notification actions and registers them with APNS to enable the app to display alert boxes with these buttons, play sounds and update badge counts in response to remote notifications:

You call this procedure from the AppDelegate’s didFinishLaunchingWithOptions method.

Register the device token with IBM Push Notifications service

You know registration with APNS was successful when the system calls your AppDelegate’s didRegisterForRemoteNotificationsWithDeviceToken method, so here’s where you register with IBM Push Notification service, passing along the device token.

Again, realize that this is not complete code, but rather just the important parts.

Invoke a Push notification from the Raspberry Pi

I’m going to change up the Node-RED flows that I created in Part 4.  The flow I had created caused the Pi to capture a picture as soon as the doorbell was pressed.  I am going to have Node-RED only send a push notification to the app when the doorbell is pressed.  The picture won’t actually be taken until the user requests it in response to receiving the Push notification on the iPhone app.  No, I don’t think this is the best design either, but again, I am using this as an opportunity to learn as much as I can about IoT, so this design will enable me to eventually send MQTT commands from the app to the Pi.

There is a Node-RED node package that sends push notification requests to the IBM Push Notifications service.  But what I found is that this node only accepts a simple string to use as the message alert string.  The IBM Push Notifications service can optionally accept a JSON object that defines a number of other items.  I would like to provide some of these other items in my Push message so I am going old school and using an HTTP node instead.  This additionally illustrates how the IBM Push Notifications service can be invoked with a simple HTTP POST.

Raspberry Pi Node-RED flow

I modified my Node-RED flow to the following:

Node-RED flow for processing the doorbell

Node-RED flow for processing the doorbell

The “send notification” and “push” nodes are new and require a little explanation.

HTTP Request node

I did not customize this node at all, with the exception of naming it.  The address, headers and content of the message will be provided in the incoming message from the function node.

Send Notification function node

  • Line #3:  The pushbutton will send a message (“1”) when pressed and a message (“0”) when released.  Also, in order to simulate a button press for testing, I added a timestamp Inject node as an input to the node as well.  I only want the node to be triggered when the payload is NOT 0 – meaning either the pushbutton was pressed (not released) or the message is a timestamp.
  • Line #5:  This request will use the HTTP POST verb
  • Line #6:  The URL address of the request.  You will need to replace “your-appID-here” with the AppGUID from your Bluemix application
  • Line #7:  The appSecret HTTP header value needs to be the appSecret from your Bluemix IBM Push Notifications service.
  • Line #8 – #22:  This defines the payload message that will be sent to the IBM Push Notifications service.  For a full explanation, click Model to the right of body at https://mobile.ng.bluemix.net/imfpushrestapidocs/#!/messages/post_apps_applicationId_messages.

Testing

Once Deployed, clicking on the timestamp node should cause the function node to create a message and the push node to send it.  You can confirm by verifying the output of the msg node in the debug view.  You should see a statusCode of 202 and a header x-backside-transport value of “OK OK”.

Assuming you have added the code above for registering for remote notifications and registering the device token with IMFPush to even a simple iOS app, you should also see the notification appear on your device.

Diagnosing problems with Push notifications is difficult.  You either get the notification on the mobile device or you don’t.  There are no diagnostic messages returned from APNS or log files created.  The most likely cause of a push not finding its way to your phone is that the SSL certificate wasn’t created or installed properly.

Next

The next thing is to set up the basics required for the app to request a picture and the Pi to respond by sending it to the app via IoT Foundation.

That will be the next blog post in this series.

Part 5: Set up the Bluemix application environment

This is part of a series of posts related to My Internet of Things and MobileFirst adventure.  An index to all posts can be found at the end of the first post.

Today I am going to configure my Bluemix environment that will talk to my Raspberry Pi.  I already have a Bluemix account, but you can go to https://ibm.biz/IBM-Bluemix and get your own free account.

Create a Bluemix application

Bluemix provides a number of boilerplates.  Boilerplates are packages of services already bundled together.  This is usually the easiest way to get started.

  1. Click Catalog and then MobileFirst Services Starter to create a new application based on the boilerplate.
  2. Enter a name for your app.  It has to be unique, so consider including your initials or something in the name.  Click Create.
  3. Bluemix will start cranking through the creation process.  First your application will be staged, then created.  Once it says your app is running, the creation process is done.

Add the IBM Internet of Things Foundation service

IBM Bluemix provides a service called Internet of Things Foundation.  This is sort of a registry service and a message broker all in one.  You can register your device in the Internet of Things, then communicate with it through IoT nodes in Node-RED.

  1. From your Bluemix App’s Overview page, click Add a service or API.  Search or scroll to the bottom and select Internet of Things Foundation.
  2. Your app will need to be restaged to add the service.  Wait until App Health indicates your application is running again.

Add the Raspberry Pi to the Internet of Things Foundation

  1. Once the app is running again, click the Internet of Things Foundation tile.
  2. Click Launch Dashboard.
  3. From the Overview tab, click Add a device.
  4. Create a device type.  This can be anything you want, say myPi.
  5. You can optionally choose the attributes you want to assigned for each device of this type.  You can skip this for now if you want.  If you choose to add attributes, you will be asked to supply defaults on the next screen.  You can also add additional metadata in JSON format.
  6. After entering all that information about the device type, you will return to the Add Device wizard.  The only bit of information here that is absolutely required is the Device ID.  That is the device’s MAC address.  To find it, go back to your Raspberry Pi command line and type ifconfig eth0.  The output will look something like this:

    ifconfig output

    ifconfig output

  7. Type the string of characters following the HWaddr (leaving out the colons) into the Bluemix IoT dialog.  In my example, it would look like this:

    IoT MAC Address entry

    ifconfig output

  8. Click through the rest of the screens until you get to the page displaying Your Device Credentials.  You will be shown a box with the Authentication Token.  Copy this down immediately!  You will not be given a second chance to see it!

Configuring the IBM Push Notifications service

Next, I’ll configure the IBM Push Notifications service.  This is one of those cases where in reality, I came back and did this later, but since we are in Bluemix now, let’s set it up here.

The IBM Push Notifications service is, in a sense, a notification broker.  Applications that want to sent push notifications to devices (in my case, the Raspberry Pi), will send message requests to the IBM Push Notifications service via HTTP REST commands.  The IBM Push Notifications service will, in turn, dispatch the request to the notification services for the appropriate platform.  In my case, I an going to be writing the app on iOS, so the IBM Push Notifications service will invoke the APNS (Apple Push Notification Service), which will send a remote notification to my device.  In order to receive the notification, the device app software will need to register with the IBM Push Notifications service.

Configuring Apple Push is not for the faint of heart.  First of all, it requires you to have an Apple Developer license.  You can buy a personal license for $99 per year if you don’t have access to a corporate license.  Once you have a license, you must use the Apple Developer Portal to create a Device ID, an App ID and a Provisioning Profile as well as an SSL certificate that must be used by any application that wants to request APNS to send a push notification.  That process is out of scope for this blog, but you can read about it in the iOS Developer Library.

Once you have your SSL key, you will need to register it with the IBM Bluemix Push Service.

    1. Go to your Bluemix application Overview and click the IBM Push Notifications service.
    2. Click Setup Push.
Bluemix Push Dashboard

Bluemix Push Dashboard

  1. Click Choose file under Apple Push Certificate.  (Note that the process would be similar for Google Cloud Messaging for Android devices.)
  2. Upload your p12 SSL key and enter the password for it.

It is possible to use the IBM Push Notifications dashboard to send out test notifications.  This can be helpful in debugging the process.

That takes care of configuring the Bluemix services in the cloud.  You have two primary services:

Internet of Things Foundation

  • Acts as a broker for MQTT messages between IoT Applications and Devices
  • Maintains registration information for all your Devices

IBM Push Notifications

  • Acts as a broker for remote notifications between requesting applications and the vendor cloud messaging services.
  • Provides a manual Push testing interface

That takes care of the system setup tasks.  In the next post, I will start implementing my solution and configure my Raspberry Pi Node-RED flows to send Push Notifications.  In a later post, I will enable my mobile application to request a picture from the Raspberry Pi and the Raspberry Pi to return the picture using the IoT Foundation.

Part 4: Adding in the camera

This is part of a series of posts related to My Internet of Things and MobileFirst adventure.  An index to all posts can be found at the end of the first post.

Now I have the Raspberry Pi running Node-RED and can control a pushbutton and LED.  Cool.  And then, the mail carrier came!  My camera module arrived!

Camera module installation is pretty easy.  Just follow the Raspberry Pi Documentation.  There is an easy command-line utility called raspistill that I used to test out the camera.

Now there is no out-of-the-box node to control the camera module from Node-RED.  I never found any Googling around the internet either.  But that’s OK – this gave me an opportunity to see how extensible Node-RED is.  I would have to integrate the Raspicam Node.js library into function nodes.

Making Raspicam accessible in Node-RED

First, I had to install the raspicam module into Node.js.  Npm package manager makes that easy enough, but again, make sure you are in the right directory.

cd ~/.node-red
npm install raspicam

Now, that makes raspicam accessible in Node.js, but there is an additional step required to make it accessible within Node-RED.  See the Global Context section in the Node-RED Documentation.  In ~/.node-red/settings.js, I added

functionGlobalContext: {
        RaspiCam:require('raspicam')
},

Bounce Node-RED and you should be able to access raspicam commands inside Node-RED modules like

 var camera = new context.global.RaspiCam( opts );

Adding a function node

Now I’m ready to add some code to control the camera.  This is done with a function node.

  1. Drag a function node onto the canvas and connect it like this
    Function Node added to test flow

    Function Node added to test flow

    A couple things to note here.  First, you can have more than one node wired to a node’s input.  In this case, both the Pin 12 node and the function node will send information to the msg.payload debug node.  We already saw this in the previous post because the Pin 12 node and timestamp injection node send output to the trigger node.  Secondly, you can have more that one node take input from a node’s output.  In this case, the trigger node will pulse the LED, but it will also send the trigger to the function node, which we will use to take a picture.

  2. Double-click the function node.  Name it Take Picture.  Paste the following code into the Function area:
    // We only want to take pictures when 
    // the button is pressed, not when it is released. 
    if (msg.payload == 1) { 
        var encoding = "png"; 
        var currTime = new Date().getTime();
    
        // Use the current timestamp to ensure
        // the picture filename is unique.
        var pictureFilename = "/home/pi/pictures/" + currTime + "." + encoding;
        var opts = {
            mode: "photo",
            encoding: encoding,
            quality: 10,
            width: 250,
            height: 250,
            output: pictureFilename,
            timeout: 1};
    
        // Use the global RaspiCam to create a camera object.
        var camera = new context.global.RaspiCam( opts ); 
    
        // Take a picture
        var process_id = camera.start( opts ); 
    
        // Send the file name to the next node as a payload.
        return {payload: JSON.stringify(
            {pictureFilename : pictureFilename}) };
    }
  3. Deploy the flow.  You see two messages in the debug view. The first is the message from the Pin 12 node.  The second is the message created by the “Take Picture” node.  That node has told the camera to take a picture (if you were paying attention, you would have seen the red light on the camera module flash) and has sent a message with the filename to the debug node.
    Deploy messages

    Deploy messages

    There is a problem here.  The Pin 12 node is configured with “Read initial state of pin on deploy/restart?” checked.  This is causing my flow to trigger and a picture to be taken when I don’t want it to.  I’ll fix that before verifying the camera worked.

  4. I’ll double-click the Pin 12 node and deselect “Read initial state of pin on deploy/restart?” and Deploy again.  This time I get no new debug messages.
  5. Press the pushbutton on the breadboard.  The camera light will blink as it takes a picture and the LED connected to Pin 22 will pulse for 2 seconds.
  6. I’ll open up a VNC session, find the picture file in /home/pi/pictures with the name in the debug message and open it.  The picture isn’t all that exciting.  My Pi camera is sitting on my desk, pointing toward my laptop monitor.  But it proves that things are working.

    Viewing picture on Pi VNC

    Viewing picture on Pi VNC

Ok, so now I have a Raspberry Pi and a Node-RED flow triggered by an external button that will take a picture using the Pi camera module and store the picture in a file on the device.  I’m making progress but so far I only really have a “thing”, not an “internet of things”.  In the next post, I’ll set up my Node-RED environment on Bluemix so I have something to communicate with.

Part 3: My first Node-RED flow on the Pi

This is part of a series of posts related to My Internet of Things and MobileFirst adventure.  An index to all posts can be found at the end of the first post.

In previous posts, I have setup the hardware and software on my Raspberry Pi.  Now it is time to create a Node-RED flow to manage my hardware.

Node-RED flow editor

Node-RED’s flow editor is browser based.  Once you have Node.js running with the Node-RED package installed, browse to your flow editor at http://your.pi.address:1880.  The Node-RED flow editor is quite simple to use.  On the left is a palette of nodes that can be added to your flow.  In the center is the canvas where you will create your flow.  On the right you see two tabs.  The Info tab will display documentation for any selected node.  The Debug tab will become really important shortly as we start putting together a flow and want to see what is going on.

Node-RED Startup Screen

Node-RED Startup Screen

Button flow

The first flow I created was a simple one to verify my Node-RED environment was seeing the button state changes.

  1. I dragged the rpi-gpio in node to the canvas.  This node isn’t in the out-of-the-box Node-RED but was added by the node-red-contrib-gpio node I added.  Note all the information about the node displayed in the Info tab on the right.
  2. Double-click the node to open its configuration dialog.  Set the values as below and close it

    Input pin configuration

    Input pin configuration

  3. Drag the debug output node to the canvas and connect them as below.
    Input flow

    Input flow

    The blue dots on the nodes indicate that these changes have not yet been deployed.

  4. Select the debug tab on the right side of the screen.
  5. Click the red Deploy button in the upper right.  You should see a ‘0’ payload displayed in the debug window.  The input node was configured to read the initial state of the pin when the flow was deployed.  That caused a message to be sent from the input pin node to the debug node which displayed the payload in the debug window.
  6. Press and release the button on the breadboard.  You should see a transition to a ‘1’, and then a transition back to ‘0’.

    Button press debug messages

    Button press debug messages

 LED flow

Next I wanted to create a simple flow that would enable me to manually control the LED state from within Node-RED.

  1. Drag the Inject node onto the canvas.  The inject node enables you to manually interact with the flow.  By default, it simply sends the current timestamp as a payload in the outgoing message.
  2. Drag the Trigger node onto the canvas.  Change the node’s settings to send a 1 then wait for 2 seconds before sending the 0.
  3. Finally, drag an rpi-gpio out node to the canvas and configure it for pin 22.
  4. Connect the nodes together like this:

    Output flow

    Output flow

  5. Deploy the flow.
  6. Click the little tab on the left side of the Inject node.  Your LED should light for 2 seconds, then go off.

Combined flow

Now, let’s combine them into a single flow.

  1. Connect the output of the Pin 12 node to the input of the trigger node.
  2. Deploy.
Combined test flow

Combined test flow

Now the LED can be triggered by either clicking on the timestamp node or by pressing the pushbutton connected to pin 12.

So now I have a Raspberry Pi with a pushbutton and LED that I’m controlling with Node-RED.  In the next post, I will install the camera and see what I need to do to control it with a Node-RED flow.

Part 1: Setting up the Raspberry Pi hardware

This is part of a series of posts related to My Internet of Things and MobileFirst adventure.  An index to all posts can be found at the end of the first post.

A couple days later, my vigil at the mailbox was rewarded – my Raspberry Pi starter kit arrived.  Since I was too cheap to pay for express shipping, the camera wouldn’t arrive for a couple more days.  That was fine with me – I had plenty to learn about the Pi before dealing with the camera.

Unpacking and firing up the Raspberry Pi

I pulled out a spare USB keyboard, mouse and network cable and plugged the Pi into an HDMI monitor.  My starter kit came with a micro-SD card pre-loaded with the NOOBS (New Out Of the Box Software) so I inserted that.  I plugged in the device and away it went.  Initializing the Raspberry Pi was extremely easy.  I went with the recommended Raspian OS and had the GUI running in no time.

Wifi

My starter kit came with a wifi USB dongle.  I plugged that in and configured the wifi settings through the GUI.

Wifi Configuration in the Raspberry Pi GUI

Wifi Configuration

With the Pi on my home wifi network, I could shell into it from my Macbook.  That’s handy because having an extra keyboard and mouse cluttering up my already cluttered desk was going to be a pain.  Now I could talk to the device without needing an external monitor or peripherals.

Circuits

Being an old hardware guy, I went straight for the breadboard and circuit components that came with my starter kit.  I set up a push button with a 10k pull-down resistor that I could use as an input and a LED with a 2.2k series resister I could use as an output for testing.  My kit even came with a GPIO to Breadboard Interface Board which made it easy to connect the Pi to the breadboard.  I connected my pushbutton circuit to BCM_GPIO 18 on physical pin 12 and my LED circuit to BCM GPIO 25 on physical pin 22.  Here is a view of the circuit:

Test circuits on breadboard

Test circuits

Ok, now I have all the hardware configured.  I just need to figure out how to control it with software.  That’s a task for the next post.

Overview: My Internet of Things and MobileFirst adventure

Featured

UPDATED:  I’ve done some follow-up work on this project and rather than keep pasting new additions and changes onto the existing content, I have decided to rewrite the series to better reflect the process from start to finish.  If you have read the series before, you may fine some interesting new aspects added and others removed.  Some of the old content was no longer applicable due to updates in Bluemix services.  I also went a little off the deep end with an Apple Watch. 🙂

I am diving into a new project where my eventual goal is to have a mobile app on my phone communicate to a “thing” on the internet.  Yes, those are pretty poorly defined requirements so right off the bat I did some research to decide what the “thing” should be, what amazing task it should perform and how I should make it talk to my phone.

Due to its popularity and just because I thought it sounded cool, I decided my “thing” would be a Raspberry Pi.  These are cheap little single board computers that can run a number of open source operating systems and application packages.  With that decided, I ordered my Raspberry Pi starter kit and anxiously waited at the curb by my mailbox.

But what cool task would it do?  I wanted something related to home automation that was more than pressing a button and lighting a lamp, but I also wanted to keep it reasonably scoped.  I decided on a doorbell interface that would take a picture when the button is pressed and make that picture available to the mobile app.  Ok, for that I would need a camera module so I ordered that and went back to the curb by the mailbox to wait.

Now I knew what the thing would be and what task it would perform.  But how would it communicate to the mobile app?  After a little more research, I decided to leverage the IBM Bluemix platform and services it provides. Hey!  What a coincidence:  I work for IBM!  Ok, maybe it isn’t such a coincidence.  My plan all along was to demonstrate how I could use Bluemix and the IBM MobileFirst Services to build this app.  But in this process, I have learned a ton about non-IBM technology as well so this adventure is not at all just an IBM sales pitch.  But it will demonstrate how you can build applications leveraging cloud-based services and the Internet of Things.

While I was still waiting at the mailbox, I sketched out this architecture diagram for the eventual system:

Yes, this does look overly complicated for a doorbell.  But my not-so-hidden agenda here is to demonstrate how all these cloud and IoT components can come together to provide services for a mobile application.  There is lots to learn here, even if you don’t want to get into the whole system, so feel free to cherry pick whatever helps.

There are four main pieces of functionality in this project:

  1. Push Notifications
  2. Picture capture
  3. Video capture
  4. Apple Watch

I ended up doing a LOT of iterating.  I am going to spare you some of that and present the tasks in a more sequential fashion so you may find there are steps that don’t seem obvious at first, but hopefully you will see why I had to do them later.

  1. Raspberry Pi Setup
    1. Set up the Raspberry Pi hardware
    2. Install the Raspberry Pi software
    3. Creating my first Node-RED flow on the Pi
    4. Add in the camera
  2. Bluemix Setup
    1. Set up the Bluemix application environment
  3. Implementation
    1. Enabling Push Notifications
    2. Requesting and Receiving a Picture
    3. Watching video from the Pi on the Phone
    4. Apple Watch

Part 2: Raspberry Pi software

This is part of a series of posts related to My Internet of Things and MobileFirst adventure.  An index to all posts can be found at the end of the first post.

With the hardware all set up, I was ready to dive into the software on the Raspberry Pi.  I quickly learned that there is a bunch of software available for the Raspberry Pi.  Most of it is really easy to install with ‘apt-get’ command and npm.  I also discovered that the Raspberry Pi Documentation is really helpful.  Here are a few things I started with:

VNC

I knew I wanted to run the GUI from my MacBook and not require an external monitor.  I followed the instructions in the Raspberry Pi Documentation pretty much exactly as written.

I already had VNC Viewer on my MacBook.  I connected to the Pi and had GUI on my MacBook in no time.

Git

Git is a very popular open source version control system.  I could already see I was going to need Git on the Pi in order to get some code I would need, so I installed with

sudo apt-get install git-core

wiringPi

But, I still don’t have a way to monitor my pushbutton or control my LED circuits.  After a little Googling, I came across wiringPi, an access package for the GPIO interface.  It also comes with a simple command line interface, so I would have a way to test out my circuits.  I installed wiringPi using the instructions on the wiringPi install page.

Now, I could go to my command prompt and run gpio commands.  The pin numbering used by wiringPi is not obvious.  There is a whole history there but I’m not going to get into that.  I could read the state of the pushbutton using

gpio read 1

I could control the LED with the following:

gpio mode 6 out
gpio write 6 1
gpio write 6 0

Eclipse

Yes, you can install Eclipse on the Raspberry Pi!  My architecture did not include a Java program written in the Eclipse IDE, but I tried it anyway.  Again, installation is pretty easy with the package manager:

sudo apt-get install eclipse

There are a couple prerequisites, though.

JDK 7

It is best to get the full Oracle Java 7 JDK using the Raspberry Pi Documentation.

Pi4J

Pi4J is an API that gives you simple access to the GPIO pins on the board.  Install it with

curl -s get.pi4j.com | sudo bash

I followed Ian Bull’s tutorial with a few minor modifications to create a simple Java program that monitors the pushbutton and controls the LED.  But to get it to run, I ran into another issue – the underlying wiringPi must be run as root.

Configure Eclipse to run programs as root

There is a really clever Stack Overflow on how to do this.

Node-RED

Ok, now that I was able to interface with the hardware using the command line and a Java program, I was ready to move on to bigger and (hopefully) better things.  I wanted to use Node-RED.  What is Node-RED?  I lifted this description from an IBM page:

Node-RED provides a browser-based UI for creating flows of events and deploying them to its light-weight runtime. With built in node.js, it can be run at the edge of the network or in the cloud. The node package manager (npm) ecosystem can be used to easily extend  the palette of nodes available, enabling connections to new devices and services.

A textual description doesn’t really do it justice.  You really need to see a flow to understand how powerful it can be, so let’s get it installed, but beware – there be dragons here.

Installing Node.js

I Googled around a bit and instead of following the instructions on nodered.org, I jumped into a tutorial I found.  Unfortunately, that tutorial was outdated and lead me down a dead end.  As of this writing, Node-RED does not run on the very latest Pi-compatible version of Node.js.  I would definitely recommend you follow the instructions specific to the Raspberry Pi version you have from the Node-RED documentation.  I won’t repeat those instructions here.

Installing additional Nodes

Node-RED can be extended easily by installing additional nodes.  The best place to look is the Node-RED Library.  I installed node-red-contrib-gpio, but here is where another dragon appeared.  Being relatively unfamiliar with Node.js, I overlooked one very important line in the instructions: “From inside your node-red directory“.  In the case of a local Node.js instance, that means the hidden .node-red directory in my home directory on the Pi.  Until I figured that out, the nodes just wouldn’t show up in Node-RED.  So, the installation instructions should be:

cd ~/.node-red
npm install node-red-contrib-gpio

In the next post, I will look at how I created my first Node-RED flow on the Raspberry Pi before I stared interfacing it to the Internet of Things.