En este tutorial vamos a enviar la lectura de un sensor DHT22 (temperatura y humedad) obtenida con una NodeMCU ESP8266 a Telegram usando la API de Bot de Telegram.
El proceso es muy simple: cada 10 segundos vamos a leer los valores del sensor DHT22 y hacer una petición a la API de Telegram enviando la humedad y temperatura en el mensaje.
Instalando drivers y configurando entorno
En caso de que no hayas instalado tu NodeMCU ni le hayas cargado código por favor revisa el siguiente vídeo para una guía:
Token de Telegram e id de chat
En este post asumo que ya tienes tu token del Bot, mismo que el BotFather te debió brindar. Si no, solo habla con él en https://t.me/botfather y crea un nuevo Bot para obtener tu token.
También estoy suponiendo que ya conoces el id de chat, grupo o canal. Si no lo tienes puedes obtener el id de usuario reenviando un mensaje al Bot https://t.me/get_id_bot o https://t.me/JsonDumpBot (no estoy afiliado ni tengo relación con ellos) y estoy seguro de que debe haber distintas maneras de obtenerlo.
Lecturas recomendadas
Previamente en el blog te he enseñado a leer el sensor DHT22 para imprimir sus valores por pantalla y también para enviarlos a un servidor local. Por otro lado te acabo de enseñar a enviar un mensaje simple a Telegram usando la API de Bots.
Te recomiendo que leas las lecturas previamente señaladas y que intentes cada cosa por separado. Si bien el código presentado en el post funciona correctamente, es importante que conozcas y pruebes el funcionamiento de cada componente individual.
Instalando librerías
Vas a necesitar las librerías DHT sensor library y Adafruit Unified Sensor. Mi archivo de configuración platformio.ini
queda como se ve a continuación:
[env:nodemcuv2]
platform = espressif8266
board = nodemcuv2
framework = arduino
lib_deps =
adafruit/Adafruit Unified Sensor@^1.1.14
adafruit/DHT sensor library@^1.4.6
Tú puedes usar VSCode con PlatformIO como lo indico en el vídeo anterior, o usar tu IDE favorito siempre y cuando instales las librerías correctas.
Circuito
Como solo vamos a leer la temperatura y humedad del DHT22 con la ESP8266 y enviarla a Telegram, el circuito queda realmente simple. Aquí hay una imagen de guía:
Básicamente el positivo del DHT22 va en el 3V de la ESP8266, lo mismo para el GND.
El único cambio para este ejemplo es la salida de datos, misma que, aunque en la imagen va al D1
yo he conectado al D7
.
Código para DHT22 con Telegram
Una vez creado el lector y configurado el Token para el Bot de Telegram procedemos a escribir el código en el loop
. Ahí, cada 10 segundos vamos a hacer lo que se describe a continuación.
Leer la temperatura y humedad con readTemperature
y readHumidity
, almacenando esos valores en una variable de tipo flotante:
porcentajeDeHumedad = sensorDht.readHumidity();
temperaturaEnGradosCelsius = sensorDht.readTemperature();
A veces el sensor va a devolver NaN cuando no haya una lectura exitosa; por eso es que estamos validando que los valores sean numéricos y armando el mensaje que se va a enviar a Telegram concatenando y creando una cadena:
String temperaturaComoCadena = " - ";
String humedadComoCadena = " - ";
if (!isnan(temperaturaEnGradosCelsius))
{
temperaturaComoCadena = String(temperaturaEnGradosCelsius) + " °C";
}
if (!isnan(porcentajeDeHumedad))
{
humedadComoCadena = String(porcentajeDeHumedad) + " %";
}
String mensaje = "Temperatura: " + temperaturaComoCadena + "\nHumedad: " + humedadComoCadena;
Si quisieras enviar más datos simplemente modifica la variable mensaje. Este mensaje es el que será enviado a Telegram desde nuestra pequeña tarjeta ESP8266. Por ahora contiene la temperatura y humedad.
Finalmente armamos la carga útil que contiene el id de chat y el texto para enviarlo a la API de Telegram:
String url = "https://api.telegram.org/bot" + tokenTelegram + "/sendMessage";
String cargaUtil = "{\"chat_id\":\"" + idChat + "\",\"text\":\"" + mensaje + "\"}";
if (clienteHttp.begin(*clienteWifi, url))
{
clienteHttp.addHeader("Content-Type", "application/json", false, true);
int httpCode = clienteHttp.POST(cargaUtil);
if (httpCode > 0)
{
if (httpCode == HTTP_CODE_OK)
{
// Llegados a este punto podemos confiar en que el mensaje fue enviado
encenderLed();
}
}
Por favor fíjate en que en mi caso solo estoy encendiendo un LED para indicar el éxito de la petición, no estoy imprimiendo mensajes o notificando de otra manera, pero eres libre de hacerlo de la manera que tú prefieras.
Poniendo todo junto
Ya te he mostrado el código más importante pero no el completo. El código queda como se ve a continuación; solo no te olvides de instalar las librerías, configurar el token del bot, el id de chat, credenciales para la red Wi-Fi y el número de pin de la ESP8266 donde está conectado el DHT22.
#include <Arduino.h>
#include "DHT.h"
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
#define PIN_CONEXION D7 // PIN donde se conecta el Out del DHT22
#define TIPO_SENSOR DHT22
const String idChat = "";
const String tokenTelegram = "";
DHT sensorDht(PIN_CONEXION, TIPO_SENSOR);
float porcentajeDeHumedad, temperaturaEnGradosCelsius = 0;
const char *NOMBRE_RED_WIFI = "";
const char *CLAVE_RED_WIFI = "";
void encenderLed()
{
// Sí, para encenderlo le mandas un LOW
digitalWrite(LED_BUILTIN, LOW);
}
void apagarLed()
{
// Sí, para apagarlo le mandas un HIGH
digitalWrite(LED_BUILTIN, HIGH);
}
void parpadearLed(int veces, unsigned long cadaCuanto)
{
for (int i = 0; i < veces; i++)
{
encenderLed();
delay(cadaCuanto);
apagarLed();
delay(cadaCuanto);
}
}
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
sensorDht.begin();
parpadearLed(1, 200);
WiFi.mode(WIFI_STA);
WiFi.begin(NOMBRE_RED_WIFI, CLAVE_RED_WIFI);
while (WiFi.status() != WL_CONNECTED)
{
delay(1000);
parpadearLed(2, 200);
}
encenderLed();
}
void loop()
{
if ((WiFi.status() == WL_CONNECTED))
{
apagarLed();
porcentajeDeHumedad = sensorDht.readHumidity();
temperaturaEnGradosCelsius = sensorDht.readTemperature();
std::unique_ptr<BearSSL::WiFiClientSecure> clienteWifi(new BearSSL::WiFiClientSecure);
clienteWifi->setInsecure();
HTTPClient clienteHttp;
String temperaturaComoCadena = " - ";
String humedadComoCadena = " - ";
if (!isnan(temperaturaEnGradosCelsius))
{
temperaturaComoCadena = String(temperaturaEnGradosCelsius) + " °C";
}
if (!isnan(porcentajeDeHumedad))
{
humedadComoCadena = String(porcentajeDeHumedad) + " %";
}
String mensaje = "Temperatura: " + temperaturaComoCadena + "\nHumedad: " + humedadComoCadena;
String url = "https://api.telegram.org/bot" + tokenTelegram + "/sendMessage";
String cargaUtil = "{\"chat_id\":\"" + idChat + "\",\"text\":\"" + mensaje + "\"}";
if (clienteHttp.begin(*clienteWifi, url))
{
clienteHttp.addHeader("Content-Type", "application/json", false, true);
int httpCode = clienteHttp.POST(cargaUtil);
if (httpCode > 0)
{
if (httpCode == HTTP_CODE_OK)
{
// Llegados a este punto podemos confiar en que el mensaje fue enviado
encenderLed();
}
}
else
{
// Petición Ok pero código no es 200
parpadearLed(10, 200);
}
clienteHttp.end();
}
else
{
// Error http client begin
parpadearLed(5, 250);
}
}
else
{
// No hay Wifi
parpadearLed(2, 500);
}
delay(10000);
}
Con este código estarás leyendo efectivamente la temperatura y humedad usando el sensor DHT22 enviando los resultados a cualquier usuario en Telegram cada 10 segundos.
El código es totalmente open source así que puedes modificarlo para enviarlo en un intervalo más corto, leer más datos de sensores, etcétera.