Integrate your Service

The reelyActive platform is designed to forward a real-time stream of events to complementary services. First we'll define the event data that your service will need to ingest, then we'll describe the means by which your service can ingest the data, and, finally, we'll suggest how to store the data.

Event data

There's just one type of data, an event, which is represented as JSON. An event is the consequence of an interaction between a radio-identifiable device and receiver infrastructure.

Types of event

There are four types of event, as illustrated in the animation below.

Basic event structure

An event always has the following basic structure:

{
  "event": "appearance",
  "time": 1420075425678,
  "deviceId": "fee150bada55",
  "receiverId": "001bc50940810000",
  "rssi": 150,
  "tiraid": { /* Included for legacy purposes only */ }
}

The individual properties are each presented in their own tab below.

An event can take one of four types, each described in the table below:

Event type Description
"appearance" Indicates that the device is detected for the first time at a point of interest.
Typically, this means that the device has come within range of a radio receiver.
"keep-alive" Indicates that the device continues to be detected and has not displaced.
The keep-alive is sent periodically (typically every few seconds) to indicate that the device remains at the same point of interest.
"displacement" Indicates that the device has moved to a different point of interest.
Specifically, it indicates that the device is detected at a stronger RSSI by a different radio receiver than previously.
"disappearance" Indicates that the device is no longer detected at any point of interest.
Typically, this means that the device has gone out of range of all radio receivers.

The time of an event is expressed as a number. It is the number of milliseconds since the Unix epoch (January 1st, 1970 UTC).

1420075425678

The above is equivalent to 01 Jan 2015 01:23:45.678 GMT.

The deviceId of an event is expressed as a hexadecimal string. It represents the (normally) unique identifier of the device to which the event corresponds. In the case of Bluetooth Low Energy devices, this is the MAC address (which may be public or random, the distinction being made in the tiraid). The deviceId does NOT include dashes or colons.

"fee150bada55"

The above is equivalent to the 48-bit identifier fe:e1:50:ba:da:55 (human-friendly representation).

The receiverId of an event is expressed as a hexadecimal string. It represents the unique identifier of the radio receiver which detects the device with the strongest signal strength in relation to the corresponding event. In the case of reelyActive reelceivers, this is the EUI-64 identifier.

"001bc50940810000"

The above is equivalent to the 48-bit identifier 00-1b-c5-09-40-81-00-00 (human-friendly representation).

The rssi of an event is expressed as a number. It represents the received signal strength as a unitless number, with greater values corresponding to greater received signal strength. In the case of reelyActive reelceivers, each unit represents 0.5dBm and the offset is constant for a given model, allowing for direct comparison.

150

The above is a unitless value which could be converted to an absolute value if a calibration is performed.

The tiraid of an event is included for legacy purposes (its pertinent properties are already included in the flattened event), and consists of three components (ti-ra-id), each described below.

timestamp

ISO 8601 timestamp, represented as a String. Includes date and time of day in UTC, with millisecond precision. Example:

2016-01-01T01:23:45.678Z

The timestamp represents the platform's interpretation of the time of the device's radio transmission which triggered the given event.

radioDecodings

Array of radioDecoding objects ordered from strongest [0] to weakest [n-1]. Each radioDecoding includes the identifier of the radio receiver, as well as the Received Signal Strength Indication, or rssi. Example:

{
  "identifier": {
    "type": "EUI-64",
    "value": "001bc50940810000"
  }
  "rssi": 169
}

The first radioDecoding in the array, tiraid.radioDecodings[0], represents the radio receiver closest to the device, in other words, the device's location.

identifier

The identifier of the radio transmitter device, which includes the entire payload of its transmission. Example:

{
  "type": "ADVA-48",
  "value": "112233445566",
  "advHeader": {
    "type": "SCAN_REQ",
    "length": 12,
    "txAdd": "random",
    "rxAdd": "public"
  },
  "advData": {}
}

The identifier value, tiraid.identifier.value, is the means by which the system distinguishes devices and thereby interprets events.


 

Contextual event structure

An event may include contextual metadata about both the device and the receiver. In this case several properties are added to the basic structure, as follows:

{
  "event": "appearance",
  "time": 1420075425678,
  "deviceId": "fee150bada55",
  "deviceAssociationIds": [],
  "deviceUrl": "http://myjson.info/stories/test",
  "deviceTags": [ 'test' ],
  "receiverId": "001bc50940810000",
  "receiverUrl": "http://sniffypedia.org/Product/reelyActive_RA-R436/",
  "receiverTags": [ 'test' ],
  "receiverDirectory": "test",
  "rssi": 150,
  "tiraid": { /* Included for legacy purposes only */ }
}

The additional properties are each presented in their own tab below.

The deviceAssociationIds of an event is expressed as an array of hexadecimal strings. Each hexadecimal string represents a complementary device identifier included in its payload(s). In the case of Bluetooth Low Energy devices, this can include 16-bit and 128-bit UUIDs, 16-bit company codes, as well as 160-bit concatenated iBeacon identifiers, among others. These identifiers do NOT include dashes or colons.

[ '004c', 'dab59c4fa4d6ee286bfe8e0000bbc2bb12345678' ]

The above is equivalent to an iBeacon with UUID dab59c4f-a4d6-ee28-6bfe-8e0000bbc2bb, Major: 1234 and Minor: 5678. It includes Apple's company code: 0x004c.

The deviceUrl of an event is expressed as a string. It represents a Uniform Resource Locator (URL) associated with the device, linking it to metadata.

"http://myjson.info/stories/test"

The above is a link to http://myjson.info/stories/test which contains metadata as JSON-LD within a human-friendly HTML representation.

The deviceTags of an event is expressed as an array of strings. Each string represents a classifier for the device.

[ 'test' ]

The above indicates that the device is part of a test class.

The receiverUrl of an event is expressed as a string. It represents a Uniform Resource Locator (URL) associated with the receiver, linking it to metadata.

"http://sniffypedia.org/Product/reelyActive_RA-R436/"

The above is a link to http://sniffypedia.org/Product/reelyActive_RA-R436/ which contains metadata as JSON-LD within a human-friendly HTML representation.

The receiverTags of an event is expressed as an array of strings. Each string represents a classifier for the receiver.

[ 'test' ]

The above indicates that the receiver is part of a test class.

The receiverDirectory of an event is expressed as a string. It represents a hierarchical directory structure which specifies the semantic location of one or more points of interest. The levels of hierarchy are colon-separated.

"test"

The above indicates that the receiver is part of the test directory.

"test:subarea"

The above indicates that the receiver is part of the subarea of the test directory.




Ingesting data

Your service can ingest data as HTTP POSTs, over websockets, or using a custom service. Each option is presented in its own tab below.

In this case, the reelyActive platform will POST events to your API.

Integration testbench

Paste the following into a file called post-test.js:

var barnowl = require('barnowl');
var barnacles = require('barnacles');
var middleware = new barnowl( { n: 2 } );
var notifications = new barnacles();
 
middleware.bind( { protocol: "test", path: "default" } );
notifications.bind( { barnowl: middleware } );

notifications.addService({
    service: "barnaclesrest",
    hostname: "localhost",
    port: 3010
});

Then from the command line, run the following, in order:
npm install barnowl
npm install barnacles
node post-test

Your service should now expect events to be POSTed to http://localhost:3010/events

In this case, your service will connect to the websocket at a specific URL.

Test your service with a live feed via http://www.hyperlocalcontext.com/reelyactive and you should receive the following:

REAL-TIME EVENT STREAM
Transmitter ID Event Receiver ID RSSI Timestamp
{{event.tiraid.identifier.value}} {{event.type}} {{event.tiraid.radioDecodings[0].identifier.value}} {{event.tiraid.radioDecodings[0].rssi}} {{event.tiraid.timestamp}}

In this case, you'll write a custom service that we'll integrate into our code base. This is reserved for cases where HTTP POST and websockets are inappropriate.

Visit the barnacles/lib/services directory on our GitHub for code examples of the existing custom services.




Storing data

If your service will store event data to a database, we suggest (at least) the following properties in flattened format:

{
  "event": "appearance",
  "time": 1451611425678,
  "deviceId": "112233445566",
  "receiverId": "001bc50940810000",
  "rssi": 169
}

The presented values are taken from the tiraid example above. We recommend using the toFlattened() method of our reelib package to flatten the event data in a standard format. Install and reference the package, respectively, as follows:
npm install reelib

var reelib = require('reelib');

var event; // See Ingesting Data section

var flattenedEvent = reelib.event.toFlattened(event);

console.log(flattenedEvent);



What's next?

Contact us if you feel your service should be integrated with our Pareto platform.

Integrate your Product Integrate your Mobile App Return to diyActive