04-oct: encender_sobremesa escalera WoL->regleta->ciclo (Power On Loss validado) + doc
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
- **2026-10-04-instalador-de-dependencias-python-plugin-omniroute-autostart** [scripts] Instalador de dependencias Python + plugin omniroute-autostart + comparativa equipos (aplicado en: portatil)
|
||||
- **2026-10-04-fix-tareas-programadas-userdomain-computername-workgroup-ssh** [scripts] Fix tareas programadas: USERDOMAIN->COMPUTERNAME (workgroup/SSH) (aplicado en: portatil)
|
||||
- **2026-10-04-sobremesa-instalados-voicestudio-autohotkey-v2-tarea-superwh** [scripts] Sobremesa: instalados VoiceStudio + AutoHotkey v2 + tarea SuperWhisper Enter (aplicado en: portatil)
|
||||
- **2026-10-04-protocolo-encendido-sobremesa-validado-wol-falla-ciclo-regle** [servicios] Protocolo encendido sobremesa validado: WoL falla, ciclo regleta funciona (Power On Loss) (aplicado en: portatil)
|
||||
|
||||
## Historial
|
||||
|
||||
@@ -50,6 +51,14 @@
|
||||
- **Aplicado en**: portatil
|
||||
- **Detalle**: Via SSH desde el portatil. VoiceStudio 0.5.6 (per-user en %LOCALAPPDATA%\Programs\VoiceStudio, instalador GitHub debpalash/VoiceStudio /S). AutoHotkey v2 (winget AutoHotkey.AutoHotkey). Tarea programada 'SuperWhisper Enter' (AtLogOn, hidden) -> AutoHotkey64.exe + scripts/superwhisper_enter.ahk. Nota: el sobremesa tiene RTX 4070 (12GB) -> VoiceStudio usara GPU; requiere abrir la app para levantar backend 3900 y crear perfiles de voz.
|
||||
|
||||
### 2026-10-04 · Protocolo encendido sobremesa validado: WoL falla, ciclo regleta funciona (Power On Loss)
|
||||
- **id**: `2026-10-04-protocolo-encendido-sobremesa-validado-wol-falla-ciclo-regle`
|
||||
- **Equipo**: portatil
|
||||
- **Categoria**: servicios
|
||||
- **Transferible**: si
|
||||
- **Aplicado en**: portatil
|
||||
- **Detalle**: Prueba 04-oct: apagado simple OK; WoL desde portatil NO responde (doble NAT .50->.1); ciclo regleta (apagar 1min + encender) arranca el PC solo (BIOS Restore on AC Power Loss = Power On). encender_sobremesa.py actualizado con la escalera WoL->regleta->ciclo-regleta. Doc PROTOCOLO_ENCENDIDO_REMOTO_SSH.md actualizado.
|
||||
|
||||
### 2026-10-03 · SuperWhisper Enter: AHK F13 boton auxiliar Logitech + tarea programada
|
||||
- **id**: `2026-10-03-superwhisper-enter-ahk-f13-boton-auxiliar-logitech-tarea-pro`
|
||||
- **Equipo**: portatil
|
||||
|
||||
@@ -423,6 +423,18 @@
|
||||
"portatil"
|
||||
],
|
||||
"detalle": "Via SSH desde el portatil. VoiceStudio 0.5.6 (per-user en %LOCALAPPDATA%\\Programs\\VoiceStudio, instalador GitHub debpalash/VoiceStudio /S). AutoHotkey v2 (winget AutoHotkey.AutoHotkey). Tarea programada 'SuperWhisper Enter' (AtLogOn, hidden) -> AutoHotkey64.exe + scripts/superwhisper_enter.ahk. Nota: el sobremesa tiene RTX 4070 (12GB) -> VoiceStudio usara GPU; requiere abrir la app para levantar backend 3900 y crear perfiles de voz."
|
||||
},
|
||||
{
|
||||
"id": "2026-10-04-protocolo-encendido-sobremesa-validado-wol-falla-ciclo-regle",
|
||||
"fecha": "2026-10-04",
|
||||
"equipo": "portatil",
|
||||
"categoria": "servicios",
|
||||
"titulo": "Protocolo encendido sobremesa validado: WoL falla, ciclo regleta funciona (Power On Loss)",
|
||||
"transferible": true,
|
||||
"aplicado_en": [
|
||||
"portatil"
|
||||
],
|
||||
"detalle": "Prueba 04-oct: apagado simple OK; WoL desde portatil NO responde (doble NAT .50->.1); ciclo regleta (apagar 1min + encender) arranca el PC solo (BIOS Restore on AC Power Loss = Power On). encender_sobremesa.py actualizado con la escalera WoL->regleta->ciclo-regleta. Doc PROTOCOLO_ENCENDIDO_REMOTO_SSH.md actualizado."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,19 +22,20 @@ Fecha: 03-oct-2026. Objetivo: **encender el sobremesa estando apagado y conectar
|
||||
```
|
||||
`offline` = apagado. (Desde la red `.1` también vale `ping 192.168.1.239`.)
|
||||
|
||||
**2. Si está apagado → encender la regleta** (comando Alexa vía Home Assistant)
|
||||
```powershell
|
||||
python C:\Users\juanm\Documents\GitHub\biblioteca_negocio_prolongo\scripts\ha_alexa.py command "enciende regleta"
|
||||
```
|
||||
**2. Escalera de intentos** (en orden; comprobar el estado tras cada uno):
|
||||
|
||||
**3. Esperar 3 minutos.**
|
||||
1. **Wake-on-LAN** — magic packet a la MAC `74:56:3C:CB:0E:CE`.
|
||||
> Desde el portátil (`.50`) el magic packet **no cruza** a `.1` por el doble NAT → normalmente **falla**. Solo funcionaría desde un equipo en la red `.1`.
|
||||
2. **Encender la regleta** (comando Alexa vía Home Assistant):
|
||||
```powershell
|
||||
python C:\Users\juanm\Documents\GitHub\biblioteca_negocio_prolongo\scripts\ha_alexa.py command "enciende regleta"
|
||||
```
|
||||
3. **Ciclo de regleta** (el **fiable**): apagar la regleta, esperar **1 min**, y volver a encenderla. Con `Restore on AC Power Loss = Power On` en BIOS, el PC **arranca solo**.
|
||||
|
||||
**4. Volver a comprobar el estado.** Si está encendido → **listo**.
|
||||
**3. Informar** (aviso voz Carolina) tras cada comprobación.
|
||||
|
||||
**5. Si sigue apagado → intentar Wake-on-LAN** (magic packet a la MAC `74:56:3C:CB:0E:CE`).
|
||||
> Nota: desde el portátil (`.50`) el magic packet **no llega** a `.1` por el doble NAT. Solo funcionaría desde un equipo en la red `.1`. El método fiable es la **regleta** (+ BIOS `Restore on AC Power Loss = Power On`).
|
||||
> **Resultado de la prueba (04-oct-2026):** apagado simple OK; **WoL NO funcionó**; **ciclo de regleta SÍ** (arrancó solo, confirma `Power On Loss`). Es la vía buena para el sobremesa.
|
||||
|
||||
**6. Esperar 3 minutos, comprobar e informar.**
|
||||
|
||||
**7. Conectar a PowerShell:**
|
||||
```powershell
|
||||
|
||||
@@ -2,20 +2,16 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""encender_sobremesa.py — Protocolo de encendido remoto del sobremesa.
|
||||
|
||||
Pasos (protocolo acordado):
|
||||
0. Estado de la regleta (best-effort, si hay acceso al Tapo).
|
||||
1. Comprobar si el PC esta apagado (Tailscale).
|
||||
2. Si esta apagado -> encender la regleta con un comando a Alexa (via Home Assistant).
|
||||
3. Esperar 3 min.
|
||||
4. Volver a comprobar. Si esta encendido -> fin.
|
||||
5. Si sigue apagado -> intentar Wake-on-LAN (best-effort).
|
||||
6. Esperar 3 min, comprobar e informar.
|
||||
|
||||
Al terminar cada comprobacion emite un aviso de voz (Carolina) para que el usuario
|
||||
pueda hacer otras cosas mientras tanto.
|
||||
Escalera de intentos (acordada):
|
||||
0. Estado de la regleta (best-effort).
|
||||
1. Si el PC esta apagado -> intento 1: Wake-on-LAN.
|
||||
2. Si no responde -> intento 2: encender la regleta (comando Alexa via Home Assistant).
|
||||
3. Si no responde -> intento 3: apagar la regleta 1 min y volver a encenderla
|
||||
(BIOS 'Restore on AC Power Loss = Power On' -> arranca solo).
|
||||
4. Informar por voz (Carolina) tras cada comprobacion.
|
||||
|
||||
Uso:
|
||||
python scripts/encender_sobremesa.py [--espera 180] [--no-voz]
|
||||
python scripts/encender_sobremesa.py [--espera 120] [--no-voz]
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -36,13 +32,11 @@ import infra_paths # noqa: E402
|
||||
|
||||
TS_EXE = os.path.join(os.environ.get("ProgramFiles", r"C:\Program Files"), "Tailscale", "tailscale.exe")
|
||||
NODO = "desktop-m8se61g"
|
||||
TAILSCALE_IP = "100.75.115.29"
|
||||
COS_ENCENDER = "enciende regleta"
|
||||
COS_APAGAR = "apaga regleta"
|
||||
MAC = "74:56:3C:CB:0E:CE"
|
||||
COMANDO_REGLETA = "enciende regleta"
|
||||
|
||||
|
||||
# --------------------------------------------------------------- estado del PC
|
||||
|
||||
def pc_encendido() -> bool | None:
|
||||
"""True/False segun Tailscale. None si no se puede determinar."""
|
||||
try:
|
||||
@@ -55,15 +49,12 @@ def pc_encendido() -> bool | None:
|
||||
return None
|
||||
|
||||
|
||||
# --------------------------------------------------------------- regleta (Tapo)
|
||||
|
||||
def estado_regleta() -> bool | None:
|
||||
"""Best-effort: True/False si se puede consultar el Tapo; None si no."""
|
||||
try:
|
||||
from PyP100 import PyP100 as PP
|
||||
except Exception:
|
||||
return None
|
||||
# credenciales hardcodeadas en un script existente del repo de negocio
|
||||
repo = infra_paths.biblioteca_repo()
|
||||
creds = None
|
||||
for f in glob.glob(str(repo / "scripts" / "protocolo_apagado*.py")) + glob.glob(str(_SCRIPTS_DIR / "protocolo_apagado*.py")):
|
||||
@@ -86,28 +77,29 @@ def estado_regleta() -> bool | None:
|
||||
return None
|
||||
|
||||
|
||||
# --------------------------------------------------------------- Alexa / HA
|
||||
|
||||
def encender_regleta() -> bool:
|
||||
"""Envia 'enciende regleta' a Alexa vía Home Assistant."""
|
||||
def _comando_alexa(texto: str) -> bool:
|
||||
infra_paths.bootstrap_biblioteca_paths()
|
||||
try:
|
||||
from ha_alexa import command
|
||||
|
||||
return command(COMANDO_REGLETA)
|
||||
return command(texto)
|
||||
except Exception as e:
|
||||
print(f"[encender_sobremesa] Error llamando a HA: {e}", file=sys.stderr)
|
||||
return False
|
||||
|
||||
|
||||
# --------------------------------------------------------------- WoL
|
||||
def encender_regleta() -> bool:
|
||||
return _comando_alexa(COS_ENCENDER)
|
||||
|
||||
|
||||
def apagar_regleta() -> bool:
|
||||
return _comando_alexa(COS_APAGAR)
|
||||
|
||||
|
||||
def wol() -> None:
|
||||
"""Magic packet (best-effort). Desde .50 no cruza a .1; se intenta igualmente."""
|
||||
import socket
|
||||
|
||||
paquete = b"\xff" * 6 + bytes.fromhex(MAC.replace(":", "")) * 16
|
||||
for destino in (f"{TAILSCALE_IP.split('.')[0]}.255", "255.255.255.255", "192.168.1.255", "192.168.50.255"):
|
||||
for destino in ("192.168.1.255", "192.168.1.239", "255.255.255.255", "192.168.50.255"):
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
||||
@@ -118,7 +110,15 @@ def wol() -> None:
|
||||
print(f" magic packet -> {destino}:9 ERROR {e}")
|
||||
|
||||
|
||||
# --------------------------------------------------------------- voz
|
||||
def esperar_encendido(segundos: int) -> bool:
|
||||
t = 0
|
||||
while t < segundos:
|
||||
if pc_encendido():
|
||||
return True
|
||||
time.sleep(10)
|
||||
t += 10
|
||||
return False
|
||||
|
||||
|
||||
def aviso(texto: str, voz: bool = True) -> None:
|
||||
print(f"[aviso] {texto}")
|
||||
@@ -131,11 +131,9 @@ def aviso(texto: str, voz: bool = True) -> None:
|
||||
pass
|
||||
|
||||
|
||||
# --------------------------------------------------------------- protocolo
|
||||
|
||||
def main() -> int:
|
||||
ap = argparse.ArgumentParser(description="Encendido remoto del sobremesa.")
|
||||
ap.add_argument("--espera", type=int, default=180, help="Segundos de espera entre comprobaciones (defecto 180).")
|
||||
ap.add_argument("--espera", type=int, default=120, help="Segundos por intento (defecto 120).")
|
||||
ap.add_argument("--no-voz", action="store_true", help="Sin avisos de voz.")
|
||||
args = ap.parse_args()
|
||||
voz = not args.no_voz
|
||||
@@ -149,24 +147,30 @@ def main() -> int:
|
||||
aviso("El sobremesa ya estaba encendido.", voz)
|
||||
return 0
|
||||
|
||||
print(f"-> Encendiendo regleta (Alexa: '{COMANDO_REGLETA}')... {encender_regleta()}")
|
||||
print(f"-> Esperando {args.espera}s...")
|
||||
time.sleep(args.espera)
|
||||
|
||||
if pc_encendido():
|
||||
aviso("El sobremesa se ha encendido correctamente con la regleta.", voz)
|
||||
return 0
|
||||
|
||||
print("-> Sigue apagado; intentando Wake-on-LAN (best-effort)...")
|
||||
# Intento 1 - Wake-on-LAN
|
||||
print(f"-> Intento 1: Wake-on-LAN...")
|
||||
wol()
|
||||
print(f"-> Esperando {args.espera}s...")
|
||||
time.sleep(args.espera)
|
||||
|
||||
if pc_encendido():
|
||||
aviso("El sobremesa se ha encendido tras el Wake on LAN.", voz)
|
||||
if esperar_encendido(args.espera):
|
||||
aviso("El sobremesa se ha encendido con Wake on LAN.", voz)
|
||||
return 0
|
||||
|
||||
aviso("No se ha podido encender el sobremesa ni con la regleta ni con Wake on LAN.", voz)
|
||||
# Intento 2 - encender regleta
|
||||
print("-> Intento 2: encender regleta (Alexa)...")
|
||||
encender_regleta()
|
||||
if esperar_encendido(args.espera):
|
||||
aviso("El sobremesa se ha encendido al dar corriente la regleta.", voz)
|
||||
return 0
|
||||
|
||||
# Intento 3 - ciclo de regleta (Power On Loss)
|
||||
print("-> Intento 3: apagar regleta 1 min y volver a encender (Power On Loss)...")
|
||||
apagar_regleta()
|
||||
time.sleep(60)
|
||||
encender_regleta()
|
||||
if esperar_encendido(args.espera):
|
||||
aviso("El sobremesa se ha encendido tras el ciclo de regleta. Power On Loss funciona.", voz)
|
||||
return 0
|
||||
|
||||
aviso("No se ha podido encender el sobremesa ni con WoL ni con la regleta.", voz)
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user