Sei sulla pagina 1di 35

UNIVERSIT DEGLI STUDI DI GENOVA

FACOLT DI INGEGNERIA

TESI DI LAUREA TRIENNALE IN INGEGNERIA ELETTRONICA


E TECNOLOGIE DELL'INFORMAZIONE

Progetto e implementazione di una API REST per


sensori di misure fisiologiche

Relatore:

Prof. Ing. Riccardo BERTA

Laureanda: Benedetta DEMICHELI

Anno Accademico 2015/2016


Indice
Premessa..........................................................................................................1

CAPITOLO I
Introduzione......................................................................................................2
-API.....................................................................................................................................................2
-IOT.....................................................................................................................................................2
-HCI e wearable computing................................................................................................................4
-Dominio applicativo..........................................................................................................................5

CAPITOLO II
Concetti fondamentali.......................................................................................6
-WoT.....................................................................................................................................................6
-REST...................................................................................................................................................7
-HTTP...................................................................................................................................................8
-Architettura del sistema .....................................................................................................................9

CAPITOLO III
Progettazione...................................................................................................11
-Risorse..............................................................................................................................................14
-Azioni................................................................................................................................................16
-Web Socket........................................................................................................................................18
-Applicazione Client..........................................................................................................................20

CAPITOLO IV
Implementazione..............................................................................................24
Strumenti utilizzati...........................................................................................27
-Node.js..............................................................................................................................................27
-Express.............................................................................................................................................28
-Visual studio code.............................................................................................................................28

CAPITOLO V
Conclusioni e Sviluppi futuri...........................................................................30

CAPITOLO VI
Bibliografia e sitografia..................................................................................33
Premessa
Scopo di questa tesi la progettazione e l'implementazione di un'API REST per la gestione
e controllo di sensori per misure fisiologiche.
Nei capitoli successivi verranno introdotti ed illustrati i concetti di "Internet of Things" e
"Web of things", fondamentali per la creazione di Application Programming Interfaces.
Il dispositivo che si occupa di raccogliere i dati provenienti dai sensori composto da una
scheda Arduino Uno a cui sono collegati misuratori fittizi ispirati a quelli presenti sullo
shield biometrico e-Health, compatibile con Arduino e Raspberry-pi.
Il server che rende disponibili le risorse attraverso le API REST stato realizzato
attraverso l'uso del framework Node.js, una piattaforma event-driven che, essendo
lightweight, ben si presta al nostro scopo, in quanto adatta a girare non solo su computer
general purpose, ma anche su microcontrollori meno potenti quali Rasberry-pi.
Tutto questo verr approfondito in seguito.

1
CAPITOLO I
Introduzione

Api
Le Application Programming Interfaces (APIs) sono degli insiemi di funzionalit,
strumenti e protocolli che vengono messi a disposizione di utenti e programmatori.
Le API forniscono un livello di astrazione che evita al programmatore di sapere come
funzionano le stesse ad un livello pi basso, favorendo quindi il "riciclo" del codice e di
funzioni preesistenti: un esempio classico di API sono le librerie software.
Questi strumenti vengono spesso messi a disposizione dei programmatori da parte di
colossi del web, quali Facebook, Google, Amazon e Microsoft, per facilitare lo sviluppo e
la realizzazione di applicazioni di vario genere.
Di fatto si pu pensare ad un parallelismo che esiste tra le GUIs (graphical user interfaces)
e le API. Prendiamo come esempio quello di un'applicazione per le e-mail: il GUI fornisce
all'utente dei comandi intuitivi, come dei pulsanti, per andare a leggere le email o spostarle
da una cartella all'altra; analogamente un'API fornisce allo sviluppatore delle funzioni per
implementare la sua applicazione, come ad esempio quella per copiare i file da una
locazione all'altra, senza che egli si debba occupare di come il file system gestisce le
operazioni.
Le API sono difatti delle interfacce aperte poste tra lo sviluppatore e i programmi (o parte
di essi) che sarebbero altrimenti inaccessibili, ampliandone le funzionalit iniziali.
Per questa tesi la nostra attenzione andr a concentrarsi sulle API Web: il nostro scopo
quello di fornire un'interfaccia Web che esponga degli endpoints per un sistema basato su
messaggi richiesta-risposta.

IoT
Con il neologismo "Internet of Things" (IoT) si intende un sistema di oggetti fisici che pu
essere esplorato, controllato e col quale si pu interagire mediante l'uso di dispositivi
elettronici che comunicano attraverso varie interfacce di rete. Tale comunicazione pu

2
essere ampliata alla rete Internet.
Grazie allo sviluppo dei sistemi embedded, si potuta realizzare una nuova categoria di
oggetti, detti "Smart Things": si tratta di oggetti fisici che, attraverso l'aggiunta di sensori,
attuatori, interfacce e sistemi di computazione, vengono dotati di una certa intelligenza ( da
cui "Smart").
IoT quellinsieme di tecnologie che portano intelligenza agli oggetti, facendo s che
questi comunichino con noi o tra di loro in modo tale da offrire un nuovo livello di
interazione o di informazione rispetto allambiente in cui questi oggetti si trovano.
Con questa premessa, quindi possibile interfacciarsi e monitorare qualsiasi cosa ci
circondi, integrandovi micro-calcolatori economici ma potenti .
Risulta quindi evidente il "Things" dell'acronimo IoT; per quanto riguarda la parte dell'
"Internet", essa fa riferimento al fatto che applicazioni esterne possano avere acesso agli
oggetti attraverso la rete internet.

Purtroppo oggigiorno non esiste un protocollo universale che permetta di far lavorare
insieme il gran numero di interfacce di rete esistenti: per questo motivo che l'IoT sfocia
nel WoT(Web of Things), al fine di evitare di creare un ulteriore protocollo e sfruttare
invece il Web, essendo esso gi ampiamente diffuso ed utilizzato per costruire moltissime
applicazioni.

3
HCI e wearable computing
Le ricerche HCI (Human-Computer Interaction) si propongono di progettare e sviluppare
tecnologie, concentrandosi in particolar modo sulle interfacce uomo-macchina: lo scopo
quello di studiare le tecnonologie esistenti al fine di svilupparne di nuove che ottimizzino
questa interazione.
L'HCI studia i modi in cui gli esseri umani utilizzano i computer (siano essi general
purpose o embedded, integrati in oggetti di uso comune), concentrando quindi le proprie
ricerche sul miglioramento della facilit di utilizzo della macchina da parte dell'utente,
ovvero sullo svliluppo delle interfacce: queste ultime sono presenti in ogni aspetto della
nostra vita (dalla tastiera e schermo dei pc al touch screen degli smartphone, dai tasti della
lavastoviglie alle GUI) e senza di esse ci sarebbe impossibile interagire coi computer.
Negli ultimi anni si inoltre cercato di rendere questo tipo di comunicazione il pi simile
possibile a quella tra due esseri umani, ovvero verbale: basti pensare agli assistenti vocali,
quali Siri e Cortana, che sono stati dotati di un'intelligenza artificiale tale da permettere al
soggetto umano di interagire col computer semplicemente attraverso l'uso della propria
voce.
Una branca dell'HCI di particolare interesse per questa tesi quella dei wearable
computers: si tratta di dispositivi elettronici di dimensioni assai ridotte, tali da poter essere
indossati o "integrati" nell'abbigliamento.
Qui l'HCI si arricchisce di studi diversi da quelli dell'informazione, per esempio di
anatomia, design, ergonomia, psicologia e sociologia.
Esempi di wearable computers possono essere gli auricolari bluetooth, le scarpe Nike+, i
Google Glasses o gli smartwatch, i quali, oltre a fungere da interfaccia aggiuntiva dello
smartphone, possono sostituire quest'ultimo offrendo le stesse funzioni ( o buona parte di
esse) a "portata di polso".

4
Dominio applicativo
Questa tesi si propone di sviluppare un'API REST per il monitoraggio e controllo delle
funzioni fisiologiche umane, i cui valori vengono acquisiti attraverso l'uso di sensori
biometrici collegati ad una scheda Arduino Uno.
Lo scopo quello di progettare un dispositivo le cui dimensioni siano sufficientemente
ridotte da renderlo portatile, in modo tale da poter essere indossato o integrato in un
accessiorio, ad esempio un cappellino o un marsupio.
Ovviamente la nostra attenzione andr a concentrarsi pi sull'API REST che non sul
dispositivo, in quanto i sensori considerati sono fittizi, e, siccome la trasmissione dei dati al
server avviene per via seriale, la loro acquisizione pu avvenire per mezzo di un qualsiasi
microcontrollore collegato ad uno shield dotato dei sensori adatti.
Tale strumento potrebbe essere in seguito utilizzato per condurre esperimenti e controlli in
ambiti differenti: per esempio, in campo "ludico", si potrebbe pensare di monitorare un
soggetto che gioca ai videogames, magari al fine di ottimizzare alcune parti del gioco
piuttosto che altre a seconda delle reazioni fisiologiche del gamer; si pu anche ragionare
in termini di sicurezza stradale, se si pensa a quanto possa essere importante ed utile
conoscere i parametri vitali di un automobilista per valutarne l'idoneit alla guida.

5
CAPITOLO II
Concetti fondamentali

WoT
Dietro al concetto di Web of things sta il proposito di riutilizzare i protocolli e gli standard
Web disponibili pi diffusi, al fine di rendere pi facilmente accessibili agli sviluppatori
dati e servizi offerti dagli oggetti.
In parole povere, si potrebbe dire che il Web of Things subentra laddove l'Internet of
Things si ferma e inizia a mostrare delle difficolt a causa del problema della gestione dei
vari standard di trasmissione esistenti.
Il World Wide Web viene utlizzato per costruire applicazioni per l'Internet of things: il
WoT consiste proprio nell'uso degli strumenti e delle tecniche che caratterizzano il Web per
lo sviluppo dell' IoT.
Web of Things e Internet of Things presentano caratteristiche differenti. Innanzitutto
mentre uno dei problemi dell'IoT ruotava attorno alle interfacce di rete, il WoT non
presenta questa difficolt, dal momento che si occupa esclusivamente dei protocolli e degli
strumenti a livello di applicazione, consentendo allo sviluppatore di concentrarsi sulla
logica dell'applicazione senza preoccuparsi di come funzionino il dispositivo e la sua
comunicazione.
Un altro aspetto importante sta nelle ridotte prestazioni richieste dai dispositivi su cui si
vuole far girare la API Web: grazie all'ottimizzazione cross-layer TCP/HTTP, i Web server
possono essere implementati su sistemi embedded con soli 8Kb di memoria.
Quest'aspetto fondamentale, poich su di esso che si basano tutte le ricerche di
Wearable Computing e Smart Things: se non fosse possibile dotare di intelligenza gli
oggetti di uso comune mantenendone le dimensioni discrete e contenendo i costi, non
avrebbe nemmeno senso concentrarsi sullo sviluppo di API Web e Web of things.
Riassumendo, nel Web of Things i dispositivi e i servizi da essi offerti sono integrati
completamente col Web dal momento che utilizzano gli stessi standard e tecniche dei
normali siti Web: ci significa che si possono scrivere applicazioni che interagiscono con
dispositivi embedded esattamente nello stesso modo in cui lo farebbero con un qualsiasi

6
altro servizio Web che usa Web APIs (in particolare quelle RESTful).
Questo fatto contribuisce ad alzare il livello di astrazione di cui si era gi parlato
nell'introduzione alle API.

REST
REST (Representational State Transfer) uno stile architetturale utilizzato per lo sviluppo
di applicazioni distribuite e costituisce il fondamento del Web moderno.
Lo scopo di REST quello di creare servizi a basso accoppiamento (coupling), in modo
tale da poter essere riutilizzati facilmente, per esempio attraverso l'uso di URI's e HTTPs.
Se l'architettura di un generico sistema distruibuito segue i principi REST, esso si dice
RESTful. Ci massimizza la scalabilit e l'interoperabilit del sistema, che sono
componenti fondamentali del Web.
Vediamo quali sono i vincoli di REST:
1)CLIENT-SERVER. Le interazioni tra componenti sono basate su uno schema richiesta-
risposta, ovvero un client manda una richiesta ad un server e riceve da esso una risposta.
Ci permette di minimizzare l'accoppiamento tra componenti, dal momento che il client
non necessita di informazioni sulle modalit di funzionamento del server, ma solo sul come
inviare ad esso le richieste per accedere ai dati di interesse.
Analogamente, il server non ha bisogno di conoscere lo stato del client o come esso user i
dati.
2)INTERFACCE UNIFORMI. Il basso accoppiamento tra componenti pu essere
realizzato solamente attraverso l'uso di un'interfaccia uniforme che venga rispettata da tutti
i componenti di tale sistema.
Questo punto essenziale per il funzionamento del WoT, in quanto nuovi e diversi
dispositivi vengono aggiunti e rimossi dal sistema in continuazione: perci importante
limitare tutte le interazioni possibili ad un sottoinsieme limitato di operazioni generiche
ben definite dall'interfaccia uniforme.
3)STATELESS. . La comunicazione clientserver ulteriormente vincolata in modo che
nessun contesto client venga memorizzato sul server. Ogni richiesta da ogni client contiene
tutte le informazioni necessarie per richiedere il servizio, e lo stato della sessione
contenuto sul client. Nonostante ci, lo stato della sessione pu essere trasferito al server

7
attraverso un altro servizio posto a persistere, ad esempio la memorizzazione su database.
4)CACHABLE. La possibilit di caching costituisce un elemento chiave del Web
moderno: si tratta di far si che i clients e i loro intermediari possano salvare alcuni dati
localmente, in modo tale che, se il client necessita nuovamente di essi, non occorra fare il
fetch sul server per ogni futura richiesta. Ci implica un minor numero di interazioni
client-server, che migliora ovviamente le performance del sistema , riducendo la latenza e
migliorando la scalabilit del server.
5)SISTEMA A STRATI. Le interfacce uniformi semplificano la fase di progettazione di
un sistema a strati, ovvero un sistema in cui diverse componenti intermedie nascondono ci
che sta dietro esse: questo vincolo strettamente legato a quello del chaching, in quanto i
sistemi a strati permettono di fare caching in varie zone del mondo, consentendo ai clients
di accedere ad alcuni dati pi rapidamente.

Hypertext transfer protocol


L'hypertext transfer protocol (HTTP) un protocollo a livello di applicativo usato
principalmente nella trasmissione di informazioni sul web.
Il funzionamento di HTTP si basa su un meccanismo richiesta- risposta: il client manda
una richiesta al server, il quale resistuir una risposta. Nell'uso comune di questo
protocollo, il client corrisponde al browser ed il server alla macchina su cui risiede il sito
web desiderato.
A differenza di altri protocolli a livello di applicazione, le connessioni HTTP vengono
chiuse quando la richiesta stata soddisfatta: ci rende HTTP ideale per il World Wide
Web, in cui le pagine spesso contengono link che rimandano ad altre richieste allo stesso
server o ad altri, dal momento che viene limitato il numero di connessioni attive a quello
effettivamente necessario. Questo ovvimanete migliora l'efficienza sia sul client sia sul
server.
Una richiesta HTTP composta da: verbo, URI e versione del protocollo.
L'URI (uniform resrource identifier) indica l'oggetto della richiesta, ovvero la risorsa a cui
si vuole accedere. Vediamo invece quali sono i verbi ( o metodi ) HTTP:
-GET. Con tale metodo, il client richiede al server una rappresentazione della risorsa
specificata dall'URI. Dal momento che la risposta contiene appunto una rappresentazione

8
della risorsa, GET non va ad incidere in alcun modo sulla risorsa stessa. Inoltre N richieste
identiche consecutive, con N>0, daranno sempre lo stesso risultato Questo verbo quindi
sicuro e idempotente.
-HEAD. Il body della richiesta identico a quello del GET, la risposta invece diversa:
essa non contiene il body. L'HEAD quindi preferibile al GET quando si vogliono
recuperare meta-informazioni scritte negli headers della risposta, evitando cos di dover
trasferire l'intero contenuto.
-POST. Attraverso l'uso del POST, il client richiede al server di creare una nuova risorsa
identificata dall'URI. Appare subito chiaro che il POST non un verbo sicuro n
idempotente.
-PUT. Il metodo PUT consente di richiedere al server di modificare una risorsa esistente.
Se tale risorsa esiste, allora verranno attuate le modifiche desiderate, in caso contrario, la
risorsa verr creata ex novo (in questo modo il PUT diventa un POST).
Tale metodo pu essere utilizzato, per esempio, per modificare lo stato di attuatori, i
parametri soglia di regole e cos via. Tale metodo idempotente, ma non sicuro.
-DELETE. Con questo verbo si elimina la risorsa specificata dalla URI. Ovviamente il
DELETE non sicuro, ma solo idempotente.
-PATCH. Il patch permette di applicare alla risorsa richiesta delle modifiche parziali.
Tale metodo non n sicuro n idempotente.
Vi sono altri tre verbi (OPTIONS, CONNECT, TRACE) che per non verranno trattati in
questa tesi.
La prima riga della risposta HTTP viene detta riga di stato ed include un codice di stato
numerico e una frase che lo descrive (es. "Not found").
I codici di stato sono divisi in 5 gruppi principali: 1XX Informazione, 2XX Successo, 3XX
Reindirizzamento, 4XX Errore del client, 5XX Errore del server.

Architettura del sistema


Lo strumento che si occupa dell'acquisizione dei dati una scheda Arduino Uno, a cui
vengono collegati quattro sensori che misurano le funzioni fisiologiche umane:
temperatura corporea, pressione sanguigna, battito caridaco e flusso di aria polmonare.
Tali sensori, in quanto non disponibili fisicamente nella realizzazione di questa tesi, sono

9
stati considerati fittizi e il loro funzionamento analogo a quello di un qualsiasi sensore
ambientale contenuto in un generico kit Arduino. I valori provenienti da essi verrano
esclusivamente simulati dai relativi plugin, ma, nonostante ci, sono gi stati inseriti nel
progetto due parti di codice: 'hardware.ino' e 'arduino.js'. Il primo verr fatto girare sul
dispositivo, e far si che quest'ultimo prelevi i dati dai sensori e li renda disponibili sulla
porta seriale, il secondo funzioner da collegamento tra il dispositivo e il server,
trasferendo i dati provenienti dai sensori e passando al dispositivo le informazioni
contenute nel body delle eventuali operazioni di PUT.

Tutto ci necessario dal momento che il server non viene implementato sulla scheda
Arduino stessa, ma si fatto ricorso ad un Web Socket implementato attraverso l'uso di
Node.js, di cui parleremo pi avanti.
La trasmissione dei dati acquisiti dai sensori attaccati alla scheda avviene per via seriale. I
dati vengono spediti uno dopo l'altro, sotto forma di pacchetti: per questo motivo nel
progetto Arduino 'hardware.ino' viene prima spedito al server il carattere 'H' come header,
seguito dai valori fisiologici rilevati.

10
CAPITOLO III
Progettazione

Durante la fase di progettazione, ci sono 5 step da tenere in considerazione per ottenere dei
buoni risultati.
Strategia di integrazione: opportuno scegliere uno schema adeguato per integrare le
cose col web e con internet.
Progettazione delle risorse: occorre identificare le funzionalit e i servizi offerti da un
oggetto, per poi organizzarli gerarchicamente.
Nel nostro caso, il nodo principale (Root URL) ha come figli i nodi delle regole e quello
dei sensori: questi ultimi hanno come nodi foglia rispettivamente quello per la gestione
delle acquisizioni dati e quelli dei sensori veri e propri (temperatura, pressione, battito
cardiaco e flusso d'aria). Analogamente sono stati organizzati i nodi fogli della regola di
gestione dei sensori, in modo tale da avere un controllo separato su ogni sensore, senza
dover intervenire ogni volta anche sugli altri qualora si volesse modificare lo stato di uno
di essi. Vi infine un controllo anche sul periodo di campionamento.

11
Progettazione delle rappresentazioni: un'altra questione saliente quella riguardante la
scelta del formato della rappresentazione che l'API fornir per ogni risorsa.
In questo progetto si optato per una rappresentazione JSON con possibilit di
conversione in html, con l'accorgimento di fornire di default una rappresentazione JSON
della risorsa nel caso in cui il formato richiesto non corrisponda a nessuno dei due previsti.
Questa scelta mossa da motivazioni ben precise: innanzitutto, sarebbe superfluo
soffermarsi eccessivamente sul formato della rappresentazione per poterne fornire
molteplici, in quanto questo argomento esula dall'obiettivo principale della tesi. Inoltre,
sono stati scelti questi due formati poich HTML (HyperText Markup Language) il
linguaggio pi diffuso per la formattazione e l'impaginazione di documenti nel World Wide
Web, mentre JSON (Javascript Object Notation) il formato pi adatto per lo scambio di
dati tra applicazioni client-server, oltre ad essere sia facilmente comprensibile e scrivibile
dagli esseri umani sia dalle macchine che possono analizzare e generare dati JSON.

// Require the two modules and instantiate a MessagePack encoder


var msgpack = require('msgpack5')();
var json2html = require('node-json2html');

var encode = msgpack.encode;

// In Express, a middleware is usually a function returning a function


module.exports = function() {
return function (req, res, next) {
console.info('Representation converter middleware called!');

// Check if the previous middleware left a result


// in req.result
if (req.result) {

// Read the request header and check if the client requested HTML

12
if (req.accepts('html')) {
console.info('HTML representation selected!');
// If HTML was requested, use json2html to transform the JSON into simple HTML
var transform = {'tag': 'div', 'html': '${name} : ${value}'};
res.send(json2html.transform(req.result, transform));
return;
}

// Read the request header and check if the client requested MessagePack
if (req.accepts('application/x-msgpack')) {
console.info('MessagePack representation selected!');
// Encode the JSON into MessagePack using the encoder
res.type('application/x-msgpack');
res.send(encode(req.result));
return;
}

// For all other formats, default to JSON


console.info('Defaulting to JSON representation!');
res.send(req.result);
return;

}
else {
// If no result was present in req.result,
// theres not much you can do, so call the next middleware
next();
}
}
};

13
Progettazione dell'interfaccia: si decidono i comandi possibili per ogni servizio, ovvero
come possibile manipolare le risorse attraverso l'API REST.
Nel nostro caso, i sensori saranno accessibili solo attraverso il metodo GET, che restituir
nel formato richiesto le infomazioni riguardanti la risorsa . Tale comando disponibile
anche per le regole, o meglio per l'unica implementata, ovvero quella della gestione
dell'acquisizione dei dati. Per questa risorsa inoltre disponibile il PUT, per attuare delle
modifiche sullo stato della regola di ciascun sensore disponibile e sul periodo di
campionamento dei dati.
Progettazione del collegamento tra risorse: si decide come le diverse risorse dovranno
essere collegate tra di loro.

Risorse
Le risorse sono funzionalit o servizi offerti da un oggetto. In questa API, le risorse sono
costituite da sensori e regole: i sensori fanno riferimento ad oggetti fisici che, una volta
collegate alla scheda Arduino Uno, si occupano di raccogliere i valori fisiologici del
soggetto. Per questo le sotto-risorse della route 'sensors' sono i quattro sensori presi in
considerazione per questo progetto: temperatura, battito cardiaco, pressione sanguigna e
flusso d'aria polmonare.
Le regole invece non sono oggetti concreti: della route 'rules' fa parte una sola risorsa,
ovvero 'manage', dal momento che per questo progetto ci siamo concentrati su una sola
regola esemplificativa, ma come essa se ne potrebbero aggiungere altre diverse (per questo
motivo non si eliminato il nodo rules per lasciarvi direttamente manage).
Il 'manage' ha cinque nodi foglia, con rispettivi nomi e valori: quattro booleani, che a
seconda del loro valore determinano se i sensori ad essi associati debbano acquisire i dati
oppure no, mentre il quinto determina il periodo con cui effettuare tale acquisizione.
Per esempio, il client pu decidere di rilevare solamente il valore della pressione, lasciando
le altre risorse all'ultima rilevazione fatta.
Riportato qui di seguito, il codice che organizza le risorse in un unico modello nel progetto
denominato 'resources' (di cui fanno parte sia il il modello stesso che il file JSON vero e
proprio delle risorse).

14
"iot": {
"name": "MyWoT",
"description": "A simple WoT API",
"port": 8484,

"sensors": {
"pressure": {
"name": "Pressure Sensor",
"description": "Blood pressure sensor.",
"unit": "H2O cm",
"value": 0
},
},

"rules": {
"manage": {
"temperature": {
"name": "Temperature Manager",
"value": false
},
"pressure": {
"name": "Pressure Manager",
"value": false
},
"airflow": {
"name": "Air flow Manager",
"value": false
},
"pulse": {
"name": "Pulse Manager",
"value": false

15
},
"period": {
"name": "Period Manager",
"value": 1000
}
}
}
}
}

Azioni
Per questa API REST non sono state previste tutte le azioni possibili, ovvero i metodi
descritti nel capitolo precedente, ma solamente due: GET e PUT.
Il GET , come gi detto, permette accedere ad una rappresentazione della risorsa
richiesta,senza andare ad incidere o a modificare in alcun modo quest'ultima.
Per il nostro scopo infatti fondamentale poter accedere ai dati acquisiti dai sensori oppure
allo stato delle regole, per poterlo eventualmente modificare dopo averne preso visione.
Il seguente codice mostra come viene implementato il GET delle regole, nella sezione
'routes' del progetto (ovviamente il codice riguardante i sensori del tutto simile).

var express = require('express');

var router = express.Router();


var resources = require('./../resources/model');

router.route('/').get(function (req, res, next) {


req.result = resources.iot.sensors;
next();
});
router.route('/manage').get(function (req, res, next) {
req.result = resources.iot.rules.manage;

16
next();
});

router.route('/manage/:id').get(function (req, res, next) {


req.result = resources.iot.rules.manage[req.params.id];
next();
});

Il PUT invece, che permette di cambiare lo stato delle risorse, viene implementato
esclusivamente per la risorsa manage, in quanto non avrebbe senso cercare di forzare una
modifica su un dato proveniente da un sensore.
L'API quindi non fornisce allo sviluppatore la possibilit di creare delle regole, ma
solamente di modificarne una gi esistente, poich, come sottolineato nel capitolo
precedente, per creare una regola, si dovrebbe aggiungere una risorsa attraverso l'uso di un
POST: tuttavia per il nostro scopo sufficiente inserire da subito nel codice la risorsa
'manage', che permette di gestire l'acquisizione dei dati e il suo periodo, consentendo al
client di modificarne i parametri a proprio piacimento e a seconda dell'applicazione.
Gli altri verbi HTTP disponibili potrebbero essere inseriti in seguito, per esempio nel caso
in cui il client fosse interessato alla possibilit di rimuovere una regola attraverso l'uso del
DELETE, di crearne una nuova attraverso un POST, o di applicare delle modifiche parziali
alla risorsa attraverso l'uso di un PATCH.
Analogamente al GET, vediamo la parte di codice riguardante l'implementazione del PUT.

router.route('/manage/:id').put(function(req, res, next) {


var selectedManage = resources.iot.rules.manage[req.params.id];

selectedManage.value = req.body.value;
req.result = selectedManage;
next();
});

17
Web Socket
Il Web Socket una tecnologia Web che fornisce canali di comunicazione full-duplex
utilizzando una sola connessione TCP. Il Web Socket stato progettato per essere
implementato sia lato browser che lato server, ma pu essere utilizzato anche per
applicazioni client-server.
L'obiettivo quello di accedere alle risorse via Web Socket, effettuando un piccolo upgrade
al protocollo.
Innanzitutto occorre installare l'apposito modulo 'ws' fornito da Node.js.
stato creato un Web Socket server e attaccato un ascoltatore al server HTTP principale di
Express per cogliere eventuali richieste di upgrade del protocollo: quando arriva una di
esse, viene usato l'URL di tale richiesta per osservare la corrispondente risorsa nel modello
e, quando si verifica un cambiamento, quest'ultimo viene inviato al client tramite la
connessione Web Socket aperta.
Vediamo come questo si traduce in codice eseguibile.

var WebSocketServer = require('ws').Server;


var resources = require('./../resources/model');

exports.listen = function(server) {
// Create a WebSockets server by passing it the Express server
var wss = new WebSocketServer({server: server});
console.info('WebSocket server started...');

// Triggered after a protocol upgrade when the client connected


wss.on('connection', function (ws) {
var url = ws.upgradeReq.url;
console.info(url);
try {

// Register an observer corresponding to the resource in the protocol upgrade URL


Object.observe(selectResouce(url), function (changes) {

18
ws.send(JSON.stringify(selectResouce(url).value), function () {
});
})
}

// Use a try/catch to catch to intercept errors (e.g., malformed/unsupported URLs)


catch (e) {
console.log('Unable to observe %s resource!', url);
};
});
};
// This function takes a request URL and returns the corresponding resource
function selectResouce(url) {
var parts = url.split('/');
parts.shift();
var result = resources;
for (var i = 0; i < parts.length; i++) {
result = result[parts[i]];
}
return result;
}

A questo punto non resta che inizializzare il Web Socket server dopo aver avviato il server
HTTP.

var httpServer = require('./servers/http');


var resources = require('./resources/model');
var wsServer = require('./servers/websockets');

var server = httpServer.listen(resources.iot.port, function () {


console.info('Your WoT Pi is up and running on port %s', resources.iot.port);

19
});

// Websockets server
wsServer.listen(server);

Applicazioni client
Per sua natura, una API non ha un utente "umano", ma piuttosto un altro software,
chiamato appunto applicazione client.
Si potrebbero creare delle applicazioni che permettano all'essere umano di fare uso delle
API in maniera pi human-friendly rispetto ad altre, quali Postman, creata da Google allo
scopo di rendere pi agevole la fase di sviluppo e di testing delle API.
Un possibile esempio potrebbe essere quello di un app per smartphone o per smartwatch
che permetta di monitorare dal propio dispositivo mobile i valori delle funzioni
fisiologiche acquisiti, di gestire le regole semplicemente selezionando o deselezionando i
sensori e inserendo il periodo di campionamento desiderato, oppure di ricevere delle
notifiche nel caso in cui i dati rilevati presentino qualche anomalia: basti pensare all'utili
di un'applicazione che permetta di avvisare il client quando il soggetto che indossa il
dispositivo ha dei parametri vitali fuori norma, che possono indicare un malore o un arresto
cardiaco.
L'obiettivo di questa tesi la creazione dell'API, non dell'applicazione client, quindi non ci
soffermeremo sullo sviluppo di quest'ultima, ma possiamo vederne un semplice esempio
implementato in C#.
Si creata una Windows Form Application dotata di quattro pulsanti e altrettanti textboxes
e labels: ad ogni pulsante corrisponde un sensore, e quando ci si clicca sopra, il suo valore
aggiornato appare sul text box corrispondente, le etichette invece sono solo accessorie, in
quanto indicano l'unit di misura del dato proveniente dal sensore. Quindi ad ogni
pressione di uno dei quattro bottoni corrisponde un GET fatto sullla risorsa desiderata: per
realizzare ci, stata creare una classe Server.cs, senza attributi n costruttori, ma con un
solo metodo statico 'GetMethod' (per semplicit stato omesso il metodo PUT, ma pu
essere aggiunto alla classe in qualsiasi momento) che prende in ingresso una stringa e
resituisce nuovamente una stringa corrispondente al valore numerico del dato.

20
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net;

namespace IoTAPI
{
public class Server
{
public static string GetMethod(string uri)
{
try
{
WebRequest request = WebRequest.Create(uri);
WebResponse response = request.GetResponse();
// Get the stream containing content returned by the server.
Stream dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
string complete = responseFromServer;
// Clean up the streams and the response.
reader.Close();
response.Close();

string result = string.Empty;


for (int i = 0; i < complete.Length; i++)

21
{
if (Char.IsDigit(complete[i]))
{
result += complete[i];
}
}
return result;
}
catch
{
return "Error: no server";
}
}
}
}

L'input di tale metodo viene fornito dalla classe che contiene il codice di funzionamento
della WFA, che varia a seconda della risorsa di cui si richiede una rappresentazione, e
l'ouput viene rimandato alla textbox corrispondente.

private void button1_Click(object sender, EventArgs e)


{
textBox1.Text = Server.GetMethod("http://localhost:8484/iot/sensors/temperature");
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}

Lanciando il file .exe di questo progetto, l'utente visualizzer solamente una finestra di
dialogo con le funzionalit sopra citate.

22
Appare subito evidente come un'applicazione di questo tipo, sebbene esponga le
funzionalit minime fornite dall'API e abbia un'implementazione grafica minimalista, sia
gi utilizzabile da un utente umano per visualizzare i dati acquisiti dal dispositivo
biometrico.

23
CAPITOLO IV
Implementazione

Abbiamo gi descritto la fase di progettazione delle risorse, seguendo uno schema


gerarchico: vediamo ora come implementare il server.
Occorre innanzitutto creare un Modello delle Risorse, trasponendo la struttura ad albero
creata in precedenza in un file JSON che viene utilizzato nel codice per esporre la struttura
URL corretta.

"sensors": {
"temperature": {
"name": "Temperature Sensor",
"description": "An ambient temperature sensor.",
"unit": "celsius",
"value": 0
}

Il modello andr quindi importato nel codice per poter essere utilizzato.
Il passo successivo consiste nella creazione di routes Express, attraverso le quali si
vincolano le regole e i sensori agli URLs ai quali questo Web server risponder.
Occorre quindi creare due file nella cartella delle routes: uno per i sensori e l'altro per le
regole.
Questo ovviamente non sufficiente, in quanto mancano i dati reali proveninenti dal
mondo esterno: si creano tanti plugin quanti sono i sensori e le regole (nel nostro caso
cinque) e ognuno di questi aggiorna il modello ogni volta che sui sensori vengono letti
nuovi dati o viene modificata la regola di gestione degli stessi.

var resources = require('./../resources/model');


var interval, sensor;

24
var model = resources.iot.sensors.pulse;
var pluginName = resources.iot.sensors.pulse.name;
var unit = resources.iot.sensors.pulse.unit;
var localParams = {'simulate': true, 'frequency': 2000};

I plugin vengono dotati delle seguenti funzioni:


-start(). Questa funzione consente l'avvio del plugin in modo tale da poter essere
accessibile da altri file ed essere esportato. Se si optato per simulare i dati acquisiti dai
sensori, esso chiamer la funzione simulate(), altrimenti connectHardware().

exports.start = function (params) {


localParams = params;
if (localParams.simulate) {
simulate(); }
else {
connectHardware();
}
};

-stop(). In modo duale alla precedente, con questa funzione si blocca l'acesso di altri file al
plugin.

exports.stop = function () {
if (localParams.simulate) {
clearInterval(interval);
} else {
sensor.unexport();
}
console.info('%s plugin stopped!', pluginName);
};

25
-connectHardware(). Questa funzione permette di connettere il driver dell'hardware vero
e proprio e di configurarlo. I dati vengono raccolti dai sensori della scheda arduino su cui
stato caricato l'apposito codice del file .ino: attraverso file javascript 'arduino.js', Node.Js
acquisisce questi dati tramite la porta seriale indicata. Da qui, infine il modello viene
aggiornato con i nuovi valori.
Viene qui riportato l'esempio per il plugin legato al sensore del battito cardiaco.

function connectHardware() {
var arduino = require('./../hardware/arduino');
interval = setInterval(function () {
model.value = arduino.BMP;
}, localParams.frequency);
console.info('Hardware %s sensor started!', pluginName);
};

-simulate(). Questa funzione molto importante soprattutto in fase di scrittura del codice,
in quanto permette di simulare i valori dei dati provenienti dai sensori, permettendo allo
sviluppatore di concentrarsi sull'API senza doversi preoccupare del dispositivo hardware
che dovr essere collegato al pc.

function simulate() {
interval = setInterval(function () {
model.value += 1;
showValue();
}, localParams.frequency);
console.info('Simulated %s sensor started!', pluginName);
};

Vi infine una funzione accessoria showValue() che permette di visualizzare i dati sulla
console che si sta utilizzando.
L'ultimo step di questa fase consiste nell'integrare i plugins nel server tramite l'istruzione

26
'require' e avviarli.

var tempPlugin = require('./plugins/tempPlugin');


tempPlugin.start({'simulate': true, 'frequency': 1000});

Fatto ci, bisogna caricare le routes su un server HTTP e creare un entry point per avviarlo.

var express = require('express');


var actuatorsRoutes = require('./../routes/rules');
var sensorRoutes = require('./../routes/sensors');
var resources = require('./../resources/model');
var converter = require('./../middleware/converter');
-------------------------------------------------------------------
var express = require('express');
var router = express.Router();
var resources = require('./../resources/model');

var server = httpServer.listen(resources.iot.port, function () {


console.info('Your WoT Pi is up and running on port %s', resources.iot.port);
});
// Websockets server
wsServer.listen(server);

Strumenti utilizzati

Node.js
Node.js una piattaforma che offre un'architettura event-driven e un'API di input/output
non bloccante che ottimizza il throughput e la scalabilit di un'applicazione. Esso si basa
sul motore Google V8 Javascript, che rappresenta il cuore del browser Chrome.

27
L'idea che sta dietro a Node quella di fornire un framework sul quale possano girare
applicazioni Web lato server ad alte prestazioni.
Il modello di networking su cui si basa Node.js I/O event-driven, ovvero Node richiede al
sistema operativo di ricevere notifiche al verificarsi di determinati eventi, per poi rimanere
in attesa fino all'arrivo della notifica stessa: quando ci si verifica, Node "torna attivo" per
eseguire le istruzioni previste nella funzione di callback, cos chiamata perch da eseguire
una volta ricevuta la notifica che il risultato dell'elaborazione del sistema operativo
disponibile.
Nonostante Node sia una cosa diversa da Javascript e si possano usare altri linguaggi,
Javascript quello pi usato per scrivere applicazioni che girino su questo framework.
Node fornisce inoltre dei moduli per estendere le proprie funzionalit: attraverso la
keyword 'require' si possono rendere attivi, esattamente come si includono le librerie in
programmi C#.
I moduli utilizzati per la realizzazione dell'API REST sono i seguenti:
-http, per poter effettuare richieste HTTP.
-serialport, consenste di importare i dati provenienti dalla porta serial desiderata
-msgpack5, si tratta di un efficiente formato per la serializzazione binaria. Come JSON ,
permette lo scambio di dati tra linguaggi diversi, ma in maniera pi veloce e leggera.
-node-json2html, questo modulo implementa il meccanismo di conversione dal formato
JSON ad HTML.
A differenza di altre piattaforme, come ad esempio Microsoft Visual Studio, Node molto
leggero, quindi adatto a girare anche su dispositivi poco potenti e con poca memoria
(ovviamente se comparati ai personal computer).

Express
Rilasciato come software open-source sotto la licenza MIT, Express un framework per
applicazioni web di Node.js flessibile e leggero che fornisce una serie di funzioni avanzate.
Una delle sue peculiarit quella di fornire allo sviluppatore metodi di utilit HTTP e
middleware, semplificando e rendendo pi efficiente ed agevole la creazione di APIs.

28
Visual Studio Code
Visual Studio Code un editor di codice sorgente sviluppato da Microsoft che offre
supporto per il debugging, refactoring del codice ed intellisense. Visual Studio Code si
basa su Electron, un framework utilizzato per far girare applicazioni di Node.js. Questo
strumento si rivelato particolarmente utile in fase di implementazione dell'API REST, in
quanto, oltre ad evidenziare gli errori di sintassi, segnalava anche le eccezioni lanciate dal
programma in caso di errori, permettendo attraverso lo stack di chiamate a funzione a
risalire al baco ed eliminarlo, cosa che sarebbe stata assai pi difficile se per lanciare l'API
si fosse dovuto ricorrere al prompt dei comandi del pc.

29
CAPITOLO V
Conclusioni e sviluppi futuri

Abbiamo quindi visto una API REST per il controllo di funzioni fisiologiche e una
semplice applicazione client per poterne visualizzare i risultati in maniera human-friendly.
I dati vegono resi disponibli attraverso la porta locale 8484: si potrebbe rendere pi
efficiente l'API se si disponesse di uno spazio web.
Come gi detto, i sensori presi in considerazione in questa tesi sono fittizi, in quanto non
fisicamente disponibili per il progetto, considerando il loro funzionamento analogo a
quello di un generico sensore presente in un qualsiasi kit Arduino.
Tuttavia, si sono tenuti in considerazione i servizi e le funzionalit offerte da e-Health, la
cui nuova versione stata rilasciata nell'agosto del 2013 da Cooking Haks: si tratta di uno
shield biometrico che, grazie anche al lavoro svolto dalla Community attraverso la
realizzazione di numerosi progetti, ha migliorato i sensori gi presenti nella scheda e ne ha
aggiunti di nuovi.

30
I sensori attualmente disponibili sono in tutto dieci: battito cardiaco, saturimetro, flusso
d'aria (respiro), temperatura corporea, elettrocardiogramma, glucometro, attivit
elettrodermica, pressione sanguigna, accelerometro (per rilevare la posizione del soggetto)
ed elettromiografia muscolare (EMG).
Questo shield compatibile con Arduino e Raspberry-Pi: le informazioni raccolte dai
sensori possono essere utilizzate per monitorare in tempo reale le funzioni fisiologiche di
un individuo o per essere analizzate in seguito (a questo proposito si pu pensare a salvare
i dati acquisiti o attraverso servizi Cloud o su una micro SD integrata sulla scheda che si
andr ad utilizzare). I valori rilevati, attraverso l'API REST realizzata per questa tesi,
possono essere resi disponibili sul web attraverso differenti tipi di connessioni wireless,
quali Wi-Fi, 3G e GPRS.
Come gi accennato, Node.js una piattaforma sufficientemente leggera, sebbene ad alte
prestazioni, tale da poter girare anche su microcontrollori come Raspberry-Pi (Arduino non
ha la memoria n la potenza sufficiente a supportarlo), permettendo cos di ottenere dei
dispositivi che, altre a rilevare le funzioni fisiologiche, possano fungere essi stessi da
server, mantenendo pur sempre un costo contenuto di poche decine di dollari.

Si pu inoltre pensare a realizzare un server implementato direttamente su una scheda


Arduino che comunica con l'esterno attraverso l'uso di uno shield Wi-Fi e della libreria
'Wifi.h', tuttavia lo strumento sicuramente non sarebbe altrettanto efficiente: potrebbe
sicuramente fornire la funzionalit del GET sul proprio indirizzo IP, ma probabilmente

31
implementare il PUT e tutti gli altri verbi HTTP non sarebbe agevole come lo stato
utilizzando Node.js.
Per quanto riguarda il fine dell'API REST implementata per questa tesi, si partiti
inizialmente dall'idea che il dispositivo dovesse servire a monitorare le funzioni
fisiologiche di un soggetto umano alla guida o intento a giocare ai videogames.
Soffermiamoci sul primo caso: si potrebbe pensare, tecnologie permettendo, di integrare i
sensori atti a rilevare le funzioni vitali principali nel volante e nel sedile del guidatore,
nonch un eventuale sensore di prossimit in corrispondenza del clacson che monitori lo
spostamento della testa del soggetto per rilevare i segnali di un colpo di sonno.
Appare chiaro quanto un apparecchio del genere possa essere importante per garantire la
sicurezza del guidatore e di chi gli sta intorno: se l'API venisse utilizzata da
un'applicazione sviluppata appositamente per l'automobile che abbia accesso ad alcuni
controlli dell'auto (ad esempio la frenata, una manovra, le quattro frecce o lo spegnimento
del motore), qualora venissero rilevati valori biometrici anomali, si potrebbero sicuramente
prevenire dei possibili incidenti.

32
CAPITOLO VI
Bibliografia e sitografia

Building the Web of Things - Dominique D. Guinard e Vlad M. Trifa, editore


Manning
Interaction design fundation - https://www.interaction-design.org/
e-Health Sensor Platform V2.0 for Arduino and Raspberry Pi [Biometric / Medical
Applications] - https://www.cooking-hacks.com/documentation/tutorials/ehealth-
biometric-sensor-platform-arduino-raspberry-pi-medical
Learn REST: a RESTful tutorial - http://www.restapitutorial.com/
https://nodejs.org/en/

33

Potrebbero piacerti anche