Sincronizzare sveglia di Android e tapparelle di casa con ESP8266

Grazie alla connettività WiFi dell’ESP8266 è possibile far interagire oggetti reali e computer/smartphone in maniera personalizzata e a basso costo.

In questi anni sono sbarcati sul mercato diversi esempi di Internet of Things, come lampadine ed elettrodomestici gestibili attraverso la rete WiFi. Rispetto a queste soluzioni, i progetti realizzati con Arduino e ESP8266 hanno l’indubbio vantaggio di poter rendere interconnessi a costi irrisori anche oggetti nati non smart, come termostati, condizionatori o tapparelle.

Se da un punto di vista prettamente hardware basta un ESP-01 e un relè per controllare la maggior parte degli elettrodomestici di casa, dal punto di vista software gestire le varie comunicazioni non è cosa da poco.

Fortunatamente Souliss offre un framework opensource già pronto per questo tipo di esigenze. Questo si compone essenzialmente di una applicazione Android e di una libreria Arduino, compatibile con un discreto numero di microcontrollori e protocolli di comunicazione (seriale, WiFi, NRF24, etc).

Souliss semplifica così tanto il lavoro sulla parte software, che ciò che è richiesto, più che programmazione lo si può definire configurazione. Souliss include infatti un database di logiche, ognuna rappresentante tutte quelle serie di azioni necessarie per (ad esempio) controllare un dato elettrodomestico o leggere un dato sensore.

Quindi basta dire cosa si vuole controllare, con quali pin del microcontrollore e i parametri della connessione (ad esempio nome e password della rete WiFi). Del resto se ne occupa Souliss.

Esempio

Il seguente sketch, liberamente tratto dalla documentazione ufficiale, mostra come controllare un semplice LED collegato a GPIO_2:

// Let the IDE point to the Souliss framework
#include "SoulissFramework.h"

// Configure the framework
#include "bconf/MCU_ESP8266.h"              // Load the code directly on the ESP8266
#include "conf/Gateway.h"                   // The main node is the Gateway, we have just one node
#include "conf/IPBroadcast.h"

// **** Define the WiFi name and password ****
#define WIFICONF_INSKETCH
#define WiFi_SSID               "mywifi"
#define WiFi_Password           "mypassword"    

// Include framework code and libraries
#include <ESP8266WiFi.h>
#include <EEPROM.h>

/*** All configuration includes should be above this line ***/ 
#include "Souliss.h"

// This identify the number of the LED logic
#define MYLEDLOGIC          0               

// **** Define here the right pin for your ESP module **** 
#define	OUTPUTPIN			2

void setup()
{   
    Initialize();

    // Connect to the WiFi network and get an address from DHCP
    GetIPAddress();                           
    SetAsGateway(myvNet_dhcp);       // Set this node as gateway for SoulissApp  

    // This is the vNet address for this node, used to communicate with other
	// nodes in your Souliss network
    SetAddress(0xAB01, 0xFF00, 0x0000);
	
    Set_SimpleLight(MYLEDLOGIC);        // Define a simple LED light logic
	
    pinMode(OUTPUTPIN, OUTPUT);         // Use pin as output 
}

void loop()
{ 
    // Here we start to play
    EXECUTEFAST() {                     
        UPDATEFAST();   
        
        FAST_50ms() {   // We process the logic and relevant input and output every 50 milliseconds
            Logic_SimpleLight(MYLEDLOGIC);
            DigOut(OUTPUTPIN, Souliss_T1n_Coil,MYLEDLOGIC);
        } 
              
        // Here we handle here the communication with Android
        FAST_GatewayComms();                                        
    }
} 

Dallo sketch si nota, come già accennato, che non occorre definire alcun comportamento. Non si è dovuto scrivere, ad esempio, if (condizione) digitalwrite(OUTPUTPIN, HIGH);, che è come normalmente si controlla un LED con Arduino, ma è bastato dichiarare che stiamo controllando un LED con Set_SimpleLight(MYLEDLOGIC); e su quale pin opera tale logica (o Typical). Sebbene nel caso di un LED questo possa sembrare banale, non lo è assolutamente nel caso di elettrodomestici più complessi.

Nel caso di altri elettrodomestici, basta eseguire il copia e incolla di questo esempio e sostituire le parti rilevanti.

Non mi dilungo di più e rimando il lettore in cerca di approfondimenti al wiki ufficiale e alla lista delle logiche supportate. Aggiungo solo che è possibile realizzare reti di dispositivi comunicanti fra di loro attraverso più protocolli contemporaneamente.

Descrizione del progetto

Il progetto proposto ha come obiettivo quello di controllare via smartphone la tapparella motorizzata della mia stanza da letto. In particolare l’effetto desiderato è farla alzare quando suona la sveglia del mio smartphone Android.

La tapparella

Pericolo

Operare in corrente continua è estremamente pericoloso. Oltre alla vita, si rischia anche di danneggiare l’impianto elettrico con conseguente rischio di blackout e incendi.

La mia tapparella (come la maggior parte) è controllata tramite 3 cavi. Il pulsante SÙ mette in corto quello rosso (che è un’estensione del filo azzurro = neutro) con il filo marrone chiaro (fase). Il pulsante GIÙ, invece collega lo stesso neutro (si noti il ponte del filo rosso) con il filo grigio (fase).

Board

Per controllare la tapparella basta mettere in corto i suddetti fili emulando l’azione del pulsante. Per farlo occorrono due relè. Oltre ai controllare il circuito bisogna anche leggere lo stato dei pulsanti, in modo da permettere il controllo manuale.

In tutto andremo ad impiegare 4 pin, che è il massimo che ha da offrire l’ESP-01, il modulo più piccolo ed economico basato su ESP8266.

L’ultima preoccupazione è l’alimentazione. Personalmente ho da parte alcuni vecchi caricabatterie per cellulari, di quelli antecedenti all’avvento dello standard microUSB ed ora divenuti inutili. Aprendone uno ho ottenuto una piccola board che eroga 5V a 0.7A massimi e che posso alimentate con i cavi fase e neutro provenienti dalla presa che si trova nella stessa scatola di derivazione dei comandi della tapparella. In alternativa, senza sventrare l’alimentatore, basta tagliare il connettore terminale per estrarre i due fili rosso e nero e inserire normalmente l’alimentatore ad una presa qualsiasi.

I 5V sono perfetti per alimentare i relè, mentre per l’ESP-01 occorre aggiungere un regolatore di tensione a 3.3V.

Schema

Nello schema J2 è una morsettiera a cui collegare i 5V e la massa dal caricatore USB. A J1 sono collegati (nell’ordine) fase SÙ (marrone), neutro (rosso) e fase GIÙ (grigio).

J3 è la morsettiera da collegare alla pulsantiera. Questa (nel mio caso) presenta quattro morsettiere. Alle due superiori (relative al pulsante SÙ) occorre collegare un filo da J3 e un filo di massa dal caricabatterie. Alle due inferiori l’altro filo collegato alla morsettiera J3 un’altro filo di massa.

Ho tradotto lo schema nel seguente PCB, che ho realizzato con la tecnica del ferro da stiro. Si noti che non è necessario saldare l’ESP-01 al PCB. Basta saldare un socket appropriato.

Software

Lo sketch caricato sull’ESP-01 è il seguente:

// Configure the framework
#include "bconf/MCU_ESP8266.h"  // Load the code directly on the ESP8266
#include "conf/Gateway.h"       // The main node is the Gateway, we have just one node
#include "conf/IPBroadcast.h"

// **** Define the WiFi name and password ****
#define WIFICONF_INSKETCH
#define WiFi_SSID               "mywifi"
#define WiFi_Password           "mypassword"    

// Include framework code and libraries
#include <ESP8266WiFi.h>
#include <EEPROM.h>

// Define the network configuration according to your router settings
uint8_t ip_address[4]  = {192, 168, 1, 77};
uint8_t subnet_mask[4] = {255, 255, 255, 0};
uint8_t ip_gateway[4]  = {192, 168, 1, 1};
#define myvNet_address  ip_address[3]       // The last byte of the IP address (77) is also the vNet address
#define myvNet_subnet   0xFF00

/*** All configuration includes should be above this line ***/ 
#include "Souliss.h"

// This identify the number of the curtain logic
#define CURTAIN_SLOT  0               

// **** Define here the right pins for your ESP module **** 
#define	BUTTON_UP    0	        // Open Command from pushbutton
#define	BUTTON_DOWN  2          // Close Command from pushbutton
#define	CURTAIN_UP   1		// Open Relay
#define	CURTAIN_DOWN 3		// Close Relay

void setup()
{   
    Initialize();


     // Set network parameters
    Souliss_SetIPAddress(ip_address, subnet_mask, ip_gateway);
    SetAsGateway(myvNet_address);     // Set this node as gateway for SoulissApp  
	
    Set_Windows(CURTAIN_SLOT);        // Define a curtain logic
	
    // Define inputs (hardware pulldown required) and outputs pins
    pinMode(BUTTON_UP, INPUT);
    pinMode(BUTTON_DOWN, INPUT);
    pinMode(CURTAIN_UP, OUTPUT);
    pinMode(CURTAIN_DOWN, OUTPUT);
}

void loop()
{   
    // Here we start to play
    EXECUTEFAST() {                     
        UPDATEFAST();   

        // Process every 510ms the logic that control the curtain
        FAST_510ms() {
            // Use OPEN and CLOSE Commands
            LowDigIn(BUTTON_UP, Souliss_T2n_OpenCmd_Local, CURTAIN_SLOT);
            LowDigIn(BUTTON_DOWN, Souliss_T2n_CloseCmd_Local, CURTAIN_SLOT);
            
            // Run the logic
            Logic_Windows(CURTAIN_SLOT);
            
            // Control the output relays, the stop is with both the relays not active.
            // If you need to active the relays on stop, use nDigOut instead.
            DigOut(CURTAIN_UP, Souliss_T2n_Coil_Open, CURTAIN_SLOT);    
            DigOut(CURTAIN_DOWN, Souliss_T2n_Coil_Close, CURTAIN_SLOT);   
                
        } 

        // Process the communication
        FAST_PeerComms();
    
        // Define the hold time of the outputs, by default the timer hold the relays for 16 times, so:
        // 124x10x16ms that is about 20 seconds. Change the parameter inside FAST_x10ms() to change this time.
        FAST_x10ms(124) {                 
            Timer_T22(CURTAIN_SLOT);
        }
    }
}

Ovviamente occorre inserire le credenziali della propria connessione. In particolare con questo sketch si richiede al router un indirizzo IP statico. Per ottenerlo senza errori, a seconda del modello e della configurazione, è possibile che sia necessario cambiare anche le seguenti righe:

uint8_t ip_address[4]  = {192, 168, 1, 77};
uint8_t subnet_mask[4] = {255, 255, 255, 0};
uint8_t ip_gateway[4]  = {192, 168, 1, 1};

Inoltre l’ESP8266 non sa se la tapparella è aperta o chiusa (ci vorrebbero dei sensori aggiuntivi), ma è possibile impostare il tempo necessario per aprire/chiudere la tapparella. Nel codice è impostato a 20 secondi, ma potrebbe essere necessario modificarlo. La riga rilevante è questa:

        // Define the hold time of the outputs, by default the timer hold the relays for 16 times, so:
        // 124x10x16ms that is about 20 seconds. Change the parameter inside FAST_x10ms() to change this time.
        FAST_x10ms(124) {  

Prima di caricare il codice, ovviamente, bisogna aver abilitato il supporto all’ESP8266 e bisogna aver installato la libreria Souliss.

Applicazione Souliss

L’applicazione dovrebbe configurarsi automaticamente al primo avvio. Se così non fosse, recarsi in “Opzioni” > “Network” ed impostare l’“Indirizzo Souliss Locale” a 192.168.1.77 (o comunque l’indirizzo statico che si è impostato nello sketch). Poi eseguire “Richiedi configurazione nodi” in “Opzioni” > “Modello”.

A questo punto è possibile controllare la tapparella via WiFi da “Manuale” > “Nodo 0”.

Figo no? Ma noi vogliamo di più, vogliamo automazione! Da “Opzioni” > “Servizi” si attivi la voce “Servizio abilitato”. Ora aprire la sezione “Comandi” e se ne aggiunga uno. Da qui è possibile selezionare il dispositivo da comandare (Nodo 0, Dispositivo motorizzato), il comando da inviare (Open o Colse) e quando inviarlo (ad un preciso orario, quando il cellulare con il GPS attivo è a casa, o quando si riceve un dato valore da un altro dispositivo Souliss).

Plugin Tasker

L’obiettivo del progetto è quello di lanciare il comando Open quando suona la sveglia di Android. Per farlo occorre l’appliazione Tasker.

Tasker è un’applicazione fantastica e serve ad automatizzare Android. Si può fare davvero di tutto, dal rispondere ad un SMS ad attivare/disattivare GPS. In pratica Tasker espone la maggior parte delle funzionalità di Android (oltre a quelle fornite dai plugin) in modo da attivarle/usarle al verificarsi di determinate condizioni impostabili.

Grazie al fatto che l’app Souliss si comporta da plugin, è anche possibile lanciare da Tasker gli “Scenari” di Souliss. Gli scenari (che è possibile aggiungere e modificare dalla sezione denominata, appunto, “Scenari”) non sono altro che elenchi di comandi. A differenza dei programmi non vengono eseguiti automaticamente dall’app Souliss.

Quindi si proceda a creare un nuovo scenario che chiameremo “apri”. Lo si selezioni e da “Menu” > “Aggiungi comando” si inserisca il comando “Open” per il “Nodo 0”, “Dispositivo Motorizzato”.

Poi avviare Tasker, passare alla sezione “Attività”, fare tap sul “+” in basso per aggiungere una nuova attività che chiameremo “apri”. Fare di nuovo tap sul “+” in basso per aggiungere una nuova azione. Dalla finestra di dialogo che si aprirà scegliere “Plugin” e quindi “SoulissApp”. Infine impostare il parametro “Configurazione” ad “apri” (come lo scenario).

Tornare alla home di Tasker, passare alla sezione “Profili”, tappare sul solito “+” per aggiungere un profilo. Dal menu a comparsa selezionare “Evento”, poi “Data/Ora” e infine “Sveglia”. Pulsante indietro e dal menu selezionare “apri”.

Problemi

Personalmente ho avuto dei problema nell’eseguire comandi automatizzati con SoulissApp, anche se credo sia dovuto più al mio cellulare che all’app in sé.

In pratica quando SoulissApp lancia un comando a schermo spento (sia impostando un Programma e sia attraverso Tasker) lo fa senza prima aver ristabilito la connessione con l’ESP8266 che quindi non riceve niente.

Questo problema si è risolto usando OpenHAB.

OpenHAB

OpenHAB è un software opensource che permette di monitorare e comandare apparecchi di home automation. Fornisce bindings per connettersi a centinaia di modelli e marche diverse. Tra questi c’è anche Souliss.

OpenHAB fornisce app per Android, iOS, permette di creare interfacce web, è programmabile attraverso script. Lo svantaggio è che deve essere eseguito su un PC sempre acceso. Fortunatamente, poiché è scritto in Java, gli unici requisiti sono la connessione internet alla rete domestica e Java Runtime installato. Un Raspberry Pi o, nel mio caso, un Banana Pi è perfetto allo scopo.

Dopo l’installazione, per creare un nuovo file di configurazione, aprire una ssh sul Raspberry Pi ed eseguire:

sudo cp /etc/openhab/configurations/openhab_default.cfg /etc/openhab/configurations/openhab.cfg

aprire il nuovo file in un editor:

sudo nano /etc/openhab/configurations/openhab.cfg

quindi cercare la sezione “#### Souliss Binding ####” e fare in modo che appaia così:

################################ Souliss Binding ######################################
#
# For ITEM defination in file .item like {souliss=<Typical>:<nodeID>:<slot>:[<bit>]}

souliss:IP_LAN=192.168.1.77
souliss:USER_INDEX=71
souliss:NODE_INDEX=134

# SERVERPORT - Leave empty for casual port
#souliss:SERVERPORT=

# Time in mills - min 50
souliss:REFRESH_DBSTRUCT_TIME=600000
souliss:REFRESH_SUBSCRIPTION_TIME=120000
souliss:REFRESH_HEALTY_TIME=60000
souliss:REFRESH_MONITOR_TIME=500
souliss:SEND_DELAY=1500
souliss:SEND_MIN_DELAY=100
souliss:SECURE_SEND_TIMEOUT_TO_REQUEUE=5000
souliss:SECURE_SEND_TIMEOUT_TO_REMOVE_PACKET=30000

poi, per aggiungere il dispositivo al database, creare ed aprire il file items/tapparella.items con il comando

sudo nano /etc/openhab/configurations/items/tapparella.items

e incollarci dentro la riga:

Rollershutter Tapparella "Tapparella" (All) {souliss="T22:0:0", autoupdate=false}

Infine avviare il demone OpenHAB sia subito che all’avvio:

sudo systemctl start openhab
sudo systemctl enable openhab

Integrazione in Tasker

Per integrare OpenHAB con Tasker, il procedimento è simile a quello descritto per Souliss, con la differenza che il comando “apri” viene inviato tramite richesta HTTP GET e non non tramite plugin.

Avviare Tasker, passare alla sezione “Attività”, fare tap sul “+” in basso per aggiungere una nuova attività che chiameremo “apri”. Fare di nuovo tap sul “+” in basso per aggiungere una nuova azione. Dalla finestra di dialogo che si aprirà scegliere “Rete” e quindi “Ottieni HTTP”.

Impostare “Server:Porta” a http://192.168.1.100:8080 o qualunque sia l’indirizzo IP del Raspberry Pi (NON DELL’ESP8266!). Inserire CMD sotto “Percorso” e Tapparella=UP sotto “Attributi”.

Tornare alla home di Tasker, passare alla sezione “Profili”, tappare sul solito “+” per aggiungere un profilo. Dal menu a comparsa selezionare “Evento”, poi “Data/Ora” e infine “Sveglia”. Pulsante indietro e dal menu selezionare “apri”.

Download

E possibile scaricare i file del progetto (rilasciati con licenza GPL) da qui.

Commenti