"""Run native DRC, schematic parity, and render the two unrouted PCB boards.""" from collections import Counter import json from pathlib import Path import subprocess import pcbnew as pcb from bootstrap_pcb import ROOT, OUT, mating_check, verify_import from check_hardware import Board CLI = 'D:/KiCad/bin/kicad-cli.exe' def run(args, output): result = subprocess.run([CLI, *args], capture_output=True, encoding='utf-8', errors='replace', timeout=120) output.with_suffix(output.suffix+'.log').write_text(result.stdout+result.stderr,encoding='utf-8') if result.returncode or not output.exists(): raise RuntimeError(f'KiCad failed ({result.returncode}); see {output}.log') def main(): reports, boards = {}, [] for n in (1,2): name = f'PhoneRail-Board{n}' path = ROOT/name/(name+'.kicad_pcb') source = Board(n) source.compile(CLI,OUT) board = pcb.LoadBoard(str(path)) checks = verify_import(board,source,n) boards.append(board) drc = OUT/f'Board{n}-drc.json' run(['pcb','drc','--format','json','--schematic-parity','-o',str(drc),str(path)],drc) data = json.loads(drc.read_text(encoding='utf-8')) checks['drc_violations'] = dict(Counter(v['type'] for v in data.get('violations',[]))) checks['unconnected_items'] = len(data.get('unconnected_items',[])) checks['schematic_parity'] = data.get('schematic_parity',[]) assert not checks['schematic_parity'], f'{name}: schematic parity mismatch' assert not data.get('violations'), f'{name}: DRC geometry/library violation; see {drc}' roundtrip = OUT/f'{name}-roundtrip.kicad_pcb' pcb.SaveBoard(str(roundtrip),board) verify_import(pcb.LoadBoard(str(roundtrip)),source,n) checks['native_save_roundtrip'] = 'passed' for face,layers in [('top','F.Cu,Edge.Cuts,Dwgs.User'),('bottom','B.Cu,Edge.Cuts,Dwgs.User')]: svg = OUT/f'Board{n}-{face}.svg' run(['pcb','export','svg','--mode-single','--layers',layers,'--page-size-mode','2', '--exclude-drawing-sheet','-o',str(svg),str(path)],svg) reports[name] = checks print(name, 'DRC', checks['drc_violations'], 'unconnected',checks['unconnected_items'], 'schematic parity',len(checks['schematic_parity']),flush=True) reports['mated_pins_checked'] = mating_check(*boards) reports['status'] = 'UNROUTED_PLACEMENT_START' (OUT/'verification.json').write_text(json.dumps(reports,indent=2,ensure_ascii=False)+'\n',encoding='utf-8') if __name__ == '__main__': main()