diff --git a/services/openwrt.py b/services/openwrt.py index 53adb4e..d2862e9 100644 --- a/services/openwrt.py +++ b/services/openwrt.py @@ -205,50 +205,62 @@ async def get_openwrt_status(cfg: dict[str, Any]) -> str: ssh_cmd += ["-i", str(identity_file)] ssh_cmd += ["-p", str(port), f"{user}@{host}"] - remote = ( - "ubus call system info >/tmp/ow_sys.json 2>/dev/null && " - "cat /tmp/ow_sys.json || (cat /proc/uptime; echo; cat /proc/loadavg); " - "echo __SEP__;" - "ubus call network.interface.wan status; echo __SEP__;" - "ubus call network.wireless status; echo __SEP__;" - "ubus call luci-rpc getDHCPLeases '{\"family\":4}' >/tmp/ow_leases.json 2>/dev/null && " - "cat /tmp/ow_leases.json || cat /tmp/dhcp.leases" - ) - cmd = ssh_cmd + ["sh", "-c", remote] - rc, out = await run_cmd(cmd, timeout=timeout_sec + 5) - if rc != 0: - return f"⚠️ OpenWrt SSH error: {out.strip() or 'unknown error'}" - - parts = [p.strip() for p in out.split("__SEP__")] - if len(parts) < 4: - return "⚠️ OpenWrt response incomplete" + async def _ssh_cmd(cmd: str) -> tuple[int, str]: + run = ssh_cmd + ["sh", "-c", cmd] + return await run_cmd(run, timeout=timeout_sec + 5) sys_info = None - wan_status = None - wireless = None - leases = None - try: - sys_info = json.loads(parts[0]) - except json.JSONDecodeError: - sys_info = None - try: - wan_status = json.loads(parts[1]) - except json.JSONDecodeError: + rc, out = await _ssh_cmd("ubus call system info 2>/dev/null") + if rc == 0 and out.strip(): + try: + sys_info = json.loads(out) + except json.JSONDecodeError: + sys_info = None + if sys_info is None: + rc_u, out_u = await _ssh_cmd("cat /proc/uptime; echo; cat /proc/loadavg") + if rc_u != 0: + return f"⚠️ OpenWrt SSH error: {out_u.strip() or 'unknown error'}" + fallback_raw = out_u + else: + fallback_raw = "" + + rc, out = await _ssh_cmd("ubus call network.interface.wan status 2>/dev/null") + if rc == 0 and out.strip(): + try: + wan_status = json.loads(out) + except json.JSONDecodeError: + wan_status = {} + else: wan_status = {} - try: - wireless = json.loads(parts[2]) - except json.JSONDecodeError: + + rc, out = await _ssh_cmd("ubus call network.wireless status 2>/dev/null") + if rc == 0 and out.strip(): + try: + wireless = json.loads(out) + except json.JSONDecodeError: + wireless = {} + else: wireless = {} - try: - leases = json.loads(parts[3]) - except json.JSONDecodeError: + + rc, out = await _ssh_cmd("ubus call luci-rpc getDHCPLeases '{\"family\":4}' 2>/dev/null") + if rc == 0 and out.strip(): + try: + leases = json.loads(out) + except json.JSONDecodeError: + leases = None + else: leases = None + rc_l, out_l = await _ssh_cmd("cat /tmp/dhcp.leases 2>/dev/null || true") + if rc_l == 0: + leases_fallback = out_l + else: + leases_fallback = "" if isinstance(sys_info, dict): uptime_raw = sys_info.get("uptime") load_raw = sys_info.get("load") else: - uptime_raw, load_raw = _parse_proc_fallback(parts[0]) + uptime_raw, load_raw = _parse_proc_fallback(fallback_raw) uptime = _format_uptime(uptime_raw) load = _format_load(load_raw) wan_ip = _extract_wan_ip(wan_status) or "unknown" @@ -268,7 +280,10 @@ async def get_openwrt_status(cfg: dict[str, Any]) -> str: if rc2 == 0 and out2.strip(): wifi_clients.extend(_parse_hostapd_clients(out2.strip(), ifname)) - leases_list = _extract_leases(leases) if leases else _parse_leases_fallback(parts[3]) + if leases: + leases_list = _extract_leases(leases) + else: + leases_list = _parse_leases_fallback(leases_fallback) lines = [ "📡 OpenWrt",