[vc_row][vc_column][vc_column_text]Ciao a tutti Arduinisti,
Stefano Ledda, uno dei responsabili del nostro gruppo, ha scritto un interessantissimo tutorial in stile “instructables” su come pilotare dispositivi da remoto con un semplice messaggio da smartphone! Immaginate di mandare un messaggio con scritto “accendi condizionatore” poco prima di arrivare a casa e tornare sapendo di trovare la casa fresca! Con questo tutorial avrete le basi per poter costruire un dispositivo IoT (Internet of Things) col quale pilotare a distanza qualsiasi cosa. Tapparelle motorizzate, le luci di casa, lo scaldabagno, il condizionatore, il microonde. Gli impieghi sono davvero molteplici!
Cosa sono i BOT?
In sintesi estrema, sono delle entità software dotate di un minimo di intelligenza (alcuni possono essere anche molto complessi!) che possono eseguire elaborazioni in base a delle domande o comunicare dei risultati secondo dei parametri impostati.
Cosa è Telegram?
È un servizio di istant messaging come Whatapp, opensource e criptato. Disponibile praticamente per qualsiasi piattaforma (iOS, Android, Windows Phone, PC, Mac, linux, etc…)
Cosa sono e perché dovrei essere interessato ai BOT e a Telegram?
Un BOT di Telegram è un tipo di utenza Telegram che si può collegare ad un dispositivo elettronico dotato di una minima capacità elaborativa. Questo vuol dire che posso scrivere un programma che si collega ai server di Telegram e tramite un altro qualsiasi account Telegram posso inviare e ricevere messaggi dal programma che ho scritto. Detto così qualcuno potrebbe dire: “Bello, ma come posso sfruttarlo?”: esiste una libreria che permette di interfacciare un dispositivo “Arduino compatibile” con Telegram.
La connessione tra il BOT Telegram ed il server avviene tramite la porta 443. Detto in linguaggio meno tecnico, la connessione avviene tramite lo stesso canale protetto utilizzato dalle pagine web https, ossia quelle che vengono utilizzate per transazioni sicure (per esempio l’home banking). Semplificando ulteriormente, è un canale (quasi) sempre aperto, ossia non devo riconfigurare router: una volta che sono a conoscenza delle credenziali per accedere ad una rete WiFi, non mi serve altro. Essendo una piattaforma disponibile per qualsiasi dispositivo (cellulare, PC), non ho bisogno di scrivere nessuna applicazione lato client: utilizzo il client Telegram che installo sul mio cellulare/PC per comunicare con il BOT.
Posso utilizzare features già implementate delle App Telegram. Per esempio, il client per cellulari di Telegram permette il riconoscimento vocale, quindi posso parlare per impartire ordini al bot e il telefono, con la funzione speech to text, converte il parlato in testo. Si presta perfettamente all’IOT: voglio accendere/spegnere le luci? Mando un messaggio al bot! Voglio sapere la temperatura di casa? Mando un messaggio al bot! Voglio che mi arrivi un messaggio ogni qualvolta viene aperta la porta di casa? Configuro il bot perché possa leggere l’apertura della porta, quando si verifica, mi manda un messaggio sul cellulare! sarete liberi dalla necessità di scrivere un’app per cellulare (utilizzo il client Telegram) e non vi dovrete preoccupare di configurare la rete.
Se avete avuto la pazienza di arrivare a leggere fin qui, vuol dire che abbiamo catturato la vostra attenzione. Bene possiamo procedere!
Cosa serve per tirar su un BOT Telegram?
Vediamo ora cosa ci serve per tuffarci nel magico mondo dei BOT Telegram.
Avremo bisogno di:
- Un PC con installato l’IDE di Arduino, l’ultima versione e funziona.
- Un NodeMCU con relativo cavo microUSB (anche un ESP8266 va bene, ma il NodeMCU è più comodo perchè ha tutta la circuiteria di alimentazione e di interfacciamento al PC già pronta, poi nell’esempio utilizziamo il LED presente nella board)
- Aver installato le librerie e la board che permettono di utilizzare l’ESP8266 all’interno dell’IDE di Arduino
- Aver installato la libreria per utilizzare i BOT di Telegram dentro l’IDE di Arduino
- Un terminale con installato Telegram (va bene anche un cellulare)
I passaggi da compiere
- Relativamente al punto 1, recuperatevi un PC ed installateci (se già non l’avete fatto) l’ultima versione dell’IDE di Arduino
- Relativamente al punto 2, BangGood è vostro amico
- Relativamente al punto 3, se non l’avete ancora fatto, utilizzare il Board Manager
- Relativamente al punto 4, scaricate la libreria . Scaricate lo ZIP e seguite le istruzioni presenti nella pagina stessa (sketch -> #include libreria -> Aggiungi libreria da file .ZIP…)
- Relativamente al punto 5, installatevi Telegram sul cellulare (via AppStore, Google Market…) e/o sul PC
Creazione delle credenziali di un BOT
La prima cosa da fare è creare un BOT e per fare questo utilizzeremo, indovinate un po’… Un BOT di Telegram! Aprite Telegram sul cellulare e cercate il contatto BotFather (ha l’immagine de “Il Padrino” in versione robotica). Seguite le istruzioni, la sequenza dovrebbe essere:
- Newbot per iniziare la creazione di un nuovo bot
- Digitate quindi il nome del vostro bot
- Digitate quindi lo username del vostro bot (deve finire con “bot”)
- Se avete fatto le cose per bene, avete creato il vostro bot!
IMPORTANTISSIMO!!!
Copiatevi, memorizzatevi e se non basta tatuatevi queste tre informazioni che BotFather vi ha dato:
- Nome del BOT (lo avete deciso voi)
- Username del BOT (anche questa, la avete decisa voi, termina con “bot”)
- Token: ve lo comunica BotFather al termine della creazione del bot
Potrebbe essere utile disabilitare la possibilità che il proprio BOT possa essere inserito arbitrariamente dentro gruppi (ci sono altri bot che fagocitano i bot, li inseriscono in gruppi e li bombardano di messaggi). Il comando è setjoingroups, seguire poi le istruzioni.
Diamo vita al BOT
Così come una rondine non fa primavera, delle semplici credenziali non fanno un BOT!
Scaricate il file allegato ed apritelo con l’IDE di Arduino. All’interno del codice dovete modificare queste cinque righe:
// WiFi credentials
char ssid[] = “”; // your network SSID (name)
char password[] = “”; // your network key
// Telegram BOT configuration
#define BOTtoken “” // BOT Token
#define BOTname “” // BOT Name
#define BOTusername “” // BOT Username
Come facilmente intuibile, le prime due identificano l’Access Point a cui il NodeMCU si deve collegare (quello di casa vostra, per intenderci) mentre le ultime tre sono i parametri che BotFather vi ha generato. Editate quindi il codice con i vostri dati, inserendoli all’interno delle virgolette. Collegate il NodeMCU al vostro PC, compilate e “uploadate” il codice compilato sul NodeMCU.
Se tutto è andato a buon fine, il LED del NodeMCU dovrebbe lampeggiare per qualche secondo per poi rimanere acceso. Se continua a lampeggiare, provate a togliere l’alimentazione al NodeMCU e dopo qualche secondo, alimentatelo nuovamente. Se anche in questo caso continua a lampeggiare, controllate le credenziali del WiFi. Se il LED rimane acceso, allora il vostro BOT è online. Prendete il telefono, cercate su Telegram l’username che avete dato al vostro BOT e provate a scrivere qualcosa ed inviate il messaggio. A questo punto il BOT dovrebbe rispondervi con un messaggio del tipo “Prova con: ACCESSO – SPENTO” Se non dovesse rispondere, non è maleducato, semplicemente potreste aver sbagliato le credenziali del BOT, fate un double check. Provate a scrivere quindi la parola “acceso” o “spento” (non è importante se usate lettere maiuscole o minuscole, è “case insensitive”).
SPOILER ON
Dovrebbe accendersi o spegnersi il LED on board del NODEMCU
SPOILER OFF
Una volta placato l’entusiasmo per il funzionamento del BOT, continuate a leggere.
Commenti finali
Questa piccola demo di per se non ha una grande utilità, se non quella di far capire il funzionamento e guidare i primi passi per implementare un BOT di Telegram. Ovviamente è possibile interagire con sensori, attuatori e quant’altro semplicemente collegandoli ai pin del NodeMCU e istruendolo (leggasi scrivendo il codice). Per esempio, la stessa funzionalità la si può replicare utilizzando un LED esterno (ricordatevi di aggiungere anche un resistore): l’unico limite è come sempre la fantasia.
Commentiamo il codice
Concludiamo con un commento del codice, cosicché possiate metterci mano in autonomia. Facciamo una descrizione top-down: dall’inizio del file commentando il codice che via via troverete.
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <ESP8266TelegramBOT.h>
Librerie necessarie per la corretta compilazione del codice
// WiFi credentials
char ssid[] = “”; // your network SSID (name)
char password[] = “”; // your network key
Inserire qui le credenziali dell’Access Point a cui il NodeMCU si dovrà collegare.
I parametri devono essere inseriti all’interno delle virgolette. Per esempio, se il vostro Access Point ha SSID = Gino e password = Pilotino, nel codice ci sarà
// WiFi credentials
char ssid[] = “Gino”; // your network SSID (name)
char password[] = “Pilotino”; // your network key
Semplice no?
// Telegram BOT configuration
#define BOTtoken “” // BOT Token
#define BOTname “” // BOT Name
#define BOTusername “” // BOT Username
All’interno delle virgolette (così come avete fatto per le credenziali WiFi) dovete inserire i tre parametri ESATTAMENTE come BotFather vi ha comunicato.
Suggerimento: siccome il Token è piuttosto complicato, potete:
copiarlo dal vostro telefono ed inviarvelo via email ad una casella di posta elettronica che leggete dal PC
installate Telegram sul vostro PC. Una volta installato e configurato, condividerà le stesse chat presenti sul cellulare (anche il pregresso) e quindi potrete copiare tranquillamente il token senza rischio di commettere errori
// instance and initialization of a TelegramBot class
TelegramBOT bot(BOTtoken, BOTname, BOTusername);
int Bot_mtbs = 1000; //mean time between scan messages
long Bot_lasttime; //last time messages’ scan has been done
Variabili ed oggetti che servono per il corretto funzionamento del BOT. Il primo è l’oggetto che gestisce le comunicazioni con il server di Telegram, il secondo è il tempo in millisecondi che intercorre tra due richieste di aggiornamento (il controllo che verifica se sono arrivati nuovi messaggi), il terzo memorizza l’ultima volta (tempo) che è stato letto un messaggio. Sono utilizzati nel blocco loop()
/*************************************************
* ParseMessages – Parse messages sent to the bot *
*************************************************/
void Bot_ParseMessages() {
for (int i = 1; i < bot.message[0][0].toInt() + 1; i++) {
String msg;
msg = bot.message[i][5];
msg.toUpperCase();
if ( 0 == msg.compareTo(“ACCESO”)) {
digitalWrite(BUILTIN_LED, LOW);
Serial.println(“LED ACCESO”);
bot.sendMessage(bot.message[i][4], “Ok!”, “”);
} else if (0 == msg.compareTo(“SPENTO”)) {
digitalWrite(BUILTIN_LED, HIGH);
Serial.println(“LED SPENTO”);
bot.sendMessage(bot.message[i][4], “Ok!”, “”);
} else {
bot.sendMessage(bot.message[i][4], “Prova con: ACCESO – SPENTO”, “”);
}
}
bot.message[0][0] = “”; // All messages have been replied – reset new messages
}
Questa è la funzione che gestisce l’intelligenza del bot. È composta da un ciclo (FOR) che scandisce tutti i messaggi inviati e scaricati. In particolare, il numero di messaggi scaricati è memorizzato in bot.message[0][0]
L’i-esimo messaggio si trova in bot.message[i][5]. Detto in altre parole, supponiamo che bot.message[0][0] contenga il valore 3 (ossia ho scaricato tre messaggi), se volessi leggere il contenuto del secondo messaggio, questo è contenuto nella stringa memorizzata in bot.message[3][5] (ancora più semplicemente il primo numero presente tra parentesi quadre identifica il numero del messaggio)
Per rendere più semplice il riconoscimento di stringhe, utilizzo la classe String che include funzionalità avanzate quali l’uppercase (rende tutta maiuscola una stringa) e la comparazione tra stringhe.
Con questo codice
String msg;
msg = bot.message[i][5];
msg.toUpperCase();
salvo l’i-esimo messaggio (msg = bot.message[i][5]) dentro un oggetto di tipo String (che ho chiamato msg) e ne faccio l’uppercase (tutto maiuscolo – msg.toUpperCase()). Per quale motivo???? Perché, qualsiasi messaggio riceverò (sia esso scritto tutto in minuscolo, tutto in maiuscolo, una lettera maiuscola ed una no) potrò poi confrontarlo con una stringa tutta maiuscola! Questo perché se due stringhe contengono lo stesso testo ma hanno maiuscole/minuscole differenti, sono due stringhe diverse.
Ed è esattamente quello che faccio nel seguente blocco:
if ( 0 == msg.compareTo(“ACCESO”)) {
digitalWrite(BUILTIN_LED, LOW);
Serial.println(“LED ACCESO”);
bot.sendMessage(bot.message[i][4], “Ok!”, “”);
} else if (0 == msg.compareTo(“SPENTO”)) {
digitalWrite(BUILTIN_LED, HIGH);
Serial.println(“LED SPENTO”);
bot.sendMessage(bot.message[i][4], “Ok!”, “”);
} else {
bot.sendMessage(bot.message[i][4], “Prova con: ACCESO – SPENTO”, “”);
}
Ogni singolo IF serve per confrontare l’iesimo messaggio (che precedentemente ho salvato in msg) con una stringa prestabilita (per esempio 0 == msg.compareTo(“ACCESO”) sta verificando se la stringa è uguale ad ACCESO) . Se l’esito del confronto è zero (le stringhe sono uguali) allora esegue il blocco di istruzioni presente all’interno delle parentesi graffe, altrimenti (ELSE) esegue il prossimo IF, finché non trova una condizione (IF) verificata oppure arriva all’ultimo ELSE, il quale esegue il relativo blocco.
Un commento a parte va alla chiamata bot.sendMessage(bot.message[i][4], “Ok!”, “”): il metodo sendMessage dell’oggetto bot (il quale è l’oggetto che gestisce le comunicazioni con il server Telegram) permette di inviare un messaggio ad un utente Telegram definito. In particolare, sono in grado di rispondere a chi mi ha scritto il messaggio in quanto il mittente è contenuto nel blocco di dati che contiene il messaggio stesso.
In particolare (come abbiamo visto precedentemente) l’iesimo messaggio è contenuto in bot.message[i][5], quindi posso sapere chi è il mittente di questo i-esimo messaggio andando a leggere bot.message[i][4].
Quindi la riga di codice
bot.sendMessage(bot.message[i][4], “Ok!”, “”);
non fa altro che spedire il messaggio OK! al destinatario presente in bot.message[i][4] che è esattamente chi mi ha mandato il messaggio presente in bot.message[i][5]
digitalWrite(BUILTIN_LED, HIGH);
Abbastanza semplice da intuire, questa accende o spegne il LED on board del NodeMCU. Una piccola precisazione, funziona in logica inversa: il comando precedente SPEGNE il LED (se ci fosse stato LOW, lo avrebbe acceso)
Vediamo ora cosa viene eseguito nel blocco di setup tipico della programmazione di Arduino
Serial.begin(115200);
Inizializza la seriale ad un boud rate di 115200
// attempt to connect to Wifi network:
Serial.print(“Connecting Wifi: “);
Serial.println(ssid);
WiFi.begin(ssid, password);
delay(500);
Oltre a scrivere dei messaggi sulla seriale (utilizzati principalmente per descrivere cosa sta facendo il NodeMCU in quel momento), con l’istruzione WiFi.begin(ssid, password) cerca di far connettere il NodeMCU alla rete WiFi avente SSID ssid e password password (che sono quelle definite precedentemente). ATTENZIONE!!!! ssid, password SONO DELLE VARIABILI CHE AL LORO INTERNO CONTENGONO UNA STRINGA CON L’SSID E LA PASSWORD CHE VOI AVETE DEFINITO ALL’INIZIO DEL PROGRAMMA. Non sono il vostro SSID e la vostra password. Per modificarli, dovete modificare la parte di codice all’inizio del file.
/*
WiFi.config(IPAddress(10, 65, 14, 156),
IPAddress(10, 65, 14, 1),
IPAddress(255, 255, 255, 0),
IPAddress(8, 8, 4, 4),
IPAddress(8, 8, 8, 8));
*/
Questo pezzo di codice commentato (quindi non viene eseguito) serve qualora il router WiFi al quale ci connettiamo non ha la funzione di DHCP (ossia non è in grado di assegnare un indirizzo IP automaticamente). Tutti i moderni router sono in grado di farlo, ma se si è in una rete nella quale questa funzionalità non è appositamente implementata oppure vogliamo assegnare un indirizzo IP statico al nostro NodeMCU, questo blocco va decommentato. In particolare, il primo parametro rappresenta l’indirizzo IP, il secondo il Gateway, il terzo la NetMask ed il quarto/quinto sono i due DNS).
pinMode(BUILTIN_LED, OUTPUT);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(“.”);
digitalWrite(BUILTIN_LED, !digitalRead(BUILTIN_LED)); // set pin to the opposite state
delay(500);
}
Questo blocco attende che il NodeMCU si colleghi effettivamente al router. in particolare, finché la connessione non viene instaurata, quello che fa è scrivere un punto sulla seriale, spegne/accende il LED on board sul NodeMCU, aspetta mezzo secondo.
Questo pezzo di codice è molto utile per capire se effettivamente c’è un problema di connessione: infatti se il NodeMCU per qualsiasi motivo non riesce a collegarsi alla rete WiFi, continua a far lampeggiare il LED on board
Serial.println(“”);
Serial.println(“WiFi connected”);
Serial.println(“IP address: “);
IPAddress ip = WiFi.localIP();
Serial.println(ip);
digitalWrite(BUILTIN_LED, LOW);
bot.begin(); // launch Bot functionalities
Questo blocco, oltre a scrivere una serie di messaggi sulla seriale, fa due cose importanti: la prima accende il LED on board del NodeMCU (quindi siamo in grado di capire a colpo d’occhio che il NodeMCU si è collegato alla rete – il LED acceso; non collegato – lampeggia), la seconda inizializza l’oggetto che gestisce le comunicazioni con il server Telegram
Passiamo quindi al blocco loop
if (millis() > Bot_lasttime + Bot_mtbs) {
bot.getUpdates(bot.message[0][1]); // launch API GetUpdates up to xxx message
Bot_ParseMessages(); // parse messages
Bot_lasttime = millis();
}
L’IF serve a far eseguire il blocco tra parentesi solo se sono trascorsi Bot_mtbs millisecondi dall’ultimo update. All’interno del blocco, scarico gli eventuali messaggi (bot.getUpdates(bot.message[0][1])) e li elaboro (Bot_ParseMessages())
Ora tocca voi testarlo!
Buone vacanze e ci vediamo a Settembre 🙂
P.S. file da scaricare: ESP8266Telegram.ino[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][us_sharing facebook=”1″ twitter=”1″ gplus=”1″ linkedin=”” pinterest=””][/vc_column][/vc_row]
Ciao interessante questo telegram con esp8266 .la mia domanda è :come si fa a inviare a telegram lo stato di un pin ad esempio un sensore PIR ?
Ciao Giovanni, l’esempio del tutorial consente di interrogare l’esp8266 via telegram. Quindi potresti aggiungere un comando per farti restituire lo stato di un pin collegato ad un sensore (ad es. pir).
Ma se ti ho capito bene, tu vorresti che ti venissero notificate le intrusioni.
Per far questo c’è da fare un po’ di modifiche al codice. E’ fattibile ma esula dallo scopo di questo tutorial.
Infatti dovresti ragionare sulla logica di gestione degli eventi e gestire i destinatari autorizzati a ricevere le notifiche. Per dirlo in altre parole: quando rilevo movimento col sensore pir, manda una notifica a tizio, caio e sempronio. Poi per non farti inondare di notifiche dovresti impostare un intervallo di tempo tra una notifica e l’altra: se rilevo altri movimenti entro un minuto ad esempio, vale la prima notifica.
Grazie per la domanda. Potrebbe essere lo spunto per un altro tutorial.
Salve, mi sto cimentando con questo BOT e la mia intenzione sarebbe quella di inviare un’immagine jpg prelevata da una telecamera collegata all’esp8266. Da dove dovrei iniziare per visualizzare la foto su telegram? ci sono già degli esempi da cui attingere il codice?