Introduzione alla seconda parte della guida: Configurazione del broker MQTT e creazione di un’app di controllo per smartphone con Flutter
Ecco la seconda puntata della nostra guida pratica per la creazione di una mini infrastruttura per i propri dispositivi smart! Nella prima parte della guida IoT e smart home, abbiamo esplorato i concetti fondamentali della comunicazione remota con i dispositivi smart, i vari protocolli di comunicazione disponibili e l’importanza dei database nella gestione dei dati dei dispositivi IoT. Abbiamo anche introdotto Firebase Firestore come database e il broker MQTT come componente chiave del nostro sistema di controllo remoto.
In questa seconda puntata, ci addentreremo nei dettagli tecnici della configurazione del broker MQTT e della creazione di un’app di controllo per smartphone utilizzando Flutter, un framework di sviluppo app molto popolare.
Configurazione di un broker MQTT sicuro con Mosquitto su Raspberry Pi
MQTT (Message Queuing Telemetry Transport) è un protocollo di messaggistica leggero e di bassa latenza, progettato specificamente per l’Internet delle Cose (IoT) e le applicazioni M2M (Machine-to-Machine). La sua efficienza energetica e la facilità d’uso lo rendono la scelta ideale per connettere una vasta gamma di dispositivi, dai sensori ai sistemi di automazione domestica. Tuttavia, con l’aumento delle minacce alla sicurezza e dei rischi associati all’IoT, è essenziale garantire che le comunicazioni tra i dispositivi e il broker MQTT siano protette e sicure.
Seguendo questa guida passo-passo, avrai una solida base per comprendere le sfide e le soluzioni legate alla sicurezza delle comunicazioni IoT. Imparerai come proteggere il tuo broker MQTT e i dispositivi connessi da potenziali minacce, garantendo al contempo un’esperienza utente fluida e senza interruzioni. Quindi, immergiti e scopri come trasformare il tuo Raspberry Pi in un broker MQTT sicuro, affidabile e facilmente accessibile da qualsiasi luogo.
Installazione e configurazione di Mosquitto su Raspberry Pi per un broker MQTT sicuro ed affidabile
Prima di immergerci nel mondo della sicurezza MQTT, è fondamentale installare e configurare correttamente Mosquitto, il popolare broker MQTT, sul tuo Raspberry Pi. In questa sezione, ti guideremo attraverso i passaggi necessari per avere Mosquitto in esecuzione sulla tua piattaforma Raspberry Pi, ponendo le basi per una solida infrastruttura IoT.
Aggiornare il sistema e installare Mosquitto
Per iniziare, assicurati di avere un Raspberry Pi aggiornato con l’ultimo sistema operativo (come Raspberry Pi OS) e connesso ad internet tramite Wi-fi o connessione Ethernet. Successivamente, segui questi passaggi per installare Mosquitto:
1. Apri il terminale sul tuo Raspberry Pi.
2. Esegui un aggiornamento e un upgrade del sistema con i seguenti comandi:
sudo apt update
sudo apt upgrade
3. Installa Mosquitto con il comando:
sudo apt install -y mosquitto mosquitto-clients
4. Abilita e avvia Mosquitto per eseguirlo all’avvio del sistema:
sudo systemctl enable mosquitto
sudo systemctl start mosquitto
Test funzionamento del broker MQTT
Una volta installato Mosquitto, è possibile testare il funzionamento del broker utilizzando i client MQTT inclusi nel pacchetto di installazione. Apri due terminali separati sul tuo Raspberry Pi e, in uno, esegui il comando per sottoscrivere un topic di test:
mosquitto_sub -h localhost -t test_topic
Nell’altro terminale, pubblica un messaggio su quel topic:
mosquitto_pub -h localhost -t test_topic -m "Hello, MQTT!"
Se il messaggio “Hello, MQTT!” viene visualizzato nel terminale con il client in sottoscrizione, il broker MQTT Mosquitto è stato installato e configurato correttamente sul tuo Raspberry Pi. Ora che abbiamo il nostro broker MQTT funzionante, è il momento di configurarlo per l’accesso remoto sicuro e protetto.
Configurazione del port forwarding e del Dynamic DNS per l’accesso remoto al broker MQTT
Per accedere al tuo broker MQTT Mosquitto da qualsiasi rete esterna, è necessario configurare il port forwarding sul tuo router e utilizzare un servizio Dynamic DNS (DDNS) per gestire gli indirizzi IP pubblici dinamici. In questa sezione, esamineremo come configurare entrambe queste funzionalità per garantire un accesso remoto senza problemi al tuo broker MQTT.
Il port forwarding consente ai dispositivi esterni di raggiungere il tuo broker MQTT attraverso il router. Per configurare il port forwarding, dovrai accedere all’interfaccia di amministrazione del tuo router. Consulta il manuale del tuo router o il sito del produttore per istruzioni su come accedere e accedere al pannello di amministrazione.
In seguito, cerca le impostazioni del port forwarding (spesso chiamate “Virtual Server”, “Applications” o “Port Mapping”) e crea una nuova regola di port forwarding con le seguenti impostazioni:
- Protocollo: TCP
- Porta esterna (o “Porta WAN”): 1883 (porta predefinita MQTT) o 8883 (se utilizzi SSL/TLS)
- Indirizzo IP interno (o “IP LAN”): l’indirizzo IP del tuo Raspberry Pi nella rete locale
- Porta interna (o “Porta LAN”): la stessa porta esterna (1883 o 8883)
Per finire, salva le impostazioni e riavvia il router, se necessario.
Impostazione del Dynamic DNS (DDNS): Utilizzare un servizio DDNS per associare un nome di dominio al tuo indirizzo IP pubblico dinamico.
Dopo aver configurato il port forwarding, è necessario impostare un servizio DDNS per gestire gli indirizzi IP pubblici dinamici assegnati dal tuo ISP:
- Scegli un servizio DDNS, come No-IP, DuckDNS o DynDNS, e registrati per un account gratuito o a pagamento.
- Crea un nuovo hostname (ad esempio, “your_mqtt_broker.ddns.net”) e associa il tuo indirizzo IP pubblico corrente all’hostname.
- Configura il tuo router o Raspberry Pi per aggiornare automaticamente il servizio DDNS ogni volta che il tuo indirizzo IP pubblico cambia. La maggior parte dei router moderni ha una funzione DDNS integrata. Se il tuo router non supporta il DDNS o preferisci configurare il Raspberry Pi, puoi utilizzare uno script o un software come `ddclient` per aggiornare il servizio DDNS.
Ora che il port forwarding e il DDNS sono configurati, il tuo broker MQTT Mosquitto dovrebbe essere accessibile da qualsiasi rete esterna utilizzando il nome di dominio fornito dal servizio DDNS. Tuttavia, prima di iniziare a utilizzare il broker MQTT da remoto, è fondamentale implementare la crittografia e l’autenticazione per proteggere le tue comunicazioni e i tuoi dispositivi.
Proteggere il broker MQTT con crittografia SSL/TLS e autenticazione
Per garantire che le comunicazioni tra il broker MQTT e i client siano protette, è necessario implementare la crittografia SSL/TLS e l’autenticazione degli utenti. In questa sezione, ti guideremo attraverso il processo di configurazione della crittografia e dell’autenticazione per il tuo broker MQTT Mosquitto su Raspberry Pi.
Configurazione della crittografia SSL/TLS:
La crittografia SSL/TLS garantisce che i dati trasmessi tra il broker MQTT e i client siano protetti e al sicuro da intercettazioni e attacchi “man-in-the-middle”. Per configurare SSL/TLS su Mosquitto, segui questi passaggi:
1. Installa `openssl` sul tuo Raspberry Pi, se non è già presente:
sudo apt install openssl
2. Crea una nuova cartella per memorizzare i certificati e le chiavi SSL/TLS:
sudo mkdir /etc/mosquitto/certs
3. Crea un certificato di autorità di certificazione (CA) e una coppia di chiavi per il server:
sudo openssl req -new -x509 -days 3650 -extensions v3_ca -keyout /etc/mosquitto/certs/ca.key -out /etc/mosquitto/certs/ca.crt
4. Crea una chiave privata per il server e una richiesta di firma del certificato (CSR):
sudo openssl genrsa -out /etc/mosquitto/certs/server.key 2048
sudo openssl req -new -out /etc/mosquitto/certs/server.csr -key /etc/mosquitto/certs/server.key
5. Crea e firma il certificato del server utilizzando la CA e la CSR:
sudo openssl x509 -req -in /etc/mosquitto/certs/server.csr -CA /etc/mosquitto/certs/ca.crt -CAkey /etc/mosquitto/certs/ca.key -CAcreateserial -out /etc/mosquitto/certs/server.crt -days 3650
6. Modifica il file di configurazione di Mosquitto (`/etc/mosquitto/mosquitto.conf`) per utilizzare i certificati e le chiavi SSL/TLS appena creati:
listener 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
7. Riavvia Mosquitto per applicare le modifiche:
sudo systemctl restart mosquitto
Configurazione dell’autenticazione:
L’autenticazione impedisce l’accesso non autorizzato al broker MQTT, proteggendo le tue comunicazioni e i tuoi dispositivi IoT. Per configurare l’autenticazione su Mosquitto, segui questi passaggi:
1. Crea un file con nome utente e password per l’autenticazione:
sudo touch /etc/mosquitto/passwd
2. Aggiungi un nome utente e una password al file (sostituisci “your_username” e “your_password” con le credenziali desiderate):
sudo mosquitto_passwd -b /etc/mosquitto/passwd your_username your_password
3. Modifica il file di configurazione di Mosquitto (`/etc/mosquitto/mosquitto.conf`) per utilizzare il file delle password appena creato:
allow_anonymous false
password_file /etc/mosquitto/passwd
4. Riavvia Mosquitto per applicare le modifiche:
sudo systemctl restart mosquitto
Con la crittografia SSL/TLS e l’autenticazione configurate, il tuo broker MQTT Mosquitto su Raspberry Pi ora dovrebbe essere protetto e sicuro per l’accesso da qualsiasi parte del mondo. Assicurati di aggiornare le impostazioni dei client MQTT per utilizzare il nome di dominio DDNS, la porta 8883 e le credenziali SSL/TLS e di autenticazione appropriate.
Monitoraggio e manutenzione del broker MQTT per un’esperienza ottimale
Una volta configurato il tuo broker MQTT Mosquitto in modo sicuro ed affidabile, è importante monitorare e mantenere il sistema per garantire prestazioni ottimali e prevenire eventuali problemi di sicurezza. Di seguito sono riportati alcuni suggerimenti per la manutenzione del broker MQTT:
1. Tieni d’occhio i log di Mosquitto per individuare eventuali problemi o attività sospette. I log di Mosquitto possono essere trovati in `/var/log/mosquitto/`.
2. Esegui regolarmentefir gli aggiornamenti del sistema operativo e del software del tuo Raspberry Pi per garantire l’installazione delle patch di sicurezza più recenti.
3. Monitora il traffico della rete e l’utilizzo delle risorse sul tuo Raspberry Pi per identificare eventuali problemi di prestazioni o tentativi di attacco.
4. Effettua regolarmente backup dei file di configurazione e delle credenziali di Mosquitto, in modo da poter ripristinare rapidamente il sistema in caso di guasto del dispositivo o perdita di dati.
5. Considera l’implementazione di misure di sicurezza aggiuntive, come un firewall, per proteggere ulteriormente il tuo broker MQTT e la rete domestica.
In questa prima parte della guida, abbiamo esplorato come configurare un broker MQTT Mosquitto su Raspberry Pi per l’accesso sicuro e affidabile da qualsiasi rete esterna. Abbiamo discusso l’importanza della crittografia, dell’autenticazione, del port forwarding e del DDNS per proteggere le comunicazioni IoT e garantire un’esperienza utente ottimale. Seguendo questi passaggi, sarai in grado di monitorare e gestire i tuoi dispositivi IoT da qualsiasi luogo, con la tranquillità che le tue comunicazioni sono protette e al sicuro.
Creazione di un’app di controllo IoT personalizzata con Flutter, Firebase e Firestore
Nella seconda sezione della nostra guida, esploreremo come creare un’app personalizzata per il controllo dei dispositivi IoT e di smart home utilizzando Flutter.
Flutter è un framework di sviluppo UI open source creato da Google che consente di creare applicazioni per dispositivi mobili, web e desktop con un unico codice sorgente. Nel corso di questa guida, discuteremo i vantaggi di Flutter, la sua integrazione con Firebase e Firestore e come creare un’app di controllo remoto per i relè utilizzando l’autenticazione dell’utente.
Cos’è Flutter e perché usarlo per il controllo IoT
Flutter è un framework sviluppato da Google che permette di creare interfacce utente attraenti e performanti multipiattaforma, come Android, iOS, web e desktop, utilizzando un singolo linguaggio di programmazione e un unico codice sorgente. Utilizza il linguaggio di programmazione Dart e fornisce un insieme di widget, animazioni e gesture predefiniti che facilitano la creazione di interfacce utente personalizzate e di alta qualità.
Alcuni vantaggi nell’utilizzo di Flutter per lo sviluppo di app di controllo IoT sono:
1. Sviluppo multipiattaforma: scrivi una volta il codice e l’app funzionerà su Android, iOS e web, facilitando la manutenzione e riducendo i costi di sviluppo.
2. Supporto della community: Flutter gode di un crescente supporto da parte della comunità di sviluppatori, offrendo numerosi pacchetti e plugin pronti all’uso che facilitano l’integrazione con servizi e dispositivi IoT.
3. Interfaccia utente personalizzabile: grazie al suo sistema di widget, Flutter permette di creare interfacce utente completamente personalizzate e reattive, offrendo un’esperienza utente coinvolgente e coerente su tutte le piattaforme.
Integrazione con Firebase e Firestore per l’autenticazione e la gestione dei dati
Firestore è un database NoSQL offerto da Firebase che consente di memorizzare e sincronizzare i dati tra le app in tempo reale.
Integrando Firebase Authenticator e Firestore con Flutter, possiamo facilmente creare un’app di controllo IoT che include:
1. Autenticazione dell’utente sicura e affidabile con supporto per l’accesso tramite email, Google, Facebook e altri provider di identità.
2. Memorizzazione e sincronizzazione dei dati dei dispositivi IoT in tempo reale, consentendo agli utenti di monitorare e controllare i loro dispositivi da qualsiasi luogo e in qualsiasi momento.
3. Scalabilità e flessibilità per gestire un numero crescente di dispositivi e utenti senza dover gestire l’infrastruttura del server.
Installazione e configurazione dell’ambiente di sviluppo Flutter:
Per iniziare a sviluppare un’app con Flutter, è necessario configurare l’ambiente di sviluppo sul tuo computer. Il modo più semplice per farlo, è quello di utilizzare Visual Studio Code (VSCode) ed installare l’estensione Flutter dalla sezione “Extensions” (Ctrl+Shift+X).
Creazione di un progetto Flutter e struttura delle cartelle:
Per creare un nuovo progetto Flutter, segui questi passaggi:
- Apri un terminale e naviga nella cartella in cui desideri creare il progetto.
- Esegui il comando `flutter create nome_del_progetto`, sostituendo “nome_del_progetto” con il nome che desideri dare al tuo progetto.
- Apri la cartella del progetto appena creato in VSCode.
- La struttura delle cartelle di un progetto Flutter dovrebbe includere:
- lib: Contiene il codice sorgente dell’app, come i file Dart e i widget personalizzati.
- assets: Contiene le risorse dell’app, come immagini, icone e file di dati.
- android e `ios`: Contengono i file di configurazione e le risorse specifiche della piattaforma per le app Android e iOS, rispettivamente.
- web: Contiene i file di configurazione e le risorse specifiche della piattaforma per le app web.
- test: Contiene i file di test per l’app.
- pubspec.yaml: È il file di configurazione del progetto, dove si dichiarano le dipendenze, le risorse e le impostazioni dell’app.
Integrazione con Firebase e configurazione di Firebase Authenticator
Per integrare Firebase nel tuo progetto Flutter, segui questi passaggi:
- Crea un nuovo progetto Firebase visitando la console di Firebase: https://console.firebase.google.com/
- Segui le istruzioni per aggiungere Firebase al tuo progetto Flutter per le piattaforme Android, iOS e web.
- Nel file `pubspec.yaml`, aggiungi le seguenti dipendenze per Firebase e Firebase Authenticator:
dependencies:
firebase_core: “^1.10.0”
firebase_auth: “^3.3.3”
4. Esegui il comando seguente nel terminale per installare le dipendenze:
flutter pub get
5. Nel file `lib/main.dart`, importa i seguenti pacchetti:
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_auth/firebase_auth.dart';
6. Inizializza Firebase nel metodo `main()` del tuo file `lib/main.dart`:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
Ora puoi utilizzare Firebase Authenticator per gestire l’autenticazione dell’utente nel tuo progetto Flutter.
Nei prossimi paragrafi, ci concentreremo sulla creazione dell’interfaccia utente dell’app e sulla navigazione tra le pagine, sulla gestione dell’autenticazione dell’utente e sulla registrazione/login e sull’introduzione a Firestore e alla struttura del database per i dispositivi IoT.
Creazione dell’interfaccia utente dell’app e navigazione tra le pagine:
Per creare l’interfaccia utente e gestire la navigazione tra le pagine, segui questi passaggi:
1. Crea una nuova cartella chiamata `pages` nella cartella `lib` del tuo progetto. Questa cartella conterrà i file Dart per le diverse pagine dell’app.
2. All’interno della cartella `pages`, crea i seguenti file Dart per le pagine dell’app: `login_page.dart`, `register_page.dart`, `home_page.dart` e `device_control_page.dart`.
3. Crea una classe StatefulWidget per ciascuna pagina e definisci l’interfaccia utente utilizzando i widget Flutter.
4. Per gestire la navigazione tra le pagine, utilizza il widget `Navigator` di Flutter. Ad esempio, per navigare dalla pagina di login alla pagina di registrazione, aggiungi il seguente codice all’interno di un evento di pressione di un pulsante:
Navigator.push(
context,
MaterialPageRoute(builder: (context) => RegisterPage()),
);
5. Configura le rotte delle pagine nel file `lib/main.dart` all’interno del widget `MaterialApp`:
MaterialApp(
...
routes: {
'/': (context) => LoginPage(),
'/register': (context) => RegisterPage(),
'/home': (context) => HomePage(),
'/device_control': (context) => DeviceControlPage(),
},
);
Gestione dell’autenticazione dell’utente e registrazione/login:
Per gestire l’autenticazione dell’utente e consentire la registrazione e il login, segui questi passaggi:
1. Nella pagina di registrazione (`register_page.dart`), crea un form che raccolga le informazioni dell’utente come email e password.
2. Utilizza il metodo `createUserWithEmailAndPassword` di Firebase Authenticator per creare un nuovo utente:
FirebaseAuth.instance.createUserWithEmailAndPassword(
email: email,
password: password,
);
3. Gestisci eventuali errori di registrazione e mostra un messaggio all’utente, se necessario.
4. Nella pagina di login (`login_page.dart`), crea un form che raccolga l’email e la password dell’utente.
5. Utilizza il metodo `signInWithEmailAndPassword` di Firebase Authenticator per autenticare l’utente:
FirebaseAuth.instance.signInWithEmailAndPassword(
email: email,
password: password,
);
6. Gestisci eventuali errori di login e mostra un messaggio all’utente, se necessario.
Introduzione a Firestore e struttura del database per i dispositivi IoT:
Firestore è un database NoSQL offerto da Firebase che consente di memorizzare e sincronizzare i dati tra le app in tempo reale. La struttura del database per i dispositivi IoT può essere organizzata come segue:
1. Crea una collezione chiamata `devices` che conterrà i documenti per ciascun dispositivo IoT.
2. Ogni documento nella collezione `devices` avrà un ID univoco. Scegli la struttura dei campi, ad esempio:
- name: il nome del dispositivo (ad esempio, “Relay 1”)
- state: lo stato corrente del dispositivo (ad esempio, “on” o “off”)
- userId: l’ID dell’utente a cui appartiene il dispositivo, per garantire che ogni utente possa accedere solo ai propri dispositivi.
3. Per interagire con Firestore nel tuo progetto Flutter, aggiungi le seguenti dipendenze nel file `pubspec.yaml`:
dependencies:
cloud_firestore: "^3.1.0"
4. Esegui il comando `flutter pub get` nel terminale per installare le dipendenze.
5. Importa il pacchetto Firestore nel file Dart in cui desideri utilizzarlo:
import ‘package:cloud_firestore/cloud_firestore.dart’;
6. Utilizza il metodo `collection()` per accedere alla collezione `devices` e il metodo `doc()` per accedere a un documento specifico. Ad esempio, per aggiungere un nuovo dispositivo, utilizza il seguente codice:
FirebaseFirestore.instance.collection('devices').add({
'name': 'Relay 1',
'type': 'relay',
'state': 'off',
'userId': FirebaseAuth.instance.currentUser.uid,
});
7. Per leggere i dati dei dispositivi dell’utente corrente, utilizza una query che filtri i documenti in base all’ID dell’utente:
FirebaseFirestore.instance
.collection('devices')
.where('userId', isEqualTo: FirebaseAuth.instance.currentUser.uid)
.snapshots();
Applicazione di esempio
Abbiamo appena visto le basi della creazione di un’app di controllo per smartphone, per gestire l’autenticazione utente ed il controllo remoto dei propri relè smart. Per concludere questa sezione senza dilungarsi, in questo reposity troverai un esempio di applicazione base, che permette la registrazione dell’utente, l’accesso ed il controllo remoto in tempo reale dei propri dispositivi DIY.