Internet of Things (IoT) Use CaseΒΆ

This tutorial builds a simple Internet of Things (IoT) application using JSON Studio and the Gateway. In most IoT applications sensors, devices, phones etc. generate data that needs to be collected in a central server and used for various application functionalities. JSON is the perfect form to store IoT data because such data can be diverse (different devices produce different data), data structures will change over time (different generations of devices may output different data and certainly no one will upgrade all devices), etc. JSON is so flexible that different devices/version etc. can create and send anything and this data can later be used for alerts, maintenance, analytics etc.

Starting with version 2.2 the Gateway can be used to insert (or update) data in addition to the classic use of the Gateway to query data - this is the main functionality used in this tutorial. The stages of this tutorial are:

  • Build a “device” that generates JSON data.
  • Send that data to the Gateway and have the Gateway insert this data into the database.
  • Write a few queries, reports and graphs that use this data using JSON Studio and expose them also through the Gateway.
  • Build application-specific functionality that should be called whenever a new device message is received and that does some operation.

In order to keep the tutorial simple and focused on how to use the Gateway, the “device” used below is simply the machine on which the tutorial is being built, a MacBook Pro machine. Using a simple Unix-style command, you can get some metrics/readings about the current state of the machine - e.g. temperature reading. For example, you can use a simple application called Temperature Monitor that you can download from:

http://www.bresink.com/osx/TemperatureMonitor.html

You can get temperature data using this utility from the command line or from a script. From the command line:

$ ./TemperatureMonitor.app/Contents/MacOS/tempmonitor -c -l -a
SMART Disk APPLE HDD HTS541010A9E682 (J5500071GB4LND): 29 C
SMC AMBIENT AIR: 35 C
SMC BATTERY: 29 C
SMC BATTERY CHARGER PROXIMITY: 32 C
SMC BATTERY POSITION 2: 29 C
SMC BATTERY POSITION 3: 27 C
SMC CPU A PROXIMITY: 42 C
SMC GPU 1 CHIP: 39 C
SMC GPU DIODE: 42 C
SMC LEFT PALM REST: 28 C
SMC MAIN HEAT SINK 2: 38 C
SMC MAIN HEAT SINK 3: 37 C
SMC PLATFORM CONTROLLER HUB: 38 C

Using this utility, we build a script that runs in a loop and extracts these readings every sixty seconds and creates a JSON document from them that looks like:

{
  "SMART Disk APPLE HDD HTS541010A9E682 (J5500071GB4LND)": 29,
    "SMC AMBIENT AIR": 35,
    "SMC BATTERY": 29,
    "SMC BATTERY CHARGER PROXIMITY": 32,
    "SMC BATTERY POSITION 2": 29,
    "SMC BATTERY POSITION 3": 27,
    "SMC CPU A PROXIMITY": 42,
    "SMC GPU 1 CHIP": 39,
    "SMC GPU DIODE": 42,
    "SMC LEFT PALM REST": 28,
    "SMC MAIN HEAT SINK 2": 38,
    "SMC MAIN HEAT SINK 3": 37,
    "SMC PLATFORM CONTROLLER HUB": 38,
    "MAC": "40:6A:8E:4C:7A:D5",
    "TS": {
    "$date": "2014-08-14T20:00:31.000Z"
    }
}

Note that in addition to the temperature readings the JSON document includes the date/time for the measurement and the MAC address to identify the machine.

The gateway in this case is running on host qa6.jsonar.com and the collection into which all these documents should be inserted is called iot1. The script will call curl in order to send the JSON data to the IoT server (the Gateway). First, ensure that the curl command is indeed working correctly and that data is inserted into the collection (the data below is arbitrary and only used for making sure the data gets saved in the database):

$ curl --ssl -k https://qa6.jsonar.com:8443/sonarFinder/Gateway -d db=test -d port=47017 -d host=localhost -d type=insert -d insertJson="{device: \"MacBook1\", text:\"This is a test\", temp: 66, time: 10}"  -d col=iot1 -d name=
{"output": { "serverUsed" : "qa6.jsonar.com:47017" , "ok" : 1 , "n" : 0}}

Specifically notice that type=insert so that the Gateway will be used to create a document per each message it receives from the device. The output gives us an “ok”:1 , but to make sure let’s log into the Studio and look whether we now have a collection named iot1 with a document. Indeed we do:

_images/iot_1.jpg

Now we run the script so that it sends the temperature readings from the Mac every 60 seconds. Our IoT server is now tracking the heat readings from the Mac (and hopefully many more such devices).

Because the data is in the database and JSON Studio can build reports, graphs, aggregation pipelines etc, the data can now be easily accessible. For example, the following graphs is the result of a simple aggregation pipeline and plots temperature readings from the last half hour.

_images/iot_2.jpg

And a full report of all values in the last half hour for this MAC address / device:

_images/iot_3.jpg

Such reports and graphs can be viewed within JSON Studio or defined using the Studio and then used directly from your own dashboards, applications or even Web sites. You can build complex analytics on this device data within minutes. For example, the following pipeline gives you the min/max/avg values for all devices or use the MAC address to parameterize and get the min/max/avg values per device in a report or a dashboard:

_images/iot_4.jpg _images/iot_5.jpg

View the other tutorials in this series to see how easy it is to build queries, reports and graphs using the Studio and how to expose them to applications and dashboards using the Gateway.

Finally, let’s add a bit of application code to alert us if the temperature reading goes over a certain value. Theoretically we could continuously query the database and see the inserted that but that is both inefficient and is not really the paradigm we want in IoT. Instead, we want to “intercept” each JSON reading coming in and look at it before it is inserted into the database.

This is supported by the Gateway using the JSONTransformer interface:

public interface JSONTransformer {

   /*
    * Returns string or DBObject to be used in the various write operations.
    * Allows application-specific transformations.
    * Return null if should not continue.
    *
    */

   public static enum WriteType { INSERT, UPDATE, UPSERT };

   // Used for inserts
   public String transform(String input, String collectionName, WriteType wt, HttpServletRequest req);
   public Object transform(Object input, String collectionName, WriteType wt, HttpServletRequest req);

   // Used for updates
   public String[] transform(String input, String query, boolean upsert, boolean multi, String collectionName, WriteType wt, HttpServletRequest req);
   public Object[] transform(Object input, Object query, boolean upsert, boolean multi, String collectionName, WriteType wt, HttpServletRequest req);


}

We will write a simple class that implements this interface and register it with the Gateway. Every incoming document will be passed to our method before it gets inserted in the database. The class is called before the insertion and receives the JSON to give you the opportunity to change the JSON structure before it is inserted. You can do whatever you want - you can compute aggregate functions, you can update a separate collection (e.g. a state collection); anything you can program in Java. In our case we will not change the JSON but only pull out the temperature reading and alert if it goes over a certain threshold (we’re just going to print it to the log file here for simplicity). In a real scenario you can track the last few readings, track how fast the temperature is increasing etc.

The class that does the work is:

public class IoTJSONTransformer implements JSONTransformer {

   // Used for inserts
   public String transform(String input, String collectionName, WriteType wt, HttpServletRequest req) {
      return input;
   }

   // Used for inserts
   public Object transform(Object input, String collectionName, WriteType wt, HttpServletRequest req) {
      DBObject dbo = (DBObject)input;
      int cpuTempReading = (Integer)dbo.get("SMC CPU A PROXIMITY"); // Get the measurement we're tracking
      if (cpuTempReading > 50) {  // Very simple check for this exercise - normally more elaborate logic
         System.out.println("SHUT DOWN MAC QUICKLY - IT'LL FRY!! Temperature is now " + cpuTempReading);  // Simulate alert
         System.out.println(dbo);
      }
      return input; // Not changing the stored JSON
   }

   // Used for updates
   public String[] transform(String input, String query, boolean upsert, boolean multi, String collectionName, WriteType wt, HttpServletRequest req) {
      String[] ret = {input, query};
      return ret;
   }

   // Used for updates
   public Object[] transform(Object input, Object query, boolean upsert, boolean multi, String collectionName, WriteType wt, HttpServletRequest req) {
      Object[] ret = {input, query};
      return ret;
   }

}

To register change the following entry in <install dir>/jsonar/sonarFinder/WEB-INF/web.xml:

<context-param>
 <param-name>jsonStudio.jsonTransformer</param-name>
 <param-value>com.jsonar.util.DefaultJSONTransformer</param-value>
</context-param>

to:

<context-param>
 <param-name>jsonStudio.jsonTransformer</param-name>
 <param-value>com.jsonar.tutorial.IoTJSONTransformer</param-value>
</context-param>

Now if we run the script and place some load on the Mac (causing it to heat up because it is working harder) the documents will show the temperature increase and as soon as the threshold is reached we will see the following in the standard log:

SHUT DOWN MAC QUICKLY - IT'LL FRY!! Temperature is now 51
{ "SMART Disk APPLE HDD HTS541010A9E682 (J5500071GB4LND)" : 30 , "SMC AMBIENT AIR" : 35 , "SMC BATTERY" : 31 , "SMC BATTERY CHARGER PROXIMITY" : 32 ,
"SMC BATTERY POSITION 2" : 29 , "SMC BATTERY POSITION 3" : 27 , "SMC CPU A PROXIMITY" : 51 , "SMC GPU 1 CHIP" : 41 , "SMC GPU DIODE" : 44 ,
"SMC LEFT PALM REST" : 28 , "SMC MAIN HEAT SINK 2" : 38 , "SMC MAIN HEAT SINK 3" : 37 , "SMC PLATFORM CONTROLLER HUB" : 38 ,
"MAC" : "40:6A:8E:4C:7A:D5" , "TS" : { "$date" : "2014-08-14T21:09:31.000Z"}}

Table Of Contents

Previous topic

Implementing a Simple Asset Management System

Next topic

Building a Recommendation Engine using R and JSON Studio using Data Stored in MongoDB

Copyright © 2013-2016 jSonar, Inc
MongoDB is a registered trademark of MongoDB Inc. Excel is a trademark of Microsoft Inc. JSON Studio is a registered trademark of jSonar Inc. All trademarks and service marks are the property of their respective owners.