element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
In the Air Design Challenge
  • Challenges & Projects
  • Design Challenges
  • In the Air Design Challenge
  • More
  • Cancel
In the Air Design Challenge
Blog AirMobile - 12 - AirVantage REST API
  • Blog
  • Forum
  • Documents
  • Polls
  • Files
  • Events
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: amgalbu
  • Date Created: 15 Dec 2014 2:35 PM Date Created
  • Views 549 views
  • Likes 2 likes
  • Comments 0 comments
  • iot_distributed
  • rest
  • airvantage
  • in_the_air
  • in-the-air
Related
Recommended

AirMobile - 12 - AirVantage REST API

amgalbu
amgalbu
15 Dec 2014

AirVantage REST API

 

In the previous post, I created a Java MQTT client to push data into the AirVantage cloud platform.

Next step is to read it out and make it available to OpenHAB. In this post I will talk about the AirVantage REST API, whereas in the next post I will provide details about my implementation of an OpenHAB  binding to get data from AirVantage

 

Authentication

The first step in getting data is to authenticate yourself. AirVantage supports three kinds of authentication

For development, the easiest approach is to use the access token that can be read on the AirVantage portal.

 

image

 

For a real-world application, probably the most user-friendly approach is to define a username and a password in a configuration file. This is the approach I will use later to create OpenHAB binding. The URL to authenticate using a username-password pair, is as follow

"https://" + server + "/api/oauth/token?grant_type=password&username=" +    username + "&password=" + password +

      "&client_id=" + clientId + "&client_secret=" + clientSecret +

      "&redirect_uri=oauth://airvantage"

 

server can be either na.airvantage.net or eu.airvantage.net

username and password are the credentials you typically use to login into the AirVantage portal

clientId and clientSecret identify the device that is requesting data and can be generated on the AirVantage.

The response includes the access token for use with following requests

{

  "access_token": "fe47d528-7414-4962-a7e6-ee6b82491f7a",

  "refresh_token": "9b465388-c9e2-45d3-98d0-1a44a503ec40",

  "expires_in": 86400,

}

 

This URL returns an access token that needs to be appended to every URL. Note that access token has an expiration time. This means that care must be taken to refresh the access token periodically

 

Last value

To show the current (or better, the last) sensor reading in OpenHAB, the last known value has to be read, This can be accomplished by invoking the following URL

"https://" + server + "/api/V1/systems/" systemUid + /"data?access_token="

      + access_token + "&ids=" + data

 

systemUid is the unique identifier of the system to query. The Uid can be read on the portal

 

image

 

dataIds is a comma-separated list of data to read. Keeping in mind the AirMobile application, an example of dataIds is

dataIds=airmobile_temperature.value, airmobile_temperature.latitude, airmobile_temperature.longitude

The document that is returned has the following format

{

   "airmobile_temperature.value": [{

"value": 30.1,

      "timestamp": 1331906459440

   }],

   " airmobile_temperature.latitude ": [{

"value": 45.913405,

"timestamp": 1331906459440

   }],

   " airmobile_temperature.longitude": [{

"value": "10.998",

"timestamp": 1331906459440

   }]

}

 

Raw values

Raw values are unfiltered values. Values are returned as sent by the field devices. Only values for the last three hours or 10000 values are available as raw data.

To get raw values, the following URL needs to be invoked

"https://" + server + "/api/V1/systems/data/raw?access_token="

      + access_token + "&targetIds=" + systemUid + "&dataIds=" + data

 

The response to this request has the following format

{

"4c6cfc5407ad4a7985e3792408bbdb4e":

   {

      "airmobile_temperature.value": [{

         "value": 30.1,

         "timestamp": 1331906459440

      }],

      " airmobile_temperature.latitude ": [{

         "value": 45.913405,

         "timestamp": 1331906459440

      }],

      " airmobile_temperature.longitude": [{

         "value": "10.998",

         "timestamp": 1331906459440

      }]

   }

}

 

Aggregate values

If data over a longer time interval is required, data must be accessed using aggregate functions. Aggregate functions apply a certain function over data in a given time interval (for example one hour) and return that value instead of all the value in that time interval. Available aggregate functions include mean, sum, min, max, standard deviation, number of samples

To get aggregate values, the following URL needs to be invoked

"https://" + server + "/api/V1/systems/data/aggregated?access_token="

      + access_token + "&dataIds=" + data

      + "&targetIds=" + systemUid

      + "&from=" + (System.currentTimeMillis() - 23 * 60 * 60 * 1000)

      + "&to=" + (System.currentTimeMillis() + 1 * 60 * 60 * 1000)

 

There are other possible parameters that can be added to the URL, like interval. Intervals are specified by a multiplier and a unit of time, i.e. 6hour or 1day. The supported time units are:

  • hour - Hours
  • day - Days
  • month - Months
  • year - Years

The multiplier has to be lower than 50. The default interval is 1 hour

The response to this request is similar to the response shown in previous section

 

An helper class

All this methods have been encapsulated in a Java class (AirVantageClient.java)  that will be very useful in the next post, when I will talk about the OpenHAB binding implementation

This class has a few fetaures that worth to be highlighted

Deserialization

I used GSON library to deserialize responses. Because responses may contain fields whose name has periods in it, a custom deserializer is required. This is for example the implementation of the custom deserializer for raw data response

 

publicclass AirVantageRawData
{
   public List<Datapoint> values;
   public List<Datapoint> lats;
   public List<Datapoint> longs;
};

private class AirVantageRawDataDeserializer implements
  JsonDeserializer<AirVantageRawData> {

   @Override
   public AirVantageRawData deserialize(JsonElement json, Type type,                          JsonDeserializationContext context) throws JsonParseException
   {
      JsonObject jobject = (JsonObject) json;

      AirVantageRawData data = new AirVantageRawData();

      Type collectionType = new TypeToken<List<Datapoint>>() 
 {}.getType();

      JsonArray array =
 jobject.get("airmobile_temperature.value").getAsJsonArray();
      data.values = context.deserialize(array, collectionType);

      array = jobject.get("airmobile_temperature.latitude").getAsJsonArray();
      data.lats = context.deserialize(array, collectionType);

      array = jobject.get("airmobile_temperature.longitude").getAsJsonArray();
      data.longs = context.deserialize(array, collectionType);
   
      return data;
 }
}

 

The usage of the deserializer is as follow

 

   Gson gson = new GsonBuilder()
       .registerTypeAdapter(AirVantageRawData.class, 
 new AirVantageRawDataDeserializer())
       .create();
   AirVantageRawData rawData = gson.fromJson(isr, collectionType);

Data fusion

Unfortunately it is not possible to read out a complete asset. Instead, it is only possible to read a specific data value in an asset.

For this reason, I created a function to merge the three array of data values (value, latitude and longitude) into a single class, because having a single class is definitely more handy. This is the code to merge data value arrays

 

publicclass GeoDatapoint {
      public long timestamp;
      public double latitude;
      public double longitude;
      public double value;
}

List<GeoDatapoint> points = new ArrayList<GeoDatapoint>();
for (int i=0; i<rawData.values.size(); i++)
{
   Datapoint lat = rawData.lats.get(i);
   Datapoint lon = rawData.longs.get(i);
   Datapoint val = rawData.values.get(i);

   GeoDatapoint dp = new GeoDatapoint();
   dp.latitude = lat.value;
   dp.longitude = lon.value;
   dp.value = val.value;

   points.add(dp);
}

  • Sign in to reply
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube