Internal BoM: `count_smd_tht` option to compute SMD/THT stats.

Closes #113
This commit is contained in:
Salvador E. Tropea 2021-11-22 14:34:07 -03:00
parent 4dcb289e73
commit 49ea1bb62a
17 changed files with 366 additions and 31 deletions

View File

@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Internal BoM: when a `Value` field can't be interpreted as a `number+unit`,
and it contain at least one space, now we try to use the text before the
space. This helps for cases like "10K 1%".
- Internal BoM: `count_smd_tht` option to compute SMD/THT stats. (#113)
- Generic filter: options to match if a field is/isn't defined.
- Excellon drill: added `route_mode_for_oval_holes` option.
- Default global `dir` option.

View File

@ -689,6 +689,7 @@ Next time you need this list just use an alias, like this:
- `join`: [list(string)|string=''] List of fields to join to this column.
- `level`: [number=0] Used to group columns. The XLSX output uses it to collapse columns.
- `name`: [string=''] Name to display in the header. The field is used when empty.
- `count_smd_tht`: [boolean=false] Show the stats about how many of the components are SMD/THT. You must provide the PCB.
- `csv`: [dict] Options for the CSV, TXT and TSV formats.
* Valid keys:
- `hide_pcb_info`: [boolean=false] Hide project information.

View File

@ -99,6 +99,8 @@ outputs:
level: 0
# [string=''] Name to display in the header. The field is used when empty
name: 'Line'
# [boolean=false] Show the stats about how many of the components are SMD/THT. You must provide the PCB
count_smd_tht: false
# [dict] Options for the CSV, TXT and TSV formats
csv:
# [boolean=false] Hide project information

View File

@ -244,6 +244,12 @@ class ComponentGroup(object):
# compare_components ensures all has the same status
return self.components[0].fixed
def is_smd(self):
return self.components[0].smd
def is_tht(self):
return self.components[0].tht
def get_field(self, field):
field = field.lower()
if field not in self.fields or not self.fields[field]:
@ -378,8 +384,8 @@ def normalize_value(c, decimal_point):
def compute_multiple_stats(cfg, groups):
for sch in cfg.aggregate:
sch.comp_total = 0
sch.comp_fitted = 0
sch.comp_total = sch.comp_total_smd = sch.comp_total_tht = 0
sch.comp_fitted = sch.comp_fitted_smd = sch.comp_fitted_tht = 0
sch.comp_build = 0
sch.comp_groups = 0
for g in groups:
@ -387,8 +393,16 @@ def compute_multiple_stats(cfg, groups):
if g_l:
sch.comp_groups = sch.comp_groups+1
sch.comp_total += g_l
if g.is_smd():
sch.comp_total_smd += g_l
if g.is_tht():
sch.comp_total_tht += g_l
if g.is_fitted():
sch.comp_fitted += g_l
if g.is_smd():
sch.comp_fitted_smd += g_l
if g.is_tht():
sch.comp_fitted_tht += g_l
sch.comp_build = sch.comp_fitted*sch.number
if cfg.debug_level > 1:
logger.debug('Stats for {}: total {} fitted {} build {}'.
@ -442,8 +456,8 @@ def group_components(cfg, components):
# First priority is the Type of component (e.g. R?, U?, L?)
groups = sorted(groups, key=lambda g: [g.components[0].ref_prefix, get_value_sort(g.components[0])])
# Enumerate the groups and compute stats
n_total = 0
n_fitted = 0
n_total = n_total_smd = n_total_tht = 0
n_fitted = n_fitted_smd = n_fitted_tht = 0
n_build = 0
c = 1
dnf = 1
@ -459,11 +473,19 @@ def group_components(cfg, components):
# Stats
g_l = g.get_count()
n_total += g_l
n_total_smd += g_l*g.is_smd()
n_total_tht += g_l*g.is_tht()
if is_fitted:
n_fitted += g_l
n_fitted_smd += g_l*g.is_smd()
n_fitted_tht += g_l*g.is_tht()
n_build += g.total
cfg.n_total = n_total
cfg.n_total_smd = n_total_smd
cfg.n_total_tht = n_total_tht
cfg.n_fitted = n_fitted
cfg.n_fitted_smd = n_fitted_smd
cfg.n_fitted_tht = n_fitted_tht
cfg.n_build = n_build
if cfg.debug_level > 1:
logger.debug('Global stats: total {} fitted {} build {}'.format(n_total, n_fitted, n_build))
@ -473,6 +495,12 @@ def group_components(cfg, components):
return groups
def smd_tht(cfg, tot, smd, tht):
if cfg.count_smd_tht:
return "{} ({} SMD/ {} THT)".format(tot, smd, tht)
return tot
def do_bom(file_name, ext, comps, cfg):
# Group components according to group_fields
groups = group_components(cfg, comps)
@ -480,5 +508,13 @@ def do_bom(file_name, ext, comps, cfg):
logger.debug("Saving BOM File: "+file_name)
number = cfg.number
cfg.number = sum(map(lambda prj: prj.number, cfg.aggregate))
# Pre-format the total and fitted strings
cfg.total_str = smd_tht(cfg, cfg.n_total, cfg.n_total_smd, cfg.n_total_tht)
cfg.fitted_str = smd_tht(cfg, cfg.n_fitted, cfg.n_fitted_smd, cfg.n_fitted_tht)
if len(cfg.aggregate) > 1:
for prj in cfg.aggregate:
prj.total_str = smd_tht(cfg, prj.comp_total, prj.comp_total_smd, prj.comp_total_tht)
prj.fitted_str = smd_tht(cfg, prj.comp_fitted, prj.comp_fitted_smd, prj.comp_fitted_tht)
# Create the BoM
write_bom(file_name, ext, groups, cfg.columns, cfg)
cfg.number = number

View File

@ -25,8 +25,8 @@ def write_stats(writer, cfg):
if not cfg.csv.hide_stats_info:
writer.writerow(["Statistics:"])
writer.writerow(["Component Groups:", cfg.n_groups])
writer.writerow(["Component Count:", cfg.n_total])
writer.writerow(["Fitted Components:", cfg.n_fitted])
writer.writerow(["Component Count:", cfg.total_str])
writer.writerow(["Fitted Components:", cfg.fitted_str])
writer.writerow(["Number of PCBs:", cfg.number])
writer.writerow(["Total Components:", cfg.n_build])
else:
@ -39,8 +39,8 @@ def write_stats(writer, cfg):
if not cfg.csv.hide_stats_info:
writer.writerow(["Global statistics:"])
writer.writerow(["Component Groups:", cfg.n_groups])
writer.writerow(["Component Count:", cfg.n_total])
writer.writerow(["Fitted Components:", cfg.n_fitted])
writer.writerow(["Component Count:", cfg.total_str])
writer.writerow(["Fitted Components:", cfg.fitted_str])
writer.writerow(["Number of PCBs:", cfg.number])
writer.writerow(["Total Components:", cfg.n_build])
# Individual stats
@ -57,8 +57,8 @@ def write_stats(writer, cfg):
if not cfg.csv.hide_stats_info:
writer.writerow(["Statistics:", prj.sch.title])
writer.writerow(["Component Groups:", prj.comp_groups])
writer.writerow(["Component Count:", prj.comp_total])
writer.writerow(["Fitted Components:", prj.comp_fitted])
writer.writerow(["Component Count:", prj.total_str])
writer.writerow(["Fitted Components:", prj.fitted_str])
writer.writerow(["Number of PCBs:", prj.number])
writer.writerow(["Total Components:", prj.comp_build])

View File

@ -291,8 +291,8 @@ def write_stats(html, cfg):
html.write(' <td class="cell-stats">\n')
if not cfg.html.hide_stats_info:
html.write(" <b>Component Groups</b>: {}<br>\n".format(cfg.n_groups))
html.write(" <b>Component Count</b>: {} (per PCB)<br>\n\n".format(cfg.n_total))
html.write(" <b>Fitted Components</b>: {} (per PCB)<br>\n".format(cfg.n_fitted))
html.write(" <b>Component Count</b>: {} (per PCB)<br>\n\n".format(cfg.total_str))
html.write(" <b>Fitted Components</b>: {} (per PCB)<br>\n".format(cfg.fitted_str))
html.write(" <b>Number of PCBs</b>: {}<br>\n".format(cfg.number))
html.write(" <b>Total Components</b>: {t} (for {n} PCBs)<br>\n".format(n=cfg.number, t=cfg.n_build))
html.write(' </td>\n')
@ -309,8 +309,8 @@ def write_stats(html, cfg):
html.write(' <td class="cell-stats">\n')
if not cfg.html.hide_stats_info:
html.write(" <b>Component Groups</b>: {}<br>\n".format(cfg.n_groups))
html.write(" <b>Component Count</b>: {} (per PCB)<br>\n\n".format(cfg.n_total))
html.write(" <b>Fitted Components</b>: {} (per PCB)<br>\n".format(cfg.n_fitted))
html.write(" <b>Component Count</b>: {} (per PCB)<br>\n\n".format(cfg.total_str))
html.write(" <b>Fitted Components</b>: {} (per PCB)<br>\n".format(cfg.fitted_str))
html.write(" <b>Number of PCBs</b>: {}<br>\n".format(cfg.number))
html.write(" <b>Total Components</b>: {t} (for {n} PCBs)<br>\n".format(n=cfg.number, t=cfg.n_build))
html.write(' </td>\n')
@ -336,8 +336,8 @@ def write_stats(html, cfg):
html.write(' <td class="cell-stats">\n')
if not cfg.html.hide_stats_info:
html.write(" <b>Component Groups</b>: {}<br>\n".format(prj.comp_groups))
html.write(" <b>Component Count</b>: {} (per PCB)<br>\n\n".format(prj.comp_total))
html.write(" <b>Fitted Components</b>: {} (per PCB)<br>\n".format(prj.comp_fitted))
html.write(" <b>Component Count</b>: {} (per PCB)<br>\n\n".format(prj.total_str))
html.write(" <b>Fitted Components</b>: {} (per PCB)<br>\n".format(prj.fitted_str))
html.write(" <b>Number of PCBs</b>: {}<br>\n".format(prj.number))
html.write(" <b>Total Components</b>: {t} (for {n} PCBs)<br>\n".format(n=prj.number, t=prj.comp_build))
html.write(' </td>\n')

View File

@ -281,8 +281,8 @@ def write_info(cfg, r_info_start, worksheet, column_widths, col1, fmt_info, fmt_
rc = r_info_start
if not cfg.xlsx.hide_stats_info:
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Component Groups:", cfg.n_groups)
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Component Count:", cfg.n_total)
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Fitted Components:", cfg.n_fitted)
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Component Count:", cfg.total_str)
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Fitted Components:", cfg.fitted_str)
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Number of PCBs:", cfg.number)
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Total Components:", cfg.n_build)
else:
@ -297,8 +297,8 @@ def write_info(cfg, r_info_start, worksheet, column_widths, col1, fmt_info, fmt_
rc = r_info_start
if not cfg.xlsx.hide_stats_info:
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Component Groups:", cfg.n_groups)
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Component Count:", cfg.n_total)
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Fitted Components:", cfg.n_fitted)
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Component Count:", cfg.total_str)
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Fitted Components:", cfg.fitted_str)
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Number of PCBs:", cfg.number)
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Total Components:", cfg.n_build)
# Individual stats
@ -322,8 +322,8 @@ def write_info(cfg, r_info_start, worksheet, column_widths, col1, fmt_info, fmt_
rc = r_info_start
if not cfg.xlsx.hide_stats_info:
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Component Groups:", prj.comp_groups)
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Component Count:", prj.comp_total)
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Fitted Components:", prj.comp_fitted)
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Component Count:", prj.total_str)
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Fitted Components:", prj.fitted_str)
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Number of PCBs:", prj.number)
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Total Components:", prj.comp_build)
r_info_start += 5

View File

@ -26,8 +26,8 @@ def write_xml(filename, groups, headings, head_names, cfg):
attrib['PCB_Variant'] = cfg.variant.name
attrib['KiCad_Version'] = cfg.kicad_version
attrib['Component_Groups'] = str(cfg.n_groups)
attrib['Component_Count'] = str(cfg.n_total)
attrib['Fitted_Components'] = str(cfg.n_fitted)
attrib['Component_Count'] = str(cfg.total_str)
attrib['Fitted_Components'] = str(cfg.fitted_str)
attrib['Number_of_PCBs'] = str(cfg.number)
attrib['Total_Components'] = str(cfg.n_build)
if len(cfg.aggregate) == 1:
@ -42,8 +42,8 @@ def write_xml(filename, groups, headings, head_names, cfg):
attrib['Schematic{}_Date'.format(n)] = prj.sch.date
attrib['Schematic{}_ID'.format(n)] = prj.ref_id
attrib['Component_Groups{}'.format(n)] = str(prj.comp_groups)
attrib['Component_Count{}'.format(n)] = str(prj.comp_total)
attrib['Fitted_Components{}'.format(n)] = str(prj.comp_fitted)
attrib['Component_Count{}'.format(n)] = str(prj.total_str)
attrib['Fitted_Components{}'.format(n)] = str(prj.fitted_str)
attrib['Number_of_PCBs{}'.format(n)] = str(prj.number)
attrib['Total_Components{}'.format(n)] = str(prj.comp_build)
xml = ElementTree.Element('KiCad_BOM', attrib=attrib, encoding='utf-8')

View File

@ -206,6 +206,7 @@ W_UNKOUT = '(W067) '
W_NOFILTERS = '(W068) '
W_NOVARIANTS = '(W069) '
W_NOENDLIB = '(W070) '
W_NEEDSPCB = '(W071) '
class Rect(object):

View File

@ -9,7 +9,7 @@ This is somehow compatible with KiBoM.
"""
import os
from .gs import GS
from .misc import W_BADFIELD
from .misc import W_BADFIELD, W_NEEDSPCB
from .optionable import Optionable, BaseOptions
from .registrable import RegOutput
from .error import KiPlotConfigurationError
@ -309,6 +309,8 @@ class BoMOptions(BaseOptions):
""" [string|list(string)] Include this distributors list. Default is all the available """
self.no_distributors = Optionable
""" [string|list(string)] Exclude this distributors list. They are removed after computing `distributors` """
self.count_smd_tht = False
""" Show the stats about how many of the components are SMD/THT. You must provide the PCB """
self._format_example = 'CSV'
super().__init__()
@ -509,6 +511,9 @@ class BoMOptions(BaseOptions):
# Get the components list from the schematic
comps = GS.sch.get_components()
get_board_comps_data(comps)
if self.count_smd_tht and not GS.pcb_file:
logger.warning(W_NEEDSPCB+"`count_smd_tht` is enabled, but no PCB provided")
self.count_smd_tht = False
# Apply the reference prefix
for c in comps:
c.ref = self.ref_id+c.ref

View File

@ -0,0 +1,282 @@
(kicad_pcb (version 20171130) (host pcbnew 5.1.9+dfsg1-1)
(general
(thickness 1.6)
(drawings 4)
(tracks 15)
(zones 0)
(modules 4)
(nets 4)
)
(page A4)
(layers
(0 F.Cu signal)
(31 B.Cu signal)
(32 B.Adhes user)
(33 F.Adhes user)
(34 B.Paste user)
(35 F.Paste user)
(36 B.SilkS user)
(37 F.SilkS user)
(38 B.Mask user)
(39 F.Mask user)
(40 Dwgs.User user)
(41 Cmts.User user)
(42 Eco1.User user)
(43 Eco2.User user)
(44 Edge.Cuts user)
(45 Margin user)
(46 B.CrtYd user)
(47 F.CrtYd user)
(48 B.Fab user)
(49 F.Fab user)
)
(setup
(last_trace_width 0.25)
(trace_clearance 0.2)
(zone_clearance 0.508)
(zone_45_only no)
(trace_min 0.2)
(via_size 0.8)
(via_drill 0.4)
(via_min_size 0.4)
(via_min_drill 0.3)
(uvia_size 0.3)
(uvia_drill 0.1)
(uvias_allowed no)
(uvia_min_size 0.2)
(uvia_min_drill 0.1)
(edge_width 0.1)
(segment_width 0.2)
(pcb_text_width 0.3)
(pcb_text_size 1.5 1.5)
(mod_edge_width 0.15)
(mod_text_size 1 1)
(mod_text_width 0.15)
(pad_size 1.524 1.524)
(pad_drill 0.762)
(pad_to_mask_clearance 0)
(aux_axis_origin 0 0)
(visible_elements FFFFFF7F)
(pcbplotparams
(layerselection 0x010fc_ffffffff)
(usegerberextensions false)
(usegerberattributes true)
(usegerberadvancedattributes true)
(creategerberjobfile true)
(excludeedgelayer true)
(linewidth 0.100000)
(plotframeref false)
(viasonmask false)
(mode 1)
(useauxorigin false)
(hpglpennumber 1)
(hpglpenspeed 20)
(hpglpendiameter 15.000000)
(psnegative false)
(psa4output false)
(plotreference true)
(plotvalue true)
(plotinvisibletext false)
(padsonsilk false)
(subtractmaskfromsilk false)
(outputformat 1)
(mirror false)
(drillshape 1)
(scaleselection 1)
(outputdirectory ""))
)
(net 0 "")
(net 1 "Net-(C1-Pad2)")
(net 2 "Net-(C1-Pad1)")
(net 3 "Net-(J1-Pad1)")
(net_class Default "Esta es la clase de red por defecto."
(clearance 0.2)
(trace_width 0.25)
(via_dia 0.8)
(via_drill 0.4)
(uvia_dia 0.3)
(uvia_drill 0.1)
(add_net "Net-(C1-Pad1)")
(add_net "Net-(C1-Pad2)")
(add_net "Net-(J1-Pad1)")
)
(module Resistor_SMD:R_0805_2012Metric (layer F.Cu) (tedit 5F68FEEE) (tstamp 619BCC07)
(at 137.9909 96.11672)
(descr "Resistor SMD 0805 (2012 Metric), square (rectangular) end terminal, IPC_7351 nominal, (Body size source: IPC-SM-782 page 72, https://www.pcb-3d.com/wordpress/wp-content/uploads/ipc-sm-782a_amendment_1_and_2.pdf), generated with kicad-footprint-generator")
(tags resistor)
(path /5F10F746)
(attr smd)
(fp_text reference R1 (at 0 -1.65) (layer F.SilkS)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_text value 1k (at 0 1.65) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_line (start 1.68 0.95) (end -1.68 0.95) (layer F.CrtYd) (width 0.05))
(fp_line (start 1.68 -0.95) (end 1.68 0.95) (layer F.CrtYd) (width 0.05))
(fp_line (start -1.68 -0.95) (end 1.68 -0.95) (layer F.CrtYd) (width 0.05))
(fp_line (start -1.68 0.95) (end -1.68 -0.95) (layer F.CrtYd) (width 0.05))
(fp_line (start -0.227064 0.735) (end 0.227064 0.735) (layer F.SilkS) (width 0.12))
(fp_line (start -0.227064 -0.735) (end 0.227064 -0.735) (layer F.SilkS) (width 0.12))
(fp_line (start 1 0.625) (end -1 0.625) (layer F.Fab) (width 0.1))
(fp_line (start 1 -0.625) (end 1 0.625) (layer F.Fab) (width 0.1))
(fp_line (start -1 -0.625) (end 1 -0.625) (layer F.Fab) (width 0.1))
(fp_line (start -1 0.625) (end -1 -0.625) (layer F.Fab) (width 0.1))
(fp_text user %R (at 0 0) (layer F.Fab)
(effects (font (size 0.5 0.5) (thickness 0.08)))
)
(pad 1 smd roundrect (at -0.9125 0) (size 1.025 1.4) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.243902)
(net 2 "Net-(C1-Pad1)"))
(pad 2 smd roundrect (at 0.9125 0) (size 1.025 1.4) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.243902)
(net 3 "Net-(J1-Pad1)"))
(model ${KISYS3DMOD}/Resistor_SMD.3dshapes/R_0805_2012Metric.wrl
(at (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)
(module Connector_PinHeader_2.54mm:PinHeader_1x02_P2.54mm_Vertical (layer F.Cu) (tedit 59FED5CC) (tstamp 619BCBF6)
(at 133.4609 93.95672)
(descr "Through hole straight pin header, 1x02, 2.54mm pitch, single row")
(tags "Through hole pin header THT 1x02 2.54mm single row")
(path /5F10E81F)
(fp_text reference J2 (at 0 -2.33) (layer F.SilkS)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_text value "Molex KK" (at 0 4.87) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_line (start 1.8 -1.8) (end -1.8 -1.8) (layer F.CrtYd) (width 0.05))
(fp_line (start 1.8 4.35) (end 1.8 -1.8) (layer F.CrtYd) (width 0.05))
(fp_line (start -1.8 4.35) (end 1.8 4.35) (layer F.CrtYd) (width 0.05))
(fp_line (start -1.8 -1.8) (end -1.8 4.35) (layer F.CrtYd) (width 0.05))
(fp_line (start -1.33 -1.33) (end 0 -1.33) (layer F.SilkS) (width 0.12))
(fp_line (start -1.33 0) (end -1.33 -1.33) (layer F.SilkS) (width 0.12))
(fp_line (start -1.33 1.27) (end 1.33 1.27) (layer F.SilkS) (width 0.12))
(fp_line (start 1.33 1.27) (end 1.33 3.87) (layer F.SilkS) (width 0.12))
(fp_line (start -1.33 1.27) (end -1.33 3.87) (layer F.SilkS) (width 0.12))
(fp_line (start -1.33 3.87) (end 1.33 3.87) (layer F.SilkS) (width 0.12))
(fp_line (start -1.27 -0.635) (end -0.635 -1.27) (layer F.Fab) (width 0.1))
(fp_line (start -1.27 3.81) (end -1.27 -0.635) (layer F.Fab) (width 0.1))
(fp_line (start 1.27 3.81) (end -1.27 3.81) (layer F.Fab) (width 0.1))
(fp_line (start 1.27 -1.27) (end 1.27 3.81) (layer F.Fab) (width 0.1))
(fp_line (start -0.635 -1.27) (end 1.27 -1.27) (layer F.Fab) (width 0.1))
(fp_text user %R (at 0 1.27 90) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(pad 1 thru_hole rect (at 0 0) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 2 "Net-(C1-Pad1)"))
(pad 2 thru_hole oval (at 0 2.54) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 1 "Net-(C1-Pad2)"))
(model ${KISYS3DMOD}/Connector_PinHeader_2.54mm.3dshapes/PinHeader_1x02_P2.54mm_Vertical.wrl
(at (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)
(module Connector_PinHeader_2.54mm:PinHeader_1x02_P2.54mm_Vertical (layer F.Cu) (tedit 59FED5CC) (tstamp 619BCCDC)
(at 142.80388 96.47174 180)
(descr "Through hole straight pin header, 1x02, 2.54mm pitch, single row")
(tags "Through hole pin header THT 1x02 2.54mm single row")
(path /5F10E435)
(fp_text reference J1 (at 0 -2.33) (layer F.SilkS)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_text value "Molex KK ñoño" (at 0 4.87) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_line (start 1.8 -1.8) (end -1.8 -1.8) (layer F.CrtYd) (width 0.05))
(fp_line (start 1.8 4.35) (end 1.8 -1.8) (layer F.CrtYd) (width 0.05))
(fp_line (start -1.8 4.35) (end 1.8 4.35) (layer F.CrtYd) (width 0.05))
(fp_line (start -1.8 -1.8) (end -1.8 4.35) (layer F.CrtYd) (width 0.05))
(fp_line (start -1.33 -1.33) (end 0 -1.33) (layer F.SilkS) (width 0.12))
(fp_line (start -1.33 0) (end -1.33 -1.33) (layer F.SilkS) (width 0.12))
(fp_line (start -1.33 1.27) (end 1.33 1.27) (layer F.SilkS) (width 0.12))
(fp_line (start 1.33 1.27) (end 1.33 3.87) (layer F.SilkS) (width 0.12))
(fp_line (start -1.33 1.27) (end -1.33 3.87) (layer F.SilkS) (width 0.12))
(fp_line (start -1.33 3.87) (end 1.33 3.87) (layer F.SilkS) (width 0.12))
(fp_line (start -1.27 -0.635) (end -0.635 -1.27) (layer F.Fab) (width 0.1))
(fp_line (start -1.27 3.81) (end -1.27 -0.635) (layer F.Fab) (width 0.1))
(fp_line (start 1.27 3.81) (end -1.27 3.81) (layer F.Fab) (width 0.1))
(fp_line (start 1.27 -1.27) (end 1.27 3.81) (layer F.Fab) (width 0.1))
(fp_line (start -0.635 -1.27) (end 1.27 -1.27) (layer F.Fab) (width 0.1))
(fp_text user %R (at 0 1.27 90) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(pad 1 thru_hole rect (at 0 0 180) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 3 "Net-(J1-Pad1)"))
(pad 2 thru_hole oval (at 0 2.54 180) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 1 "Net-(C1-Pad2)"))
(model ${KISYS3DMOD}/Connector_PinHeader_2.54mm.3dshapes/PinHeader_1x02_P2.54mm_Vertical.wrl
(at (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)
(module Capacitor_SMD:C_0805_2012Metric (layer F.Cu) (tedit 5F68FEEE) (tstamp 619BCBCA)
(at 138 93)
(descr "Capacitor SMD 0805 (2012 Metric), square (rectangular) end terminal, IPC_7351 nominal, (Body size source: IPC-SM-782 page 76, https://www.pcb-3d.com/wordpress/wp-content/uploads/ipc-sm-782a_amendment_1_and_2.pdf, https://docs.google.com/spreadsheets/d/1BsfQQcO9C6DZCsRaXUlFlo91Tg2WpOkGARC1WS5S8t0/edit?usp=sharing), generated with kicad-footprint-generator")
(tags capacitor)
(path /5F10F92F)
(attr smd)
(fp_text reference C1 (at 0 -1.68) (layer F.SilkS)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_text value 1nF (at 0 1.68) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_line (start 1.7 0.98) (end -1.7 0.98) (layer F.CrtYd) (width 0.05))
(fp_line (start 1.7 -0.98) (end 1.7 0.98) (layer F.CrtYd) (width 0.05))
(fp_line (start -1.7 -0.98) (end 1.7 -0.98) (layer F.CrtYd) (width 0.05))
(fp_line (start -1.7 0.98) (end -1.7 -0.98) (layer F.CrtYd) (width 0.05))
(fp_line (start -0.261252 0.735) (end 0.261252 0.735) (layer F.SilkS) (width 0.12))
(fp_line (start -0.261252 -0.735) (end 0.261252 -0.735) (layer F.SilkS) (width 0.12))
(fp_line (start 1 0.625) (end -1 0.625) (layer F.Fab) (width 0.1))
(fp_line (start 1 -0.625) (end 1 0.625) (layer F.Fab) (width 0.1))
(fp_line (start -1 -0.625) (end 1 -0.625) (layer F.Fab) (width 0.1))
(fp_line (start -1 0.625) (end -1 -0.625) (layer F.Fab) (width 0.1))
(fp_text user %R (at 0 0) (layer F.Fab)
(effects (font (size 0.5 0.5) (thickness 0.08)))
)
(pad 1 smd roundrect (at -0.95 0) (size 1 1.45) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25)
(net 2 "Net-(C1-Pad1)"))
(pad 2 smd roundrect (at 0.95 0) (size 1 1.45) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25)
(net 1 "Net-(C1-Pad2)"))
(model ${KISYS3DMOD}/Capacitor_SMD.3dshapes/C_0805_2012Metric.wrl
(at (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)
(gr_line (start 131 100) (end 131 91) (layer Edge.Cuts) (width 0.1) (tstamp 619BCF98))
(gr_line (start 146 100) (end 131 100) (layer Edge.Cuts) (width 0.1))
(gr_line (start 146 91) (end 146 100) (layer Edge.Cuts) (width 0.1))
(gr_line (start 131 91) (end 146 91) (layer Edge.Cuts) (width 0.1))
(segment (start 133.4609 96.49672) (end 133.49672 96.49672) (width 0.25) (layer B.Cu) (net 1))
(segment (start 133.49672 96.49672) (end 136 99) (width 0.25) (layer B.Cu) (net 1))
(segment (start 136 99) (end 144 99) (width 0.25) (layer B.Cu) (net 1))
(segment (start 144 99) (end 145 98) (width 0.25) (layer B.Cu) (net 1))
(segment (start 145 98) (end 145 95) (width 0.25) (layer B.Cu) (net 1))
(segment (start 143.93174 93.93174) (end 142.80388 93.93174) (width 0.25) (layer B.Cu) (net 1))
(segment (start 145 95) (end 143.93174 93.93174) (width 0.25) (layer B.Cu) (net 1))
(segment (start 142.80388 93.93174) (end 139.93174 93.93174) (width 0.25) (layer B.Cu) (net 1))
(segment (start 139.93174 93.93174) (end 139 93) (width 0.25) (layer B.Cu) (net 1))
(segment (start 133.4609 93.95672) (end 135.04328 93.95672) (width 0.25) (layer B.Cu) (net 2))
(segment (start 135.04328 93.95672) (end 136 93) (width 0.25) (layer B.Cu) (net 2))
(segment (start 136 93) (end 137 93) (width 0.25) (layer B.Cu) (net 2))
(segment (start 137 93) (end 137 96) (width 0.25) (layer B.Cu) (net 2))
(segment (start 142.80388 96.47174) (end 139.47174 96.47174) (width 0.25) (layer B.Cu) (net 3))
(segment (start 139.47174 96.47174) (end 139 96) (width 0.25) (layer B.Cu) (net 3))
)

View File

@ -21,7 +21,7 @@ U 1 1 5F10E435
P 2850 2300
F 0 "J1" H 2750 2200 50 0000 C CNN
F 1 "Molex KK ñoño" H 2850 2100 50 0000 C CNN
F 2 "" H 2850 2300 50 0001 C CNN
F 2 "Connector_PinHeader_2.54mm:PinHeader_1x02_P2.54mm_Vertical" H 2850 2300 50 0001 C CNN
F 3 "https://www.molex.com/webdocs/datasheets/pdf/en-us//0022232021_PCB_HEADERS.pdf" H 2850 2300 50 0001 C CNN
F 4 "900-0022232021-ND" H 2850 2300 50 0001 C CNN "digikey#"
F 5 "0022232021" H 2850 2300 50 0001 C CNN "manf#"
@ -35,7 +35,7 @@ U 1 1 5F10E81F
P 4500 2300
F 0 "J2" H 4450 2200 50 0000 R CNN
F 1 "Molex KK" H 4700 2100 50 0000 R CNN
F 2 "" H 4500 2300 50 0001 C CNN
F 2 "Connector_PinHeader_2.54mm:PinHeader_1x02_P2.54mm_Vertical" H 4500 2300 50 0001 C CNN
F 3 "https://www.molex.com/webdocs/datasheets/pdf/en-us//0022232021_PCB_HEADERS.pdf" H 4500 2300 50 0001 C CNN
F 4 "900-0022232021-ND" H 4500 2300 50 0001 C CNN "digikey#"
F 5 "0022232021" H 4500 2300 50 0001 C CNN "manf#"
@ -49,7 +49,7 @@ U 1 1 5F10F746
P 3450 2300
F 0 "R1" V 3350 2300 50 0000 C CNN
F 1 "1k" V 3450 2300 50 0000 C CNN
F 2 "" V 3380 2300 50 0001 C CNN
F 2 "Resistor_SMD:R_0805_2012Metric" V 3380 2300 50 0001 C CNN
F 3 "https://www.bourns.com/docs/product-datasheets/CRxxxxx.pdf" H 3450 2300 50 0001 C CNN
F 4 "CR0805-JW-102ELFCT-ND" V 3450 2300 50 0001 C CNN "digikey#"
F 5 "CR0805-JW-102ELF" V 3450 2300 50 0001 C CNN "manf#"
@ -63,7 +63,7 @@ U 1 1 5F10F92F
P 3750 2500
F 0 "C1" H 3865 2546 50 0000 L CNN
F 1 "1nF" H 3865 2455 50 0000 L CNN
F 2 "" H 3788 2350 50 0001 C CNN
F 2 "Capacitor_SMD:C_0805_2012Metric" H 3788 2350 50 0001 C CNN
F 3 "https://content.kemet.com/datasheets/KEM_C1002_X7R_SMD.pdf" H 3750 2500 50 0001 C CNN
F 4 "399-1147-1-ND" H 3750 2500 50 0001 C CNN "digikey#"
F 5 "C0805C102K5RACTU" H 3750 2500 50 0001 C CNN "manf#"

View File

@ -86,11 +86,13 @@ KIBOM_TEST_COMPONENTS_ALT2 = ['C1-C4', 'R9', 'R10', 'R7', 'R8', 'R1', 'R2', 'R4'
KIBOM_TEST_EXCLUDE = ['R6']
KIBOM_TEST_GROUPS = 5
KIBOM_PRJ_INFO = ['kibom-test', 'default', 'A', '2020-03-12', None]
LINKS_PRJ_INFO = ['links', 'default', 'A', '2020-03-12', None]
KIBOM_STATS = [KIBOM_TEST_GROUPS+len(KIBOM_TEST_EXCLUDE),
len(KIBOM_TEST_COMPONENTS)+len(KIBOM_TEST_EXCLUDE),
len(KIBOM_TEST_COMPONENTS),
1,
len(KIBOM_TEST_COMPONENTS)]
LINKS_STATS = [3, '4 (2 SMD/ 2 THT)', '3 (1 SMD/ 2 THT)', 1, 3]
VARIANTE_PRJ_INFO = ['kibom-variante', 'default', 'A', '2020-03-12', None]
LINK_HEAD = ['References', 'Part', 'Value', 'Quantity Per PCB', 'digikey#', 'digikey_alt#', 'manf#']
LINKS_COMPONENTS = ['J1', 'J2', 'R1']
@ -774,6 +776,7 @@ def test_int_bom_column_rename_xlsx(test_dir):
assert header == KIBOM_RENAME_HEAD
ref_column = header.index(REF_COLUMN_NAME_R)
check_kibom_test_netlist(rows, ref_column, LINKS_GROUPS, LINKS_EXCLUDE, LINKS_COMPONENTS)
check_head_xlsx(sh_head, LINKS_PRJ_INFO, LINKS_STATS)
ctx.clean_up()

View File

@ -8,6 +8,7 @@ outputs:
type: bom
dir: BoM
options:
count_smd_tht: true
columns:
- field: Row
name: Renglón

View File

@ -9,6 +9,7 @@ outputs:
dir: BoM
options:
format: XLSX
count_smd_tht: true
columns:
- field: Row
name: Renglón

View File

@ -9,6 +9,7 @@ outputs:
dir: BoM
options:
format: XML
count_smd_tht: true
columns:
- field: Row
name: Renglón

View File

@ -11,6 +11,7 @@ outputs:
html:
datasheet_as_link: 'Part'
output: '%f.%x'
count_smd_tht: true
columns:
- References
- Part