All MobileFabric Posts

IoT with Raspberry Pi and Messaging

Ajay Bhat - Feb 08, 2017 - Engagement

Now for something very cool! In this post, Matt Trevathan discusses how you can use Kony MobileFabric for your next IoT project. Here, Matt sets up a Raspberry Pi-based sensor and shows how you can send targeted notifications for sensor events using Engagement Services on Kony MobileFabric.

An important aspect of IoT is targeting the right end user at the right time in the right place.  IoT analytics engine provide events that allow the engine to call an API or perform an action based on a set of rules or machine learning, but they still don’t  have the infrastructure or logic to target end users based off proximity, job skills or other factors when a problem occurs.  Instead, the IoT vendors commonly blast out a particular message to a group in the hope that someone is close to the proximity of the problem to fix it. At other times, these same platforms lack the ability to push across multiple channels, including SMS and email. Instead they target push notifications only, which may not be available when SMS is.

 

IoT Reference Block Diagram

 

Kony MobileFabric has the ability to segment users based on job type, location, time of day or other context, and even a specific user. This allows the IoT ecosystem to target the skills to meet the problem in a timely manner. The diagram above shows a collection of IoT devices that are communicating over an MQTT broker. Both the analytics engine and a Node.js client are subscribers to the topics on the bridge allowing the IoT ecosystem to send messages to the end user. These messages can be sent based off observations made by the analytics engine using techniques such as predictive analytics. Alternatively, notifications can be sent directly to the end user by looking for critical messages that were published to the broker.  In either case, Kony Engagement Services can send a message within the proximity of a specific iBeacon or geolocation by dynamically creating a segment using the messaging API. Then they can specify the job group and location to send the message. Only users with the job skills at the specific location will receive the message.  Kony MobileFabric’s Engagement Services enable your mobile users to be an interactive rather than a reactive part of the ecosystem.

This article will show you how to setup a Raspberry Pi with Node.JS and use MQTT to send messages to a MQTT broker, and Node.JS subscriber and Kony Engagement Services to target an end user’s phone with push notifications.

Setting up Raspberry Pi

The Hardware Configuration

For the tutorial, we are using a KY-002 shock sensor to determine if the sensor is “knocked” against something. The diagram below shows the configuration of the button sensor.

KY-002 shock sensor

 

Before proceeding, ensure your sensor uses the following pins:

Pin 2, 5V

Pin 11, GPIO17

If have a shock sensor, you can connect a button to GPIO17 in a similar fashion. 

Installing Node.js

If you’re a Kony developer, you’re familiar with JavaScript and most likely, Node.js.  Raspberry Pi can run node.js scripts with a few simple commands. Installing Node.js is simple on Pi.

  1. Ssh into your Raspberry Pi.
  2. Run the following Commands.:
            curl -sLS https://apt.adafruit.com/add | sudo bash

            sudo apt-get install node
  1. Once complete, type node –v  to ensure it installed correctly. It should return the current version of node installed on your Raspberry Pi.
Connecting Raspberry Pi to MQTT

In this tutorial, we will use the Mosquito MQ test server to publish and subscribe to events. Before writing any code, we will need to install the MQTT library and the GPIO library for Raspberry Pi. If you haven’t done so, follow these steps:

  1. ssh into your Raspberry Pi.
  2. Install the MQTT library 
        npm install mqtt –save
  1. Install the GPIO library
        npm install onoff –save

Once you’ve installed both the libraries, we will need to setup our knock script.  Using Nana or VI create a script called knock.js and add the following code:

var mqtt = require('mqtt');

// Setting up GPIO knock switch using buttons
var GPIO = require('onoff').Gpio,
    button = new GPIO(17, 'in', 'both');

button.watch(function(err, state) {
    // This function will detect when a knock happens by sensing when the state is changed to 1.
    // The knock switch has a binary output of 1 or 0 similar to a button switch.
    if (state == 1) {
        console.log("knocking");
        sendmessage();
    }

});


function sendmessage() {
    // Setting up the MQTT by connecting to the MQTT Broker. 
    var client = mqtt.connect('mqtt://test.mosquitto.org');

    client.on('connect', function() {
        console.log("Sending knock knock");
        client.subscribe('presence');
        client.publish('presence', 'knock knock');
        client.end();
    });
}

This code will publish a “knock knock” to the presence topic on the test.mosquitto.org test server.

You can test the program from the command line by  typing the following:

            node knock.js

If you shake your knock sensor, it will send a “knock knock” to the broker. In the console, you will also see a “Sending knock knock” message each time you shake the shock sensor with enough force to activate it.

Configure Mobile Fabric

You will need to follow a video on setting up your mobile fabric instance to send messages and your app to receive them, watch the following video:

 

You will need Visualizer Enterprise edition and the Kony Engagement Services Demo App found here:

https://github.com/kony/Kony-Engagement-Service-Demo-Visualizer

Download the zip file and expand it into a directory. The root directory of the expanded zip file will be Kony-Engagement-Service-Demo-Visualizer-master. Under that directory will be the KonyMSGDemo directory. When you get read to import your app into Visualizer, import the app with KonyMWGDemo as the root directory.

Kony Visualizer Import Screen

Please refer to the documentation for configuring the demo app.

  If you want to filter your app to your device for testing your pushes, follow these additional directions:

  1. Login to MobileFabric and click on the cloud icon in the left hand navigation bar.
  2. Click on the "Engagement Services" icon on the cloud you published your push services to. This will take you to the Engagement Services runtime.
  3. Click on the App you deployed in the video and click on the "Users" tab to find the user you created. Record the KSID of that user.

Creating an Event in Engagement Services

MobileFabric allows you to publish single messages using Adhoc Push as well as constructed messages using campaigns and events. In this example, we are going to setup an event-based push to our end users. You’ll need to start by logging into your Engagement Services runtime. Once connected to the runtime dashboard, we will create a message template.  

Open the left hand navigation bar from the Engagement Services console and choose templates.

Choose Templates

 

In the left hand navigation, choose "Templates" from the "Settings" section.

Template View

 

The templates view allows you to create new messaging, passbook, email and SMS templates. These templates are used when you want to deliver a standardized messages to applications, and simplifies the API call process when invoking a messaging event.

Click the Add Template button to add a new template. It will display the popup below:

Template Details

I named my template "IoT". On this screen, you can use predefined personalization attributes stored in the database about the user or you send parameters in via the API. To do this:

  1. Create your message template and create a variable name for the variable you want to pass into the template.
  2. Highlight the variable in the template.
  3. Then use the Mark as Name Value Pair button on the screen to highlight the variable you want to send in as a parameter. In my case, I named my variable myIoTDevices.
  4. Once you name your variables, click the Save or Update button to save this template.

We can now use this template as part of our event and call it from the API. Now, we can create our event by selecting it from them left hand navigation.

Events view

From the events screen, click the "Add Event" button. This will allows you to create a new event.

Add Event

I named my event IoTEvent. Once you have named your event, you will need to define a message. Click the Define Message button.

Message Information detail

 

You’ll need to associate the message with the application you created by selecting it from the dropdown. You can also copy your standard message from the messaging template. Notice that the myIoTDevice variable is already selected.  When we create an API payload, we can send this variable in to create a dynamic message from the API tailored to the end user. Scroll down to the bottom of the window and click the Save or Update button.View Event

 

Once completed, click the View API Payload. This will display a sample API call for the event.

Test Event Payload

 

Notice that the eventNamePairs has a sample key for myIoTDevice. Scrolling further down the Sample request also shows the eventid to invoke this specific API.

Putting it Together

Creating an MQTT Subscriber

Finally, we need to build a MQTT subscriber.  The subscriber code will watch the MQTT topic and send a push notification to the app targeting the end user that we created in the previous section. Fortunately, we can run this on the same Raspberry Pi where we put our MQTT publisher or we can deploy this on a separate Node.JS capable device.

There are a few items you will need to configure before deploying the code.  You will need to set the consolepassword, consoleuser and appID you copied from the Engagement Services console.  It’s important to use your console password and user.  We also need the KSID of the user we created from the console. We can use other parameters, such as the user segment or device ID to identify the target user.  Using user segments is useful if you want to target a group of people in a specific location or a group of people with a specific skill set.

var consolepassword = "";
var consoleuser = "";
var appId = "";

Similar to the push code, the subscriber code will establish a connection with the MQTT broker and watch for messages on the presence topic. When a message is published to the presence topic, the code calls the loginMF function to get an authorization token from MobileFabric

function loginMF() {
    //Login to MobileFabric using the accounts service. I
    //It is important to login using your management console login, 
    // not the application's login for sending messages.

    var req = httpclient.post("https://accounts.auth.konycloud.com/login", loginargs, function(data, response) {
        console.log(data);
        var claims = data.claims_token.value;
        pushPhone(claims);
    });

Its important to note that we are talking to the accounts.auth.konycloud.com platform for authentication since we are validating our console user and password for sending push notifications. The authorization service uses the loginargs argument at the top of the code to pass in the user and password. Once we are authenticated, we can push a message to the phone using the pushPhone function.

For the pushPhone function, you will need to change the murl variable to match the url of the cloud you deployed your code into. In my case, I deployed the code to demo.messaging.konycloud.com.  It’s also important to note that we are using the postargs object from the top of the code as part of the message submission process.

function pushPhone(claims) {
    //call the messaging API using your MF url
    murl = "http://demo.messaging.konycloud.com";
    target = murl + /api/v1/events/push ";
    postargs.headers['X-Kony-Authorization'] = claims;
    postargs.data.messageRequest.messages.message.content.data = mymessage;
    postargs.data.appId = appId;
    httpclient.post(url, postargs, function(data, response) {
        console.log("pushed");
    });
}
});
}

The postargs object has the basic attributes needed to post a message to Kony Engagement Services. Save your code as client.js and you’re ready for the final step.

Once complete, you can start your subscriber code and publisher’s code by issuing the following commands on Raspberry Pi in the directory you created your two scripts.

Node knock.js &  
Node client.js

If you hit the knock sensor, you will see the client code write the following output in the console.

Pushed

This will let you know it saw a message publish to the topic and it sent a push request to the mobile client. If everything is setup correctly, you will see the push notification on your client.

Here is the completed MQTT subscriber code:

var mqtt = require('mqtt');
var client = mqtt.connect('mqtt://test.mosquitto.org');

var Client = require('node-rest-client').Client;
var httpclient = new Client();
var mymessage = "";

//******************************************************************

// Use your manage.kony.com credentials, ! your app credentials to authenticate.
var consolepassword = "";
var consoleuser = "";
var appId = "";

var loginargs = {
    data: {
        "userid": "",
        "password": ""
    },
    headers: {
        "Accept": "application/json",
        "Content-Type": "application/json"
    }
};

loginargs.data.userid = consoleuser;
loginargs.data.password = consolepassword;

var postargs = {
    "data": {
        //I keep the whole message obejct posted here to see an example 
        //filled out for an example that targets a single phone.
        "messageRequest": {
            "appId": "",
            "global": {},
            "event": {
                 "message": {
   "content": {
    "priorityService": "false",
    "eventNamePairs": {
     "key": [
      {
       //REPLACE WITH CONTENT for IOT Device ID
       "content": "xxxx",
       "name": "myIoTDevice"
      }
     ]
    },
    "mimeType": "text/plain"
   },
   "subscribers": {
    "subscriber": [
     {
    //REPLACE WITH YOUR SEGMENATION. If you do not use these parameters, remove them from the payload.
      "ufid": "xxxx",
      "ksid": "xxxx",
      "deviceId": "xxxx"
     }
    ]
   }
  },
//REPLACE WITH EVENTID – EXAMPLE ID BELOW
  "eventid": "7051179322426224607"
 }
 
        }

        /////////////////////////
    },
    "headers": {
        "Accept": "application/json",
        "Content-Type": "application/json",
        "X-Kony-Authorization": "a"
    }
};


client.on('connect', function() {
    // subscribe to the presence topic.
    client.subscribe('presence');

});


client.on('message', function(topic, message) {
    // publish the message to the topic
    console.log(message.toString());
    mymessage = message.toString();
    loginMF();
});



function loginMF() {
    //Login to MobileFabric using the accounts service. I
    //t is important to login using your management console login, 
    // not the application's login for sending messages.

    var req = httpclient.post("https://accounts.auth.konycloud.com/login", loginargs, function(data, response) {
        console.log(data);
        var claims = data.claims_token.value;
        pushPhone(claims);
    });


}

function pushPhone(claims) {
    //call the messaging API using your MF url
    murl = "http://my-demo.messaging.konycloud.com";
    target = murl + "/api/v1//messages";
    postargs.headers['X-Kony-Authorization'] = claims;
    postargs.data.messageRequest.messages.message.content.data = mymessage;
    postargs.data.appId = appId;
    httpclient.post(url, postargs, function(data, response) {
        console.log("pushed");

    });
}

});
}