[Global Options] Added field_lcsc_part: to select the LCSC/JLCPCB part field
This commit is contained in:
parent
ac14910505
commit
c39d21f3cf
|
|
@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Internal templates import
|
||||
- Better support for wrong pre-flight options (#360)
|
||||
- A mechanism to cache downloaded 3D models
|
||||
- Global options:
|
||||
- field_lcsc_part: to select the LCSC/JLCPCB part field
|
||||
- New outputs:
|
||||
- `vrml` export the 3D model in Virtual Reality Modeling Language (#349)
|
||||
- `ps_sch_print`, `dxf_sch_print` and `hpgl_sch_print` variants of
|
||||
|
|
|
|||
13
README.md
13
README.md
|
|
@ -790,6 +790,8 @@ global:
|
|||
This is because the plating reduces the hole, so you need to use a bigger drill.
|
||||
For more information consult: https://www.eurocircuits.com/pcb-design-guidelines/drilled-holes/.
|
||||
- `field_3D_model`: [string='_3D_model'] Name for the field controlling the 3D models used for a component.
|
||||
- `field_lcsc_part`: [string=''] The name of the schematic field that contains the part number for the LCSC/JLCPCB distributor.
|
||||
When empty KiBot will try to discover it.
|
||||
- `filters`: [list(dict)] KiBot warnings to be ignored.
|
||||
* Valid keys:
|
||||
- `error`: [string=''] Error id we want to exclude.
|
||||
|
|
@ -917,6 +919,7 @@ filters:
|
|||
Column names are case-insensitive.
|
||||
* Valid keys:
|
||||
- `column`: [string=''] Name of the column to apply the regular expression.
|
||||
Use `_field_lcsc_part` to get the value defined in the global options.
|
||||
- *field*: Alias for column.
|
||||
- `invert`: [boolean=false] Invert the regex match result.
|
||||
- `match_if_field`: [boolean=false] Match if the field exists, no regex applied. Not affected by `invert`.
|
||||
|
|
@ -942,6 +945,7 @@ filters:
|
|||
If empty this rule is ignored.
|
||||
* Valid keys:
|
||||
- `column`: [string=''] Name of the column to apply the regular expression.
|
||||
Use `_field_lcsc_part` to get the value defined in the global options.
|
||||
- *field*: Alias for column.
|
||||
- `invert`: [boolean=false] Invert the regex match result.
|
||||
- `match_if_field`: [boolean=false] Match if the field exists, no regex applied. Not affected by `invert`.
|
||||
|
|
@ -1732,6 +1736,7 @@ Notes:
|
|||
Can be just the name of the field.
|
||||
* Valid keys:
|
||||
- **`field`**: [string=''] Name of the field to use for this column.
|
||||
Use `_field_lcsc_part` to get the value defined in the global options.
|
||||
- **`name`**: [string=''] Name to display in the header. The field is used when empty.
|
||||
- `comment`: [string=''] Used as explanation for this column. The XLSX output uses it.
|
||||
- `join`: [list(dict)|list(string)|string=''] List of fields to join to this column.
|
||||
|
|
@ -1826,6 +1831,7 @@ Notes:
|
|||
'_power', '_current', '_voltage', '_frequency', '_temp_coeff', '_manf', '_size'.
|
||||
* Valid keys:
|
||||
- **`field`**: [string=''] Name of the field to use for this column.
|
||||
Use `_field_lcsc_part` to get the value defined in the global options.
|
||||
- **`name`**: [string=''] Name to display in the header. The field is used when empty.
|
||||
- `comment`: [string=''] Used as explanation for this column. The XLSX output uses it.
|
||||
- `join`: [list(dict)|list(string)|string=''] List of fields to join to this column.
|
||||
|
|
@ -1870,6 +1876,7 @@ Notes:
|
|||
Can be just the name of the field.
|
||||
* Valid keys:
|
||||
- **`field`**: [string=''] Name of the field to use for this column.
|
||||
Use `_field_lcsc_part` to get the value defined in the global options.
|
||||
- **`name`**: [string=''] Name to display in the header. The field is used when empty.
|
||||
- `comment`: [string=''] Used as explanation for this column. The XLSX output uses it.
|
||||
- `join`: [list(dict)|list(string)|string=''] List of fields to join to this column.
|
||||
|
|
@ -2723,6 +2730,7 @@ Notes:
|
|||
Can be just the name of the field.
|
||||
* Valid keys:
|
||||
- **`field`**: [string=''] Name of the field to use for this column.
|
||||
Use `_field_lcsc_part` to get the value defined in the global options.
|
||||
- **`name`**: [string=''] Name to display in the header. The field is used when empty.
|
||||
- `join`: [list(string)|string=''] List of fields to join to this column.
|
||||
- **`fit_field`**: [string='Config'] Field name used to determine if a particular part is to be fitted (also DNC and variants).
|
||||
|
|
@ -2766,6 +2774,7 @@ Notes:
|
|||
regex: 'fiducial'.
|
||||
* Valid keys:
|
||||
- `column`: [string=''] Name of the column to apply the regular expression.
|
||||
Use `_field_lcsc_part` to get the value defined in the global options.
|
||||
- *field*: Alias for column.
|
||||
- `regex`: [string=''] Regular expression to match.
|
||||
- *regexp*: Alias for regex.
|
||||
|
|
@ -2779,6 +2788,7 @@ Notes:
|
|||
If empty all the components are included.
|
||||
* Valid keys:
|
||||
- `column`: [string=''] Name of the column to apply the regular expression.
|
||||
Use `_field_lcsc_part` to get the value defined in the global options.
|
||||
- *field*: Alias for column.
|
||||
- `regex`: [string=''] Regular expression to match.
|
||||
- *regexp*: Alias for regex.
|
||||
|
|
@ -5093,7 +5103,8 @@ They include support for:
|
|||
- _FusionPCB_drill: Drill files
|
||||
- _FusionPCB_compress: Gerbers and drill files compressed in a ZIP
|
||||
- _FusionPCB: _FusionPCB_gerbers+_FusionPCB_drill
|
||||
- [JLCPCB](https://jlcpcb.com/): contain fabrication outputs compatible with JLC PCB
|
||||
- [JLCPCB](https://jlcpcb.com/): contain fabrication outputs compatible with JLC PCB.
|
||||
Use the `field_lcsc_part` global option to specify the LCSC part number field if KiBot fails to detect it.
|
||||
- _JLCPCB_gerbers: Gerbers.
|
||||
- _JLCPCB_drill: Drill files
|
||||
- _JLCPCB_position: Pick and place, applies the `_rot_footprint` filter. You can change this filter.
|
||||
|
|
|
|||
|
|
@ -1297,7 +1297,8 @@ They include support for:
|
|||
- _FusionPCB_drill: Drill files
|
||||
- _FusionPCB_compress: Gerbers and drill files compressed in a ZIP
|
||||
- _FusionPCB: _FusionPCB_gerbers+_FusionPCB_drill
|
||||
- [JLCPCB](https://jlcpcb.com/): contain fabrication outputs compatible with JLC PCB
|
||||
- [JLCPCB](https://jlcpcb.com/): contain fabrication outputs compatible with JLC PCB.
|
||||
Use the `field_lcsc_part` global option to specify the LCSC part number field if KiBot fails to detect it.
|
||||
- _JLCPCB_gerbers: Gerbers.
|
||||
- _JLCPCB_drill: Drill files
|
||||
- _JLCPCB_position: Pick and place, applies the `_rot_footprint` filter. You can change this filter.
|
||||
|
|
|
|||
|
|
@ -295,7 +295,8 @@ outputs:
|
|||
columns:
|
||||
# [string=''] Used as explanation for this column. The XLSX output uses it
|
||||
- comment: ''
|
||||
# [string=''] Name of the field to use for this column
|
||||
# [string=''] Name of the field to use for this column.
|
||||
# Use `_field_lcsc_part` to get the value defined in the global options
|
||||
field: 'Row'
|
||||
# [list(dict)|list(string)|string=''] List of fields to join to this column
|
||||
join:
|
||||
|
|
@ -333,7 +334,8 @@ outputs:
|
|||
cost_extra_columns:
|
||||
# [string=''] Used as explanation for this column. The XLSX output uses it
|
||||
- comment: ''
|
||||
# [string=''] Name of the field to use for this column
|
||||
# [string=''] Name of the field to use for this column.
|
||||
# Use `_field_lcsc_part` to get the value defined in the global options
|
||||
field: 'Row'
|
||||
# [list(dict)|list(string)|string=''] List of fields to join to this column
|
||||
join:
|
||||
|
|
@ -552,7 +554,8 @@ outputs:
|
|||
specs_columns:
|
||||
# [string=''] Used as explanation for this column. The XLSX output uses it
|
||||
- comment: ''
|
||||
# [string=''] Name of the field to use for this column
|
||||
# [string=''] Name of the field to use for this column.
|
||||
# Use `_field_lcsc_part` to get the value defined in the global options
|
||||
field: 'Row'
|
||||
# [list(dict)|list(string)|string=''] List of fields to join to this column
|
||||
join:
|
||||
|
|
@ -1295,7 +1298,8 @@ outputs:
|
|||
# [list(dict)|list(string)] List of columns to display.
|
||||
# Can be just the name of the field
|
||||
columns:
|
||||
# [string=''] Name of the field to use for this column
|
||||
# [string=''] Name of the field to use for this column.
|
||||
# Use `_field_lcsc_part` to get the value defined in the global options
|
||||
- field: 'Row'
|
||||
# [list(string)|string=''] List of fields to join to this column
|
||||
join: ''
|
||||
|
|
@ -1337,7 +1341,8 @@ outputs:
|
|||
# - column: Footprint
|
||||
# regex: 'fiducial'
|
||||
exclude_any:
|
||||
# [string=''] Name of the column to apply the regular expression
|
||||
# [string=''] Name of the column to apply the regular expression.
|
||||
# Use `_field_lcsc_part` to get the value defined in the global options
|
||||
- column: ''
|
||||
# `field` is an alias for `column`
|
||||
# [string=''] Regular expression to match
|
||||
|
|
@ -1365,7 +1370,8 @@ outputs:
|
|||
# Column names are case-insensitive.
|
||||
# If empty all the components are included
|
||||
include_only:
|
||||
# [string=''] Name of the column to apply the regular expression
|
||||
# [string=''] Name of the column to apply the regular expression.
|
||||
# Use `_field_lcsc_part` to get the value defined in the global options
|
||||
- column: ''
|
||||
# `field` is an alias for `column`
|
||||
# [string=''] Regular expression to match
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020 Salvador E. Tropea
|
||||
# Copyright (c) 2020 Instituto Nacional de Tecnología Industrial
|
||||
# Copyright (c) 2020-2023 Salvador E. Tropea
|
||||
# Copyright (c) 2020-2023 Instituto Nacional de Tecnología Industrial
|
||||
# License: GPL-3.0
|
||||
# Project: KiBot (formerly KiPlot)
|
||||
# Description: Implements the KiBoM and IBoM filters.
|
||||
|
|
@ -123,6 +123,7 @@ class Generic(BaseFilter): # noqa: F821
|
|||
if not self.include_only: # Nothing to match against, means include all
|
||||
return True
|
||||
for reg in self.include_only:
|
||||
reg.column = Optionable.solve_field_name(reg.column)
|
||||
if reg.skip_if_no_field and not c.is_field(reg.column):
|
||||
# Skip the check if the field doesn't exist
|
||||
continue
|
||||
|
|
@ -148,6 +149,7 @@ class Generic(BaseFilter): # noqa: F821
|
|||
if not self.exclude_any: # Nothing to match against, means don't exclude any
|
||||
return False
|
||||
for reg in self.exclude_any:
|
||||
reg.column = Optionable.solve_field_name(reg.column)
|
||||
if reg.skip_if_no_field and not c.is_field(reg.column):
|
||||
# Skip the check if the field doesn't exist
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -240,6 +240,9 @@ class Globals(FiltersOptions):
|
|||
more precedence than KiCad paths defined in the GUI.
|
||||
You can make reference to any OS environment variable using ${VARIABLE}.
|
||||
The KIPRJMOD is also available for expansion """
|
||||
self.field_lcsc_part = ''
|
||||
""" The name of the schematic field that contains the part number for the LCSC/JLCPCB distributor.
|
||||
When empty KiBot will try to discover it """
|
||||
self.set_doc('filters', " [list(dict)] KiBot warnings to be ignored ")
|
||||
self._filter_what = 'KiBot warnings'
|
||||
self.filters = FilterOptionsKiBot
|
||||
|
|
|
|||
|
|
@ -119,10 +119,11 @@ class GS(object):
|
|||
global_edge_plating = None
|
||||
global_extra_pth_drill = None
|
||||
global_field_3D_model = None
|
||||
global_field_lcsc_part = None
|
||||
global_hide_excluded = None
|
||||
global_impedance_controlled = None
|
||||
global_kiauto_time_out_scale = None
|
||||
global_kiauto_wait_start = None
|
||||
global_impedance_controlled = None
|
||||
# This value will overwrite GS.def_global_output if defined
|
||||
# Classes supporting global "output" option must call super().__init__()
|
||||
# after defining its own options to allow Optionable do the overwrite.
|
||||
|
|
|
|||
|
|
@ -128,6 +128,8 @@ DNC = {
|
|||
# KiCost distributors
|
||||
DISTRIBUTORS = ['arrow', 'digikey', 'farnell', 'lcsc', 'mouser', 'newark', 'rs', 'tme']
|
||||
DISTRIBUTORS_F = [d+'#' for d in DISTRIBUTORS]
|
||||
DISTRIBUTORS_STUBS = ['part#', '#', 'p#', 'pn', 'vendor#', 'vp#', 'vpn', 'num']
|
||||
DISTRIBUTORS_STUBS_SEPS = '_- '
|
||||
# ISO ISO4217 currency codes
|
||||
# Not all, but the ones we get from the European Central Bank (march 2021)
|
||||
ISO_CURRENCIES = {'EUR', 'USD', 'JPY', 'BGN', 'CZK', 'DKK', 'GBP', 'HUF', 'PLN', 'RON', 'SEK', 'CHF', 'ISK', 'NOK', 'HRK',
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import re
|
|||
from re import compile
|
||||
from .error import KiPlotConfigurationError
|
||||
from .gs import GS
|
||||
from .misc import W_UNKOPS
|
||||
from .misc import W_UNKOPS, DISTRIBUTORS_STUBS, DISTRIBUTORS_STUBS_SEPS
|
||||
from . import log
|
||||
|
||||
logger = log.get_logger()
|
||||
|
|
@ -468,6 +468,67 @@ class Optionable(object):
|
|||
def color_str_to_rgb(self, color):
|
||||
return self.color_to_rgb(self.parse_one_color(color))
|
||||
|
||||
@staticmethod
|
||||
def _solve_field_name(field, empty_when_none):
|
||||
""" Applies special replacements for field """
|
||||
# The global name for the LCSC part field
|
||||
if GS.global_field_lcsc_part:
|
||||
logger.debug('- User selected: '+GS.global_field_lcsc_part)
|
||||
return GS.global_field_lcsc_part
|
||||
# No name defined, try to figure out
|
||||
if not GS.sch and GS.sch_file:
|
||||
GS.load_sch()
|
||||
if not GS.sch:
|
||||
logger.debug("- No schematic loaded, can't search the name")
|
||||
return '' if empty_when_none else 'LCSC#'
|
||||
if hasattr(GS.sch, '_field_lcsc_part'):
|
||||
return GS.sch._field_lcsc_part
|
||||
# Look for a common name
|
||||
fields = {f.lower() for f in GS.sch.get_field_names([])}
|
||||
for stub in DISTRIBUTORS_STUBS:
|
||||
fld = 'lcsc'+stub
|
||||
if fld in fields:
|
||||
GS.sch._field_lcsc_part = fld
|
||||
return fld
|
||||
if stub != '#':
|
||||
for sep in DISTRIBUTORS_STUBS_SEPS:
|
||||
fld = 'lcsc'+sep+stub
|
||||
if fld in fields:
|
||||
GS.sch._field_lcsc_part = fld
|
||||
return fld
|
||||
if 'lcsc' in fields:
|
||||
GS.sch._field_lcsc_part = 'LCSC'
|
||||
return 'LCSC'
|
||||
# Look for a field that only contains LCSC codes
|
||||
comps = GS.sch.get_components()
|
||||
lcsc_re = re.compile(r'C\d+')
|
||||
for f in fields:
|
||||
found = False
|
||||
for c in comps:
|
||||
val = c.get_field_value(f).strip()
|
||||
if not val:
|
||||
continue
|
||||
if lcsc_re.match(val):
|
||||
found = True
|
||||
else:
|
||||
break
|
||||
if found:
|
||||
GS.sch._field_lcsc_part = f
|
||||
return f
|
||||
logger.debug('- No LCSC field found')
|
||||
res = '' if empty_when_none else 'LCSC#'
|
||||
GS.sch._field_lcsc_part = res
|
||||
return res
|
||||
|
||||
@staticmethod
|
||||
def solve_field_name(field, empty_when_none=False):
|
||||
if field != '_field_lcsc_part':
|
||||
return field
|
||||
logger.debug('Looking for LCSC field name')
|
||||
field = Optionable._solve_field_name(field, empty_when_none)
|
||||
logger.debug('Using {} as LCSC field name'.format(field))
|
||||
return field
|
||||
|
||||
|
||||
class BaseOptions(Optionable):
|
||||
""" A class to validate and hold output options.
|
||||
|
|
|
|||
|
|
@ -199,7 +199,8 @@ class BoMRegex(Optionable):
|
|||
self._unkown_is_error = True
|
||||
with document:
|
||||
self.column = ''
|
||||
""" Name of the column to apply the regular expression """
|
||||
""" Name of the column to apply the regular expression.
|
||||
Use `_field_lcsc_part` to get the value defined in the global options """
|
||||
self.regex = ''
|
||||
""" Regular expression to match """
|
||||
self.field = None
|
||||
|
|
@ -215,6 +216,11 @@ class BoMRegex(Optionable):
|
|||
self.invert = False
|
||||
""" Invert the regex match result """
|
||||
|
||||
def config(self, parent):
|
||||
super().config(parent)
|
||||
if not self.column:
|
||||
raise KiPlotConfigurationError("Missing or empty `column` in field regex ({})".format(str(self._tree)))
|
||||
|
||||
|
||||
class VariantOptions(BaseOptions):
|
||||
""" BaseOptions plus generic support for variants. """
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020-2022 Salvador E. Tropea
|
||||
# Copyright (c) 2020-2022 Instituto Nacional de Tecnología Industrial
|
||||
# Copyright (c) 2020-2023 Salvador E. Tropea
|
||||
# Copyright (c) 2020-2023 Instituto Nacional de Tecnología Industrial
|
||||
# License: MIT
|
||||
# Project: KiBot (formerly KiPlot)
|
||||
"""
|
||||
|
|
@ -22,7 +22,7 @@ from copy import deepcopy
|
|||
import os
|
||||
import re
|
||||
from .gs import GS
|
||||
from .misc import W_BADFIELD, W_NEEDSPCB, DISTRIBUTORS, W_NOPART, W_MISSREF
|
||||
from .misc import W_BADFIELD, W_NEEDSPCB, DISTRIBUTORS, W_NOPART, W_MISSREF, DISTRIBUTORS_STUBS, DISTRIBUTORS_STUBS_SEPS
|
||||
from .optionable import Optionable, BaseOptions
|
||||
from .registrable import RegOutput
|
||||
from .error import KiPlotConfigurationError
|
||||
|
|
@ -137,7 +137,8 @@ class BoMColumns(Optionable):
|
|||
self._unkown_is_error = True
|
||||
with document:
|
||||
self.field = ''
|
||||
""" *Name of the field to use for this column """
|
||||
""" *Name of the field to use for this column.
|
||||
Use `_field_lcsc_part` to get the value defined in the global options """
|
||||
self.name = ''
|
||||
""" *Name to display in the header. The field is used when empty """
|
||||
self.join = BoMJoinField
|
||||
|
|
@ -153,9 +154,10 @@ class BoMColumns(Optionable):
|
|||
super().config(parent)
|
||||
if not self.field:
|
||||
raise KiPlotConfigurationError("Missing or empty `field` in columns list ({})".format(str(self._tree)))
|
||||
self.field = self.solve_field_name(self.field)
|
||||
field = self.field.lower()
|
||||
# Ensure this is None or a list
|
||||
# Also arrange it as field, cols...
|
||||
field = self.field.lower()
|
||||
if isinstance(self.join, type):
|
||||
self.join = None
|
||||
elif isinstance(self.join, str):
|
||||
|
|
@ -1030,12 +1032,12 @@ class BoM(BaseOutput): # noqa: F821
|
|||
mpn_fields = fld_set.intersection(mpn_set)
|
||||
# Look for distributor part number
|
||||
dpn_set = set()
|
||||
for stub in ['part#', '#', 'p#', 'pn', 'vendor#', 'vp#', 'vpn', 'num']:
|
||||
for stub in DISTRIBUTORS_STUBS:
|
||||
for dist in DISTRIBUTORS:
|
||||
dpn_set.add(dist+stub)
|
||||
if stub != '#':
|
||||
dpn_set.add(dist+'_'+stub)
|
||||
dpn_set.add(dist+'-'+stub)
|
||||
for sep in DISTRIBUTORS_STUBS_SEPS:
|
||||
dpn_set.add(dist+sep+stub)
|
||||
dpn_fields = fld_set.intersection(dpn_set)
|
||||
# Collect the used distributors
|
||||
dists = set()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020 Salvador E. Tropea
|
||||
# Copyright (c) 2020 Instituto Nacional de Tecnología Industrial
|
||||
# Copyright (c) 2020-2023 Salvador E. Tropea
|
||||
# Copyright (c) 2020-2023 Instituto Nacional de Tecnología Industrial
|
||||
# Copyright (c) 2018 John Beard
|
||||
# License: GPL-3.0
|
||||
# Project: KiBot (formerly KiPlot)
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
import os
|
||||
from pcbnew import (PLOT_FORMAT_GERBER, FromMM, ToMM)
|
||||
from .gs import GS
|
||||
from .optionable import Optionable
|
||||
from .out_any_layer import (AnyLayer, AnyLayerOptions)
|
||||
from .error import KiPlotConfigurationError
|
||||
from .macros import macros, document, output_class # noqa: F401
|
||||
|
|
@ -122,6 +123,7 @@ class Gerber(AnyLayer):
|
|||
# Filter the list of layers using the ones we are interested on
|
||||
useful = GS.get_useful_layers(USEFUL_LAYERS, layers, include_copper=True)
|
||||
tpl_layers = [AnyLayer.layer2dict(la) for la in useful]
|
||||
lcsc_field = Optionable.solve_field_name('_field_lcsc_part', empty_when_none=True)
|
||||
# Add the list of layers to the templates
|
||||
for tpl in templates:
|
||||
outs_used = []
|
||||
|
|
@ -135,7 +137,7 @@ class Gerber(AnyLayer):
|
|||
skip = True
|
||||
out['run_by_default'] = False
|
||||
out['options'] = {'pre_transform': ['_kicost_rename', '_rot_footprint']}
|
||||
if out['type'] == 'bom' and not GS.sch_file:
|
||||
if out['type'] == 'bom' and (not GS.sch_file or (out['name'].startswith('JLCPCB') and not lcsc_field)):
|
||||
skip = True
|
||||
out['run_by_default'] = False
|
||||
if out['type'] == 'compress':
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ class KiBoMRegex(Optionable):
|
|||
self._unkown_is_error = True
|
||||
with document:
|
||||
self.column = ''
|
||||
""" Name of the column to apply the regular expression """
|
||||
""" Name of the column to apply the regular expression.
|
||||
Use `_field_lcsc_part` to get the value defined in the global options """
|
||||
self.regex = ''
|
||||
""" Regular expression to match """
|
||||
self.field = None
|
||||
|
|
@ -44,6 +45,12 @@ class KiBoMRegex(Optionable):
|
|||
""" {regex} """
|
||||
self._category = 'Schematic/BoM'
|
||||
|
||||
def config(self, parent):
|
||||
super().config(parent)
|
||||
if not self.column:
|
||||
raise KiPlotConfigurationError("Missing or empty `column` in regex ({})".format(str(self._tree)))
|
||||
self.column = Optionable.solve_field_name(self.column)
|
||||
|
||||
def __str__(self):
|
||||
return self.column+'\t'+self.regex
|
||||
|
||||
|
|
@ -55,7 +62,8 @@ class KiBoMColumns(Optionable):
|
|||
self._unkown_is_error = True
|
||||
with document:
|
||||
self.field = ''
|
||||
""" *Name of the field to use for this column """
|
||||
""" *Name of the field to use for this column.
|
||||
Use `_field_lcsc_part` to get the value defined in the global options """
|
||||
self.name = ''
|
||||
""" *Name to display in the header. The field is used when empty """
|
||||
self.join = Optionable
|
||||
|
|
@ -67,6 +75,7 @@ class KiBoMColumns(Optionable):
|
|||
super().config(parent)
|
||||
if not self.field:
|
||||
raise KiPlotConfigurationError("Missing or empty `field` in columns list ({})".format(str(self._tree)))
|
||||
self.column = Optionable.solve_field_name(self.column)
|
||||
if isinstance(self.join, type):
|
||||
self.join = None
|
||||
elif isinstance(self.join, list):
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ filters:
|
|||
comment: 'Only parts with JLC (LCSC) code'
|
||||
type: generic
|
||||
include_only:
|
||||
- column: 'LCSC#'
|
||||
- column: _field_lcsc_part
|
||||
regex: '^C\d+'
|
||||
|
||||
groups:
|
||||
|
|
@ -108,7 +108,7 @@ outputs:
|
|||
- field: References
|
||||
name: Designator
|
||||
- Footprint
|
||||
- field: 'LCSC#'
|
||||
- field: _field_lcsc_part
|
||||
name: 'LCSC Part #'
|
||||
csv:
|
||||
hide_pcb_info: true
|
||||
|
|
|
|||
|
|
@ -0,0 +1,131 @@
|
|||
(kicad_sch (version 20211123) (generator eeschema)
|
||||
|
||||
(uuid db0a65e7-fab8-4ee6-8724-c1011468bd27)
|
||||
|
||||
(paper "A4")
|
||||
|
||||
(lib_symbols
|
||||
(symbol "Device:R" (pin_numbers hide) (pin_names (offset 0)) (in_bom yes) (on_board yes)
|
||||
(property "Reference" "R" (id 0) (at 2.032 0 90)
|
||||
(effects (font (size 1.27 1.27)))
|
||||
)
|
||||
(property "Value" "R" (id 1) (at 0 0 90)
|
||||
(effects (font (size 1.27 1.27)))
|
||||
)
|
||||
(property "Footprint" "" (id 2) (at -1.778 0 90)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "Datasheet" "~" (id 3) (at 0 0 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "ki_keywords" "R res resistor" (id 4) (at 0 0 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "ki_description" "Resistor" (id 5) (at 0 0 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "ki_fp_filters" "R_*" (id 6) (at 0 0 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(symbol "R_0_1"
|
||||
(rectangle (start -1.016 -2.54) (end 1.016 2.54)
|
||||
(stroke (width 0.254) (type default) (color 0 0 0 0))
|
||||
(fill (type none))
|
||||
)
|
||||
)
|
||||
(symbol "R_1_1"
|
||||
(pin passive line (at 0 3.81 270) (length 1.27)
|
||||
(name "~" (effects (font (size 1.27 1.27))))
|
||||
(number "1" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin passive line (at 0 -3.81 90) (length 1.27)
|
||||
(name "~" (effects (font (size 1.27 1.27))))
|
||||
(number "2" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(symbol (lib_id "Device:R") (at 114.3 54.61 0) (unit 1)
|
||||
(in_bom yes) (on_board yes) (fields_autoplaced)
|
||||
(uuid 3ba877ba-6c15-4bf9-911a-bede4b8103e2)
|
||||
(property "Reference" "R2" (id 0) (at 116.078 53.7753 0)
|
||||
(effects (font (size 1.27 1.27)) (justify left))
|
||||
)
|
||||
(property "Value" "R" (id 1) (at 116.078 56.3122 0)
|
||||
(effects (font (size 1.27 1.27)) (justify left))
|
||||
)
|
||||
(property "Footprint" "" (id 2) (at 112.522 54.61 90)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "Datasheet" "~" (id 3) (at 114.3 54.61 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "LCSC_pn" "C1234" (id 4) (at 127 54.61 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(pin "1" (uuid 39c3be48-48be-4598-a62d-ee41b899e213))
|
||||
(pin "2" (uuid 1b30cb63-49b1-4ba7-b097-7ae72754941f))
|
||||
)
|
||||
|
||||
(symbol (lib_id "Device:R") (at 127 54.61 0) (unit 1)
|
||||
(in_bom yes) (on_board yes) (fields_autoplaced)
|
||||
(uuid 615091a6-0d61-4a51-9c02-509e158ea9d6)
|
||||
(property "Reference" "R3" (id 0) (at 128.778 53.7753 0)
|
||||
(effects (font (size 1.27 1.27)) (justify left))
|
||||
)
|
||||
(property "Value" "R" (id 1) (at 128.778 56.3122 0)
|
||||
(effects (font (size 1.27 1.27)) (justify left))
|
||||
)
|
||||
(property "Footprint" "" (id 2) (at 125.222 54.61 90)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "Datasheet" "~" (id 3) (at 127 54.61 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "LCSC_pn" "C1234" (id 4) (at 127 54.61 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(pin "1" (uuid 20f2f92a-ae98-4133-ba84-f5d7a9c977ae))
|
||||
(pin "2" (uuid e088d214-94d0-44a2-a744-aa518c868708))
|
||||
)
|
||||
|
||||
(symbol (lib_id "Device:R") (at 101.6 54.61 0) (unit 1)
|
||||
(in_bom yes) (on_board yes) (fields_autoplaced)
|
||||
(uuid d90f5601-6146-47ff-a6ef-b6f3da310882)
|
||||
(property "Reference" "R1" (id 0) (at 103.378 53.7753 0)
|
||||
(effects (font (size 1.27 1.27)) (justify left))
|
||||
)
|
||||
(property "Value" "R" (id 1) (at 103.378 56.3122 0)
|
||||
(effects (font (size 1.27 1.27)) (justify left))
|
||||
)
|
||||
(property "Footprint" "" (id 2) (at 99.822 54.61 90)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "Datasheet" "~" (id 3) (at 101.6 54.61 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "LCSC_pn" "C1234" (id 4) (at 127 54.61 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(pin "1" (uuid 672f8777-9560-4f26-bcf9-d47c285b54e6))
|
||||
(pin "2" (uuid b9f1a732-28ab-496c-93f7-3f99c9c56900))
|
||||
)
|
||||
|
||||
(sheet_instances
|
||||
(path "/" (page "1"))
|
||||
)
|
||||
|
||||
(symbol_instances
|
||||
(path "/d90f5601-6146-47ff-a6ef-b6f3da310882"
|
||||
(reference "R1") (unit 1) (value "R") (footprint "")
|
||||
)
|
||||
(path "/3ba877ba-6c15-4bf9-911a-bede4b8103e2"
|
||||
(reference "R2") (unit 1) (value "R") (footprint "")
|
||||
)
|
||||
(path "/615091a6-0d61-4a51-9c02-509e158ea9d6"
|
||||
(reference "R3") (unit 1) (value "R") (footprint "")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
(kicad_sch (version 20211123) (generator eeschema)
|
||||
|
||||
(uuid db0a65e7-fab8-4ee6-8724-c1011468bd27)
|
||||
|
||||
(paper "A4")
|
||||
|
||||
(lib_symbols
|
||||
(symbol "Device:R" (pin_numbers hide) (pin_names (offset 0)) (in_bom yes) (on_board yes)
|
||||
(property "Reference" "R" (id 0) (at 2.032 0 90)
|
||||
(effects (font (size 1.27 1.27)))
|
||||
)
|
||||
(property "Value" "R" (id 1) (at 0 0 90)
|
||||
(effects (font (size 1.27 1.27)))
|
||||
)
|
||||
(property "Footprint" "" (id 2) (at -1.778 0 90)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "Datasheet" "~" (id 3) (at 0 0 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "ki_keywords" "R res resistor" (id 4) (at 0 0 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "ki_description" "Resistor" (id 5) (at 0 0 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "ki_fp_filters" "R_*" (id 6) (at 0 0 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(symbol "R_0_1"
|
||||
(rectangle (start -1.016 -2.54) (end 1.016 2.54)
|
||||
(stroke (width 0.254) (type default) (color 0 0 0 0))
|
||||
(fill (type none))
|
||||
)
|
||||
)
|
||||
(symbol "R_1_1"
|
||||
(pin passive line (at 0 3.81 270) (length 1.27)
|
||||
(name "~" (effects (font (size 1.27 1.27))))
|
||||
(number "1" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin passive line (at 0 -3.81 90) (length 1.27)
|
||||
(name "~" (effects (font (size 1.27 1.27))))
|
||||
(number "2" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(symbol (lib_id "Device:R") (at 114.3 54.61 0) (unit 1)
|
||||
(in_bom yes) (on_board yes) (fields_autoplaced)
|
||||
(uuid 3ba877ba-6c15-4bf9-911a-bede4b8103e2)
|
||||
(property "Reference" "R2" (id 0) (at 116.078 53.7753 0)
|
||||
(effects (font (size 1.27 1.27)) (justify left))
|
||||
)
|
||||
(property "Value" "R" (id 1) (at 116.078 56.3122 0)
|
||||
(effects (font (size 1.27 1.27)) (justify left))
|
||||
)
|
||||
(property "Footprint" "" (id 2) (at 112.522 54.61 90)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "Datasheet" "~" (id 3) (at 114.3 54.61 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "Cryptic" "C1234" (id 4) (at 127 54.61 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(pin "1" (uuid 39c3be48-48be-4598-a62d-ee41b899e213))
|
||||
(pin "2" (uuid 1b30cb63-49b1-4ba7-b097-7ae72754941f))
|
||||
)
|
||||
|
||||
(symbol (lib_id "Device:R") (at 127 54.61 0) (unit 1)
|
||||
(in_bom yes) (on_board yes) (fields_autoplaced)
|
||||
(uuid 615091a6-0d61-4a51-9c02-509e158ea9d6)
|
||||
(property "Reference" "R3" (id 0) (at 128.778 53.7753 0)
|
||||
(effects (font (size 1.27 1.27)) (justify left))
|
||||
)
|
||||
(property "Value" "R" (id 1) (at 128.778 56.3122 0)
|
||||
(effects (font (size 1.27 1.27)) (justify left))
|
||||
)
|
||||
(property "Footprint" "" (id 2) (at 125.222 54.61 90)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "Datasheet" "~" (id 3) (at 127 54.61 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "Cryptic" "C1234" (id 4) (at 127 54.61 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(pin "1" (uuid 20f2f92a-ae98-4133-ba84-f5d7a9c977ae))
|
||||
(pin "2" (uuid e088d214-94d0-44a2-a744-aa518c868708))
|
||||
)
|
||||
|
||||
(symbol (lib_id "Device:R") (at 101.6 54.61 0) (unit 1)
|
||||
(in_bom yes) (on_board yes) (fields_autoplaced)
|
||||
(uuid d90f5601-6146-47ff-a6ef-b6f3da310882)
|
||||
(property "Reference" "R1" (id 0) (at 103.378 53.7753 0)
|
||||
(effects (font (size 1.27 1.27)) (justify left))
|
||||
)
|
||||
(property "Value" "R" (id 1) (at 103.378 56.3122 0)
|
||||
(effects (font (size 1.27 1.27)) (justify left))
|
||||
)
|
||||
(property "Footprint" "" (id 2) (at 99.822 54.61 90)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "Datasheet" "~" (id 3) (at 101.6 54.61 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "Cryptic" "C1234" (id 4) (at 127 54.61 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(pin "1" (uuid 672f8777-9560-4f26-bcf9-d47c285b54e6))
|
||||
(pin "2" (uuid b9f1a732-28ab-496c-93f7-3f99c9c56900))
|
||||
)
|
||||
|
||||
(sheet_instances
|
||||
(path "/" (page "1"))
|
||||
)
|
||||
|
||||
(symbol_instances
|
||||
(path "/d90f5601-6146-47ff-a6ef-b6f3da310882"
|
||||
(reference "R1") (unit 1) (value "R") (footprint "")
|
||||
)
|
||||
(path "/3ba877ba-6c15-4bf9-911a-bede4b8103e2"
|
||||
(reference "R2") (unit 1) (value "R") (footprint "")
|
||||
)
|
||||
(path "/615091a6-0d61-4a51-9c02-509e158ea9d6"
|
||||
(reference "R3") (unit 1) (value "R") (footprint "")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
@ -1559,3 +1559,34 @@ def test_sub_pcb_bp(test_dir):
|
|||
ctx.expect_out_file(fname_b+'charger.kicad_pcb')
|
||||
ctx.expect_out_file(fname_b+'connector.kicad_pcb')
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
@pytest.mark.skipif(context.ki5(), reason="Needs porting")
|
||||
def test_lcsc_field_known(test_dir):
|
||||
""" Test we can detect a known LCSC field name """
|
||||
prj = 'lcsc_field_known'
|
||||
ctx = context.TestContextSCH(test_dir, prj, 'lcsc_field_detect', 'JLCPCB')
|
||||
ctx.run(extra=['_JLCPCB_bom'])
|
||||
r, _, _ = ctx.load_csv(prj+'_bom_jlc.csv')
|
||||
assert r[0][3] == 'C1234'
|
||||
|
||||
|
||||
@pytest.mark.skipif(context.ki5(), reason="Needs porting")
|
||||
def test_lcsc_field_unknown(test_dir):
|
||||
""" Test we can detect an unknown LCSC field name """
|
||||
prj = 'lcsc_field_unknown'
|
||||
ctx = context.TestContextSCH(test_dir, prj, 'lcsc_field_detect', 'JLCPCB')
|
||||
ctx.run(extra=['_JLCPCB_bom'])
|
||||
r, _, _ = ctx.load_csv(prj+'_bom_jlc.csv')
|
||||
assert r[0][3] == 'C1234'
|
||||
|
||||
|
||||
@pytest.mark.skipif(context.ki5(), reason="Needs porting")
|
||||
def test_lcsc_field_specified(test_dir):
|
||||
""" Test we select the field """
|
||||
prj = 'lcsc_field_unknown'
|
||||
ctx = context.TestContextSCH(test_dir, prj, 'lcsc_field_specified', 'JLCPCB')
|
||||
ctx.run(extra=['_JLCPCB_bom'])
|
||||
assert ctx.search_err('User selected.*Cryptic')
|
||||
r, _, _ = ctx.load_csv(prj+'_bom_jlc.csv')
|
||||
assert r[0][3] == 'C1234'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
# Example KiBot config file
|
||||
kibot:
|
||||
version: 1
|
||||
|
||||
import:
|
||||
- file: JLCPCB
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# Example KiBot config file
|
||||
kibot:
|
||||
version: 1
|
||||
|
||||
global:
|
||||
field_lcsc_part: Cryptic
|
||||
|
||||
import:
|
||||
- file: JLCPCB
|
||||
Loading…
Reference in New Issue