Chatbot: Telegram + Python + Arduino

Publicado por

Actualmente los chatbots se están posicionando como una de las tecnologías más prometedoras para la sociedad. Estos agentes funcionan a través del procesamiento del lenguaje natural, que puede ser a través de la voz o mensajes de texto, y tienen como función mantener conversaciones mediante Inteligencia Artificial con las personas. Cada día son más utilizados para resolver problemas de la vida cotidiana, principalmente por empresas que desean dar soporte o atención a sus clientes, ya que estos permiten dar respuestas rápidas a preguntas frecuentes.

Con esta nota aprenderás a crear un chatbot en Telegram, para conectarlo con un Arduino a través de Python y poder manipular algunos LED y sensores a través del chatbot.

 Componentes para el prototipo

  • 1 Arduino UNO
  • 1 Sensor de temperatura y humedad DHT11
  • 1 Sensor de ultrasonidos HC-SR04
  • 3 LED de cualquier color
  • 1 Protoboard
  • Cables para conexión

Diagrama de conexión de componentes

Conectamos todos los componentes al Arduino como se muestra en el siguiente diagrama.

Diagrama de conexión de componentes de Arduino

Software necesario

  • Python 2.7 o superior
  • IDE de Arduino
  • Biblioteca DHT11 cargada en el IDE de Arduino
  • Telegram

Previamente instalado el software necesario y armado el prototipo, se deben seguir las siguientes instrucciones:

1. Creación de bot en Telegram

Ingresar a Telegram y buscar a @BotFather para crear el bot de este prototipo. Una vez que se inicie la conversación con este bot:

  1. Escribir el comando /start
  2. Leer la lista de comandos que mostrará
  3. Escribir el comando /newbot
  4. Escribir el nombre y usuario para el chatbot. En caso de que ya existan se deben escribir otro nombre y usuario hasta que sean aceptados.

Una vez creado el bot mostrará un token en pantalla que debe ser guardado para su uso posterior.

2. Código de Arduino

Se debe cargar el siguiente código escrito en lenguaje C, en la tarjeta Arduino.

#include "DHT.h" //Biblioteca DHT para el sensor de temperatura y humedad
#define pinLeeDHT 3 //Define el pin que será encargado de leer el sensor
#define tipoDHT DHT11 //Define el tipo de sensor

//Crea un objeto DHT
DHT dht(PinLeeDHT, TipoDHT);

//Variables para manipular los leds
const int led1 = 12;
const int led2 = 2;
const int led3 = 13;
String estado_led1;
String estado_led2;
String estado_led3;

//Variables para manipular del sensor de distancia
const int EchoPin = 5;
const int TriggerPin = 6;
float distancia;
long tiempo;


//Variable para guardar los valores recibidos desde Python
unsigned int dato;

void setup() {
    Serial.begin(9600); //Se inicializa la comunicacion Serial a 9600 Baudios
    pinMode(led1,OUTPUT);
    pinMode(led2,OUTPUT); //Se define los pines de los leds como Salidas
    pinMode(led3, OUTPUT);
    pinMode(TriggerPin, OUTPUT);
    pinMode(EchoPin, INPUT);
}

void loop() {
    //Se comprueba que la comunicacion serial este disponible
    while(Serial.available()>0){
    //Se lee el puerto serial y se guardan los valores
        dato=Serial.read();

        //Enciende o apaga los leds
        if(dato=='Y'){
            digitalWrite(led1,HIGH);
            estado_led1="luz 1 encendida ";
        }

        if(dato=='N'){
            digitalWrite(led1,LOW);
            estado_led1="luz 1 apagada ";
        }

        if(dato=='E'){
            digitalWrite(led2,HIGH);
            estado_led1="luz 2 encendida ";
        }

       if(dato=='F'){
            digitalWrite(led2,LOW);
            estado_led1="luz 2 apagada ";
       }

       //Reporta la temperatura o humedad
       if(dato=='T')
            Serial.println(int(dht.readTemperature())+String("°C"));
       
       if(dato=='H')
            Serial.println(int(dht.readHumidity())+String("%"));

       //Reporta movimiento a cierta distancia
       if(dato=='M')
            Serial.println(distancia);

       //Enciende todas las luces
       if(dato=='X'){
            digitalWrite(led1,HIGH);
            digitalWrite(led2,HIGH);
            digitalWrite(led3,HIGH);
       }

       //Apaga todas las luces
       if(dato=='W'){
           digitalWrite(led1,LOW);
           digitalWrite(led2,LOW);
           digitalWrite(led3,LOW);
       }

       //Genera el reporte general
       if(dato=='R')
           Serial.println(String(" temperatura ")
            +int(dht.readTemperature())
            +String("°C, ")
            +String("humedad ")
            +int(dht.readHumidity())
            +String("%, ")
            +String("movimiento a la distancia ")
            +float(distancia)
            +String(", ")
            +String(estado_led1+" "+estado_led2+" "+estado_led3));
    }

    //Lee datos del sensor de distancia

    digitalWrite(TriggerPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(TriggerPin, LOW);

    tiempo = (pulseIn(EchoPin, HIGH)/2);
    distancia = float(tiempo * 0.0343);

    if (distancia <= 10) {
        digitalWrite(led3 , HIGH);
        estado_led3 = "luz de movimiento encendida ";
    }
    else {
        digitalWrite(led3 , LOW);
        estado_led3 = "luz de movimiento apagada ";
    }

    delay(1000);
}

3. Código en Python

Este código permite establecer la conexión entre la tarjeta de Arduino y el bot de Telegram. Se recomienda ejecutarlo desde la terminal.

#!/usr/bin/python
import telepot, time, serial, sys
ser = serial.Serial('/dev/ttyACM0', 9600)

print('Bot')
print('Esperando acciones...')
def handle(msg):
usuario = msg['from']['first_name']

content_type, chat_type, chat_id = telepot.glance(msg)

if (content_type == 'text'):
    comando = msg['text']
    print ('Comando obtenido: %s' % comando)
    
if '/start' in comando:
    bot.sendMessage(chat_id, "Hola,
                "+userName
                +"\n"+"te muestro la lista de acciones que puedo reconocer:"+"\n"
                +"Encender luz 1"+" -Enciendo la luz 1"+"\n"
                +"Apagar luz 1"+" -Apago luz 1"+"\n"
                +"Encender luz 2"+" -Enciendo la luz 2"+"\n"
                +"Apagar luz 2"+" -Apago la luz 2"+"\n"
                +"Humedad"+" -Te muestro la Humedad en el ambiente"+"\n"
                +"Movimiento"
                +" -Si detecto movimiento enciendo una luz de alerta"+"\n"
                +"Encender todas las luces"+" -Enciendo todas las luces"+"\n"
                +"Apagar todas las luces"+" -Apago todas las luces"+"\n"
                +"Temperatura"+" -Te muestro la temperatura"+"\n"
                +"Reporte general"
                +" -Te muestro el estado de todos los dispositivos"+"\n"
                +"/start"+" -Te muestro esta lista")
                
elif 'Encender luz 1' in comando:
    ser.write('Y')
    bot.sendMessage(chat_id, "Luz 1 encendida")
    
elif 'Apagar luz 1' in comando:
    ser.write('N')
    bot.sendMessage(chat_id, "Luz 1 apagada")

elif 'Encender luz 2' in comando:
    ser.write('E')
    bot.sendMessage(chat_id, "Luz 2 encendida")

elif 'Apagar luz 2' in comando:
    ser.write('F')
    bot.sendMessage(chat_id, "Luz 2 apagada")

elif 'Temperatura' in comando:
    ser.write('T')
    linea = ser.readline()
    bot.sendMessage(chat_id, "Temperatura: " +linea)

elif 'Movimiento' in comando:
    ser.write('M')
    linea = ser.readline()
    bot.sendMessage(chat_id, "Se detecto movimiento a la distancia: " +linea)

elif 'Humedad' in comando:
    ser.write('H')
    linea = ser.readline()
    bot.sendMessage(chat_id, "Humedad Relativa: " +linea)

elif 'Encender todas las luces' in comando:
    ser.write('X')
    bot.sendMessage(chat_id, "Todas las luces encendidas")

elif 'Apagar todas las luces' in comando:
    ser.write('W')
    bot.sendMessage(chat_id, "Todas las luces apagadas")

elif 'Reporte general' in comando:
    ser.write('R')
    linea = ser.readline()
    bot.sendMessage(chat_id, "Reporte general: " +linea)

else:
    bot.sendMessage(chat_id, "Lo siento, no reconozco esa frase")

//En esta instrucción se utiliza el token que se guardo de Telegram.
bot = telepot.Bot('token de telegram')

bot.message_loop(handle)

//Espera por nuevos mensajes
while 1:
    time.sleep(20)

Se ejecuta el script desde una terminal: python bot.py

Una vez que ya está ejecutado puede ser utilizado de la siguiente manera:

  • Para poder utilizar el bot es necesario que el prototipo esté previamente instalado.
  • Ingresa a la app de Telegram desde tu smartphone y busca tu bot y seleccionalo.
  • Después toca el botón iniciar, que aparece en la parte inferior de la pantalla.
  • Te mostrará un menú de acciones que puedes solicitar.
  • Listo, ya puedes utilizarlo.

Demostración

11 comments

    1. ¡Hola!
      El arduino se comunica con otros dispositivos a través de los puertos serial. En este caso se comunica el arduino con Telegram por medio de los paquetes de python: telepot y serial.

    1. ¡Hola!

      El script de python se debe ejecutar en la terminal de tu computadora, para que funcione se tiene que sustituir el token que se obtuvo de telegram en la siguiente segmento de código:

      //En esta instrucción se utiliza el token que se guardo de Telegram.
      bot = telepot.Bot(‘token de telegram’)

      Saludos.

      1. hola , que parte del codigo es la programación de luz ? , quiero hacer pruebas en mi proyecto de titulación y quisiera monitorear solamente la humedad del suelo y la temperatura ambiente

        1. la otra cosa que descubrí , es que si haces la programación en un doc txt y despues guardas como archivo de lectura de python , igualmente te admite la interconexión de telegram con python

          1. Sí, de hecho cualquier código de cualquier lenguaje de programación que escribas puedes hacerlo en cualquier editor de texto, no es necesario tener un IDE especial para eso, basta con que al guardarlo le des la extensión y formato adecuado al archivo.

        2. ¡Hola!
          En el código de Arduino todas las partes que mencionan los led’s son los que corresponden a la luz, en el código de Python son todas las partes que mencionan el encendido y apagado de luces. Para lo que quieres hacer debes omitir esas partes.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *