Kaa Documentation

Getting Started: Collecting Data from a Device

Time to complete: 10 min.

Overview

We assume that you have successfully connected your first device to Kaa, so make sure to review the Getting Started guide before proceeding here.

From this tutorial you will learn some additional concepts of the Kaa platform and discover how to:

  • collect telemetry data from a device
  • transform raw telemetry data into well-structured time series
  • use the time series auto-extraction feature
  • visualize time series data on the Kaa UI

Terms and concepts

Let us start by reviewing some new terms and concepts related to the Kaa data collection feature.

Data sample

Think of data sample as a block of data in JSON format that a client sends to the platform for data collection.

Let’s consider an example.

You have a greenhouse monitoring station that consists of temperature, humidity and light sensors, and a gateway (e.g. Arduino) that all sensors are connected to. Every minute Arduino polls all connected sensors for their current values. Then the Arduino formats sensor values into a JSON object: this is a data sample in terms of Kaa.

{
  "temperature": 25,
  "humidity": 46,
  "lux": 8600
}

Time series

Time series is a named sequence of data points. Each data point contains a timestamp and one or more named values. A set of value names and their types (numeric, string, boolean) defines a time series.

You may want different time series defined for various things. For example, a fuel level time series may only have one numeric value: level. On the other hand, a geo-location time series may have several numeric values: latitude, longitude, and in some applications altitude.

You can configure Kaa to transform data samples received from endpoints into time series for displaying them on charts, gauges, maps, etc. Kaa can use a timestamp present in a data sample or use a data sample receipt timestamp. For simplicity, in this tutorial we will use data receipt timestamps.

Also, Kaa has an Auto-extraction feature that stores each numeric top-level data sample field into a separate time-series. All auto-extracted time series have a name that follows the pattern auto~<field name> and one numeric value with the name value. So, if your endpoint sends data a sample with two fields, e.g.:

  {
    "temperature": 23,
    "humidity": 48
  }

and the auto-extraction feature is enabled (see below how to enable it), Kaa creates two time-series: auto~temperature and auto~humidity.

Let’s now send some data to Kaa and see the auto-extraction feature in action.

Playbook

We assume that you have already created an application, application version, and endpoint with a token while following the “connecting your first device” tutorial. You can reuse them or create new ones.

Start by logging into your Kaa Cloud account.

Enable the Time Series Auto-extraction

To keep things simple, at this time we will not define any configurable time series, but rather just use the auto-extraction feature. Let us make sure that it is turned on in your application. Go to the Device management -> Applications -> expand your application -> select “epts” (Kaa component that is responsible for time series processing) and enable the “Autoextract” checkbox.

Enable auto-extraction feature

With this function enabled, Kaa will automatically create a time series for each numeric field it encounters at the root of data samples your endpoints in this application will submit. You will then be able to view these time series in Kaa UI, no extra configuration required.

Go to the pre-defined endpoint dashboard and scroll to the “Device telemetry” widget. (The endpoint dashboard is available from Device management -> Devices -> select your endpoint in the list.) Now we are all set to send our first data sample to the platform.

Send data samples

You can submit telemetry data via a variety of MQTT- and HTTP-based interfaces. Let’s take a look at a couple of the simplest ones: plain HTTP and plain MQTT.

Execute the below cURL command to send one data sample with temperature and humidity fields. You can run this command several times to get multiple data points shown as a line in the Kaa UI.

Remember to replace <app-version-name> and <endpoint-token> with your application version name and the endpoint token respectively.

curl --location --request POST 'https://connect.cloud.kaaiot.com:443/kp1/<app-version-name>/dcx/<endpoint-token>/json' \
--data-raw '{
  "temperature": 23,
  "humidity": 48
}'

To run the below MQTT client on your PC, you will need Python 3 installed. To speed things up a little, you can also just open and run it on Replit.com.

Remember to initialize APPLICATION_VERSION and ENDPOINT_TOKEN variables your application version name and the endpoint token respectively.

# Simple MQTT-based data collection client for the Kaa IoT platform.
# See https://docs.kaaiot.io/KAA/docs/current/Tutorials/getting-started/collecting-data-from-a-device/.

import json
import random
import signal
import string
import time

import paho.mqtt.client as mqtt

KPC_HOST = "mqtt.cloud.kaaiot.com"  # Kaa Cloud plain MQTT host
KPC_PORT = 1883                     # Kaa Cloud plain MQTT port

ENDPOINT_TOKEN = ""       # Paste your endpoint token
APPLICATION_VERSION = ""  # Paste your application version


class DataCollectionClient:

    def __init__(self, client):
        self.client = client
        self.data_collection_topic = f'kp1/{APPLICATION_VERSION}/dcx/{ENDPOINT_TOKEN}/json'

    def connect_to_server(self):
        print(f'Connecting to Kaa server at {KPC_HOST}:{KPC_PORT} using application version {APPLICATION_VERSION} and endpoint token {ENDPOINT_TOKEN}')
        self.client.connect(KPC_HOST, KPC_PORT, 60)
        print('Successfully connected')

    def disconnect_from_server(self):
        print(f'Disconnecting from Kaa server at {KPC_HOST}:{KPC_PORT}...')
        self.client.loop_stop()
        self.client.disconnect()
        print('Successfully disconnected')

    def compose_data_sample(self):
        return json.dumps({
            'timestamp': int(round(time.time() * 1000)),
            'temperature': random.randint(15, 25),
            'humidity': random.randint(35, 60),
        })


def on_message(client, userdata, message):
    print(f'<-- Received message on topic "{message.topic}":\n{str(message.payload.decode("utf-8"))}')


def main():
    # Initiate server connection
    client = mqtt.Client(client_id=''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(6)))

    data_collection_client = DataCollectionClient(client)
    data_collection_client.connect_to_server()
    client.on_message = on_message

    # Start the loop
    client.loop_start()

    # Send data samples in loop
    listener = SignalListener()
    while listener.keepRunning:

        payload = data_collection_client.compose_data_sample()

        result = data_collection_client.client.publish(topic=data_collection_client.data_collection_topic, payload=payload)
        if result.rc != 0:
            print('Server connection lost, attempting to reconnect')
            data_collection_client.connect_to_server()
        else:
            print(f'--> Sent message on topic "{data_collection_client.data_collection_topic}":\n{payload}')

        time.sleep(3)

    data_collection_client.disconnect_from_server()


class SignalListener:
    keepRunning = True

    def __init__(self):
        signal.signal(signal.SIGINT, self.stop)
        signal.signal(signal.SIGTERM, self.stop)

    def stop(self, signum, frame):
        print('Shutting down...')
        self.keepRunning = False


if __name__ == '__main__':
    main()

Feel free to play with the client and use it as a reference for your client integration.

Verify that the auto~temperature and auto~humidity time series appeared on the right side of the “Device telemetry” chart and the chart is filled with data points.

Chart with time-series data