Leveraging IoT Data

IoT applications generate loads of data stemming from the devices and the services they involve. Because data is issued in (near) real-time from a wide range of sources (e.g. wearable devices, home, vehicles, urban equipment, services, etc.), it holds the promise of unlocking tremendous opportunities, such as improvements of products and services quality or the creation of new business models, thanks to an increased knowledge of the applications’ environment.

However, without the ability to turn it into actionnable information, this huge amount of data is just “noise”. Therefore, IoT applications should first be able to process data, transform it and/or enrich it into meaningful data sets, which is something you can do using scriptr.io. As a second step, IoT applications should be able to rely on sound analytics infrastructure that will help turning data sets into actionable information, gaining granular insights into their environment.

Keen.io

Keen.io is a comprehensive data analytics service for the Internet of Things. It provides valuable SDKs and REST APIs to store events on its premises, to define and run analytics and queries on data and display them through – embedded – charts, thanks to a library that can be used to build reports and dashboards. We thought scriptr.io’s developers would be interested in leveraging Keen.io’s set of features from within their scripts and thus, we wrapped Keen.io’s APIs into a connector. The latter can easily be deployed into your scriptr.io account from your workspace, by clicking on “New script” > “Import module” then selecting “Keen.io”.

Sample implementation: satisfaction survey


In the remainder of this document, we’ll implement a simple satisfaction survey application to illustrate how easy it is to leverage Keen.io’s features using the connector. Our scenario will be as follows: using a – very basic – web page, end users will rate the quality of the services of a given venue by pressing one of the “good”, “average” or “bad” icons on the page. These values, along with the corresponding venue, will be sent in real-time to Keen.io. We will then implement some simple reporting based on the ratings: (1) determine the number of good, average and bad ratings per venue, (2) determine what venue has the best rating and conversely (3) what venue has the worse evaluations.

Pre-requisites
In order to implement the following sample application, you need to have:

  • Created an account at Keen.io and a project,
  • A scriptr.io account,
  • Installed the Keen.io module in your scriptr.io account (from your workspace, click on “New Script” > “Import” and scroll down to Keen.io),
  • Updated the “/keenio/config” file in your workspace, replacing the values of “readKey” and “writeKey” with those that are associated to your Keen.io project

Don’t worry though it you do not yet meet the above requirements. You can still check the code below and try the app using the demo link.

Source code.

Requiring the Keen.io connector

Before we can use Keen.io’s feature from within our scripts, we need to require the corresponding connector (make sure you imported it to your workspace). Let’s go ahead an create a script (we’ll call it “analytics”) into which we’ll type the following lines:

var keenioclient = require("keenio/keenioclient");
var keenio = new keenioclient.Keenio("YOUR_KEENIO_PROJECT_KEY"); // replace with your actual Keen.io project key

What we just did is to require (import) the keenio connector to our script and create an instance of the Keenio class, which is our main entry point to Keen.io’s APIs.

Sending events to Keen.io

First step of our sample application is to store the events that were generated by the survey into Keen.io. As we previously metioned, the data we need to store for every event are the rating and the venue. In addition, since Keen.io associates events to “collections”, we will have to specify what collection to use for the event.

var COLLECTION = "satisfaction_survey";

// rating can be any JSON structure, in our case {"rating": 0_1_or_2, "location": "venue1_or_venue2_or_venue3"} 
function addRating(rating, location) {
  
  var event = {
    rating:rating,
    location: location
  };
  
  return keenio.recordEvent({data:event, collection:COLLECTION});
}

As you can see in the above code, to push an event to Keen.io, you just need to create a data structure with a “data” property holding the event’s data, and a “collection” property referring to the collection to which the event belongs. We then pass this structure to the recordEvent method of the keenio object.

Get ratings counts

Now that we can send as many events that we need to Keen.io, let’s see how we can retrieve the count of each rating value (good, average, bad) for a given location. That’s actually pretty easy to do, since it is just about counting the number of different values, for the provided location. For that, we’ll create an “Analysis” object, used to execute queries and more particularly “count” queries in our case:

function countResults(location) {
  
  var analyses = keenio.createAnalyses();  // We need to create an Analyses object that will be used to issue queries
  var params = {    
    event_collection: COLLECTION,
    timeframe: "this_1_year", // the time frame we are interested in
    group_by: "rating",
    filters:  ["location == " + location] // we filter results for that location only
  };
              
  return analyses.count(params); // ask Keen.io to "count" according to the provided parameters
}

Get best and worse locations

Getting the best, respectively worse, location consists in finding the location with the highest, respectively lowest, rating average. Therefore, what we need is to ask Keen.io to calculate the average rating of all our locations, using once again an instance of Analyses:

function getRatingsAverage() {
  
  var analyses = keenio.createAnalyses();  
  var params = {    
    event_collection: COLLECTION,
    timeframe: "this_1_year",
    target_property: "rating",
    group_by: "location"
  };
  
  return analyses.average(params).result;   
}

Once we get the average, we just need to loop through the result to find the location with the best, respectively worse, average:

function getBestVenue() {
  
  var ratings = getRatingsAverage();
  var max = 0;
  var bestVenue = "";
  for (var i = 0; i < ratings.length; i++) { if (ratings[i].result > max) {
      
      max = ratings[i].result;
      bestVenue = ratings[i].location;
    } 
  }
  return bestVenue;
}

Add a rating

Let’s create the “addRating” script that will be invoked through HTTP requests to post new ratings. The script retrieves the rating and location parameters from the request and pass them to the “addRating” function of the “analytics” script.

// Note: for simplication purposes the below code is not checking the availability of the rating and location parameters
// nore does it cater to exceptions that might be thrown by the underlying code
var analytics = require("./analytics");
var rating = request.body ? request.body.rating : request.parameters.rating;
var location = request.body ? request.body.location : request.parameters.location;
return analytics.addRating(Number(rating), location);

Get the code

You can get the source code of this sample application from Github.

Try it!

Start the survey.