Huella, bellagente, saluti, baci abbracci e buona domenica.
Qualche tempo fa avevo letto di uno che usava telegram per comandare il suo arduino, figo, e lo volevo fare anch'io, mi son fatto dare due link e ci ho provato.
Devo dire che si tratta di una libreria fatta bene, che prevede tanti bei casi, ma se devo dire di esserne stato soddisfatto direi una bugia, e grossa.
Macchinosa, e usa troppo gli oggetti stringa, appena ho cominciato a divertirmi la mia povera nodemcu si incatastava, povera piccola. quindi mi sono messo di buzzo buono, e ho stroncato l'intera libreria, sostituita con due/tre funzioni in santo C, senza Stringhe di liquerizia o altri santi da chiamare.
vi metto qui il programma che funzia, funzia abbastanza bene.
// la quarta zucca e' bianca
//una semplice interfaccia ai bot di Telegram
// librerie
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
WiFiClientSecure client;
// Dati connessione wifi
char ssid[] = "XXX"; // SSID
char password[] = "YYY"; // PSK
// token del bot
#define TOKEN "11111:AAAAAAAAA"
// variabili di appoggio
char testo[101]; // il messaggio in ricezione, lungo al massimo 100 caratteri
int lentesto;
unsigned long int ultimo; // il numero dell'ultimo messaggio ricevuto
unsigned long int appoggio; // il numero del messaggio in ricezione
unsigned long int mittente; // il numero del mittente ultimo messaggio
int passo = 10000; //tempo tra una richiesta e la successiva
unsigned long int ultimotempo; //ultima ricezione tentata
void setup() {
Serial.begin(9600);
// su il wifi
Serial.print(F("Connessione al wifi: "));
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.print(F("Connesso. IP: "));
IPAddress ip = WiFi.localIP();
Serial.println(ip);
}
void loop() {
// ogni passo millisecondi
if (millis() - ultimotempo > passo) {
ricevidalbot(); // lancio la ricezione
// controllo che sia arrivato un nuovo messaggio
if (appoggio > ultimo) {
// aggiorno l'ultimo messaggio ricevuto
ultimo = appoggio;
// stampo la stringa ricevuta
Serial.print(F("Updateid: "));
Serial.println (appoggio);
Serial.print(F("mittente: "));
Serial.println(mittente);
Serial.print(F("testo: "));
Serial.println(testo);
// ringrazio per avermi scritto
trasmettialbot(mittente, "grazie per avermi scritto");
}
else {
Serial.print(F("nulla di nuovo, ultimo update ricevuto: "));
Serial.println(ultimo);
}
}
}
void ricevidalbot(void) {
// connessione con telegram
ultimotempo = millis(); // aggiorno il timer
IPAddress server(149, 154, 167, 198);
if (client.connect(server, 443)) {
Serial.println(F(".... connesso al server"));
unsigned long ora;
client.print(F("GET /bot"));
client.print (TOKEN);
client.print (F("/getUpdates?offset="));
client.print (ultimo + 1);
client.println (F("&limit=1"));
// resetto la variabile di appoggio che mi serve per conteggiare il valore di ultimo update ricevuto
appoggio = 0;
// resetto la variabile di ultimo mittente
mittente = 0;
// svuoto il campo testo
testo[0] = '\0'; // basta il primo carattere, le stringhe sono terminate dallo \0
// il contatore di lunghezza del testo
lentesto = 0;
ora = millis();
while (millis() - ora < 1000) {
if (client.available()) {
// passo alla funzione di trattamento il carattere ricevuto
if (!tratta(client.read())) {
break;
// la tratta restituisce zero quando è il momento di troncare
};
}
}
}
}
void trasmettialbot(unsigned long int mittente, char messaggio[]) {
//trasmette al bot il messaggio
// connessione con telegram
IPAddress server(149, 154, 167, 198);
if (client.connect(server, 443)) {
Serial.println(F(".... connesso al server"));
client.print(F("GET /bot"));
client.print (TOKEN);
client.print (F("/sendMessage?chat_id="));
client.print (mittente);
client.print (F("&text="));
client.print (messaggio);
client.println();
}
}
int tratta(char c) {
// tratta carattere per caratttere il testo messaggio ricevuto da telegram
// riconosce le coppie di parentesi graffe
// riconosce alcuni campi
// restituisce zero per fermare
static int livello = 0; // il livello di rientro delle parentesi graffe
static int trovato = 0; // quale nome di oggetto è stato trovato
# define numoggetti 4
static char * oggetti[numoggetti] = {"none", "\"update_id\":", "chat\":\"id\":", "\"text\":\""};
// questo somiglia a un array di stringhe
// realmente e' un array di puntatori a stringa
// il primo elemento è messo a ciccare, per evitare trovato=0, che si confonde con trovato nulla
static int corrente[numoggetti];
// un array di posizioni correnti nell'array di stringhe
// Serial.println(c);
if (c == '{') {
livello++;
return livello;
}
if (c == '}') {
livello--;
// trovato=0;
return livello;
}
// ok, siamo nel corpo del messaggio
//devo riconoscere se stiamo leggendo il nome di un oggetto conosciuto
if (trovato) {
// abbiamo trovato un nome di oggetto (: compreso)
// adesso fino alla virgola o alla virgoletta
// se si tratta di una virgola
if (c == ',') {
trovato = 0;
// fine del valore
return 1;
}
// o di una virgoletta
if (c == '\"') {
trovato = 0;
// fine del valore
return 1;
}
}
// ok non è una virgola ne una virgoletta
// campi numerici
if (trovato == 1)
{ // updateid, che vale come ultimo messaggio
appoggio = appoggio * 10 + c - '0';
// traduco in intero
}
if (trovato == 2)
{ // mittente
mittente = mittente * 10 + c - '0';
// traduco in intero
}
// campi alfabetici, che per ora è solo text, corpo del messaggio
if (trovato == 3)
// siamo nel testo
if (lentesto <= 100) {
testo[lentesto] = c;
lentesto++;
testo[lentesto] = '\0'; // termina qui
}
else {
trovato = 0;
// tronco la lettura, per non sbordare, siamo oltre i 100 byte
}
else {
// non abbiamo ancora trovato il nome di un oggetto
// vado avanti a cercarlo
for (int i = 0; i < numoggetti; i++) {
//per ogni oggetto
if (c != oggetti[i][corrente[i]]) {
// non corrisponde
corrente[i] = 0;
}
else {
// corrisponde
corrente[i]++;
//avanza un passo
if (oggetti[i][corrente[i]] == '\0') {
// oggetto finito
// caso trovato
corrente[i] = 0; //torno indietro
trovato = i;
}
}
}
}
return 1; // OK in lettura
}