aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2018-07-17 12:23:58 +0200
committerTrygve Laugstøl <trygvis@inamo.no>2018-07-17 12:23:58 +0200
commita30b71772e7eb831e8d87759172a02e79f9673c4 (patch)
tree365d292e6ce73341055d888dd80f7e45b445beec
parentd72247b46519609fb0b373d34bcc5d5939d7b9c3 (diff)
downloadee-python-a30b71772e7eb831e8d87759172a02e79f9673c4.tar.gz
ee-python-a30b71772e7eb831e8d87759172a02e79f9673c4.tar.bz2
ee-python-a30b71772e7eb831e8d87759172a02e79f9673c4.tar.xz
ee-python-a30b71772e7eb831e8d87759172a02e79f9673c4.zip
wip. pcb.
-rw-r--r--demo/doit/demo/demo.pro33
-rw-r--r--src/ee/fact/__init__.py50
-rw-r--r--src/ee/kicad/doit.py97
-rw-r--r--src/ee/kicad/pcb/__init__.py40
-rw-r--r--test/doit/schematics/schematic-1.kicad_pcb280
-rw-r--r--test/doit/schematics/schematic-1.pro7
-rw-r--r--test/doit/schematics/schematic-1.sch22
-rw-r--r--test/doit/test_doit.py14
8 files changed, 426 insertions, 117 deletions
diff --git a/demo/doit/demo/demo.pro b/demo/doit/demo/demo.pro
deleted file mode 100644
index 152769c..0000000
--- a/demo/doit/demo/demo.pro
+++ /dev/null
@@ -1,33 +0,0 @@
-update=22/05/2015 07:44:53
-version=1
-last_client=kicad
-[general]
-version=1
-RootSch=
-BoardNm=
-[pcbnew]
-version=1
-LastNetListRead=
-UseCmpFile=1
-PadDrill=0.600000000000
-PadDrillOvalY=0.600000000000
-PadSizeH=1.500000000000
-PadSizeV=1.500000000000
-PcbTextSizeV=1.500000000000
-PcbTextSizeH=1.500000000000
-PcbTextThickness=0.300000000000
-ModuleTextSizeV=1.000000000000
-ModuleTextSizeH=1.000000000000
-ModuleTextSizeThickness=0.150000000000
-SolderMaskClearance=0.000000000000
-SolderMaskMinWidth=0.000000000000
-DrawSegmentWidth=0.200000000000
-BoardOutlineThickness=0.100000000000
-ModuleOutlineThickness=0.150000000000
-[cvpcb]
-version=1
-NetIExt=net
-[eeschema]
-version=1
-LibDir=
-[eeschema/libraries]
diff --git a/src/ee/fact/__init__.py b/src/ee/fact/__init__.py
index 959e755..1bdef0d 100644
--- a/src/ee/fact/__init__.py
+++ b/src/ee/fact/__init__.py
@@ -1,12 +1,13 @@
-from typing import Optional, Mapping, List
import configparser
+import logging
import os
-from pathlib import Path
from functools import total_ordering
-import logging
+from pathlib import Path
+from typing import MutableMapping, Optional, Mapping, List
logger = logging.getLogger(__name__)
+
@total_ordering
class ObjectType(object):
def __init__(self, name: str):
@@ -14,28 +15,20 @@ class ObjectType(object):
self._fields = []
self._objects = {}
- def __eq__(self, o: object) -> bool:
- other = o # type ObjectType
+ def __eq__(self, o) -> bool:
+ other = o # type: ObjectType
return isinstance(o, ObjectType) and self._name == other._name
def __lt__(self, o: object) -> bool:
if not isinstance(o, ObjectType):
return True
- other = o # type ObjectType
- return (self._name) < (self._name)
+ other = o # type: ObjectType
+ return self._name < other._name
def __hash__(self) -> int:
return self._name.__hash__()
- def by_key(self, key: str) -> "Object":
- try:
- return self._objects[key]
- except ValueError:
- o = Object(self, key, {}, {})
- self._objects[key] = o
- return o
-
@property
def name(self):
return self._name
@@ -54,6 +47,7 @@ class ObjectType(object):
self._fields.append(field)
return len(self._fields) - 1
+
class Object(object):
def __init__(self, ds: "DataSet", ot: ObjectType, key: str):
self._ds = ds
@@ -81,13 +75,14 @@ class Object(object):
def get(self, key: str) -> Optional[str]:
idx = self._ot.index_of(key)
- return self._data[idx]
+ return self._data[idx] if idx < len(self._data) else None
+
class DataSet(object):
def __init__(self, name):
self._name = name
self._object_types = {}
- self._objects_by_type = {} # type: Mapping[str, Mapping[str, Object]]
+ self._objects_by_type = {} # type: MutableMapping[str, Mapping[str, Object]]
self._frozen = False
self._changed = False
@@ -146,6 +141,7 @@ class DataSet(object):
return ds
+
class DataSetManager(object):
def __init__(self, basedir: Path):
self._basedir = Path(basedir)
@@ -181,7 +177,7 @@ class DataSetManager(object):
ini = self._load_ini(o_path)
o = ds.get_object(ot, key)
for k, v in ini.items("values"):
- o.set(k, v)
+ o.set(k, v)
if freeze:
ds.freeze()
@@ -212,11 +208,13 @@ class DataSetManager(object):
ini.add_section("values")
for k in ot.fields:
v = o.get(k)
- ini.set("values", k, v)
+ if v:
+ ini.set("values", k, str(v))
self._store_ini(ini, ot_dir / "{}.ini".format(key))
- def _blank_ini(self):
- return configparser.ConfigParser(interpolation = None)
+ @staticmethod
+ def _blank_ini():
+ return configparser.ConfigParser(interpolation=None)
def _load_ini(self, path: Path):
ini = self._blank_ini()
@@ -224,10 +222,12 @@ class DataSetManager(object):
raise IOError("Could not load ini file: {}".format(path))
return ini
- def _store_ini(self, ini, path):
+ @staticmethod
+ def _store_ini(ini, path):
with open(path, "w") as f:
ini.write(f)
+
class LazyDataSet(object):
def __init__(self, dsm: DataSetManager, name, inputs):
self._dsm = dsm
@@ -235,7 +235,7 @@ class LazyDataSet(object):
self._inputs = inputs
def __enter__(self):
-# logger.info("enter: name={}, inputs={}".format(self._name, self._inputs))
+ # logger.info("enter: name={}, inputs={}".format(self._name, self._inputs))
ds = DataSet(self._name)
for name in self._inputs:
ds = ds.merge(self._dsm.load(name, freeze=True))
@@ -243,7 +243,7 @@ class LazyDataSet(object):
return self._ds
def __exit__(self, *args):
-# logger.info("exit: name={}, inputs={}".format(self._name, self._inputs))
-# logger.info("ds.size={}".format(len(self._ds.items())))
+ # logger.info("exit: name={}, inputs={}".format(self._name, self._inputs))
+ # logger.info("ds.size={}".format(len(self._ds.items())))
self._dsm.store(self._ds)
return False
diff --git a/src/ee/kicad/doit.py b/src/ee/kicad/doit.py
index 10de885..fcbcaef 100644
--- a/src/ee/kicad/doit.py
+++ b/src/ee/kicad/doit.py
@@ -1,13 +1,14 @@
+import logging
import os.path
-from doit.exceptions import TaskFailed
-from doit.tools import check_timestamp_unchanged
-from configclass import Config
from typing import List
+
+from configclass import Config
+
from ee.fact import DataSetManager
-import logging
logger = logging.getLogger(__name__)
+
class KicadDoitTasks(object):
config = Config({
"sch": None,
@@ -15,7 +16,7 @@ class KicadDoitTasks(object):
"gerber_dir": None,
"gerber_zip": None,
"data_set_dir": None,
- })
+ })
def __init__(self, *args, **kwargs):
self.config = self.config.make(kwargs)
@@ -24,7 +25,6 @@ class KicadDoitTasks(object):
logger.info("_task: args={}, kwars={}".format(args, kwargs))
def tasks(self, *args, **kwargs):
- import ee.kicad
kicad_pcb = self.config["kicad_pcb"]
sch = self.config["sch"]
tasks = []
@@ -32,24 +32,32 @@ class KicadDoitTasks(object):
dsm = DataSetManager(self.config["data_set_dir"])
gerber_dir = self.config["gerber_dir"]
- if gerber_dir:
- tasks.append(task_kicad_gerber())
+ gerber_zip = self.config["gerber_zip"]
+ if kicad_pcb and gerber_dir:
+ tasks.append(task_kicad_gerber(kicad_pcb, gerber_dir, gerber_zip))
- sch_ds = task_kicad_sch_to_data_set(dsm, sch, \
- in_data_sets=[], \
- out_data_set="kicad-sch-data-set") \
- if sch else None
+ sch_ds = task_kicad_sch_to_data_set(dsm, sch,
+ in_data_sets=[],
+ out_data_set="kicad-sch-data-set") \
+ if sch else None
- component_ds = task_kicad_create_component_data_set(dsm, \
- in_data_sets=sch_ds["targets"], \
- out_data_set="raw-component") \
- if sch_ds else None
+ component_ds = task_kicad_create_component_data_set(dsm,
+ in_data_sets=sch_ds["targets"],
+ out_data_set="raw-component") \
+ if sch_ds else None
- return (t for t in [sch_ds, component_ds] if t is not None)
+ pcb_ds = task_kicad_pcb_to_data_set(dsm, kicad_pcb, in_data_sets=[], out_data_set="kicad-pcb") \
+ if kicad_pcb else None
-def task_kicad_gerber(name="kicad-gerber"):
- gerber_zip = self.config["gerber_zip"] or "{}.zip".format(gerber_dir)
- #logger.info("gerber_zip={}".format(gerber_zip))
+ tasks = [sch_ds, component_ds, pcb_ds]
+ return (t for t in tasks if t)
+
+
+def task_kicad_gerber(kicad_pcb: str, gerber_dir: str, gerber_zip: str, name="kicad-gerber"):
+ import ee.kicad
+
+ gerber_zip = len(gerber_zip) or "{}.zip".format(gerber_dir)
+ # logger.info("gerber_zip={}".format(gerber_zip))
eg = next((p for p in (os.path.join(p, "export_gerber.py") for p in ee.kicad.__path__) if os.path.isfile(p)), None)
if not eg:
@@ -63,6 +71,7 @@ def task_kicad_gerber(name="kicad-gerber"):
"--output-directory", gerber_dir,
"--protel-extensions",
])
+
def make_zip():
import zipfile
from pathlib import Path
@@ -79,12 +88,12 @@ def task_kicad_gerber(name="kicad-gerber"):
"file_dep": [kicad_pcb],
}
-def task_kicad_sch_to_data_set(dsm: DataSetManager, sch, in_data_sets: List[str], out_data_set, name="kicad-sch-to-data-set"):
+
+def task_kicad_sch_to_data_set(dsm: DataSetManager, sch, in_data_sets: List[str], out_data_set,
+ name="kicad-sch-to-data-set"):
def action():
import ee.kicad
- from ee.kicad.model import Component, ComponentField
- import csv
- import configparser
+ from ee.kicad.model import ComponentField
with dsm.create_rw(out_data_set, inputs=in_data_sets) as ds:
schematics = ee.kicad.read_schematics(sch)
@@ -109,10 +118,46 @@ def task_kicad_sch_to_data_set(dsm: DataSetManager, sch, in_data_sets: List[str]
"targets": [dsm.metafile_for_ds(out_data_set)],
}
-def task_kicad_create_component_data_set(dsm: DataSetManager, in_data_sets: List[str], out_data_set, name="kicad-create-component-data-set"):
+
+def task_kicad_pcb_to_data_set(dsm: DataSetManager, pcb_path, in_data_sets: List[str], out_data_set,
+ name="kicad-pcb-to-data-set"):
+ def action():
+ import ee.kicad.pcb
+ from ee.kicad.pcb import FpText
+
+ with dsm.create_rw(out_data_set, inputs=in_data_sets) as ds:
+ # [ds.delete(o) for o in ds.items(object_type="kicad-pcb-component")]
+
+ pcb: ee.kicad.pcb.KicadPcb = ee.kicad.pcb.parse(pcb_path)
+ for _m in pcb.modules:
+ m: ee.kicad.pcb.Module = _m
+ logger.info("attrs")
+ for s in dir(m):
+ logger.info(s)
+
+ o = ds.get_object("kicad-pcb-component", m.tstamp)
+
+ ref_text: FpText = next((t for t in m.fp_texts if t.kind == "reference"), None)
+ o.set("reference", ref_text.value)
+
+ x, y, rot = m.at
+ o.set("at-x", x)
+ o.set("at-y", y)
+ o.set("at-rot", rot)
+ o.set("layer", m.layer)
+
+ return {
+ "name": name,
+ "file_dep": [pcb_path] + [dsm.metafile_for_ds(ds) for ds in in_data_sets],
+ "actions": [action],
+ "targets": [dsm.metafile_for_ds(out_data_set)],
+ }
+
+
+def task_kicad_create_component_data_set(dsm: DataSetManager, in_data_sets: List[str], out_data_set,
+ name="kicad-create-component-data-set"):
def action(*args, **kwargs):
logger.info("args={}, kwargs={}".format(args, kwargs))
- import ee.fact as fact
with dsm.create_rw(out_data_set, inputs=in_data_sets) as ds:
items = ds.items()
diff --git a/src/ee/kicad/pcb/__init__.py b/src/ee/kicad/pcb/__init__.py
index 79987e6..25689ef 100644
--- a/src/ee/kicad/pcb/__init__.py
+++ b/src/ee/kicad/pcb/__init__.py
@@ -49,18 +49,21 @@ class Pad(object):
@auto_str
class FpText(object):
def __init__(self, **kwargs):
+ self.kind = None # type: str
+ self.value = None # type: str
for k, v in kwargs.items():
setattr(self, k, v)
-def parse(path):
+
+def parse(path) -> KicadPcb:
count = 0
p = sexpr.parse(path)
#p = sexpr.logging_parser(p)
- (event, token) = next(p)
- assert event == sexpr.EVENT_LPAREN
+ (e, t) = next(p)
+ assert e == sexpr.EVENT_LPAREN
- (event, token) = next(p)
- assert event == sexpr.EVENT_TEXT and token == "kicad_pcb"
+ (e, t) = next(p)
+ assert e == sexpr.EVENT_TEXT and t == "kicad_pcb"
idx = 0
def _consume():
@@ -134,10 +137,14 @@ def parse(path):
pads = []
fp_texts = []
- args = {}
- args["footprint"] = _parse_text()
- args["pads"] = pads
- args["fp_texts"] = fp_texts
+ args = {
+ "footprint": _parse_text(),
+ "pads": pads,
+ "fp_texts": fp_texts,
+ "layer": None,
+ "tedit": None,
+ "tstamp": None,
+ }
(event, token) = next(p)
while event == sexpr.EVENT_TEXT:
@@ -145,12 +152,12 @@ def parse(path):
while event == sexpr.EVENT_LPAREN:
(event, token) = next(p)
- if token == "layer":
- args[token] = _parse_text(rparen = True)
+ if token in ["layer", "tedit", "tstamp"]:
+ args[token] = _parse_text(rparen=True)
elif token == "at":
args[token] = _parse_at()
elif token == "attr":
- args[token] = [_parse_text(rparen = True)]
+ args[token] = [_parse_text(rparen=True)]
elif token == "pad":
pads.append(_parse_pad())
elif token == "fp_text":
@@ -163,8 +170,9 @@ def parse(path):
def _parse_pad():
texts = []
- args = {}
- args["footprint"] = _parse_text()
+ args = {
+ "footprint": _parse_text()
+ }
(event, token) = next(p)
while event == sexpr.EVENT_TEXT:
@@ -182,7 +190,7 @@ def parse(path):
return Pad(**args)
- def _parse_fp_text():
+ def _parse_fp_text() -> FpText:
args = {
"kind": _parse_text(),
"value": _parse_text(),
@@ -202,7 +210,7 @@ def parse(path):
x = _parse_text(to=float)
y = _parse_text(to=float)
rot = _parse_text(to=float, optional = True, rparen = True)
- return (x, y, rot or 0)
+ return x, y, rot or 0
kicad_pcb = _parse_kicad_pcb()
assert next(p, None) == None
diff --git a/test/doit/schematics/schematic-1.kicad_pcb b/test/doit/schematics/schematic-1.kicad_pcb
new file mode 100644
index 0000000..861eed1
--- /dev/null
+++ b/test/doit/schematics/schematic-1.kicad_pcb
@@ -0,0 +1,280 @@
+(kicad_pcb (version 20171130) (host pcbnew 5.0.0-rc3+dfsg1-2)
+
+ (general
+ (thickness 1.6)
+ (drawings 0)
+ (tracks 13)
+ (zones 0)
+ (modules 3)
+ (nets 4)
+ )
+
+ (page A4)
+ (layers
+ (0 F.Cu signal)
+ (31 B.Cu signal)
+ (32 B.Adhes user)
+ (33 F.Adhes user)
+ (34 B.Paste user)
+ (35 F.Paste user)
+ (36 B.SilkS user)
+ (37 F.SilkS user)
+ (38 B.Mask user)
+ (39 F.Mask user)
+ (40 Dwgs.User user)
+ (41 Cmts.User user)
+ (42 Eco1.User user)
+ (43 Eco2.User user)
+ (44 Edge.Cuts user)
+ (45 Margin user)
+ (46 B.CrtYd user)
+ (47 F.CrtYd user)
+ (48 B.Fab user)
+ (49 F.Fab user)
+ )
+
+ (setup
+ (last_trace_width 0.25)
+ (trace_clearance 0.2)
+ (zone_clearance 0.508)
+ (zone_45_only no)
+ (trace_min 0.2)
+ (segment_width 0.2)
+ (edge_width 0.15)
+ (via_size 0.8)
+ (via_drill 0.4)
+ (via_min_size 0.4)
+ (via_min_drill 0.3)
+ (uvia_size 0.3)
+ (uvia_drill 0.1)
+ (uvias_allowed no)
+ (uvia_min_size 0.2)
+ (uvia_min_drill 0.1)
+ (pcb_text_width 0.3)
+ (pcb_text_size 1.5 1.5)
+ (mod_edge_width 0.15)
+ (mod_text_size 0.000001 0.000001)
+ (mod_text_width 0.15)
+ (pad_size 1.4 1.4)
+ (pad_drill 0.6)
+ (pad_to_mask_clearance 0.2)
+ (aux_axis_origin 0 0)
+ (visible_elements FFFFFF7F)
+ (pcbplotparams
+ (layerselection 0x010fc_ffffffff)
+ (usegerberextensions false)
+ (usegerberattributes false)
+ (usegerberadvancedattributes false)
+ (creategerberjobfile false)
+ (excludeedgelayer true)
+ (linewidth 0.100000)
+ (plotframeref false)
+ (viasonmask false)
+ (mode 1)
+ (useauxorigin false)
+ (hpglpennumber 1)
+ (hpglpenspeed 20)
+ (hpglpendiameter 15.000000)
+ (psnegative false)
+ (psa4output false)
+ (plotreference true)
+ (plotvalue true)
+ (plotinvisibletext false)
+ (padsonsilk false)
+ (subtractmaskfromsilk false)
+ (outputformat 1)
+ (mirror false)
+ (drillshape 1)
+ (scaleselection 1)
+ (outputdirectory ""))
+ )
+
+ (net 0 "")
+ (net 1 GND)
+ (net 2 "Net-(BT1-Pad1)")
+ (net 3 "Net-(C1-Pad1)")
+
+ (net_class Default "This is the default net class."
+ (clearance 0.2)
+ (trace_width 0.25)
+ (via_dia 0.8)
+ (via_drill 0.4)
+ (uvia_dia 0.3)
+ (uvia_drill 0.1)
+ (add_net GND)
+ (add_net "Net-(BT1-Pad1)")
+ (add_net "Net-(C1-Pad1)")
+ )
+
+ (module Battery:BatteryHolder_Keystone_103_1x20mm (layer F.Cu) (tedit 5787C32C) (tstamp 5B59DAE3)
+ (at 145.975001 79.779834)
+ (descr http://www.keyelco.com/product-pdf.cfm?p=719)
+ (tags "Keystone type 103 battery holder")
+ (path /5B431438)
+ (fp_text reference BT1 (at 0 -4.3) (layer F.SilkS)
+ (effects (font (size 1 1) (thickness 0.15)))
+ )
+ (fp_text value 9V (at 15 13) (layer F.Fab)
+ (effects (font (size 1 1) (thickness 0.15)))
+ )
+ (fp_text user + (at 2.75 0) (layer F.SilkS)
+ (effects (font (size 1.5 1.5) (thickness 0.15)))
+ )
+ (fp_text user %R (at 0 0) (layer F.Fab)
+ (effects (font (size 1 1) (thickness 0.15)))
+ )
+ (fp_arc (start 15.2 0) (end 4.01 3.6) (angle -162.5) (layer F.CrtYd) (width 0.05))
+ (fp_arc (start 15.2 0) (end 4.01 -3.6) (angle 162.5) (layer F.CrtYd) (width 0.05))
+ (fp_arc (start 3.5 3.8) (end 3.5 3.25) (angle 70) (layer F.CrtYd) (width 0.05))
+ (fp_arc (start 3.5 -3.8) (end 3.5 -3.25) (angle -70) (layer F.CrtYd) (width 0.05))
+ (fp_arc (start 15.2 0) (end 4.25 3.5) (angle -162.5) (layer F.SilkS) (width 0.12))
+ (fp_arc (start 3.5 3.8) (end 3.5 3) (angle 70) (layer F.SilkS) (width 0.12))
+ (fp_arc (start 15.2 0) (end 4.25 -3.5) (angle 162.5) (layer F.SilkS) (width 0.12))
+ (fp_arc (start 3.5 -3.8) (end 3.5 -3) (angle -70) (layer F.SilkS) (width 0.12))
+ (fp_arc (start 3.5 3.8) (end 3.5 2.9) (angle 70) (layer F.Fab) (width 0.1))
+ (fp_arc (start 15.2 0) (end 4.35 3.5) (angle -162.5) (layer F.Fab) (width 0.1))
+ (fp_arc (start 15.2 0) (end 4.35 -3.5) (angle 162.5) (layer F.Fab) (width 0.1))
+ (fp_arc (start 15.2 0) (end 5.2 1.3) (angle -180) (layer F.Fab) (width 0.1))
+ (fp_line (start -2.45 -3.25) (end 3.5 -3.25) (layer F.CrtYd) (width 0.05))
+ (fp_line (start -2.45 3.25) (end 3.5 3.25) (layer F.CrtYd) (width 0.05))
+ (fp_line (start -2.45 3.25) (end -2.45 -3.25) (layer F.CrtYd) (width 0.05))
+ (fp_line (start -2.2 -3) (end 3.5 -3) (layer F.SilkS) (width 0.12))
+ (fp_line (start -2.2 3) (end -2.2 -3) (layer F.SilkS) (width 0.12))
+ (fp_line (start -2.2 3) (end 3.5 3) (layer F.SilkS) (width 0.12))
+ (fp_arc (start 15.2 0) (end 9 1.3) (angle -170) (layer F.Fab) (width 0.1))
+ (fp_arc (start 15.2 0) (end 13.3 1.3) (angle -150) (layer F.Fab) (width 0.1))
+ (fp_line (start 23.5712 7.7216) (end 22.6568 6.8834) (layer F.Fab) (width 0.1))
+ (fp_line (start 23.5712 -7.7216) (end 22.6314 -6.858) (layer F.Fab) (width 0.1))
+ (fp_arc (start 15.2 0) (end 13.3 -1.3) (angle 150) (layer F.Fab) (width 0.1))
+ (fp_arc (start 15.2 0) (end 9 -1.3) (angle 170) (layer F.Fab) (width 0.1))
+ (fp_arc (start 15.2 0) (end 5.2 -1.3) (angle 180) (layer F.Fab) (width 0.1))
+ (fp_line (start 3.5306 -2.9) (end -1.7 -2.9) (layer F.Fab) (width 0.1))
+ (fp_line (start -1.7 2.9) (end 3.5306 2.9) (layer F.Fab) (width 0.1))
+ (fp_line (start -2.1 -2.5) (end -2.1 2.5) (layer F.Fab) (width 0.1))
+ (fp_line (start 0 1.3) (end 16.2 1.3) (layer F.Fab) (width 0.1))
+ (fp_line (start 16.2 -1.3) (end 0 -1.3) (layer F.Fab) (width 0.1))
+ (fp_arc (start 3.5 -3.8) (end 3.5 -2.9) (angle -70) (layer F.Fab) (width 0.1))
+ (fp_arc (start 16.2 0) (end 16.2 -1.3) (angle 180) (layer F.Fab) (width 0.1))
+ (fp_line (start 0 -1.3) (end 0 1.3) (layer F.Fab) (width 0.1))
+ (fp_arc (start -1.7 2.5) (end -2.1 2.5) (angle -90) (layer F.Fab) (width 0.1))
+ (fp_arc (start -1.7 -2.5) (end -2.1 -2.5) (angle 90) (layer F.Fab) (width 0.1))
+ (pad 2 thru_hole circle (at 20.49 0) (size 3 3) (drill 1.5) (layers *.Cu *.Mask)
+ (net 1 GND))
+ (pad 1 thru_hole rect (at 0 0) (size 3 3) (drill 1.5) (layers *.Cu *.Mask)
+ (net 2 "Net-(BT1-Pad1)"))
+ (model ${KISYS3DMOD}/Battery.3dshapes/BatteryHolder_Keystone_103_1x20mm.wrl
+ (at (xyz 0 0 0))
+ (scale (xyz 1 1 1))
+ (rotate (xyz 0 0 0))
+ )
+ )
+
+ (module Capacitor_THT:CP_Axial_L18.0mm_D8.0mm_P25.00mm_Horizontal (layer F.Cu) (tedit 5AE50EF2) (tstamp 5B59DB0A)
+ (at 201.5 64.75 270)
+ (descr "CP, Axial series, Axial, Horizontal, pin pitch=25mm, , length*diameter=18*8mm^2, Electrolytic Capacitor, , http://www.vishay.com/docs/28325/021asm.pdf")
+ (tags "CP Axial series Axial Horizontal pin pitch 25mm length 18mm diameter 8mm Electrolytic Capacitor")
+ (path /5B4314AB)
+ (fp_text reference C1 (at 12.5 -5.12 270) (layer F.SilkS)
+ (effects (font (size 1 1) (thickness 0.15)))
+ )
+ (fp_text value 1u (at 12.5 5.12 270) (layer F.Fab)
+ (effects (font (size 1 1) (thickness 0.15)))
+ )
+ (fp_line (start 3.5 -4) (end 3.5 4) (layer F.Fab) (width 0.1))
+ (fp_line (start 21.5 -4) (end 21.5 4) (layer F.Fab) (width 0.1))
+ (fp_line (start 3.5 -4) (end 5.18 -4) (layer F.Fab) (width 0.1))
+ (fp_line (start 5.18 -4) (end 6.08 -3.1) (layer F.Fab) (width 0.1))
+ (fp_line (start 6.08 -3.1) (end 6.98 -4) (layer F.Fab) (width 0.1))
+ (fp_line (start 6.98 -4) (end 21.5 -4) (layer F.Fab) (width 0.1))
+ (fp_line (start 3.5 4) (end 5.18 4) (layer F.Fab) (width 0.1))
+ (fp_line (start 5.18 4) (end 6.08 3.1) (layer F.Fab) (width 0.1))
+ (fp_line (start 6.08 3.1) (end 6.98 4) (layer F.Fab) (width 0.1))
+ (fp_line (start 6.98 4) (end 21.5 4) (layer F.Fab) (width 0.1))
+ (fp_line (start 0 0) (end 3.5 0) (layer F.Fab) (width 0.1))
+ (fp_line (start 25 0) (end 21.5 0) (layer F.Fab) (width 0.1))
+ (fp_line (start 5.2 0) (end 7 0) (layer F.Fab) (width 0.1))
+ (fp_line (start 6.1 -0.9) (end 6.1 0.9) (layer F.Fab) (width 0.1))
+ (fp_line (start 1.28 -2.6) (end 3.08 -2.6) (layer F.SilkS) (width 0.12))
+ (fp_line (start 2.18 -3.5) (end 2.18 -1.7) (layer F.SilkS) (width 0.12))
+ (fp_line (start 3.38 -4.12) (end 3.38 4.12) (layer F.SilkS) (width 0.12))
+ (fp_line (start 21.62 -4.12) (end 21.62 4.12) (layer F.SilkS) (width 0.12))
+ (fp_line (start 3.38 -4.12) (end 5.18 -4.12) (layer F.SilkS) (width 0.12))
+ (fp_line (start 5.18 -4.12) (end 6.08 -3.22) (layer F.SilkS) (width 0.12))
+ (fp_line (start 6.08 -3.22) (end 6.98 -4.12) (layer F.SilkS) (width 0.12))
+ (fp_line (start 6.98 -4.12) (end 21.62 -4.12) (layer F.SilkS) (width 0.12))
+ (fp_line (start 3.38 4.12) (end 5.18 4.12) (layer F.SilkS) (width 0.12))
+ (fp_line (start 5.18 4.12) (end 6.08 3.22) (layer F.SilkS) (width 0.12))
+ (fp_line (start 6.08 3.22) (end 6.98 4.12) (layer F.SilkS) (width 0.12))
+ (fp_line (start 6.98 4.12) (end 21.62 4.12) (layer F.SilkS) (width 0.12))
+ (fp_line (start 1.44 0) (end 3.38 0) (layer F.SilkS) (width 0.12))
+ (fp_line (start 23.56 0) (end 21.62 0) (layer F.SilkS) (width 0.12))
+ (fp_line (start -1.45 -4.25) (end -1.45 4.25) (layer F.CrtYd) (width 0.05))
+ (fp_line (start -1.45 4.25) (end 26.45 4.25) (layer F.CrtYd) (width 0.05))
+ (fp_line (start 26.45 4.25) (end 26.45 -4.25) (layer F.CrtYd) (width 0.05))
+ (fp_line (start 26.45 -4.25) (end -1.45 -4.25) (layer F.CrtYd) (width 0.05))
+ (fp_text user %R (at 12.5 0 270) (layer F.Fab)
+ (effects (font (size 1 1) (thickness 0.15)))
+ )
+ (pad 1 thru_hole rect (at 0 0 270) (size 2.4 2.4) (drill 1.2) (layers *.Cu *.Mask)
+ (net 3 "Net-(C1-Pad1)"))
+ (pad 2 thru_hole oval (at 25 0 270) (size 2.4 2.4) (drill 1.2) (layers *.Cu *.Mask)
+ (net 1 GND))
+ (model ${KISYS3DMOD}/Capacitor_THT.3dshapes/CP_Axial_L18.0mm_D8.0mm_P25.00mm_Horizontal.wrl
+ (at (xyz 0 0 0))
+ (scale (xyz 1 1 1))
+ (rotate (xyz 0 0 0))
+ )
+ )
+
+ (module Resistor_THT:R_Axial_DIN0204_L3.6mm_D1.6mm_P5.08mm_Horizontal (layer F.Cu) (tedit 5AE5139B) (tstamp 5B59DB1D)
+ (at 183.5 53.5 180)
+ (descr "Resistor, Axial_DIN0204 series, Axial, Horizontal, pin pitch=5.08mm, 0.167W, length*diameter=3.6*1.6mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf")
+ (tags "Resistor Axial_DIN0204 series Axial Horizontal pin pitch 5.08mm 0.167W length 3.6mm diameter 1.6mm")
+ (path /5B431328)
+ (fp_text reference R1 (at 2.54 -1.92 180) (layer F.SilkS)
+ (effects (font (size 1 1) (thickness 0.15)))
+ )
+ (fp_text value 10k (at 2.54 1.92 180) (layer F.Fab)
+ (effects (font (size 1 1) (thickness 0.15)))
+ )
+ (fp_line (start 0.74 -0.8) (end 0.74 0.8) (layer F.Fab) (width 0.1))
+ (fp_line (start 0.74 0.8) (end 4.34 0.8) (layer F.Fab) (width 0.1))
+ (fp_line (start 4.34 0.8) (end 4.34 -0.8) (layer F.Fab) (width 0.1))
+ (fp_line (start 4.34 -0.8) (end 0.74 -0.8) (layer F.Fab) (width 0.1))
+ (fp_line (start 0 0) (end 0.74 0) (layer F.Fab) (width 0.1))
+ (fp_line (start 5.08 0) (end 4.34 0) (layer F.Fab) (width 0.1))
+ (fp_line (start 0.62 -0.92) (end 4.46 -0.92) (layer F.SilkS) (width 0.12))
+ (fp_line (start 0.62 0.92) (end 4.46 0.92) (layer F.SilkS) (width 0.12))
+ (fp_line (start -0.95 -1.05) (end -0.95 1.05) (layer F.CrtYd) (width 0.05))
+ (fp_line (start -0.95 1.05) (end 6.03 1.05) (layer F.CrtYd) (width 0.05))
+ (fp_line (start 6.03 1.05) (end 6.03 -1.05) (layer F.CrtYd) (width 0.05))
+ (fp_line (start 6.03 -1.05) (end -0.95 -1.05) (layer F.CrtYd) (width 0.05))
+ (fp_text user %R (at 2.54 0 180) (layer F.Fab)
+ (effects (font (size 0.72 0.72) (thickness 0.108)))
+ )
+ (pad 1 thru_hole circle (at 0 0 180) (size 1.4 1.4) (drill 0.7) (layers *.Cu *.Mask)
+ (net 3 "Net-(C1-Pad1)"))
+ (pad 2 thru_hole oval (at 5.08 0 180) (size 1.4 1.4) (drill 0.7) (layers *.Cu *.Mask)
+ (net 2 "Net-(BT1-Pad1)"))
+ (model ${KISYS3DMOD}/Resistor_THT.3dshapes/R_Axial_DIN0204_L3.6mm_D1.6mm_P5.08mm_Horizontal.wrl
+ (at (xyz 0 0 0))
+ (scale (xyz 1 1 1))
+ (rotate (xyz 0 0 0))
+ )
+ )
+
+ (segment (start 167.965 81.279833) (end 174.529833 81.279833) (width 0.25) (layer B.Cu) (net 1))
+ (segment (start 166.465001 79.779834) (end 167.965 81.279833) (width 0.25) (layer B.Cu) (net 1))
+ (segment (start 174.529833 81.279833) (end 189 95.75) (width 0.25) (layer B.Cu) (net 1))
+ (segment (start 195.5 95.75) (end 201.5 89.75) (width 0.25) (layer B.Cu) (net 1))
+ (segment (start 189 95.75) (end 195.5 95.75) (width 0.25) (layer B.Cu) (net 1))
+ (segment (start 145.975001 78.029834) (end 145.75 77.804833) (width 0.25) (layer F.Cu) (net 2))
+ (segment (start 145.975001 79.779834) (end 145.975001 78.029834) (width 0.25) (layer F.Cu) (net 2))
+ (segment (start 145.75 77.804833) (end 145.75 62.75) (width 0.25) (layer F.Cu) (net 2))
+ (segment (start 155 53.5) (end 178.42 53.5) (width 0.25) (layer F.Cu) (net 2))
+ (segment (start 145.75 62.75) (end 155 53.5) (width 0.25) (layer F.Cu) (net 2))
+ (segment (start 201.5 63.3) (end 201.5 64.75) (width 0.25) (layer F.Cu) (net 3))
+ (segment (start 191.7 53.5) (end 201.5 63.3) (width 0.25) (layer F.Cu) (net 3))
+ (segment (start 183.5 53.5) (end 191.7 53.5) (width 0.25) (layer F.Cu) (net 3))
+
+)
diff --git a/test/doit/schematics/schematic-1.pro b/test/doit/schematics/schematic-1.pro
new file mode 100644
index 0000000..dd201c7
--- /dev/null
+++ b/test/doit/schematics/schematic-1.pro
@@ -0,0 +1,7 @@
+update=22/05/2015 07:44:53
+version=1
+last_client=kicad
+[general]
+version=1
+RootSch=
+BoardNm=
diff --git a/test/doit/schematics/schematic-1.sch b/test/doit/schematics/schematic-1.sch
index a805e83..9efffc4 100644
--- a/test/doit/schematics/schematic-1.sch
+++ b/test/doit/schematics/schematic-1.sch
@@ -14,34 +14,34 @@ Comment3 ""
Comment4 ""
$EndDescr
$Comp
-L Device:R R?
+L Device:R R1
U 1 1 5B431328
P 4400 2600
-F 0 "R?" V 4193 2600 50 0000 C CNN
+F 0 "R1" V 4193 2600 50 0000 C CNN
F 1 "10k" V 4284 2600 50 0000 C CNN
-F 2 "" V 4330 2600 50 0001 C CNN
+F 2 "Resistor_THT:R_Axial_DIN0204_L3.6mm_D1.6mm_P5.08mm_Horizontal" V 4330 2600 50 0001 C CNN
F 3 "~" H 4400 2600 50 0001 C CNN
1 4400 2600
0 1 1 0
$EndComp
$Comp
-L Device:Battery_Cell BT?
+L Device:Battery_Cell BT1
U 1 1 5B431438
P 3700 2900
-F 0 "BT?" H 3818 2996 50 0000 L CNN
+F 0 "BT1" H 3818 2996 50 0000 L CNN
F 1 "9V" H 3818 2905 50 0000 L CNN
-F 2 "" V 3700 2960 50 0001 C CNN
+F 2 "Battery:BatteryHolder_Keystone_103_1x20mm" V 3700 2960 50 0001 C CNN
F 3 "~" V 3700 2960 50 0001 C CNN
1 3700 2900
1 0 0 -1
$EndComp
$Comp
-L Device:C C?
+L Device:C C1
U 1 1 5B4314AB
P 5000 2850
-F 0 "C?" H 5115 2896 50 0000 L CNN
+F 0 "C1" H 5115 2896 50 0000 L CNN
F 1 "1u" H 5115 2805 50 0000 L CNN
-F 2 "" H 5038 2700 50 0001 C CNN
+F 2 "Capacitor_THT:CP_Axial_L18.0mm_D8.0mm_P25.00mm_Horizontal" H 5038 2700 50 0001 C CNN
F 3 "~" H 5000 2850 50 0001 C CNN
1 5000 2850
1 0 0 -1
@@ -51,10 +51,10 @@ Wire Wire Line
Wire Wire Line
5000 3100 5000 3000
$Comp
-L power:GND #PWR?
+L power:GND #PWR0101
U 1 1 5B4315FE
P 3700 3200
-F 0 "#PWR?" H 3700 2950 50 0001 C CNN
+F 0 "#PWR0101" H 3700 2950 50 0001 C CNN
F 1 "GND" H 3705 3027 50 0000 C CNN
F 2 "" H 3700 3200 50 0001 C CNN
F 3 "" H 3700 3200 50 0001 C CNN
diff --git a/test/doit/test_doit.py b/test/doit/test_doit.py
index 7708ca7..a379c97 100644
--- a/test/doit/test_doit.py
+++ b/test/doit/test_doit.py
@@ -1,37 +1,39 @@
-import logging
import os
import os.path
-import pytest
-import logging
filedir = os.path.dirname(os.path.abspath(__file__))
schematics_dir = os.path.join(filedir, "schematics")
+
def find_task(tasks, name: str):
t = next((t for t in tasks if t["name"] == name), None)
- assert(t is not None)
+ assert t is not None, "Could not find task named {}".format(name)
return t
+
def exec_task(task):
targets = task["targets"]
for a in task["actions"]:
if isinstance(a, str):
cmd = a % dict(targets=" ".join(targets))
ret = os.system(cmd)
- assert(ret == 0)
+ assert (ret == 0)
else:
a()
+
def test_doit(tmpdir, caplog):
from ee.kicad.doit import KicadDoitTasks
args = dict(
sch=os.path.join(schematics_dir, "schematic-1.sch"),
+ kicad_pcb=os.path.join(schematics_dir, "schematic-1.kicad_pcb"),
data_set_dir=os.path.join(tmpdir, "ee"),
)
tasks = list(KicadDoitTasks(**args).tasks())
- assert(len(tasks) > 1)
+ assert (len(tasks) > 1)
exec_task(find_task(tasks, "kicad-sch-to-data-set"))
+ exec_task(find_task(tasks, "kicad-pcb-to-data-set"))
exec_task(find_task(tasks, "kicad-create-component-data-set"))
# thirdparty/olinuxino/HARDWARE/A64-OLinuXino/A64-OLinuXino_Rev_C/A64-OlinuXino_Rev_C.sch