bom_html_by_value.py 4 KB
Newer Older
1 2 3 4 5 6 7
#
# Example python script to generate a BOM from a KiCad generic netlist
#
# Example: Sorted and Grouped HTML BOM with more advanced grouping
#

# Import the KiCad python helper module and the csv formatter
8
import ky_generic_netlist_reader
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
import sys

# Start with a basic html template
html = """
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>KiCad BOM Example 5</title>
    </head>
    <body>
    <h1><!--SOURCE--></h1>
    <p><!--DATE--></p>
    <p><!--TOOL--></p>
    <p><!--COMPCOUNT--></p>
    <table>
    <!--TABLEROW-->
    </table>
    </body>
</html>
    """

def myEqu(self, other):
33
    """myEqu is a more advanced equivalence function for components which is
34 35
    used by component grouping. Normal operation is to group components based
    on their Value, Library source, and Library part.
36 37

    In this example of a more advanced equivalency operator we also compare the
38
    custom fields Voltage, Tolerance and Manufacturer as well as the assigned
39
    footprint. If these fields are not used in some parts they will simply be
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
    ignored (they will match as both will be empty strings).

    """
    result = True
    if self.getValue() != other.getValue():
        result = False
    elif self.getLib() != other.getLib():
        result = False
    elif self.getPart() != other.getPart():
        result = False
    elif self.getFootprint() != other.getFootprint():
        result = False
    elif self.getField("Tolerance") != other.getField("Tolerance"):
        result = False
    elif self.getField("Manufacturer") != other.getField("Manufacturer"):
        result = False
    elif self.getField("Voltage") != other.getField("Voltage"):
57 58
        result = False

59 60 61 62 63
    return result

# Override the component equivalence operator - it is important to do this
# before loading the netlist, otherwise all components will have the original
# equivalency operator.
64 65
ky_generic_netlist_reader.component.__equ__ = myEqu

66
# Generate an instance of a generic netlist, and load the netlist tree from
67 68
# video.xml. If the file doesn't exist, execution will stop
net = ky_generic_netlist_reader.netlist(sys.argv[1])
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84

# 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
    f = stdout

# Output a set of rows for a header providing general information
html = html.replace('<!--SOURCE-->', net.getSource())
html = html.replace('<!--DATE-->', net.getDate())
html = html.replace('<!--TOOL-->', net.getTool())
html = html.replace('<!--COMPCOUNT-->', "<b>Component Count:</b>" + \
    str(len(net.components)))

85 86 87 88 89 90
row  = "<tr><th style='width:640px'>Ref</th>" + "<th>Qnty</th>"
row += "<th>Value</th>" + "<th>Part</th>"
row +=  "<th>Description</th>"
#row +=  "<th>Datasheet</th>"
row += "<th>PartNumber</th>" + "<th>Vendor</th></tr>"

91 92
html = html.replace('<!--TABLEROW-->', row + "<!--TABLEROW-->")

93 94
# Get all of the components in groups of matching parts + values
# (see ky_generic_netlist_reader.py)
95 96 97 98 99 100
grouped = net.groupComponents()

# Output all of the component information
for group in grouped:
    refs = ""

101
    # Add the reference of every component in the group and keep a reference
102 103 104 105 106
    # to the component so that the other data can be filled in once per group
    for component in group:
        refs += component.getRef() + ", "
        c = component

107 108 109 110 111 112 113
    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.getDatasheet() + "</td><td>"
    row += c.getDescription() + "</td><td>"
    row += c.getField("PartNumber") + "</td><td>"
    row += c.getField("Vendor")
114
    row += "</td></tr>"
115

116 117 118 119
    html = html.replace('<!--TABLEROW-->', row + "<!--TABLEROW-->")

# Print the formatted html to output file
print >> f, html