Enviar dados do Raspberry Pi para o Oracle IoT Cloud Service

Hoje estamos experimentando a transformação causada pela Internet das coisas (IoT) e é comum ver projetos simples de IoT, como monitoramento de umidade e temperatura ou projetos complexos, como carros conectados. Os projetos mais simples estão usando plataformas de baixo custo como Arduino ou Raspberry Pi e qualquer um pode iniciar seu próprio projeto IoT com facilidade.

Neste post, aprenderemos como enviar dados de umidade e temperatura do Raspberry Pi para o Oracle Internet of Things Cloud Service.
Vou usar meu Raspberry Pi Zero W e um sensor DHT11.

Para este projeto, usarei a linguagem C e o C Posix SDK fornecido pela Oracle, mas você tem outras opções de linguagem de programação.

Vá para a sua instância do Iot Cloud Service e crie uma nova aplicação. Nomeie-o como “Humidity and Temperature” e clique no botão Create.

Clique no aplicativo “Humidity and Temperature” e crie um novo Device Model. Nomeie-o como “Humidity and Temperature Sensor” e configure a URN como “urn:com:oracle:iot:device:humidity_temperature”.

Adicione dois Custom Attributes, humidity e temperature.
Defina ambos os atributos como tipo Number.

Clique no botão Save.
Vá para a página Registration e clique no botão Register Single Device.

Preencha o formulário e clique no botão Register.

Para gerar o arquivo de provisionamento do dispositivo, especifique uma senha e clique no botão Download Provisioning File.

Faça login no seu Raspberry Pi e execute o seguinte comando:

sudo apt-get install libssl1.0-dev -y

Neste momento, a última versão do C POSIX Client Software Library é 18.1.5.0.0-18, mas recomendo que você verifique a versão atual aqui: Oracle IoT Cloud Service Client Software Library downloads page.
Execute o seguinte comando para criar uma nova pasta “iotcs-cposix” e baixe o arquivo binário C POSIX Client Software Library

mkdir iotcs-cposix

cd iotcs-cposix

wget http://download.oracle.com/otn_software/samples/cloud/iotcs-csl-c-posix-bin-18.1.5.0.0-18.zip

Execute o seguinte comando para extrair o conteúdo do arquivo iotcs-csl-c-posix-bin-18.1.5.0.0-18.zip.

unzip iotcs-csl-c-posix-bin-18.1.5.0.0-18.zip

No diretório bin (/home/pi/iotcs-cposix/iotcs/csl/c/posix/bin), crie um novo arquivo humidity_temperature.c e use o seguinte código:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <wiringPi.h>
#include <stdint.h>
 
/* include common public types */
#include "iotcs.h"
/* include iot cs device model APIs */
#include "iotcs_virtual_device.h"
/* include methods for device client*/
#include "iotcs_device.h"
 
/* Current humidity value */
static int current_humidity_value;
/* Current temperature value */
static int current_temperature_value;
/* Device model handle */
static iotcs_device_model_handle device_model_handle = NULL;
/* Device handle */
static iotcs_virtual_device_handle device_handle = NULL;

#define MAXTIMINGS  85
#define DHTPIN    15
int dht11_dat[5] = { 0, 0, 0, 0, 0 };

 
static void finalize_library() {
  /* free device handle */
  if (device_handle) {
    iotcs_free_virtual_device_handle(device_handle);
    device_handle = NULL;
  }
	
  /* free device model handle */
  if (device_model_handle) {
    iotcs_free_device_model(device_model_handle);
    device_model_handle = NULL;
  }
	
  iotcs_finalize();
}

/* print error message and terminate the program execution */
static void error(const char* message) {
  printf("Error occurred: %s\n", message);
  finalize_library();
  exit(EXIT_FAILURE);
}

void sensor_work() {
  uint8_t laststate = HIGH;
  uint8_t counter   = 0;
  uint8_t j   = 0, i;
  float f; /* fahrenheit */

  dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;

  /* pull pin down for 18 milliseconds */
  pinMode( DHTPIN, OUTPUT );
  digitalWrite( DHTPIN, LOW );
  delay( 18 );
  /* then pull it up for 40 microseconds */
  digitalWrite( DHTPIN, HIGH );
  delayMicroseconds( 40 );
  /* prepare to read the pin */
  pinMode( DHTPIN, INPUT );

  /* detect change and read data */
  for ( i = 0; i < MAXTIMINGS; i++ ) {
    counter = 0;
    while ( digitalRead( DHTPIN ) == laststate ) {
      counter++;
      delayMicroseconds( 1 );
      if ( counter == 255 ) {
        break;
      }
    }
    laststate = digitalRead( DHTPIN );

    if ( counter == 255 ) {
      break;
    }

    /* ignore first 3 transitions */
    if ( (i >= 4) && (i % 2 == 0) ) {
      /* shove each bit into the storage bytes */
      dht11_dat[j / 8] <<= 1;
      if ( counter > 16 ) {
        dht11_dat[j / 8] |= 1;
      }
      j++;
    }
  }

  /*
   * check we read 40 bits (8bit x 5 ) + verify checksum in the last byte
   * print it out if data is good
   */
  if ( (j >= 40) && (dht11_dat[4] == ( (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF) ) ) {
    f = dht11_dat[2] * 9. / 5. + 32;
    current_humidity_value = dht11_dat[0];
    current_temperature_value = dht11_dat[2];
    printf( "Humidity = %d.%d %% Temperature = %d.%d *C (%.1f *F)\n", dht11_dat[0], dht11_dat[1], dht11_dat[2], dht11_dat[3], f );
  } else  {
    current_humidity_value = 0;
    current_temperature_value = 0;
    printf( "Data not good, skip\n" );
  }
}
 
int main(int argc, char** argv) {
  /* This is the URN of your device model. */
  const char* device_urns[] = {
    "urn:com:oracle:iot:device:humidity_temperature",
    NULL
  };
 
  iotcs_result rv;
 
  if (argc < 3) {
    error("Too few parameters.\n"
          "\nUsage:"
          "\n\tdirectly_connected_device.out path password"
          "\n\tpath is a path to trusted assets store."
          "\n\tpassword is a password for trusted assets store.");
  }
  const char* ts_path = argv[1];
  const char* ts_password = argv[2];
  
  /*
   * Initialize the library before any other calls.
   * Initiate all subsystems like ssl, TAM, request dispatcher,
   * async message dispatcher, etc which needed for correct library work.
   */
  if (iotcs_init(ts_path, ts_password) != IOTCS_RESULT_OK) {
    error("Initialization failed");
  }
 
  /*
   * Activate the device, if it's not already activated.
   * Always check if the device is activated before calling activate.
   * The device model URN is passed into the activate call to tell
   * the server the device model(s) that are supported by this
   * directly connected device
   */
  if (!iotcs_is_activated()) {
    if (iotcs_activate(device_urns) != IOTCS_RESULT_OK) {
      error("Sending activation request failed");
    }
  }
 
  /* get device model handle */
  if (iotcs_get_device_model(device_urns[0], &device_model_handle) != IOTCS_RESULT_OK) {
    printf("iotcs_get_device_model_handle method failed\n");
    return IOTCS_RESULT_FAIL;
  }
 
  /* get device handle */
  if (iotcs_create_virtual_device_handle(iotcs_get_endpoint_id(), device_model_handle, &device_handle) != IOTCS_RESULT_OK) {
    printf("iotcs_create_virtual_device_handle method failed\n");
    return IOTCS_RESULT_FAIL;
  }
	
  printf( "Humidity and Temperature Program initializing...\n" );
	
  if ( wiringPiSetup() == -1 ) {
    exit( 1 );
  }

  while ( 1 ) {
    /* wait 1sec to refresh */
    delay( 1000 );
    sensor_work();
    if (current_humidity_value > 0 && current_temperature_value > 0) {
      iotcs_virtual_device_start_update(device_handle);

      /* set humidity value */
      rv = iotcs_virtual_device_set_float(device_handle, "humidity", current_humidity_value);

      if (rv != IOTCS_RESULT_OK) {
        error("iotcs_virtual_device_set_integer method failed\n");
      }

      /* set temperature value */
      rv = iotcs_virtual_device_set_float(device_handle, "temperature", current_temperature_value);

      if (rv != IOTCS_RESULT_OK) {
        error("iotcs_virtual_device_set_integer method failed\n");
      }

      iotcs_virtual_device_finish_update(device_handle);
    }
  }
	
  finalize_library();
  return EXIT_SUCCESS;
}

Execute os seguintes comandos para instalar a biblioteca GPIO:

sudo git clone git://git.drogon.net/wiringPi

cd wiringPi

sudo ./build

Compile o programa C.

cd ..

gcc -g -I../include -I../lib/arm -o ./humidity_temperature.out ./humidity_temperature.c -Wl,-Bstatic -L../lib/arm -liotdeviceclient -Wl,-Bdynamic -lssl -lcrypto -lm -lrt -lpthread -lwiringPi -ldl

Copie o arquivo de provisionamento que foi baixado quando você registrou o dispositivo, nesse diretório.

Crie um novo arquivo start_humidity_temperature.sh e use o seguinte código: (Nota: File_Protection_Password é o mesmo que você usou no Oracle IoT Cloud Service para baixar o arquivo de provisionamento.)

export IOTCS_OS_NAME="Raspbian GNU/Linux"
export IOTCS_OS_VERSION="8"
./humidity_temperature.out B8-27-EB-E6-8C-58 File_Protection_Password

Execute o seguinte comando para iniciar o programa C:

chmod +x start_humidity_temperature.sh

./start_humidity_temperature.sh

Agora, você pode monitorar a umidade e a temperatura usando o Oracle IoT Cloud Service.

Fontes:

Autor: Waslley Souza

Consultor Oracle com foco em tecnologias Oracle Fusion Middleware e SOA. Certificado Oracle WebCenter Portal, Oracle ADF e Java.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *