2. Utilizando a API da dojot

Esta seção descreve o passo a passo completo de como criar, alterar, enviar mensagens e conferir dados históricos relativo a um dispositivo. Este tutorial assume que está sendo utilizada a instalação docker-compose e que todos os componentes necessários estão sendo executados corretamente na dojot.

Nota

  • Audiência: desenvolvedores

  • Nível: básico

  • Tempo de leitura: 15 minutos

2.1. Pré-requisitos

Vamos utilizar:

  • curl para acessar as APIs da plataforma dojot;

  • jq para processar o retorno JSON das APIs da plataforma dojot.

  • mosquitto publicar e se subscrever no iotagent-mosca (or iotagent-mqtt) via MQTT.

Em distribuições Linux baseadas em Debian, você pode executar:

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

2.2. Obtendo um token de acesso

Todas as requisições devem conter um token de acesso que seja válido. É possível gerar um novo token enviando a seguinte requisição:

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

Checar:

echo $JWT

Se o intuito for gerar um token para outro usuário, é necessário somente mudar o username e passwd no corpo da requisição. O token (“eyJ0eXAiOiJKV1QiL…”) deve ser usado em toda a requisição HTTP enviada para a dojot, colocando-o no cabeçalho da mensagem. A requisição seria algo desse tipo:

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

É importante ressaltar que o token deve estar inteiro no cabeçalho da requisição, não apenas parte dele. No exemplo, somente os primeiros caracteres foram mostrados por questão de simplificação. Todas as demais requisições serão compostas da variável de ambiente chamada bash ${JWT} que contém o token obtido da dojot (mais especificamente do componente de autorização da dojot).

2.3. Criação de dispositivo

A fim de configurar um dispositivo físico na dojot, é necessário criar sua representação na plataforma. O exemplo mostrado aqui é apenas uma parte pequena do que é oferecido pelo componente DeviceManager. Para mais informações sobre esse componente, confira a documentação do `DeviceManager`_.

Primeiramente vamos criar um modelo (template) para o dispositivo, pois todos os dispositivos são baseados em modelos, não esqueça.

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"
    }
  ]
}'

Esta requisição deve retornar a seguinte mensagem:

 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 que o template (modelo) ID é 1 (linha 35), caso você já tenha criado algum outro template este ID será diferente.

Para criar um dispositivo baseado nesse modelo (ID 1), envie a seguinte requisição para a dojot:

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

A lista de IDs de modelos na linha 6 contém um único ID do modelo configurado até o momento. Para conferir os dispositivos configurados, basta enviar uma requisição do tipo GET para /device:

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

Que deve retornar:

 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. Publicando mensagens

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 publish messages to dojot with all its attributes and their current values. For this tutorial we will publish MQTT messages by hand to the platform, emulating such physical device. For that, we will use mosquitto_pub and mosquitto_sub from mosquitto.

O formato padrão de mensagem usado pela dojot é um simples “chave-valor” JSON (é possível traduzir qualquer formato para esse esquema utilizando fluxos), como abaixo:

{
  "temperature" : 10.6
}

Atenção

Algumas distribuições Linux, como as baseadas em Debian, têm dois pacotes para mosquitto - um contendo ferramentas para cliente (ou seja, mosquitto_pub e mosquitto_sub para publicar mensagens e se subscrever em tópicos) e outro contendo um broker MQTT também. Neste tutorial, apenas as ferramentas do pacote mosquitto-clients em Distribuições Linux baseadas no Debian serão usadas. Verifique se um outro broker MQTT não está em execução antes de iniciar a dojot (executando comandos como ps aux | grep mosquitto) para evitar conflitos de porta.

Por simplicidade, nós não estamos utilizando TLS nos exemplos abaixo. Verifique o artigo Usando MQTT com segurança (TLS) para maiores esclarecimentos sobre sua utilização.

Nota

Para executar mosquitto_pub e` mosquitto_sub` sem usar TLS como nos exemplos abaixo, você precisa definir algumas configurações (ou para como desativar o modo sem TLS). Para obter mais detalhes sobre este tópico, consulte a página Modo inseguro do MQTT (sem TLS).

A partir da versão v0.5.0, você pode escolher entre dois brokers MQTT: Mosca ou VerneMQ. Por padrão, o VerneMQ é utilizado, mas você pode utilizar o Mosca também. Verifique o Guia de instalação para mais informações.

2.4.1. Usando o VerneMQ

Let’s publish the following message:

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

Se não houver saída (output), a mensagem foi enviada ao broker MQTT.

Note that we publish a message with the parameter -q 1. This means that the message will use QoS 1, i.e., the message is guaranteed to be sent at least one time.

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

Para simular o recebimento da mensagem em um dispositivo, podemos usar o mosquitto_sub:

mosquitto_sub -h localhost -p 1883 -u admin:0998 -t admin:0998/config -q 1

Triggering the publishing 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}}'

Como descrito no Dúvidas Mais Frequentes, existem algumas considerações a respeito dos tópicos MQTT:

  • Você deve adicionar o username que originou a mensagem usando o atributo de mesmo nome do MQTT. Ele deve seguir o seguinte padrão: <tenant>:<device-id>, como admin:efac. Ele deve ser o mesmo que o colocado no tópico.

  • O tópico para publicação deve assumir o padrão <tenant>:<device-id>/attrs (por exemplo: admin:efac/attrs).

  • O tópico de subscrição deve assumir o padrão <tenant>:<device-id>/config (por exemplo: admin:efac/config).

  • Os dados da mensagem MQTT (payload) devem ser um JSON com cada chave sendo um atributo do dispositivo cadastrado na dojot, como:

{ "temperature" : 10.5, "pressure" : 770 }

2.4.2. Usando o Mosca (legado)

Atenção

VerneMQ é o novo broker MQTT padrão. O suporte ao Mosca será eventualmente retirado, então use o VerneMQ se possível!

Vamos publicar a mensagem a seguir:

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

Se não houver saída (output), a mensagem foi enviada ao broker MQTT.

Além disso, você pode publicar uma mensagem de configuração da dojot para o dispositivo. O atributo de destino deve ser do tipo “actuator” ou “atuador”.

Para simular o recebimento da mensagem em um dispositivo, podemos usar o mosquitto_sub:

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

Disparando a publicação da mensagem da dojot para o dispositivo.

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

Como descrito no Dúvidas Mais Frequentes, existem algumas considerações a respeito dos tópicos MQTT:

  • Pode-se configurar o ID do dispositivo origem da mensagem utilizando o parâmetro MQTT client-id. Deve seguir o seguinte padrão: <service>:<deviceid>, como em admin:efac.

  • Se algo o impossibilita de realizar isto, então o dispositivo deve configurar seu ID no tópico utilizado para publicar as mensagens. O tópico deve assumir o padrão /<service-id>/<device-id>/attrs (e.g.: /admin/efac/attrs).

  • O tópico deve assumir o padrão /<service-id>/<device-id>/config (por exemplo: /admin/efac/config).

  • Os dados da mensagem MQTT (payload) devem ser um JSON com cada chave sendo um atributo do dispositivo cadastrado na dojot, como:

{ "temperature" : 10.5, "pressure" : 770 }

Nota

Consideraremos a utilização de VerneMQ pelo restante do tutorial.

2.5. Conferindo dados históricos

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

mosquitto_pub -h localhost -p 1883 -u admin:0998 -t admin:0998/attrs -m '{"temperature": 36.5}' -q 1
mosquitto_pub -h localhost -p 1883 -u admin:0998 -t admin:0998/attrs -m '{"temperature": 15.6}' -q 1
mosquitto_pub -h localhost -p 1883 -u admin:0998 -t admin:0998/attrs -m '{"temperature": 10.6}' -q 1

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

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

O endpoint do histórico é construído por meio desses valores:

  • .../device/0998/...: o ID do dispositivo é 0998 - isso é obtido do atributo id do próprio dispositivo

  • .../history?lastN=3&attr=temperature: o atributo requerido é temperature e deve ser recuperado os 3 últimos valores.

    A requisição deve resultar na seguinte mensagem:

[
  {
    "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"
  }
]

A mensagem acima contém todos os valores previamente enviados pelo dispositivo.