Example #1
0
    def _read_netlist(self,netlist_path=None):
        self._netlist_path = self.find_netlist_path(netlist_path)
        if self._netlist_path is None:
            return None

        # Generate an instance of a generic netlist and load the netlist tree.
        self._netlist = kicad_netlist_reader.netlist(self._netlist_path)

        # subset the components to those wanted in the BOM, controlled
        # by <configure> block in kicad_netlist_reader.py
        components = self._netlist.getInterestingComponents()

        compfields = self._netlist.gatherComponentFieldUnion(components)
        compfields -= set(['PartCount'])
        partfields = self._netlist.gatherLibPartFieldUnion()
        partfields -= set(['Reference','Value','Datasheet','Footprint','PartCount'])

        additional_columns = compfields | partfields     # union

        self._column_names = ['Item','Reference(s)','Quantity']
        self._base_column_length = len(self._column_names)
        if 'PartNumber' in additional_columns:
            self._column_names.append('PartNumber')
        if 'Vendor' in additional_columns:
            self._column_names.append('Vendor')
        if 'Description' in additional_columns:
            self._column_names.append('Description')

        # Get all of the components in groups of matching parts + values
        # (see kicad_netlist_reader.py)
        self._grouped_components = self._netlist.groupComponents(components)
Example #2
0
# Import the KiCad python helper module and the csv formatter
import kicad_netlist_reader
import csv
import sys
import re


if len(sys.argv) != 4:
    print("Usage ", __file__, "<generic_netlist.xml> <output.csv> <quantity>", 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 = 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:
    e = "Can't open output file for writing: " + sys.argv[2]
    print(__file__, ":", e, file=sys.stderr)
    f = sys.stdout

quantity_multiplier = 1
if (int(sys.argv[3]) > 1):
    quantity_multiplier = int(sys.argv[3])

# subset the components to those wanted in the BOM, controlled
Example #3
0
def generate_boms():
    if len(sys.argv) != 2:
        print("Usage ", __file__, "<netlist.xml>", file=sys.stderr)
        sys.exit(1)

    input_path = sys.argv[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 = kicad_netlist_reader.netlist(input_path)

    # Open a file to write to, if the file cannot be opened output to stdout
    # instead
    try:
        output_dir = os.path.join(os.path.dirname(input_path),'bom')
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)
        output_path = os.path.join(output_dir,'bom_pcb.csv')
        # if os.path.exists(output_path):
        #     shutil.copyfile(output_path,output_path+'.bck')
        f = open(output_path, 'w')
    except IOError:
        e = "Can't open output file for writing: " + output_path
        print(__file__,":",e,sys.stderr)
        f = sys.stdout

    # subset the components to those wanted in the BOM, controlled
    # by <configure> block in kicad_netlist_reader.py
    components = net.getInterestingComponents()

    # Header providing general information
    # source = os.path.basename(net.getSource())
    # f.write('Source: ' + source + '\n')
    # f.write('Date: ' + str(net.getDate()) + '\n')
    # f.write('Tool: ' + str(net.getTool()) + '\n')
    # f.write('Component Count: ' + str(len(components)) + '\n')
    # f.write('\n')

    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','Reference(s)','Value','Footprint','Quantity'] + sorted(list(columnset))

    # Create a new csv writer object to use as the output formatter
    out = csv.writer(f,quotechar='\"',quoting=csv.QUOTE_MINIMAL )

    # override csv.writer's writerow() to support utf8 encoding:
    def writerow(acsvwriter,columns):
        utf8row = []
        for col in columns:
            utf8row.append(str(col).encode('utf8'))
        acsvwriter.writerow(utf8row)

    # Get all of the components in groups of matching parts + values
    # (see kicad_netlist_reader.py)
    grouped = net.groupComponents(components)


    # Output component information organized by group, aka as collated:
    row = []
    for c in columns:
        row.append(c)
    writerow(out,row)

    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:
            if len(refs) > 0:
                refs += " "
            refs += component.getRef()
            c = component

        # Fill in the component groups common data
        # columns = ['Item','Reference(s)','Value','Footprint','Quantity'] + sorted(list(columnset))
        item += 1
        row.append(item)
        row.append(refs);
        row.append(c.getValue())
        row.append(c.getFootprint())
        row.append(len(group))

        # from column 4 upwards, use the fieldnames to grab the data
        for field in columns[4:]:
            row.append( net.getGroupField(group, field) );

        writerow(out,row)

    f.close()

    # Create vendor set
    vendor_set = set()
    for group in grouped:
        try:
            vendor = net.getGroupField(group,'Vendor')
            vendor_set |= set([vendor])
        except:
            pass

    # Make order csv file for each vendor
    for vendor in vendor_set:
        # Open a file to write to, if the file cannot be opened output to stdout
        # instead
        try:
            output_dir = os.path.join(os.path.dirname(input_path),'bom')
            if not os.path.exists(output_dir):
                os.makedirs(output_dir)
            filename = str(vendor) + '_order_pcb.csv'
            output_path = os.path.join(output_dir,filename)
            f = open(output_path, 'w')
            # Create a new csv writer object to use as the output formatter
            out = csv.writer(f,quotechar='\"',quoting=csv.QUOTE_MINIMAL )
        except IOError:
            e = "Can't open output file for writing: " + output_path
            print(__file__,":",e,sys.stderr)
            f = sys.stdout

        for group in grouped:
            del row[:]
            try:
                if vendor == net.getGroupField(group,'Vendor'):
                    row.append(len(group))
                    row.append(net.getGroupField(group,'PartNumber'))
            except:
                pass

            writerow(out,row)

        f.close()
Example #4
0
        #print(other.getValue())
        #elif self.getField("Manufacturer") != other.getField("Manufacturer"):
        #    result = False
        '''elif self.getPartName() != other.getPartName():
        result = False
        print('\''+other.getPartName()+'\'')
        print('\''+self.getPartName()+'\'')'''

    return result


kicad_netlist_reader.comp.__eq__ = myEqu
#kicad_netlist_reader.netlist().excluded_values.append("TestPoint")
# 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 = kicad_netlist_reader.netlist(sys.argv[1])

components = net.getInterestingComponents()
grouped = net.groupComponents()

thin = Side(style='thin', color="000000")
thick = Side(style='thick', color="000000")
wb = Workbook()
worksheet = wb.active
worksheet.page_setup.orientation = worksheet.ORIENTATION_LANDSCAPE

title = NamedStyle(name="title")
title.font = Font(bold=True, size=14)
wb.add_named_style(title)

header = NamedStyle(name="header")
Example #5
0
try:
    f = open(args.output, 'w')
except IOError:
    e = "Can't open output file for writing: " + args.output
    print(__file__, ":", e, sys.stderr)
    f = sys.stdout

dates = []
tools = []
components = []
columnset = set()

for netlist_file in args.netlist:
    # 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 = kicad_netlist_reader.netlist(netlist_file)

    dates.append(net.getDate())
    tools.append(net.getTool())

    # subset the components to those wanted in the BOM, controlled
    # by <configure> block in kicad_netlist_reader.py
    components += net.getInterestingComponents()

    compfields = kicad_netlist_reader.netlist.gatherComponentFieldUnion(
        components)
    partfields = net.gatherLibPartFieldUnion()

    # remove Reference, Value, Datasheet, and Footprint, they will come from 'columns' below
    partfields -= set(['Reference', 'Value', 'Datasheet', 'Footprint'])
Example #6
0
# Set up the database connection
conn = sqlite3.connect(dbpath)
cur = conn.cursor()


# Get the default manufactuer from the database
defaultMfgr = getmfgr('M0000000')
if(defaultMfgr is None):
    defaultMfgr = 'Default MFG Error'



# 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 = kicad_netlist_reader.netlist(infile)

# Open a file to write to, if the file cannot be opened output to stdout
# instead
try:
    f = open(outfile, 'w')
except IOError:
    e = "Can't open output file for writing: " + outfile
    print( __file__, ":", e, sys.stderr )
    f = sys.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)
Example #7
0
infile = args.infile
outfile = args.outfile

# Set up the database connection
conn = sqlite3.connect(dbpath)
cur = conn.cursor()

# Get the default manufactuer from the database
defaultMfgr = getmfgr('M0000000')
if (defaultMfgr is None):
    defaultMfgr = 'Default MFG Error'

# 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 = kicad_netlist_reader.netlist(infile)

# Open a file to write to, if the file cannot be opened output to stdout
# instead
try:
    f = open(outfile, 'w')
except IOError:
    e = "Can't open output file for writing: " + outfile
    print(__file__, ":", e, sys.stderr)
    f = sys.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)
Example #8
0
def process(pcbfile, side=pcbnew.F_Cu, netlist=None, output=None):
    refs = None

    # load netlist
    if netlist is not None:
        net = kicad_netlist_reader.netlist(netlist)
        refs = [x.getRef() for x in net.getInterestingComponents()]

    # build BOM
    print("Loading %s" % pcbfile)
    pcb = pcbnew.LoadBoard(pcbfile)
    bom_table = generate_bom(pcb, filter_layer=side, filter_refs=refs)
    footprints = load_footprints(pcb, layer=side)
    board_xmin, board_ymin, board_width, board_height = get_bbox(pcb)
    margin = Point(5, 15)
    text_margin = Point(5, 2)

    # Render all components into a base surface for performance
    base = cairo.RecordingSurface(cairo.Content.COLOR_ALPHA, None)
    ctx = cairo.Context(base)

    # Render Footprints
    render_footprints(pcb, ctx, footprints, BASE_STYLE)

    # Show Board Edge for context
    ctx.set_source_rgb(0, 0, 0)
    ctx.set_line_width(0.25)
    ctx.rectangle(board_xmin, board_ymin, board_width, board_height)
    ctx.stroke()

    # for each part group, print page to PDF
    fname_out = output
    if output is None:
        sidename = "top" if side == pcbnew.F_Cu else "bottom"
        fname_out = os.path.splitext(
            pcbfile)[0] + "_place_" + sidename + ".pdf"

    with cairo.PDFSurface(fname_out, 72, 72) as pdf:
        for i, bom_row in enumerate(bom_table):
            print("Plotting page (%d/%d)" % (i + 1, len(bom_table)))
            pdf.set_size((board_width + 2 * margin.x) * POINTS_PER_MM,
                         (board_height + 2 * margin.y) * POINTS_PER_MM)
            ctx = pangocairo.CairoContext(cairo.Context(pdf))

            # Scale from points to mm
            ctx.scale(POINTS_PER_MM, POINTS_PER_MM)
            # Render Text
            render_text(
                ctx,
                text_margin.x,
                margin.y - text_margin.y,
                board_width + 2 * margin.x - 2 * text_margin.x,
                "%dx %s, %s" % (len(bom_row.refs), bom_row.value,
                                bom_row.footprint),
                align_bottom=True)
            render_text(
                ctx, text_margin.x, board_height + margin.y + text_margin.y,
                board_width + 2 * margin.x - 2 * text_margin.x, ", ".join(
                    bom_row.refs))

            # Offset within page for margins+header
            ctx.translate(margin.x, margin.y)
            # Set corner of board on kicad page to 0,0
            ctx.translate(-board_xmin, -board_ymin)
            ctx.set_source_surface(base, 0.0, 0.0)
            ctx.paint()
            render_footprints(
                pcb,
                ctx,
                footprints,
                HIGHLIGHT_STYLE,
                include_only=bom_row.refs)
            pdf.show_page()

    print("Output written to %s" % fname_out)