aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ee/kicad/__init__.py3
-rw-r--r--src/ee/kicad/model.py80
-rw-r--r--src/ee/kicad/read_schematic.py35
-rw-r--r--test/parser/hierarchical/child.sch35
-rw-r--r--test/parser/hierarchical/grand-child.sch29
-rw-r--r--test/parser/hierarchical/hierarchical-cache.lib63
-rw-r--r--test/parser/hierarchical/hierarchical.pro35
-rw-r--r--test/parser/hierarchical/hierarchical.sch35
-rw-r--r--test/test_read_schematic.py13
9 files changed, 301 insertions, 27 deletions
diff --git a/src/ee/kicad/__init__.py b/src/ee/kicad/__init__.py
index f431e13..1aac33d 100644
--- a/src/ee/kicad/__init__.py
+++ b/src/ee/kicad/__init__.py
@@ -1,7 +1,7 @@
from typing import Any
from ee import EeException
-from ee.kicad.read_schematic import read_schematic
+from ee.kicad.read_schematic import read_schematic, read_schematics
from ee.kicad.to_bom import to_bom, to_bom_xml
from .model import *
@@ -11,6 +11,7 @@ __all__ = [
"Component",
"Schematic",
"read_schematic",
+ "read_schematics",
"to_bom",
"to_bom_xml",
"to_pandas",
diff --git a/src/ee/kicad/model.py b/src/ee/kicad/model.py
index 7d9a437..eacf8e2 100644
--- a/src/ee/kicad/model.py
+++ b/src/ee/kicad/model.py
@@ -133,16 +133,17 @@ class Component(object):
class Sheet(object):
- def __init__(self):
- self._components = []
- pass
+ def __init__(self, name, path):
+ self._name = name
+ self._path = path
@property
- def components(self):
- return frozenset(self._components)
+ def path(self):
+ return self._path
- def add_component(self, component):
- self._components.append(component)
+ @property
+ def name(self):
+ return self._name
class Library(object):
@@ -153,12 +154,8 @@ class Library(object):
class Schematic(object):
def __init__(self):
self._libraries = set()
- self._sheets = [Sheet()]
- pass
-
- @property
- def first_sheet(self):
- return self._sheets[0]
+ self._sheets = []
+ self._components = []
@property
def libraries(self):
@@ -167,18 +164,61 @@ class Schematic(object):
def add_library(self, library):
self._libraries.add(Library(library))
- # Getters
@property
- def components(self) -> List[Component]:
- a = []
- for s in self._sheets:
- for c in s.components:
- a.append(c)
- return a
+ def sheets(self):
+ return frozenset(self._sheets)
+
+ def add_sheet(self, sheet):
+ self._sheets.append(sheet)
+
+ @property
+ def components(self):
+ return frozenset(self._components)
+
+ def add_component(self, component):
+ self._components.append(component)
def get_component(self, ref, unit=1):
+ c = find_component(self, ref, unit)
+
+ if c:
+ return c
+
+ raise KeyError("No such component: {}".format(ref))
+
+ def find_component(self, ref, unit=1):
for c in self.components:
if c.ref == ref and unit == unit:
return c
+class Schematics(object):
+ def __init__(self, schematics):
+ self._schematics = schematics
+
+ @property
+ def schematics(self) -> List[Schematic]:
+ return list(self._schematics)
+
+ @property
+ def components(self) -> List[Component]:
+ cs = []
+ for s in self._schematics:
+ for c in s.components:
+ cs.append(c)
+ return cs
+
+ def get_component(self, ref, unit=1):
+ for s in self._schematics:
+ c = s.find_component(ref, unit)
+ if c:
+ return c
+
raise KeyError("No such component: {}".format(ref))
+
+ @property
+ def libraries(self) -> List[Library]:
+ ls = []
+ for s in self._schematics:
+ for l in s.libraries:
+ ls.append(l)
+ return ls
diff --git a/src/ee/kicad/read_schematic.py b/src/ee/kicad/read_schematic.py
index e70d1a7..ed5ce21 100644
--- a/src/ee/kicad/read_schematic.py
+++ b/src/ee/kicad/read_schematic.py
@@ -1,16 +1,42 @@
import shlex
from ee import EeException
from ee.kicad.model import *
+import os.path
+def read_schematics(path):
+ def read(path):
+ schematic = read_schematic(path)
+ schematics = [schematic]
+ for sheet in schematic.sheets:
+ p = os.path.join(os.path.dirname(path), sheet.path)
+ print("Loading {} from {}, path: {}".format(sheet.name, sheet.path, p))
+ children = read(p)
+ schematics.extend(children)
+ return schematics
+
+ return Schematics(read(path))
+
def read_schematic(path):
schematic = Schematic()
- sheet = None
def descr_section(lines):
# print("descr_section: len={}".format(len(lines)))
pass
+ def sheet_section(lines):
+
+ for line in lines:
+ parts = shlex.split(line)
+ if len(parts) < 2:
+ continue
+ if parts[0] == "F0":
+ name = parts[1]
+ elif parts[0] == "F1":
+ path = parts[1]
+
+ schematic.add_sheet(Sheet(name, path))
+
def comp_section(lines):
# print("comp_section: len={}".format(len(lines)))
timestamp = None
@@ -65,16 +91,13 @@ def read_schematic(path):
else:
raise EeException("Bad component field: '{}'".format(line))
- sheet.add_component(Component(position, timestamp, library, name, unit, ref, fields))
+ schematic.add_component(Component(position, timestamp, library, name, unit, ref, fields))
def load(f):
header = f.readline()
if "EESchema Schematic File Version" not in header:
raise EeException("Not a KiCAD schematic file.")
- nonlocal sheet
- sheet = schematic.first_sheet
-
section_name = None
section = []
@@ -93,6 +116,8 @@ def read_schematic(path):
comp_section(section)
elif section_name == "$Descr":
descr_section(section)
+ elif section_name == "$Sheet":
+ sheet_section(section)
else:
if line == "$EndSCHEMATIC":
seen_end = True
diff --git a/test/parser/hierarchical/child.sch b/test/parser/hierarchical/child.sch
new file mode 100644
index 0000000..b80f666
--- /dev/null
+++ b/test/parser/hierarchical/child.sch
@@ -0,0 +1,35 @@
+EESchema Schematic File Version 2
+LIBS:device
+LIBS:hierarchical-cache
+EELAYER 25 0
+EELAYER END
+$Descr A4 11693 8268
+encoding utf-8
+Sheet 2 3
+Title ""
+Date ""
+Rev ""
+Comp ""
+Comment1 ""
+Comment2 ""
+Comment3 ""
+Comment4 ""
+$EndDescr
+$Comp
+L C C201
+U 1 1 59DF3621
+P 5200 3000
+F 0 "C201" H 5225 3100 50 0000 L CNN
+F 1 "1u" H 5225 2900 50 0000 L CNN
+F 2 "" H 5238 2850 50 0001 C CNN
+F 3 "" H 5200 3000 50 0001 C CNN
+ 1 5200 3000
+ 1 0 0 -1
+$EndComp
+$Sheet
+S 2800 3200 1300 600
+U 59DF3A64
+F0 "Grand Child" 60
+F1 "grand-child.sch" 60
+$EndSheet
+$EndSCHEMATC
diff --git a/test/parser/hierarchical/grand-child.sch b/test/parser/hierarchical/grand-child.sch
new file mode 100644
index 0000000..f4bc921
--- /dev/null
+++ b/test/parser/hierarchical/grand-child.sch
@@ -0,0 +1,29 @@
+EESchema Schematic File Version 2
+LIBS:device
+LIBS:hierarchical-cache
+EELAYER 25 0
+EELAYER END
+$Descr A4 11693 8268
+encoding utf-8
+Sheet 3 3
+Title ""
+Date ""
+Rev ""
+Comp ""
+Comment1 ""
+Comment2 ""
+Comment3 ""
+Comment4 ""
+$EndDescr
+$Comp
+L L L301
+U 1 1 59DF3A6F
+P 4700 2100
+F 0 "L301" V 4650 2100 50 0000 C CNN
+F 1 "10u" V 4775 2100 50 0000 C CNN
+F 2 "" H 4700 2100 50 0001 C CNN
+F 3 "" H 4700 2100 50 0001 C CNN
+ 1 4700 2100
+ 1 0 0 -1
+$EndComp
+$EndSCHEMATC
diff --git a/test/parser/hierarchical/hierarchical-cache.lib b/test/parser/hierarchical/hierarchical-cache.lib
new file mode 100644
index 0000000..22e755f
--- /dev/null
+++ b/test/parser/hierarchical/hierarchical-cache.lib
@@ -0,0 +1,63 @@
+EESchema-LIBRARY Version 2.3
+#encoding utf-8
+#
+# C
+#
+DEF C C 0 10 N Y 1 F N
+F0 "C" 25 100 50 H V L CNN
+F1 "C" 25 -100 50 H V L CNN
+F2 "" 38 -150 50 H I C CNN
+F3 "" 0 0 50 H I C CNN
+$FPLIST
+ C_*
+$ENDFPLIST
+DRAW
+P 2 0 1 20 -80 -30 80 -30 N
+P 2 0 1 20 -80 30 80 30 N
+X ~ 1 0 150 110 D 50 50 1 1 P
+X ~ 2 0 -150 110 U 50 50 1 1 P
+ENDDRAW
+ENDDEF
+#
+# L
+#
+DEF L L 0 40 N N 1 F N
+F0 "L" -50 0 50 V V C CNN
+F1 "L" 75 0 50 V V C CNN
+F2 "" 0 0 50 H I C CNN
+F3 "" 0 0 50 H I C CNN
+$FPLIST
+ Choke_*
+ *Coil*
+ Inductor_*
+ L_*
+$ENDFPLIST
+DRAW
+A 0 -75 25 -899 899 0 1 0 N 0 -100 0 -50
+A 0 -25 25 -899 899 0 1 0 N 0 -50 0 0
+A 0 25 25 -899 899 0 1 0 N 0 0 0 50
+A 0 75 25 -899 899 0 1 0 N 0 50 0 100
+X 1 1 0 150 50 D 50 50 1 1 P
+X 2 2 0 -150 50 U 50 50 1 1 P
+ENDDRAW
+ENDDEF
+#
+# R
+#
+DEF R R 0 0 N Y 1 F N
+F0 "R" 80 0 50 V V C CNN
+F1 "R" 0 0 50 V V C CNN
+F2 "" -70 0 50 V I C CNN
+F3 "" 0 0 50 H I C CNN
+$FPLIST
+ R_*
+ R_*
+$ENDFPLIST
+DRAW
+S -40 -100 40 100 0 1 10 N
+X ~ 1 0 150 50 D 50 50 1 1 P
+X ~ 2 0 -150 50 U 50 50 1 1 P
+ENDDRAW
+ENDDEF
+#
+#End Library
diff --git a/test/parser/hierarchical/hierarchical.pro b/test/parser/hierarchical/hierarchical.pro
new file mode 100644
index 0000000..8543101
--- /dev/null
+++ b/test/parser/hierarchical/hierarchical.pro
@@ -0,0 +1,35 @@
+update=Mon 31 Jul 2017 10:04:56 AM MDT
+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]
+LibName1=device
+LibName2=hierarchical-cache
diff --git a/test/parser/hierarchical/hierarchical.sch b/test/parser/hierarchical/hierarchical.sch
new file mode 100644
index 0000000..daf7b88
--- /dev/null
+++ b/test/parser/hierarchical/hierarchical.sch
@@ -0,0 +1,35 @@
+EESchema Schematic File Version 2
+LIBS:device
+LIBS:hierarchical-cache
+EELAYER 25 0
+EELAYER END
+$Descr A4 11693 8268
+encoding utf-8
+Sheet 1 3
+Title ""
+Date ""
+Rev ""
+Comp ""
+Comment1 ""
+Comment2 ""
+Comment3 ""
+Comment4 ""
+$EndDescr
+$Comp
+L R R101
+U 1 1 59DF35E4
+P 5100 2600
+F 0 "R101" V 5180 2600 50 0000 C CNN
+F 1 "1k" V 5100 2600 50 0000 C CNN
+F 2 "" V 5030 2600 50 0001 C CNN
+F 3 "" H 5100 2600 50 0001 C CNN
+ 1 5100 2600
+ 1 0 0 -1
+$EndComp
+$Sheet
+S 2600 3300 1300 600
+U 59DF3614
+F0 "Child" 60
+F1 "child.sch" 60
+$EndSheet
+$EndSCHEMATC
diff --git a/test/test_read_schematic.py b/test/test_read_schematic.py
index 1af7002..2b269a6 100644
--- a/test/test_read_schematic.py
+++ b/test/test_read_schematic.py
@@ -35,7 +35,7 @@ def dump_bom(sch):
def load(path):
p = basedir + "/parser/" + path
print("p={}".format(p))
- sch = kicad.read_schematic(p)
+ sch = kicad.read_schematics(p)
return sch
@@ -51,3 +51,14 @@ def test_sch():
sch = load("foo.sch")
dump_schema(sch)
dump_bom(sch)
+
+
+def test_hierarchical():
+ sch = load("hierarchical/hierarchical.sch")
+ dump_schema(sch)
+ dump_bom(sch)
+ assert 3 == len(sch.components)
+ assert 3 == len(sch.schematics)
+ assert sch.get_component("R101")
+ assert sch.get_component("C201")
+ assert sch.get_component("L301")