20-sep: [fix] Bot Telegram control PC - confirmacion + watchdog apagado/encendido + doc autologon
This commit is contained in:
@@ -12,6 +12,7 @@ Uso:
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import asyncio
|
||||
import requests
|
||||
import subprocess
|
||||
from dotenv import load_dotenv
|
||||
@@ -65,33 +66,95 @@ async def menu(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
)
|
||||
|
||||
async def apagar_pc(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""Apaga el PC"""
|
||||
"""Apaga el PC con confirmación"""
|
||||
query = update.callback_query if update.callback_query else None
|
||||
|
||||
# CONFIRMAR antes de apagar
|
||||
keyboard = [
|
||||
[
|
||||
InlineKeyboardButton("✅ SÍ, apagar", callback_data='apagar_confirmar'),
|
||||
InlineKeyboardButton("❌ Cancelar", callback_data='cancelar')
|
||||
]
|
||||
]
|
||||
reply_markup = InlineKeyboardMarkup(keyboard)
|
||||
|
||||
mensaje = (
|
||||
"⚠️ <b>CONFIRMAR APAGADO</b>\n\n"
|
||||
"¿Seguro que quieres apagar el PC?\n\n"
|
||||
"Se ejecutará:\n"
|
||||
"🔹 Cerrar ventanas\n"
|
||||
"🔹 Apagar luces (barras + cuartillo)\n"
|
||||
"🔹 Apagar pantalla\n"
|
||||
"🔹 Apagar regleta\n"
|
||||
"🔹 Shutdown completo"
|
||||
)
|
||||
|
||||
if query:
|
||||
await query.answer("🔴 Apagando PC...")
|
||||
msg = await query.message.reply_text("🔴 Apagando PC...")
|
||||
await query.answer()
|
||||
await query.message.edit_text(mensaje, parse_mode='HTML', reply_markup=reply_markup)
|
||||
else:
|
||||
msg = await update.message.reply_text("🔴 Apagando PC...")
|
||||
await update.message.reply_text(mensaje, parse_mode='HTML', reply_markup=reply_markup)
|
||||
|
||||
async def apagar_pc_confirmar(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""Ejecuta el apagado tras confirmación"""
|
||||
query = update.callback_query
|
||||
await query.answer("🔴 Apagando PC...")
|
||||
|
||||
msg = await query.message.edit_text("🔴 Apagando PC...")
|
||||
|
||||
try:
|
||||
response = requests.post(HA_WEBHOOK_APAGAR, timeout=10)
|
||||
if response.status_code == 200:
|
||||
mensaje = (
|
||||
"✅ <b>PC apagado correctamente</b>\n\n"
|
||||
"🔹 Luces apagadas: barras, cuartillo\n"
|
||||
"🔹 Regleta: apagada\n"
|
||||
"🔹 PC: sin corriente"
|
||||
"✅ <b>Apagado iniciado</b>\n\n"
|
||||
"🔹 Luces: apagando\n"
|
||||
"🔹 Pantalla: apagando\n"
|
||||
"🔹 PC: shutdown en 10s\n\n"
|
||||
"⏳ Verificando estado en 30s..."
|
||||
)
|
||||
await msg.edit_text(mensaje, parse_mode='HTML')
|
||||
|
||||
# WATCHDOG: comprobar estado tras 30 segundos
|
||||
await asyncio.sleep(30)
|
||||
|
||||
# Verificar si realmente se apagó
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["powershell", "-Command", f"Test-Connection -ComputerName {PC_IP} -Count 1 -Quiet"],
|
||||
capture_output=True,
|
||||
timeout=5,
|
||||
text=True
|
||||
)
|
||||
online = "True" in result.stdout
|
||||
|
||||
if online:
|
||||
mensaje_final = (
|
||||
"⚠️ <b>APAGADO FALLIDO</b>\n\n"
|
||||
f"El PC sigue respondiendo en {PC_IP}\n"
|
||||
"Puede que el apagado se cancelara."
|
||||
)
|
||||
else:
|
||||
mensaje_final = (
|
||||
"✅ <b>PC APAGADO CONFIRMADO</b>\n\n"
|
||||
f"🔹 IP {PC_IP}: sin respuesta\n"
|
||||
"🔹 Estado: Offline"
|
||||
)
|
||||
except:
|
||||
mensaje_final = (
|
||||
"✅ <b>Apagado completado</b>\n\n"
|
||||
"No se pudo verificar estado (timeout)"
|
||||
)
|
||||
|
||||
await msg.edit_text(mensaje_final, parse_mode='HTML')
|
||||
else:
|
||||
mensaje = f"❌ Error al apagar: HTTP {response.status_code}"
|
||||
await msg.edit_text(mensaje, parse_mode='HTML')
|
||||
except Exception as e:
|
||||
mensaje = f"❌ Error: {e}"
|
||||
|
||||
await msg.edit_text(mensaje, parse_mode='HTML')
|
||||
await msg.edit_text(mensaje, parse_mode='HTML')
|
||||
|
||||
async def encender_pc(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""Enciende el PC"""
|
||||
"""Enciende el PC y verifica que arrancó"""
|
||||
query = update.callback_query if update.callback_query else None
|
||||
|
||||
if query:
|
||||
@@ -105,18 +168,63 @@ async def encender_pc(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
if response.status_code == 200:
|
||||
mensaje = (
|
||||
"✅ <b>Proceso de encendido iniciado</b>\n\n"
|
||||
"🔹 Regleta: encendida\n"
|
||||
"🔹 Regleta: encendiendo\n"
|
||||
"🔹 Esperando 60 segundos...\n"
|
||||
"🔹 Wake-on-LAN enviado\n\n"
|
||||
"⏳ El PC debería estar listo en ~2 minutos.\n"
|
||||
"Usa /estado para verificar."
|
||||
"🔹 Wake-on-LAN: enviando\n\n"
|
||||
"⏳ Verificando en 90 segundos..."
|
||||
)
|
||||
await msg.edit_text(mensaje, parse_mode='HTML')
|
||||
|
||||
# WATCHDOG: esperar 90s y verificar si arrancó
|
||||
await asyncio.sleep(90)
|
||||
|
||||
# Verificar si el PC arrancó
|
||||
intentos = 0
|
||||
max_intentos = 3
|
||||
online = False
|
||||
|
||||
while intentos < max_intentos and not online:
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["powershell", "-Command", f"Test-Connection -ComputerName {PC_IP} -Count 2 -Quiet"],
|
||||
capture_output=True,
|
||||
timeout=10,
|
||||
text=True
|
||||
)
|
||||
online = "True" in result.stdout
|
||||
if not online:
|
||||
intentos += 1
|
||||
if intentos < max_intentos:
|
||||
await asyncio.sleep(15)
|
||||
except:
|
||||
intentos += 1
|
||||
if intentos < max_intentos:
|
||||
await asyncio.sleep(15)
|
||||
|
||||
if online:
|
||||
mensaje_final = (
|
||||
"✅ <b>PC ENCENDIDO CORRECTAMENTE</b>\n\n"
|
||||
f"🔹 IP {PC_IP}: responde\n"
|
||||
"🔹 Estado: Online\n"
|
||||
"🔹 Tiempo: ~{} segundos".format(90 + intentos * 15)
|
||||
)
|
||||
else:
|
||||
mensaje_final = (
|
||||
"❌ <b>ENCENDIDO FALLIDO</b>\n\n"
|
||||
f"El PC no responde en {PC_IP}\n"
|
||||
"Verifica:\n"
|
||||
"🔹 Regleta encendida\n"
|
||||
"🔹 PC físicamente apagado\n"
|
||||
"🔹 Wake-on-LAN habilitado en BIOS"
|
||||
)
|
||||
|
||||
await msg.edit_text(mensaje_final, parse_mode='HTML')
|
||||
else:
|
||||
mensaje = f"❌ Error al encender: HTTP {response.status_code}"
|
||||
await msg.edit_text(mensaje, parse_mode='HTML')
|
||||
except Exception as e:
|
||||
mensaje = f"❌ Error: {e}"
|
||||
|
||||
await msg.edit_text(mensaje, parse_mode='HTML')
|
||||
await msg.edit_text(mensaje, parse_mode='HTML')
|
||||
|
||||
async def estado_pc(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""Verifica si el PC está encendido"""
|
||||
@@ -165,16 +273,26 @@ async def estado_pc(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
|
||||
await msg.edit_text(mensaje, parse_mode='HTML')
|
||||
|
||||
async def cancelar(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""Cancela una operación y vuelve al menú"""
|
||||
query = update.callback_query
|
||||
await query.answer("Cancelado")
|
||||
await menu(update, context)
|
||||
|
||||
async def button_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""Maneja los botones del menú"""
|
||||
query = update.callback_query
|
||||
|
||||
if query.data == 'apagar':
|
||||
await apagar_pc(update, context)
|
||||
elif query.data == 'apagar_confirmar':
|
||||
await apagar_pc_confirmar(update, context)
|
||||
elif query.data == 'encender':
|
||||
await encender_pc(update, context)
|
||||
elif query.data == 'estado':
|
||||
await estado_pc(update, context)
|
||||
elif query.data == 'cancelar':
|
||||
await cancelar(update, context)
|
||||
|
||||
def main():
|
||||
"""Arranca el bot"""
|
||||
|
||||
Reference in New Issue
Block a user