116 行
4.7 KiB
Python
116 行
4.7 KiB
Python
# -*- coding: utf-8 -*-
|
||
u"""FAN-R2 落到下板 PCB1:**只动风扇那一块**的 24 个元件,别的 277 个和已有铜一律不碰。
|
||
|
||
/c/Python314/python .claude/pcb1_fan.py # 干跑
|
||
/c/Python314/python .claude/pcb1_fan.py --push # 摆件 + 拆废铜 + 存盘
|
||
|
||
为什么不直接 `pcb1_place.py --push`:那会重摆全部 301 个元件,
|
||
把已经布好的 3116 段铜全部作废。整板重布是 PROGRESS 里单列的下一步,不该由这一轮顺手引爆。
|
||
|
||
拆铜的判据只有一条:**这个网络在板上已经一个焊盘都没有了**(旧风扇拓扑留下的孤儿),
|
||
外加 FAN_PWM —— 它的两个焊盘都还在,但 R733 从 (98,80.5) 挪到了 (108,74),旧铜接不上了。
|
||
"""
|
||
import io
|
||
import json
|
||
import os
|
||
import sys
|
||
|
||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||
sys.path.insert(0, HERE)
|
||
from eda import run
|
||
import pcb1_place as PL
|
||
|
||
PCB = '7e9415a16a909c51'
|
||
MIL = 39.3701
|
||
|
||
FAN = ['Q6', 'Q7', 'Q8', 'Q9', 'Q10', 'DZ3', 'D2', 'C738',
|
||
'R733', 'R734', 'R746', 'R747', 'R748', 'R749', 'R750', 'R751',
|
||
'R752', 'R753', 'R754', 'R755', 'R756', 'R757', 'J26', 'J27']
|
||
|
||
# 死网络(板上已无焊盘)+ FAN_PWM(焊盘在、但 R733 挪了位,旧铜作废)
|
||
RIP = ['$17N148', '$17N151', '$17N154', 'FAN_TACH', 'FAN_PWM']
|
||
|
||
|
||
def call(js, timeout=300):
|
||
r = run(js, timeout=timeout)
|
||
if not r.get('success'):
|
||
raise RuntimeError(json.dumps(r, ensure_ascii=False)[:900])
|
||
return r['result']
|
||
|
||
|
||
def main():
|
||
push = '--push' in sys.argv
|
||
plan = [[d, round(PL.POS[d][0] * MIL, 2), round(PL.POS[d][1] * MIL, 2), PL.POS[d][2]] for d in FAN]
|
||
print(u'风扇块 %d 个元件;拆废铜网络 %s' % (len(plan), ', '.join(RIP)))
|
||
for d, x, y, r in plan:
|
||
print(u' %-5s (%8.2f, %8.2f) rot %d' % (d, x, y, r))
|
||
if not push:
|
||
print(u'加 --push 执行')
|
||
return
|
||
|
||
call("""
|
||
await eda.dmt_EditorControl.openDocument('%s'); await new Promise(r=>setTimeout(r,2000));
|
||
return 1;""" % PCB)
|
||
|
||
n = call("""
|
||
const P = %s;
|
||
const map = {};
|
||
for (const c of await eda.pcb_PrimitiveComponent.getAll()) map[c.getState_Designator()] = c;
|
||
let n = 0;
|
||
for (const [d, x, y, rot] of P) {
|
||
const c = map[d]; if (!c) throw new Error('板上没有 ' + d);
|
||
await eda.pcb_PrimitiveComponent.modify(c.getState_PrimitiveId(), {layer: 1});
|
||
await eda.pcb_PrimitiveComponent.modify(c.getState_PrimitiveId(), {x, y, rotation: rot});
|
||
n++;
|
||
}
|
||
return n;
|
||
""" % json.dumps(plan))
|
||
print(u'已摆 %d 个元件' % n)
|
||
|
||
# 拆铜:循环删到剩 0(skill §9x:一次 getAll 逐条 delete 删不干净)
|
||
rip = call("""
|
||
const NETS = %s;
|
||
let dl = 0, dv = 0;
|
||
for (let pass = 0; pass < 4; pass++) {
|
||
let left = 0;
|
||
for (const l of await eda.pcb_PrimitiveLine.getAll())
|
||
if (NETS.includes(l.getState_Net())) { await eda.pcb_PrimitiveLine.delete(l.getState_PrimitiveId()); dl++; }
|
||
for (const v of await eda.pcb_PrimitiveVia.getAll())
|
||
if (NETS.includes(v.getState_Net())) { await eda.pcb_PrimitiveVia.delete(v.getState_PrimitiveId()); dv++; }
|
||
for (const l of await eda.pcb_PrimitiveLine.getAll()) if (NETS.includes(l.getState_Net())) left++;
|
||
for (const v of await eda.pcb_PrimitiveVia.getAll()) if (NETS.includes(v.getState_Net())) left++;
|
||
if (!left) return {dl, dv, left: 0, pass};
|
||
}
|
||
let left = 0;
|
||
for (const l of await eda.pcb_PrimitiveLine.getAll()) if (NETS.includes(l.getState_Net())) left++;
|
||
for (const v of await eda.pcb_PrimitiveVia.getAll()) if (NETS.includes(v.getState_Net())) left++;
|
||
return {dl, dv, left};
|
||
""" % json.dumps(RIP))
|
||
print(u'拆铜:导线 %d 段 / 过孔 %d 个,剩余 %d' % (rip['dl'], rip['dv'], rip['left']))
|
||
if rip['left']:
|
||
raise SystemExit(u'废铜没删干净')
|
||
|
||
got = call("""
|
||
const P = %s;
|
||
const map = {};
|
||
for (const c of await eda.pcb_PrimitiveComponent.getAll()) map[c.getState_Designator()] = c;
|
||
const out = [];
|
||
for (const [d, x, y, rot] of P) {
|
||
const c = map[d];
|
||
out.push([d, Math.round(c.getState_X()*100)/100, Math.round(c.getState_Y()*100)/100,
|
||
c.getState_Rotation(), c.getState_Layer()]);
|
||
}
|
||
await eda.pcb_Document.save();
|
||
return out;
|
||
""" % json.dumps(plan))
|
||
bad = []
|
||
for (d, x, y, r), (gd, gx, gy, gr, gl) in zip(plan, got):
|
||
if abs(gx - x) > 0.02 or abs(gy - y) > 0.02 or gr != r or gl != 1:
|
||
bad.append(u'%s 期望 (%.2f,%.2f) rot %d L1,实测 (%.2f,%.2f) rot %s L%s' % (d, x, y, r, gx, gy, gr, gl))
|
||
if bad:
|
||
raise SystemExit(u'回读对不上:\n ' + u'\n '.join(bad))
|
||
print(u'回读 %d 个元件,位置/角度/层逐个一致;已存盘' % len(got))
|
||
|
||
|
||
main()
|