05-sep: [parental] preparar API ASUSWRT
This commit is contained in:
@@ -150,6 +150,8 @@ Reservas aplicadas para los 39 leases actuales y 3 reservas historicas conservad
|
|||||||
|
|
||||||
Control parental por dispositivo o grupo: horarios, bloqueo temporal, perfiles, pausas desde Telegram y registro de cambios. Se implementara despues de terminar la normalizacion de nombres del inventario.
|
Control parental por dispositivo o grupo: horarios, bloqueo temporal, perfiles, pausas desde Telegram y registro de cambios. Se implementara despues de terminar la normalizacion de nombres del inventario.
|
||||||
|
|
||||||
|
La lectura avanzada de control parental usa `asusrouter` y requiere `ASUS_USERNAME` y `ASUS_PASSWORD` solo en el `.env` local de la Raspberry. No se guardan en el repositorio.
|
||||||
|
|
||||||
## Despliegue
|
## Despliegue
|
||||||
|
|
||||||
La Pi no tiene Git operativo para este flujo. El despliegue se hace por el VPS y el tunel inverso:
|
La Pi no tiene Git operativo para este flujo. El despliegue se hace por el VPS y el tunel inverso:
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ TAPO_USERNAME=
|
|||||||
TAPO_PASSWORD=
|
TAPO_PASSWORD=
|
||||||
TAPO_TERMO_IP=
|
TAPO_TERMO_IP=
|
||||||
|
|
||||||
|
# ASUSWRT API para control parental (no compartir la contrasena)
|
||||||
|
ASUS_ROUTER_IP=192.168.50.1
|
||||||
|
ASUS_USERNAME=
|
||||||
|
ASUS_PASSWORD=
|
||||||
|
|
||||||
# Franja horaria activa (formato 24h)
|
# Franja horaria activa (formato 24h)
|
||||||
HORA_INICIO=08
|
HORA_INICIO=08
|
||||||
HORA_FIN=17
|
HORA_FIN=17
|
||||||
|
|||||||
57
vigilancia/asus_api_control.py
Normal file
57
vigilancia/asus_api_control.py
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
"""Lectura segura de datos ASUSWRT mediante la API web del router."""
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
|
from asusrouter import AsusData, AsusRouter
|
||||||
|
|
||||||
|
|
||||||
|
def _load_env():
|
||||||
|
values = {}
|
||||||
|
path = os.path.join(os.path.dirname(os.path.abspath(__file__)), ".env")
|
||||||
|
try:
|
||||||
|
with open(path) as stream:
|
||||||
|
for line in stream:
|
||||||
|
line = line.strip()
|
||||||
|
if line and not line.startswith("#") and "=" in line:
|
||||||
|
key, value = line.split("=", 1)
|
||||||
|
values[key.strip()] = value.strip()
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
return values
|
||||||
|
|
||||||
|
|
||||||
|
FILE_ENV = _load_env()
|
||||||
|
|
||||||
|
|
||||||
|
def _env(name, default=""):
|
||||||
|
return os.getenv(name, FILE_ENV.get(name, default)).strip()
|
||||||
|
|
||||||
|
|
||||||
|
async def _parental_data():
|
||||||
|
username = _env("ASUS_USERNAME")
|
||||||
|
password = _env("ASUS_PASSWORD")
|
||||||
|
if not username or not password:
|
||||||
|
raise RuntimeError(
|
||||||
|
"Falta ASUS_USERNAME o ASUS_PASSWORD en el .env de la Raspberry"
|
||||||
|
)
|
||||||
|
session = aiohttp.ClientSession()
|
||||||
|
router = AsusRouter(
|
||||||
|
hostname=_env("ASUS_ROUTER_IP", "192.168.50.1"),
|
||||||
|
username=username,
|
||||||
|
password=password,
|
||||||
|
session=session,
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
await router.async_connect()
|
||||||
|
return await router.async_get_data(AsusData.PARENTAL_CONTROL, force=True)
|
||||||
|
finally:
|
||||||
|
await router.async_disconnect()
|
||||||
|
await session.close()
|
||||||
|
|
||||||
|
|
||||||
|
def parental_status():
|
||||||
|
data = asyncio.run(_parental_data())
|
||||||
|
return json.dumps(data, ensure_ascii=False, indent=2, default=str)
|
||||||
@@ -115,6 +115,30 @@ def reservas():
|
|||||||
return f"<pre>{html.escape(output)}</pre>"
|
return f"<pre>{html.escape(output)}</pre>"
|
||||||
|
|
||||||
|
|
||||||
|
def control_parental():
|
||||||
|
try:
|
||||||
|
from asus_api_control import parental_status
|
||||||
|
return f"<pre>{html.escape(parental_status())}</pre>"
|
||||||
|
except RuntimeError as exc:
|
||||||
|
return f"<pre>{html.escape(str(exc))}</pre>"
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
keys = (
|
||||||
|
"yadns_enable_x",
|
||||||
|
"yadns_mode",
|
||||||
|
"yadns_clientlist",
|
||||||
|
"bwdpi_enable",
|
||||||
|
"bwdpi_rulelist",
|
||||||
|
"keyword_rulelist",
|
||||||
|
"url_rulelist",
|
||||||
|
"time_zone",
|
||||||
|
)
|
||||||
|
lines = []
|
||||||
|
for key in keys:
|
||||||
|
lines.append(f"{key}={_run(f'nvram get {key}')}")
|
||||||
|
return f"<pre>{html.escape(chr(10).join(lines))}</pre>"
|
||||||
|
|
||||||
|
|
||||||
def reiniciar():
|
def reiniciar():
|
||||||
return _run("reboot")
|
return _run("reboot")
|
||||||
|
|
||||||
@@ -128,5 +152,6 @@ if __name__ == "__main__":
|
|||||||
"inventario": inventario,
|
"inventario": inventario,
|
||||||
"reservar": reservar_dhcp,
|
"reservar": reservar_dhcp,
|
||||||
"reservas": reservas,
|
"reservas": reservas,
|
||||||
|
"parental": control_parental,
|
||||||
}
|
}
|
||||||
print(actions.get(action, estado)())
|
print(actions.get(action, estado)())
|
||||||
|
|||||||
Reference in New Issue
Block a user