R2 焊接:丝印临时换成器件值 + 摆放优化 + 1:1 器件值打印稿
2026-09-25 为焊接底板与旧版刀片(BLADE-PCB 3b9c4e39c8d164db): - silk_value.py:隐藏位号、在原位建自由丝印写器件值(Value,没有就用型号), --restore 按 _silk_value_restore.json 删字并恢复位号。⚠ 再出 Gerber / 下单前必须先 --restore。 - silk_value_plan.py:器件值摆放优化(不压焊盘 / 不重叠 / 不出框 / 避开开槽与金手指区; 软代价:压过孔、压他件本体、离本件远、缩字号)。EDA 默认字体实测字宽 ≈0.78×字高。 - print_value.py:两块板背面镜像 1:1 画在同一张 A4,红框标 1 脚; print/print_1to1.ps1 按 210×297 mm 直送打印机(不经 PDF 阅读器缩放)。 - 数据:_silk_value_geom/_extra(板上读回几何)、_dump/_plan(排位结果)。 Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
@@ -0,0 +1,116 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
u"""焊接用:把底板 / 旧版刀片的丝印从「位号」临时换成「器件值」,焊完再换回来。
|
||||
|
||||
/c/Python314/python .claude/r2/silk_value.py --push # 隐藏位号 + 在原位建器件值文字,存还原表
|
||||
/c/Python314/python .claude/r2/silk_value.py --restore # 删掉建的文字 + 位号恢复可见
|
||||
|
||||
- 器件值 = 元件 `Value` 属性(阻容感);没有就用 `Device`(型号)去掉 `_Cxxxx` 后缀,个别手工缩写(LABEL_FIX)。
|
||||
- 位号没有「换成别的属性显示」的接口(PCB 属性不能新建),所以做法是:
|
||||
位号 `valueVisible=false` + 同层同位置同字号建一条**自由丝印** `pcb_PrimitiveString`。
|
||||
- 还原表 `_silk_value_restore.json`:建出来的文字 id + 原本可见的位号 id。⚠ 再下单打板前必须 --restore。
|
||||
"""
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
sys.stdout.reconfigure(encoding='utf-8')
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, os.path.dirname(HERE))
|
||||
from eda import run # noqa: E402
|
||||
|
||||
BOARDS = {'BASE': '7b9524b6aaf6f235', 'BLADE': '3b9c4e39c8d164db'} # 刀片用旧版 BLADE-PCB
|
||||
RESTORE = os.path.join(HERE, '_silk_value_restore.json')
|
||||
LABEL_FIX = {
|
||||
'6.3TPV2200M10X10.5 SMD': '2200uF 6.3V',
|
||||
'BM24-50DS/2-0.35V(51) HRS-PIN': 'BM24-50DS',
|
||||
'PCA9555PW,112': 'PCA9555PW',
|
||||
'NCP18XH103F03RB': 'NTC 10k',
|
||||
'MI8-KEY-PAD D1.5': 'KEY',
|
||||
'2.54mm 1*5P 直排针': '1x5P 2.54',
|
||||
}
|
||||
|
||||
|
||||
def label(value, device):
|
||||
if value:
|
||||
return value.replace(u'kΩ', 'k').replace(u'MΩ', 'M')
|
||||
d = device or ''
|
||||
if d in LABEL_FIX:
|
||||
return LABEL_FIX[d]
|
||||
return re.sub(r'_C\d+$', '', d)
|
||||
|
||||
|
||||
READ = u"""
|
||||
await eda.dmt_EditorControl.openDocument('%s');
|
||||
await new Promise(r=>setTimeout(r,3000));
|
||||
const C = await eda.pcb_PrimitiveComponent.getAll()||[];
|
||||
const cv = {}; C.forEach(c=>{const o=c.otherProperty||{}; cv[c.primitiveId]=[o.Value||null, o.Device||null];});
|
||||
const A = (await eda.pcb_PrimitiveAttribute.getAll()||[]).filter(a=>a.key==='Designator').map(a=>({id:a.primitiveId, pid:a.parentPrimitiveId, ref:a.value, layer:a.layer, x:a.x, y:a.y, rot:a.rotation, fs:a.fontSize, lw:a.lineWidth, align:a.alignMode, vis:a.valueVisible, mirror:a.mirror, font:a.fontFamily, reverse:a.reverse, expansion:a.expansion}));
|
||||
return {cv, attrs:A};
|
||||
"""
|
||||
|
||||
PUSH = u"""
|
||||
await eda.dmt_EditorControl.openDocument('%s');
|
||||
await new Promise(r=>setTimeout(r,3000));
|
||||
const J = %s;
|
||||
const made = [], hid = [], err = [];
|
||||
for (const t of J) {
|
||||
try {
|
||||
const s = await eda.pcb_PrimitiveString.create(t.layer, t.x, t.y, t.text, t.font, t.fs, t.lw, t.align, t.rot, t.reverse, t.expansion, t.mirror, false);
|
||||
if (s) made.push([t.ref, s.primitiveId]); else err.push(['create', t.ref]);
|
||||
await eda.pcb_PrimitiveAttribute.modify(t.id, {valueVisible: false});
|
||||
hid.push(t.id);
|
||||
} catch (e) { err.push([t.ref, String(e)]); }
|
||||
}
|
||||
await eda.pcb_Document.save();
|
||||
return {made, hid, err};
|
||||
"""
|
||||
|
||||
UNDO = u"""
|
||||
await eda.dmt_EditorControl.openDocument('%s');
|
||||
await new Promise(r=>setTimeout(r,3000));
|
||||
const R = %s;
|
||||
const ok = await eda.pcb_PrimitiveString.delete(R.made.map(m=>m[1]));
|
||||
let n = 0; for (const id of R.hid) { try { await eda.pcb_PrimitiveAttribute.modify(id, {valueVisible: true}); n++; } catch (e) {} }
|
||||
await eda.pcb_Document.save();
|
||||
return {deleted: ok, shown: n};
|
||||
"""
|
||||
|
||||
|
||||
def push():
|
||||
if os.path.exists(RESTORE):
|
||||
sys.exit(u'已有还原表 %s —— 先 --restore 再重推' % RESTORE)
|
||||
rec = {}
|
||||
for name, u in BOARDS.items():
|
||||
d = run(READ % u, timeout=300)['result']
|
||||
todo = []
|
||||
for a in d['attrs']:
|
||||
if not a['vis']:
|
||||
continue # 原本就隐藏的位号不动
|
||||
v, dev = d['cv'].get(a['pid'], [None, None])
|
||||
a['text'] = label(v, dev)
|
||||
todo.append(a)
|
||||
r = run(PUSH % (u, json.dumps(todo, ensure_ascii=False)), timeout=900)
|
||||
res = r.get('result')
|
||||
assert res, json.dumps(r, ensure_ascii=False)[:600]
|
||||
rec[name] = {'pcb': u, 'made': res['made'], 'hid': res['hid']}
|
||||
io.open(RESTORE, 'w', encoding='utf-8').write(json.dumps(rec, ensure_ascii=False, indent=1))
|
||||
print(u'%s:建 %d 条器件值、藏 %d 个位号,错误 %s' % (name, len(res['made']), len(res['hid']), res['err']))
|
||||
|
||||
|
||||
def restore():
|
||||
rec = json.load(io.open(RESTORE, encoding='utf-8'))
|
||||
for name, R in rec.items():
|
||||
r = run(UNDO % (R['pcb'], json.dumps(R, ensure_ascii=False)), timeout=900)
|
||||
print(name, r.get('result') or r)
|
||||
os.rename(RESTORE, RESTORE + '.done')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if '--push' in sys.argv:
|
||||
push()
|
||||
elif '--restore' in sys.argv:
|
||||
restore()
|
||||
else:
|
||||
print(__doc__)
|
||||
在新工单中引用
屏蔽一个用户