Hoje vamos criar um bot no
ESP8266/ESP32 para servir de contato no Telegram. Assim, podemos
modificar/verificar o estado de um relé e verificar a temperatura e umidade de
acordo com mensagens que enviamos para ele. Ou seja, é como se este contato
fosse uma pessoa real que estivesse executando os seus comandos, estes enviados
pelo programa de troca de mensagens.
Montagem
Atualizar o core do ESP8266
Em caso de problemas com o
ESP8266, na IDE do Arduino vá em:
Ferramentas->Placa->Gerenciar de
Placas...
Atualize o ESP8266 (no caso
utilizamos a versão 2.4.2)
Biblioteca ArduinoJson
Na IDE do Arduino vá em
Sketch->Incluir Biblioteca->Gerenciar Bibliotecas...
Instale ArduinoJson (no caso
utilizamos a versão 5.13.2)
Biblioteca UniversalTelegramBot
Na IDE do Arduino vá em
Sketch->Incluir Biblioteca->Gerenciar Bibliotecas...
Instale UniversalTelegramBot
Biblioteca SimpleDHT
Na IDE do Arduino vá em
Sketch->Incluir Biblioteca->Gerenciar Bibliotecas...
Instale SimpleDHT
Criando um Bot no Telegram
Abra o Telegram e pesquise por
botfather. Selecione o com a marca azul
Nesta tela clique em COMEÇAR
O BotFather te mostrará
algumas opções
Digite /newbot
Digite o nome que queira para
seu bot
Digite o nome de usuário para
seu bot. Deve terminar com bot (Exemplo: TesteFKBot).
Guarde o token gerado para
substituir no código fonte .ino
TelegramBot.ino
Declarações e variáveis
#if defined(ESP8266) #include <ESP8266WiFi.h> #else #include <WiFi.h> #endif #include <WiFiClientSecure.h> #include <UniversalTelegramBot.h> #include <SimpleDHT.h> //Pino onde está o Relê #define RELAY_PIN 5 //Pino onde está o DHT22 #define DHT_PIN 4 //Intervalo entre as checagens de novas mensagens #define INTERVAL 1000 //Token do seu bot. Troque pela que o BotFather te mostrar #define BOT_TOKEN "000000000:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" //Troque pelo ssid e senha da sua rede WiFi #define SSID "SSID" #define PASSWORD "12345678"
Comandos e definições
//Comandos aceitos const String LIGHT_ON = "ligar a luz"; const String LIGHT_OFF = "desligar a luz"; const String CLIMATE = "clima"; const String STATS = "status"; const String START = "/start"; //Objeto que realiza a leitura da temperatura e umidade SimpleDHT22 dht; //Estado do relê int relayStatus = HIGH; //Cliente para conexões seguras WiFiClientSecure client; //Objeto com os métodos para comunicarmos pelo Telegram UniversalTelegramBot bot(BOT_TOKEN, client); //Tempo em que foi feita a última checagem uint32_t lastCheckTime = 0; //Quantidade de usuários que podem interagir com o bot #define SENDER_ID_COUNT 2 //Ids dos usuários que podem interagir com o bot. //É possível verificar seu id pelo monitor serial ao enviar uma mensagem para o bot String validSenderIds[SENDER_ID_COUNT] = {"012345678", "123456789"};
Setup
void setup() { Serial.begin(115200); //Inicializa o WiFi e se conecta à rede setupWiFi(); //Coloca o pino do relê como saída e enviamos o estado atual pinMode(RELAY_PIN, OUTPUT); digitalWrite(RELAY_PIN, relayStatus); }
SetupWiFi
void setupWiFi() { Serial.print("Connecting to SSID: "); Serial.println(SSID); //Inicia em modo station e se conecta à rede WiFi WiFi.mode(WIFI_STA); WiFi.begin(SSID, PASSWORD); //Enquanto não estiver conectado à rede while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(500); } //Se chegou aqui está conectado Serial.println(); Serial.println("Connected"); }
Loop
void loop() { //Tempo agora desde o boot uint32_t now = millis(); //Se o tempo passado desde a última checagem for maior que o intervalo determinado if (now - lastCheckTime > INTERVAL) { //Coloca o tempo de útlima checagem como agora e checa por mensagens lastCheckTime = now; int numNewMessages = bot.getUpdates(bot.last_message_received + 1); handleNewMessages(numNewMessages); } }
handleNewMessages
void handleNewMessages(int numNewMessages) { for (int i=0; i<numNewMessages; i++) //para cada mensagem nova { String chatId = String(bot.messages[i].chat_id); //id do chat String senderId = String(bot.messages[i].from_id); //id do contato Serial.println("senderId: " + senderId); //mostra no monitor serial o id de quem mandou a mensagem boolean validSender = validateSender(senderId); //verifica se é o id de um remetente da lista de remetentes válidos if(!validSender) //se não for um remetente válido { bot.sendMessage(chatId, "Desculpe mas você não tem permissão", "HTML"); //envia mensagem que não possui permissão e retorna sem fazer mais nada continue; //continua para a próxima iteração do for (vai para próxima mensgem, não executa o código abaixo) } String text = bot.messages[i].text; //texto que chegou if (text.equalsIgnoreCase(START)) { handleStart(chatId, bot.messages[i].from_name); //mostra as opções } else if (text.equalsIgnoreCase(LIGHT_ON)) { handleLightOn(chatId); //liga o relê } else if(text.equalsIgnoreCase(LIGHT_OFF)) { handleLightOff(chatId); //desliga o relê } else if(text.equalsIgnoreCase(CLIMATE)) { handleClimate(chatId); //envia mensagem com a temperatura e umidade } else if (text.equalsIgnoreCase(STATS)) { handleStatus(chatId); //envia mensagem com o estado do relê, temperatura e umidade } else { handleNotFound(chatId); //mostra mensagem que a opção não é válida e mostra as opções } }//for }
validateSender
boolean validateSender(String senderId) { //Para cada id de usuário que pode interagir com este bot for(int i=0; i<SENDER_ID_COUNT; i++) { //Se o id do remetente faz parte do array retornamos que é válido if(senderId == validSenderIds[i]) { return true; } } //Se chegou aqui significa que verificou todos os ids e não encontrou no array return false; }
handleStart
void handleStart(String chatId, String fromName) { //Mostra Olá e o nome do contato seguido das mensagens válidas String message = "<b>Olá " + fromName + ".</b>\n"; message += getCommands(); bot.sendMessage(chatId, message, "HTML"); }
getCommands
String getCommands() { //String com a lista de mensagens que são válidas e explicação sobre o que faz String message = "Os comandos disponíveis são:\n\n"; message += "<b>" + LIGHT_ON + "</b>: Para ligar a luz\n"; message += "<b>" + LIGHT_OFF + "</b>: Para desligar a luz\n"; message += "<b>" + CLIMATE + "</b>: Para verificar o clima\n"; message += "<b>" + STATS + "</b>: Para verificar o estado da luz e a temperatura"; return message; }
handleLightOn
void handleLightOn(String chatId) { //Liga o relê e envia mensagem confirmando a operação relayStatus = LOW; //A lógica do nosso relê é invertida digitalWrite(RELAY_PIN, relayStatus); bot.sendMessage(chatId, "A luz está <b>acesa</b>", "HTML"); }
handleLightOff
void handleLightOff(String chatId) { //Desliga o relê e envia mensagem confirmando a operação relayStatus = HIGH; //A lógica do nosso relê é invertida digitalWrite(RELAY_PIN, relayStatus); bot.sendMessage(chatId, "A luz está <b>apagada</b>", "HTML"); }
handleClimate
void handleClimate(String chatId) { //Envia mensagem com o valor da temperatura e da umidade bot.sendMessage(chatId, getClimateMessage(), ""); }
getClimateMessage
String getClimateMessage() { //Faz a leitura da temperatura e da umidade float temperature, humidity; int status = dht.read2(DHT_PIN, &temperature, &humidity, NULL); //Se foi bem sucedido if (status == SimpleDHTErrSuccess) { //Retorna uma string com os valores String message = ""; message += "A temperatura é de " + String(temperature)+ " °C e "; message += "a umidade é de " + String(humidity) + "%"; return message; } //Se não foi bem sucedido retorna um mensagem de erro return "Erro ao ler temperatura e umidade"; }
handleStatus
void handleStatus(String chatId) { String message = ""; //Verifica se o relê está ligado ou desligado e gera a mensagem de acordo if(relayStatus == LOW) //A lógica do nosso relê é invertida { message += "A luz está acesa\n"; } else { message += "A luz está apagada\n"; } //Adiciona à mensagem o valor da temperatura e umidade message += getClimateMessage(); //Envia a mensagem para o contato bot.sendMessage(chatId, message, ""); }
handleNotFound
void handleNotFound(String chatId) { //Envia mensagem dizendo que o comando não foi encontrado e mostra opções de comando válidos String message = "Comando não encontrado\n"; message += getCommands(); bot.sendMessage(chatId, message, "HTML"); }
Interagindo com o Bot no Telegram
Vá até o BotFather e clique no
link para conversar com o bot
Clique em COMEÇAR
Envie os comandos e verifique
as mensagens que o bot retorna
Faça o download dos arquivos
17 Comentários
Ola Fernando, muito bom este artigo, só uma dúvida, para usar com um ESP32 eu utilizo a mesma biblioteca?
ResponderExcluirGostaria de saber também, estou tentando mas da Erro ao Compilar... ESP-WROOM-32
ExcluirEu estava tendo o mesmo problema, incluí a biblioteca ArduinoJson.h (que ele até ensina como instalar na IDE), mas mesmo assim continuava a dar o erro, percebi que a versão está diferente da que ele usou, coloquei na mesma versão e o problema foi resolvido.
ExcluirGostaria de desenvolver um sistema que informasse em tempo real a temperatura de um liquido que fica dentro de um tanque de um caminhão. Será que tem como?
ResponderExcluirMuito bom, parabéns pelo artigo
ResponderExcluirboa tarde no meu aparece que não tenho permissão
ResponderExcluirSó fazer esse procedimento aqui amigo e depois colar no seu codigo
Excluir//É possível verificar seu id pelo monitor serial ao enviar uma mensagem para o bot
String validSenderIds[SENDER_ID_COUNT] = {"12345678", "12345678"};
Boa tarde. Qual a comunidade para discutir sobre o artigo ?
ResponderExcluirÓtimo artigo ser usado não a barreira
ResponderExcluire Para o ESP32:, estou tentando mas da Erro ao Compilar... ESP-WROOM-32
ResponderExcluir(Erro compilando para a Placa DOIT ESP32 DEVKIT V1)
Ótima Aula, por favor me fala dos os componentes usados nesse exemplo.
ResponderExcluirValeu pelo conteúdo... parabéns...
ResponderExcluirMuito interessante. Funcionou muito bem. Só não foi mostrado no video como achar o sender id para incluir na string de permissões. Descobri o id pela serial. Não vi como achar pelo proprio Telegram.
ResponderExcluiroi fernando bom projeto..so que esse telegram não que funcionar comigo não..kkk..deu tudo certo a compilação e o envio para o esp 8266 mcu lolin so que monitor serial dar conectado mando o comando que voce deixou o mesmo (ligar a luz) so quem nem manda o comando de retorno com o Led fica aceso apaga nem acende .. dar para voce me dizer qual o problema..e ja testei com outros exemplos de outras pessoas nem conectado dar esse pelo menos deu conectado so que mando os comandos e não obedece...
ResponderExcluirParou de funcionar pra mim, estava normsl e parou.
ExcluirOlá, pessoal!
ResponderExcluirAlguém sabe se é possível implementar esse projeto usando GPRS com um SIM808 ao invés de wifi? O projeto se encaixa com o que preciso, mas no meu caso a mobilidade é essencial.
Valeu, pessoal!
Olá Fernando. O código não esta rodando, poderia verificar por favor?
ResponderExcluir