panel_table.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. #!/usr/bin/env python3
  2. """Render the supported-panels table from display.py's PANELS registry.
  3. PANELS (in components/gxepd2/display.py) is the single source of truth for
  4. which panels ship and their status. This reads it by AST (no esphome import)
  5. and prints a Markdown table for the README / CONTRIBUTING.md.
  6. tools/panel_table.py
  7. """
  8. import ast
  9. import pathlib
  10. DISPLAY_PY = pathlib.Path(__file__).resolve().parent.parent / "components" / "gxepd2" / "display.py"
  11. STATUS = {
  12. "verified": "✅ verified",
  13. "structural": "⚪ structural",
  14. "diagnostic": "🔧 diagnostic",
  15. }
  16. def panels():
  17. tree = ast.parse(DISPLAY_PY.read_text())
  18. for node in ast.walk(tree):
  19. if isinstance(node, ast.Assign) and any(getattr(t, "id", None) == "PANELS" for t in node.targets):
  20. for key, val in zip(node.value.keys, node.value.values):
  21. model = key.value
  22. # val is a Call: Panel(descriptor, part, controller, fmt, status)
  23. descriptor, part, controller, fmt, status = (a.value for a in val.args)
  24. yield model, part, controller, fmt, status
  25. return
  26. raise SystemExit("PANELS not found in display.py")
  27. def main():
  28. rows = list(panels())
  29. print("| `model:` | Panel | Controller | Format | Status |")
  30. print("|---|---|---|---|---|")
  31. for model, part, controller, fmt, status in rows:
  32. print(f"| `{model}` | {part} | {controller} | {fmt} | {STATUS.get(status, status)} |")
  33. n_ver = sum(1 for *_, s in rows if s == "verified")
  34. print(f"\n{len(rows)} panels; {n_ver} hardware-verified. "
  35. "✅ rendered correctly on real hardware · ⚪ captured, not yet bench-confirmed · 🔧 diagnostic variant.")
  36. if __name__ == "__main__":
  37. main()