#!/usr/bin/env python3 """Render the supported-panels table from display.py's PANELS registry. PANELS (in components/gxepd2/display.py) is the single source of truth for which panels ship and their status. This reads it by AST (no esphome import) and prints a Markdown table for the README / CONTRIBUTING.md. tools/panel_table.py """ import ast import pathlib DISPLAY_PY = pathlib.Path(__file__).resolve().parent.parent / "components" / "gxepd2" / "display.py" STATUS = { "verified": "✅ verified", "structural": "⚪ structural", "diagnostic": "🔧 diagnostic", } def panels(): tree = ast.parse(DISPLAY_PY.read_text()) for node in ast.walk(tree): if isinstance(node, ast.Assign) and any(getattr(t, "id", None) == "PANELS" for t in node.targets): for key, val in zip(node.value.keys, node.value.values): model = key.value # val is a Call: Panel(descriptor, part, controller, fmt, status) descriptor, part, controller, fmt, status = (a.value for a in val.args) yield model, part, controller, fmt, status return raise SystemExit("PANELS not found in display.py") def main(): rows = list(panels()) print("| `model:` | Panel | Controller | Format | Status |") print("|---|---|---|---|---|") for model, part, controller, fmt, status in rows: print(f"| `{model}` | {part} | {controller} | {fmt} | {STATUS.get(status, status)} |") n_ver = sum(1 for *_, s in rows if s == "verified") print(f"\n{len(rows)} panels; {n_ver} hardware-verified. " "✅ rendered correctly on real hardware · ⚪ captured, not yet bench-confirmed · 🔧 diagnostic variant.") if __name__ == "__main__": main()