Sending Data

Follow

You may want to first read this article on the data format in Exosite's platform.

Exosite's Data Format

When sending data to Exosite, you will need to determine which dataport or dataports to write to.  Dataports are resources under a client object that hold time-series data.  Essentially as you write to them, the value is held with a unix time-stamp so that you can go back and get the values over a time period.  Only one value may exist at a specific time stamp.  Any attempts to write a second value at the same time-stamp will fail.

There are two functions to get data into Exosite.  A 'write' and a 'record' function.  The write method allows the platform to time-stamp the data when received with what the server's current time (now).  The record method allows the sender to provide a timestamp along with the value and this is what is used in the dataport storage. 

Choose an API

Some of Exosite's APIs only support write, some support both write and record.  For devices, Exosite recommends using one of the following APIs:

HTTP Data - HTTP REST-like APIs supporting write and multiple write.

CoAP - CoAP based APIs that support write and multiple write.  

RPC - There is a JSON RPC (HTTP transport) and a COBR RPC (CoAP Transport) that support both write and record functions.  

 

What does a 'write' actually do?

The dataports are like global variables that devices and applications can write to with the proper authentication / access rights.  When a device writes to a dataport, generally the API looks something like temperature=32.1, where 'temperature' is the alias of the dataport and 32.1 is the value.  The 'alias' is essentially the global variable name, instead of using the resource identifier (RID) which is a 40 character hash value.

In this case, 32.1 would be stored with a timestamp inside of the platform.  If any application or the device did a read at that specific timestamp, they would get that value.

Sending multiple dataports at a time

The APIs generally all support writing to multiple dataports with one call and take a format like temperature=32.1&humidity=45.  

Sending multiple values to a dataport

For APIs that include the 'record' function, you can send multiple values with their unique timestamps.  For example, the JSON RPC record function allows you to send an array of arrays like [[timestamp1:value1],[timestamp2:value2]].

Sending formatted data

The string type dataport can take a formatted string (JSON, XML, CSV, etc).  A device could send a JSON packet in this way.  That entire string is stored at a timestamp of course and is up to the application that is interacting / processing the data to decode it properly.

You could send a string like '{"temperature":32.1,{"lat":49.3233,"long":-49.090},"humidity":45}' for example.  This would be stored complete and would need to be parsed by the application.

 

Example Use Cases

A device needs to send 5 pieces of information, some of which may be raw sensor data, some is more for information (device status, error messages). 

Let's cover the 5 pieces of information this device has to send first. Data is held in the One Platform as 'Dataports', also referred to as Data Sources (this is the nomenclature Exosite Portals uses). Each of these dataports is time-series data, so in the One Platform, they store new values with a time-stamp when written to. If using a API that allows providing a timestamp, the platform will use provided time, otherwise it will use the server's timestamp when data is received. (Note: All data is stored with Unix Time Stamp, UTC)

 

Send each piece of data separately to it's own data port.

This approach will write to each dataport. Note, all of the Exosite API's allow for multiple dataports to be written with one request. If I were using the HTTP Data Interface API, it would look something like this:

POST /api:v1/stack/alias HTTP/1.1
Host: m2.exosite.com
Content-Type: application/x-www-form-urlencoded; charset=utf-8
X-Exosite-CIK: fff51d1a260b4b258fefffd9a9313c433e419fff
 
data1=34&data2=490&data3=ok&data4=test&data5=1

Send all of the data as a formatted packet to one data port and parse the data using a script.

This approach will write all of the data to one dataport as a string in some type of formatted data (CSV, JSON, etc). If I were still using the HTTP Data Interface API, it would look something like this below. Let's assume the data packet I want to send is JSON formatted data and is the same as approach number 1 above. The JSON packet would look like this and we would send it as a string to a data port called 'datapacket'.  {"data1":34,"data2"=490,"data3"="ok","data4"="test","data5"=1}

 
POST /api:v1/stack/alias HTTP/1.1
Host: m2.exosite.com
Content-Type: application/x-www-form-urlencoded; charset=utf-8
X-Exosite-CIK: fff51d1a260b4b258fefffd9a9313c433e419fff
  
datapacket=%7B%22data1%22%3A34%2C%22data2%22%3D490%2C%22data3%22%3D%22ok%22%2C%22data4%22%3D%22test%22%2C%22data5%22%3D1%7D

Note that the body is URL encoded, that's why all of the % signs are showing up.

You may ask "Why would I do this?". Well, in doing this you now have one dataport called 'datapacket' that all data is sent to. Since it is formatted data, you may not send all of the data every time, you may just send one new piece of information (data1) or all of them. On the One Platform side of things, it has the rawpacket dataport receiving this data. You can write a script that simply waits for new values to 'rawpacket' and then parses it / processes it. This gives you a chance to convert the data before it is written to individual dataports. You could do this same thing with approach #1 above, but you would have a script for each dataport and you would have a 'raw' and 'processes' dataport for each.

Here may be what the One Platform script would look like to parse the data out of the formatted JSON string and put into individual dataports:

local packet = alias['rawpacket']
local temp = alias['temperature']
local sig = alias['signal']
local status = alias['status'] 
local debug = alias['debug']
local button = alias['buttonstatus']
 
 
local converttemp(tempC)
 -- conversion code, perhaps convert raw analog to degrees C or F
end
 
 
local getusermessage(status)
-- use status to provide a friendly message to the user on the web portal
-- convert to a string to return
end
 
 
while true do
  local ts1 = packet.wait()
  local rawdata = json.decode(packet[ts1])  -- my data is in JSON format, decode it into lua table
  if data then
    if data.data1 then
      temp.value = converttemp(data.data1)
    end
    if data.data2 then
      sig.value = data.data2
    end
    if data.data3 then
      status.value = getusermessage(data.data3)
    end
    if data.data4 then
      debug.value = data.data4
    end
    if data.data5 then
      button.value = data.data5
    end
  end
end

 

 

Have more questions? Submit a request

Comments

  • Avatar
    Kurt Larson

    I found I needed to add a new line at the end of this example to make it go:
    "POST /api:v1/stack/alias?data1&command HTTP/1.1
    Host: m2.exosite.com
    Accept: application/x-www-form-urlencoded; charset=utf-8
    X-Exosite-CIK: fff51d1a260b4b258fefffd9a9313c433e419fff"
    insert new line here

Powered by Zendesk