Telegrambot
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 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.
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 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.
code: [select]
// 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 0 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 0 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 un array di stringhe
// realmente e' un array di puntatori stringa
// il primo elemento è messo 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 100 byte
}
else {
// non abbiamo ancora trovato il nome di un oggetto
// vado avanti cercarlo
(int = 0; < 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
}
c'è poco da commentare, credo, il programma è ben commentato di suo. limiti:
riceve un solo messaggio per volta, il più vecchio nella catasta di ricezione di telegram, ma tanto lo da subito per ricevuto e quindi la prossima volta ne riceve un'altro
accetta solo massimo 100 caratteri, dovrei dire primi 100, non si lamenta se ne arrivano di più, li scarta.
rispetto alle librerie più conosciute usa unsigned long per gli utenti e per messaggi, come dice papà telegram. interessante che la lavorazione del testo viene fatta mano mano che arriva, carattere per carattere, questo evita di dover usare stringhe di liquerizia e non richiede nemmeno grandi buffer di testo
provate e fatemi sapere
riceve un solo messaggio per volta, il più vecchio nella catasta di ricezione di telegram, ma tanto lo da subito per ricevuto e quindi la prossima volta ne riceve un'altro
accetta solo massimo 100 caratteri, dovrei dire primi 100, non si lamenta se ne arrivano di più, li scarta.
rispetto alle librerie più conosciute usa unsigned long per gli utenti e per messaggi, come dice papà telegram. interessante che la lavorazione del testo viene fatta mano mano che arriva, carattere per carattere, questo evita di dover usare stringhe di liquerizia e non richiede nemmeno grandi buffer di testo
provate e fatemi sapere
Arduino Forum > International > Italiano > Software (Moderator: leo72) > Telegrambot
arduino
Comments
Post a Comment