Commit 0ba6f998 authored by Dick Hollenbeck's avatar Dick Hollenbeck

Clarify, extend, and rename ky*.py to kicad_netlist_reader.py.

Significantly enhance the bom_csv_grouped_by_value.py BOM generator.
IMO it at this moment, the best BOM production tool for KiCad.
parent b6110bfc
......@@ -4,8 +4,10 @@
# Example: Sorted and Grouped HTML BOM with more advanced grouping
#
from __future__ import print_function
# Import the KiCad python helper module and the csv formatter
import ky_generic_netlist_reader
import kicad_netlist_reader
import sys
# Start with a basic html template
......@@ -43,9 +45,9 @@ def myEqu(self, other):
result = True
if self.getValue() != other.getValue():
result = False
elif self.getLib() != other.getLib():
elif self.getLibName() != other.getLibName():
result = False
elif self.getPart() != other.getPart():
elif self.getPartName() != other.getPartName():
result = False
elif self.getFootprint() != other.getFootprint():
result = False
......@@ -61,18 +63,18 @@ def myEqu(self, other):
# Override the component equivalence operator - it is important to do this
# before loading the netlist, otherwise all components will have the original
# equivalency operator.
ky_generic_netlist_reader.component.__equ__ = myEqu
kicad_netlist_reader.comp.__equ__ = myEqu
# Generate an instance of a generic netlist, and load the netlist tree from
# video.tmp. If the file doesn't exist, execution will stop
net = ky_generic_netlist_reader.netlist(sys.argv[1])
net = kicad_netlist_reader.netlist(sys.argv[1])
# Open a file to write too, if the file cannot be opened output to stdout
# instead
try:
f = open(sys.argv[2], 'w')
except IOError:
print >> sys.stderr, __file__, ":", e
print(__file__, ":", e, file=sys.stderr)
f = stdout
# Output a set of rows for a header providing general information
......@@ -88,9 +90,11 @@ row += "<th>Description</th>" + "<th>Vendor</th></tr>"
html = html.replace('<!--TABLEROW-->', row + "<!--TABLEROW-->")
components = net.getInterestingComponents()
# Get all of the components in groups of matching parts + values
# (see ky_generic_netlist_reader.py)
grouped = net.groupComponents()
# (see kicad_netlist_reader.py)
grouped = net.groupComponents(components)
# Output all of the component information
for group in grouped:
......@@ -99,17 +103,19 @@ for group in grouped:
# Add the reference of every component in the group and keep a reference
# to the component so that the other data can be filled in once per group
for component in group:
refs += component.getRef() + ", "
if len(refs) > 0:
refs += ", "
refs += component.getRef()
c = component
row = "\n "
row += "<tr><td>" + refs +"</td><td>" + str(len(group))
row += "</td><td>" + c.getValue() + "</td><td>" + c.getLib() + "/"
row += c.getPart() + "</td><td>" + c.getDatasheet() + "</td><td>"
row += "</td><td>" + c.getValue() + "</td><td>" + c.getLibName() + ":"
row += c.getPartName() + "</td><td>" + c.getDatasheet() + "</td><td>"
row += c.getDescription() + "</td><td>" + c.getField("Vendor")
row += "</td></tr>"
html = html.replace('<!--TABLEROW-->', row + "<!--TABLEROW-->")
# Print the formatted html to output file
print >> f, html
print(html, file=f)
......@@ -4,21 +4,23 @@
# Example: Tab delimited list (The same as std output) Ungrouped
#
from __future__ import print_function
# Import the KiCad python helper module and the csv formatter
import ky_generic_netlist_reader
import kicad_netlist_reader
import csv
import sys
# Generate an instance of a generic netlist, and load the netlist tree from
# the command line option. If the file doesn't exist, execution will stop
net = ky_generic_netlist_reader.netlist(sys.argv[1])
net = kicad_netlist_reader.netlist(sys.argv[1])
# Open a file to write to, if the file cannot be opened output to stdout
# instead
try:
f = open(sys.argv[2], 'w')
except IOError:
print >> sys.stderr, __file__, ":", e
print(__file__, ":", e, file=sys.stderr)
f = stdout
# Create a new csv writer object to use as the output formatter, although we
......@@ -32,7 +34,9 @@ out.writerow(['Tool:', net.getTool()])
out.writerow(['Component Count:', len(net.components)])
out.writerow(['Ref', 'Value', 'Part', 'Documentation', 'Description', 'Vendor'])
components = net.getInterestingComponents()
# Output all of the component information
for c in net.components:
out.writerow([c.getRef(), c.getValue(), c.getLib() + "/" + c.getPart(),
for c in components:
out.writerow([c.getRef(), c.getValue(), c.getLibName() + ":" + c.getPartName(),
c.getDatasheet(), c.getDescription(), c.getField("Vendor")])
......@@ -4,21 +4,23 @@
# Example: Ungrouped (One component per row) CSV output
#
from __future__ import print_function
# Import the KiCad python helper module
import ky_generic_netlist_reader
import kicad_netlist_reader
import csv
import sys
# Generate an instance of a generic netlist, and load the netlist tree from
# the command line option. If the file doesn't exist, execution will stop
net = ky_generic_netlist_reader.netlist(sys.argv[1])
net = kicad_netlist_reader.netlist(sys.argv[1])
# Open a file to write to, if the file cannot be opened output to stdout
# instead
try:
f = open(sys.argv[2], 'w')
except IOError:
print >> sys.stderr, __file__, ":", e
print(__file__, ":", e, file=sys.stderr)
f = stdout
# Create a new csv writer object to use as the output formatter
......@@ -31,8 +33,10 @@ out.writerow(['Tool:', net.getTool()])
out.writerow(['Component Count:', len(net.components)])
out.writerow(['Ref', 'Value', 'Footprint', 'Datasheet', 'Manufacturer', 'Vendor'])
components = net.getInterestingComponents()
# Output all of the component information (One component per row)
for c in net.components:
for c in components:
out.writerow([c.getRef(), c.getValue(), c.getFootprint(), c.getDatasheet(),
c.getField("Manufacturer"), c.getField("Vendor")])
......@@ -4,49 +4,123 @@
# Example: Sorted and Grouped CSV BOM
#
from __future__ import print_function
# Import the KiCad python helper module and the csv formatter
import ky_generic_netlist_reader
import kicad_netlist_reader
import csv
import sys
if len(sys.argv) != 3:
print("Usage ", __file__, "<generic_netlist.xml> <output.csv>", file=sys.stderr)
sys.exit(1)
# Generate an instance of a generic netlist, and load the netlist tree from
# the command line option. If the file doesn't exist, execution will stop
net = ky_generic_netlist_reader.netlist(sys.argv[1])
net = kicad_netlist_reader.netlist(sys.argv[1])
# Open a file to write to, if the file cannot be opened output to stdout
# instead
try:
f = open(sys.argv[2], 'w')
except IOError:
print >> sys.stderr, __file__, ":", e
print(__file__, ":", e, file=sys.stderr)
f = stdout
# subset the components to those wanted in the BOM, controlled
# by <configure> block in kicad_netlist_reader.py
components = net.getInterestingComponents()
compfields = net.gatherComponentFieldUnion(components)
partfields = net.gatherLibPartFieldUnion()
# remove Reference, Value, Datasheet, and Footprint, they will come from 'columns' below
partfields -= set( ['Reference', 'Value', 'Datasheet', 'Footprint'] )
columnset = compfields | partfields # union
# prepend an initial 'hard coded' list and put the enchillada into list 'columns'
columns = ['Item', 'Qty', 'Reference(s)', 'Value', 'LibPart', 'Footprint', 'Datasheet'] + sorted(list(columnset))
# Create a new csv writer object to use as the output formatter
out = csv.writer(f, lineterminator='\n', delimiter=',', quotechar='\"', quoting=csv.QUOTE_ALL)
out = csv.writer(f, lineterminator='\n', delimiter=',', quotechar='\"', quoting=csv.QUOTE_MINIMAL)
# Output a set of rows for a header providing general information
# Output a set of rows as a header providing general information
out.writerow(['Source:', net.getSource()])
out.writerow(['Date:', net.getDate()])
out.writerow(['Tool:', net.getTool()])
out.writerow(['Component Count:', len(net.components)])
out.writerow(['Ref', 'Qnty', 'Value', 'Part', 'Datasheet', 'Description', 'Vendor'])
out.writerow(['Component Count:', len(components)])
out.writerow([])
out.writerow(['Individual Components:'])
out.writerow([]) # blank line
out.writerow(columns)
# Output all the interesting components individually first:
row = []
for c in components:
del row[:]
row.append('') # item is blank in individual table
row.append('') # Qty is always 1, why print it
row.append( c.getRef() ) # Reference
row.append( c.getValue() ) # Value
row.append( c.getLibName() + ":" + c.getPartName() ) # LibPart
#row.append( c.getDescription() )
row.append( c.getFootprint() )
row.append( c.getDatasheet() )
# from column 7 upwards, use the fieldnames to grab the data
for field in columns[7:]:
row.append( c.getField( field ) );
out.writerow(row)
out.writerow([]) # blank line
out.writerow([]) # blank line
out.writerow([]) # blank line
out.writerow(['Collated Components:'])
out.writerow([]) # blank line
out.writerow(columns) # reuse same columns
# Get all of the components in groups of matching parts + values
# (see ky_generic_netlist_reader.py)
grouped = net.groupComponents()
# (see kicad_netlist_reader.py)
grouped = net.groupComponents(components)
# Output all of the component information
# Output component information organized by group, aka as collated:
item = 0
for group in grouped:
del row[:]
refs = ""
# Add the reference of every component in the group and keep a reference
# to the component so that the other data can be filled in once per group
for component in group:
refs += component.getRef() + ", "
if len(refs) > 0:
refs += ", "
refs += component.getRef()
c = component
# Fill in the component groups common data
out.writerow([refs, len(group), c.getValue(), c.getLib() + "/" + c.getPart(), c.getDatasheet(),
c.getDescription(), c.getField("Vendor")])
# columns = ['Item', 'Qty', 'Reference(s)', 'Value', 'LibPart', 'Footprint', 'Datasheet'] + sorted(list(columnset))
item += 1
row.append( item )
row.append( len(group) )
row.append( refs );
row.append( c.getValue() )
row.append( c.getLibName() + ":" + c.getPartName() )
row.append( net.getGroupFootprint(group) )
row.append( net.getGroupDatasheet(group) )
# from column 7 upwards, use the fieldnames to grab the data
for field in columns[7:]:
row.append( net.getGroupField(group, field) );
out.writerow( row )
f.close()
......@@ -4,8 +4,10 @@
# Example: Sorted and Grouped HTML BOM with more advanced grouping
#
from __future__ import print_function
# Import the KiCad python helper module and the csv formatter
import ky_generic_netlist_reader
import kicad_netlist_reader
import sys
# Start with a basic html template
......@@ -43,9 +45,9 @@ def myEqu(self, other):
result = True
if self.getValue() != other.getValue():
result = False
elif self.getLib() != other.getLib():
elif self.getLibName() != other.getLibName():
result = False
elif self.getPart() != other.getPart():
elif self.getPartName() != other.getPartName():
result = False
elif self.getFootprint() != other.getFootprint():
result = False
......@@ -61,18 +63,18 @@ def myEqu(self, other):
# Override the component equivalence operator - it is important to do this
# before loading the netlist, otherwise all components will have the original
# equivalency operator.
ky_generic_netlist_reader.component.__equ__ = myEqu
kicad_netlist_reader.comp.__equ__ = myEqu
# Generate an instance of a generic netlist, and load the netlist tree from
# video.xml. If the file doesn't exist, execution will stop
net = ky_generic_netlist_reader.netlist(sys.argv[1])
net = kicad_netlist_reader.netlist(sys.argv[1])
# Open a file to write too, if the file cannot be opened output to stdout
# instead
try:
f = open(sys.argv[2], 'w')
except IOError:
print >> sys.stderr, __file__, ":", e
print(__file__, ":", e, file=sys.stderr)
f = stdout
# Output a set of rows for a header providing general information
......@@ -90,9 +92,11 @@ row += "<th>PartNumber</th>" + "<th>Vendor</th></tr>"
html = html.replace('<!--TABLEROW-->', row + "<!--TABLEROW-->")
components = net.getInterestingComponents()
# Get all of the components in groups of matching parts + values
# (see ky_generic_netlist_reader.py)
grouped = net.groupComponents()
# (see kicad_netlist_reader.py)
grouped = net.groupComponents(components)
# Output all of the component information
for group in grouped:
......@@ -101,12 +105,14 @@ for group in grouped:
# Add the reference of every component in the group and keep a reference
# to the component so that the other data can be filled in once per group
for component in group:
refs += component.getRef() + ", "
if len(refs) > 0:
refs += ", "
refs += component.getRef()
c = component
row = "<tr><td>" + refs +"</td><td>" + str(len(group))
row += "</td><td>" + c.getValue() + "</td><td>"
row += c.getLib() + "/" + c.getPart() + "</td><td>"
row += c.getLibName() + ":" + c.getPartName() + "</td><td>"
#row += c.getDatasheet() + "</td><td>"
row += c.getDescription() + "</td><td>"
row += c.getField("PartNumber") + "</td><td>"
......@@ -116,4 +122,4 @@ for group in grouped:
html = html.replace('<!--TABLEROW-->', row + "<!--TABLEROW-->")
# Print the formatted html to output file
print >> f, html
print(html, file=f)
......@@ -4,8 +4,10 @@
# Example: Sorted and Grouped HTML BOM
#
from __future__ import print_function
# Import the KiCad python helper module and the csv formatter
import ky_generic_netlist_reader
import kicad_netlist_reader
import sys
# Start with a basic html template
......@@ -30,14 +32,14 @@ html = """
# Generate an instance of a generic netlist, and load the netlist tree from
# the command line option. If the file doesn't exist, execution will stop
net = ky_generic_netlist_reader.netlist(sys.argv[1])
net = kicad_netlist_reader.netlist(sys.argv[1])
# Open a file to write to, if the file cannot be opened output to stdout
# instead
try:
f = open(sys.argv[2], 'w')
except IOError:
print >> sys.stderr, __file__, ":", e
print(__file__, ":", e, file=sys.stderr)
f = stdout
# Output a set of rows for a header providing general information
......@@ -53,9 +55,11 @@ row += "<th>Description</th>" + "<th>Vendor</th></tr>"
html = html.replace('<!--TABLEROW-->', row + "<!--TABLEROW-->")
components = net.getInterestingComponents()
# Get all of the components in groups of matching parts + values
# (see ky_generic_netlist_reader.py)
grouped = net.groupComponents()
# (see kicad_netlist_reader.py)
grouped = net.groupComponents(components)
# Output all of the component information
for group in grouped:
......@@ -64,16 +68,18 @@ for group in grouped:
# Add the reference of every component in the group and keep a reference
# to the component so that the other data can be filled in once per group
for component in group:
refs += component.getRef() + ", "
if len(refs) > 0:
refs += ", "
refs += component.getRef()
c = component
row = "<tr><td>" + refs +"</td><td>" + str(len(group))
row += "</td><td>" + c.getValue() + "</td><td>" + c.getLib() + "/"
row += c.getPart() + "</td><td>" + c.getDatasheet() + "</td><td>"
row += "</td><td>" + c.getValue() + "</td><td>" + c.getLibName() + ":"
row += c.getPartName() + "</td><td>" + c.getDatasheet() + "</td><td>"
row += c.getDescription() + "</td><td>" + c.getField("Vendor")
row += "</td></tr>"
html = html.replace('<!--TABLEROW-->', row + "<!--TABLEROW-->")
# Print the formatted html to the file
print >> f, html
print(html, file=f)
......@@ -4,20 +4,24 @@
# Example: Round robin, XML to XML conversion
#
from __future__ import print_function
# Import the KiCad python helper module and the csv formatter
import ky_generic_netlist_reader
import kicad_netlist_reader
import sys
import pdb
# Generate an instance of a generic netlist, and load the netlist tree from
# the command line option. If the file doesn't exist, execution will stop
net = ky_generic_netlist_reader.netlist(sys.argv[1])
net = kicad_netlist_reader.netlist(sys.argv[1])
# Open a file to write to, if the file cannot be opened output to stdout
# instead
try:
f = open(sys.argv[2], 'w')
except IOError:
print >> sys.stderr, __file__, ":", e
print( __file__, ":", e, file=sys.stderr)
f = stdout
print >> f, net.formatXML()
print(net.formatXML(), file=f)
......@@ -4,8 +4,10 @@
# Example: Round value robin, XML to XML conversion with partial value monging
#
from __future__ import print_function
# Import the KiCad python helper module and the csv formatter
import ky_generic_netlist_reader
import kicad_netlist_reader
import sys
def checkvalue(self):
......@@ -51,21 +53,21 @@ def checkvalue(self):
# Give components a new method for checking the values (this could easily be a
# Company Part Number generator method instead)
ky_generic_netlist_reader.component.checkvalue = checkvalue
kicad_netlist_reader.comp.checkvalue = checkvalue
# Generate an instance of a generic netlist, and load the netlist tree from
# the command line option. If the file doesn't exist, execution will stop
net = ky_generic_netlist_reader.netlist(sys.argv[1])
net = kicad_netlist_reader.netlist(sys.argv[1])
# Open a file to write to, if the file cannot be opened output to stdout
# instead
try:
f = open(sys.argv[2], 'w')
except IOError:
print >> sys.stderr, __file__, ":", e
print(__file__, ":", e, file=sys.stderr)
f = stdout
for c in net.components:
c.checkvalue()
print >> f, net.formatXML()
print(net.formatXML(), file=f)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment