1#
2# Example python script to generate a BOM from a KiCad generic netlist
3#
4# Example: Sorted and Grouped CSV BOM
5#
6
7"""
8    @package
9    Output: CSV (comma-separated)
10    Grouped By: Value, Footprint
11    Sorted By: Ref
12    Fields: Ref, Qnty, Value, Cmp name, Footprint, Description, Vendor
13
14    Command line:
15    python "pathToFile/bom_csv_grouped_by_value_with_fp.py" "%I" "%O.csv"
16"""
17
18# Import the KiCad python helper module and the csv formatter
19import kicad_netlist_reader
20import kicad_utils
21import csv
22import sys
23
24# A helper function to convert a UTF8/Unicode/locale string read in netlist
25# for python2 or python3
26def fromNetlistText( aText ):
27    if sys.platform.startswith('win32'):
28        try:
29            return aText.encode('utf-8').decode('cp1252')
30        except UnicodeDecodeError:
31            return aText
32    else:
33        return aText
34
35# Generate an instance of a generic netlist, and load the netlist tree from
36# the command line option. If the file doesn't exist, execution will stop
37net = kicad_netlist_reader.netlist(sys.argv[1])
38
39# Open a file to write to, if the file cannot be opened output to stdout
40# instead
41try:
42    f = kicad_utils.open_file_write(sys.argv[2], 'w')
43except IOError:
44    e = "Can't open output file for writing: " + sys.argv[2]
45    print(__file__, ":", e, sys.stderr)
46    f = sys.stdout
47
48# Create a new csv writer object to use as the output formatter
49out = csv.writer(f, delimiter=',', quotechar='\"', quoting=csv.QUOTE_ALL)
50
51# Output a set of rows for a header providing general information
52out.writerow(['Source:', net.getSource()])
53out.writerow(['Date:', net.getDate()])
54out.writerow(['Tool:', net.getTool()])
55out.writerow( ['Generator:', sys.argv[0]] )
56out.writerow(['Component Count:', len(net.components)])
57out.writerow(['Ref', 'Qnty', 'Value', 'Cmp name', 'Footprint', 'Description', 'Vendor'])
58
59
60# Get all of the components in groups of matching parts + values
61# (see ky_generic_netlist_reader.py)
62grouped = net.groupComponents()
63
64# Output all of the component information
65for group in grouped:
66    refs = ""
67
68    # Add the reference of every component in the group and keep a reference
69    # to the component so that the other data can be filled in once per group
70    for component in group:
71        refs += fromNetlistText( component.getRef() ) + ", "
72        c = component
73
74    # Fill in the component groups common data
75    out.writerow([refs, len(group),
76        fromNetlistText( c.getValue() ),
77        fromNetlistText( c.getPartName() ),
78        fromNetlistText( c.getFootprint() ),
79        fromNetlistText( c.getDescription() ),
80        fromNetlistText( c.getField("Vendor") )])
81
82
83