#!/usr/bin/env python3 """ Pull state, config, or info from a WLED device. Uses only standard library (no pip install). """ import argparse import json import sys from typing import Optional from urllib.request import Request, urlopen from urllib.error import URLError, HTTPError DEFAULT_HOST = "192.168.240.30" ENDPOINTS = ("state", "info", "cfg", "eff", "pal", "full") def pull(host: str, endpoint: str, save_path: Optional[str], indent: Optional[int]) -> dict: base = host if host.startswith("http") else f"http://{host}" url = f"{base}/json" if endpoint == "full" else f"{base}/json/{endpoint}" req = Request(url, headers={"Accept": "application/json"}) try: with urlopen(req, timeout=10) as r: data = json.loads(r.read().decode()) except HTTPError as e: print(f"HTTP error: {e.code} {e.reason}", file=sys.stderr) if e.fp: print(e.fp.read().decode(), file=sys.stderr) sys.exit(1) except URLError as e: print(f"Request failed: {e.reason}", file=sys.stderr) sys.exit(1) except json.JSONDecodeError as e: print(f"Invalid JSON: {e}", file=sys.stderr) sys.exit(1) if save_path: with open(save_path, "w") as f: json.dump(data, f, indent=indent or 2) print(f"Saved to {save_path}") else: print(json.dumps(data, indent=indent or 2)) return data def main(): p = argparse.ArgumentParser(description="Pull state/config from WLED") p.add_argument("--host", "-H", default=DEFAULT_HOST, help=f"WLED host (default: {DEFAULT_HOST})") p.add_argument( "endpoint", nargs="?", default="full", choices=ENDPOINTS, help="state, info, cfg, eff, pal, or full (default: full)", ) p.add_argument("--save", "-o", metavar="FILE", help="Write JSON to file") p.add_argument("--no-indent", action="store_true", help="Compact JSON output") args = p.parse_args() pull( args.host, args.endpoint, args.save, None if args.no_indent else 2, ) if __name__ == "__main__": main()