Skip to content

Monitoring Location Engine data

After completing the setup procedure all that is left is to get the data collected by Gateways. This is possible via WebSocket and MQTT streams.

WebSocket

In order to facilitate realtime analytics Location Engine provides a stream of Presence data over a secure WebSocket. This data can come from either a single Gateway or from all Gateways assigned to a Location (Venue).

wss://ovs.kontakt.io:9090/stream?apiKey=yourSuperSecretAPIKey

This WebSocket uses the STOMP 1.2 protocol. Once you create a STOMP client for the WebSocket, you can use it to connect to Kontakt.io Cloud. In order to do that the connection has to be started with a custom api-key header with a value being your actual API key. Then you can subscribe to new messages by providing one of these paths:

  • /presence/stream/:sourceId – for data from a single Gateway
  • /stream/:venueId/presence – for data from all Gateways assigned to a Location (Venue)

Additionally the Location Engine provide WebSocket streams of Telemetry data from sensor-equipped beacons scanned by Gateways. They are available through these paths:

  • /stream/:uniqueId/health - for live information about battery life of a given beacon
  • /stream/:uniqueId/accelerometer - for raw accelerometer data and information about an event detection
  • /stream/:uniqueId/sensor - for data from other sensors available on a beacon
  • /stream/:uniqueId/button - for data about button events from button-equipped beacons

Stream content

For more information about WebSocket streams' content please refer to this document: Data streams

Sample implementation

A sample implementation of the Presence stream subscription in JavaScript might look like this:

<html>
<head>

<script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script>
</head>
<body>
    <script type="text/javascript">
    var stomp = Stomp.client('wss://ovs.kontakt.io:9090/stream?apiKey=yourSuperSecretAPIKey');

    var headers = {'api-key': 'yourSuperSecretAPIKey'};

    stomp.connect(headers, function(cb) {
        var topic = stomp.subscribe('/presence/stream/:receiverId', function(e) {
            console.log(JSON.parse(e.body));
        }, headers);
    });
    </script>
</body>
</html>

MQTT

The WebSocket is not always the best solution for gathering real-time analytics in certain use cases. That's why we also provide Location Engine data via MQTT. In order to receive information about detected devices or their Telemetry data, your MQTT client needs to connect to our server:

  • Host: ovs.kontakt.io
  • Port: 8083
  • Protocol: MQTTS (TLS 1.2)
  • User: (this value can't be empty, but you can use anything here)
  • Password: You API Key
  • Client ID: (can be random)

Available topics

Topics that you can subscribe to on our MQTT broker correspond exactly to what is available through a WebSocket:

Presence

  • /presence/stream/:sourceId – for data from a single Gateway
  • /stream/:venueId/presence – for data from all Gateways assigned to a Location (Venue)

Telemetry

  • /stream/:uniqueId/health - for live information about battery life of a given beacon
  • /stream/:uniqueId/accelerometer - for raw accelerometer data and information about an event detection
  • /stream/:uniqueId/sensor - for data from other sensors available on a beacon
  • /stream/:uniqueId/button - for data about button events from button-equipped beacons

Stream content

For more information about WebSocket streams' content please refer to this document: Data streams

Webhooks

Webhooks can be used to notify a registered URL on a 3rd party server about Location Engine events. Just like WebSocket or MQTT, they give access to real-time data collected by Gateways.

Setup

Configuring a new webhook starts with calling the POST /webhook/subscribe endpoint and providing two required parameters as an URL-encoded form:

  • url - URL where Location Engine should send data (it has to use HTTPS)
  • sourceId - Unique ID of a Gateway that should provide data

Additionally, you can provide a number of parameters that can represent headers that our servers will use when calling your webhook URL. This can be useful e.g. for authorization. These optional parameters' names should follow this pattern: headers[<yourHeadersName>]

The full HTTP call should look like this:

POST /webhook/subscribe HTTP/1.1
Accept: application/vnd.com.kontakt+json;version=10
Api-Key: yourSuperSecretAPIKey
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: ovs.kontakt.io
Connection: close
User-Agent: Paw/3.0.16 (Macintosh; OS X/10.12.3) GCDHTTPRequest
Content-Length: 130

url=https%3A%2F%2Fyour.server.com%2Fyour%endpoint&sourceId=abcde&headers%5ByourCustomHeader1%5D=valueForHeader1&headers%5ByourCustomHeader2%5D=valueForHeader1

Confirmation

When our backend receives this request it will make a POST request to the specified URL. This request will have two important headers: Type and X-Request-ID. The former's value will be SUBSCRIPTION_CONFIRMATION and the latter's an UUID generated by our server for your subscription request. It will look similarly to this:

POST /your/endpoint HTTP/1.1
type: SUBSCRIPTION_CONFIRMATION
X-Request-ID: a50ad921-652a-4051-9826-81d067a6c420
content-type: application/json
yourCustomHeader1: valueForHeader1
yourCustomHeader2: valueForHeader2
Content-Length: 0
Host: your.server.com
User-Agent: Apache-HttpClient/4.5.2 (Java/1.8.0_91)
Accept-Encoding: gzip,deflate

The webhook client has to respond with HTTP code 200 OK and a JSON-encoded body containing your managerId and requestId with value from the X-Request-ID header. It should be similar to this:

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 103
ETag: W/"67-/DMbwqz4/hmBFCNOKPV1Uw"
Date: Wed, 08 Mar 2017 12:54:08 GMT
Connection: keep-alive

{"managerId":"5d96e777-0a55-4969-8e64-496f3f943a46","requestId":"a50ad921-652a-4051-9826-81d067a6c420"}

Receiving data

If your server's confirmation response is valid, Location Engine will start sending POST requests containing JSON with Presence data every 5 seconds (future adjustments of this value are possible). Type header of these requests will be set to DATA.

You backend has to respond to each POST with HTTP code 202 Accepted. If a response is either 502 Bad Gateway, 503 Service Unavailable or 504 Gateway Timeout, the Location Engine will try to send data after 5 minutes. If it gets the same response once again, it will retry once more after another 5 minutes. If the second attempt is also unsuccessful, the webhook will be unsubscribed. Similarly with all other possible HTTP codes, although in these cases Location engine tries three times without waiting and closes the webhook if it don't get 202 Accepted.

Additional information

At a given moment a single manager can have up to 10 active webhooks. You can check what webhooks are active by calling GET /webhook endpoint.

If you want to unsubscribe from a webhook, call POST /webhook/unsubscribe and provide webhookId parameter with the ID of a webhook in the body of your request.