文件

64 行
2.5 KiB
Python

#!/usr/bin/env python3
"""对账 4:封装库完整性。
三项:
1. 原理图里每个元件引用的封装,库里都有;
2. 封装的焊盘号集合 ⊇ 符号的引脚号集合(少一个焊盘 = 网络接不上,PCB 里才会暴露);
3. 文件能被 KiCad 解析(交给 kicad-cli 做)。
"""
import json, os, re, sys, collections
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from k_netlist import parse_pads
ROOT = os.path.dirname(os.path.abspath(__file__))
SRC = os.path.join(ROOT, "eda_src")
PRETTY = os.path.join(os.path.dirname(ROOT), "kicad", "lib", "PhoneRail.pretty")
def fp_pads(path):
s = open(path, encoding="utf-8").read()
return {m.group(1) for m in re.finditer(r'\(pad "([^"]*)"', s)}
def main():
have = {}
for f in os.listdir(PRETTY):
if f.endswith(".kicad_mod"):
have[f[:-10]] = fp_pads(os.path.join(PRETTY, f))
ok = True
for board in ("Board1", "Board2"):
base = parse_pads(os.path.join(SRC, board, "netlist.asc"))
want = collections.Counter(base["parts"].values())
missing = sorted(n for n in want if n and n not in have)
print(f"[{board}] 引用封装 {len(want)} 种", end="")
if missing:
print(f" ✘ 库里缺 {len(missing)}: {missing[:6]}"); ok = False
else:
print(" ✔ 全部存在")
# 焊盘号 vs 引脚号
tree = json.load(open(os.path.join(SRC, "_tree.json"), encoding="utf-8"))
pages = next(x for x in tree["boards"] if x["board"] == board)["pages"]
bad = []
for p in pages:
g = json.load(open(os.path.join(SRC, board, p["name"] + ".geom.json"), encoding="utf-8"))
for c in (g["prims"]["Component"] or []):
if c["ComponentType"] != "part":
continue
fp = (c.get("Footprint") or {}).get("name")
if fp not in have:
continue
pins = {str(q["PinNumber"]) for q in (c.get("__pins") or [])}
miss = pins - have[fp]
if miss:
bad.append((c["Designator"], fp, sorted(miss)[:4]))
if bad:
print(f" ✘ 引脚号在封装里找不到对应焊盘 {len(bad)}: {bad[:4]}"); ok = False
else:
print(" ✔ 焊盘号覆盖全部引脚号")
print("\n" + ("封装库检查通过 ✔" if ok else "封装库有问题 ✘"))
sys.exit(0 if ok else 1)
if __name__ == "__main__":
main()