Oracle IoT: uno starter (versione italiana)

Luigi Saetta
10 min readSep 12, 2018

Un’introduzione, con esempi e strumenti, all’utilizzo di Oracle IoT Cloud Service. (v. 1.3)

Introduzione.

Con questo articolo vorrei fornire un insieme di informazioni, di note, di esempi per consentire a chi ha voglia di iniziare a sperimentare le tecnologie dell’Internet of Things (IoT) e di farlo utilizzando Oracle IoT Cloud.

Molte delle informazioni che troverete sono abbastanza generali e non dipendono strettamente dall’adozione del Cloud Oracle, in quanto basate sull’adozione di protocolli standard (es: MQTT), di strumenti Open (Java, Eclipse Paho, etc). A queste informazioni, per le persone meno familiari con i servizi Cloud Oracle, ho aggiunto una serie di note che, come vedrete, vi consentiranno di iniziare ad inviare messaggi IoT sul Cloud Oracle in un paio di ore.

Le note sono nate per supportare una serie di Workshop dedicati all’IoT, organizzati nell’ambito delle attività del Business Innovation Team italiano. Poi, ho pensato di organizzarle e pubblicarle qui su Medium, per metterle a disposizione non solo dei partecipanti dei workshop ma anche di una platea più ampia di “IoT-Entusiasti”.

L’articolo vuole essere uno scritto a metà tra un documento di divulgazione e quello che in gergo tecnico chiamiamo “How-to”. Non sarà un articolo rigoroso e completo al punto da riuscire a soddisfare i lettori più rigorosi. Ma, spero che risulti gradevole da leggere, ovviamente il più possibile chiaro e comprensibile ed, in ultima sintesi, utile.

Un mondo di messaggi: MQTT.

Anche se viviamo in un mondo in cui si fa ampio uso, ed abuso, del protocollo HTTP, esso non è molto adatto alla comunicazione con dispositivi “limitati” (constrained), con poca memoria e limitata capacità computazionale. Volete capire di quali dispositivi parlo? Bene, immaginate di voler creare una piccola stazione meteo con Arduino. Arduino è un microcontrollore che rientra nella categoria dei “constrained device”.

Se volessimo trasmettere un messaggio JSON di pochi byte

{ “temp”: 22.5}

l’HTTP vi aggiungerebbe un header di gran lunga più grande (100 byte ?). Può funzionare ed in alcuni casi anche bene se abbiamo banda di comunicazione sufficiente, ma è fondamentalmente uno spreco di risorse. E questo utilizzo non efficiente si rende evidente sopratutto laddove chi trasmette è un “piccolo e limitato dispositivo”, come un Arduino.

Inoltre, l’HTTP di suo non aggiunge nessun meccanismo per garantire l’affidabilità della trasmissione, oltre a quelli forniti dal TCP. In altre parole, non prevede nessun meccanismo per controllare che un messaggio arrivi a destinazione o sia automaticamente ritrasmesso.

Per questa ragione, oramai alla fine del secolo passato (!), è stato definito un protocollo di messaggistica nato specificamente per dispositivi e reti con banda limitata, non del tutto affidabili (lossy, con possibile perdita di messaggi): MQTT.

Per quanto vogliamo discutere qui, mettiamo tre punti fermi e chiari:

  • è un protocollo semplice ed efficiente (header fisso di 2 bytes);
  • consente di implementare una trasmissione affidabile, con ritrasmissione (si parla di QoS);
  • è oramai uno standard OASIS.

Last-but-not-the-least, MQTT è basato sul paradigma “Publish&Subscribe”: il client pubblica messaggi su una (o più topic) e le applicazioni che vogliono ricevere i messaggi fanno il subscribe. Per operare in tal modo, vi è bisogno di un MQTT broker, che riceve i messaggi e li pubblica per i subscriber sulle topic.

L’unico vero limite dell’MQTT è che esso è basato su TCP. Quindi adottabile solo da dispositivi che riescono a supportare uno stack TCP affidabile.

Per le nostre piacevoli sperimentazioni useremo un broker semplice ma efficiente ed affidabile: il broker, Mosquitto, ospitato ed evoluto da uno dei progetti dell’Eclipse Foundation.

Sul sito del progetto leggiamo: ”the current implementation of Mosquitto has an executable in the order of 120kB that consumes around 3MB RAM with 1000 clients connected”. Amazing.

Nell’ambito dei casi d’uso qui esplorati l’MQTT lo useremo per la comunicazione tra i dispositivi (“device”), che assumiamo piccoli e limitati, ed un IoT Gateway. Sarà solo l’IoT Gateway poi a colloquiare con l’IoT Cloud.

MQTT client.

Per realizzare la porzione di codice sui “device”, che si deve occupare di inviare i dati tramite messaggi MQTT al broker, utilizzeremo le librerie fornite da un altro memorabile progetto di Eclipse: Paho.

Paho fornisce librerie per tutti i linguaggi più utilizzati in ambito IoT (Java, Javascript, Python, …). Nella nostra breve ma allegra sperimentazione useremo due linguaggi: Java e Python.

Publish&Subscribe

Lo scenario che consideriamo è il seguente: sul Gateway IoT è installato un broker MQTT. I device inviano i messaggi con i dati su TOPIC distinte (es: device/meteo1/data). Sul Gateway vi è software, scritto in Java, che fa’ la subscribe a tali TOPIC ed, utilizzando una client library di Oracle IoT, invia i dati all’Oracle IoT Cloud Service.

Lo scenario considerato non è, ovviamente, l’unico possibile. Ma è un opzione valida (se le board con device possono usare TCP ed MQTT). Utilizzando il paradigma Publish&Subscribe l’accoppiamento device-gateway è lasco, il che è una buona cosa.

Il codice contenuto nel file SimpleMQTTSubscriber.java (vedi repository Github, nota sotto) è un esempio di codice, basato su Eclipse Paho, per creare un Subscriber, in Java, in grado di ricevere i messaggi inviati su una topic MQTT.

In sintesi, nel codice si deve definire una callback function che è invocata ogni volta che è ricevuto un messaggio sulla topic a cui si è effettuato il subscribe. E’ compito della callback de-serializzare il messaggio, estrarre i dati interessanti ed inviare al Cloud.

Nel secondo file JSONMQTTSubscriber.java si mostra come, utilizzando la libreria Open Source GSON, è semplice de-serializzare un messaggio JSON.

Prerequisiti

  • ambiente (preferibilmente IDE) con JDK 8; Noi tipicamente utilizziamo Eclipse
  • ambiente con Python3 funzionante (consiglierei l’adozione della distribuzione Anaconda)

Installare:

  • (libreria Paho per Python) pip install paho-mqtt
  • le librerie per Java

Un simulatore

Per simulare i dati inviati al Gateway da una board equipaggiata con N sensori, nel repository Github metto a disposizione un programma Python

meteosym.py

Il programma legge i dati (veri) da un file csv.

La command-line con cui lanciarlo è:

python3 meteosym.py dati.txt

Nel programma è possibile specificare alcuni parametri:

  • l’intervallo temporale che si vuole considerare (ID1, ID2)
  • l’hostname del broker MQTT
  • l’intervallo (in sec) tra un invio ed il successivo; cambiandolo si può “comprimere” il tempo

Il programma simula una Stazione meteo, in grado di raccogliere non solo i dati interessanti dal punto di vista del confort ambientale (temperatura, umidità) ma anche i dati importanti per valutare qualità dell’aria ed inquinamento (indice di qualità dell’aria, pm2.5, pm10…).

La scelta fatta per il formato dei messaggi MQTT è di utilizzare il formato JSON.

I passi da compiere in Oracle IoT Cloud

Questi sono, in sintesi, i passi da compiere per poter inviare messaggi all’Oracle IoT Cloud (nel seguito IoT CS):

  • creare un’applicazione in IoT CS
  • creare all’interno di quest’applicazione un Device Model
  • registrare i Device
  • creare una esplorazione
  • creare un’integrazione con una Enterprise Application

Applicazione e DeviceModel.

L’applicazione che useremo si chiama: WorkshopIoT. Possiamo descriverla come una sorta di contenitore, di Namespace, all’interno del quale si definiscono i DeviceModel, le integrazioni, le esplorazioni.

Il Device Model descrive quali dati sono inviati dal Device o Gateway, il formato (number, string…) di questi dati, etc. Il Device Model è identificato univocamente da una URN.

Negli esempi utilizzeremo un Device Model di nome AircareModel, che prevede questi dati:

  • temp
  • hum
  • light (in lumen)
  • iaq (indice di qualità dell’aria, lower-is-better)
  • pm25
  • pm10
Custom attributes del DeviceModel (dalla IoT UI)

Il DeviceModel prevede anche due attributi di sistema (latitude e longitude) che, se forniti, consentono la geo-localizzazione dei dispositivi.

La struttura del messaggio JSON è rappresentata dalla seguente figura

Struttura messaggio JSON (dalla IoT UI)

Registrazione dei Device.

Prima che un device (sia esso un DCD sia un Gateway) possa comunicare con Oracle IoT CS, esso deve essere registrato.

All’atto della registrazione viene generato un file, il cui contenuto è protetto da password, che contiene la URL di accesso all’IoT CS ed una serie di “credenziali” che saranno utilizzate per consentire l’accesso in modo sicuro.

Il file deve essere scaricato sul device e collocato in una directory il cui percorso è specificato al client. La password è utilizzata dall’applicazione client.

La registrazione del device si può fare nei seguenti modi:

  • dalla IoT UI, device per device (Single Registration)
  • dalla IoT UI, in modo batch per una lista di device
  • utilizzando la REST API di IoT CS
Single Device registration using IoT UI

Dopo aver registrato il device

Dopo averlo registrato, il device può essere attivato da codice e può inviare messaggi all’IoT CS. L’IoT CS può inviare alert e comandi al device (in questo primo articolo non tratteremo la seconda parte).

A questo punto, per avere una prima idea di come comunicare, si può esaminare l’API dedicata ai Directly Connected Device (DCD): sono device che comunicano direttamente con IoT Cloud senza l’intermediazione di un Gateway.

L’esempio di codice è il file: SimpleDCDClient.java

Visualizzare i messaggi ricevuti da IoT CS

Lo si può fare dalla dashboard dell’applicazione

Dashboard dell’applicazione (IoT UI)

Realizzare un semplice MQTT subscriber che invia messaggi ad IoT CS

Combinando il codice realizzato per sviluppare un MQTT subscriber con il codice del DCD client è abbastanza semplice realizzare un componente Java che legge i messaggi dalla topic a cui ha sottoscritto, li elabora e li invia ad IoT CS. E’ un primo esempio, funzionante, del tipo di codice da realizzare per implementare un IoT Gateway (attenzione: un Gateway reale è molto più ricco di funzionalità e complesso).

Il codice che realizza tutto ciò è dato dalla combinazione dei tre file:

  • JSONMQTTSubscriber.java
  • SimpleDCDClient.java
  • AircareMessage.java

Nella directory lib del repository github trovate i file JAR che compongono le librerie necessarie per compilare ed eseguire il codice.

La DCD Device Virtualization library è composta dal file device-library.jar insieme al file di supporto json-20160212.jar

API REST

Oracle IoT CS ha un’API REST completa, con cui è possibile, dopo opportuna autenticazione, effettuare praticamente tutte le operazioni su IoT Cloud.

Ad esempio, se vogliamo avere informazioni relative al DeviceModel definito, possiamo usare l’invocazione:

curl -X GET -k -u user:pwd -H ‘Accept: application/json’ https://iotserver/iot/api/v2/deviceModels/urn:com:oracle:aircare

In questo esempio ho utilizzato CURL come client, ma potete utilizzare qualunque altro client (Postman, etc..).

Con l’API REST possiamo anche leggere gli ultimi N (nell’esempio N=10) messaggi ricevuti da IoT CS:

curl -X GET -k -u user:pwd -H ‘Accept: application/json’ https://iotserver/iot/api/v2/messages?type=data&limit=10

La documentazione completa relativa all’API è reperibile qui: Oracle IoT API REST DOC

Esplorazioni.

E’ possibile attuare elaborazioni su uno stream di messaggi (associati ad un Device Model) utilizzando le Exploration.

Ad esempio, è possibile attuare un filtro: far passare solo i messaggi in cui alcuni dati sono fuori da un intervallo pre-definito. E’ la più semplice attuazione di un sistema di controllo anomalie.

E’ anche possibile semplicemente visualizzare i messaggi in arrivo, eventualmente selezionando soltanto i dati a cui siamo interessati.

Live input stream from the exploration.

Integrazione con Enterprise Application.

Un’Enterprise Application è un’applicazione esterna ad Oracle IoT CS, a cui vogliamo mandare uno stream di messaggi, eventualmente filtrato, elaborato.

Oracle IoT consente, in modo dichiarativo di definire un’integrazione. E’ sufficiente che l’applicazione esponga un endpoint REST a cui inviare, tramite POST, i messaggi.

L’unico vincolo è che l’endpoint sia esposto tramite HTTPS (noi crediamo che la sicurezza sia molto importante). Ma se, in ambiente di test, si vogliono utilizzare certificati self-signed è possibile caricare in Oracle IoT i certificati.

Integrations in Oracle IoT

Il formato dei messaggi è il formato JSON interno di Oracle IoT CS.

Ovviamente, se l’Enterprise Application richiede trasformazioni complesse, è opportuno che IoT invochi un proxy, ad esempio realizzato con Oracle Integration Cloud.

Esempio JavaScript

Il file iotfmproxy.js, contenuto nel repository github del progetto, è un esempio di proxy, realizzato in Javascript, per IoT CS.

E’ in grado di ricevere messaggi JSON via POST HTTP e dopo le dovute trasformazioni, inviarli ad Oracle IoT CS. Il modello dati utilizzato è differente (è preso da una PoC per il Fleet Monitoring) ma può essere utilizzato per capire come utilizzare l’API Javascript di Oracle IoT CS.

Ovviamente, per chi non è familiare, una certa complessità alla struttura del codice è aggiunta dalla natura asincrona di NodeJS.

Oracle IoT Cloud Service Client Software

La versione delle librerie che utilizzeremo è la 18.1.5.

La URL da cui può essere effettuato il download è:

Java SE client SW

I file indispensabili sono:

  • device-library.jar
  • json-XXXXXX.jar
  • enterprise-library.jar

(Per essere più precisi, in un client DCD sono necessari soltanto i primi due file JAR).

One last thing

Il repository Github in cui potete trovare i dati e gli esempi di codice descritti in questo articolo è il seguente: MeteoSimulation.

Troubleshooting.

Alcune note/suggerimenti per l’identificazione di problemi:

  • allo stesso broker MQTT non si possono collegare simultaneamente due client (anche publisher e subscriber) con lo stesso clientID; Il secondo è disconnesso dal broker. Quindi, nel codice Python e Java non possiamo usare lo stesso clientID.

Link alla documentazione:

--

--

Luigi Saetta

Born in the wonderful city of Naples, but living in Rome. Always curious about new technologies and new things., especially in the AI field.