diff --git a/scripts/protocolo_apagado_final.py b/scripts/protocolo_apagado_final.py new file mode 100644 index 0000000..766291b --- /dev/null +++ b/scripts/protocolo_apagado_final.py @@ -0,0 +1,137 @@ +""" +Protocolo de apagado completo del PC usando HOME ASSISTANT + COMANDOS DE VOZ ALEXA. + +Pasos: +1. Cerrar ventanas abiertas +2. Apagar luces Alexa via comandos de voz: "apaga barras" y "apaga cuartillo" +3. Apagar pantalla (Tapo via tunel RPi) +4. Shutdown del PC en 10 segundos + +Uso: + python protocolo_apagado_final.py +""" +import os +import sys +import subprocess +import requests +from dotenv import load_dotenv + +# Fix encoding para Windows +if sys.platform == 'win32': + import codecs + sys.stdout = codecs.getwriter('utf-8')(sys.stdout.buffer, 'strict') + sys.stderr = codecs.getwriter('utf-8')(sys.stderr.buffer, 'strict') + +# Cargar variables de entorno locales (.env de biblioteca_negocio_prolongo) +dotenv_path = r"C:\Users\juanm\Documents\GitHub\biblioteca_negocio_prolongo\.env" +load_dotenv(dotenv_path) + +def cerrar_ventanas(): + """Cierra todas las ventanas excepto terminal/OpenCode""" + print("1. Cerrando ventanas abiertas (excepto terminal de OpenCode)...") + ps_command = """ + $procesos = Get-Process | Where-Object { $_.MainWindowHandle -ne 0 -and $_.ProcessName -notmatch 'OpenCode|WindowsTerminal|cmd|powershell|Code|conhost' } + foreach ($p in $procesos) { + try { + $p.CloseMainWindow() | Out-Null + Start-Sleep -Milliseconds 200 + if (-not $p.HasExited) { $p.Kill() } + } catch {} + } + """ + subprocess.run(["powershell", "-Command", ps_command], capture_output=True) + print(" [OK] Ventanas cerradas.") + +def apagar_luces_alexa(): + """Apaga las luces 'barras' y 'cuartillo' via comandos de voz a Alexa""" + print("2. Apagando luces de Alexa via comandos de voz (barras + cuartillo)...") + + url = os.getenv("HOMEASSISTANT_URL") + token = os.getenv("HOMEASSISTANT_TOKEN") + + if not url or not token: + print(" [ERROR] Falta HOMEASSISTANT_URL o HOMEASSISTANT_TOKEN en .env") + return + + headers = { + "Authorization": f"Bearer {token}", + "Content-Type": "application/json" + } + + # Entity ID del Echo Dot principal + echo_entity = "media_player.echo_dot_de_nahid" + + comandos = [ + ("barras", "apaga barras"), + ("cuartillo", "apaga cuartillo") + ] + + for nombre, comando in comandos: + data = { + "entity_id": echo_entity, + "media_content_type": "custom", + "media_content_id": comando + } + + try: + response = requests.post( + f"{url}/api/services/media_player/play_media", + headers=headers, + json=data, + timeout=10 + ) + + if response.status_code == 200: + print(f" [OK] Comando enviado: '{comando}'") + else: + print(f" [ERROR] Error HTTP {response.status_code} al apagar '{nombre}'") + except Exception as e: + print(f" [ERROR] Error al apagar '{nombre}': {e}") + +def apagar_pantalla_tapo(): + """Apaga el enchufe Tapo de la pantalla via tunel RPi""" + print("3. Apagando pantalla (Tapo) via tunel RPi...") + + # Script Python que se ejecutara en la RPi + tapo_script = r"""from PyP100 import PyP100 +p100 = PyP100.P100('192.168.50.224', 'hermes211@gmail.com', 'Nelo@36666') +p100.handshake() +p100.login() +p100.turnOff()""" + + # Comando SSH en dos saltos: local -> VPS -> RPi + cmd = [ + "ssh", "-i", r"C:\Users\juanm\Documents\GitHub\contabo", + "root@185.187.169.109", + f"ssh -i /root/.ssh/pi_deploy -p 2222 -o StrictHostKeyChecking=no pi@127.0.0.1 'python3 -c \"{tapo_script}\"'" + ] + + try: + result = subprocess.run(cmd, capture_output=True, timeout=15, text=True) + if result.returncode == 0: + print(" [OK] Pantalla apagada.") + else: + print(f" [ERROR] Error al apagar pantalla (codigo {result.returncode})") + if result.stderr: + print(f" stderr: {result.stderr.strip()}") + except subprocess.TimeoutExpired: + print(" [ERROR] Timeout al apagar pantalla (>15s)") + except Exception as e: + print(f" [ERROR] Excepcion al apagar pantalla: {e}") + +def shutdown_pc(): + """Apaga el PC en 10 segundos""" + print("4. Apagando el PC en 10 segundos...") + os.system("shutdown /s /t 10") + +if __name__ == "__main__": + print("=" * 60) + print(" PROTOCOLO DE APAGADO COMPLETO") + print("=" * 60) + cerrar_ventanas() + apagar_luces_alexa() + apagar_pantalla_tapo() + shutdown_pc() + print("=" * 60) + print(" PROTOCOLO COMPLETADO") + print("=" * 60) diff --git a/scripts/protocolo_apagado_final_test.py b/scripts/protocolo_apagado_final_test.py new file mode 100644 index 0000000..8a62d00 --- /dev/null +++ b/scripts/protocolo_apagado_final_test.py @@ -0,0 +1,145 @@ +""" +Protocolo de apagado completo (VERSION TEST - SIN SHUTDOWN). + +Pasos: +1. Cerrar ventanas abiertas +2. Apagar luces Alexa via comandos de voz: "apaga barras" y "apaga cuartillo" +3. Apagar pantalla (Tapo via tunel RPi) +4. [COMENTADO] Shutdown del PC + +Uso: + python protocolo_apagado_final_test.py +""" +import os +import sys +import subprocess +import requests +from dotenv import load_dotenv + +# Fix encoding para Windows +if sys.platform == 'win32': + import codecs + sys.stdout = codecs.getwriter('utf-8')(sys.stdout.buffer, 'strict') + sys.stderr = codecs.getwriter('utf-8')(sys.stderr.buffer, 'strict') + +# Cargar variables de entorno locales (.env de biblioteca_negocio_prolongo) +dotenv_path = r"C:\Users\juanm\Documents\GitHub\biblioteca_negocio_prolongo\.env" +load_dotenv(dotenv_path) + +def cerrar_ventanas(): + """Cierra todas las ventanas excepto terminal/OpenCode""" + print("1. Cerrando ventanas abiertas (excepto terminal de OpenCode)...") + ps_command = """ + $procesos = Get-Process | Where-Object { $_.MainWindowHandle -ne 0 -and $_.ProcessName -notmatch 'OpenCode|WindowsTerminal|cmd|powershell|Code|conhost' } + foreach ($p in $procesos) { + try { + $p.CloseMainWindow() | Out-Null + Start-Sleep -Milliseconds 200 + if (-not $p.HasExited) { $p.Kill() } + } catch {} + } + """ + subprocess.run(["powershell", "-Command", ps_command], capture_output=True) + print(" [OK] Ventanas cerradas.") + +def apagar_luces_alexa(): + """Apaga las luces 'barras' y 'cuartillo' via comandos de voz a Alexa""" + print("2. Apagando luces de Alexa via comandos de voz (barras + cuartillo)...") + + url = os.getenv("HOMEASSISTANT_URL") + token = os.getenv("HOMEASSISTANT_TOKEN") + + if not url or not token: + print(" [ERROR] Falta HOMEASSISTANT_URL o HOMEASSISTANT_TOKEN en .env") + return + + headers = { + "Authorization": f"Bearer {token}", + "Content-Type": "application/json" + } + + # Entity ID del Echo Dot principal + echo_entity = "media_player.echo_dot_de_nahid" + + comandos = [ + ("barras", "apaga barras"), + ("cuartillo", "apaga cuartillo") + ] + + for nombre, comando in comandos: + data = { + "entity_id": echo_entity, + "media_content_type": "custom", + "media_content_id": comando + } + + try: + response = requests.post( + f"{url}/api/services/media_player/play_media", + headers=headers, + json=data, + timeout=10 + ) + + if response.status_code == 200: + print(f" [OK] Comando enviado: '{comando}'") + else: + print(f" [ERROR] Error HTTP {response.status_code} al apagar '{nombre}'") + except Exception as e: + print(f" [ERROR] Error al apagar '{nombre}': {e}") + +def apagar_pantalla_tapo(): + """Apaga el enchufe Tapo de la pantalla via tunel RPi""" + print("3. Apagando pantalla (Tapo) via tunel RPi...") + + # Crear script temporal en VPS y ejecutar via RPi + script_content = """from PyP100 import PyP100 +p100 = PyP100.P100('192.168.50.224', 'hermes211@gmail.com', 'Nelo@36666') +p100.handshake() +p100.login() +p100.turnOff()""" + + # Paso 1: Crear script en VPS + cmd1 = [ + "ssh", "-i", r"C:\Users\juanm\Documents\GitHub\contabo", + "root@185.187.169.109", + f"echo '{script_content}' > /tmp/tapo_off.py" + ] + + # Paso 2: Copiar a RPi y ejecutar + cmd2 = [ + "ssh", "-i", r"C:\Users\juanm\Documents\GitHub\contabo", + "root@185.187.169.109", + "scp -i /root/.ssh/pi_deploy -P 2222 -o StrictHostKeyChecking=no /tmp/tapo_off.py pi@127.0.0.1:/tmp/ && ssh -i /root/.ssh/pi_deploy -p 2222 -o StrictHostKeyChecking=no pi@127.0.0.1 'python3 /tmp/tapo_off.py'" + ] + + try: + subprocess.run(cmd1, capture_output=True, timeout=5, text=True) + result = subprocess.run(cmd2, capture_output=True, timeout=15, text=True) + if result.returncode == 0: + print(" [OK] Pantalla apagada.") + else: + print(f" [ERROR] Error al apagar pantalla (codigo {result.returncode})") + if result.stderr: + print(f" stderr: {result.stderr.strip()}") + except subprocess.TimeoutExpired: + print(" [ERROR] Timeout al apagar pantalla (>15s)") + except Exception as e: + print(f" [ERROR] Excepcion al apagar pantalla: {e}") + +def shutdown_pc(): + """NO APAGA el PC en modo test""" + print("4. [TEST MODE] Shutdown deshabilitado para pruebas.") + print(" En produccion ejecutaria: shutdown /s /t 10") + +if __name__ == "__main__": + print("=" * 60) + print(" PROTOCOLO DE APAGADO (TEST - SIN SHUTDOWN)") + print("=" * 60) + cerrar_ventanas() + apagar_luces_alexa() + apagar_pantalla_tapo() + shutdown_pc() + print("=" * 60) + print(" PROTOCOLO COMPLETADO") + print("=" * 60) diff --git a/scripts/test_alexa_voz.py b/scripts/test_alexa_voz.py new file mode 100644 index 0000000..bf2a12e --- /dev/null +++ b/scripts/test_alexa_voz.py @@ -0,0 +1,88 @@ +""" +Test de comandos de voz a Alexa via Home Assistant. + +Uso: + python test_alexa_voz.py "apaga barras" + python test_alexa_voz.py "apaga cuartillo" + python test_alexa_voz.py "enciende barras" +""" +import sys +import os +import requests +from dotenv import load_dotenv + +# Fix encoding +if sys.platform == 'win32': + import codecs + sys.stdout = codecs.getwriter('utf-8')(sys.stdout.buffer, 'strict') + sys.stderr = codecs.getwriter('utf-8')(sys.stderr.buffer, 'strict') + +dotenv_path = r"C:\Users\juanm\Documents\GitHub\biblioteca_negocio_prolongo\.env" +load_dotenv(dotenv_path) + +def enviar_comando_voz(echo_entity, comando): + """Envia un comando de voz a un dispositivo Echo""" + url = os.getenv("HOMEASSISTANT_URL") + token = os.getenv("HOMEASSISTANT_TOKEN") + + if not url or not token: + print("[ERROR] Falta HOMEASSISTANT_URL o HOMEASSISTANT_TOKEN en .env") + return False + + headers = { + "Authorization": f"Bearer {token}", + "Content-Type": "application/json" + } + + data = { + "entity_id": echo_entity, + "media_content_type": "custom", + "media_content_id": comando + } + + try: + response = requests.post( + f"{url}/api/services/media_player/play_media", + headers=headers, + json=data, + timeout=10 + ) + + if response.status_code == 200: + print(f"[OK] Comando enviado: '{comando}' -> {echo_entity}") + return True + else: + print(f"[ERROR] HTTP {response.status_code}: {response.text}") + return False + except Exception as e: + print(f"[ERROR] {e}") + return False + +def main(): + if len(sys.argv) < 2: + print("Uso: python test_alexa_voz.py \"comando\"") + print() + print("Ejemplos:") + print(" python test_alexa_voz.py \"apaga barras\"") + print(" python test_alexa_voz.py \"apaga cuartillo\"") + print(" python test_alexa_voz.py \"enciende barras\"") + return + + comando = sys.argv[1] + + # Probamos con el Echo Dot principal + echo_entity = "media_player.echo_dot_de_nahid" + + print("=" * 60) + print(f" ENVIANDO COMANDO DE VOZ A ALEXA") + print("=" * 60) + print(f"Comando: {comando}") + print(f"Echo: {echo_entity}") + print() + + enviar_comando_voz(echo_entity, comando) + + print("=" * 60) + +if __name__ == "__main__": + main()