diff options
-rw-r--r-- | src/ee/kicad/pcb/__init__.py | 8 | ||||
-rw-r--r-- | src/ee/tools/kicad_make_pos.py | 65 | ||||
-rw-r--r-- | test/kicad_pcb/parser-1-all.pos | 4 |
3 files changed, 66 insertions, 11 deletions
diff --git a/src/ee/kicad/pcb/__init__.py b/src/ee/kicad/pcb/__init__.py index 679c5ea..79987e6 100644 --- a/src/ee/kicad/pcb/__init__.py +++ b/src/ee/kicad/pcb/__init__.py @@ -26,7 +26,8 @@ class Module(object): for k, v in kwargs.items(): setattr(self, k, v) - self.fp_texts = self.fp_texts or [] + self.fp_texts = self.fp_texts if hasattr(self, "fp_texts") else [] + self.attr = self.attr if hasattr(self, "attr") else [] def filter_fp_text(self, kind = None): filters = [] @@ -36,6 +37,9 @@ class Module(object): return (fp_text for fp_text in self.fp_texts if run_filters(filters, fp_text)) + def has_attr(self, name): + return next((True for a in self.attr if a == name), False) + @auto_str class Pad(object): def __init__(self, **kwargs): @@ -145,6 +149,8 @@ def parse(path): args[token] = _parse_text(rparen = True) elif token == "at": args[token] = _parse_at() + elif token == "attr": + args[token] = [_parse_text(rparen = True)] elif token == "pad": pads.append(_parse_pad()) elif token == "fp_text": diff --git a/src/ee/tools/kicad_make_pos.py b/src/ee/tools/kicad_make_pos.py index cd381a5..0b5e9b4 100644 --- a/src/ee/tools/kicad_make_pos.py +++ b/src/ee/tools/kicad_make_pos.py @@ -1,6 +1,7 @@ import sys import argparse import csv +import datetime as dt from . import mk_parents from ..kicad import pcb, parse_ref from .._utils import run_filters @@ -17,13 +18,24 @@ parser.add_argument("--out", metavar="FILE", help="The output file") +parser.add_argument("--format", + metavar="FORMAT", + default="plain", + help="The format of the output file. Either 'plain' or 'kicad'") + args = parser.parse_args() pcb = pcb.parse(args.pcb) +fmt = args.format + +if fmt != "plain" and fmt != "kicad": + print("Bad format: {}".format(fmt), file=sys.stderr) + def run(stream): rows = [] - for m in pcb.modules: + modules = [m for m in pcb.modules if m.has_attr("smd")] + for m in modules: row = {} ref_fp_text = next(m.filter_fp_text(kind = "reference"), None) row["ref"] = ref= ref_fp_text and ref_fp_text.value @@ -31,7 +43,9 @@ def run(stream): value_fp_text = next(m.filter_fp_text(kind = "value"), None) row["value"] = value_fp_text and value_fp_text.value (row["library"], row["footprint"]) = m.footprint.split(":") - (row["x"], row["y"], row["rot"]) = m.at + (x, y, rotation) = m.at + # The Y axis is inverted for some unknown reason. + (row["x"], row["y"], row["rotation"]) = (float(x), -float(y), float(rotation)) if m.layer == "F.Cu": row["side"] = "top" elif m.layer == "B.Cu": @@ -40,13 +54,48 @@ def run(stream): row["side"] = None rows.append(row) - rows = sorted(rows, key=lambda row: row["r"]) + if fmt == "plain": + rows = sorted(rows, key=lambda row: row["r"]) + + out = csv.writer(stream) + out.writerow(["ref", "value", "library", "footprint", "x", "y", "rotation", "side"]) + for row in rows: + del row["r"] + out.writerow(row.values()) + elif fmt == "kicad": + lines = [] + for row in rows: + row["x"] = "{:>9.4f}".format(row["x"]) + row["y"] = "{:>9.4f}".format(row["y"]) + row["rotation"] = "{:>9.4f}".format(float(row["rotation"])) + + def find_max(name, mn): + return str(max(mn, max((len(str(row[name])) for row in rows)) + 1)) + ref_sz = find_max("ref", 8) + value_sz = find_max("value", 8) + footprint_sz = find_max("footprint", 16) + x_sz = find_max("x", 10) + y_sz = find_max("y", 10) + rotation_sz = find_max("rotation", 0) + fmts = "{ref:" + ref_sz + "}" +\ + " {value:" + value_sz + "}" +\ + " {footprint:" + footprint_sz + "}" +\ + " {x} {y} {rotation}" +\ + " {side}" + #print("fmts={}".format(fmts)) + for row in rows: + #print("row={}".format(row)) + s = fmts.format(**row) + lines.append(s) - out = csv.writer(stream) - out.writerow(["ref", "value", "library", "footprint", "x", "y", "rotation", "side"]) - for row in rows: - del row["r"] - out.writerow(row.values()) + print("### Module positions - created on {:%Y-%m-%d %H:%M:%S} ###".format(dt.datetime.now()), file=stream) + print("### Printed by ee tools", file=stream) + print("## Unit = mm, Angle = deg.", file=stream) + print("## Side : All", file=stream) + print("# Ref Val Package PosX PosY Rot Side", file=stream) + for line in lines: + print(line, file=stream) + print("## End", file=stream) if args.out: mk_parents(args.out) diff --git a/test/kicad_pcb/parser-1-all.pos b/test/kicad_pcb/parser-1-all.pos index 0a41e18..a6bd81f 100644 --- a/test/kicad_pcb/parser-1-all.pos +++ b/test/kicad_pcb/parser-1-all.pos @@ -1,9 +1,9 @@ -### Module positions - created on Fri Dec 8 21:36:06 2017 ### +### Module positions - created on Tue Dec 12 15:32:09 2017 ### ### Printed by Pcbnew version kicad 4.0.7+dfsg1-1 ## Unit = mm, Angle = deg. ## Side : All # Ref Val Package PosX PosY Rot Side -C1 C C_0603 149.8600 -106.6800 180.1000 top +C1 C C_0603 149.8600 -106.6800 179.9000 bottom R1 R R_0603 146.0500 -104.1400 0.0000 top R2 R R_0603 146.0500 -106.6800 180.0000 top ## End |