Creazione del terzo esempio: trasmissione di alcune informazioni dell’occupazione del suolo tramite dispositivo Bluetooth.
In questo terzo esempio, per verificare l’occupazione dell’area del suolo pubblico, si è pensato di utilizzare un Beacon Bluetooth con relativo ricevitore. L’obiettivo è quello di capire quando il richiedente/utente che ha eseguito la richiesta di occupazione del suolo è realmente presente in quest’area. Al Beacon è associato un ID univoco proprio del dispositivo. In virtù di tale caratteristica, il Beacon può essere installato sui veicoli (nell’ipotesi di area di mercato) dei commercianti (i famosi richiedenti del portale delle richieste) che occuperanno il suolo pubblico ai fini di mercato, manifestazione o altra attività di interesse. L’ID univoco del Beacon sarà attribuito alla persona (commerciante/richiedente) che di fatto occuperà l’area, quindi a un entità Persona presente all’interno del RDBMS della nuova piattaforma di gestione del suolo pubblico già tratta precedentemente. In teoria, nel momento in cui il veicolo verrà rilevato dal ricevitore nella data prevista dalla richiesta eseguita nel portale delle istanze delle richieste, verrà, attribuito all’ID_AREA, o a più aree (più ID_AREA), la presenza in tempo reale del commerciante. Le informazioni relative all’occupazione dell’area verranno trasmesse tramite il ricevitore associato al Beacon e inviate tramite API relativa alla nuova piattaforma di occupazione del suolo. Il ricevitore può essere associato a più Beacon in questo modo si possono attuare delle logiche di ridondanza del segnale nel caso di uno o più ricevitori.
E’ importante, che il ricevitore Bluetooth dovrà possedere un ambiente di programmazione (per ipotesi Python, ma potrebbe essere anche Java o qualsiasi altro linguaggio) per l’invio delle informazioni all’API. Inoltre, dovrà avere la possibilità di inviare e gestire l’autenticazione con protocollo OAUTH2 (nel contesto reale), ma vediamo di seguito quali informazioni dovranno essere trasmesse.
Per prima cosa, realizziamo l’API che mi permetterà di inviare le informazioni relative al Beacon rilevato. Al contrario di prima utilizzeremo un database relazionale SQLite per memorizzare le informazioni delle rilevazioni del sensore. Come per gli esempi precedenti utilizzeremo NodeJS come server per distribuire l’API per la registrazione delle informazioni del sensore, l’autenticazione JWT (in questo caso, utilizziamo una SECRET KEY implementata, ma nel caso in produzione il tutto avviene con autenticazione OAUTH2).
L’immagine precedente mostra chiaramente quali sono i soggetti coinvolti nel terzo esempio e come funziona l’utilizzo dell’API e dei dispositivi Bluetooth coinvolti. Non descrivo in modo approfondito i passaggi del diagramma di sequenza come fatto precedente perché il digramma di sequenza è molto chiaro.
Di seguito troverete il codice in NodeJS che realizzerà l’API di comunicazione con i dispositivi Bluetooth.
const express = require('express');
const jwt = require('jsonwebtoken');
const bodyParser = require('body-parser');
const sqlite3 = require('sqlite3').verbose();
const app = express();
const port = 3000;
const SECRET_KEY = '23829382839283@@__woeiowieL';
// Creazione del database SQLite nella directory del progetto
const db = new sqlite3.Database('./OccupaSuolo.sqlite3');
// Inizializzazione del database
db.serialize(() => {
db.run("CREATE TABLE IF NOT EXISTS sensore (idUnivoco TEXT, dataRilevazione TEXT)");
});
app.use(bodyParser.json());
// Middleware per la verifica del token
const verifyToken = (req, res, next) => {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if (!token) return res.sendStatus(401);
try {
const decoded = jwt.verify(token, SECRET_KEY);
req.user = decoded;
next();
} catch (error) {
return res.sendStatus(403);
}
};
app.use(verifyToken);
// Endpoint per registrare la rilevazione del Beacon
app.post('/rilevazione', (req, res) => {
const { idUnivoco, dataRilevazione } = req.body;
const stmt = db.prepare("INSERT INTO sensore (idUnivoco, dataRilevazione) VALUES (?, ?)");
stmt.run(idUnivoco, dataRilevazione, (err) => {
if (err) {
res.status(500).json({ message: 'Errore durante la registrazione della rilevazione.' });
} else {
res.json({ message: 'Rilevazione registrata con successo!' });
}
});
stmt.finalize();
});
app.listen(port, () => {
console.log(`Server in ascolto su http://localhost:${port}`);
});
Come si vede, nelle prime quattro righe di codice si “caricano” i moduli Express, Jsonwebtoken, Body-parser, e Sqlite3. Sottolineo ancora, come da linea di comando dalla cartella di progetto si possono installare i moduli con la seguente istruzione: “npm install express jsonwebtoken body-parser sqlite3“.
Nelle righe dalla sei alla otto viene valorizzata l’istanza di Express nella costante “app“; Si attribuisce alla costante “port” il valore di 3000 (porta utilizzata dal server Web). Infine, nell’ultima riga si definisce la costante “SECRET_KEY“. Questa chiave segreta statica viene definita per firmare e verificare i token JWT. Questa chiave dovrebbe essere mantenuta segreta e per nessun motivo pubblicata. E’ ovvio che in produzione non può essere presente una soluzione del genere come già spiegato.
Nella riga undici si crea un database SQLite nella directory di progetto dal nome “OccupaSuolo.sqlite3“. Se il file esiste già, verrà utilizzato, altrimenti ne verrà creato uno nuovo.
Nelle righe dalla quattordici alla sedici viene creata una tabella chiamata “sensore” con l’attributo per l’ID univoco del Beacon e la data di rilevazione. La tabella verrà creata se non esiste già.
Nella riga diciotto il middleware “body-parser” viene utilizzato per analizzare il corpo delle richieste HTTP in formato JSON.
Dalla riga venti alla riga trentaquattro viene costruito il middleware verifyToken. Questa funzione viene eseguita prima di ogni richiesta al server. Il suo scopo è di verificare la presenza e la validità del token JWT fornito con la richiesta.
La riga trentasei esplicita il fatto che il middleware “verifyToken” venga applicato a tutte le richieste al server.
Dalla riga trentotto alla riga cinquanta si crea l’endpoint per salvare la rilevazione del Beacon. Questo endpoint accetta richieste POST per registrare una nuova rilevazione. Si procede ad Estrarre l’ID univoco e la data di rilevazione dal corpo della richiesta e si inseriscono questi dati nella tabella sensore del database SQLite.
Nelle righe dalla cinquantadue alla cinquantaquattro si avvia il server Express che inizia ad ascoltare sulla porta 3000 come definito precedentemente nei codici del primo e secondo esempio.
Per quanto riguarda la parte dell’API sul server Express dovrebbe essere tutto chiaro o quasi, ora sviluppiamo la parte del client in Python.