NAV Navbar
JavaScript Node.JS Python Java (Android) Swift (iOS)

Introduction

Welcome to the Sensum Emotion AI API & SDK.

The SensumAPI and SensumSDK enables you to build services or products which respond to emotional events in real time.

Glossary of Terms

Term Description
SensumAPI The SensumAPI is the RESTful API that is used either directly or through the SensumSDK
SensumSDK SensumSDK refers to the Android and iOS SDKs
SensumKit SensumKit is the framework file that allows an iOS application to use the SensumSDK

SensumAPI

Introduction

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

SensumAPI enables you to access our emotional intelligence platform. Our API is designed to be RESTful, responding to HTTP requests with bodies in JSON format. All requests require that the Content-Type: application/json header be specified. SensumAPI is also cross-origin resource sharing ready.

SensumSDK handles many of these requests and responses natively. It can however be useful to utilise the SensumAPI directly.

URI Structure

SensumAPI uses URI resources to provide access to its services. To use a RESTful API, your application will use HTTP Methods(GET, POST, etc.) to request and parse a response. SensumAPI uses JSON for communication between your application and the server.

An example URI: https://api.sensum.co/v0/testdata

Authorization

SensumAPI uses a combination of an API Key and request signing to authorize access. You can register a new API Key by contacting us.

SensumAPI expects each call to contain the following headers to gain access:

To calculate the value for the Authorization header you must calculate a hash of your request, add extra information, then add the AWS secret key in order to create a signing key and then use this to sign the request. To learn more about generating the Signature please read the AWS Documentation on Signature v4

When using the SDK, the signature will be automatically generated when making API calls through it.

Available Metrics

Below are the metrics that SensumAPI can analyse and the units that the data is posted in

Metric Name Unit
heartrate bpm
breathingrate bpm
temperature oC, assumed to be ambient/external
skintemperature oC
gsr microsiemens*
location_latitude deg
location_longitude deg
location_altitude m
location_accuracy or location_accuracy_horizontal/vertical if available
location_speed m/s
acceleration linear acceleration in m/s2**
acceleration_x m/s2
acceleration_y m/s2
acceleration_z m/s2

* The GSR Conductance unit ‘microsiemens’ is the inverse of the skin resistance; some devices return GSR as resistance in Ohms and this must be converted before upload, i.e. if a device returns values in x kOhms, the conversion is 1/(1000*x)

** All acceleration values should exclude gravity and be in m/s2 i.e. using the userAcceleration iOS method rather than the acceleration method

SensumAPI Analysis Responses

Input Metric(s) Generated Events Generated Records Generated Stats
any Events for that Metric Stats for that event
heartrate arousal arousal (See Fuzzy Class Stats)
gsr engagement engagement (See Fuzzy Class Stats)
acceleration_[x,y,z] activity activity (See Fuzzy Class Stats)

Events

Event Fields Type Meaning
time UTC Timestamp (ms) Time of event
value String: One of [‘normal’, ‘rising’, ‘falling’, ‘max’, ‘min’] Type of event (normal is not currently used)
severity                               Float Relative severity of the event, i.e. how much of value change between forward/backward events with respect to the average value

Stats

Stats Field Type Meaning
avg Float average (mean) value
duration Float (seconds) time between first and last analysed records
max Float max value
min Float min value
std Float standard deviation of the record
percentiles Object(dict) 10th, 50th, and 90th percentile values

Fuzzy Class Stats

For “fuzzy” classification outputs such as arousal, engagement and activity, an additional stats structure is used containing 3 fields:

Field Type Meaning
value Float [0-1] activation value
dominant string label of the dominant classification category
sectors Object(dict) per-category-label activivation i.e {label:value,...}

Current Sector Labels (highest to lowest activation value):

Send text data to analyse emoji and text sentiment

This endpoint allows users to send strings of text to our service for emotional sentiment analysis.

The service will return a JSON object that contain Positivity, Negativity and Emotionality values for emojis and text.

HTTP Request

POST https://api.sensum.co/v0/sentiment

Glossary

Term Description
positivity The level of positive emotion expressed in an input(Scale: 0 to +1)
negativity The level of negative emotion expressed in an input(Scale: 0 to +1)
emotionality The overall strength of emotion contained in an input(Scale: -1 to +1)*

Code samples

var headers = {
  'Content-Type':'application/json',
  'Authorization' : 'AWS Sig v4 Key',
  'x-api-key' : 'PublicDemoKeyForDocumentation'

};

var data = {
  "text":"👌👌👌"
};

$.ajax({
  url: 'https://api.sensum.co/v0/sentiment',
  method: 'post',
  data: JSON.stringify(data);
  headers: headers,
  success: function(data) {
    console.log(JSON.stringify(data));
  }
})
const request = require('node-fetch');

const headers = {
  'Content-Type':'application/json',
  'Authorization' : 'AWS Sig v4 Key',
  'x-api-key' : 'PublicDemoKeyForDocumentation'

};

var data = {
  "text":"👌👌👌"
};


fetch('https://api.sensum.co/v0/sentiment',
{
  method: 'POST',
  body : body,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});
import requests
headers = {
  'Content-Type':'application/json',
  'Authorization' : 'AWS Sig v4 Key',
  'x-api-key' : 'PublicDemoKeyForDocumentation'
}


data = {
  "text":"👌👌👌"
}

r = requests.post('https://api.sensum.co/v0/sentiment', data=data, headers = headers)

print r.json()

Responses

Status Meaning Description
200 OK 200 response

Examples

Please refer to the code samples for request and response examples

Text Only - Unemotional

Request

{
  "text": "This is nothing"
}

Response

{
  "emoji_sentiment": null,
  "text_sentiment": {
    "emotionality": 0.0, //Aggregate Emotionality Score from -1,+1
    "negativity": 0.0, // Negativity Score from 0 to +1
    "positivity": 0.0  // Positivity Score from 0 to +1
   }
}

Text Only - Emotional

Request

{
  "text": "This was a very good test"
}

Response

{
  "emoji_sentiment": null,
  "text_sentiment": {
    "positivity": 0.444,
    "negativity": 0.0,
    "emotionality": 0.4927
  }
}

Emoji

Request

{
  "text":"👌👌👌"
}

Response

{
  "text_sentiment": {
    "negativity": 0.0,
    "positivity": 0.0,
    "emotionality": 0.0
  },
  "emoji_sentiment": {
    "positivity": 0.6575529733,
    "negativity": 0.0936431989,
    "emotionality": 0.4236068641
  }
}

Retrieve previously recorded data

This endpoint allows the user to retrieve previously entered data by providing a start time, an end time and the metrics to be retrieved.

HTTP Request

GET https://api.sensum.co/v0/data/

Code samples

var headers = {
  'Content-Type':'application/json',
  'Authorization' : 'AWS Sig v4 Key',
  'x-api-key' : 'PublicDemoKeyForDocumentation'
};

var params = {
    'start' : '2017-08-15',
    'end' : '2017-08-25',
    'metrics' : ['heartrate','breathingrate']
};

$.ajax({
  url: 'https://api.sensum.co/v0/data/',
  method: 'get',
  data : params,
  headers: headers,
  success: function(data) {
    console.log(JSON.stringify(data));
  }
})
const request = require('node-fetch');

const headers = {
  'Content-Type':'application/json',
  'Authorization' : 'AWS Sig v4 Key',
  'x-api-key' : 'PublicDemoKeyForDocumentation'

};

fetch('https://api.sensum.co/v0/data?start=2017-08-15&end=2017-08-25&metrics=['heartrate','breathingrate']',
{
  method: 'get',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});
import requests
headers = {
  'Content-Type':'application/json',
  'Authorization' : 'AWS Sig v4 Key',
  'x-api-key' : 'PublicDemoKeyForDocumentation'
}

params = {
    'start' : '2017-08-15',
    'end' : '2017-08-25',
    'metrics' : ['heartrate','breathingrate']
}


r = requests.get('https://api.sensum.co/v0/data/', params = params, headers = headers)

print r.json()

Parameters

Parameter Type Required Description
start string true Datetime compatible start time for query
end string true End time for query
metrics string true List of strings of requested metrics

Responses

Status Meaning Description
200 OK Successful request

Retrieve available records

This endpoint allows the user to retrieve a list of available records based on the supplied query information.

HTTP Request

GET https://api.sensum.co/data/records.json

Code samples

var headers = {
  'Content-Type':'application/json',
  'Authorization' : 'AWS Sig v4 Key',
  'x-api-key' : 'PublicDemoKeyForDocumentation'
};

var params = {
    'start' : '2017-08-15',
    'end' : '2017-08-25',
    'metrics' : ['heartrate','breathingrate']
};

$.ajax({
  url: 'https://api.sensum.co/v0/data/records.json',
  method: 'get',
  data: 'params',
  headers: headers,
  success: function(data) {
    console.log(JSON.stringify(data));
  }
})
const request = require('node-fetch');

const headers = {
  'Content-Type':'application/json',
  'Authorization' : 'AWS Sig v4 Key',
  'x-api-key' : 'PublicDemoKeyForDocumentation'
};

fetch('https://api.sensum.co/v0/data/records.json?start=2017-08-15&end=2017-08-25&metrics=['heartrate','breathingrate']',
{
  method: 'get',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});
import requests
headers = {
  'Content-Type':'application/json',
  'Authorization' : 'AWS Sig v4 Key',
  'x-api-key' : 'PublicDemoKeyForDocumentation'
}


params = {
    'start' : '2017-08-15',
    'end' : '2017-08-25',
    'metrics' : ['heartrate','breathingrate']
}


r = requests.get('https://api.sensum.co/v0/data/records.json', params = params, headers = headers)

print r.json()

Parameters

Parameter Type Required Description
start string true Datetime compatible start time for query
end string true End time for query
metrics string true List of strings of requested metrics

Responses

Status Meaning Description
200 OK Successful request

Example Response

{
  "data": {
    "acceleration_x": [
      {"time": 1501761816636,"value": 0.00222260966538161},
      {"time": 1501761817632, "value": -0.0132070300688734},
      {"time": 1501761818631, "value": -0.0390399978164584},
      {"time": 1501761819632, "value": -0.0268580912779318},
      ...
      ],
   "acceleration_y": [...],
  },
  "metrics":
    [
      "acceleration_x","acceleration_y", "acceleration_z",
      "location_altitude", "location_horizontalaccuracy", "location_latitude",
      "location_longitude", "location_speed", "location_verticalaccuracy"]
  }

Retrieve available metrics

This endpoint allows the user to retrieve a list of available metrics in the requested records.

HTTP Request

GET https://api.sensum.co/v0/data/metrics.json

Code samples

var headers = {
  'Content-Type':'application/json',
  'Authorization' : 'AWS Sig v4 Key',
  'x-api-key' : 'PublicDemoKeyForDocumentation'
};

var params = {
    'start' : '2017-08-15',
    'end' : '2017-08-25',
    'metrics' : ['heartrate','breathingrate']
};

$.ajax({
  url: 'https://api.sensum.co/v0/data/metrics.json',
  method: 'get',
  data: params,
  headers: headers,
  success: function(data) {
    console.log(JSON.stringify(data));
  }
})
const request = require('node-fetch');

const headers = {
  'Content-Type':'application/json',
  'Authorization' : 'AWS Sig v4 Key',
  'x-api-key' : 'PublicDemoKeyForDocumentation'

};

fetch('https://api.sensum.co/v0/data/metrics.json?start=2017-08-15&end=2017-08-25&metrics=['heartrate','breathingrate']',
{
  method: 'get',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});
import requests
headers = {
  'Content-Type':'application/json',
  'Authorization' : 'AWS Sig v4 Key',
  'x-api-key' : 'PublicDemoKeyForDocumentation'
}

params = {
    'start' : '2017-08-15',
    'end' : '2017-08-25',
    'metrics' : ['heartrate','breathingrate']
};


r = requests.get('https://api.sensum.co/v0/data/metrics.json', params= params, headers = headers)

print r.json()

Parameters

Parameter Type Required Description
start string true Datetime compatible start time for query
end string true End time for query
metrics string true List of strings of requested metrics

Responses

Status Meaning Description
200 OK Successful request

Example Response

{
    "metrics":[
      "heartrate",
      "breatingrate"
    ]
}

Retrieve available wide-format records

This endpoint allows the user to retrieve a wide-format array of time series records for the available metrics, filled with null values for unavailable values.

HTTP Request

GET https://api.sensum.co/v0/data/wide.json

Code samples

var headers = {
  'Content-Type':'application/json',
  'Authorization' : 'AWS Sig v4 Key',
  'x-api-key' : 'PublicDemoKeyForDocumentation'

};

var params = {
    'start' : '2017-08-15',
    'end' : '2017-08-25',
    'metrics' : ['heartrate','breathingrate']
};


$.ajax({
  url: 'https://api.sensum.co/v0/data/wide.json',
  method: 'get',
  data: params,
  headers: headers,
  success: function(data) {
    console.log(JSON.stringify(data));
  }
})
const request = require('node-fetch');

const headers = {
   'Content-Type':'application/json',
  'Authorization' : 'AWS Sig v4 Key',
  'x-api-key' : 'PublicDemoKeyForDocumentation'

};

fetch('https://api.sensum.co/v0/data/wide.json?start=2017-08-15&end=2017-08-25&metrics=['heartrate','breathingrate']',
{
  method: 'get',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});
import requests
headers = {
  'Content-Type':'application/json',
  'Authorization' : 'AWS Sig v4 Key',
  'x-api-key' : 'PublicDemoKeyForDocumentation'
}

params = {
    'start' : '2017-08-15',
    'end' : '2017-08-25',
    'metrics' : ['heartrate','breathingrate']
};


r = requests.get('https://api.sensum.co/v0/data/wide.json', params = params, headers = headers)

print r.json()

Parameters

Parameter Type Required Description
start string true Datetime compatible start time for query
end string true End time for query
metrics string true List of strings of requested metrics

Responses

Status Meaning Description
200 OK Successful request

Send data for events analysis

This endpoint allows the user to send data to the Emotion AI service for analysis. The response will return a series of significant events.

An event is triggered when there is a statistically significant timeseries change detected in an incoming data stream, be that from a Bluetooth sensor or internal sensor such as Accelerometer. Depending on the data stream applied, this can indicate a shift or change in emotional or activity state.

The severity of an event is dependent on

How “steep” the event is and
How “isolated” the event is with respect to any events identified before / after it.

HTTP Request

POST https://api.sensum.co/v0/events

Code samples

var headers = {
  'Content-Type':'application/json',
  'Authorization': 'AWS_Sig v4 Key',
  'x-api-key': 'Public'

};

var data = {
    "records": {
      "heartrate": [
        {
          "time": 1502807187332,
          "value": 111.77347523527911
        },
        {
          "time": 1502807188332,
          "value": 112.89604978090439
        },
        {
          "time": 1502807189332,
          "value": 112.37719504311998
        },
        {
          "time": 1502807190332,
          "value": 113.68469103590627
        },
        {
          "time": 1502807191332,
          "value": 113.67799449012763
        },
        {
          "time": 1502807192332,
          "value": 112.71988545819869
        },
        {
          "time": 1502807193332,
          "value": 113.05775062793727
        },
        {
          "time": 1502807194332,
          "value": 114.53499763344529
        },
        {
          "time": 1502807195332,
          "value": 115.4964191594706
        },
        {
          "time": 1502807196332,
          "value": 115.31744641217797
        }
      ]
    }
  };

$.ajax({
  url: 'https://api.sensum.co/v0/events',
  method: 'post',
  data: JSON.stringify(data),
  headers: headers,
  success: function(data) {
    console.log(JSON.stringify(data));
  }
})
const request = require('node-fetch');
const inputBody = '{
    "records": {
      "heartrate": [
        {
          "time": 1502807187332,
          "value": 111.77347523527911
        },
        {
          "time": 1502807188332,
          "value": 112.89604978090439
        },
        {
          "time": 1502807189332,
          "value": 112.37719504311998
        },
        {
          "time": 1502807190332,
          "value": 113.68469103590627
        },
        {
          "time": 1502807191332,
          "value": 113.67799449012763
        },
        {
          "time": 1502807192332,
          "value": 112.71988545819869
        },
        {
          "time": 1502807193332,
          "value": 113.05775062793727
        },
        {
          "time": 1502807194332,
          "value": 114.53499763344529
        },
        {
          "time": 1502807195332,
          "value": 115.4964191594706
        },
        {
          "time": 1502807196332,
          "value": 115.31744641217797
        }
      ]
    }
  }
';
const headers = {
  'Content-Type':'application/json',
  'Authorization' : 'AWS Sig v4 Key',
  'x-api-key' : 'PublicDemoKeyForDocumentation'

};

fetch('https://api.sensum.co/v0/events',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});
import requests
headers = {
  'Content-Type':'application/json',,
  'Authorization' : 'AWS Sig v4 Key',
  'x-api-key' : 'PublicDemoKeyForDocumentation'
}

data = {
    "records": {
      "heartrate": [
        {
          "time": 1502807187332,
          "value": 111.77347523527911
        },
        {
          "time": 1502807188332,
          "value": 112.89604978090439
        },
        {
          "time": 1502807189332,
          "value": 112.37719504311998
        },
        {
          "time": 1502807190332,
          "value": 113.68469103590627
        },
        {
          "time": 1502807191332,
          "value": 113.67799449012763
        },
        {
          "time": 1502807192332,
          "value": 112.71988545819869
        },
        {
          "time": 1502807193332,
          "value": 113.05775062793727
        },
        {
          "time": 1502807194332,
          "value": 114.53499763344529
        },
        {
          "time": 1502807195332,
          "value": 115.4964191594706
        },
        {
          "time": 1502807196332,
          "value": 115.31744641217797
        }
      ]
    }
  }


r = requests.post('https://api.sensum.co/v0/events', params = data, headers = headers)

print r.json()

Body parameter

{
    "records": {
      "heartrate": [
        {
          "time": 1502807187332,
          "value": 111.77347523527911
        },
        {
          "time": 1502807188332,
          "value": 112.89604978090439
        },
        {
          "time": 1502807189332,
          "value": 112.37719504311998
        },
        {
          "time": 1502807190332,
          "value": 113.68469103590627
        },
        {
          "time": 1502807191332,
          "value": 113.67799449012763
        },
        {
          "time": 1502807192332,
          "value": 112.71988545819869
        },
        {
          "time": 1502807193332,
          "value": 113.05775062793727
        },
        {
          "time": 1502807194332,
          "value": 114.53499763344529
        },
        {
          "time": 1502807195332,
          "value": 115.4964191594706
        },
        {
          "time": 1502807196332,
          "value": 115.31744641217797
        }
      ]
    }
  }

Responses

Status Meaning Description
200 OK Successful request

Response Headers

Status Header Type Format Description
200 Access-Control-Allow-Origin string

Example responses

{
    "events":{
        "heartrate":[
            {"time":1502807187000,"value":"min","severity":0.03176537181134584},
            {"time":1502807196000,"value":"max","severity":0.03176537181134584}
        ]
    },
    "stats":{
        "heartrate":{
            "avg":113.55359048765672,
            "duration":9,
            "max":115.4964191594706,
            "min":111.77347523527911,
            "std":1.175057115344551,
            "percentiles":{"10":112.3168230623359,"50":113.36787255903245,"90":115.33534368690724}}
    },
    "records":{
        "arousal":[
            {"time":1502807187332,"value":5.359549491038813e-15},
            {"time":1502807188332,"value":0.052921639437207874},
            {"time":1502807189332,"value":0.028461220785887004},
            {"time":1502807190332,"value":0.09010062973692541},
            {"time":1502807191332,"value":0.08978493383721622},
            {"time":1502807192332,"value":0.044616707881203976},
            {"time":1502807193332,"value":0.06054471797280525},
            {"time":1502807194332,"value":0.13018671519236316},
            {"time":1502807195332,"value":0.17551110237516387},
            {"time":1502807196332,"value":0.16707377298958567}
        ]
    },
    "exec_time":0.12196207046508789
}

Get test data

This endpoint allows the user to generate a series of test data streams that can be fed into the events endpoint to test the analysis service. When testing the events endpoint only POST the “records” JSON object in the request body.

HTTP Request

GET https://api.sensum.co/v0/testdata

Code samples

var headers = {
   'Content-Type':'application/json',
  'Authorization' : 'AWS Sig v4 Key',
  'x-api-key' : 'PublicDemoKeyForDocumentation'

};

var params = {
    'n' : '10',
    'freq' : '1',
    'values' : ['heartrate']
};

$.ajax({
  url: 'https://api.sensum.co/v0/testdata',
  method: 'get',
  data : params,
  headers: headers,
  success: function(data) {
    console.log(JSON.stringify(data));
  }
})
const request = require('node-fetch');

const headers = {
  'Content-Type':'application/json',
  'Authorization' : 'AWS Sig v4 Key',
  'x-api-key' : 'PublicDemoKeyForDocumentation'

};

var params = {
    'n' : '10',
    'freq' : '1',
    'values' : ['heartrate']
};

fetch('https://api.sensum.co/v0/testdata?n=10&freq=1&values=['heartrate']',
{
  method: 'GET',
  data: params,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});
import requests
headers = {
  'Content-Type':'application/json',
  'Authorization' : 'AWS Sig v4 Key',
  'x-api-key' : 'PublicDemoKeyForDocumentation'
}

params = {
    'n' : '10',
    'freq' : '1',
    'values' : ['heartrate']
}

r = requests.get('https://api.sensum.co/v0/testdata', params = params, headers = headers)

print r.json()

Parameters

Parameter Default Type Required Description
values [heartrate] string false An array of the metrics to be generated
freq 1 string false Frequency of generated records in seconds. Determines timestamps
n 100 string false Number of records to be generated per metric

Responses

Status Meaning Description
200 OK Successful request

Response Headers

Status Header Type Format Description
200 Access-Control-Allow-Origin string

Example responses

{
    "data":{
        "records":{
            "heartrate":[
                {"time":1502807389973,"value":150.97562499389198},
                {"time":1502807390973,"value":152.35592250838624},
                {"time":1502807391973,"value":152.7272449519015},
                {"time":1502807392973,"value":153.35354662656178},
                {"time":1502807393973,"value":153.78404886070086},
                {"time":1502807394973,"value":155.3441181915241},
                {"time":1502807395973,"value":155.18001608899218},
                {"time":1502807396973,"value":154.5414565968463},
                {"time":1502807397973,"value":156.35855725243886},
                {"time":1502807398973,"value":156.83569789892923}
            ]
        }
    },
    "params":{"n":10,"values":["heartrate"],"freq":1}
}

Errors

SensumAPI uses the following error codes:

Error Code Meaning
400 Bad Request - Your Request may have caused an error
401 Unauthorized - This error will likely occur if the Cognito Authorization Header (AWS Signature v4) is either missing or invalid.
403 Forbidden -This error will likely occur if the API Key Header is either invalid or missing.
405 Method Not Allowed - You have attempted to make a request using a HTTP Method that is invalid for the requested resource.
429 Too Many Requests - You have made more requests than is allowed under the usage plan.
500 Internal Server Error - There is an error with our service
503 Service Unavailable - Our service is down for maintenance. Please try again later.

SensumSDK - Android

Android Device Compatibility

The Android version of SensumSDK can be installed on devices with 5.1.1 (Lollipop) up to 7.0 (Nougat).

We recommend the Samsung S6, S7, S8, OnePlus X and above or the Google Pixel as suitable devices

Bluetooth Device Compatibility

Note: This document is regularly updated with new devices. Please contact us for integration details. GSR data is only accessible from Shimmer devices at present.

Accepted Biometric Data Inputs

The Android SensumSDK can accept the following metrics:

Service Constants

These constants can used to construct message bundled that are then relayed to the Emotion AI service to send and retrieve data.

One example of a call to the service would be to send credentials in order to authorize a user. See “Submit Credentials to service for authorization” for an example in how these bundles are constructed.

Enable Scan

public static final String ENABLE_SCAN = "enable-scan"

This passes a message of enabling scan for the devices to the SensumSDK service.

Device List

public static final String DEVICE_LIST = "device-list"

This is used to get a list of scanned devices.

Request

public static final String REQUEST = "send-request"

This is used to get request data.

Request Filter

public static final String REQUEST_FILTER = "request-filter"

This is used to pass a message from the SensumSDK service which is used as an intent filter at the front end for the request which is made to the SensumSDK service.

Device filter

public static final String DEVICE_FILTER = "device-filter"

This is used to pass a message from the SensumSDK service which is used as an intent filter at the front end for the connected device.

Value Filter

public static final String VALUE_FILTER = "value-filter"

This is used to pass a message from the SensumSDK service which is used as an intent filter at the front end for receiving the heart rate value.

Login Filter

public static final String LOGIN_FILTER = "login-filter"

This is used to pass a message from the SensumSDK service which is used as an intent filter at the front end for the user login.

GPS Filter

public static final String GPS_FILTER = "gps-filter"

This is used to pass a message from the SensumSDK service which is used as an intent filter at the front end for receiving the GPS values.

Accelerometer Filter

public static final String ACC_FILTER = "acc-filter"

This is used to pass a message from the SensumSDK service which is used as an intent filter at the front end for receiving the accelerometer values.

Extra Data

public static final String EXTRA_DATA = "extra-data"

This is used to bundle up extra data to the intents.

Device Name

public static final String DEVICE_NAME = "device-name"

This is used to get the connected device name.

Device Address

public static final String DEVICE_ADDRESS = "device-address"

This is used to get the connected device address.

User Name

public static final String USER_NAME = "user-name"

This is used to pass the username for authentication to the SensumSDK service, only authenticated users are able to use the SensumSDK service.

Password

public static final String PASSWORD = "password"

This is used to pass the password for authentication to the SensumSDK service.

Wear HR Value

public static final String WEAR_HR_VALUE = "wear-hr-value"

This is used to pass the Heart Rate value captured using Android Wear to the SensumSDK service.

Text Message

public static final String TEXT_MESSAGE = "text-message"

This is used to pass Text/Emoji value to the SensumSDK service.

X Value

public static final String X_VALUE = "x-value"

This is used to pass the captured accelerometer x value.

Y Value

public static final String Y_VALUE = "y-value"

This is used to pass the captured accelerometer y value.

Z Value

public static final String Z_VALUE = "z-value"

This is used to pass the captured accelerometer z value.

Speed Value

public static final String SPEED_VALUE = "speed-value"

This is used to pass the captured GPS speed value.

Latitude Value

public static final String LATITUDE_VALUE = "latitude-value"

This is used to pass the captured GPS latitude value.

Longitude Value

public static final String LONGITUDE_VALUE = "longtitude-value"

This is used to pass the captured GPS longitude value.

Altitude Value

public static final String ALTITUDE_VALUE = "altitude-value"

This is used to pass the captured GPS altitude value.

Bearing Value

public static final String BEARING_VALUE = "bearing-value"

This is used to pass the captured GPS bearing value.

Accuracy Value

public static final String ACCURACY_VALUE = "accuracy-value"

This is used to pass the captured GPS accuracy value.

Acceleration Capture

public static final String ACCELERATION_CAPTURE = "acceleration-capture"

This is used to enable/disable capturing of accelerometer data which is sent to the API.

GPS Capture

public static final String GPS_CAPTURE = "gps-capture"

This is used to enable/disable capturing of GPS data which is sent to the API.

HR Capture

public static final String HR_CAPTURE = "heartrate-capture"

This is used to enable/disable capturing of heart rate data which is sent to the API.

Input Capture

public static final String INPUT_CAPTURE = "input-capture"

This is used to enable/disable capturing of text/emoji data which is sent to the API.

HR Data Rate

public static final String HEARTRATE_DATA_RATE = "heartrate_data_rate"

This is used to pass the interval rate (in milliseconds) for the heart rate data to be sent to the API.

Accelerometer Data Rate

public static final String ACCELEROMETER_DATA_RATE = "accelerometer_data_rate"

This is used to pass the interval rate (in milliseconds) for the accelerometer data to be sent to the API.

GPS Data Rate

public static final String GPS_DATA_RATE = "gps_data_rate"

This is used to pass the interval rate (in milliseconds) for the GPS data to be sent to the API.

Input Tags Data Rate

public static final String INPUT_TAGS_DATA_RATE = "input_tags_data_rate"

This is used to pass the interval rate (in milliseconds) for the text/emoji data to be sent to the API.

Device Disconnected

public static final String DEVICE_DISCONNECTED = "com.example.bluetooth.le.ACTION_GATT_DISCONNECTED"

This is used to pass a message from the SensumSDK service in case of any device disconnection.

API Response

public static final String API_RESPONSE = "api-response"

This is used to pass message from the SensumSDK service for the API response.

Toast Message

public static final String TOAST_MESSAGE = "toast-message"

This is used to pass informative toast message from the SensumSDK service.

API Base URL

public static final String API_BASEURL = "api-baseurl"

This is used to pass the base url for API to the SensumSDK service which is used for setting up communication with the API.

Auth Token

public static final String AUTH_TOKEN = "auth-token"

This is used to pass the authentication token for API to the SensumSDK service which is used for setting up communication with the API.

User Pool Id

public static final String USER_POOL_ID = "user-poolid"

This is used to pass the user pool id to the SensumSDK service which is used for user authentication.

Client Id

public static final String CLIENT_ID = "client-id"

This is used to pass the client id to the SensumSDK service which is used for user authentication.

Connect

public static final int CONNECT = 101

This is used to connect to the selected device from the list of the devices.

Bind Service

public static final int BIND_SERVICE = 103

This is used for binding to the service.

Unbind Service

public static final int UNBIND_SERVICE = 104

This is used for unbinding from the service.

Scan

public static final int SCAN = 105

This is used internally in the SensumSDK service to filter scan for devices.

Devices

public static final int DEVICES = 106

This is used to filter for devices.

Send

public static final int SEND = 108

This is used to filter send from the front end.

Connecting

public static final int CONNECTING = 109

This is used to filter connecting from the front end.

Start Service

public static final int START_SERVICE = 111

This is used to start the service.

Cancel Capture

public static final int CANCEL_CAPTURE = 112

This is used to cancel sending of the captured data to the API.

Start Capture

public static final int START_CAPTURE = 113

This is used to start sending of the captured data to the API.

Enable Storing

public static final int ENABLE_STORING = 114

This is used to enable storing of the captured data locally on the device.

Disable Storing

public static final int DISABLE_STORING = 115

This is used to disable storing of the captured data locally on the device.

Enable HR Timer

public static final int ENABLE_HRTIMER = 116

This is used to enable the timer for sending the heart rate data to the API.

Disable HR Timer

public static final int DISABLE_HRTIMER = 117

This is used to disable the timer for sending the heart rate data to the API.

Enable Accelerometer Timer

public static final int ENABLE_ACCTIMER = 118

This is used to enable the timer for sending the accelerometer data to the API.

Disable Accelerometer Timer

public static final int DISABLE_ACCTIMER = 119

This is used to disable the timer for sending the accelerometer data to the API.

Enable GPS Timer

public static final int ENABLE_GPSTIMER = 120

This is used to enable the timer for sending the GPS data to the API.

Disable GPS Timer

public static final int DISABLE_GPSTIMER = 121

This is used to disable the timer for sending the GPS data to the API.

Enable Input Timer

public static final int ENABLE_INPUTTIMER = 122

This is used to enable the timer for sending the text/emoji data to the API.

Disable Input Timer

public static final int DISABLE_INPUTTIMER = 123

This is used to enable the timer for sending the text/emoji data to the API.

Login

public static final int LOGIN = 124

This is used to pass a login message to the SensumSDK service.

Input Text

public static final int INPUT_TEXT = 125

This is used to filter/pass text & emoji message to the SensumSDK service.

Example Methods

Examples available in the ‘Android’ tab.

Initiate connection to service

    private final ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
            mIsBound = true;
            mServiceMessenger = new Messenger(binder);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

private final ServiceConnection mConnection = new ServiceConnection()

Connection made to the service.

Once bound to the service, the binder object is passed through to messenger to set it up.

 

 

 

 

Submit Credentials to service for authorization (Cognito User Pools)

    void submit() {
        Bundle bundle = new Bundle();
        bundle.putString(USER_NAME, "username");
        bundle.putString(PASSWORD, "password");
        bundle.putString(USER_POOL_ID, "userPoolId");
        bundle.putString(CLIENT_ID, "clientId");
        bundle.putString(API_BASEURL, "apiBaseUrl");
        bundle.putString(AUTH_TOKEN, "authToken");
        sendToService(bundle, LOGIN);
    }

void submit()

Sets up the credential bundle to be sent to the SensumSDK service this needs to be sent first to the SensumSDK service as only authenticated users can use the service.

 

 

 

 

Submit Credentials to service for authorization (Google Sign-In)

    void submit() {
        Bundle bundle = new Bundle();
        bundle.putString(API_BASEURL, apiBaseUrl);
        bundle.putString(API_KEY, apiKey);
        bundle.putString(IDENTITY_POOL_ID, identityPoolId);
        bundle.putString(GOOGLE_ID_TOKEN, googleIdToken);
        bundle.putString(GOOGLE_WEB_CLIENT_ID, googleWebClientId);
        sendToService(bundle, GOOGLE_LOGIN);
    }

Follow Google’s instructions to add Google Sign-In to your application.

Once successfully implemented you must send the Google Id token for the Google Sign-In application to us.

void submit()

Sets up the credential bundle to be sent to the SensumSDK service this needs to be sent first to the SensumSDK service as only authenticated users can use the service.

 

 

 

 

Send a data message to the service

    public void sendToService(Bundle bundle, int argValue) {
        Message message = Message.obtain();
        message.arg1 = argValue;
        message.setData(bundle);
        try {
            mServiceMessenger.send(message);
            Toast.makeText(this, "Requested the service", Toast.LENGTH_SHORT).show();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

public void sendToService(Bundle bundle, int argValue)

Send message to the service.

 

 

 

 

Create New Broadcast Receiver Object

    private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            switch (action) {
                case DEVICE_FILTER:
                    ArrayList<BluetoothDevice devices = intent.getParcelableArrayListExtra(EXTRA_DATA);
                    break;
                case VALUE_FILTER:
                    String message = intent.getStringExtra(EXTRA_DATA);
                    Log.d(TAG, "onReceive: " + message);
                    break;
                case GPS_FILTER:
                    Bundle gpsBundle = intent.getBundleExtra(EXTRA_DATA);
                    break;
                case ACC_FILTER:
                    Bundle accBundle = intent.getBundleExtra(EXTRA_DATA);
                    break;
                case DEVICE_DISCONNECTED:
                    Log.d(TAG, "Device disconnected, please re-connect");
                    break;
                case API_RESPONSE:
                    String apiResponse = intent.getStringExtra(EXTRA_DATA);
                    Log.d(TAG, apiResponse);
                    break;
                case TOAST_MESSAGE:
                    String toastMessage = intent.getStringExtra(EXTRA_DATA);
                    break;
                case WEAR_HR_VALUE:
                    String wearMessage = intent.getStringExtra(EXTRA_DATA);
                    break;
            }

        }
    };

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver()

Broadcast receiver with the list of registered filters.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Update IntentFilter with new Actions

    private IntentFilter updateIntentFilter() {
        final IntentFilter intentFilter = new IntentFilter();

        intentFilter.addAction(REQUEST_FILTER);
        intentFilter.addAction(DEVICE_FILTER);
        intentFilter.addAction(VALUE_FILTER);
        intentFilter.addAction(GPS_FILTER);
        intentFilter.addAction(ACC_FILTER);
        intentFilter.addAction(DEVICE_DISCONNECTED);
        intentFilter.addAction(API_RESPONSE);
        intentFilter.addAction(TOAST_MESSAGE);
        intentFilter.addAction(WEAR_HR_VALUE);
        return intentFilter;
    }

private IntentFilter updateIntentFilter()

 

 

 

 

 

 

 

 

Start Biometric Data Capture

    private void startCaptureSetUp() {
        Toast.makeText(this, "Started capturing", Toast.LENGTH_SHORT).show();
        Log.d(TAG, "Started capturing");
        sendToService(getCaptureBundle(), START_CAPTURE);
    }

private void startCaptureSetUp()

Starts capturing of biometric/contextual data.  

 

 

 

 

 

Get Capture Bundle

    private Bundle getCaptureBundle() {
        Bundle bundle = new Bundle();
        bundle.putBoolean(ACCELERATION_CAPTURE, adapter.accelerationView.getSwitchValue());
        bundle.putBoolean(HR_CAPTURE, true);
        bundle.putBoolean(GPS_CAPTURE, true);
        bundle.putBoolean(INPUT_CAPTURE, true);
        bundle.putLong(HEARTRATE_DATA_RATE, 20000);
        bundle.putLong(ACCELEROMETER_DATA_RATE, 30000);
        bundle.putLong(GPS_DATA_RATE, 20000);
        bundle.putLong(INPUT_TAGS_DATA_RATE, 20000);
        return bundle;
    }

private Bundle getCaptureBundle()

Sets up the bundle data for capture using the service constants.

 

 

 

 

 

 

 

 

Stop Biometric Data Capture

    private void stopCaptureSetUp() {
        Toast.makeText(this, "Stopped capturing", Toast.LENGTH_SHORT).show();
        sendToService(getCaptureBundle(), ServiceConstants.CANCEL_CAPTURE);
    }

private void stopCaptureSetUp()

Stops capturing of biometric/contextual data.

 

 

 

 

SensumSDK - iOS

iOS Device Compatibility

The iOS version of the SensumSDK can be installed on devices with v10.3.3 and up.

We recommend the iPhone 5 and up as devices to use with the SensumSDK.

Bluetooth Device Compatibility

Note: This document is regularly updated with new devices. Please contact us for integration details.

Accepted Biometric Data Inputs

The iOS SensumSDK can accept the following metrics:

SDK Module Command Protocol

Every SensumSDK module conforms to the module command protocol. At present these can be switched on and off independently. Every SensumSDK-managed object has three states that can be toggled independently:

Protocol Code - SensumSDK written in Swift 3

import foundation

public protocol SDKModuleCommandProtocol {
    func startUpdating()
    func stopUpdating()
    func startRecording()
    func stopRecording()
    func startSendingToAPI()
    func stopSendingToAPI()
    func isUpdating() -> Bool
    func isRecording() -> Bool
    func isSendingToAPI() -> Bool
}

Starting the SensumSDK

To start the SensumSDK you will need:

By default, the host URL and stage URL should be “api.sensum.co” and “v0” respectively, unless we have instructed you otherwise.

The SensumSDKManager is the root object in the SensumKit which starts the service. The manager prepares all objects you can use to interface with your device motion, location and bluetooth peripheral frameworks. As well as all the data required to send data to the SensumAPI.

In order to create a single instance of the SensumSDKManager, follow the example within the Code Snippet below (the example makes use of a TabBarController to do this, but this could be achieved within any file).

Code Snippet

import UIKit
import SensumKit

class TabBarController: UITabBarController {
    var sensumSDK : SensumSDKManager?

    override func viewDidLoad() {
           super.viewDidLoad()
           // Do any additional setup after loading the view, typically from a nib.
           sensumSDK = SensumSDKManager(
               requestEngineInternalInSeconds: 30,
               apiKey: "PublicDemoKeyForDocumentation",
               host: "api.sensum.co",
               stage: "v0")
        startEverythingUpdating()
       }

    func startEverythingUpdating() {
        sensumSDK?.accelerometer.startUpdating()
        sensumSDK?.location.startUpdating()
        sensumSDK?.bluetooth.startUpdating()
        sensumSDK?.tag.startUpdating()
    }
}

This single instance of the SensumSDKManager can then be referenced from elsewhere within your application.

Authentication

To get started working with the SensumSDKManager you’re going to need a valid Authentication session. Create an instance of this object and give it valid sign-in details. When using third-party login providers you must provide us with an Audience ID. In the case of Google Sign-In, you must provide use with the Google Applications Client ID. You can find this id contained inside the plist configuration file generated when you set up the login application. For more details please read Google’s documentation here.

Authentication Command

Federated sign-in

In order to authenticate you must sign in using Google Sign-in. Once this has been implemented, use this function to sign in to access the SensumAPI.

sdkManager?authentication.federatedSignIn(provider: provider, authenticationToken: authenticationToken)

Parameters

Name Description
provider The URL of the identity provider that you are using this will be ‘accounts.google.com’ in the case of Google Sign-In
authenticationToken This is the authentication token generated by successful login with the identity provider

API Command

All available commands for configuring and enabling API communication.

Initialisation

var apiCommand = APICommand()

Set Server Request Rate

apiCommand.setServerRequestRate(requestRateInSeconds)

Set the frequency of data uploads to the SensumAPI.

Parameters

Name Description
requestRateInSeconds Frequency of server updates in seconds

Get Server Request Rate

apiCommand.getServerRequestRate()

Returns how often requests are sent to the SensumAPI.

Assign Listener

apiCommand.assignListener(listener)

Assign a listener to listen for SensumAPI events.

Parameters

Name Type Description
listener APIResponseListener An instance of a class that conforms to the APIResponseListener extension

Accelerometer Command

All available commands for the SensumSDK accelerometer component.

Start Updating

sdkManager?.accelerometer.startUpdating()

Start the updates from CoreMotion.

Stop Updating

sdkManager?accelerometer.stopUpdating()

Stop the updates from CoreMotion.

Start Recording

sdkManager?accelerometer.startRecording()

Start recording the updates from CoreMotion.

Stop Recording

sdkManager?accelerometer.stopRecording()

Stop recording the updates from CoreMotion.

Start Sending to API

sdkManager?accelerometer.startSendingToAPI()

Start sending the updates of CoreMotion to the SensumAPI.

Stop Sending to API

sdkManager?accelerometer.stopSendingToAPI()

Stop sending the updates of CoreMotion to the SensumAPI.

Check Module Update Status

sdkManager?accelerometer.isUpdating()

Check if CoreMotion Accelerometer is updating. Returns a boolean value.

Check Module Recording Status

sdkManager?accelerometer.isRecording()

Check if CoreMotion Accelerometer is recording. Returns a boolean value.

Check SensumAPI Update Status

sdkManager?accelerometer.isSendingToAPI()

Check if CoreMotion Accelerometer is sending to the SensumAPI.

Assign Listener

sdkManager?accelerometer.assignListener(listener)

Assign a listener to the accelerometer module to receive CoreMotion event updates.

Parameters

Parameter Type Description
listener AccelerometerListener An instance of a class that conforms to the AccelerometerListener extension

Set Read Frequency

sdkManager?accelerometer.setReadFrequency(newIntervalInSeconds)

Set the frequency of the updates from the accelerometer.

Parameters

Parameter Type Description
newIntervalInSeconds Double Set the interval time in seconds, (minimum interval is 0.01s)

Bluetooth Command

Below are all available commands relating to Bluetooth within the SensumSDK.

Note: This document is regularly updated with new devices. Please contact us for integration details. GSR data is only accessible from Shimmer devices at present.

Start Updating

sdkManager?bluetooth.startUpdating()

Start the updates of any connected heart rate peripheral.

Stop Updating

sdkManager?bluetooth.stopUpdating()

Stop the updates of any connected heart rate peripheral.

Start Recording

sdkManager?bluetooth.startRecording()

Start recording the updates of any connected heart rate peripheral.

Stop Recording

sdkManager?bluetooth.stopRecording()

Stop recording the updates of any connected heart rate peripheral.

Start Sending to SensumAPI

sdkManager?bluetooth.startSendingToAPI()

Start sending the updates of any connected heart rate peripheral to the SensumAPI.

Stop Sending to SensumAPI

sdkManager?bluetooth.stopSendingToAPI()

Stop sending the updates of any connected heart rate peripheral to the SensumAPI.

Check Module Update Status

sdkManager?bluetooth.isUpdating()

Check if module is updating. Returns a boolean value.

Check Module Recording Status

sdkManager?bluetooth.isRecording()

Check if module is recording. Returns a boolean value.

Check SensumAPI Update Status

sdkManager?bluetooth.isSendingToAPI()

Check if module is sending to the SensumAPI.

Assign Listener

sdkManager?bluetooth.assignListener(listener)

Assign a listener to the bluetooth module to receive bluetooth event updates.

Parameters

Parameter Type Description
listener BluetoothListener An instance of a class that conforms to the BluetoothListener extension

Start Scan for Devices

sdkManager?bluetooth.startScanForDevices()

Start scanning for discoverable peripheral devices.

Connect to peripheral device

sdkManager?bluetooth.connectTo(peripheralDevice)

Connect to a discovered peripheral device. Discovered devices can be acquired from the listOfDevices returned by the getDeviceList() function.

Parameters

Parameter Type Description
peripheralDevice CBPeripheral The bluetooth peripheral device you want to connect to

Clear List of Discovered Devices

sdkManager?bluetooth.clearDeviceList()

Clear the list of devices discovered (equivalent to a refresh).

Disconnect from Device

sdkManager?bluetooth.disconnect()

Disconnect from the currently connected peripheral device.

Get Device List

sdkManager?bluetooth.getDeviceList()

Return a list of all discovered peripherals. The list will begin populating after startScanForDevices() is called.

Returns a list of dictionaries containing bluetooth peripheral information with three fields:

Field Name Type Description
deviceName String returns a String of the device name
peripheral CoreBluetooth CBPeripheral returns the CoreBluetooth CBPeripheral object (import CoreBluetooth to use this)
type String For now all peripherals are of type BLE

Example Usage

     if let peripheralDictionary = sdkManager?.bluetooth.getDeviceList()[index]?["peripheral"] {
        let peripheralToAdd = peripheralDictionary as! CBPeripheral
     }

Location Command

All available commands for the SensumSDK location component.

Start Updating

sdkManager?location.startUpdating()

Start the updates from CoreLocation.

Stop Updating

sdkManager?location.stopUpdating()

Stop the updates from CoreLocation.

Start Recording

sdkManager?location.startRecording()

Start recording the updates from CoreLocation.

Stop Recording

sdkManager?location.stopRecording()

Stop recording the updates from CoreLocation.

Start Sending to API

sdkManager?location.startSendingToAPI()

Start sending the updates of CoreLocation to the SensumAPI.

Stop Sending to API

sdkManager?location.stopSendingToAPI()

Stop sending the updates of CoreLocation to the SensumAPI.

Check Module Update Status

sdkManager?location.isUpdating()

Check if the location module is updating. Returns a boolean value.

Check Module Recording Status

sdkManager?location.isRecording()

Check if the location module is recording. Returns a boolean value.

Check SensumAPI Update Status

sdkManager?location.isSendingToAPI()

Check if the location module is sending to the SensumAPI.

Assign Listener

sdkManager?location.assignListener()

Assign a listener to the location module to receive CoreLocation event updates.

Parameters

Parameter Type Description
listener LocationListener An instance of a class that conforms to the LocationListener extension

Tag Command

All available commands for our tagging module. This is useful for noting events that occur in data. e.g. “Started workout set”, “Jumped out of a plane”, “Finished jogging”. These events are automatically timestamped.

Start Updating

sdkManager?tag.startUpdating()

Start the updates from the tag system which notifies listeners of new tags.

Stop Updating

sdkManager?tag.stopUpdating()

Stop the updates from the tag system.

Start Recording

sdkManager?tag.startRecording()

Start recording tags created.

Stop Recording

sdkManager?tag.stopRecording()

Stop recording tags created.

Start Sending to SensumAPI

sdkManager?tag.startSendingToAPI()

Start sending tags to the SensumAPI.

Stop Sending to SensumAPI

sdkManager?tag.stopSendingToAPI()

Stop sending tags to the SensumAPI.

Check Module Update Status

sdkManager?tag.isUpdating()

Check if the tag module is updating. Returns a boolean value.

Check Module Recording Status

sdkManager?tag.isRecording()

Check if the tag module is recording. Returns a boolean value.

Check SensumAPI Update Status

sdkManager?tag.isSendingToAPI()

Check if the tag module is sending to the SensumAPI.

Assign Listener

sdkManager?tag.assignListener(listener)

Assign a listener to the tag module to receive tag event updates.

Parameters

Parameter Type Description
listener TagListener An instance of a class that conforms to the TagListener extension

Create Tag

sdkManager?tag.createTag(tag)

Creates a tag object composed of a string and timestamp pair.

Parameters

Parameter Type Description
tag String A string object of a message or emoticon

Sentiment Command

All available commands for our sentiment module. This runs analysis on the text input and returns it’s emotionality data.

Start Updating

sdkManager?sentiment.startUpdating()

Start the updates from the sentiment text system which notifies listeners of new sentiment text .

Stop Updating

sdkManager?sentiment.stopUpdating()

Stop the updates from the sentiment system.

Start Recording

sdkManager?sentiment.startRecording()

Start recording senrtiment text created.

Stop Recording

sdkManager?sentiment.stopRecording()

Stop recording sentiment text created.

Start Sending to SensumAPI

sdkManager?sentiment.startSendingToAPI()

Start sending sentiment text to the SensumAPI.

Stop Sending to SensumAPI

sdkManager?sentiment.stopSendingToAPI()

Stop sending sentiment text to the SensumAPI.

Check Module Update Status

sdkManager?sentiment.isUpdating()

Check if the sentiment text module is updating. Returns a boolean value.

Check Module Recording Status

sdkManager?sentiment.isRecording()

Check if the sentiment text module is recording. Returns a boolean value.

Check SensumAPI Update Status

sdkManager?sentiment.isSendingToAPI()

Check if the sentiment text module is sending to the SensumAPI.

Assign Listener

sdkManager?sentiment.assignListener(listener)

Assign a listener to the sentiment text module to receive sentiment updates.

Parameters

Parameter Type Description
listener SentimentListener An instance of a class that conforms to the SentimentListener extension

Create Sentiment

sdkManager?sentiment.createSentiment(sentiment)

Creates a sentiment object composed of a string and timestamp pair.

Parameters

Parameter Type Description
sentiment String A string object of a message or emoticon

APIListener

To be able to listen for updates from the API you must extend your class using an extension of type API Listener using the following example code.

APIListener extension

 extension RecordingMasterViewController: APIListener {

    func realmResponseSaved() {
        // saved to Realm, lets query it and print the values
        if let realmResponse = try? Realm().objects(Response.self).last {
            print(realmResponse)
        }
    }

    func sentimentResponseSaved() {
        if let realmSentiment = try? Realm().objects(SentimentResponse.self).last {
            print(realmSentiment)
        }
    }

    func arousalReceived(arousalScore: Double) {
        print("arousalScore \(arousalScore)")
    }

    func apiRequestFailure(message: String, statusCode: Int?) {
        print("Failed to send to SensumAPI \(message) \(statusCode)")
    }

    func apiRequestSuccessful() {
        print("successfully saved")
    }

}

API Listener Functions: API Request Successful

func apiRequestSuccessful()

Used to notify listeners that a request made to the SensumAPI was successful. Called immediately after a 200 HTTP response is received but not before the data received has been safely saved to Realm instance of SensumKit.

API Listener Functions: API Request Failure

func apiRequestFailure(message: String, statusCode: Int?)

Used to notify listeners that a request made to the SensumAPI was unsuccessful. Called immediately after a HTTP response that was not 200.

Parameters

Parameter Type Description
message String The error message from the HTTP request
statusCode Int? Optional URLResponse HTTP status code from the HTTP request

API Listener Functions: Realm Response Saved

func realmResponseSaved()

Used to notify listeners that a successful request body has been parsed and is ready for querying in Realm. Called immediately after response.save() is called.

API Listener Functions: Arousal Received

func arousalReceived(arousalScore: Double)

Used to notify listeners that a successful request body has been parsed and an arousal score value is sent to listeners.

Parameters

Parameter Type Description
arousalScore Double Double value of the calculated arousal from the SensumAPI

API Listener Functions: Realm Sentiment Response Saved

func realmSentimentResponseSaved()

Used to notify listeners that a successful request body for a text/emoji object has been parsed and is ready for querying in Realm. Called immediately after sentimentEmotion.save() is called.

API Listener Functions: Retrieve JSON From SensumAPI

func retrieveJSONFromSensumAPI(json: [String:Any]?)

Used to notify listeners that a successful request body has been safely parsed and is available for use in the users application.

Parameters

Parameter Type Description
json JSON A dictionary of JSON returned from the SensumSDK

API Listener Functions: Sentiment Response Received

func sentimentResponseReceived()

Used to notify listeners that a successful request body for a text/emoji object has been parsed and is ready for querying in Realm. Called immediately after sentimentEmotion.save() is called.

API Listener Functions: Sentiment Request Successful

func sentimentRequestSuccesful()

Used to notify listeners that a request made to the SensumAPI sentiment endpoint was successful. Note this is only for sentiment analysis and not general requests. Called immediately after a 200 HTTP response is received but not before the data received has been safely saved to the Realm instance of SensumKit.

API Listener Functions: Sentiment Request Failure

func sentimentRequestFailure(message: String, statusCode: Int?)

Used to notify listeners that a request made to the SensumAPI sentiment endpoint was unsuccessful. Note this is only for sentiment analysis and not general requests. Called immediately after a HTTP response that was not 200.

Parameters

Parameter Type Description
message String The error message from the HTTP request
statusCode Int Optional URLResponse HTTP status code from the HTTP request

AccelerometerListener

Accelerometer listeners handle updates from the SensumSDK accelerometer component. Subscribers will be notified of updates to the Accelerometer object. To use this listener extend your class using the following example code:

AccelerometerListener extension

extension AccelerometerViewController: AccelerometerListener {
  func accelerationUpdated(newAcceleration: CMAcceleration, dateTime: Date) {
        DispatchQueue.main.async {
            print(newAcceleration)
        }
    }
}

AccelerometerListener Functions: Acceleration Updated

func accelerationUpdated(newAcceleration: CMAcceleration, dateTime: Date)

Called when a new accelerometer value is generated by the device.

Parameters

Parameter Type Description
newAcceleration CMAcceleration A raw acceleration object from the CoreMotion framework.
dateTime Date The native Date() in date time of when the acceleration object was created.

AuthenticationListener

This listener can be used to handle the Authentication component of the local federated identity sign-in process. This step occurs after the third party login, where the SensumAPI will validate the idToken from the end user.

AuthenticationListener Functions: Sign In Successful

func signInSuccesful(message: String)

Implement to handle the result of a successful login to the SensumAPI after the third party identity provider authentication.

Parameters

Parameter Type Description
message String A success message from a valid sign-in result.

AuthenticationListener Functions: Sign In Failed

func signInFailed(message: String)

AuthenticationListener Functions: Sign In Successful

func signInSuccesful(message: String)

Implement to handle the result of a successful login to the SensumAPI after the third party identity provider authentication.

Parameters

Parameter Type Description
message String A fail message from an invalid sign-in result.

BluetoothListener

Bluetooth listeners handle updates from the SensumSDK bluetooth component. Subscribers will be notified of updates to the Bluetooth object.

To use a BluetoothListener extend your class as in the following example code:

BluetoothListener extension

extension BluetoothTableViewController: BluetoothListener {

  public func deviceDiscovered() {
    DispatchQueue.main.async {
      self.tableView.reloadData()
    }
  }

  public func bpmUpdated(newBpm: Int, dateTime: Date) {}
  public func deviceConnectionSuccess() {}
  public func deviceConnectionFailure() {}
  public func deviceDisconnected(disconnectedPeripheral: CBPeripheral) {}
}

BluetoothListener Functions: Device Discovered

func deviceDiscovered()

Called when a BLE device has been discovered during a device scan.

BluetoothListener Functions: Device Connection Success

func deviceConnectionSuccess()

Called when the users device has successfully connected to a BLE device.

BluetoothListener Functions: Device Connection Failure

func deviceConnectionFailure()

Called when the users device has failed to connect to a BLE device.

BluetoothListener Functions: Device Disconnected

func deviceDisconnected(disconnectedPeripheral: CBPeripheral)

Called when the users device has been disconnected from a BLE device.

Parameters

Parameter Type Description
disconnectedPeripheral CBPeripheral The CoreBluetooth BLE device that disconnected.

BluetoothListener Functions: BPM Updated

func bpmUpdated(newBpm: Int, dateTime: Date)

Called when the BLE device connected to the users device has a processed update value ready.

Parameters

Parameter Type Description
newBpm Int A heart rate value in beats per minute.
dateTime Date A native Date() object of when the reading was generated.

LocationListener

Location listeners handles updates from the Location SensumSDK component. Subscribers will be notified of updates to the Location object.

To use a LocationListener, extend your class as seen in the following example code:

LocationListener extension

extension GPSViewController: LocationListener {
    func locationUpdated(newLocation: CLLocation) {
        DispatchQueue.main.async {
      print(newLocation)
        }
    }
}

LocationListener Functions: Location Updated

func locationUpdated(newLocation:CLLocation)

Called when a new location update has been generated by the device.

Parameters

Parameter Type Description
newLocation CLLocation A CoreLocation type location object containing fine values about the device location.

TagListener

This listener can be used to handle the response to Tag objects of unicode text/emoji objects.

TagListener Functions: Tag Created

func tagCreated(newTag: String, dateTime: Date)

Called when a new tag object is created.

Parameters

Parameter Type Description
newTag String The literal string tag that was created.
dateTime Date A native Date() object representing time and date when the tag was created.

SentimentListener

This listener can be used to handle the event of a newly created Sentiment object of unicode text/emoji objects from local user input. This is NOT used for retrieving Sentiment from the SensumSDK. Please use the APIListener.swift protocols instead.

SentimentListener Functions: Sentiment Created

func func sentimentCreated(sentimentText: String, dateTime: Date)

Used to nofity listeners that a new sentiment object was created locally.

Parameters

Parameter Type Description
sentimentText String The literal string sentiment that was created.
dateTime Date A native Date() object representing time and date when the sentiment was created.

ServerRequestEngine

ServerRequestEngine Functions: Set Request Interval

public func setRequestInterval(newUpdateInterval : Int)

This changes the interval immediately, destroying the old timer and starting a new one counting from time zero.

Parameters

Parameter Type Description
newUpdateInterval Int The new update interval in seconds

SDKManagedObject

The managed DataSource that custom types must implement to use with the SensumAPI.

SDKManagedObject Functions: Start Updates

func startUpdates()

Start retrieving updates from the data source.

SDKManagedObject Functions: Stop Updates

func stopUpdates()

Stop retrieving updates from the data source.

SDKManagedObject Functions: Start Recording

func startRecording()

Start recording updates from the data source to the local Realm store on device.

SDKManagedObject Functions: Stop Recording

func stopRecording()

Stop recording updates from the data source to the local Realm store on device.

SDKManagedObject Functions: Start Sending To API

func startSendingToAPI()

Start sending updates from the data source to the SensumAPI.

SDKManagedObject Functions: Stop Sending To API

func stopSendingToAPI()

Stop sending updates from the data source to the SensumAPI.

Database

Database manager handles the key functions of the Realm instance used as part of the SensumSDK.

Database Functions: Delete All Records

static public func deleteAllRecords()

Attempts to delete the default Realm database on the device, deleting all SensumKit related data.

BluetoothPeripheral

public struct BluetoothPeripheral

BluetoothPeripheral

public struct BluetoothPeripheral {
    var advertisedName: String = ""
    var peripheral: CBPeripheral
    var type: String = "ble"
}

Struct composing a Bluetooth Device, including name, type and peripheral value.

Response

Parent response Realm object generated from request data sent from the device.

Response Functions: Save

func save()

Saves to Realm.

HeartRateResponse

A root heart rate response object generated from the SensumAPI.

Response Functions: Save

func save()

Saves to Realm.

AccelerometerResponse

AccelerometerResponse is a mapping to Accelerometer based data from the device that was sent and processed by the SensumAPI. Realm type object which is persisted under the Response object.

AccelerometerResponse Functions: Save

func save()

Saves to Realm.

LocationResponse

A root location response object generated from the SensumAPI.

LocationResponse Functions: Save

func save()

Saves to Realm.

ArousalResponse

ArousalResponse is the root object of arousal data generated by the SensumAPI.

ArousalResponse Functions: Save

func save()

Saves to Realm.

SentimentResponse

Sentiment represents the SensumAPI analysis of textual and emoji input sent from SensumKit.

SentimentResponse Functions: Save

func save()

Saves to Realm.

HeartRate

A raw heart rate value processed from a BLE device that was connected to the users device.

HeartRate Functions: Map To Schema

public func mapToSchema() -> [RecordTuple]

Maps the raw Heart rate value to the database record.

Location

A CLLocation Realm type object saved from the location data that was generated by the device.

HeartRate Functions: Map To Schema

public func mapToSchema() -> [RecordTuple]

Maps the location data to the database record.

Accelerometer

The Realm Accelerometer object class, used for persisting raw accelerometer readings to Realm.

Accelerometer Functions: Map To Schema

public func mapToSchema() -> [RecordTuple]

Maps the location data to the database record.

UnicodeTag

Local text/emoji unicode objects created that can be used for sentiment analysis completed by the SensumAPI.

UnicodeTag Functions: Map To Schema

public func mapToSchema() -> [RecordTuple]

Maps the location data to the database record.

ArousalStat

Statistical information relating to arousal which is generated by the SensumAPI.

ArousalStat Functions: Save

func save()

Saves to Realm.

ArousalRecord

The arousal record relates to the arousal calculated and sent as a response from the SensumAPI which processed heart rate data to generate this object.

ArousalRecord Functions: Save

func save()

Saves to Realm.

Stat

A generic statistic object that represents related values about a processed data from the SensumAPI.

Stat Functions: Save

func save()

Saves to Realm.

Percentile

A percentile object represents the amount of values that exist as part of a parent reading in a certain percentile. Generated from the SensumAPI.

Percentile Functions: Save

func save()

Saves to Realm.

Event

Generic events that can occur relating to the changes of the values coming from a typical data stream.

Event Functions: Save

func save()

Emotion

Emotion is a collection of inferred emotions from the sentiment analysis performed by the SensumAPI.

Emotion Functions: Save

func save()

Tutorial - Android

Introduction

This tutorial is designed to assist Android Developers working with the SensumSDK and SensumAPI.

It is intended to provide a detailed guide to using the Sensum Emotion AI toolkit, providing code examples and guidelines for use.

Have fun and enjoy!

Getting Started

We strongly recommend using Android Studio v2.3.3 and above. We work on Android Studio v2.3.3 at time of our first public SensumSDK release.

Figure 1 - Start New Project

Figure 1 - Start New Project


Figure 2 - Create New Project

Figure 2 - Create New Project


Figure 3 - Select Platforms

Figure 3 - Select Platforms


Figure 4 - Add Activity

Figure 4 - Add Activity


Figure 5 - Customize the Activity

Figure 5 - Customize the Activity


Figure 6 - Add an Activity to Wear

Figure 6 - Add an Activity to Wear


Figure 7 - Customize the Wear Activity

Figure 7 - Customize the Wear Activity


Managing Project Dependencies

 Figure 8 - New Module

Figure 8 - Creating A New Module


 Figure 9 - Import .JAR/.AAR Package

Figure 9 - Import .JAR/.AAR Package


 Figure 10 - Create New Module

Figure 10 - Create New Module


Figure 11 - Project Structure

Figure 11 - Project Structure


Figure 12 - Module Dependency

Figure 12 - Module Dependency


Figure 13 - Choose Modules

Figure 13 - Choose Modules


Implementing the Shimmer library for GSR values

Including Permissions

Code Snippet 1

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

Creating a Service

Code Snippet 2

private final ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mIsBound = true;
            mServiceMessenger = new Messenger(iBinder);
        }

       @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.d(TAG, "onServiceDisconnected: ");
        }
    };

Code Snippet 3

<service android:name="co.sensum.sensumservice.SDK.SdkService"/>
<service android:name="co.sensum.sensumservice.SDK.BLE.BluetoothLeService"/>

Binding and Unbinding the Service

Code Snippet 4

@Override
protected void onStart() {
    super.onStart();
    Intent intent = new Intent(this, SdkService.class);
    bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}

Code Snippet 5

@Override
protected void onDestroy() {
    super.onDestroy();
    if (mIsBound) {
        unbindService(mConnection);
        mIsBound = false;
    }
}

Using a Broadcast Receiver

Table 1: Broadcast Receiver Filters

Action Description IntentExtras
BLE_DEVICE_FILTER Filters for BLE devices ArrayList<BluetoothDevice>
VALUE_FILTER Filters for heart rate value String
GPS_FILTER Filters for GPS values Bundle
ACC_FILTER Filters for acceleration values Bundle
DEVICE_DISCONNECTED Filters for a device disconnected value null
API_RESPONSE Filters for responses from the API String
TOAST_MESSAGE Filters for messages from the Service String
CONNECTION_FILTER Filters for connection BLE messages String
BLUETOOTH_CONNECTION_FILTER Filters for bluetooth connection messages String
BLUETOOTH_DEVICE_FILTER Filters for bluetooth devices ArrayList<BluetoothDevice>
GSR_FILTER Filters for GSR values String
ACC_FAILED_REGISTERED Filters for acceleration failure from unsupported devices null
HELLO_FILTER Filters for hello message String

Setting up the Broadcast Receiver

Code Snippet 6

    private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            switch (action){
                case HELLO_FILTER:
                    Toast.makeText(MainActivity.this, intent.getStringExtra(EXTRA_DATA), Toast.LENGTH_LONG).show();
                    break;
                case GPS_FILTER:
                    Bundle gpsBundle = intent.getBundleExtra(EXTRA_DATA);
                    break;
                case ACC_FILTER:
                    Bundle accBundle = intent.getBundleExtra(EXTRA_DATA);
                    isAcc = true;
                    break;
                case VALUE_FILTER:
                    String hrValue = intent.getStringExtra(EXTRA_DATA);
                    break;
                case GSR_FILTER:
                    String gsrValue = intent.getStringExtra(EXTRA_DATA);
                    break;
                case API_RESPONSE:
                    String apiResponse = intent.getStringExtra(EXTRA_DATA);
                    break;
                case TOAST_MESSAGE:
                    String toastMessage = intent.getStringExtra(EXTRA_DATA);
                    break;
            }
        }
    };

Code Snippet 7

 @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(mMessageReceiver, getUpdateIntentFilter());
    }

Code Snippet 8

  private IntentFilter getUpdateIntentFilter() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(HELLO_FILTER);
        filter.addAction(GPS_FILTER);
        filter.addAction(ACC_FILTER);
        filter.addAction(VALUE_FILTER);
        filter.addAction(GSR_FILTER);
        filter.addAction(API_RESPONSE);
        filter.addAction(TOAST_MESSAGE);
        return filter;
    }

Code Snippet 9

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mIsBound){
            unbindService(mConnection);
            mIsBound = false;
            unregisterReceiver(mMessageReceiver);
        }
    }

Communicating with the Service

Table 2: Send to Service Commands

Constants (of type ‘Int’) Required Bundle Data
CONNECT String DEVICE_NAME,
String DEVICE_ADDRESS
BLE_SCAN null
START_CAPTURE boolean ACCELERATION_CAPTURE,
boolean HR_CAPTURE, boolean GPS_CAPTURE,
boolean INPUT_CAPTURE,
int DATA_RATE_SAMPLE,
int DATA_RATE_SEND
CANCEL_CAPTURE boolean ACCELERATION_CAPTURE,
boolean HR_CAPTURE,
boolean GPS_CAPTURE,
boolean INPUT_CAPTURE
LOGIN String USER_NAME,
String PASSWORD,
String API_BASEURL,
String AUTH_TOKEN
GOOGLE_LOGIN String API_BASEURL_IAM,
String API_KEY,
String IDENTITY_POOL_ID,
String GOOGLE_ID_TOKEN,
String GOOGLE_AUTH_CODE
INPUT_TEXT String TEXT_MESSAGE
BLUETOOTH_SCAN null
CONNECT_BLUETOOTH_DEVICE String DEVICE_NAME,
String DEVICE_ADDRESS
HELLO null
EXPORT_DATABASE null
DELETE_ALL_DATA null

Code Snippet 10

   public void sendToService(Bundle bundle, int argValue){
        Message message = Message.obtain();
        message.arg1 = argValue;
        message.setData(bundle);
        try {
            mServiceMessenger.send(message);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

Testing the Service

Code Snippet 11

  private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            switch (action){
                case HELLO_FILTER:
                    Toast.makeText(MainActivity.this, intent.getStringExtra(EXTRA_DATA), Toast.LENGTH_LONG).show();
                    break;
                case GPS_FILTER:
                    Bundle gpsBundle = intent.getBundleExtra(EXTRA_DATA);
                    break;
                case ACC_FILTER:
                    Bundle accBundle = intent.getBundleExtra(EXTRA_DATA);
                    isAcc = true;
                    break;
                case VALUE_FILTER:
                    String hrValue = intent.getStringExtra(EXTRA_DATA);
                    break;
                case GSR_FILTER:
                    String gsrValue = intent.getStringExtra(EXTRA_DATA);
                    break;
                case API_RESPONSE:
                    String apiResponse = intent.getStringExtra(EXTRA_DATA);
                    break;
                case TOAST_MESSAGE:
                    String toastMessage = intent.getStringExtra(EXTRA_DATA);
                    break;
            }
        }
    };

Code Snippet 12

Button button = (Button) findViewById(R.id.hello_button);
button.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
       sendToService(null, HELLO);
   }
});

Setting up BLE

Code Snippet 13

Button button = (Button) findViewById(R.id.scanButton);
button.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
       sendToService(null, BLE_SCAN);
   }
});

Receiving BLE Devices

Connecting a BLE Device

Code Snippet 14

Bundle bundle =  new Bundle();
bundle.putString(ServiceConstants.DEVICE_NAME, deviceName);
bundle.putString(ServiceConstants.DEVICE_ADDRESS, deviceAddress);
sendToService(bundle, CONNECT);

Receiving Values

Bluetooth

Note: This document is regularly updated with new devices. Please contact us for integration details. GSR data is only accessible from Shimmer 2r devices at present.

Receiving GPS and Acceleration Values

Table 3: Broadcast Receiver Filter Examples

Filter Bundle Constants Example Method Call
GPS Filter Float speed SPEED_VALUE gpsBundle.getFloat(SPEED_VALUE)
Double latitude LATITUDE_VALUE gpsBundle.getFloat(LATITUDE_VALUE)
Double longitude LONGITUDE_VALUE gpsBundle.getFloat(LONGITUDE_VALUE)
Double altitude ALTITUDE_VALUE gpsBundle.getFloat(ALTITUDE_VALUE)
Float bearing BEARING_VALUE gpsBundle.getFloat(BEARING_VALUE)
Float accuracy ACCURACY_VALUE gpsBundle.getFloat(ACCURACY_VALUE)
ACC_FILTER Float x X_VALUE accBundle.getFloat(X_VALUE)
Float y Y_VALUE accBundle.getFloat(Y_VALUE)
Float z Z_VALUE accBundle.getFloat(Z_VALUE)

Capturing Data

Code Snippet 15

public Bundle getCaptureBundle() {
 Bundle bundle = new Bundle();
 bundle.putBoolean(ACCELERATION_CAPTURE, isAcc);
 bundle.putBoolean(HR_CAPTURE, isHr);
 bundle.putBoolean(GPS_CAPTURE, isGps);
 bundle.putBoolean(INPUT_CAPTURE, isInput);
 bundle.putLong(DATA_RATE_SEND, dataRate);
 return bundle;
}

Code Snippet 16

sendToService(getCaptureBundle(), START_CAPTURE);
...
sendToService(getCaptureBundle(), CANCEL_CAPTURE);

Receiving Values from SensumAPI

Table 4: Additional Broadcast Receiver Filters

Action (description) Intent Extras
HR_EVENTS_FILTER Filters for heart rate events null
ACC_EVENT_FILTER Filters for acceleration events null
AROUSAL_EVENT_FILTER Filters for arousal events null
GPS_EVENT_FILTER Filters for GPS events null
GSR_EVENT_FILTER Filters for GSR events null
EMOJI_SENTIMENT_FILTER Filters for Emoji Sentiment values Bundle
TEXT_SENTIMENT_FILTER Filters for Text Sentiment values Bundle

Code Snippet 17

private IntentFilter getUpdateIntentFilter() {
      IntentFilter filter = new IntentFilter();
      filter.addAction(HELLO_FILTER);
      filter.addAction(GPS_FILTER);
      filter.addAction(ACC_FILTER);
      filter.addAction(VALUE_FILTER);
      filter.addAction(GSR_FILTER);
      filter.addAction(API_RESPONSE);
      filter.addAction(TOAST_MESSAGE);
      filter.addAction(HR_EVENTS_FILTER);
      filter.addAction(ACC_EVENT_FILTER);
      filter.addAction(AROUSAL_EVENT_FILTER);
      filter.addAction(GPS_EVENT_FILTER);
      filter.addAction(GSR_EVENT_FILTER);
      filter.addAction(EMOJI_SENTIMENT_FILTER);
      filter.addAction(TEXT_SENTIMENT_FILTER);
      return filter;
  }

Realm Queries

Code Snippet 18

private void queryRealmForArousalStats() {
   try {
       realm = Realm.getDefaultInstance().getDefaultInstance();
       RealmResults<ArousalStats> realmResults = realm.where(ArousalStats.class).findAll();
       realmResults.load();
       if (!realmResults.isEmpty()) {
           for (ArousalStats realmRecords : realmResults) {
               updateArousalStats(realmRecords);
           }
       } else {
           Log.d(TAG, "No arousal stats data found in the database");
       }
   } catch (Throwable e) {
       Log.d(TAG, "Unable to get arousal stats data from the database " + e.toString());
   }
}

private void updateArousalStats(ArousalStats arousalStats) {
   ArousalSectors arousalSectors = arousalStats.getArousalSectors();
   double activated = arousalSectors.getActivated();
   double calm = arousalSectors.getCalm();
   double excited = arousalSectors.getExcited();
   double passive = arousalSectors.getPassive();
   double relaxed = arousalSectors.getRelaxed();

}

Table 5: Example Event Realm Object

Realm Object Associated Methods Method Type Description
ResHeartRate Events associated with Heart Rate getValue() String Retrieves a value associated with the event event - min, max, normal, rising, falling
getTime() long Event time
getSeverity() double How much of value change between forward/backward events with respect to the average value

Table 6: SensumSDK Realm Objects

Realm Event Objects
ResAccelerometerX
ResAccelerometerY
ResAccelerometerZ
ResGpsAccuracy
ResGpsAltitude
ResGpsBearing
ResGpsLatitude
ResGpsLongitude
ResGpsSpeed
ResGSR

Table 7: Example Statistics Object

Realm Object Associated Methods Method Type Description
HeartRateStats getAvg() Double Returns an average value
getDuration() Double Returns duration value
getMax() Double Returns max value
getMin() double Returns min value
getPercentiles() Percentiles Returns a percentile object (see Table 9)
getStd() Double Returns a standard deviation value

Table 8: SensumSDK Statistics Objects

Realm Stats Objects
AccelerometerXStats
AccelerometerYStats
AccelerometerZStats
GpsAccuracyStats
GpsAltitudeStats
GpsBearingStats
GpsLatitudeStats
GpsLongitudeStats
GpsSpeedStats
GsrStats

Table 9: SensumSDK Percentiles Object

Object Associated Methods Type Description
Percentiles get10() double Returns 10th percentile value
get50() double Returns 50th percentile value
get90() double Returns 90th percentile value

Table 10: ArousalStats Realm Object

Realm Stats Object Associated Methods Type Description
ArousalStats getValue() double Returns an activation value
getDominant() String Label of the dominant classification category
getSectors() ArousalSectors Returns the sectors associated with the arousal stats object (Table 12)

Table 11: EngagementStats Realm Object

Realm Stats Object Associated Methods Type Description
EngagementStats getValue() double Returns an activation value
getDominant() String Label of the dominant classification category
getSectors() EngagementSectors Returns the sectors associated with the arousal stats object (Table 12)

Table 12: ArousalSectors and EngagmentSectors Realm Objects

Object Associated Methods Type Description
ArousalSectors and EngagmentSectors getExcited() double Returns a value associated with excitement
getActivated() double Returns a value associated with activity
getCalm() double Returns a value associated with calmness
getPassive() double Returns a value associated with passiveness
getRelaxed() double Returns a value associated with relaxation

Table 13: Sentiment Filter Data

Object Type Description
EMOTIONALITY double Returns a value associated with emotionality
POSITIVITY double Returns a value associated with positivity
NEGATIVITY double Returns a value associated with negativity

Google Sign-In

Code Snippet 19

compile 'com.google.android.gms:play-services-auth:+'

Code Snippet 20

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
       .requestEmail()
       .requestProfile()
       .requestIdToken(googleWebClientId)
       .requestServerAuthCode(googleWebClientId)
       .requestId()
       .build();

googleApiClient = new GoogleApiClient.Builder(this)
       .enableAutoManage(this, this )
       .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
       .build();

Code Snippet 21

Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(googleApiClient);
this.startActivityForResult(signInIntent, RC_SIGN_IN);

Bundle Parameters

Parameter Type Description
apiBaseUrl String This is the base url for the API, currently this is http://api.sensum.co/v0
apiKey String This is the API Key that will be required to access the SensumAPI(For trial usage use PublicDemoKeyForDocumentation)
identityPoolId String The CognitoIdentityPoolId required to successfully authenticate with the SensumAPI. We will provide you with this.
googleIdToken String This is the google id token returned when successfully logged in with a valid Google account
googleWebClientId                                                            String This is the web client id that was created when you set up sign-in with Google. It can be found in the Credentials page under 'APIs and Service’ in the Google Cloud Platform page

Code Snippet 22

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
   super.onActivityResult(requestCode, resultCode, data);
   if (requestCode == RC_SIGN_IN) {
       GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
       GoogleSignInAccount acct = result.getSignInAccount();
       String googleIdToken = acct.getIdToken();
       Bundle bundle = new Bundle();
       bundle.putString(API_BASEURL, apiBaseUrl);
       bundle.putString(API_KEY, apiKey);
       bundle.putString(IDENTITY_POOL_ID, identityPoolId);
       bundle.putString(GOOGLE_ID_TOKEN, googleIdToken);
       bundle.putString(GOOGLE_WEB_CLIENT_ID, googleWebClientId);
       sendToService(bundle, GOOGLE_LOGIN);
   }
}

Gradle Dependencies

Code Snippet 23

compile 'com.amazonaws:aws-android-sdk-core:2.4.+'
compile 'com.amazonaws:aws-android-sdk-s3:2.4.+'
compile 'com.amazonaws:aws-android-sdk-cognito:2.4.+'
compile 'com.amazonaws:aws-android-sdk-ddb:2.4.+'
compile 'com.amazonaws:aws-android-sdk-cognitoidentityprovider:2.4.+'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-moshi:2.1.0'
compile 'com.squareup.moshi:moshi:1.2.0'
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
compile 'com.google.code.gson:gson:2.8.0'
compile 'com.google.guava:guava:19.0'

Tutorial - iOS

Getting Started

The SensumKit framework is only compatible with Swift 3 and above. We strongly recommend using Xcode version 8 and above. We work on Xcode 8.3.3 at time of our first public framework release.

Create a project

Figure 1 - Project Creation in Xcode

Figure 1 - Project Creation in Xcode


Figure 2 - Project template selection in Xcode

Figure 2 - Project template selection in Xcode


Figure 3 - Project options in Xcode

Figure 3 - Project options in Xcode


Figure 4 - Overview of Xcode Environment

Figure 4 - Overview of Xcode Environment


Figure 5 - Overview of Project Navigator (top left-hand-side of Figure 4), Xcode project file selected

Figure 5 - Overview of Project Navigator (top left-hand-side of Figure 4), Xcode project file selected


Installing the SensumKit framework

Figure 6 - Accessing *Embedded Binaries* within *General* tab of the Xcode project file

Figure 6 - Accessing Embedded Binaries within General tab of the Xcode project file


Figure 7 - SensumKit.framework

Figure 7 - SensumKit.framework


Figure 8 - Import SensumKit.framework

Figure 8 - Import SensumKit.framework


Figure 9 - Embedded Binaries import dialogue box

Figure 9 - Embedded Binaries import dialogue box


Figure 10 - SensumKit.framework imported into Embedded Libraries

Figure 10 - SensumKit.framework imported into Embedded Libraries


Figure 11 - SensumKit.framework as a Linked Framework and Library

Figure 11 - SensumKit.framework as a Linked Framework and Library

Carthage and Dependencies

Figure 12 - Xcode error message due to missing dependencies

Figure 12 - Xcode error message due to missing dependencies


Process

Figure 13 - Dragging Cartfile from source

Figure 13 - Dragging Cartfile from source


Figure 14 - Dragging Cartfile to destination within Xcode

Figure 14 - Dragging Cartfile to destination within Xcode


Figure 15 - Cartfile import dialogue box

Figure 15 - Cartfile import dialogue box


Figure 16 - Overview of Project Navigator on successful import of Cartfile

Figure 16 - Overview of Project Navigator on successful import of Cartfile


Figure 17 - Updating Carthage via Terminal

Figure 17 - Updating Carthage via Terminal


Figure 18 - Updating Carthage via Terminal (detailed output displayed )

Figure 18 - Updating Carthage via Terminal (detailed output displayed )


Code Snippet 1

#If you're not using brew don't run this
brew upgrade carthage
#cd to your project (yours may be named differently)
cd <Root Project Directory>
#Update brings in all new changes
carthage update

Figure 19 - Linked Frameworks and Libraries section, within General tab of the Xcode project file

Figure 19 - Linked Frameworks and Libraries section, within General tab of the Xcode project file


Figure 20 - Selecting frameworks/libraries to add to the Xcode project

Figure 20 - Selecting frameworks/libraries to add to the Xcode project


Figure 21 - Navigating to Carthage iOS frameworks

Figure 21 - Navigating to Carthage iOS frameworks


Code Snippet 2

AWSCognitoIdentityProvider.framework
AWSCore.framework
Realm.framework
RealmSwift.framework
CryptoSwift.framework

Figure 22 - Overview of successfully linked frameworks within the *Linked Frameworks and Libraries*

Figure 22 - Overview of successfully linked frameworks within the Linked Frameworks and Libraries


Create a run script

Figure 23 - Build Phases section of the Xcode project file

Figure 23 - Build Phases section of the Xcode project file


Figure 24 - Adding a New Script Run Phase

Figure 24 - Adding a New Script Run Phase


Code Snippet 3

/usr/local/bin/carthage copy-frameworks

Figure 25 - View of successfully added Run Script

Figure 25 - View of successfully added Run Script


Code Snippet 4 - Adding input files to the Run Script

$(SRCROOT)/Carthage/Build/iOS/Realm.framework
$(SRCROOT)/Carthage/Build/iOS/RealmSwift.framework
$(SRCROOT)/Carthage/Build/iOS/AWSCore.framework
$(SRCROOT)/Carthage/Build/iOS/AWSCognitoIdentityProvider.framework
$(SRCROOT)/Carthage/Build/iOS/CryptoSwift.framework

Figure 26 - Overview of updated Input Files section

Figure 26 - Overview of updated Input Files section


Code Snippet 5 - Adding output files to the Run Script

$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/Realm.framework
$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/RealmSwift.framework
$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/AWSCore.framework
$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/AWSCognitoIdentityProvider.framework
$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/CryptoSwift.framework

Figure 27 - Overview of updated *Output Files* section

Figure 27 - Overview of updated Output Files section


Figure 28 - Xcode ‘Run’ button

Figure 28 - Xcode ‘Run’ button


Code Snippet 6 - Importing the SensumKit into your own project

import SensumKit

Using CocoaPods (for Google Sign-In)

Code Snippet 7 - Installing CocoaPods

sudo gem install cocoapods

Figure 29 - CocoaPods GUI

Figure 29 - CocoaPods GUI


Figure 30 - Creating a new Podfile from an Xcode Project

Figure 30 - Creating a new Podfile from an Xcode Project


Figure 31 - Selecting the Xcode Project

Figure 31 - Selecting the Xcode Project file


Figure 32 - Overview of newly created Podfile for selected Xcode Project

Figure 32 - Overview of newly created Podfile for selected Xcode Project


Code Snippet 8 - Adding a pod to the Podfile

pod 'GoogleSignIn', '4.0.1'

Figure 33 - Installing specified pods

Figure 33 - Installing specified pods


Figure 34 - CocoaPods fetching necessary pods

Figure 34 - CocoaPods fetching necessary pods


Figure 35 - Overview of Xcode Project folder

Figure 35 - Overview of Xcode Project folder


Figure 36 - Utilising the SensumKit within an Xcode project

Figure 36 - Utilising the SensumKit within an Xcode project


Starting the SensumSDK

Code Snippet 9

import UIKit
import SensumKit

class TabBarController: UITabBarController {
    var sensumSDK : SensumSDKManager?

    override func viewDidLoad() {
           super.viewDidLoad()
           // Do any additional setup after loading the view, typically from a nib.
           sensumSDK = SensumSDKManager(
               requestEngineInternalInSeconds: 30,
               apiKey: "PublicDemoKeyForDocumentation",
               host: "api.sensum.co",
               stage: "v0")
        startEverythingUpdating()
       }

    func startEverythingUpdating() {
        sensumSDK?.accelerometer.startUpdating()
        sensumSDK?.location.startUpdating()
        sensumSDK?.bluetooth.startUpdating()
        sensumSDK?.tag.startUpdating()
    }
}

Getting Accelerometer and GPS Data from the SensumSDK

Code Snippet 10

import CoreMotion

Code Snippet 11

extension AccelerometerViewController: AccelerometerListener {
    func accelerationUpdated(newAcceleration: CMAcceleration, dateTime: Date) {
        DispatchQueue.main.async {
            print(newAcceleration)
        }
    }
}

Code Snippet 12

sdkManager?.accelerometer.assignListener(self)

CMAcceleration(x: 0.00097714154981076717, y: -0.001684999093413353, z: -0.010779784061014652)

Code Snippet 13

import CoreLocation

Code Snippet 14

extension GPSViewController: LocationListener {
    func locationUpdated(newLocation: CLLocation) {
        DispatchQueue.main.async {
            print(newLocation)
        }
    }
}

Code Snippet 15

sdkManager?.location.assignListener(self)

<+54.58727634,-5.90740191> +/- 50.00m (speed 0.00 mps / course -1.00) @ 01/09/2017, 10:51:08 British Summer Time

Scanning for BLE devices

Note: This document is regularly updated with new devices. Please contact us for integration details. GSR data is only accessible from Shimmer devices at present.

Code Snippet 16

import CoreBluetooth

Code Snippet 17

extension BluetoothTableViewController: BluetoothListener {

    public func deviceDiscovered() {
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    }

    public func bpmUpdated(newBpm: Int, dateTime: Date) {}
    public func deviceConnectionSuccess() {}
    public func deviceConnectionFailure() {}
    public func deviceDisconnected(disconnectedPeripheral: CBPeripheral) {}
}

Code Snippet 18

sdkManager?.bluetooth.assignListener(self)

Code Snippet 19

import UIKit
import CoreBluetooth

class BluetoothPeripheralTableViewCell: UITableViewCell {

    var peripheral: CBPeripheral? {
        didSet {
            if let newValue = peripheral {
                self.textLabel?.text = newValue.name
            }
        }
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        // Configure the view for the selected state
    }
}

Code Snippet 20

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // the identifier is what was set in your .storyboard in the attributes inspector
        let bleCell = self.tableView.dequeueReusableCell(withIdentifier: "bleCell", for: indexPath) as! BluetoothPeripheralTableViewCell
        if let dictValue = sdkManager?.bluetooth.getDeviceList()[indexPath.item]?["peripheral"] {
            let peripheralToAdd = dictValue as! CBPeripheral
            bleCell.peripheral = peripheralToAdd
        }
        return bleCell
    }

Code Snippet 21 swift func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return (sdkManager?.bluetooth.getDeviceList().count)! }

Connecting to a BLE Device

Code Snippet 22

Scanning for bluetooth devices
Connecting to device: MIO GLOBAL-LINK
Stopping device scan
Device connected.
Device Connected
Discovered service: Heart Rate
Discovered service: Battery

Listening for Updates from the SensumAPI

Code Snippet 23

 func startEverythingRecording() {
        sdkManager?.accelerometer.startRecording()
        sdkManager?.location.startRecording()
        sdkManager?.bluetooth.startRecording()
        sdkManager?.tag.startRecording()
        sdkManager?.accelerometer.startSendingToAPI()
        sdkManager?.location.startSendingToAPI()
        sdkManager?.bluetooth.startSendingToAPI()
        sdkManager?.tag.startSendingToAPI()
    }
extension RecordingMasterViewController: APIListener {

    func realmResponseSaved() {
        // saved to Realm, lets query it and print the values
        if let realmResponse = try? Realm().objects(Response.self).last {
            print(realmResponse)
        }
    }

    func realmSentimentResponseSaved() {
        if let realmSentiment = try? Realm().objects(SentimentResponse.self).last {
            print(realmSentiment)
        }
    }

    func arousalReceived(arousalScore: Double) {
        print("arousalScore \(arousalScore)")
    }

    func apiRequestFailure(message: String, statusCode: Int?) {
        print("Failed to send to SensumAPI \(message) \(statusCode)")
    }

    func apiRequestSuccessful() {
        print("api request successful")
    }

}
Optional(SentimentResponse {
    textSentiment = Emotion {
        emotionality = 0;
        negativity = 0;
        positivity = 0;
    };
    emojiSentiment = Emotion {
        emotionality = 0.4236068641;
        negativity = 0.0936431989;
        positivity = 0.6575529733;
    };
})

Third Party Authentication

Google:

IMPORTANT after creating your Configuration file, please ensure you contact us at: bertha@sensum.co, including your CLIENT_ID as selected below from the Configuration file generated by the Google Sign-In service (see Figure 37). The format of this ID is typically a combination of numbers and characters followed by apps.googleusercontent.com. Upon confirmation that the CLIENT_ID has been saved, you will be able to successfully authenticate users in your application.

Figure 37 - Configuration File plist generated from Google Sign In guide.

Figure 37 - Configuration File plist generated from Google Sign In guide.


Code Snippet 26

func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
    if error != nil {
        print(error ?? "google sign in error")
    } else {
        signInStatusLabel.text = "Signed in with Google"
        sensumSDK?.authentication.federatedSignIn(provider: "accounts.google.com",    
            authenticationToken: user.authentication.idToken)
    }
}

Summary Guide

API Control

Setting Server Request Rate

iOS

Android

When using the sendToService method ensure that you send the integer parameters DATA_RATE_SAMPLE and DATA_RATE_SEND as part of your bundle.

Getting the Server Request Rate

iOS

Android

Listen for API events

iOS

Android

Use a Broadcast Receiver

Table 1

Action Description IntentExtras
BLE_DEVICE_FILTER Filters for BLE devices ArrayList
VALUE_FILTER Filters for heart rate value String
GPS_FILTER Filters for GPS values Bundle
ACC_FILTER Filters for acceleration values Bundle
DEVICE_DISCONNECTED Filters for a device disconnected value null
API_RESPONSE Filters for responses from the API String
TOAST_MESSAGE Filters for messages from the Service String
CONNECTION_FILTER Filters for connection BLE messages String
BLUETOOTH_CONNECTION_FILTER Filters for bluetooth connection messages String
BLUETOOTH_DEVICE_FILTER Filters for bluetooth devices ArrayList
GSR_FILTER Filters for GSR values String
ACC_FAILED_REGISTERED Filters for acceleration failure from unsupported devices null
HELLO_FILTER Filters for hello message String

Setting up the Broadcast Receiver

Code Snippet 1

    private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            switch (action){
                case HELLO_FILTER:
                    Toast.makeText(MainActivity.this, intent.getStringExtra(EXTRA_DATA), Toast.LENGTH_LONG).show();
                    break;
                case GPS_FILTER:
                    Bundle gpsBundle = intent.getBundleExtra(EXTRA_DATA);
                    break;
                case ACC_FILTER:
                    Bundle accBundle = intent.getBundleExtra(EXTRA_DATA);
                    isAcc = true;
                    break;
                case VALUE_FILTER:
                    String hrValue = intent.getStringExtra(EXTRA_DATA);
                    break;
                case GSR_FILTER:
                    String gsrValue = intent.getStringExtra(EXTRA_DATA);
                    break;
                case API_RESPONSE:
                    String apiResponse = intent.getStringExtra(EXTRA_DATA);
                    break;
                case TOAST_MESSAGE:
                    String toastMessage = intent.getStringExtra(EXTRA_DATA);
                    break;
            }
        }
    };

Code Snippet 5

 @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(mMessageReceiver, getUpdateIntentFilter());
    }

Code Snippet 3

  private IntentFilter getUpdateIntentFilter() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(HELLO_FILTER);
        filter.addAction(GPS_FILTER);
        filter.addAction(ACC_FILTER);
        filter.addAction(VALUE_FILTER);
        filter.addAction(GSR_FILTER);
        filter.addAction(API_RESPONSE);
        filter.addAction(TOAST_MESSAGE);
        return filter;
    }

Code Snippet 4

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mIsBound){
            unbindService(mConnection);
            mIsBound = false;
            unregisterReceiver(mMessageReceiver);
        }
    }

Accelerometer Control

Start Updating

iOS

Android

Use the sendToService method the the boolean ACCELERATION_CAPTURE = true with the constant START_CAPTURE to the background service.

Stop Updating

iOS

Android

Use the sendToService method the the boolean ACCELERATION_CAPTURE = true with the constant CANCEL_CAPTURE to the background service.

Start Recording

iOS

Android

Use the sendToService method the the boolean ACCELERATION_CAPTURE = true with the constant START_CAPTURE to the background service.

Stop Recording

iOS

Android

Use the sendToService method the the boolean ACCELERATION_CAPTURE = true with the constant CANCEL_CAPTURE to the background service.

Start SendingTo API

iOS

Android

Create a Broadcast Receiver, setting it up to handle Accelerometer data using the ACC_Filter intent If not done already.

Use the sendToService method the the boolean ACCELERATION_CAPTURE = true with the constant START_CAPTURE to the background service.

Stop Sending to the API

iOS

Android

Use the sendToService method the the boolean ACCELERATION_CAPTURE = true with the constant CANCEL_CAPTURE to the background service.

Check Update status

iOS

Android

Check Recording status

iOS

Android

Check API Sending status

iOS

Android

Assign Listener

iOS

Android

Set Read Frequency

iOS

Android

Location Control

Start Updating

iOS

Android

Use the sendToService method the the boolean GPS_CAPTURE = true with the constant START_CAPTURE to the background service.

Stop Updating

iOS

Android

Use the sendToService method the the boolean GPS_CAPTURE = true with the constant CANCEL_CAPTURE to the background service.

Start Recording

iOS

Android

Use the sendToService method the the boolean GPS_CAPTURE = true with the constant START_CAPTURE to the background service.

Stop Recording

iOS

Android

Use the sendToService method the the boolean GPS_CAPTURE = true with the constant CANCEL_CAPTURE to the background service.

Start Sending To API

iOS

Android

Create a Broadcast Receiver, setting it up to handle location data using the GPS_Filter intent If not done already.

Use the sendToService method the the boolean GPS_CAPTURE = true with the constant START_CAPTURE to the background service.

Stop Sending to the API

iOS

Android

Use the sendToService method the the boolean GPS_CAPTURE = true with the constant CANCEL_CAPTURE to the background service.

Check Update status

iOS

Android

Check Recording status

iOS

Android

Check API Sending status

iOS

Android

Assign Listener

iOS

Android

Set Read Frequency

iOS

Android

Tag Control

Start Updating

iOS

Android

Use the sendToService method the the boolean INPUT_CAPTURE = true with the constant START_CAPTURE to the background service.

Stop Updating

iOS

Android

Use the sendToService method the the boolean INPUT_CAPTURE = true with the constant CANCEL_CAPTURE to the background service.

Start Recording

iOS

Android

Use the sendToService method the the boolean INPUT_CAPTURE = true with the constant START_CAPTURE to the background service.

Stop Recording

iOS

Android

Use the sendToService method the the boolean INPUT_CAPTURE = true with the constant CANCEL_CAPTURE to the background service.

Start Sending To API

iOS

Android

Create a Broadcast Receiver, setting it up to handle tag data using the TOAST_MESSAGE intent If not done already.

Use the sendToService method the the boolean INPUT_CAPTURE = true with the constant START_CAPTURE to the background service.

Stop Sending to the API

iOS

Android

Use the sendToService method the the boolean INPUT_CAPTURE = true with the constant CANCEL_CAPTURE to the background service.

Check Update status

iOS

Android

Check Recording status

iOS

Android

Check API Sending status

iOS

Android

Assign Listener

iOS

Android

Create Tag

iOS

Android

Bluetooth Control

Start Updating

iOS

Android

Use the sendToService method the the boolean HR_CAPTURE = true with the constant START_CAPTURE to the background service.

Stop Updating

iOS

Android

Use the sendToService method the the boolean HR_CAPTURE = true with the constant CANCEL_CAPTURE to the background service.

Start Recording

iOS

Android

Use the sendToService method the the boolean HR_CAPTURE = true with the constant START_CAPTURE to the background service.

Stop Recording

iOS

Android

Use the sendToService method the the boolean HR_CAPTURE = true with the constant CANCEL_CAPTURE to the background service.

Start Sending To API

iOS

Android

Create a Broadcast Receiver, setting it up to handle bluetooth data using the BLE_DEVICE_FILTER, BLUETOOTH_CONNECTION_FILTER, BLUETOOTH_DEVICE_FILTER, DEVICE_DISCONNECTED and CONNECTION_FILTER intents if not done already.

Use the sendToService method the the boolean HR_CAPTURE = true with the constant START_CAPTURE to the background service.

Stop Sending to the API

iOS

Android

Use the sendToService method the the boolean HR_CAPTURE = true with the constant CANCEL_CAPTURE to the background service.

Check Update status

iOS

Android

Check Recording status

iOS

Android

Check API Sending status

iOS

Android

Assign Listener

iOS

Android

Scan for Devices

iOS

Android

Connect to Device

iOS

Android

Clear List of Discovered Devices

iOS

Android

There is no equivalent function in the Android SDK. To perform this function perform another scan by using the sendToService method with the constant BLE_SCAN or BLUETOOTH_SCAN, depending on if the device is compatible with Bluetooth LE or standard, to send the command to the background service.

### Disconnect From Device

iOS

Android