Compare commits

..

2 Commits

Author SHA1 Message Date
52cd694a41 edit readme y arreglos menores 2022-04-20 22:23:18 -04:00
da563be55d Reestructuración - separación de la vista 2022-04-20 15:56:56 -04:00
7 changed files with 666 additions and 349 deletions

3
.gitignore vendored
View File

@ -1 +1,4 @@
__pycache__/
caldera_esp/confidencial.h caldera_esp/confidencial.h
esp_conf.cfg
TODO.txt

134
README.md
View File

@ -1,82 +1,80 @@
# Automatizacion de Caldera # Automatizacion de Caldera
***Control de encendido para caldera electrica.***
Enciende o apaga el termo según configuración. Admite hasta dos
horarios de funcionamiento al día, ajustables en modo 3.
El funcionamiento autonomo es la opción por defecto (modo 1).
Funcionamiento manual espera instrucción para realizar acción de
encendido o apagado (modo 5).
Hora y fecha ajustables en el modo 2
Posiciones del servo al encender o apagar el termo (modo 4).
Son dos posiciones, ya que el servo realiza movimiento repetitivo
con para asegurar el accionamiento mecánico del interruptor del termo.
El modo 6 permite mover libremente el servo (desde 16 hasta 144).
Útil para probar ajustes.
Enciende o apaga el termo según configuración. Admite hasta dos horarios
de funcionamiento al día, ajustables en modo 3.
El funcionamiento autonomo es la opción por defecto (modo 1).
Funcionamiento manual espera instrucción para realizar acción de encendido
o apagado (modo 5).
Hora y fecha ajustables en el modo 2.
Hardware utilizado: Posiciones del servo al encender o apagar el termo (modo 4). Son dos posiciones,
- ATmega328p (ArduinoNano old bootloader) ya que el servo realiza movimiento repetitivo para asegurar el accionamiento
- RTC-DS3231 mecánico del interruptor del termo.
- Servo
- esp8266 (ESP01)
Arduino funciona de forma autonoma, no requiere del módulo wifi. El modo 6 permite mover libremente el servo (desde 16 hasta 144). Útil para probar ajustes.
El ESP-01 funciona como interface web entre el usuario y el puerto serie de arduino.
caldera.sh: utilidad para enviar controlar caldera por terminal. ### Hardware utilizado:
- [ATmega328p](https://en.wikipedia.org/wiki/Arduino_Nano) (ArduinoNano old bootloader)
- [Real time clock](https://en.wikipedia.org/wiki/Real-time_clock) (RTC-DS3231)
- [Servo](https://es.wikipedia.org/wiki/Servomotor)
- [esp8266](https://en.wikipedia.org/wiki/ESP8266) (ESP01)
- [buck converter](https://en.wikipedia.org/wiki/Buck_converter)
**Arduino** funciona de forma autonoma, no requiere del módulo wifi.
**ESP-01** funciona como interface web basica entre el usuario y el puerto serie de arduino.
### Herramientas de control (scripts)
- [caldera.sh](https://gitea.kickto.net/SyDeVoS/Caldera-ino/src/branch/master/scripts#bash) (bash)
- [caldera.py](https://gitea.kickto.net/SyDeVoS/Caldera-ino/src/branch/master/scripts#python) (python)
----- -----
## Control de horario de encendido caldera electrica ## Arduino
Control de horario de encendido caldera electrica.
Trabaja de forma autonoma y/o comandado por puerto serie (**115200 baudio**). Trabaja de forma autonoma y/o comandado por puerto serie (**115200 baudio**).
* 3 Modos de Operación * 3 Modos de Operación
- Automatizado (1, por defecto) - Automatizado (1, por defecto)
- Manual (5) - Manual (5)
- Libre (6) - Libre (6)
* 3 Modos de Configuracion * 3 Modos de Configuración
- Configuracion de fecha y hora (2) - Configuración fecha y hora (2)
- Configuracion horas de encendido y apagado (3) - Configuración horas de encendido y apagado (3)
- Configuracion de posiciones de encendido y apagado (4) - Configuración de posiciones de encendido y apagado (4)
Arduino envia cada segundo los valores actuales de las variables de control al puerto serie. Arduino envia cada segundo los valores actuales de las variables de control al puerto serie.
ej: `1,0,5,7,16,18,120,90,45,62,1,42,24,14,7,2021`
``` ```
ej. 1____________________________________________ modo
1,0,5,7,16,18,120,90,45,62,1,42,24,14,7,2021 | 0__________________________________________ estado termo (O=apagado, 1=Encendido)
| | 5________________________________________ hora de encendido
1 > modo, | | | 7______________________________________ hora de apagado
| 0 > estado termo (O = apagado, 1 = Encendido) | | | | 16___________________________________ 2da hora de encendido (opcional)
| | 5 > hora de encendido | | | | | 18________________________________ 2da hora de apagado (opcional)
| | | 7 > hora de apagado | | | | | | 120____________________________ 1ra posicion encendido
| | | | 16 > 2da hora de encendido (opcional) | | | | | | | 90_________________________ 2ra posicion encendido
| | | | | 18 > 2da hora de apgado (opcional) | | | | | | | | 45______________________ 1ra posicion apagado
| | | | | | 120 > 1ra posicion encendido | | | | | | | | | 62___________________ 2ra posicion apagado
| | | | | | | 90 > 2ra posicion encendido | | | | | | | | | | 1_________________ hora en RTC
| | | | | | | | 45 > 1ra posicion apagado | | | | | | | | | | | 42______________ minutos en RTC
| | | | | | | | | 62 > 2ra posicion apagado | | | | | | | | | | | | 24___________ segundos en RTC
| | | | | | | | | | 1 > hora en RTC | | | | | | | | | | | | | 14________ dia en RTC
| | | | | | | | | | | 42 > minutos en RTC | | | | | | | | | | | | | | 7______ mes en RTC
| | | | | | | | | | | | 24 > segundos en RTC | | | | | | | | | | | | | | | 2021_ año en RTC
| | | | | | | | | | | | | 14 > dia en RTC 1,0,5,7,16,18,120,90,45,62,1,42,24,14,7,2021
| | | | | | | | | | | | | | 7 > mes en RTC
| | | | | | | | | | | | | | | 2021 > año en RTC
1,0,5,7,16,18,120,90,45,62,1,42,24,14,7,2021
``` ```
----- -----
## ESP01 ## ESP01
Establece comunicación serial con arduino (**115200 baudio**). Establece comunicación serial con arduino (**115200 baudio**).
Interface web sencilla para consulta y configuraciones Interface web básica para consulta y configuraciones.
Archivo de configuracion ***confidencial.h*** Archivo de configuracion ***confidencial.h***
```c ```c
@ -85,27 +83,28 @@ const char* password = "password";
``` ```
#### Urls #### Urls
* '**/**' : muestra valores actuales de variables. * **/** : muestra valores actuales de variables.
- ej. http://192.168.65.10/ - ej. `http://192.168.65.10/`
* '**/accion**' : accionamiento manual, espera argumentos on u off. * '**/accion** : accionamiento manual, espera argumentos on u off.
- ej. http://192.168.65.10/accion?mod=5&acc=on - ej. `http://192.168.65.10/accion?mod=5&acc=on`
* '**/sethora**' : configurar de fecha y hora. * **/sethora** : configurar de fecha y hora.
- ej. http://192.168.65.10/sethora?mod=2&dia=14&mes=7&año=2021&hrs=1&mins=33&segs=24 - ej. `http://192.168.65.10/sethora?mod=2&dia=14&mes=7&año=2021&hrs=1&mins=33&segs=24`
* '**/horasAcc**' : configurar horas de funcionamiento. * **/horasAcc** : configurar horas de funcionamiento.
- ej. http://192.168.65.10/horasAcc?mod=3&hrOn1=5&hrOff1=7&hrOn2=16&hrOff2=18 - ej. `http://192.168.65.10/horasAcc?mod=3&hrOn1=5&hrOff1=7&hrOn2=16&hrOff2=18`
* '**/setservo**' : configurar posiciones de encendido y apagado. * **/setservo** : configurar posiciones de encendido y apagado.
- ej. http://192.168.65.10/setservo?mod=4&posOn1=110&posOn2=85&posOff1=45&posOff2=62 - ej. `http://192.168.65.10/setservo?mod=4&posOn1=110&posOn2=85&posOff1=45&posOff2=62`
* '**/setlibre**' : Mover servo libremente (15 < posicion > 165). * **/setlibre** : Mover servo libremente (15 < posicion > 165).
- ej. http://192.168.65.10/setlibre?mod=6&pos=125 - ej. `http://192.168.65.10/setlibre?mod=6&pos=125`
* '**/auto**' : Modo autonomo. * **/auto** : Modo autonomo.
- ej. http://192.168.65.10/auto - ej. `http://192.168.65.10/auto`
----- -----
## Utilidades ## Utilidades
Scripts para enviar peticiones web al ESP. Scripts para enviar peticiones web al ESP.
### caldera.sh ### Bash
[caldera.sh](https://gitea.kickto.net/SyDeVoS/Caldera-ino/src/branch/master/scripts#bash)
``` ```
============================== ==============================
@ -134,6 +133,7 @@ const char* password = "password";
``` ```
### caldera.py ### Python
[caldera.py](https://gitea.kickto.net/SyDeVoS/Caldera-ino/src/branch/master/scripts#python)
![python_script](./scripts/script_python.png) ![python_script](./scripts/script_python.png)

View File

@ -1,7 +1,25 @@
## Utilidades # Utilidades
Scripts para enviar peticiones web al ESP. Scripts para enviar peticiones web al ESP.
### caldera.sh ## Bash
```
─ 📂️ scripts
├── 📄️ caldera.sh
└── 📄️ esp_conf.cfg
```
Archivo de configuración
***./esp_conf.cfg***
```cfg
[esp01]
URL = <direcion_ESP>
```
Dependencias
- curl
- grep
- cut
Correr: ` ./caldera.sh `
``` ```
============================== ==============================
@ -29,7 +47,27 @@
Ingresa Opcion : Ingresa Opcion :
``` ```
----
### caldera.py ## Python
```
─ 📂️ scripts
├── 📄️ caldera.py
├── 📄️ esp_conf.cfg
└── 📄️ vista_term.py
```
Archivo de configuración
***./esp_conf.cfg***
```cfg
[esp01]
URL = <direcion_ESP>
```
Dependencias:
- requests
- colorama
Correr: ` ./caldera.py ` o ` python caldera.py `
![python_script](./script_python.png) ![python_script](./script_python.png)

View File

@ -1,296 +1,174 @@
#!/usr/bin/python3 #!/usr/bin/env python3
""" """
Script de control Caldera autmatizada Arduino+ESP01 Script de control Caldera automatizada [Arduino]+[ESP01]
""" """
import os import os
import sys import sys
from time import sleep from time import sleep
import configparser as cfg
import vista_term as vt
try: try:
import requests parser = cfg.ConfigParser()
from colorama import Fore, Back, Style parser.read('esp_conf.cfg')
except ModuleNotFoundError as ex: ESP01 = parser.get('esp01', 'URL')
print("Debes instalar los modulos necesarios\n") except cfg.Error as ex:
print(ex) print('Error al leer archivo de configuración\n', ex)
sleep(2) sys.exit()
try:
import requests
except ModuleNotFoundError as ex:
print("Debes instalar los modulos necesarios\n", ex)
sys.exit() sys.exit()
ESP01 = "http://<IP_ESP>"
clear = lambda: os.system('clear') if os.name == 'posix' else os.system('cls') clear = lambda: os.system('clear') if os.name == 'posix' else os.system('cls')
def enviar_consulta(consulta): def enviar_consulta(consulta):
"""Retorna la respuesta a la petición GET *consulta*
:consulta: str ( consulta creada por consultas() )
:returns: str ( respuesta del GET request )
"""
resp = requests.get(consulta) resp = requests.get(consulta)
return resp.text return resp.text
def consultas(modo, *args): def consultas(modo, id_modo='', datos=['']):
orden = '?' """Crea la petición GET según si los datos son list o str
for indx, arg in enumerate(args): Retorna la respuesta de enviar_consulta()
orden += str(indx+1)+'='+str(arg)+'&'
resp = enviar_consulta(ESP01+modo+orden[:-1]) :modo: str (sub-menu)
:id_modo: str (id modo de operacion)
:datos: list[str] | str
:returns: str (respuesta del GET request)
"""
if id_modo != '':
modo = modo + '?1=' + id_modo
orden = ''
cont = 2
if type(datos) is list:
if len(datos) == 1:
orden = ''
else:
for dato in datos:
if dato != '':
orden += '&' + str(cont) + '=' + str(dato)
cont += 1
else:
orden += '&' + str(cont) + '=' + str(datos)
resp = enviar_consulta(ESP01 + modo + orden)
return resp return resp
def pantallas(pantalla, vals):
if pantalla == '':
if vals[0] == '\n1':
vals[0] = ' AUTO '
elif vals[0] == '\n5':
vals[0] = ' MANUAL '
elif vals[0] == '\n6':
vals[0] = ' LIBRE '
else:
vals[0] = '¡¡¡ERROR!!!'
for i in range(10,15):
if int(vals[i]) < 10:
vals[i] = '0'+vals[i]
for i in range(2,6):
if int(vals[i]) < 10:
vals[i] = ' '+vals[i]
clear()
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+"==========================="+Style.RESET_ALL)
if vals[1] == '1':
print(Fore.BLUE+Back.LIGHTWHITE_EX+Style.DIM+" ESTADO TERMO "+Style.RESET_ALL+
Fore.GREEN+Back.BLUE+Style.BRIGHT+f" ENCENDIDO " + Style.RESET_ALL)
elif vals[1] == '0':
print(Fore.BLUE+Back.LIGHTWHITE_EX+Style.DIM+" ESTADO TERMO "+Style.RESET_ALL+
Fore.RED+Back.BLUE+Style.BRIGHT+f" APAGADO " + Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTWHITE_EX+Style.DIM+" MODO "+Style.RESET_ALL+
Fore.LIGHTRED_EX+Back.BLUE+Style.BRIGHT+f"{vals[0]}" + Style.RESET_ALL)
print(Fore.LIGHTGREEN_EX+Back.LIGHTBLACK_EX+
f" {vals[10]}:{vals[11]}:{vals[12]} {vals[13]}/{vals[14]}/{vals[15]} "+
Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTWHITE_EX+Style.DIM+" ON-1 "+Style.RESET_ALL+
Fore.LIGHTRED_EX+Back.BLUE+Style.BRIGHT+f" {vals[2]} " + Style.RESET_ALL, end='')
print(Fore.BLUE+Back.LIGHTWHITE_EX+Style.DIM+" OFF-1 "+Style.RESET_ALL+
Fore.LIGHTRED_EX+Back.BLUE+Style.BRIGHT+f" {vals[3]} " + Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTWHITE_EX+Style.DIM+" ON-2 "+Style.RESET_ALL+
Fore.LIGHTRED_EX+Back.BLUE+Style.BRIGHT+f" {vals[4]} " + Style.RESET_ALL, end='')
print(Fore.BLUE+Back.LIGHTWHITE_EX+Style.DIM+" OFF-2 "+Style.RESET_ALL+
Fore.LIGHTRED_EX+Back.BLUE+Style.BRIGHT+f" {vals[5]} " + Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+"==========================="+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" Menu de Opciones "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" 1.- Modo Autonomo "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" 2.- Ajustar hora y fecha "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" 3.- Ajustar temporizador "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" 4.- Calibrar servo "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" 5.- Modo Manual "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" 6.- Modo Libre "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" 0.- Salir "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" ⏎.- Actualizar "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" Ingresa una opción "+Style.RESET_ALL,
end='\b\b\b\b\b\b')
elif pantalla == '1':
print(Fore.MAGENTA+Back.BLUE+Style.BRIGHT+vals+Style.RESET_ALL)
elif pantalla == '2':
for i in range(0,5):
if int(vals[i]) < 10 and vals[i][0:1] != '0' :
vals[i] = '0'+vals[i]
clear()
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+"==========================="+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" Valores actuales en RTC "+Style.RESET_ALL)
print(Fore.LIGHTGREEN_EX+Back.LIGHTBLACK_EX+
f" Hora : {vals[0]}:{vals[1]}:{vals[2]} "+Style.RESET_ALL)
print(Fore.LIGHTGREEN_EX+Back.LIGHTBLACK_EX+
f" Fecha : {vals[3]}/{vals[4]}/{vals[5]} "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+"==========================="+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" Ajustando fecha y hora "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+Style.RESET_ALL)
elif pantalla == '3':
for i in range(0,4):
if int(vals[i]) < 10 and vals[i][0:1] != ' ':
vals[i] = ' '+vals[i]
clear()
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+"==========================="+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" Horario Temporizador "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTWHITE_EX+Style.DIM+" ON-1 "+Style.RESET_ALL+
Fore.LIGHTRED_EX+Back.BLUE+Style.BRIGHT+f" {vals[0]} " + Style.RESET_ALL, end='')
print(Fore.BLUE+Back.LIGHTWHITE_EX+Style.DIM+" OFF-1 "+Style.RESET_ALL+
Fore.LIGHTRED_EX+Back.BLUE+Style.BRIGHT+f" {vals[1]} " + Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTWHITE_EX+Style.DIM+" ON-2 "+Style.RESET_ALL+
Fore.LIGHTRED_EX+Back.BLUE+Style.BRIGHT+f" {vals[2]} " + Style.RESET_ALL, end='')
print(Fore.BLUE+Back.LIGHTWHITE_EX+Style.DIM+" OFF-2 "+Style.RESET_ALL+
Fore.LIGHTRED_EX+Back.BLUE+Style.BRIGHT+f" {vals[3]} " + Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+"==========================="+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" Ingresa nuevo horario "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+Style.RESET_ALL)
elif pantalla == '4':
for i in range(0,4):
if int(vals[i]) < 100:
vals[i] = ' '+vals[i]
clear()
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+"==========================="+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" Configuracion Actual "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTWHITE_EX+Style.DIM+" 1 Posición ON "+Style.RESET_ALL+
Fore.LIGHTRED_EX+Back.BLUE+Style.BRIGHT+f" {vals[0]} " + Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTWHITE_EX+Style.DIM+" 2 Posición ON "+Style.RESET_ALL+
Fore.LIGHTRED_EX+Back.BLUE+Style.BRIGHT+f" {vals[1]} " + Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTWHITE_EX+Style.DIM+" 1 Posición OFF "+Style.RESET_ALL+
Fore.LIGHTRED_EX+Back.BLUE+Style.BRIGHT+f" {vals[2]} " + Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTWHITE_EX+Style.DIM+" 2 Posición OFF "+Style.RESET_ALL+
Fore.LIGHTRED_EX+Back.BLUE+Style.BRIGHT+f" {vals[3]} " + Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+"==========================="+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" Ingresa nuevos valores "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+Style.RESET_ALL)
elif pantalla == '5':
clear()
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+"==========================="+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" Accionamiento Manual "+Style.RESET_ALL)
if vals[0] == '1':
print(Fore.BLUE+Back.LIGHTWHITE_EX+Style.DIM+" ESTADO TERMO "+Style.RESET_ALL+
Fore.GREEN+Back.BLUE+Style.BRIGHT+f" ENCENDIDO " + Style.RESET_ALL)
elif vals[0] == '0':
print(Fore.BLUE+Back.LIGHTWHITE_EX+Style.DIM+" ESTADO TERMO "+Style.RESET_ALL+
Fore.RED+Back.BLUE+Style.BRIGHT+f" APAGADO " + Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+"==========================="+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" Encender o Apagar "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+Style.RESET_ALL)
elif pantalla == '6':
clear()
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+"==========================="+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" Movimiento Libre "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+"==========================="+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" Ingresa posición (16..164)"+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+Style.RESET_ALL)
def solicita_dato(valid, mensaje): intentos=0
invalido = True
while invalido: def datos_a_lista() -> list[str] :
"""Retorna el str recibido de consultas() como una lista, valida el largo
de la lista, añade 0 o ' ' a valores, según sea necesario para el correcto
formateo del texto a mostrar.
:returns: list[str] ( len(list) = 16 )
"""
datos = []
global intentos
while True:
try: try:
dato = input(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+mensaje+Style.RESET_ALL) resp = consultas('')
dato = int(dato) for var in resp.split(','):
if valid[0] < dato < valid[1]: datos.append(var)
invalido = False assert len(datos) == 16
return dato for i in range(10,15):
raise ValueError if int(datos[i]) < 10:
except ValueError: datos[i] = '0'+datos[i]
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+ for i in range(2,6):
"Ingresa un número válido "+Style.RESET_ALL) if int(datos[i]) < 10:
datos[i] = ' '+datos[i]
def solicita_dato_str(valid, mensaje):
invalido = True
while invalido:
try:
dato = input(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+mensaje+Style.RESET_ALL)
if dato in valid:
invalido = False
return dato
raise ValueError
except ValueError:
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+
" Debes ingresar \'on\' u \'off\' "+Style.RESET_ALL)
intentos = 0
while True:
#res[1] = 'ENCENDIDO' if res[1] == '1' else 'APAGADO' if '0' else ''
res = []
try:
clear()
resp = consultas('')
for var in resp.split(','):
res.append(var)
assert len(res) == 16
pantallas('', res)
opc = input(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+":"+Style.RESET_ALL)
if opc == '0':
sys.exit()
elif opc == '1':
resp = consultas('/auto')
print(Fore.MAGENTA+Back.BLUE+Style.BRIGHT+resp+Style.RESET_ALL)
sleep(8)
intentos = 0 intentos = 0
elif opc == '2': return datos
pantallas('2',[res[10], res[11], res[12], res[13], res[14], res[15]]) except KeyboardInterrupt:
resp = consultas('/sethora', opc, solicita_dato((0,32),' DIA : '), sys.exit()
solicita_dato((0,13),' MES : '), except AssertionError:
solicita_dato((2020,2100),' AÑO : '), vt.resp_conex('assert', intentos)
solicita_dato((-1,24),' HORA : '), intentos += 1
solicita_dato((-1,60),' MINUTO : '), sleep(2)
solicita_dato((-1,60),' SEGUNDO : ')) except ConnectionError:
print(Fore.MAGENTA+Back.BLUE+Style.BRIGHT+resp+Style.RESET_ALL) vt.resp_conex('conexion', intentos)
sleep(8) intentos += 1
elif opc == '3': sleep(2)
pantallas('3',[res[2], res[3], res[4], res[5]]) except OSError:
resp = consultas('/horasAcc', opc, vt.resp_conex('oserror', intentos)
solicita_dato((-1,24),' 1er Encendido : '), intentos += 1
solicita_dato((-1,24),' 1er Apagado : '), sleep(2)
solicita_dato((-1,24),' 2do Ecendido (opc.): '), if intentos > 4:
solicita_dato((-1,24),' 2do Apagado (opc.): ')) vt.resp_conex()
print(Fore.MAGENTA+Back.BLUE+Style.BRIGHT+resp+Style.RESET_ALL) sys.exit()
sleep(8)
elif opc == '4':
pantallas('4',[res[6], res[7], res[8], res[9]])
resp = consultas('/setservo', opc,
solicita_dato((15,165),' 1ra Posición Encendido:'),
solicita_dato((15,165),' 2ra Posición Encendido:'),
solicita_dato((15,165),' 1ra Posición Apagado :'),
solicita_dato((15,165),' 2da Posición Apagado :'))
print(Fore.MAGENTA+Back.BLUE+Style.BRIGHT+resp+Style.RESET_ALL)
sleep(8)
elif opc == '5':
pantallas('5',[res[1]])
resp = consultas('/accion', opc, solicita_dato_str(('on','off'),
' Ingresa \'on\' u \'off\': '))
print(Fore.MAGENTA+Back.BLUE+Style.BRIGHT+resp+Style.RESET_ALL)
sleep(8)
elif opc == '6':
pantallas('6',[res[1]])
resp = consultas('/setlibre', opc, solicita_dato((15,165),' Ingresa posición :'))
print(Fore.MAGENTA+Back.BLUE+Style.BRIGHT+resp+Style.RESET_ALL)
sleep(8)
elif opc == '':
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+
Style.RESET_ALL)
print(Fore.RED+Back.YELLOW+Style.BRIGHT+" Actualizando... "+
Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+
Style.RESET_ALL)
sleep(1.5)
else:
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+
Style.RESET_ALL)
print(Fore.RED+Back.YELLOW+Style.BRIGHT+" Opción incorrecta "+
Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+
Style.RESET_ALL)
sleep(1.5)
except KeyboardInterrupt:
sys.exit()
except AssertionError:
clear()
intentos += 1
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+Style.RESET_ALL)
print(Fore.RED+Back.YELLOW+Style.BRIGHT+" Arduino no disponible "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+f" Intentando nuevamente ({intentos+1}) "+
Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+Style.RESET_ALL)
intentos += 1
sleep(2)
except ConnectionError:
clear()
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+f" Intentando conexión ({intentos+1}) "+
Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+Style.RESET_ALL)
intentos += 1
sleep(2)
except OSError:
clear()
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+f" Intentando conexión ({intentos+1}) "+
Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+Style.RESET_ALL)
intentos += 1
sleep(2)
if intentos > 4:
print(Fore.RED+Back.YELLOW+Style.BRIGHT+" Imposible conectar con "+Style.RESET_ALL)
print(Fore.RED+Back.YELLOW+Style.BRIGHT+" ESP, o Arduino, verfica "+Style.RESET_ALL)
print(Fore.RED+Back.YELLOW+Style.BRIGHT+" IP, conexión o estado de "+Style.RESET_ALL)
print(Fore.RED+Back.YELLOW+Style.BRIGHT+ " de los dispositivos. "+Style.RESET_ALL)
print(Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM+" "+Style.RESET_ALL)
sys.exit()
def main():
global intentos
while True:
# Lista con valores de los datos recibidos
vals = datos_a_lista()
clear()
vt.pant_principal(vals[0], vals[1], vals[10:16], vals[2:6])
modo_user = vt.entrada_usuario()
match modo_user:
case 's':
sys.exit()
case '1':
#vt.pant_test_valores(vals)
vt.respuesta_config(consultas('/auto'))
intentos = 0
sleep(3)
case'2':
vt.pant_config_fecha(vals[10:16])
resp_user = vt.entrada_usuario('/sethora')
vt.respuesta_config(consultas('/sethora', modo_user, resp_user))
intentos = 0
sleep(5)
case '3':
vt.pant_termporizador(vals[2:6])
resp_user = vt.entrada_usuario('/horasAcc')
vt.respuesta_config(consultas('/horasAcc', modo_user, resp_user))
intentos = 0
sleep(5)
case '4':
pos_servo = []
for val in vals[6:10]:
if int(val) < 100:
pos_servo.append(' '+val)
else:
pos_servo.append(val)
vt.pant_posic_servo(pos_servo)
resp_user = vt.entrada_usuario('/setservo')
vt.respuesta_config(consultas('/setservo', modo_user, resp_user))
intentos = 0
sleep(5)
case '5':
vt.pant_accion_manual(vals[1])
resp_user = vt.entrada_usuario('/accion')
vt.respuesta_config(consultas('/accion', modo_user, resp_user))
intentos = 0
sleep(5)
case '6':
vt.pant_servo_manual()
resp_user = vt.entrada_usuario('/setlibre')
vt.respuesta_config(consultas('/setlibre', modo_user, resp_user))
intentos = 0
sleep(5)
case '':
vt.respuesta_info()
sleep(1.5)
case 'v':
vt.respuesta_info('volver')
intentos = 0
sleep(1.5)
case _:
modo_user = vt.entrada_usuario()
vt.respuesta_info('error')
sleep(1.5)
if __name__ == "__main__":
main()

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/usr/bin/env bash
IP_CALDERA="<IP_ESP01>" IP_CALDERA=$(grep URL esp_conf.cfg | cut -d'=' -f2)
estado_caldera() { estado_caldera() {
RESP=$(curl -s ${IP_CALDERA}) RESP=$(curl -s ${IP_CALDERA})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 30 KiB

398
scripts/vista_term.py Normal file
View File

@ -0,0 +1,398 @@
"""
Gestión de pantallas (dialogos, opcs, menus, etc) y entradas de usuario.
"""
import os
import sys
from time import sleep
from caldera import main
try:
from colorama import Fore, Back, Style
except ModuleNotFoundError as ex:
print("Debes instalar los modulos necesarios\n")
print(ex)
sleep(2)
sys.exit()
clear = lambda: os.system('clear') if os.name == 'posix' else os.system('cls')
# Colores
col_rst = Style.RESET_ALL
col_menu = Fore.BLACK+Back.LIGHTBLACK_EX+Style.DIM
col_head = Fore.BLUE+Back.LIGHTWHITE_EX+Style.NORMAL
col_headGrn = Fore.GREEN+Back.MAGENTA+Style.BRIGHT
col_headRed = Fore.RED+Back.BLUE+Style.DIM
col_headLred = Fore.LIGHTRED_EX+Back.BLUE+Style.DIM
col_headBBlk = Fore.BLACK+Back.MAGENTA+Style.BRIGHT
col_headBlk = Fore.BLACK+Back.MAGENTA+Style.NORMAL
col_date = Fore.LIGHTGREEN_EX+Back.LIGHTBLACK_EX
col_error = Fore.RED+Back.YELLOW+Style.NORMAL
col_errorB = Fore.RED+Back.YELLOW+Style.BRIGHT
col_input = Fore.BLACK+Back.LIGHTBLACK_EX+Style.DIM
col_excep = Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM
col_resp = Fore.BLACK+Back.MAGENTA+Style.BRIGHT
# Dialogos
diag_bar = '==========================='
diag_spc = ' '
diag_state = [ diag_bar, ' ESTADO TERMO ', ' ENCENDIDO ', ' APAGADO ', ' - - - - ' ]
diag_modo = [ ' MODO ', ' AUTO ', ' MANUAL ',
' LIBRE ', ' ¡ERROR! ' ]
diag_hrsfun = [ ' ON-1 ', ' OFF-1 ', ' ON-2 ', ' OFF-2 ', diag_bar ]
diag_opcs = [ diag_bar, ' Menu de Opciones ', diag_spc,
' 1) Modo Autonomo ', ' 2) Ajustar hora y fecha ',
' 3) Ajustar temporizador ', ' 4) Calibrar servo ',
' 5) Modo Manual ', ' 6) Modo Libre ',
' v) Volver(en sub-menus) ', ' s) Salir ',
' ⏎) Actualizar ', diag_spc,
' Ingresa una opción \b\b\b\b\b\b:' ]
diag_setdate = [ diag_bar,' Valores actuales en RTC ', ' Hora : ', ' Fecha : ',
diag_bar, diag_spc, ' Ajustando fecha y hora ', diag_spc,
' DIA : \b\b\b\b\b\b\b',
' MES : \b\b\b\b\b\b\b',
' AÑO : \b\b\b\b\b\b\b',
' HORA : \b\b\b\b\b\b\b',
' MINUTO : \b\b\b\b\b\b\b',
' SEGUNDO : \b\b\b\b\b\b\b' ]
diag_error = [ ' Ingresa un número válido! ', ' Debes ingresar \'on\' u \'off\' ',
' Entrada no válida! ', ' Entrada incorrecta! ' ]
diag_settimer = [ diag_bar,' Horario Temporizador ', ' ON-1 ', ' OFF-1 ',
' ON-2 ',' OFF-2 ', diag_bar, diag_spc, ' Ingresa nuevo horario ',
diag_spc, ' 1er Encendido : ', ' 1er Apagado : ',
' 2do Ecendido (opc.): ', ' 2do Apagado (opc.): ' ]
diag_posservo = [ diag_bar,' Configuracion Actual ', ' 1 Posición ON ',
' 2 Posición ON ', ' 1 Posición OFF ',' 2 Posición OFF ',
diag_bar, diag_spc,' Ingresa nuevos valores ', diag_spc,
' 1ra posic. encendido : \b\b\b\b',
' 2da posic. encendido : \b\b\b\b',
' 1ra posic. apagado : \b\b\b\b',
' 2da posic. apagado : \b\b\b\b' ]
diag_accman = [ diag_bar, ' Accionamiento Manual ', diag_state[1:5],
diag_bar, diag_spc, ' Encender o Apagar ? ', diag_spc,
' Ingresa \'on\' u \'off\': \b\b\b\b' ]
diag_servman = [ diag_bar, ' Movimiento Libre ', diag_bar, diag_spc,
'Posiciónes validas (16-164)', diag_spc ,
' Ingresa posición : \b\b\b\b\b' ]
diag_excepcn = [ diag_spc, ' Error en lectura de datos ', ' Arduino no disponible ',
' Error al solicitar datos ', f' Intentando conexión (', ') ',
' Imposible conectar con ', ' ESP o Arduino, verifica ',
' IP, conexión o estado de ', ' de los dispositivos. ' ]
diag_volver = [ diag_spc, ' Actualizando... ',
' Volviendo... ', ' Seleción incorrecta ' ]
# Valores para validación
# (min, max) dia - mes - año - hora - minuto - segundo
valid_dates = [(0,32),(0,13),(2020,2100),(-1,24),(-1,60),(-1,60)]
valid_opcs = ['1','2','3','4','5','6','']
valid_hrs_timer = (-1,24)
valid_posicion = (15,168)
valid_manual = ('on', 'off')
def resp_conex(excepcion=None, intentos=0):
"""Imprime en terminal dialogos de error de conexión
:excepcion: str (tipo de error)
:intentos: int (nro. de intentos de conexión)
"""
intentos += 1
dialogos = diag_excepcn
match excepcion:
case 'assert':
clear()
print(col_menu + dialogos[0] + col_rst)
print(col_error + dialogos[1] + col_rst)
print(col_menu + dialogos[4] + str(intentos) + dialogos[5] + col_rst)
print(col_menu + dialogos[0] + col_rst)
case 'conexion':
clear()
print(col_menu + dialogos[0] + col_rst)
print(col_error + dialogos[2] + col_rst)
print(col_menu + dialogos[4] + str(intentos) + dialogos[5] + col_rst)
print(col_menu + dialogos[0] + col_rst)
case 'oserror':
clear()
print(col_menu + dialogos[0] + col_rst)
print(col_error + dialogos[3] + col_rst)
print(col_menu + dialogos[4] + str(intentos) + dialogos[5] + col_rst)
print(col_menu + dialogos[0] + col_rst)
case _:
clear()
print(col_menu + dialogos[0] + col_rst)
for dialogo in dialogos[6:10]:
print(col_errorB + dialogo + col_rst)
print(col_menu + dialogos[0] + col_rst)
def pant_servo_manual():
"""Imprime en terminal dialogos de configuración manual del servo
"""
clear()
dialogos = diag_servman[:-1]
for dialogo in dialogos:
print(col_menu+dialogo+col_rst)
def pant_accion_manual(estado):
"""Imprime en terminal dialogos de accionamiento manual del servo
:estado: str ('0' o '1')
"""
clear()
dialogos = diag_accman[0:7]
for ind, dialogo in enumerate(dialogos):
match ind:
case 2:
print(col_head+dialogo[0]+col_rst, end='')
match estado:
case '1':
print(col_headGrn+dialogo[1]+col_rst)
case '0':
print(col_headBlk+dialogo[2]+col_rst)
case _:
print(col_headBlk+dialogo[3]+col_rst)
ind+=3
case _:
print(col_menu+dialogo+col_rst)
def pant_posic_servo(pos_servo):
"""Imprime en terminal posiciones de trabajo del servo
:pos_servo: list[str]
"""
clear()
dialogos = diag_posservo[0:10]
for ind, dialogo in enumerate(dialogos):
match ind:
case 2:
print(f"{col_head}{dialogo}{col_headGrn} {pos_servo[0]} {col_rst}")
case 3:
print(f"{col_head}{dialogo}{col_headGrn} {pos_servo[1]} {col_rst}")
case 4:
print(f"{col_head}{dialogo}{col_headGrn} {pos_servo[2]} {col_rst}")
case 5:
print(f"{col_head}{dialogo}{col_headGrn} {pos_servo[3]} {col_rst}")
case _:
print(col_menu + dialogo + col_rst)
def pant_termporizador(hrs_timer):
"""Imprime en terminal horas de trabajo del servo
:hrs_timer: list[str]
"""
clear()
dialogos = diag_settimer[0:10]
for ind, dialogo in enumerate(dialogos):
match ind:
case 2:
#ind+=1
print(f"{col_head}{dialogo}{col_headGrn} {hrs_timer[0]} {col_rst}", end='')
case 3:
print(f"{col_head}{dialogo}{col_headGrn} {hrs_timer[1]} {col_rst}")
case 4:
print(f"{col_head}{dialogo}{col_headGrn} {hrs_timer[2]} {col_rst}", end='')
case 5:
print(f"{col_head}{dialogo}{col_headGrn} {hrs_timer[3]} {col_rst}")
case _:
print(col_menu + dialogo + col_rst)
def pant_config_fecha(tiempo):
"""Imprime hora y fecha en terminal, segun ESP.
:tiempo: list[str] [hora, minuto, segundo, dia, mes, año]
"""
clear()
dialogos = diag_setdate
for ind, dialogo in enumerate(dialogos):
match ind:
case 2:
print(f"{col_date}{dialogo}{tiempo[0]}:{tiempo[1]}:{tiempo[2]} {col_rst}")
case 3:
print(f"{col_date}{dialogo}{tiempo[3]}/{tiempo[4]}/{tiempo[5]} {col_rst}")
case 8:
break
case _:
print(col_menu + dialogo + col_rst)
def pant_principal(modo, estado, tiempo, hrs_timer):
"""Imprime menu principal en terminal.
:modo: str (ej. '\\n')
:estado: str estado del termo ('0','1')
:tiempo: List[str] hora y fecha
:hrs_timer: List[str] horario de accionamiento
"""
clear()
# Estado
dialogos = diag_state
print(col_menu+dialogos[0]+col_rst)
print(col_head+dialogos[1]+col_rst, end='')
match estado:
case '1':
print(col_headGrn+dialogos[2]+col_rst)
case '0':
print(col_headBlk+dialogos[3]+col_rst)
case _:
print(col_headBlk+dialogos[4]+col_rst)
# Modo de operación
dialogos = diag_modo
print(col_head+dialogos[0]+col_rst, end='')
match modo:
case '\n1':
print(col_headGrn+dialogos[1]+col_rst)
case '\n5':
print(col_headBlk+dialogos[2]+col_rst)
case '\n6':
print(col_headBlk+dialogos[3]+col_rst)
case _:
print(col_headRed+dialogos[4]+col_rst)
# Hora y Fecha
print(col_date, end='')
print(f" {tiempo[0]}:{tiempo[1]}:{tiempo[2]}", end='')
print(f" {tiempo[3]}/{tiempo[4]}/{tiempo[5]} "+col_rst)
# Horas de funcionamiento
dialogos = diag_hrsfun
print(col_head + dialogos[0] + col_rst, end='')
print(col_headBBlk + ' ' + hrs_timer[0] + ' ' + col_rst, end='')
print(col_head + dialogos[1]+col_rst, end='')
print(col_headBBlk + ' ' + hrs_timer[1] + ' ' + col_rst)
print(col_head + dialogos[2] + col_rst, end='')
print(col_headBBlk + ' ' + hrs_timer[2] + ' ' + col_rst, end='')
print(col_head + dialogos[3]+col_rst, end='')
print(col_headBBlk + ' ' + hrs_timer[3] + ' ' + col_rst)
# Opciones del menu principal
dialogos = diag_opcs[:-1]
for indx, dialogo in enumerate(dialogos):
if indx != (len(dialogos)-1):
print(col_menu+dialogo+col_rst)
else:
print(col_menu+dialogo+col_rst)
def pant_test_valores(valores):
"""Función de prueba, imprime en terminal valores de lista.
:valores: Lista de strings [ str, str, ...]
"""
for val in valores:
print(Fore.MAGENTA+Back.BLACK+Style.BRIGHT+val+Style.RESET_ALL)
def valida_entrada(valid, mensaje, tipo_dato='') -> list[str] | str:
"""Solicita entrada de usuario, imprime dialogo en terminal y
valida según tupla *valid*.
:valid: tuple (límites o alternativas válidas)
:mensaje: str (mensaje para solicitar entrada de usuario)
"""
invalido = True
err_msg = ''
while invalido:
entrada_usuario = input(col_input+mensaje+Style.RESET_ALL)
if entrada_usuario == 's':
sys.exit()
#return 's'
elif entrada_usuario == 'v':
main()
#return 'v'
match tipo_dato:
case '':
try:
entrada_usuario = int(entrada_usuario)
if valid[0] < entrada_usuario < valid[1]:
invalido = False
return str(entrada_usuario)
else:
raise ValueError
except ValueError:
err_msg = diag_error[0]
print(col_error + err_msg + Style.RESET_ALL)
case 'str':
try:
if entrada_usuario in valid:
invalido = False
return entrada_usuario
else:
err_msg = diag_error[3]
raise ValueError
except ValueError:
err_msg = diag_error[3]
print(col_error + err_msg + Style.RESET_ALL)
case _:
assert entrada_usuario in ['','str']
err_msg = diag_error[2]
print(col_error + err_msg + Style.RESET_ALL)
def entrada_usuario(caso=None) -> list[str] | str :
"""Retorna la(s) respuesta(s) del usuario, segun caso (submenu)
:caso: str (submenu)
"""
match caso:
case '/sethora':
user_ins = []
i = 0
for preg in diag_setdate[8:14]:
user_ins.append(valida_entrada(valid_dates[i], preg))
i += 1
return user_ins
case '/horasAcc':
user_ins = []
for preg in diag_settimer[10:14]:
user_ins.append(valida_entrada(valid_hrs_timer, preg))
return user_ins
case '/setservo':
user_ins = []
for preg in diag_posservo[10:14]:
user_ins += valida_entrada(valid_posicion, preg)
return user_ins
case '/accion':
return valida_entrada(valid_manual ,diag_accman[-1],'str')
case '/setlibre':
return valida_entrada(valid_posicion ,diag_servman[-1])
case _:
mensaje = ' Ingresa una opción \b\b\b\b\b\b:'
return valida_entrada(valid_opcs, mensaje, 'str')
def respuesta_config(respuesta):
"""Imprime el argumento formateado en el terminal bajo el contexto de
respuesta del ESP a alguna configuración.
:respuesta: str (mensaje de respuesta)
"""
print(col_resp + respuesta + col_rst)
def respuesta_info(caso='foo'):
"""Imprime en terminal bajo el contexto de respuesta informativa o
advertencia del ESP a alguna solicitud.
:caso: str (tipo de mensaje)
"""
match caso:
case 'error':
print(col_error + diag_volver[3] + col_rst)
sleep(1)
case 'volver':
print(col_error + diag_volver[2] + col_rst)
sleep(1)
case _:
print(col_error + diag_volver[1] + col_rst)
sleep(1)