Files
Ofensteuerung/pcb/fab.py
T

52 lines
3.2 KiB
Python

#!/usr/bin/env python3
"""Fertigungsdaten: Gerber+Bohrdaten (zip), Stückliste mit Inventar-Fächern, Schaltplan-PDF, 1:1-Druck, Doku-Bilder."""
import os, sys, csv, shutil, subprocess, zipfile, collections
HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, HERE)
from design import PARTS, PROJECT
FAB = os.path.join(HERE, 'fab'); G = os.path.join(FAB, 'gerber')
shutil.rmtree(G, ignore_errors=True); os.makedirs(G)
pcb = os.path.join(HERE, PROJECT + '.kicad_pcb'); sch = os.path.join(HERE, PROJECT + '.kicad_sch')
def run(*a):
subprocess.run(a, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
run('kicad-cli', 'pcb', 'export', 'gerbers', '-o', G + '/', '--layers',
'F.Cu,B.Cu,F.Silkscreen,B.Silkscreen,F.Mask,B.Mask,Edge.Cuts', '--subtract-soldermask', pcb)
run('kicad-cli', 'pcb', 'export', 'drill', '-o', G + '/', '--format', 'excellon', '--excellon-separate-th', pcb)
zp = os.path.join(FAB, PROJECT + '_gerber.zip')
with zipfile.ZipFile(zp, 'w', zipfile.ZIP_DEFLATED) as z:
for f in sorted(os.listdir(G)):
z.write(os.path.join(G, f), f)
run('kicad-cli', 'sch', 'export', 'pdf', '-o', os.path.join(FAB, PROJECT + '_schaltplan.pdf'), sch)
run('kicad-cli', 'pcb', 'export', 'pdf', '--mode-single', '-l', 'F.Silkscreen,F.Fab,Edge.Cuts,F.Courtyard',
'--include-border-title', '-o', os.path.join(FAB, PROJECT + '_1zu1_druck.pdf'), pcb)
# ---------- Stückliste ----------
INV = { # (Wert, Footprint-Teil) -> Inventar-Fach (Parts_Inventory.xlsx)
'100': 'E-01-3', '220': 'E-05-3', '330': 'E-07-3', '470': 'E-09-3', '1k': 'E-01-4', '2k2': 'E-05-4',
'4k7': 'E-09-4', '10k': 'E-01-5', '100n': 'C-07-1', '10u': 'C-10-2 / D-04-3', '470u/10V': 'C-04-3',
'1000u/10V': 'C-05-3', 'BC546B': 'B-01-4', '1N4007': 'B-02-1', 'LED grün': 'B-07-5', 'LED rot': 'B-08-5',
'Pull-up 5V': 'A-07-2 + Jumper A-11-3', 'ERWEITERUNG': 'A-07-2',
'SRD-05VDC-SL-C': 'A-07-1 prüfen (sonst kaufen)', 'T 2A': 'Clips/Halter B-12-2, Sicherung B-11-2',
'WEMOS D1 mini': 'Buchsenleisten A-06-5 / A-07-3', 'ADS1115 Modul': 'Buchsenleiste A-06-5; Modul ggf. B-11-5',
'MAX6675 Modul': 'Buchsenleiste A-06-5; Modul ggf. B-11-5',
}
BUY = {'ZMCT103C': 'kaufen (Stromwandler 5A/5mA)', 'MAX6675 Modul': 'kaufen inkl. Thermoelement Typ K (Abgasfühler)',
'ADS1115 Modul': 'kaufen, falls kein Rest von der Umwälzpumpe', 'WEMOS D1 mini': 'vorhanden/kaufen'}
rows = collections.OrderedDict()
for p in PARTS:
if p.get('board') is False or p['ref'].startswith('H'):
continue
key = (p['val'], p['fp'].split(':')[-1])
rows.setdefault(key, []).append(p)
with open(os.path.join(FAB, PROJECT + '_bom.csv'), 'w', newline='') as f:
w = csv.writer(f, delimiter=';')
w.writerow(['Anzahl', 'Referenzen', 'Wert', 'Footprint', 'Inventar-Fach', 'Beschaffung / Hinweis'])
for (val, fp), ps in rows.items():
refs = ' '.join(sorted((q['ref'] for q in ps), key=lambda r: (r.rstrip('0123456789'), int(''.join(c for c in r if c.isdigit()) or 0))))
term = ps[0]['fp'].startswith('Connector_Phoenix')
inv = '' if term else INV.get(val, '')
hint = ps[0].get('mpn') or BUY.get(val, '')
w.writerow([len(ps), refs, val, fp, inv, hint])
print('fab ok:', sorted(os.listdir(FAB)))