2. Using API interface

This section provides a complete step-by-step tutorial of how to create, update, send messages to and check historical data of a device. Also, this tutorial assumes that you are using docker-compose, which has all the necessary components to properly run dojot.

Note

  • Audience: developers
  • Level: basic
  • Reading time: 15 m

2.1. Prerequisites

It uses:

  • curl to access the dojot platform APIs;
  • jq to process the return JSON from the dojot platform APIs.
  • mosquitto to publish and subscribe in iotagent-mosca (or iotagent-mqtt) via MQTT.

In Debian-based Linux distributions you can run:

sudo apt-get install curl
sudo apt-get install jq
sudo apt-get install mosquitto-clients

2.2. Getting access token

As said in User authentication, all requests must contain a valid access token. You can generate a new token by sending the following request:

JWT=$(curl -s -X POST http://localhost:8000/auth \
-H 'Content-Type:application/json' \
-d '{"username": "admin", "passwd" : "admin"}' | jq -r ".jwt")

To check:

echo $JWT

If you want to generate a token for other user, just change the username and password in the request payload. The token (“eyJ0eXAiOiJKV1QiL…”) should be used in every HTTP request sent to dojot in a special header. Such request would look like:

curl -X GET http://localhost:8000/device \
  -H "Authorization: Bearer eyJ0eXAiOiJKV1QiL..."

Remember that the token must be set in the request header as a whole, not parts of it. In the example only the first characters are shown for the sake of simplicity. All further requests will use an evironment variable called ${JWT}, which contains the token got from auth component.

2.3. Device creation

In order to properly configure a physical device in dojot, you must first create its representation in the platform. The example presented here is just a small part of what is offered by DeviceManager. For more information, check the DeviceManager how-to for more detailed instructions.

First of all, let’s create a template for the device - all devices are based off of a template, remember.

curl -X POST http://localhost:8000/template \
-H "Authorization: Bearer ${JWT}" \
-H 'Content-Type:application/json' \
-d ' {
  "label": "Thermometer Template",
  "attrs": [
    {
      "label": "temperature",
      "type": "dynamic",
      "value_type": "float"
    },
    {
      "label": "fan",
      "type": "actuator",
      "value_type": "float"
    }
  ]
}'

This request should give back this message:

 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
 {
   "result": "ok",
   "template": {
     "created": "2018-01-25T12:30:42.164695+00:00",
     "data_attrs": [
       {
         "template_id": "1",
         "created": "2018-01-25T12:30:42.167126+00:00",
         "label": "temperature",
         "value_type": "float",
         "type": "dynamic",
         "id": 1
       }
     ],
     "label": "Thermometer Template",
     "config_attrs": [],
     "attrs": [
       {
         "template_id": "1",
         "created": "2018-01-25T12:30:42.167126+00:00",
         "label": "temperature",
         "value_type": "float",
         "type": "dynamic",
         "id": 1
       },
       {
         "template_id": "1",
         "created": "2018-01-25T12:30:42.167126+00:00",
         "label": "fan",
         "type": "actuator",
         "value_type": "float",
         "id": 2
       }
     ],
     "id": 1
   }
 }

Note that the template ID is 1 (line 35), if you have already created another template this id will be different.

To create a template based on it, send the following request to dojot:

curl -X POST http://localhost:8000/device \
-H "Authorization: Bearer ${JWT}" \
-H 'Content-Type:application/json' \
-d ' {
  "templates": [
    "1"
  ],
  "label": "device"
}'

The template ID list on line 6 contains the only template ID configured so far. To check out the configured device, just send a GET request to /device:

curl -X GET http://localhost:8000/device -H "Authorization: Bearer ${JWT}"

Which should give back:

 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
  {
    "pagination": {
      "has_next": false,
      "next_page": null,
      "total": 1,
      "page": 1
    },
    "devices": [
      {
        "templates": [
          1
        ],
        "created": "2018-01-25T12:36:29.353958+00:00",
        "attrs": {
          "1": [
            {
              "template_id": "1",
              "created": "2018-01-25T12:30:42.167126+00:00",
              "label": "temperature",
              "value_type": "float",
              "type": "dynamic",
              "id": 1
            },
            {
              "template_id": "1",
              "created": "2018-01-25T12:30:42.167126+00:00",
              "label": "fan",
              "value_type": "actuator",
              "type": "float",
              "id": 2
           }
          ]
        },
        "id": "0998",
        "label": "device_0"
      }
    ]
  }

2.4. Sending messages

So far we got an access token and created a template and a device based on it. In an actual deployment, the physical device would send messages to dojot with all its attributes and their current values. For this tutorial we will send MQTT messages by hand to the platform, emulating such physical device. For that, we will use mosquitto_pub and mosquitto_sub from mosquitto.

Attention

Some Linux distributions, Debian-based Linux distributions in particular, have two packages for mosquitto - one containing tools to access it (i.e. mosquitto_pub and mosquitto_sub for publishing messages and subscribing to topics) and another one containing the MQTT broker too. In this tutorial, only the tools from package mosquitto-clients on Debian-based Linux distributions are going to be used. Please check if MQTT broker is not running before starting dojot (by running commands like ps aux | grep mosquitto) to avoid port conflicts.

Note

To run mosquitto_pub and mosquitto_sub without using TLS, as in the examples below, you must set the environment variable ALLOW_UNSECURED_MODE with the value ‘true’ to the iotagent-mqtt service, that is, ALLOW_UNSECURED_MODE=’true’. You can change this value in the dojot docker-compose.yml file and then kill and up the docker-compose again. By default this value is already ‘true’.

The default message format used by dojot is a simple key-value JSON (you could translate any message format to this scheme using flows, though), such as:

{
  "temperature" : 10.6
}

Let’s send this message to dojot:

mosquitto_pub -h localhost -t /admin/0998/attrs -p 1883 -i admin:0998 -m '{"temperature": 10.6}'

If there is no output, the message was sent to MQTT broker.

Also you can send a configuration message from dojot to the device to change some of its attributes. The target attribute must be of type “actuator”.

To simulate receiving the message on a device, we can use the mosquitto_sub:

mosquitto_sub -h localhost -p 1883  -i admin:0998 -t /admin/0998/config

Triggering the sending of the message from the dojot to the device.

curl -X PUT \
    http://localhost:8000/device/0998/actuate \
    -H "Authorization: Bearer ${JWT}" \
    -H 'Content-Type:application/json' \
    -d '{"attrs": {"fan" : 100}}'

As noted in the Frequently Asked Questions, there are some considerations regarding MQTT topics:

  • You can set the device ID that originates the message using the client-id MQTT parameter. It should follow the following pattern: <service>:<deviceid>, such as admin:efac.
  • If you can’t do such thing, then the device should set its ID using the topic used to publish messages. The topic should assume the pattern /<service-id>/<device-id>/attrs (for instance: /admin/efac/attrs).
  • The topic to subscrine should assume the pattern /<service-id>/<device-id>/config (for instance: /admin/efac/config).
  • MQTT payload must be a JSON with each key being an attribute of the dojot device, such as:
{ "temperature" : 10.5,"pressure" : 770 }

This examples are using MQTT without TLS, we recommend Using MQTT with security (TLS).

2.5. Checking historical data

In order to check all values that were sent from a device for a particular attribute, you could use the history api, see more in Components and APIs. Let’s first send a few other values to dojot so we can get a few more interesting results:

mosquitto_pub -t /admin/0998/attrs -i admin:0998 -m '{"temperature": 36.5}'
mosquitto_pub -t /admin/0998/attrs -i admin:0998 -m '{"temperature": 15.6}'
mosquitto_pub -t /admin/0998/attrs -i admin:0998 -m '{"temperature": 10.6}'

To retrieve all values sent for temperature attribute of this device:

curl -X GET \
  -H "Authorization: Bearer ${JWT}" \
  "http://localhost:8000/history/device/0998/history?lastN=3&attr=temperature"

The history endpoint is built from these values:

  • .../device/0998/...: the device ID is 0998 - this is retrieved from the id attribute from the device

  • .../history?lastN=3&attr=temperature: the requested attribute is temperature and it should get the last 3 values.

    The request should result in the following message:

[
  {
    "device_id": "0998",
    "ts": "2018-03-22T13:47:07.050000Z",
    "value": 10.6,
    "attr": "temperature"
  },
  {
    "device_id": "0998",
    "ts": "2018-03-22T13:46:42.455000Z",
    "value": 15.6,
    "attr": "temperature"
  },
  {
    "device_id": "0998",
    "ts": "2018-03-22T13:46:21.535000Z",
    "value": 36.5,
    "attr": "temperature"
  }
]

This message contains all previously sent values.