About Cradlepoint

Cradlepoint is a global market leader in 4G and LTE solutions that combine wireless first class routers and cloud-based device management for a wide range of industries and domains. Cradlepoint notably provides a very interesting cloud-based management platform, called ECM, used to deploy and dynamically manage networks at geographically distributed locations. Among the many interesting features of the ECM is the availability of an API that provides developers with the building blocks needed to implement bespoke applications that access the data of their Cradlepoint devices.

Cradlepoint connector

As we’ve done it with other interesting IoT solutions providers and device manufacturers, we’ve wrapped ECM’s API into a connector that is delivered as a set of native scripts that you can easily deploy into your application on scriptr.io. Using the connector, you can seamlessly incorporate ECM’s features into your own IoT application and augment ECM’s APIs with your own logic. We’ll actually demonstrate how to do this through a sample application described in the following paragraphs. You can read this step by tutorial to implement the sample application or simply check the online demo.

Sample application

Our sample application will expose the following features:

  • Retrieve the daily bytes usage of a given router, for the current month, and display it in a line chart
  • Calculate the total bytes usage for the current month and display it in a gauge
  • Display the router and related information on a map
  • Allow the end user to subscribe to alerts that are automatically sent whenever the total usage is above a threshold he specifies

Regarding the first three features on the list, note that our purpose is to show how simple it is to leverage the ECM API using the connector, not to provide an alternative to the dashboard that is already available in ECM.

Get the source code from Github

Pre-requisites

If you do not have an ECM account yet, that’s not a problem! You can still check the code in the coming paragraphs and try this demo link.

Deploy the Cradlepoint Connector

Sign-in to your scriptr.io workspace. In the bottom let corner of the screen, click on “+ New Script” > “Import Modules”, then scroll down to “Cradlepoint” then click “Import”.

Seamless Integration: A Monitor Object

We’ll start the implementation of our sample application by creating a script that defines a “Monitor” class that leverages our connector to provide all the core features required by the application, i.e. list the daily bytes usage, get the monthly bytes usage and get router data + its geographical location.

As a first step, we have to require the “principal” and “cradlepointmanagement” modules of the Cradlepoint connector. The “principal” module defines the “Principal” class that is used to wrap the ECM credentials we intend to use. The “cradlepointmanagement” module contains the CradlepointManagement class which is used to obtain instances of other controller classes (ECM API Wrappers).

// require the principal module to wrap our ECM credentials
var principalModule = require("modules/cradlepoint/auth/principal.js");
// require the cradlepointmanagement module
var cradlepointManagementModule = require("modules/cradlepoint/cradlepointmanagement.js");

Let’s now create the Monitor class to retrieve the data of a specific router. We’ll specify the name of the router using the constructor function of the class:

function Monitor(name) {
  
  // let's complain if the name parameter is not defined, by throwing an exception
  if (!name) {    
    throw {
      errorCode:"Missing_Parameter",
      errorDetail: "You need to pass the name of the router as a parmeter"
    };
  }

Let’s update the above code by creating an instance of CradlepointManager and use it to obtain an instance of RouterManager, which allows for manipulating Cradlepoint routers and more specifically, obtain an instance of Router that points at our specific device:

function Monitor(name) {
  
  if (!name) {
    
    throw {
      errorCode:"Missing_Parameter",
      errorDetail: "You need to pass the name of the router as a parmeter"
    };
  }
  
  // Create principal with your ECM role credentials
  this.principal = new principalModule.Principal({ecmId:"YOUR_ECM_ID", ecmKey:"YOUR_ECM_KEY"});
  
  // Instanciate a CradlepointMananger using the above credentials
  this.cradlepointManager = new cradlepointManagementModule.CradlepointManager({principal:this.principal});

  //  Obtain an instance of RouterManager to manipulate Routers
  this.routerManager = this.cradlepointManager.getRouterManager();

  // Obtain a reference to a specific Router
  this.router = this.routerManager.getRouter({name:name});
}

List the Daily Usage

As mentioned, we need to list the daily usage for the router since the beginning of the month, so let’s add a method to our Monitor class, which will list all usage samples since that date. This is pretty simple to do as we actually just need to invoke the built-in “listStreamUsageSamples()” method of our router. Notice how we specify our date filter by passing the “filter” property and how we ask the connector to return all available records by setting the paging.limit parameter.

Monitor.prototype.listMonthlyUsage = function() {
  
  // Beginning of the month  
  var date = new Date();
  var month = date.getMonth() + 1; 
  var year = date.getFullYear();
  var firstOfMonth = new Date(year + "/" + month + "/01");

  // Retrieve usage samples for that router (all available pages)                         
  return this.router.listStreamUsageSamples ({filter:{created_at__gt:firstOfMonth.toISOString()}, paging:{offset:1, limit:99999}}).data;
};

Get the Total Monthly Usage

Let’s go ahead now and calculate the total usage for the month. This is very easy to do as well: all we need is to invoke the listMonthlyUsage() method we’ve just created, loop through the results and add up the daily usages:

Monitor.prototype.geTotalMonthlyUsage = function(){
  
  var data =  this.listMonthlyUsage();
  var bytesIn = 0;
  var bytesOut = 0;
  for (var i = 0; i < data.length; i++) {
    
    bytesIn += data[i].bytes_in;
    bytesOut += data[i].bytes_out;
  }
  
  return {bytesIn:bytesIn, bytesOut:bytesOut};
};

Get Router Details and Coordinates

Last part of our Monitor class is adding a method that returns our router’s data combined to its location (lat and lon). To obtain the latter, we’ll invoke a public API that provides location data based on a given IP (we’ll use our router’s IP). Once again, this is pretty straightforward to do:

Monitor.prototype.getRouter = function() {
  
  // Invoke the IP-To-Coordinates API
  var http = require("http");
  var queryParams = {
    "url": "http://ip-api.com/json/" + this.router["ipv4_address"] 
  };

  var queryResponse = http.request(queryParams);
  
  // If a response was obtained, combine it's returned data to router's data
  if (queryResponse.body) {
    
    var location = JSON.parse(queryResponse.body);
    for (var prop in location) {
      this.router[prop] = location[prop];      
    }
    
    delete this.router.client; // remove client (connector) specific data
    return this.router;
  }else {
   return {};
  }
};

Building the Dashboard

We’ll build our dashboard using scriptr.io’s powerful Google chart scripts, which transform data returned by scripts (in a specific format) into charts. Since Google chart scripts cannot invoke functions inside others scripts, we’ll create three separate scripts that will respectively invoke the listMonthlyUsage(), geTotalMonthlyUsage() and getRouter() functions of our Monitor, transform the data they return into the adequate Google chart format and return it to the Google charts.

Total usage API

Let’s create a simple script that requires our monitor module, creates an instance of the Monitor class and invokes the geTotalMonthlyUsage () function, then transforms the obtained data structure into a format that can be used to display a gauge:

var monitorModule = require("../monitor.js");

try {
  
  var monitor = new monitorModule.Monitor("eb-wan-kenobe");
  var total = monitor.geTotalMonthlyUsage();
  var totalBytes = total.bytesIn + total.bytesOut
  return [
    ["Usage", "Total"],
    ["Bytes", totalBytes ]
  ];
}catch(exception) {
  return exception;
}

Save your script (call it “getMonthlyUsage” for example) and head to the next step.

Monthly Usage Gauge

In this step, we create a Google chart script to display the data returned by the above code into a line chart. In your scriptr.io workspace, click on “+New Script” > “Google Chart”. Select the above script (“listMonthlyUsage”) as a data source then choose the “gauge” chart as output (if the gauge does not appear in the “recommended charts” list, click on “More” to see more chart types).

totalysage

You can further customize the look of the gauge by clicking on “customize”.

Augment the API: Receive a notification when usage is above a predefined threshold

In this last step, we want to add some logic to send an email to a predefined address whenever the monthly usage is above a given threshold. To keep it simple, we’ll add this logic in the “getMonthlyUsage” script above, by inserting a few lines of code:

var monitorModule = require("../monitor.js");	 	 
try {	 	 
 	 	 
 // ... 	 	 
 	 	 
 // retrieve target email address and max threshold from request parameters	 	 
 var email = request.parameters.email;	 	 
 // determine threshold value, if not specified used default	 	 
 var threshold = request.parameters.threshold ? Number(request.parameters.threshold) : 4500000;	 	 
 	 	 
 // if email address is provided check if total usage is great or equal to max threshold	 	 
 // if so, send a notification by email	 	 
 if (email) {	 	 
 	 	 
   if (totalBytes >= threshold) {	 	 
 	 	 
     var msg = "Your usage (" + totalBytes + ") is above the threshold (" + threshold + ")";	 	 
     sendMail(email, "Usage monitor", "Monthly usage alert", msg); 	 	 
   }	 	 
 } 	 	 
 	 	 
 // ...	 	 
}catch(exception) {	 	 
 return exception;	 	 
}

Note: Google chart scripts automatically forward any parameter they receive in their request to their data source script! Therefore, passing the email and threshold upon the invocation of the Gauge script will allows you to forward these parameters to the getMonthlyUsage” script!

Get the Source Code

Get the source code from Github

Try it

You can try the sample application online:

  • Load the dashboard
  • Receive notifications: add email and threshold parameters to the above link, e.g. https://iotdemos.scriptrapps.io/samples/cradlepointsample/view/dashboard?email=YOUR_EMAIL&threshold=SOME_VALUE_BELOW_5000000