Apriamo il portone con Google Assistant – ESP01

ESP-01_Open_Door

Se avete voglia di aprire il portone di casa in maniera smart, senza più dover suonare al citofono siete nel posto giusto, in questo articolo vedremo come farci aprire il portone direttamente da Google Assistant.

Per realizzare questo progetto ci occorre:

  • ESP-01 (ESP8266)
  • Modulo relè compatibile con ESP-01
  • Account IO Adafruit
  • Account IFTTT

In questo progetto parleremo di protocollo MQTT (MQ Telemetry Transport), necessario per far comunicare il nostro ESP01 con il server Adafruit quindi prima di iniziare con il codice giusto una piccola infarinatura su cos’è il protocollo MQTT e come funziona.

Protocollo MQTT

Il protocollo MQTT è stato inventato nel 1999 da due ricercatori (Andy Stanford-Clark di IBM e Arlen Nipper di Arcom) e le sue specifiche sono pubbliche (sito IBM).
La caratteristica principale di MQTT è di essere un protocollo publish/subscribe.

In una comunicazione tradizionale, la sorgente del dato (ad esempio un sensore di temperatura) invia il dato direttamente all’utilizzatore finale (ad esempio il termostato).
In una comunicazione publish/subscribe invece il sensore invia (pubblica, publish in inglese) il dato ad un sistema centrale detto broker. Tutti i dispositivi che vogliono ottenere tale dato lo comunicano al broker (si iscrivono, subscribe in inglese) ed è il broker ad inviare loro il dato quando questo è disponibile.
Un altro termine che entra in gioco in questo sistema è il topic ossia l’argomento al quale un determinato dispositivo è interessato e vuole sottoscriversi, in questo caso ogni qual volta c’è un nuovo messaggio per un determinato topic, sarà il broker a preoccuparsi di comunicarlo a tutti i dispositivi che si sono sottoscritti a quel topic.

Protocollo MQTT

Configurazione IO Adafruit

Ora che conosciamo il funzionamento che sta alla base del protocollo MQTT non ci resta che configurare l’account Adafruit.
Dopo esserci registrati sul sito IO Adafruit dobbiamo creare il nostro topic, al quale il dispositivo ESP01 si sottoscriverà, per far questo seguiamo i seguenti passaggi:

  1. Facciamo il login sul portale IO Adafruit
  2. Andiamo nella sezione Feeds, che si trova a lato sinistro
  3. Clicchiamo sul menù a tendina Action->Create new Feed
  4. Nel form che si apre inseriamo un nome, che sarà il nostro topic, ad esempio “open-door” ed eventualmente una descrizione

A questo punto sul sito IO Adafruit abbiamo finito, ricordiamo solo che per connetterci al server bisognerà utilizzare username (definita in fase di registrazione) e la password che è possibile ottenere cliccando sul link View AIO Key sempre sul lato sinistro della pagina principale.

Configurazione IFTTT

Dopo esserci registrati dobbiamo creare la nostra applet, che sarà in ascolto quando parliamo con Google Assistant e alla frase “apri il portone” pubblicherà sul topic “open-door”, che abbiamo creato in precedenza, un messaggio che sarà utilizzato dal nostro ESP01 per attivare il relè.

Per creare la nostra applet seguiamo i seguenti passaggi:

  1. Facciamo il login sul sito IFTTT
  2. Nella pagina principale clicchiamo sul pulsante a destraNew Applet
  3. Clicchiamo su this e tra i servizi cerchiamo Google Assistant
  4. Tra i vari trigger scegliamo Say a simple phrase
  5. Alla domanda What do you want to say?” scriviamo “Apri il portone, nelle domande successive “What’s another way to say it?” e “And another way?” se vogliamo possiamo aggiungere altri tipi di frase per far si che google riesca a capire il nostro intento anche in modi differenti.
  6. Alla frase “What do you want the Assistant to say in response?” scriviamo “Ok, portone aperto” (rappresenta la risposta dell’assistente Google)
  7. Nella sezione lingua scegliamo “Italiano”
  8. Clicchiamo su “Create trigger”
  9. A questo punto scegliamo come action service “Adafruit”->”Send Data to Adafruit IO”
  10. Nel campo “Feed name” scegliamo “Open Door” che abbiamo creato in precedenza
  11. Nel campo “Date to save” il messaggio che vogliamo salvare tipo “Portone aperto con Google Assistant”
  12. Infine clicchiamo su “Create action” e poi sul tasto “Finish”

Codice ESP01

Ora che abbiamo configurato gli account di IO Adafruit e IFTTT siamo pronti per caricare il codice necessario all’ ESP01 per pilotare il relè e quindi aprire il portone.

#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

#define DOOR_PIN 0

/************************* WiFi Access Point *********************************/

#define WLAN_SSID       "...your SSID..."
#define WLAN_PASS       "...your password..."

/************************* Adafruit.io Setup *********************************/

#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  1883                   // use 8883 for SSL
#define AIO_USERNAME    "...your AIO username (see https://accounts.adafruit.com)..."
#define AIO_KEY         "...your AIO key..."

/************ Global State (you don't need to change this!) ******************/

// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;
// or... use WiFiFlientSecure for SSL
//WiFiClientSecure client;

// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

/****************************** Feeds ***************************************/
// Setup a feed called 'open-door' for subscribing to changes.
Adafruit_MQTT_Subscribe openDoorFeed = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/open-door");

/*************************** Sketch Code ************************************/

// Bug workaround for Arduino 1.6.6, it seems to need a function declaration
// for some reason (only affects ESP8266, likely an arduino-builder bug).
void MQTT_connect();

void setup() {
  Serial.begin(115200);
  delay(10);

  Serial.println(F("Adafruit MQTT demo"));

  //pin output
  pinMode(DOOR_PIN, OUTPUT);
  digitalWrite(DOOR_PIN, LOW);

  // Connect to WiFi access point.
  Serial.println(); Serial.println();
  Serial.print("Connecting to ");
  Serial.println(WLAN_SSID);

  WiFi.begin(WLAN_SSID, WLAN_PASS);   
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  Serial.println("WiFi connected");
  Serial.println("IP address: "); Serial.println(WiFi.localIP());

  // Setup MQTT subscription for onoff feed.
  mqtt.subscribe(&openDoorFeed);
}

uint32_t x=0;

void loop() {
  // Ensure the connection to the MQTT server is alive (this will make the first
  // connection and automatically reconnect when disconnected).  See the MQTT_connect
  // function definition further below.
  MQTT_connect();

  // this is our 'wait for incoming subscription packets' busy subloop
  // try to spend your time here

  Adafruit_MQTT_Subscribe *subscription;
  while ((subscription = mqtt.readSubscription(5000))) {
    if (subscription == &openDoorFeed) {
      Serial.print(F("Got: "));
      Serial.println((char *)openDoorFeed.lastread);
      openDoor();
    }
  }

  // ping the server to keep the mqtt connection alive
  // NOT required if you are publishing once every KEEPALIVE seconds
  if(! mqtt.ping()) {
    mqtt.disconnect();
  }
}

void openDoor() {
  digitalWrite(DOOR_PIN, HIGH);
  delay(1000);
  digitalWrite(DOOR_PIN, LOW);
}

// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
  int8_t ret;

  // Stop if already connected.
  if (mqtt.connected()) {
    return;
  }

  Serial.print("Connecting to MQTT... ");

  uint8_t retries = 3;
  while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
       Serial.println(mqtt.connectErrorString(ret));
       Serial.println("Retrying MQTT connection in 5 seconds...");
       mqtt.disconnect();
       delay(5000);  // wait 5 seconds
       retries--;
       if (retries == 0) {
         // basically die and wait for WDT to reset me
         while (1);
       }
  }
  Serial.println("MQTT Connected!");
}

Nel codice sopra le uniche cose che dovete cambiare sono l’username e la password sia della vostra rete WiFi che del vostro account IO Adafruit, per configurare l’IDE di Arduino per compilare il progetto sull’ESP01 vi rimando ad un mio vecchio articolo dove spiego come fare ESP8266 – IoT low cost, mentre per quanto riguarda le librerie MQTT di Adafruit per aggiungerle al vostro IDE basta andare in Sketch->#include libreria->Gestione Librerie , cercare “adafruit mqtt” e installare la libreria come si vede nella foto seguente (nel mio caso risulta già installata nel vostro ci sarà un pulsante con scritto “installa”).adafruit mqtt

Ora che abbiamo caricato il codice sull’ESP01 vi spiego come funziona questo sistema, senza però entrare nel dettaglio del codice in quanto è già ampiamente commentato.
Ogni qual volta comunichiamo con Google Assistant dicendo la frase “Ok Google” la nostra applet IFTTT si mette in ascolto e se pronunciamo la frase che abbiamo scelto, in questo caso “apri il portone” Google ci risponderà con “Ok, portone Aperto” e nel frattempo IFTTT avrà già pubblicato sul topic “open-door” il messaggio “Portone aperto con Google Assistan“.
Il nostro dispositivo ESP01 non appena è alimentato si collegherà alla rete WiFi e successivamente al server IO Adafruit sottoscrivendosi al topicopen-door“, in questo modo ogni qual volta sarà presente un nuovo messaggio verrà eseguito il metodo openDoor() il quale ecciterà per 1 secondo il relè aprendo così il portone.

Apri portone con Google Assistant.png

Configurazione Hardware

Modulo Rele - ESP01

Modulo Relè – ESP01

Il modulo relè che ospita l’ESP01 e quello nella figura sopra, e da quanto letto in rete è compatibile con la versione dell’ESP-01S non con la versione “vecchia” che mi è arrivata (ESP01 senza S), per questo motivo è necessario eseguire le seguenti modifiche al modulo:

  1. Cortocircuitare il pin VCC con il CH_PD (anche detto EN), in questo modo abilitiamo il chip ad eseguire il codice caricato
  2. Collegare una resistenza da 10K tra VCC e Io0 (IO Zero)

La modifica è possibile realizzarla anche usando semplicemente la resistenza di 10K come si può vedere nella figura sotto.

Modifica modulo relè ESP01

Modifica modulo relè ESP01

Ora che abbiamo modificato il modulo siamo pronti per collegarlo al nostro citofono, i passaggi che seguono si riferiscono ad un particolare modello della Urmet quindi nel vostro caso i collegamenti potrebbero essere differenti:

  1. Collegare l’alimentazione del modulo con un alimentatore da 5V rispettando gli ingressi (5V e GND) come si può vedere dal retro del modulo
  2. Collegare due fili all’uscita del relè uno al comune l’altro al NO (Normally Open)
  3. Connettere gli altri estremi dei fili uno alla massa del citofono e l’altro al pin del pulsante

Ripeto i passaggi che ho descritto si riferiscono ad un particolare citofono della Urmet, quindi ATTENZIONE a quello che fate sta a voi controllare come funziona il vostro citofono e quali sono i pin da collegare.

Citofono + ESP01 + relè

Citofono + ESP01 + relè

Spero che il progetto vi sia piaciuto, ora non vi resta che pronunciare “Ok Google, apri il portone” e come per magia si aprirà 😉