Controlar dos leds desde Telegram con Servidor Esp8266




Presentación


Este proyecto es una modificacion de los anteriores para controlar el Funcionamiento de los Leds a partir de un Bot de Telegram.

El control de realiza a traves de una pagina web con funciones javascript dado que hasta el momento no me ha sido posible comunicar en forma directa el bot de telegram con la Esp8266

Para realizar esta comunicacion con una funcion en javascript capturo el ultimo mensaje del bot de telegram, este dato es pasado a otra funcion que verifica si es un mensaje nuevo, y si es nuevo lo envia al servidor para que realice la operacion correspondiente y a la vez envia un mensaje al bot de telegram informando la recepcion del mensaje.

Tambien se previo un mensaje especifico "Menu" que envie al bot de telegram los mensajes que comandan las funciones programadas en la placa.

La mayor deficiencia de este proyecto es que necesariamente para su funcionamiento debe haberse accedido a la pagina de la Esp8266 a traves un navegador para que se activen las funciones javascript.


Materiales


Placa Wemos D1 R1

Dos Leds


Montaje del proyecto en la placa Wemos D1 R1


Para utilizar la placa Wemos D1 R1 con MicroPython es necesario flashear primero la misma con el firmware correspondiente. En el caso de la utilizada en este modelo se utilizo el "v1.21.0 (2023-10-05) .bin" provisto por la pagina de Firmware ESP8266

Pueden usar esa version o alguna otra de la pagina, no todas las versiones son compatibles con todas las placas segun mi experiencia.

Para flashear la placa lo hago directamente desde un a terminal de linux abierta en la carperta donde trngo el firmware y utilizo la linea de comando: esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect -fm dout 0 esp8266-20220618-v1.19.1.bin.

Aqui cabe la misma aclaracion realizada con respecto al firmware, no todas las placas admiten la misma linea de comandos para grabar eñ firmware e incluso algunas lo hacen mejor con aplicaciones como Thonny. Hay que animarse y probar cambios cuando no funciona.

Una vez instalado el firmware en la placa utilizando la utilidad que viene provista por el IDE Thonny, o por aquella que ustedes utilicen elimino el archivo boot.py y copio el codigo que se detalla mas adelante

Ademas deben conectarse a la placa los dos leds conforme el diagrama puesto a continuacion:


Tambien debe copiarse en la placa esp8266 el modulo uaiohttpclient.py que se puede descargar de este link


Código


El código se ha escrito en un unico archivo main.py.




        from machine import Pin
        import uasyncio
        import network
        import utime
        import uaiohttpclient as aiohttp
        
        red = 'xxxxxxxxxxxx'
        clave = 'xxxxxxxxxxxxxxxxx'
        
        pin_04 = Pin(4, Pin.OUT, value=0)
        pin_05 = Pin(5, Pin.OUT, value=0)
        
        control1 = False
        control2 = False
        
        def conecta_wifi():
                    wifi = network.WLAN(network.STA_IF)
                    wifi.active(True)
                    wifi.connect(red, clave)
                    while wifi.isconnected() == False:
                        pass
                
                    print('Conectada a Wifi')
                    print('************************')
                    print('RED:     %s' % red)
                    print('IP:      %s\nSUBNET:  %s\nGATEWAY: %s\nDNS:     %s' % wifi.ifconfig()[0:4])
                    a = wifi.config('mac')
                    print('MAC:     {:02x}:{:02x}:{:02x}:{:02x}:{:02x}'.format(a[0],a[1],a[2],a[3],a[4]))
                    print('************************+')
        
        def crear_respuesta_http(solicitud):
            global control1
            global control2
            if solicitud.find('/?fecha=') == 6:
                print("recibe orden")
                print(solicitud.find('dato=prendeverde'))
                if solicitud.find('dato=actverde') == 25:
                        print('Activa Led verde')
                        control1 = True
                if solicitud.find('dato=desverde') == 25:
                        print('Desactiva Led verde')
                        control1 = False                
                if solicitud.find('dato=actrojo') == 25:
                        print('Activa Led rojo')
                        control2 = True
                if solicitud.find('dato=desrojo') == 25:
                        print('Desactiva Led rojo')
                        control2 = False
                
                pagina = """
        <!DOCTYPE HTML>
        <html>
            <head>
                <meta charset="UTF-8">
                <meta http-equiv="X-UA-Compatible" content="IE=edge">
                <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
                <title>Trabajo</title>
            </head>
            <body>
                <p>Mensaje enviado</p>
                <script>
                      function closeCurrentWindow() {
                            window.close();
                      }
                </script>
            </body>
        </html>
        """
            else:    
         
                pagina = """
        <!DOCTYPE HTML>
        <html>
            <head>
                <meta charset="UTF-8">
                <meta http-equiv="X-UA-Compatible" content="IE=edge">
                <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
                <title>Trabajo</title>
            </head>
            <body>
                <div id="caja">
                    <label>Fecha     :</label>
                    <label id="label1" ></label>
                    <br>
                    <label>Dato      :</label>
                    <label id="label2" ></label>
                </div>
            <script>
                var resfecha = "xxxxx";
                var dato = "Menu";
                setInterval('recargar()',5000);
        
                function respuesta() {
                    var datos = JSON.parse(this.responseText);
                    fecha = datos.result[0].message.date;
                    dato = datos.result[0].message.text;
                    if(resfecha != fecha){
                        if(dato == "Menu" || resfecha == "xxxxx"){
                        mensaje = "BOT DE CONTROL ESP8266 %0AEnviar comandos: %0Aactverde:      activar led verde %0Adesverde:      desactiva led verde %0Aactrojo:       activar led rojo %0Adesrojo:       desactivar led rojo %0AParaver este mensaje: Menu"
                        enviotele2 = window.open('https://api.telegram.org/bot000000000000:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/sendMessage?chat_id=1581658976&text=' + mensaje);
                        setTimeout(function(){ enviotele2.close(); }, 200);
                        }
                    resfecha = fecha
                    document.getElementById('label1').innerHTML=fecha;
                    document.getElementById('label2').innerHTML=dato;
                    enviotele = window.open('http://192.168.0.55/?fecha=' + fecha + '&dato=' + dato );
                    setTimeout(function(){enviotele.close(); }, 100);
                    mensaje = "Se recibio la instruccion: " + dato; 
                    enviotele1 = window.open('https://api.telegram.org/bot000000000000:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/sendMessage?chat_id=1581658976&text=' + mensaje);
                    setTimeout(function(){ enviotele1.close(); }, 200);
                    }
                }
        
                function recargar(){
                    var consulta = new XMLHttpRequest(); 
                    consulta.onload = respuesta; 
                    consulta.open('GET', 'https://api.telegram.org/bot000000000000:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/getUpdates?offset=-1');
                    consulta.send(); 
                }
            </script>
            </body>
        </html>
        """      
            return (pagina)
        
        async def conexion_servidor(lectura, escritura):
            print("Cliente conectado")
            solicitud = await lectura.read(1024)
            solicitud = str(solicitud)
            respuesta = crear_respuesta_http(solicitud)
            escritura.write(respuesta)
            await escritura.drain()
            lectura.close()
            await lectura.wait_closed()
            escritura.close()
            print("Conexion cerrada")
        
        async def contador():
            contador = 0                      
            while True:               
                print("contador")
                print(contador)
                await uasyncio.sleep(1)
                contador +=1
                
        async def led_verde():
            global control1
            while True:
                if (control1 == True):
                    pin_04.on()
                    print("Led verde encendido")
                    await uasyncio.sleep(3)
                    pin_04.off()
                    print("Led verde apaagado")
                await uasyncio.sleep(3)
         
        async def led_rojo():
            global control2
            while True:
                if (control2 == True):
                    pin_05.on()
                    print("Led rojo encendido")
                    await uasyncio.sleep(5)
                    pin_05.off()
                    print("Led rojo apagado")
                await uasyncio.sleep(5)
        
        conecta_wifi()
        print("Servidor funcionando...")
        servidor = uasyncio.start_server(conexion_servidor, '0.0.0.0', 80, 5)
        loop = uasyncio.get_event_loop()
        loop.create_task(servidor)
        loop.create_task(contador())
        loop.create_task(led_verde())
        loop.create_task(led_rojo())
        loop.run_forever()

    


Funcionamiento


Una vez iniciado el programa debemos acceder con un navegador a la IP que nuestra red le haya asignado a la placa y se abrira la siguiente pagina:


En la misma observaremos la fecha y el contenido de eltimo mensaje que haya en el bot de telegram cada vez que se actualice automaticamente, para que el sistema funcione la pagina debe estar abierta.

A futuro estoy buscando el modo de evitar que deba abrirse pagina web para su funcionamiento o que la misma se abra automaticamente, pero hasta ahora no lo he logrado.


Quedo disposición de quien quiera hacerme consultas o sugerencias mi correo electronico es carlosvaccaro1960@gmail.com