# -*- 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__)