05-sep: [dhcp] inventariar y reservar IPs del ASUS
This commit is contained in:
@@ -392,6 +392,8 @@ def procesar(texto, chat_id):
|
||||
"<code>/router estado</code> — modelo, firmware, IP y uptime\n"
|
||||
"<code>/router clientes</code> — tabla ARP de clientes\n"
|
||||
"<code>/router wifi</code> — radios Wi-Fi\n"
|
||||
"<code>/router inventario</code> — leases DHCP con IP y MAC\n"
|
||||
"<code>/router reservar confirmar</code> — fija las IP actuales\n"
|
||||
"<code>/router reiniciar confirmar</code> — reinicio protegido",
|
||||
chat_id,
|
||||
)
|
||||
@@ -416,6 +418,24 @@ def procesar(texto, chat_id):
|
||||
except Exception as e:
|
||||
log(f"router wifi error: {e}")
|
||||
enviar(f"❌ Error consultando Wi-Fi: {e}", chat_id)
|
||||
elif accion_router == "inventario":
|
||||
try:
|
||||
from router_control import inventario
|
||||
enviar("📋 <b>INVENTARIO DHCP ASUS</b>\n" + inventario(), chat_id)
|
||||
except Exception as e:
|
||||
log(f"router inventario error: {e}")
|
||||
enviar(f"❌ Error consultando inventario: {e}", chat_id)
|
||||
elif accion_router == "reservar":
|
||||
if len(partes_router) < 2 or partes_router[1] != "confirmar":
|
||||
enviar("Para reservar las IP actuales responde exactamente: <code>/router reservar confirmar</code>", chat_id)
|
||||
else:
|
||||
try:
|
||||
from router_control import reservar_dhcp
|
||||
enviar("⏳ Aplicando reservas DHCP...", chat_id)
|
||||
enviar(f"✅ {reservar_dhcp()}", chat_id)
|
||||
except Exception as e:
|
||||
log(f"router reservar error: {e}")
|
||||
enviar(f"❌ Error aplicando reservas: {e}", chat_id)
|
||||
elif accion_router in ("reiniciar", "reboot"):
|
||||
if len(partes_router) < 2 or partes_router[1] != "confirmar":
|
||||
enviar("Para reiniciar responde exactamente: <code>/router reiniciar confirmar</code>", chat_id)
|
||||
@@ -488,7 +508,7 @@ def procesar(texto, chat_id):
|
||||
" ✏️ Ej: <code>/estado</code>\n"
|
||||
"<b>14.</b> <code>temperatura</code> — temperatura de la Pi\n"
|
||||
" ✏️ Ej: <code>/temperatura</code>\n"
|
||||
"<b>15.</b> <code>router estado|clientes|wifi</code> — controla el ASUS\n"
|
||||
"<b>15.</b> <code>router estado|clientes|wifi|inventario</code> — controla el ASUS\n"
|
||||
" ✏️ Ej: <code>/router estado</code>\n"
|
||||
"<b>16.</b> <code>panorama</code> — fotos de las cámaras\n"
|
||||
" ✏️ Ej: <code>/panorama</code>\n"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
"""Consultas seguras al ASUS RT-AX88U PRO desde la Raspberry."""
|
||||
|
||||
import html
|
||||
import re
|
||||
import shlex
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
@@ -59,11 +61,63 @@ def clientes():
|
||||
return f"<pre>{html.escape(output)}</pre>"
|
||||
|
||||
|
||||
def _reservas_actuales(text):
|
||||
return re.findall(r"<([^>]+)>([^>]+)>>", text or "")
|
||||
|
||||
|
||||
def _inventario():
|
||||
leases = _run("cat /var/lib/misc/dnsmasq.leases")
|
||||
reservas = _reservas_actuales(_run("nvram get dhcp_staticlist"))
|
||||
by_mac = {mac.upper(): ip for mac, ip in reservas}
|
||||
devices = []
|
||||
for line in leases.splitlines():
|
||||
fields = line.split()
|
||||
if len(fields) < 4 or not fields[2].startswith("192.168.50."):
|
||||
continue
|
||||
mac, ip, name = fields[1].upper(), fields[2], fields[3]
|
||||
by_mac.setdefault(mac, ip)
|
||||
devices.append((ip, mac, name if name != "*" else "pendiente-identificar"))
|
||||
devices.sort(key=lambda item: int(item[0].rsplit(".", 1)[1]))
|
||||
return devices, by_mac
|
||||
|
||||
|
||||
def inventario():
|
||||
devices, _by_mac = _inventario()
|
||||
lines = ["IP MAC NOMBRE"]
|
||||
lines.extend(f"{ip:<18} {mac:<22} {name}" for ip, mac, name in devices)
|
||||
return f"<pre>{html.escape(chr(10).join(lines))}</pre>"
|
||||
|
||||
|
||||
def reservar_dhcp():
|
||||
devices, by_mac = _inventario()
|
||||
payload = "".join(f"<{mac}>{ip}>>" for mac, ip in by_mac.items())
|
||||
command = (
|
||||
f"nvram set dhcp_staticlist={shlex.quote(payload)}; "
|
||||
"nvram commit; service restart_dnsmasq"
|
||||
)
|
||||
result = _run(command)
|
||||
if result.startswith("Error "):
|
||||
return result
|
||||
return f"Reservas DHCP aplicadas: {len(by_mac)} dispositivos. Leases inventariados: {len(devices)}."
|
||||
|
||||
|
||||
def reservas():
|
||||
output = _run("nvram get dhcp_staticlist")
|
||||
return f"<pre>{html.escape(output)}</pre>"
|
||||
|
||||
|
||||
def reiniciar():
|
||||
return _run("reboot")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
action = sys.argv[1] if len(sys.argv) > 1 else "estado"
|
||||
actions = {"estado": estado, "clientes": clientes, "wifi": wifi}
|
||||
actions = {
|
||||
"estado": estado,
|
||||
"clientes": clientes,
|
||||
"wifi": wifi,
|
||||
"inventario": inventario,
|
||||
"reservar": reservar_dhcp,
|
||||
"reservas": reservas,
|
||||
}
|
||||
print(actions.get(action, estado)())
|
||||
|
||||
Reference in New Issue
Block a user