Documentation:API Documentation

From Sense Tecnic Wiki

Jump to: navigation, search

Contents

Overview

This document describes the current WoTKit API.

Authentication

The WoTKit API uses both Keys with basic authentication and Applications with OAuth2 authorization to control access to user's sensors and their data. Using the WoTKit portal, developers can create keys or register applications to allow access to the WoTKit from server based applications, integration scripts, or sensor gateways (clients).

Please note
Most examples in this document use basic authentication with keys or WoTKit username and passwords. However,

OAuth2 authorization is also possible by removing the id and password and by appending an access_token parameter. See Applications and OAuth2 for details.

Keys and Basic Authentication

Keys are created on the WoTKit UI (http://wotkit.sensetecnic.com/wotkit/keys) and are unique to each user.

To grant a client access to your sensors, you can create a key. The client can then be supplied the auto-generated 'key id' and 'key password'. These will act as username and password credentials, using basic authentication to access sensors on the user's behalf.

For example, the following curl command uses a 'key id' and 'key password' to get information about the sensor sensetecnic.mule1. (Note that you will need to replace the {key_id} and {key_password} in the code with appropriate values copied from the WoTKit UI.)

curl --user {key_id}:{key_password} "http://wotkit.sensetecnic.com/api/sensors/sensetecnic.mule1"

This returns:

{
	"name":"mule1",
	"fields":[
		{"name":"lat","value":49.20532,"type":"NUMBER","index":0,"required":true,"longName":"latitude","lastUpdate":"2012-12-07T01:47:18.639Z"},
		{"name":"lng","value":-123.1404,"type":"NUMBER","index":1,"required":true,"longName":"longitude","lastUpdate":"2012-12-07T01:47:18.639Z"},
		{"name":"value","value":58.0,"type":"NUMBER","index":2,"required":true,"longName":"Data","lastUpdate":"2012-12-07T01:47:18.639Z"},
		{"name":"message","type":"STRING","index":3,"required":false,"longName":"Message"}
	],
	"id":1,
	"private":false,
	"owner":"sensetecnic",
	"description":"A big yellow taxi that travels from Vincent's house to UBC and then back.",
	"longName":"Big Yellow Taxi",
	"latitude":51.060386316691,
	"longitude":-114.087524414062,
	"lastUpdate":"2012-12-07T01:47:18.639Z"}
}

Registered Applications and OAuth2

Applications are registered on the WoTKit UI (http://wotkit.sensetecnic.com/wotkit/apps). They can be installed by many users, but the credentials are unique to the contributor.

To grant a client access to your sensors, you first register an application. The client can then be supplied the 'application client id' and auto-generated 'application secret'. These will act as credentials, allowing clients to access the WoTKit on the user's behalf, using OAuth2 authorization.

The OAuth2 authorization asks the user's permission for a client to utilize the application credentials on the user's behalf. If the user allows this, an access token is generated. This access token can then be appended to the end of each WoTKit URL, authorizing access. (No further id/passwords are needed.)

For example, the following curl command uses an access token to get information about the sensor sensetecnic.mule1.

curl "http://wotkit.sensetecnic.com/api/sensors/sensetecnic.mule1?access_token={access_token}"

In order to obtain an access token for your client, the following steps are taken:

  1. An attempt to access the WoTKit is made by providing an 'application client id' and requesting a code.
  2. If no user is currently logged in to the WoTKit, a login page will be presented. A WoTKit user must log in to continue.
  3. A prompt asks the user to authorize the 'application client id' to act on their behalf. Once authorized, a code is provided.
  4. Using the application credentials, this code is exchanged for an access token. This access token is then appended to the end of each URL, authorizing access.

Example: PHP file pointed to by {redirect_uri}

$code = $_GET['code'];
$access_token = "none";
$ch = curl_init();
	
if(isset($code)) {
	// try to get an access token
	$params = array("code" => $code,
			"client_id"=> {application client id},
			"client_secret" => {application secret},
			"redirect_uri" => {redirect uri},
			"grant_type" => "authorization_code");			
	$data = ArraytoNameValuePairs ($params);
			
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_URL, "http://wotkit.sensetecnic.com/api/oauth/token");
	curl_setopt($ch, CURLOPT_POST, TRUE);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
		
	$access_token = json_decode($response)->access_token;	
	}	

Access Token Facts

When obtaining an access token, the 'response' field holds the following useful information:

  • response->access_token
  • response->expires_in
    • default value is approx. 43200 seconds (or 12 hrs)

Error Reporting

Errors are reported with an HTTP status code accompanied by an error JSON object. The object contains the status, an internal error code, user-displayable message, and an internal developer message.

HTTP/1.1 404 Not Found

{
  "error" : {
    "status" : 404,
    "code" : 0,
    "message" : "No sensor with that id",
    "developerMessage" : "user: mike sensor:gfhghjhj is not in the database"
  }
}

Sensors

A sensor represents a physical or virtual sensor or actuator. It contains a data stream made up of fields. A sensor has the following attributes:

Name Value Description
id the numeric id of the sensor. This may be used in the API in place of the sensor name.
name ** the name of the sensor. Note that the global name is {username}.{sensorname}. When logged in as a the owner,

you can refer to the sensor using only {sensorname}. To access a public sensor created by another user, you can refer to it by its numeric id or the global name {username}.{sensorname}.

description ** A description of the sensor for text searches.
longName ** Longer display name of the sensor.
url deprecated
latitude the latitude location of the sensor in degrees. This is a static location used for locating sensors on a map,

and location based queries. Dynamic location e.g. for mobile sensors is in the lat and lng fields of sensor data.

longitude the longitude location of the sensor in degrees. This is a static location used for locating sensors on a map,

and location based queries. Dynamic location e.g. for mobile sensors is in the lat and lng fields of sensor data.

lastUpdate last update time in milliseconds. This is the last time sensor data was recorded, or an actuator script

polled for control messages.

private true when the sensor is private, only accessible by the owner. When private is false, all users of the system

can access the sensor using its global sensor name or id.

owner the owner of the sensor
fields the expected data fields, their type (number or string), units and if available, last update time and value.
tags the list of tags for the sensor
data sensor data (not shown yet)

** Required when creating a new sensor.

Querying Sensors

A list of matching sensors may also be queried by the system. The current query parameters are as follows:

Name Value Description
scope all - all sensors the current user has access to; subscribed - the sensors the user has subscribed to; contributed - the sensors the user has contributed to the system.
tags list of comma separated tags
private true - private sensors only; false - public only
text text to search for in the name, long name and description
active when true, only returns sensors that have been updated in the last 15 minutes.
offset offset into list of sensors for paging
limit limit to show for paging. The maximum number of sensors to display is 1000.
location geo coordinates for a bounding box to search within. Format is yy.yyy,xx.xxx:yy.yyy,xx.xxx,

the order of the coordinates are North,West:South,East. Example: location=56.89,-114.55:17.43,-106.219

To query for sensors, add query parameters after the sensors URL as follows:

URL http://wotkit.sensetecnic.com/api/sensors?{query}
Format json
Method GET
Returns On error, an appropriate HTTP status code; On success, OK 204 and a list of sensor descriptions matching the query.

Example:

curl --user {id}:{password} "http://wotkit.sensetecnic.com/api/sensors/sensetecnic.mule1?tags=canada"

Output:

[
  {
	"tags":["data","vancouver","canada"],
		"latitude":0.0,
		"longitude":0.0,
		"longName":"api-data-test-1",
		"lastUpdate":"2013-01-26T01:55:36.514Z",
		"name":"api-data-test-1",
		"fields":	
			[{"required":true, "longName":"latitude", "lastUpdate":"2013-01-26T01:55:36.514Z", "name":"lat", "value":39.0, "type":"NUMBER","index":0},
			{"required":true,"longName":"longitude","lastUpdate":"2013-01-26T01:55:36.514Z","name":"lng","value":85.0,"type":"NUMBER","index":1},
			{"required":true,"longName":"Data","lastUpdate":"2013-01-26T01:55:36.514Z","name":"value","value":20.0,"type":"NUMBER","index":2},
			{"required":false,"longName":"Message","lastUpdate":"2013-01-26T01:55:36.514Z","name":"message","value":"test message to be active 164","type":"STRING","index":3}],
	"id":69,
	"private":false,
	"owner":"roseyr",
	"description":"api-data-test-1"
  },
	
  {
	"tags":["data","canada","edmonton"],
	"latitude":0.0,
	"longitude":0.0,
	"longName":"api-data-test-2",
	"lastUpdate":"2013-01-26T01:55:42.400Z",
	"name":"api-data-test-2",
	"fields":	
		[{"required":true,"longName":"latitude","lastUpdate":"2013-01-26T01:55:37.537Z", "name":"lat","value":65.0,"type":"NUMBER","index":0},
		{"required":true,"longName":"longitude","lastUpdate":"2013-01-26T01:55:37.537Z","name":"lng","value":74.0,"type":"NUMBER","index":1},
		{"required":true,"longName":"Data","lastUpdate":"2013-01-26T01:55:37.537Z","name":"value","value":82.0,"type":"NUMBER","index":2},	
		{"required":false,"longName":"Message","lastUpdate":"2013-01-26T01:55:37.537Z","name":"message","value":"test message to be active 110","type":"STRING","index":3}],
	"id":70,
	"private":false,
	"owner":"roseyr",
	"description":"api-data-test-1"
  },
	
  {
	"tags":["data","canada","winnipeg"],
	"latitude":0.0,
	"longitude":0.0,
	"longName":"api-data-test-3",
	"lastUpdate":"2013-01-26T01:55:34.488Z",
	"name":"api-data-test-3",
	"fields":
		[{"required":true,"longName":"latitude","name":"lat","value":0.0,"type":"NUMBER","index":0},	
		{"required":true,"longName":"longitude","name":"lng","value":0.0,"type":"NUMBER","index":1},	
		{"required":true,"longName":"Data","name":"value","value":0.0,"type":"NUMBER","index":2},	
		{"required":false,"longName":"Message","name":"message","type":"STRING","index":3}],
	"id":71,
	"private":false,
	"owner":"roseyr",
	"description":"api-data-test-3"
  }
]

Viewing a Single Sensor

To view a single sensor, query the sensor by sensor name or id as follows:

URL http://wotkit.sensetecnic.com/api/sensors/{sensorname}
Format json
Method GET
Returns Appropriate HTTP status code; OK 200 - if successful

Example:

curl --user {id}:{password} "http://wotkit.sensetecnic.com/api/sensors/sensetecnic.mule1"

Output:

{
	"name":"mule1",
	"fields":[
		{"name":"lat","value":49.20532,"type":"NUMBER","index":0,"required":true,"longName":"latitude","lastUpdate":"2012-12-07T01:47:18.639Z"},
		{"name":"lng","value":-123.1404,"type":"NUMBER","index":1,"required":true,"longName":"longitude","lastUpdate":"2012-12-07T01:47:18.639Z"},
		{"name":"value","value":58.0,"type":"NUMBER","index":2,"required":true,"longName":"Data","lastUpdate":"2012-12-07T01:47:18.639Z"},
		{"name":"message","type":"STRING","index":3,"required":false,"longName":"Message"}
	],
	"id":1,
	"private":false,
	"owner":"sensetecnic",
	"description":"A big yellow taxi that travels from Vincent's house to UBC and then back.",
	"longName":"Big Yellow Taxi",
	"latitude":51.060386316691,
	"longitude":-114.087524414062,
	"lastUpdate":"2012-12-07T01:47:18.639Z"}
}

Creating/Registering a Sensor

To register a sensor, you POST a sensor resource to the url /sensors.

  • The sensor resources is a JSON object.
  • The "name", "longName", "description", "latitude", and "longitude", "private" fields are required when creating a sensor.
  • The "tags" and "fields" information are optional.

To create a sensor:

URL http://wotkit.sensetecnic.com/api/sensors
Format json
Method POST
Returns HTTP status code; Created 201 if successful


Example:

curl --user {id}:{password} --request POST --header "Content-Type: application/json"
   --data-binary @test-sensor.txt 'http://wotkit.sensetecnic.com/api/sensors'

For this example, the file test-sensor.txt contains the following. This is the minimal information needed to register a sensor resource.

{
"private":false,
"name":"taxi-cab",
"description":"A big yellow taxi.",
"longName":"Big Yellow Taxi",
"latitude":51.060386316691,
"longitude":-114.087524414062
}


Updating a Sensor

Updating a sensor is the same as registering a new sensor other than PUT is used and the sensor name or id is included in the URL. A best practice is to get a sensor description, modify it, and then update it.

Note that all top level fields supplied will be updated.

  • The "name", "longName", and "description" fields are required.
  • If "tags" list or "fields" list are not included, they will not be changed.

To update a sensor owned by the current user:

URL http://wotkit.sensetecnic.com/api/sensors/{sensorname}
Format json
Method PUST
Returns HTTP status code; No Content 204 if successful


For example, to update a sensor description and add tags:

curl --user {id}:{password} --request PUT --header "Content-Type: application/json"
   --data-binary @update-sensor.txt 'http://wotkit.sensetecnic.com/api/sensors/taxi-cab'

The file update-sensor.txt would contain the following.

{
"private":false,
"name":"taxi-cab",
"description":"A big yellow taxi. Updated description",
"longName":"Big Yellow Taxi",
"latitude":51.060386316691,
"longitude":-114.087524414062,
"tags": ["big", "yellow", "taxi"]
}

TODO: Fix API bug so that the sensor name cannot be updated.

Deleting a Sensor

Deleting a sensor is done by deleting the sensor resource.

To delete a sensor owned by the current user:

URL http://wotkit.sensetecnic.com/api/sensors/{sensorname}
Format not applicable
Method DELETE
Returns HTTP status code; No Response 204 if successful

Example:

curl --user {id}:{password} --request DELETE 'http://wotkit.sensetecnic.com/api/sensors/test-sensor'

Sensor Subscriptions

Sensor subscriptions are handled using the /subscribe URL.

Current Subscriptions

To view sensors that the current user is subscribed to:

URL http://wotkit.sensetecnic.com/api/subscribe
Format json
Method GET
Returns Appropriate HTTP status code; OK 200 - if successful

Subscribe to a Sensor

To subscribe to a non-private sensor or private sensor owned by the current user:

URL http://wotkit.sensetecnic.com/api/subscribe/{sensorname}
Format json
Method PUT
Returns HTTP status code; No Content 204 if successful

Unsubscribe to a Sensor

To unsubscribe from a sensor:

URL http://wotkit.sensetecnic.com/api/subscribe/{sensorname}
Format json
Method DELETE
Returns HTTP status code; No Content 204 if successful

Sensor Fields

Each sensor has the following default fields:

Field Name Information
value The numerical data for the sensor. Required.
lat The latitude of the sensor. Required.
lng The longitude of the sensor. Required.
message The string message for the sensor. Not Required.

Each pieces of sensor field data has the following sub-fields:

Sub-field Name Information
name The unique identifier for the field. It is required when creating/updating a field and cannot be changed.
longName The display name for the field.
type Can be "NUMBER" or "STRING". It is required when creating/updating a field.
required Is a boolean field. If true, data sent to a sensor must include this field or an error will result. Optional.
units Is a string. Optional.
index The numerical identifier of the field. Automatically populated.
value The last value sent to the field. Automatically populated.
lastUpdate The time stamp of the last value sent to the field. Automatically populated.

TODO: Fix bug where the sub-field 'required' is not currently checked. Only "value" is actually required.

Querying Sensor Fields

To query all sensor fields for a specific sensor:

URL http://wotkit.sensetecnic.com/api/sensors/{sensorname}/fields
Format json
Method GET
Returns Appropriate HTTP status code; OK 200 - if successful

To query a single sensor field for a specific sensor:

URL http://wotkit.sensetecnic.com/api/sensors/{sensorname}/fields/{fieldName}
Format json
Method GET
Returns Appropriate HTTP status code; OK 200 - if successful

Updating a Sensor Field

You can update an existing sensor field or add a new sensor field by performing a PUT and including the field name in the URL. The field information is supplied in a JSON format.

If the sensor already has a field with the given "fieldname", it will be updated with new information. Otherwise, a new field will be created.

  • When inputting field data, the sub-fields "name" and "type" are required - both for adding a new field or updating an

existing one.

  • The "name" sub-field of an existing field cannot be updated.
  • For user defined fields, the "longName", "type", "required", and "units" sub-fields may be updated.
  • For the default fields (lat, lng, value, message), only the "longName" and "unit" sub-fields may be updated.

To update/add a sensor field:

URL http://wotkit.sensetecnic.com/api/sensors/{sensorname}/fields/{fieldname}
Format json
Method PUT
Returns HTTP status code; No Content 204 if successful

For example, to create a new field called "test-field":

curl --user {id}:{password} --request POST --header "Content-Type: application/json"
   --data-binary @field-data.txt 'http://wotkit.sensetecnic.com/api/sensors/test-sensor/fields/test-field'

The file field-data.txt could contain the following. (This is the minimal information needed to create a new field.)

{
	"name"=>"test-field",
	"type"=>"STRING"
} 

To then update "test-field" sub-fields, the same curl command would be used, and field-data.txt could now contain the following.

{
	"name"=>"test-field",
	"type"=>"NUMBER"
	"longName"=>"Test Field",
	"required"=>true,
	"units"=>"mm"
}	

Deleting a Sensor Field

You can delete an existing sensor field by performing a DELETE and including the field name in the URL.

None of the existing default fields (lat, lng, value, message) can be deleted.

To delete a sensor field:

URL http://wotkit.sensetecnic.com/api/sensors/{sensorname}/fields/{fieldname}
Format n/a
Method DELETE
Returns HTTP status code; No Content 204 if successful

Sensor Data

In the WoTKit, sensor data consists of a timestamp followed by one or more named fields. There are a number of reserved fields supported by the WoTKit:

Name Value Description
timestamp the time that the sensor data was collected. This is a long integer representing the number of milliseconds from

Jan 1, 1970 UTC*. Optional; if not supplied, a server-supplied timestamp will be used.

sensor_id the globally unique sensor id that produced the data.
sensor_name the globally unique sensor name, in the form {username}.{sensorname}
lng the current longitude location of the sensor in degrees (number). Needed for map visualizations.
value the primary value of the sensor data collected (number). Needed for most visualizations.
message a text message, for example a twitter message (text). Needed for text/newsfeed visualizations.

In addition to these reserved fields, additional fields can be added by updating the sensor schema in the WoTKit UI or Sensor Fields in the API.

*NOTE: python's time.time() function generates the system time in seconds, not milliseconds. To convert this to an integer in milliseconds use int(time.time()*1000). Using Java: System.currentTime()

Sending New Data

To send new data to a sensor, POST name value pairs corresponding to the data fields to the /sensors/{sensorname}/data URL.

There is no need to provide a timestamp since it will be assigned by the server. Data posted to the system will be processed in real time.

To send new data:

URL http://wotkit.sensetecnic.com/api/sensors/{sensorname}/data
Format not applicable
Method POST
Returns HTTP status code; No Response 201 (Created) if successful

For example:

curl --user {id}:{password} --request POST 
   -d value=5 -d lng=6 -d lat=7 'http://wotkit.sensetecnic.com/api/sensors/test-sensor/data'

Updating Data

To update a single data point, or a range of data, you PUT data (rather than POST) data into the system. Note that data PUT into the WoTKit will not be processed in real time, since it occurred in the past

  • The data sent must contain a list of JSON objects containing a timestamp and a value.
  • If providing a single piece of data, existing data with the provided timestamp will be deleted and replaced. Otherwise,

the new data will be added.

  • If providing a range of data, the list must be ordered from earliest to most recent timestamp. Any existing data within

this timestamp range will be deleted and replaced by the new data.

To update data:

URL http://wotkit.sensetecnic.com/api/sensors/{sensorname}/data
Format not applicable
Method PUT
Returns HTTP status code; No Response 204 if successful

Example of valid data:

[{"timestamp":"2012-12-12T03:34:28.626Z","value":67.0,"lng":-123.1404,"lat":49.20532},
{"timestamp":"2012-12-12T03:34:28.665Z","value":63.0,"lng":-123.14054,"lat":49.20554},
{"timestamp":"2012-12-12T03:34:31.621Z","value":52.0,"lng":-123.14063,"lat":49.20559},
{"timestamp":"2012-12-12T03:34:35.121Z","value":68.0,"lng":-123.14057,"lat":49.20716},
{"timestamp":"2012-12-12T03:34:38.625Z","value":51.0,"lng":-123.14049,"lat":49.20757},
{"timestamp":"2012-12-12T03:34:42.126Z","value":55.0,"lng":-123.14044,"lat":49.20854},
{"timestamp":"2012-12-12T03:34:45.621Z","value":56.0,"lng":-123.14215,"lat":49.20855},
{"timestamp":"2012-12-12T03:34:49.122Z","value":55.0,"lng":-123.14727,"lat":49.20862},
{"timestamp":"2012-12-12T03:34:52.619Z","value":59.0,"lng":-123.14765,"lat":49.20868}]

Deleting Data

Currently you can only delete data by timestamp, where timestamp is in numeric or ISO form. Note that if more than one sensor data point has the same timestamp, they all will be deleted.

To delete data:

URL http://wotkit.sensetecnic.com/api/sensors/{sensorname}/data/{timestamp}
Format not applicable
Method DELETE
Returns HTTP status code; No Response 204 if successful

Raw Data Retrieval

To retrieve raw data use the following:

URL http://wotkit.sensetecnic.com/api/sensors/{sensor-name}/data?{query-params}
Format json
Method GET
Returns On success, OK 200 with a list of timestamped data records.

The query parameters supported are the following:

Name Value Description
start the absolute start time of the range of data selected in milliseconds. (Defaults to current time.)
end the absolute end time of the range of data in milliseconds
after the relative time after the start time, e.g. after=300000 would be 5 minutes after the start time (Start time MUST

also be provided.)

afterE the number of elements after the start element or time (Start time MUST also be provided.)
before the relative time before the start time. E.g. data from the last hour would be before=3600000 (If not provided, start

time default to current time.)

beforeE the number of elements before the start time. E.g. to get the last 1000, use beforeE=1000 (If not provided, start time

default to current time.)

reverse true - order the data from oldest to newest; false (or leave out) - order from newest to oldest

TODO: add support for out parameter, csv and location-only kml output formats. Add support for list of fields to display.

Formatted Data Retrieval

To retrieve data in a format suitable for Google Visualizations, we support an additional resource for retrieving data called the dataTable.

URL http://wotkit.sensetecnic.com/api/sensors/{sensor-name}/dataTable?{query-params}
Format json
Method GET
Returns On success, OK 200 with a list of timestamped data records.

In addition to the above query parameters, the following parameters are also supported:

tqx A set of colon-delimited key/value pairs for standard parameters as defined in [1].
tq A google selection clause to choose fields to return as in [2].

Note that when using tq sql queries, they must be url encoded. When using tqx name/value pairs, the reqId parameter is necessary.

For example, the following would take the "test-sensor", select all data where value was greater than 20, and display the output as an html table.

curl --user {id}:{password}
http://wotkit.sensetecnic.com/api/sensors/test-sensor/dataTable?tq=select%20*%20where%20value%3E20&reqId=1&out=html

TODO: examples

Aggregated Data Retrieval

Aggregated data retrieval allows one to receive data from multiple sensors, queried using the same parameters as when searching for sensors or sensor data. The following parameters may be added to the /data url:

  • scope
  • tags
  • private
  • text
  • active
  • start
  • end
  • after
  • afterE
  • before
  • beforeE

In addition to the above parameters, the orderBy is also supported. It can have value sensor or time. The former groups by sensor_id and then timestamp, the latter orders all data by timestamp regardless of the sensor it comes from. The default is value for orderBy is time.

To receive data from more that one sensor, use the following:

URL http://wotkit.sensetecnic.com/api/data?{query-param}={query-value}&{param}={value}...
Format json
Method GET
Returns On success, OK 200 with a list of timestamped data records.

Example:

curl --user {id}:{password} "http://wotkit.sensetecnic.com/api/data?subscribed=all&beforeE=20&orderBy=sensor"

Sensor Control Channel: Actuators

An actuator is a sensor that uses a control channel to actuate things. Rather than POSTing data to the WoTKit, an actuator script or gateway polls the control URL for messages to affect the actuator, to do things like move a servo motor, turn a light on or off, or display a message on a screen. To demonstrate actuators, the control visualization that comes with the WoTKit sends three type of events to the sensor control channel:

button 'on' or 'off' to control a light, or switch.
message text message for use by the actuator, for example to be shown on a message board or display.
slider a numeric value to affect the position of something, such as a server motor.

Any name/value pair can be sent to an actuator in a message, these are just the names sent by the visualization.

Sending Actuator Messages

To send a control message to a sensor (actuator), POST name value pairs corresponding to the data fields to the /sensors/{sensorname}/message URL.

URL http://wotkit.sensetecnic.com/api/sensors/{sensorname}/message
Format json
Method POST
Returns On success, OK 204 (no content).

Receiving Actuator Messages

To receive data sent to a sensor, the sensor script must first subscribe to the controller by POSTing to /api/control/sub/{sensor-name}. In return we receive a json object containing a subscription id.

URL http://wotkit.sensetecnic.com/api/control/sub/{sensor-name}
Format json
Method POST
Returns On success, OK 200 with JSON containing subscription id.

Example subscription id returned:

{
	"subscription":1234
}

Using the subscription id, the script then polls the following resource: /api/control/sub/{subscription-id}?wait=10. The wait specifies the time to wait in seconds for a control message. If unspecified, a default wait time of 10 seconds is used. The maximum wait time is 20 seconds. The server will respond on timeout, or when a control messages is received.

URL http://wotkit.sensetecnic.com/api/control/sub/{subscription-id}?wait={wait-time}
Format json
Method GET
Returns On success, OK 200 with JSON containing control messages.

To illustrate, the following code snippet uses HTTP client libraries to subscribe and get actuator messages from the server, and then print the data. Normally, the script would change the state of an actuator like a servo or a switch based on the message received.

# sample actuator code
import urllib
import urllib2
import base64
import httplib

try:
	import json
except ImportError:
	import simplejson as json 

#note trailing slash to ensure .testactuator is not dropped as a file extension
actuator="mike.testactuator/"

# authentication setup
conn = httplib.HTTPConnection("wotkit.sensetecnic.com")
base64string = base64.encodestring('%s:%s' % ('{id}', '{password}'))[:-1]
authheader =  "Basic %s" % base64string
headers = {'Authorization': authheader}
       
#subscribe to the controller and get the subscriber ID
conn.request("POST", "/api/control/sub/" + actuator, headers=headers)
response = conn.getresponse()
data = response.read()

json_object = json.loads(data)
subId = json_object['subscription']

#loop to long poll for actuator messages
while 1:
	print "request started for subId: " + str(subId)
	conn.request("GET", "/api/control/sub/" + str(subId) + "?wait=10", headers=headers)
	response = conn.getresponse()
	data = response.read()

	json_object = json.loads(data)

        # change state of actuator based on json message received
	print json_object

API Features under development

This is a list of API features under development:

  • /user resources for priveledged app to manage users
  • Long polling for sensor and control streams.
  • WebSocket server to provide access to sensor and control data streams.

  • OAuth2 for server-based applications (done - to be documented)
  • Data aggregation using a top level /data resource by specifying the sensors to include in a query.

Fields will be merged or different for each sensor.

  • individual schema field updates (work in progress)
  • subscribe or unsubscribe to sensors

Personal tools