Sensore di temperatura e Domotica
Ho sempre diffidato della domotica, e in particolar modo ho sempre diffidato dei sistemi domotici che funzionano attraverso il cloud: il sensore registra un dato, il dato viene mandato al server di chi ti ha venduto il sensore, e alla fine ti viene reso disponibile mediante un'app o un sito web. Questo approccio semplifica la vita quando si realizza il sistema (è tutto pronto, preconfigurato, chiavi in mano) ma crea una serie di problematiche che superano di gran lunga i vantaggi:
- Sei vincolato all'hardware e al software deciso dal produttore, che ha tutto l'interesse a renderti la vita impossibile se vuoi aggiungere prodotti di altre aziende.
- I tuoi dati sono di proprietà del produttore, che in barba a qualunque promessa di privacy può farne letteralmente quel che vuole.
- Se il server ha un problema, ti ritrovi a piedi.
- Se il prodotto non è più interessante per il produttore, a un certo punto può decidere di spegnere il suo server e ti ritrovi la casa piena di costosi fermacarte.
- Poichè sei limitato a usare prodotti di un unico produttore (per il punto 1), questo ha di fatto un monopolio, che può sfruttare chiedendo prezzi elevati che non hanno niente a che vedere con il vero valore dell'hardware o del servizio.
La soluzione a questi problemi è il fai da te. E questo, invece, suscita il mio interesse. Ho quindi deciso di fare un piccolo esperimento.
Ho scoperto l'esistenza di un piccolo e simpatico sensore di temperatura prodotto da Xiaomi.
Si tratta di un dispositivo estremamente economico (5-7 euro), alimentato a batteria e che supporta la comunicazione via Bluetooth Low Energy. E, ciliegina sulla torta, esiste il modo di craccarlo per rimuovere la cifratura (che lo vincolerebbe, ovviamente, al suo cloud proprietario).
Primo passo: sistemare il termometro
Il primo passo, una volta ottenuto il dispositivo, è quindi flasharlo con un firmware modificato che rimuove la cifratura e consente anche modificare alcune impostazioni. Il procedimento può essere svolto direttamente da una pagina web! Io l'ho fatto usando un cellulare Android e Chrome.
Per prima cosa si preme il tasto "Connect". Viene mostrata una lista dei dispositivi Bluetooth raggiungibili, il termometro si presenta con un nome tipo "LYWSD03...". Una volta selezionato, nella schermata dovrebbero apparire le informazioni lette dal termometro, da cui si può verificare l'effettiva connessione.
A questo punto dovrebbe essere apparso un pulsante "Custom firmware". Si preme il pulsante e si attende la fine della procedura di flashing. Una volta terminata, si preme di nuovo il tasto connect, e dovrebbero apparire una serie di parametri di configurazione impostabili grazie al firmware modificato.
L'unica cosa che ci interessa è l'"Advertising Type", che deve essere impostato su MI. Al termine delle modifiche ricordiamo di premere il tasto "Send Config" per aggiornare il dispositivo.
Importantissimo: dopo aver terminato le operazioni CHIUDERE la pagina del browser. Questo dispositivo mantiene una sola connessione bluetooth alla volta, se vi rimane la pagina aperta non lo vedrete apparire nei passi successivi!
Secondo passo: predisporre il gateway Bluetooth-WiFi
Il passo successivo è scoprire come fare in modo che questi pacchetti Bluetooth arrivino al nostro server. A questo scopo si può usare un ESP-32, una scheda di sviluppo da pochi euro (5-10) che possiede sia connettività Bluetooth che WiFi e può essere programmata con ESPHome, un comodo firmware pensato apposta per questo genere di applicazioni.
Per prima cosa bisogna flashare la scheda. La colleghiamo via USB al nostro server linux, e verifichiamo che sia stata riconosciuta usando il comando "dmesg":
Dobbiamo predisporre un file di configurazione, che verrà caricato alla prima configurazione. Esiste un wizard che ci consente di creare questo file senza fatica, e questo wizard può essere eseguito addirittura da una macchina Docker creata al momento, alla quale passiamo come parametro la directory in cui andare ad ospitare i file temporanei (in questo caso /config) e il nome del file di configurazione da creare (in questo caso "primonodo.yaml").
docker run --rm -v "${PWD}":/config -it esphome/esphome wizard primonodo.yaml
Verrà chiesto di configurare i parametri di connessione alla rete WiFi, un nome, il tipo di dispositivo ecc. Al termine di questa operazione dovremo modificare il file prodotto per aggiungere una riga:
Questa riga abilita il supporto al Bluetooth Low Energy. Mi raccomando i due punti alla fine.
Possiamo passare a questo punto a flashare il dispositivo, sempre usando Docker:
docker run --rm -v "${PWD}":/config --device=/dev/ttyUSB0 -it esphome/esphome run primonodo.yaml
Quando verrà richiesta la modalità di configurazione usiamo la connessione cablata (qualcosa del tipo ttyUSB0). Una volta terminate le operazioni il terminale rimarrà aperto e mostrerà il log delle attività della scheda. Teniamo d'occhio questo terminale, che ci mostrerà l'elenco degli indirizzi dei dispositivi bluetooth nella stanza. A noi serve l'indirizzo del nostro termometro.
A un certo punto (magari dopo 1/2 minuti) dovrebbe apparire qualcosa del genere:
Il nostro dispositivo dovrebbe avere Address Type PUBLIC. Prendiamo nota del mac address (sono le 6 coppie di caratteri separati da :). Quando siamo soddisfatti possiamo terminare il programma con Control+C e passare oltre.
Dobbiamo aggiungere nel file di configurazione già modificato in passato i dettagli relativi al nostro sensore, in questo formato:
sensor:
- platform: xiaomi_lywsd03mmc
mac_address: "A4:C1:38:CC:30:6B"
bindkey: "eef418daf699a0c188f3bfd17e4565d9"
temperature:
name: "LYWSD03MMC Temperature"
humidity:
name: "LYWSD03MMC Humidity"
battery_level:
name: "LYWSD03MMC Battery Level"
Il mac_address è quello che ci siamo annotati prima. La bind key va lasciata così com'è (è posticcia, visto che abbiamo flashato il nostro termometro per eliminare la cifratura). I tre "name" sono liberi.
Già che ci siamo consiglio di impostare un IP fisso al nostro ESP32, per evitare difficoltà con la connessione al nostro server. Si può fare aggiungendo questo blocco al solito file di configurazione, dentro il blocco "wifi" (già esistente, non modifichiamo quanto già presente):
wifi:
....
manual_ip:
# Set this to the IP of the ESP
static_ip: 192.168.1.244
# Set this to the IP address of the router. Often ends with .1
gateway: 192.168.1.2
# The subnet of the network. 255.255.255.0 works for most home networks.
subnet: 255.255.255.0
Possiamo ora flashare ancora il dispositivo, con la stessa modalità seguita prima. Se tutto ha funzionato, nel log a questo punto dovrebbe apparire, magari dopo qualche minuto, qualcosa del genere:
Ora il nostro ESP32 sta ricevendo correttamente i dati. Non è più necessario tenerlo connesso al server, visto che comunica via WiFi: ha solo bisogno di una qualunque connessione USB per l'alimentazione (anche un caricabatterie per cellulari va bene).
Non ci resta che trovare un modo di mostrare come si deve questi dati.
Nota: per gestire il nostro dispositivo ESP32 esiste una applicazione con interfaccia web che possiamo eseguire sempre da docker:
docker run --rm --net=host -v "${PWD}":/config -it esphome/esphome
Nel nostro caso non ci serve, ma può essere utile quando si hanno più dispositivi o per accedere comodamente ai log. Può anche essere usata per modificare in futuro il file di configurazione senza dover ricollegare la scheda al server.
Visualizzare i dati
Per visualizzare i dati raccolti ho deciso di installare sul mio server un software web based per la domotica, Home Assistant. Nella sua versione semplificata si può eseguire direttamente da Docker usando un file docker-composer.yaml:
version: '3'
services:
homeassistant:
container_name: homeassistant
image: "ghcr.io/home-assistant/home-assistant:stable"
volumes:
- /apps/homeassistant/config:/config
- /etc/localtime:/etc/localtime:ro
restart: unless-stopped
privileged: true
network_mode: host
Una volta avviato sarà visibile alla porta 8123 del nostro server. Non voglio soffermarmi troppo su come funziona e come si configura, dato che richiederebbe ben più di un capitolo in un post, quindi cercherò di riassumere i passaggi specifici per questa funzionalità.
Nel menu "Impostazioni", "Integrazioni" premiamo il pulsante "Aggiungi Integrazione.." e nel menu che appare selezioniamo ESPHome
Una volta attivato Home Assistant cercherà di collegarsi al nostro ESP32. Nel mio caso non è riuscito a trovare il dispositivo in maniera automatica e mi ha chiesto di inserire l'indirizzo IP (è per questo motivo che nel capitolo precedente ho consigliato di impostare un indirizzo statico). Una volta configurato, il nostro nodo ESP32 rende disponibili a Home Assistant tre entità: temperatura, umidità e carica della batteria.
Seguendo le istruzioni in un qualunque tutorial (ce ne sono infiniti) possiamo creare una dashboard per mostrare queste entità:
Cliccando su un qualunque sensore è anche possibile vedere i valori registrati:
E con questo ho concluso questo primo esperimento. Non ho ancora deciso se mi interessa proseguire su questo filone. Magari potrebbe essere interessante recuperare 4/5 altri sensori e coprire tutta la casa, o magari provare un misuratore per tenere traccia dei consumi elettrici. Chissà.
Alla prossima!