Working with telemetry data

NDU provides a rich set of features related to telemetry data:

This guide provides an overview of the features listed above and some useful links to get more details.

image

Device telemetry upload API

NDU provides an API to upload timeseries key-value data. Flexibility and simplicity of key-value format allow easy and seamless integration with almost any IoT device on the market. Telemetry upload API is specific for each supported network protocol. You can review API and examples in corresponding reference page:

Telemetry Service

Telemetry Service is responsible for persisting timeseries data to internal data storage; provides server-side API to query and subscribe for data updates.

Internal data storage

NDU uses either Cassandra NoSQL database or SQL database to store all data.

A device that is sending data to the server will receive confirmation about data delivery as soon as data is stored in DB. Modern MQTT clients allow temporary local storage of undelivered data. Thus, even if one of the NDU nodes goes down, the device will not lose the data and will be able to push it to other servers.

Server side applications are also able to publish telemetry valued for different entities and entity types.

Although you can query the database directly, NDU provides set of RESTful and Websocket API that simplify this process and apply certain security policies:

Data Query API

Telemetry Service provides following REST API to fetch entity data:

image

Timeseries data keys API

You can fetch list of all data keys for particular entity type and entity id using GET request to the following URL

1
https://smartapp.netcad.com/api/plugins/telemetry/{entityType}/{entityId}/keys/timeseries
resources/get-telemetry-keys.sh
1
2
3
curl -v -X GET http://smartapp.netcad.com/api/plugins/telemetry/DEVICE/ac8e6020-ae99-11e6-b9bd-2b15845ada4e/keys/timeseries \
--header "Content-Type:application/json" \
--header "X-Authorization: $JWT_TOKEN"

Supported entity types are: TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, ENTITY_VIEW

Timeseries data values API

You can fetch list of latest values for particular entity type and entity id using GET request to the following URL

1
https://smartapp.netcad.com/api/plugins/telemetry/{entityType}/{entityId}/values/timeseries?keys=key1,key2,key3
resources/get-latest-telemetry-values.sh
1
2
3
curl -v -X GET http://smartapp.netcad.com/api/plugins/telemetry/DEVICE/ac8e6020-ae99-11e6-b9bd-2b15845ada4e/values/timeseries?keys=gas,temperature \
--header "Content-Type:application/json" \
--header "X-Authorization: $JWT_TOKEN"
resources/get-latest-telemetry-values-result.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "gas": [
    {
      "ts": 1479735870786,
      "value": "1"
    }
  ],
  "temperature": [
    {
      "ts": 1479735870786,
      "value": "3"
    }
  ]
}

Supported entity types are: TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, ENTITY_VIEW

You can also fetch list of historical values for particular entity type and entity id using GET request to the following URL

1
https://smartapp.netcad.com/api/plugins/telemetry/{entityType}/{entityId}/values/timeseries?keys=key1,key2,key3&startTs=1479735870785&endTs=1479735871858&interval=60000&limit=100&agg=AVG

The supported parameters are described below:

NDU will use startTs, endTs and interval to identify aggregation partitions or sub-queries and execute asynchronous queries to DB that leverage built-in aggregation functions.

resources/get-telemetry-values.sh
1
2
3
curl -v -X GET "http://smartapp.netcad.com/api/plugins/telemetry/DEVICE/ac8e6020-ae99-11e6-b9bd-2b15845ada4e/values/timeseries?keys=gas,temperature&startTs=1479735870785&endTs=1479735871858&interval=60000&limit=100&agg=AVG" \
--header "Content-Type:application/json" \
--header "X-Authorization: $JWT_TOKEN"
resources/get-telemetry-values-result.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
  "gas": [
    {
      "ts": 1479735870786,
      "value": "1"
    },
    {
      "ts": 1479735871857,
      "value": "2"
    }
  ],
  "temperature": [
    {
      "ts": 1479735870786,
      "value": "3"
    },
    {
      "ts": 1479735871857,
      "value": "4"
    }
  ]
}

Supported entity types are: TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, ENTITY_VIEW

Websocket API

Websockets are actively used by You can open a websocket connection to a telemetry service using the following URL

1
ws(s)://smartapp.netcad.com/api/ws/plugins/telemetry?token=$JWT_TOKEN
Example

Change values of the following variables :

resources/web-socket.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<!DOCTYPE HTML>
<html>
<head>

    <script type="text/javascript">
        function WebSocketAPIExample() {
            var token = "YOUR_JWT_TOKEN";
            var entityId = "YOUR_DEVICE_ID";
            var webSocket = new WebSocket("ws(s)://smartapp.netcad.com/api/ws/plugins/telemetry?token=" + token);

            if (entityId === "YOUR_DEVICE_ID") {
                alert("Invalid device id!");
                webSocket.close();
            }

            if (token === "YOUR_JWT_TOKEN") {
                alert("Invalid JWT token!");
                webSocket.close();
            }

            webSocket.onopen = function () {
                var object = {
                    tsSubCmds: [
                        {
                            entityType: "DEVICE",
                            entityId: entityId,
                            scope: "LATEST_TELEMETRY",
                            cmdId: 10
                        }
                    ],
                    historyCmds: [],
                    attrSubCmds: []
                };
                var data = JSON.stringify(object);
                webSocket.send(data);
                alert("Message is sent: " + data);
            };

            webSocket.onmessage = function (event) {
                var received_msg = event.data;
                alert("Message is received: " + received_msg);
            };

            webSocket.onclose = function (event) {
                alert("Connection is closed!");
            };
        }
    </script>

</head>
<body>

<div id="sse">
    <a href="javascript:WebSocketAPIExample()">Run WebSocket</a>
</div>

</body>
</html>