diff --git a/CHANGELOG_INFRA.md b/CHANGELOG_INFRA.md index ccbe8e8..b4728e7 100644 --- a/CHANGELOG_INFRA.md +++ b/CHANGELOG_INFRA.md @@ -10,6 +10,8 @@ - **2026-10-03-superwhisper-enter-ahk-f13-boton-auxiliar-logitech-tarea-pro** [scripts] SuperWhisper Enter: AHK F13 boton auxiliar Logitech + tarea programada (aplicado en: portatil) - **2026-10-03-monitor-de-estado-telegram-correo-jira-en-segundo-plano** [servicios] Monitor de estado (Telegram + correo + Jira) en segundo plano (aplicado en: portatil) - **2026-10-03-acceso-remoto-al-sobremesa-openssh-server-tailscale-ssh-powe** [servicios] Acceso remoto al sobremesa: OpenSSH Server + Tailscale (ssh -> PowerShell) (aplicado en: portatil) +- **2026-10-03-voicemonkey-sustituido-por-home-assistant-alexa** [servicios] VoiceMonkey sustituido por Home Assistant (Alexa) (aplicado en: portatil) +- **2026-10-03-omniroute-3-8-48-3-8-51-fix-catalogo-live-antigravity** [omniroute] OmniRoute 3.8.48 -> 3.8.51: fix catalogo live antigravity (aplicado en: portatil) ## Historial @@ -37,6 +39,22 @@ - **Aplicado en**: portatil - **Detalle**: Scripts en scripts/acceso_remoto/: setup_tailscale.ps1 (malla privada) y setup_ssh_server.ps1 (OpenSSH Server, shell PowerShell, firewall solo Tailscale+LAN, instala clave publica). Clave SSH del portatil: ~/.ssh/id_ed25519. Doc: docs/ACCESO_REMOTO_SOBREMESA.md. Permite ssh juanm@sobremesa desde cualquier red sin abrir puertos. Requiere en cada equipo: ejecutar setup_tailscale; en el sobremesa ademas setup_ssh_server (admin). +### 2026-10-03 · VoiceMonkey sustituido por Home Assistant (Alexa) +- **id**: `2026-10-03-voicemonkey-sustituido-por-home-assistant-alexa` +- **Equipo**: portatil +- **Categoria**: servicios +- **Transferible**: si +- **Aplicado en**: portatil +- **Detalle**: Validado con efecto real (anuncio por voz + comando 'apaga/enciende barras'). Nuevo helper biblioteca/scripts/ha_alexa.py (announce/command via HA REST). Migrados: netatmo_tool.notificar_alexa, telegram_read_tracker.notificar_alexa, protocolo_apagado.py y protocolo_apagado_test.py (apagar_luces_alexa). .env: +HOMEASSISTANT_URL/TOKEN (long-lived), -VOICEMONKEY_TOKEN/DEVICE. Obsoletos: alexa_notify.js, configurar_voicemonkey.py. Requiere en el otro equipo: git pull + tener HOMEASSISTANT_TOKEN en .env. + +### 2026-10-03 · OmniRoute 3.8.48 -> 3.8.51: fix catalogo live antigravity +- **id**: `2026-10-03-omniroute-3-8-48-3-8-51-fix-catalogo-live-antigravity` +- **Equipo**: portatil +- **Categoria**: omniroute +- **Transferible**: si +- **Aplicado en**: portatil +- **Detalle**: Actualizado omniroute a 3.8.51 (npm i -g omniroute@latest). Ahora valida contra el 'active live catalog' de Antigravity: los modelos deprecados (gemini-3.5-flash-*, gemini-2.5-*, claude-* en antigravity) devuelven HTTP 400 en vez de texto de deprecacion. Funcionan: gemini-3.1-pro-low/high, gemini-3.1-flash-lite, gemini-pro-agent, gpt-oss-120b-medium. Servidor relanzado via omniroute_watchdog.ps1 -Once. + ### 2026-10-02 · superguardado.py: protocolo guardado total automatico portatil+sobremesa - **id**: `2026-10-02-superguardado-py-protocolo-guardado-total-automatico-portati` - **Equipo**: portatil diff --git a/changelog_infra.json b/changelog_infra.json index c48bcdd..b8627b6 100644 --- a/changelog_infra.json +++ b/changelog_infra.json @@ -249,6 +249,30 @@ "portatil" ], "detalle": "Scripts en scripts/acceso_remoto/: setup_tailscale.ps1 (malla privada) y setup_ssh_server.ps1 (OpenSSH Server, shell PowerShell, firewall solo Tailscale+LAN, instala clave publica). Clave SSH del portatil: ~/.ssh/id_ed25519. Doc: docs/ACCESO_REMOTO_SOBREMESA.md. Permite ssh juanm@sobremesa desde cualquier red sin abrir puertos. Requiere en cada equipo: ejecutar setup_tailscale; en el sobremesa ademas setup_ssh_server (admin)." + }, + { + "id": "2026-10-03-voicemonkey-sustituido-por-home-assistant-alexa", + "fecha": "2026-10-03", + "equipo": "portatil", + "categoria": "servicios", + "titulo": "VoiceMonkey sustituido por Home Assistant (Alexa)", + "transferible": true, + "aplicado_en": [ + "portatil" + ], + "detalle": "Validado con efecto real (anuncio por voz + comando 'apaga/enciende barras'). Nuevo helper biblioteca/scripts/ha_alexa.py (announce/command via HA REST). Migrados: netatmo_tool.notificar_alexa, telegram_read_tracker.notificar_alexa, protocolo_apagado.py y protocolo_apagado_test.py (apagar_luces_alexa). .env: +HOMEASSISTANT_URL/TOKEN (long-lived), -VOICEMONKEY_TOKEN/DEVICE. Obsoletos: alexa_notify.js, configurar_voicemonkey.py. Requiere en el otro equipo: git pull + tener HOMEASSISTANT_TOKEN en .env." + }, + { + "id": "2026-10-03-omniroute-3-8-48-3-8-51-fix-catalogo-live-antigravity", + "fecha": "2026-10-03", + "equipo": "portatil", + "categoria": "omniroute", + "titulo": "OmniRoute 3.8.48 -> 3.8.51: fix catalogo live antigravity", + "transferible": true, + "aplicado_en": [ + "portatil" + ], + "detalle": "Actualizado omniroute a 3.8.51 (npm i -g omniroute@latest). Ahora valida contra el 'active live catalog' de Antigravity: los modelos deprecados (gemini-3.5-flash-*, gemini-2.5-*, claude-* en antigravity) devuelven HTTP 400 en vez de texto de deprecacion. Funcionan: gemini-3.1-pro-low/high, gemini-3.1-flash-lite, gemini-pro-agent, gpt-oss-120b-medium. Servidor relanzado via omniroute_watchdog.ps1 -Once." } ] } diff --git a/docs/configuracion-voicemonkey-luces.md b/docs/configuracion-voicemonkey-luces.md index 845ed18..72355e2 100644 --- a/docs/configuracion-voicemonkey-luces.md +++ b/docs/configuracion-voicemonkey-luces.md @@ -1,5 +1,9 @@ # Configuración VoiceMonkey para luces Alexa +> **OBSOLETO desde 03-oct-2026.** Sustituido por **Home Assistant + Alexa Media Player** +> (gratis e ilimitado). Ver `docs/home-assistant-setup-alexa.md` y `scripts/ha_alexa.py`. +> Este documento se conserva solo como referencia histórica. + ## Resumen VoiceMonkey permite disparar rutinas de Alexa desde scripts Python mediante HTTP triggers. diff --git a/docs/home-assistant-setup-alexa.md b/docs/home-assistant-setup-alexa.md index fe0388b..64ba227 100644 --- a/docs/home-assistant-setup-alexa.md +++ b/docs/home-assistant-setup-alexa.md @@ -4,6 +4,25 @@ Home Assistant instalado en el VPS Contabo para controlar luces de Alexa ("barras" y "cuartillo") de forma gratuita e ilimitada, reemplazando VoiceMonkey. +## Estado de la migración (03-oct-2026) — COMPLETADA + +**Validado** (con efecto real): anuncio por voz (`notify.alexa_media_echo_dot_de_nahid`) y comando a Alexa ("apaga/enciende barras" vía `media_player.play_media` custom). + +**Helper común:** `biblioteca_negocio_prolongo/scripts/ha_alexa.py` +- `announce(mensaje)` — anuncio TTS a un Echo. +- `command(texto)` — envía un comando de voz a Alexa (dispara rutinas/dispositivos). + +**Sustituido VoiceMonkey por HA en:** +- `scripts/netatmo_tool.py::notificar_alexa` +- `scripts/telegram_read_tracker.py::notificar_alexa` +- `scripts/protocolo_apagado.py::apagar_luces_alexa` (y `protocolo_apagado_test.py`) + +**Credenciales:** `HOMEASSISTANT_URL` + `HOMEASSISTANT_TOKEN` en `.env` (token de larga duración). +Se han eliminado `VOICEMONKEY_TOKEN`/`VOICEMONKEY_DEVICE` del `.env`. +Ficheros VoiceMonkey ahora obsoletos: `scripts/alexa_notify.js`, `scripts/configurar_voicemonkey.py`. + +Nota: Alexa Media Player pide re-login en Amazon cada ~2 semanas. + --- ## 1. Instalación (YA HECHA) diff --git a/scripts/protocolo_apagado.py b/scripts/protocolo_apagado.py index 9c16dd8..7635173 100644 --- a/scripts/protocolo_apagado.py +++ b/scripts/protocolo_apagado.py @@ -9,6 +9,16 @@ from dotenv import load_dotenv dotenv_path = r"C:\Users\juanm\Documents\GitHub\biblioteca_negocio_prolongo\.env" load_dotenv(dotenv_path) +# Permitir importar modulos del repo de negocio (ha_alexa). +_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) +if _SCRIPT_DIR not in sys.path: + sys.path.insert(0, _SCRIPT_DIR) +try: + import infra_paths + infra_paths.bootstrap_biblioteca_paths() +except Exception: + pass + def cerrar_ventanas(): print("1. Cerrando ventanas abiertas (excepto terminal de OpenCode)...") ps_command = """ @@ -25,32 +35,16 @@ def cerrar_ventanas(): print(" -> Ventanas cerradas.") def apagar_luces_alexa(): - """Apaga las luces 'barras' y 'cuartillo' via VoiceMonkey""" - print("2. Apagando luces de Alexa (barras + cuartillo)...") - token = os.getenv("VOICEMONKEY_TOKEN") - if not token: - print(" -> [ERROR] Falta VOICEMONKEY_TOKEN en .env") + """Apaga las luces 'barras' y 'cuartillo' via HOME ASSISTANT (sustituye a VoiceMonkey).""" + print("2. Apagando luces de Alexa via Home Assistant (barras + cuartillo)...") + try: + from ha_alexa import command + except Exception as e: + print(f" -> [ERROR] No se pudo cargar ha_alexa: {e}") return - - # VoiceMonkey: crear dos "monkeys" (triggers virtuales) llamados 'apagar-barras' y 'apagar-cuartillo' - # que en su rutina de Alexa ejecutan: "Alexa, apaga barras" y "Alexa, apaga cuartillo" - - luces = [ - ("barras", "apagar-barras"), - ("cuartillo", "apagar-cuartillo") - ] - - for nombre, monkey in luces: - url = f"https://api-v2.voicemonkey.io/trigger?token={token}&device={monkey}" - try: - req = urllib.request.Request(url) - with urllib.request.urlopen(req, timeout=10) as response: - if response.status == 200: - print(f" -> Señal enviada para apagar '{nombre}'") - else: - print(f" -> Error HTTP {response.status} al apagar '{nombre}'") - except Exception as e: - print(f" -> Error al apagar '{nombre}': {e}") + for nombre in ("barras", "cuartillo"): + ok = command(f"apaga {nombre}") + print(f" -> {'OK' if ok else 'ERROR'} al apagar '{nombre}'") def apagar_pantalla_tapo(): print("3. Apagando pantalla (Tapo) via túnel RPi...") diff --git a/scripts/protocolo_apagado_test.py b/scripts/protocolo_apagado_test.py index a594fdd..cfc2f98 100644 --- a/scripts/protocolo_apagado_test.py +++ b/scripts/protocolo_apagado_test.py @@ -3,7 +3,7 @@ Protocolo de apagado completo del PC (VERSION DE PRUEBA - SIN SHUTDOWN) Pasos: 1. Cerrar ventanas abiertas -2. Apagar luces Alexa: "barras" y "cuartillo" (via VoiceMonkey) +2. Apagar luces Alexa: "barras" y "cuartillo" (via Home Assistant) 3. Apagar pantalla (Tapo via tunel RPi) 4. [COMENTADO] Shutdown del PC @@ -27,6 +27,16 @@ if sys.platform == 'win32': dotenv_path = r"C:\Users\juanm\Documents\GitHub\biblioteca_negocio_prolongo\.env" load_dotenv(dotenv_path) +# Permitir importar modulos del repo de negocio (ha_alexa). +_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) +if _SCRIPT_DIR not in sys.path: + sys.path.insert(0, _SCRIPT_DIR) +try: + import infra_paths + infra_paths.bootstrap_biblioteca_paths() +except Exception: + pass + def cerrar_ventanas(): """Cierra todas las ventanas excepto terminal/OpenCode""" print("1. Cerrando ventanas abiertas (excepto terminal de OpenCode)...") @@ -44,37 +54,16 @@ def cerrar_ventanas(): print(" ✓ Ventanas cerradas.") def apagar_luces_alexa(): - """Apaga las luces 'barras' y 'cuartillo' via VoiceMonkey""" - print("2. Apagando luces de Alexa (barras + cuartillo)...") - token = os.getenv("VOICEMONKEY_TOKEN") - if not token: - print(" ✗ [ERROR] Falta VOICEMONKEY_TOKEN en .env") + """Apaga las luces 'barras' y 'cuartillo' via HOME ASSISTANT (sustituye a VoiceMonkey).""" + print("2. Apagando luces de Alexa via Home Assistant (barras + cuartillo)...") + try: + from ha_alexa import command + except Exception as e: + print(f" ✗ [ERROR] No se pudo cargar ha_alexa: {e}") return - - # VoiceMonkey: crear dos "monkeys" (triggers virtuales) llamados 'apagar-barras' y 'apagar-cuartillo' - # que en su rutina de Alexa ejecutan: "Alexa, apaga barras" y "Alexa, apaga cuartillo" - - luces = [ - ("barras", "apagar-barras"), - ("cuartillo", "apagar-cuartillo") - ] - - for nombre, monkey in luces: - url = f"https://api-v2.voicemonkey.io/trigger?token={token}&device={monkey}" - try: - req = urllib.request.Request(url) - with urllib.request.urlopen(req, timeout=10) as response: - if response.status == 200: - print(f" ✓ Señal enviada para apagar '{nombre}'") - else: - print(f" ✗ Error HTTP {response.status} al apagar '{nombre}'") - except Exception as e: - print(f" ✗ Error al apagar '{nombre}': {e}") - - print(" ℹ️ Si las luces no se apagaron, verifica que existan los monkeys:") - print(" - 'apagar-barras' → rutina Alexa: 'Alexa, apaga barras'") - print(" - 'apagar-cuartillo' → rutina Alexa: 'Alexa, apaga cuartillo'") - print(" en https://voicemonkey.io/") + for nombre in ("barras", "cuartillo"): + ok = command(f"apaga {nombre}") + print(f" {'✓' if ok else '✗'} apagar '{nombre}'") def apagar_pantalla_tapo(): """Apaga el enchufe Tapo de la pantalla via tunel RPi"""