diff --git a/aria-brain/agent.py b/aria-brain/agent.py index a582970..79f3b0f 100644 --- a/aria-brain/agent.py +++ b/aria-brain/agent.py @@ -1292,7 +1292,9 @@ META_TOOLS = [ "existiert, weiss SNMP NICHT). 'snmp.get'/'snmp.walk' " "(params={'ip':'...','oid':'...','community':'public'}) fuer beliebige " "SNMP-Werte. 'fritzbox.info' / 'fritzbox.hosts' (params={'ip':''}) " - "— Internetverbindung/Datenrate/externe IP bzw. verbundene Geraete (braucht " + "— Internetverbindung/Datenrate/externe IP bzw. verbundene Geraete MIT " + "Verbindungsart (LAN/WLAN), lan_port (an welcher LAN-Buchse der Box) und " + "speed_mbit; 'find' filtert nach Name/IP/MAC (braucht " "hinterlegten FritzBox-Login). 'ssh.exec' (params={'ip':'...','cmd':'...'}) " "— fuehrt EIN Shell-Kommando per SSH auf einem Geraet aus (Server, Pi, NAS) " "und gibt exit_code + stdout (gefenstert: contains/offset/max_chars) + " diff --git a/satellite/satellite.py b/satellite/satellite.py index 850bfbf..6459c2e 100644 --- a/satellite/satellite.py +++ b/satellite/satellite.py @@ -1199,7 +1199,9 @@ def _tr064(ip: str, user: str, pw: str, service: str, control: str, def _do_fritzbox(action: str, params: dict) -> dict: """fritzbox.info -> Modell/Firmware/Verbindung/externe IP/Datenrate. - fritzbox.hosts -> Liste der bekannten Geraete (Name/IP/MAC/aktiv).""" + fritzbox.hosts -> Liste der bekannten Geraete (Name/IP/MAC/aktiv) plus + Verbindungsart (LAN/WLAN), LAN-Port und Geschwindigkeit. + params.find: nur Geraete, deren Name/IP/MAC das enthaelt.""" ip = _snmp_target(params) if not ip: return {"ok": False, "error": "ip/host erforderlich."} @@ -1227,16 +1229,36 @@ def _do_fritzbox(action: str, params: dict) -> dict: except Exception as exc: return {"ok": False, "error": f"Host-Liste nicht abrufbar: {exc}"} hosts = [] + find = str(params.get("find") or "").strip().lower() for item in re.finditer(r"(.*?)", r.text, re.DOTALL): blk = item.group(1) def _t(tag): m = re.search(rf"<{tag}>(.*?)", blk, re.DOTALL) - return m.group(1) if m else "" - hosts.append({"name": _t("HostName"), "ip": _t("IPAddress"), - "mac": _t("MACAddress"), - "active": _t("Active") in ("1", "true")}) - return {"ok": True, "result": {"ip": ip, "count": len(hosts), "hosts": hosts}} + return m.group(1).strip() if m else "" + h = {"name": _t("HostName"), "ip": _t("IPAddress"), + "mac": _t("MACAddress"), + "active": _t("Active") in ("1", "true")} + # AVM-Zusatzfelder (je nach FRITZ!OS vorhanden): Verbindungsart, + # LAN-Port der Box (0 = kein direkter LAN-Port, z.B. WLAN/Mesh), + # Geschwindigkeit in Mbit/s, Gast-Netz. + iface = _t("InterfaceType") + if iface: + h["interface"] = iface + port = _to_int(_t("X_AVM-DE_Port")) + if port: + h["lan_port"] = port + speed = _to_int(_t("X_AVM-DE_Speed")) + if speed: + h["speed_mbit"] = speed + if _t("X_AVM-DE_Guest") in ("1", "true"): + h["guest"] = True + if find and not any(find in str(h.get(k, "")).lower() for k in ("name", "ip", "mac")): + continue + hosts.append(h) + return {"ok": True, "result": {"ip": ip, "count": len(hosts), "hosts": hosts, + "hinweis": "lan_port = LAN-Buchse DIESER Box. Haengt ein Geraet " + "hinter einem Switch/Repeater, steht hier dessen Port."}} # fritzbox.info (Default): mehrere Services, Teil-Fehler tolerieren. info = {"ip": ip}