Added field rename filter.
Including an internal version to emulate KiCost behavior.
This commit is contained in:
parent
cc77ba9204
commit
01291ebe63
|
|
@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- `erc_warnings` pre-flight option to consider ERC warnings as errors.
|
||||
- Pattern expansion in the `dir` option for outputs (#58)
|
||||
- New filter type `suparts`. Adds support for KiCost's subparts feature.
|
||||
- New filter type `field_rename`. Used to rename schematic fields.
|
||||
|
||||
### Changed
|
||||
- Errors and warnings from KiAuto now are printed as errors and warnings.
|
||||
|
|
|
|||
14
README.md
14
README.md
|
|
@ -276,6 +276,16 @@ Currently the only type available is `generic`.
|
|||
|
||||
#### Supported filters:
|
||||
|
||||
- field_rename: Field_Rename
|
||||
This filter implements a field renamer.
|
||||
The internal `_kicost_rename` filter emulates the KiCost behavior.
|
||||
* Valid keys:
|
||||
- `comment`: [string=''] A comment for documentation purposes.
|
||||
- `name`: [string=''] Used to identify this particular filter definition.
|
||||
- `rename`: [list(dict)] Fields to rename.
|
||||
* Valid keys:
|
||||
- `field`: [string=''] Name of the field to rename.
|
||||
- `name`: [string=''] New name.
|
||||
- generic: Generic filter
|
||||
This filter is based on regular expressions.
|
||||
It also provides some shortcuts for common situations.
|
||||
|
|
@ -320,7 +330,8 @@ Currently the only type available is `generic`.
|
|||
- `name`: [string=''] Used to identify this particular filter definition.
|
||||
- rot_footprint: Rot_Footprint
|
||||
This filter can rotate footprints, used for the positions file generation.
|
||||
Some manufacturers use a different rotation than KiCad..
|
||||
Some manufacturers use a different rotation than KiCad.
|
||||
The internal `_rot_footprint` filter implements the simplest case.
|
||||
* Valid keys:
|
||||
- `comment`: [string=''] A comment for documentation purposes.
|
||||
- `extend`: [boolean=true] Extends the internal list of rotations with the one provided.
|
||||
|
|
@ -347,6 +358,7 @@ Currently the only type available is `generic`.
|
|||
- `split_fields`: [list(string)] List of fields to split, usually the distributors part numbers.
|
||||
- `split_fields_expand`: [boolean=false] When `true` the fields in `split_fields` are added to the internal names.
|
||||
- `use_ref_sep_for_first`: [boolean=true] Force the reference separator use even for the first component in the list (KiCost behavior).
|
||||
- `value_alt_field`: [string='value_subparts'] Field containing replacements for the `Value` field. So we get real values for splitted parts.
|
||||
- var_rename: Var_Rename
|
||||
This filter implements the VARIANT:FIELD=VALUE renamer to get FIELD=VALUE when VARIANT is in use.
|
||||
* Valid keys:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
all: ../README.md samples/generic_plot.kibot.yaml
|
||||
|
||||
../README.md: README.in replace_tags.pl ../kibot/out_*.py ../kibot/pre_*.py ../kibot/__main__.py ../kibot/config_reader.py
|
||||
../README.md: README.in replace_tags.pl ../kibot/out_*.py ../kibot/pre_*.py ../kibot/fil_*.py ../kibot/__main__.py ../kibot/config_reader.py
|
||||
cat README.in | perl replace_tags.pl > ../README.md
|
||||
|
||||
samples/generic_plot.kibot.yaml: ../kibot/out_*.py ../kibot/pre_*.py ../kibot/config_reader.py
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
# License: GPL-3.0
|
||||
# Project: KiBot (formerly KiPlot)
|
||||
from .registrable import RegFilter, Registrable, RegOutput
|
||||
from .misc import IFILT_MECHANICAL, IFILT_VAR_RENAME, IFILT_ROT_FOOTPRINT
|
||||
from .misc import IFILT_MECHANICAL, IFILT_VAR_RENAME, IFILT_ROT_FOOTPRINT, IFILT_KICOST_RENAME, DISTRIBUTORS
|
||||
from .error import KiPlotConfigurationError
|
||||
from .bom.columnlist import ColumnList
|
||||
from .macros import macros, document # noqa: F401
|
||||
|
|
@ -21,6 +21,41 @@ DEFAULT_EXCLUDE = [{'column': ColumnList.COL_REFERENCE, 'regex': '^TP[0-9]*'},
|
|||
{'column': ColumnList.COL_FP, 'regex': 'mount.*hole'},
|
||||
{'column': ColumnList.COL_FP, 'regex': 'fiducial'},
|
||||
]
|
||||
KICOST_NAME_TRANSLATIONS = {
|
||||
# Manufacturer part number
|
||||
'mpn': 'manf#',
|
||||
'pn': 'manf#',
|
||||
'manf_num': 'manf#',
|
||||
'manf-num': 'manf#',
|
||||
'mfg_num': 'manf#',
|
||||
'mfg-num': 'manf#',
|
||||
'mfg#': 'manf#',
|
||||
'mfg part#': 'manf#',
|
||||
'man_num': 'manf#',
|
||||
'man-num': 'manf#',
|
||||
'man#': 'manf#',
|
||||
'mnf_num': 'manf#',
|
||||
'mnf-num': 'manf#',
|
||||
'mnf#': 'manf#',
|
||||
'mfr_num': 'manf#',
|
||||
'mfr-num': 'manf#',
|
||||
'mfr#': 'manf#',
|
||||
'part-num': 'manf#',
|
||||
'part_num': 'manf#',
|
||||
'p#': 'manf#',
|
||||
'part#': 'manf#',
|
||||
# Manufacturer
|
||||
'manufacturer': 'manf',
|
||||
'mnf': 'manf',
|
||||
'man': 'manf',
|
||||
'mfg': 'manf',
|
||||
'mfr': 'manf',
|
||||
# Various
|
||||
'version': 'variant',
|
||||
'nopop': 'dnp',
|
||||
'description': 'desc',
|
||||
'pdf': 'datasheet',
|
||||
}
|
||||
|
||||
|
||||
class DummyFilter(Registrable):
|
||||
|
|
@ -214,6 +249,25 @@ class BaseFilter(RegFilter):
|
|||
logger.debug('Creating internal filter: '+str(o_tree))
|
||||
return o_tree
|
||||
|
||||
@staticmethod
|
||||
def _create_kicost_rename(name):
|
||||
o_tree = {'name': name}
|
||||
o_tree['type'] = 'field_rename'
|
||||
o_tree['comment'] = 'Internal filter to emulate KiCost field aliases'
|
||||
rename = []
|
||||
for k, v in KICOST_NAME_TRANSLATIONS.items():
|
||||
rename.append({'field': k, 'name': v})
|
||||
for stub in ['part#', '#', 'p#', 'pn', 'vendor#', 'vp#', 'vpn', 'num']:
|
||||
for dist in DISTRIBUTORS:
|
||||
base = dist[:-1]
|
||||
if stub != '#':
|
||||
rename.append({'field': base + stub, 'name': dist})
|
||||
rename.append({'field': base + '_' + stub, 'name': dist})
|
||||
rename.append({'field': base + '-' + stub, 'name': dist})
|
||||
o_tree['rename'] = rename
|
||||
logger.debug('Creating internal filter: '+str(o_tree))
|
||||
return o_tree
|
||||
|
||||
@staticmethod
|
||||
def _create_internal_filter(name):
|
||||
if name == IFILT_MECHANICAL:
|
||||
|
|
@ -224,6 +278,8 @@ class BaseFilter(RegFilter):
|
|||
tree = BaseFilter._create_var_rename(name)
|
||||
elif name == IFILT_ROT_FOOTPRINT:
|
||||
tree = BaseFilter._create_rot_footprint(name)
|
||||
elif name == IFILT_KICOST_RENAME:
|
||||
tree = BaseFilter._create_kicost_rename(name)
|
||||
else:
|
||||
return None
|
||||
filter = RegFilter.get_class_for(tree['type'])()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2021 Salvador E. Tropea
|
||||
# Copyright (c) 2021 Instituto Nacional de Tecnología Industrial
|
||||
# License: GPL-3.0
|
||||
# Project: KiBot (formerly KiPlot)
|
||||
"""
|
||||
Implements a field renamer
|
||||
"""
|
||||
from .optionable import Optionable
|
||||
from .error import KiPlotConfigurationError
|
||||
from .gs import GS
|
||||
from .misc import W_EMPTYREN
|
||||
from .macros import macros, document, filter_class # noqa: F401
|
||||
from . import log
|
||||
|
||||
logger = log.get_logger(__name__)
|
||||
|
||||
|
||||
class FieldRename(Optionable):
|
||||
""" Field translation """
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._unkown_is_error = True
|
||||
with document:
|
||||
self.field = ''
|
||||
""" Name of the field to rename """
|
||||
self.name = ''
|
||||
""" New name """
|
||||
self._field_example = 'mpn'
|
||||
self._name_example = 'manf#'
|
||||
|
||||
def config(self, parent):
|
||||
super().config(parent)
|
||||
if not self.field:
|
||||
raise KiPlotConfigurationError("Missing or empty `field` in rename list ({})".format(str(self._tree)))
|
||||
if not self.name:
|
||||
raise KiPlotConfigurationError("Missing or empty `name` in rename list ({})".format(str(self._tree)))
|
||||
self.field = self.field.lower()
|
||||
|
||||
|
||||
@filter_class
|
||||
class Field_Rename(BaseFilter): # noqa: F821
|
||||
""" Field_Rename
|
||||
This filter implements a field renamer.
|
||||
The internal `_kicost_rename` filter emulates the KiCost behavior """
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._is_transform = True
|
||||
with document:
|
||||
self.rename = FieldRename
|
||||
""" [list(dict)] Fields to rename """
|
||||
|
||||
def config(self, parent):
|
||||
super().config(parent)
|
||||
if isinstance(self.rename, type):
|
||||
self.rename = []
|
||||
if not self.rename:
|
||||
logger.warning(W_EMPTYREN+'Nothing to rename in filter `{}`'.format(self.name))
|
||||
self.rename = {f.field: f.name for f in self.rename}
|
||||
|
||||
def filter(self, comp):
|
||||
""" Change the names of the specified fields """
|
||||
for f in set(comp.get_field_names()).intersection(self.rename):
|
||||
new_name = self.rename[f]
|
||||
if GS.debug_level > 2:
|
||||
logger.debug('ref: {} field: {} -> {}'.format(comp.ref, f, new_name))
|
||||
comp.rename_field(f, new_name)
|
||||
|
|
@ -51,7 +51,8 @@ DEFAULT_ROTATIONS = [["^R_Array_Convex_", 90.0],
|
|||
class Rot_Footprint(BaseFilter): # noqa: F821
|
||||
""" Rot_Footprint
|
||||
This filter can rotate footprints, used for the positions file generation.
|
||||
Some manufacturers use a different rotation than KiCad. """
|
||||
Some manufacturers use a different rotation than KiCad.
|
||||
The internal `_rot_footprint` filter implements the simplest case """
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._is_transform = True
|
||||
|
|
|
|||
|
|
@ -12,13 +12,12 @@ import re
|
|||
from copy import deepcopy
|
||||
from .gs import GS
|
||||
from .optionable import Optionable
|
||||
from .misc import W_NUMSUBPARTS, W_PARTMULT
|
||||
from .misc import W_NUMSUBPARTS, W_PARTMULT, DISTRIBUTORS
|
||||
from .macros import macros, document, filter_class # noqa: F401
|
||||
from . import log
|
||||
|
||||
|
||||
logger = log.get_logger(__name__)
|
||||
DISTRIBUTORS = ['digikey#', 'farnell#', 'mouser#', 'newark#', 'rs#', 'arrow#', 'tme#', 'lcsc#']
|
||||
|
||||
|
||||
class DistributorsList(Optionable):
|
||||
|
|
|
|||
|
|
@ -859,8 +859,9 @@ class SchematicComponent(object):
|
|||
f.number = self.get_free_field_number()
|
||||
self.add_field(f)
|
||||
|
||||
# def get_field_names(self):
|
||||
# return [f.name for f in self.fields]
|
||||
def get_field_names(self):
|
||||
""" List of all the available field names for this component """
|
||||
return self.dfields.keys()
|
||||
|
||||
def get_user_fields(self):
|
||||
""" Returns a list of tuples with the user defined fields (name, value) """
|
||||
|
|
@ -870,6 +871,13 @@ class SchematicComponent(object):
|
|||
self.fields.append(field)
|
||||
self.dfields[field.name.lower()] = field
|
||||
|
||||
def rename_field(self, old_name, new_name):
|
||||
old_name = old_name.lower()
|
||||
field = self.dfields[old_name]
|
||||
field.name = new_name
|
||||
del self.dfields[old_name]
|
||||
self.dfields[new_name.lower()] = field
|
||||
|
||||
def back_up_fields(self):
|
||||
""" First call makes a back-up of the fields.
|
||||
Next calls restores the back-up. """
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ KICAD_VERSION_5_99 = 5099000
|
|||
IFILT_MECHANICAL = '_mechanical'
|
||||
IFILT_VAR_RENAME = '_var_rename'
|
||||
IFILT_ROT_FOOTPRINT = '_rot_footprint'
|
||||
IFILT_KICOST_RENAME = '_kicost_rename'
|
||||
# KiCad 5 GUI values for the attribute
|
||||
UI_THT = 0 # 1 for KiCad 6
|
||||
UI_SMD = 1 # 2 for KiCad 6
|
||||
|
|
@ -117,6 +118,9 @@ DNC = {
|
|||
"no change",
|
||||
"fixed",
|
||||
}
|
||||
# KiCost distributors
|
||||
DISTRIBUTORS = ['digikey#', 'farnell#', 'mouser#', 'newark#', 'rs#', 'arrow#', 'tme#', 'lcsc#']
|
||||
|
||||
|
||||
W_VARCFG = '(W001) '
|
||||
W_VARPCB = '(W002) '
|
||||
|
|
@ -178,6 +182,8 @@ W_NOTASCII = '(W057) '
|
|||
W_KIAUTO = '(W058) '
|
||||
W_NUMSUBPARTS = '(W059) '
|
||||
W_PARTMULT = '(W060) '
|
||||
W_EMPTYREN = '(W061) '
|
||||
W_BADFIELD = '(W062) '
|
||||
|
||||
|
||||
class Rect(object):
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ This is somehow compatible with KiBoM.
|
|||
"""
|
||||
import os
|
||||
from .gs import GS
|
||||
from .misc import W_BADFIELD
|
||||
from .optionable import Optionable, BaseOptions
|
||||
from .registrable import RegOutput
|
||||
from .error import KiPlotConfigurationError
|
||||
|
|
@ -428,7 +429,9 @@ class BoMOptions(BaseOptions):
|
|||
self.join.append(col.join)
|
||||
# Check this is a valid column
|
||||
if new_col.lower() not in valid_columns_l:
|
||||
raise KiPlotConfigurationError('Invalid column name `{}`'.format(new_col))
|
||||
# The Field_Rename filter can change this situation:
|
||||
# raise KiPlotConfigurationError('Invalid column name `{}`'.format(new_col))
|
||||
logger.warning(W_BADFIELD+'Invalid column name `{}`'.format(new_col))
|
||||
columns.append(new_col)
|
||||
# This is the ordered list with the case style defined by the user
|
||||
self.columns = columns
|
||||
|
|
|
|||
|
|
@ -0,0 +1,164 @@
|
|||
EESchema Schematic File Version 4
|
||||
EELAYER 30 0
|
||||
EELAYER END
|
||||
$Descr A4 11693 8268
|
||||
encoding utf-8
|
||||
Sheet 1 1
|
||||
Title "KiCost subparts test"
|
||||
Date "2021-03-16"
|
||||
Rev "r1"
|
||||
Comp "KiBot"
|
||||
Comment1 ""
|
||||
Comment2 ""
|
||||
Comment3 ""
|
||||
Comment4 ""
|
||||
$EndDescr
|
||||
$Comp
|
||||
L Mechanical:Heatsink HS1
|
||||
U 1 1 6063AB02
|
||||
P 3750 1325
|
||||
F 0 "HS1" H 3891 1491 50 0000 L CNN
|
||||
F 1 "322400B00000G" H 3891 1400 50 0000 L CNN
|
||||
F 2 "" H 3762 1325 50 0001 C CNN
|
||||
F 3 "~" H 3762 1325 50 0001 C CNN
|
||||
F 4 "Aavid" H 3750 1325 50 0001 C CNN "manufacturer"
|
||||
F 5 "322400B00000G" H 3891 1309 50 0000 L CNN "mpn"
|
||||
F 6 "HS100-ND" H 3750 1325 50 0001 C CNN "digikey_part#"
|
||||
F 7 "HEAT SINK TO-18 1W BLK" H 3750 1325 50 0001 C CNN "Description"
|
||||
1 3750 1325
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:Q_NPN_BCE Q2
|
||||
U 1 1 6063D25D
|
||||
P 3750 1550
|
||||
F 0 "Q2" V 3675 1350 50 0000 C CNN
|
||||
F 1 "2N2222A" V 3575 1250 50 0000 C CNN
|
||||
F 2 "Package_TO_SOT_THT:TO-18-3" H 3950 1650 50 0001 C CNN
|
||||
F 3 "~" H 3750 1550 50 0001 C CNN
|
||||
F 4 "Central Semiconductor Corp" V 3750 1550 50 0001 C CNN "mnf"
|
||||
F 5 "2N2222A PBFREE" V 3500 1100 50 0000 C CNN "pn"
|
||||
F 6 "TRANS NPN 40V 0.8A TO-18" V 3750 1550 50 0001 C CNN "Description"
|
||||
F 7 "1514-2N2222APBFREE-ND" V 3750 1550 50 0001 C CNN "digikey_p#"
|
||||
1 3750 1550
|
||||
0 -1 -1 0
|
||||
$EndComp
|
||||
Text Notes 3600 1100 0 50 ~ 0
|
||||
A Transistor and its heatsink\nOnly one goes to the PCB
|
||||
Text Notes 575 825 0 200 ~ 40
|
||||
KiCost subparts
|
||||
$Comp
|
||||
L Device:Q_NPN_BCE Q1
|
||||
U 1 1 60640F08
|
||||
P 1075 1300
|
||||
F 0 "Q1" V 1000 1100 50 0000 C CNN
|
||||
F 1 "2N2222A" V 900 1000 50 0000 C CNN
|
||||
F 2 "Package_TO_SOT_THT:TO-18-3" H 1275 1400 50 0001 C CNN
|
||||
F 3 "~" H 1075 1300 50 0001 C CNN
|
||||
F 4 "Central Semiconductor Corp; Aavid" V 1075 1300 50 0001 C CNN "man"
|
||||
F 5 "2N2222A PBFREE; 322400B00000G" V 825 500 50 0000 C CNN "manf_num"
|
||||
F 6 "TRANS NPN 40V 0.8A TO-18 + Heatsink" V 1075 1300 50 0001 C CNN "Description"
|
||||
F 7 "1514-2N2222APBFREE-ND; HS100-ND" V 1075 1300 50 0001 C CNN "digikey_pn"
|
||||
F 8 "2N2222A;322400B00000G" V 1150 2600 50 0001 C CNN "Value_Subparts"
|
||||
1 1075 1300
|
||||
0 -1 -1 0
|
||||
$EndComp
|
||||
Text Notes 2650 1550 0 50 ~ 0
|
||||
Equivalent to ->
|
||||
$Comp
|
||||
L Connector_Generic:Conn_01x06 J1
|
||||
U 1 1 60649B1F
|
||||
P 1150 2600
|
||||
F 0 "J1" V 1114 2212 50 0000 R CNN
|
||||
F 1 "Conn_01x06" V 1023 2212 50 0000 R CNN
|
||||
F 2 "Connector_PinHeader_2.54mm:PinHeader_1x06_P2.54mm_Vertical" H 1150 2600 50 0001 C CNN
|
||||
F 3 "~" H 1150 2600 50 0001 C CNN
|
||||
F 4 "Molex; Molex; Molex; LEM; LEM" V 1150 2600 50 0001 C CNN "mfg"
|
||||
F 5 "0022232061;0022012067; 6: 08-50-0114; LA 55-P; lv 25-P" V 1150 2600 50 0001 C CNN "mfg part#"
|
||||
F 6 "WM4204-ND; WM2015-ND; WM1114-ND; 398-1010-ND; 398-1019-ND" V 1150 2600 50 0001 C CNN "digikey_vendor#"
|
||||
F 7 "CONN HEADER VERT 6POS 2.54MM; CONN HOUSING 6POS .100 W/RAMP; CONN 22-30AWG CRIMP TIN; SENSOR CURRENT HALL 50A AC/DC; TRANSDUCR VOLTAG CLOSE LOOP 10MA" V 1150 2600 50 0001 C CNN "Description"
|
||||
F 8 "Male_01x06;Female_01x06;Crimp_Pin;LA 55-P;LV 25-P" V 1150 2600 50 0001 C CNN "Value_Subparts"
|
||||
1 1150 2600
|
||||
0 -1 -1 0
|
||||
$EndComp
|
||||
Text Notes 900 2400 0 50 ~ 0
|
||||
A male header\nBut we want to include the female, the pins and the two\nsensors wired to the female.
|
||||
$Comp
|
||||
L Device:R R1
|
||||
U 1 1 6064C12F
|
||||
P 3750 2650
|
||||
F 0 "R1" H 3820 2696 50 0000 L CNN
|
||||
F 1 "0" H 3820 2605 50 0000 L CNN
|
||||
F 2 "" V 3680 2650 50 0001 C CNN
|
||||
F 3 "~" H 3750 2650 50 0001 C CNN
|
||||
F 4 "Bourns" H 3750 2650 50 0001 C CNN "mfr"
|
||||
F 5 "CR0603-J/-000ELF:5" H 3750 2650 50 0001 C CNN "mfg#"
|
||||
F 6 "CR0603-J/-000ELFCT-ND: 5" H 3750 2650 50 0001 C CNN "digikey_vpn"
|
||||
F 7 "RES SMD 0 OHM JUMPER 1/8W 0603" H 3750 2650 50 0001 C CNN "Description"
|
||||
1 3750 2650
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Text Notes 3675 2475 0 50 ~ 0
|
||||
A simple resistor, \nbut multiplied by 5\nWe add: R4 no mult \n and R5 no manf#\nTotal: 7
|
||||
$Comp
|
||||
L Device:R R2
|
||||
U 1 1 6064CA86
|
||||
P 3750 3400
|
||||
F 0 "R2" H 3820 3446 50 0000 L CNN
|
||||
F 1 "100" H 3820 3355 50 0000 L CNN
|
||||
F 2 "" V 3680 3400 50 0001 C CNN
|
||||
F 3 "~" H 3750 3400 50 0001 C CNN
|
||||
F 4 "Bourns" H 3750 3400 50 0001 C CNN "manf"
|
||||
F 5 "CR0603-JW-101ELF : 4.5" H 3750 3400 50 0001 C CNN "mfg-num"
|
||||
F 6 "CR0603-JW-101ELFCT-ND :4.5" H 3750 3400 50 0001 C CNN "digikey_num"
|
||||
F 7 "RES SMD 100 OHM 5% 1/10W 0603" H 3750 3400 50 0001 C CNN "Description"
|
||||
1 3750 3400
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Text Notes 3675 3225 0 50 ~ 0
|
||||
A simple resistor, \nbut multiplied by 4.5
|
||||
$Comp
|
||||
L Device:R R3
|
||||
U 1 1 6064D8D1
|
||||
P 3750 4150
|
||||
F 0 "R3" H 3820 4196 50 0000 L CNN
|
||||
F 1 "100k" H 3820 4105 50 0000 L CNN
|
||||
F 2 "" V 3680 4150 50 0001 C CNN
|
||||
F 3 "~" H 3750 4150 50 0001 C CNN
|
||||
F 4 "Bourns" H 3750 4150 50 0001 C CNN "manf"
|
||||
F 5 "4/5 : CR0603-JW-104ELF " H 3750 4150 50 0001 C CNN "mfg_num"
|
||||
F 6 " 4/5 : CR0603-JW-104ELFCT-ND" H 3750 4150 50 0001 C CNN "digikey-p#"
|
||||
F 7 "RES SMD 100K OHM 5% 1/10W 0603" H 3750 4150 50 0001 C CNN "Description"
|
||||
1 3750 4150
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Text Notes 3675 3975 0 50 ~ 0
|
||||
A simple resistor, \nbut multiplied by 4/5
|
||||
$Comp
|
||||
L Device:R R4
|
||||
U 1 1 6064EF62
|
||||
P 4250 2650
|
||||
F 0 "R4" H 4320 2696 50 0000 L CNN
|
||||
F 1 "0" H 4320 2605 50 0000 L CNN
|
||||
F 2 "" V 4180 2650 50 0001 C CNN
|
||||
F 3 "~" H 4250 2650 50 0001 C CNN
|
||||
F 4 "Bourns" H 4250 2650 50 0001 C CNN "manf"
|
||||
F 5 "CR0603-J/-000ELF" H 4250 2650 50 0001 C CNN "manf-num"
|
||||
F 6 "CR0603-J/-000ELFCT-ND" H 4250 2650 50 0001 C CNN "digikeyvp#"
|
||||
F 7 "RES SMD 0 OHM JUMPER 1/8W 0603" H 4250 2650 50 0001 C CNN "Description"
|
||||
1 4250 2650
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R R5
|
||||
U 1 1 6064F812
|
||||
P 4500 2650
|
||||
F 0 "R5" H 4570 2696 50 0000 L CNN
|
||||
F 1 "0" H 4570 2605 50 0000 L CNN
|
||||
F 2 "" V 4430 2650 50 0001 C CNN
|
||||
F 3 "~" H 4500 2650 50 0001 C CNN
|
||||
F 4 "RES SMD 0 OHM JUMPER 1/8W 0603" H 4500 2650 50 0001 C CNN "Description"
|
||||
1 4500 2650
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$EndSCHEMATC
|
||||
|
|
@ -1516,3 +1516,23 @@ def test_int_bom_subparts_1(test_dir):
|
|||
ctx.expect_out_file(output)
|
||||
ctx.compare_txt(output)
|
||||
ctx.clean_up()
|
||||
|
||||
|
||||
def test_int_bom_subparts_2(test_dir):
|
||||
prj = 'subparts_rename'
|
||||
ctx = context.TestContextSCH(test_dir, 'test_int_bom_subparts_2', prj, 'int_bom_subparts_2', '')
|
||||
ctx.run(extra_debug=True)
|
||||
output = prj+'-bom.csv'
|
||||
ctx.expect_out_file(output)
|
||||
ctx.compare_txt(output, 'subparts-bom.csv')
|
||||
ctx.clean_up()
|
||||
|
||||
|
||||
def test_int_bom_subparts_3(test_dir):
|
||||
prj = 'subparts_rename'
|
||||
ctx = context.TestContextSCH(test_dir, 'test_int_bom_subparts_3', prj, 'int_bom_subparts_3', '')
|
||||
ctx.run(extra_debug=True)
|
||||
output = prj+'-bom.csv'
|
||||
ctx.expect_out_file(output)
|
||||
ctx.compare_txt(output, 'subparts-bom.csv')
|
||||
ctx.clean_up()
|
||||
|
|
|
|||
|
|
@ -532,7 +532,7 @@ def test_error_int_bom_unknown_style(test_dir):
|
|||
|
||||
def test_error_int_bom_invalid_col(test_dir):
|
||||
ctx = context.TestContextSCH(test_dir, 'test_error_int_bom_invalid_col', 'links', 'error_int_bom_invalid_col', '')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
ctx.run()
|
||||
assert ctx.search_err("Invalid column name")
|
||||
ctx.clean_up()
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,142 @@
|
|||
# Example KiBot config file
|
||||
kibot:
|
||||
version: 1
|
||||
|
||||
filters:
|
||||
- name: 'Subparts splitter'
|
||||
type: subparts
|
||||
# We want to also split the `Description` field
|
||||
split_fields: ['Description']
|
||||
split_fields_expand: true
|
||||
# We only use the multiplier in `manf#`
|
||||
check_multiplier: ['manf#', 'digikey#']
|
||||
|
||||
- name: 'Field rename'
|
||||
type: field_rename
|
||||
rename:
|
||||
# KiCost manf# variants
|
||||
- field: 'mpn'
|
||||
name: 'manf#'
|
||||
- field: 'pn'
|
||||
name: 'manf#'
|
||||
- field: 'manf_num'
|
||||
name: 'manf#'
|
||||
- field: 'manf-num'
|
||||
name: 'manf#'
|
||||
- field: 'mfg_num'
|
||||
name: 'manf#'
|
||||
- field: 'mfg-num'
|
||||
name: 'manf#'
|
||||
- field: 'mfg#'
|
||||
name: 'manf#'
|
||||
- field: 'mfg part#'
|
||||
name: 'manf#'
|
||||
- field: 'man_num'
|
||||
name: 'manf#'
|
||||
- field: 'man-num'
|
||||
name: 'manf#'
|
||||
- field: 'man#'
|
||||
name: 'manf#'
|
||||
- field: 'mnf_num'
|
||||
name: 'manf#'
|
||||
- field: 'mnf-num'
|
||||
name: 'manf#'
|
||||
- field: 'mnf#'
|
||||
name: 'manf#'
|
||||
- field: 'mfr_num'
|
||||
name: 'manf#'
|
||||
- field: 'mfr-num'
|
||||
name: 'manf#'
|
||||
- field: 'mfr#'
|
||||
name: 'manf#'
|
||||
- field: 'part-num'
|
||||
name: 'manf#'
|
||||
- field: 'part_num'
|
||||
name: 'manf#'
|
||||
- field: 'p#'
|
||||
name: 'manf#'
|
||||
- field: 'part#'
|
||||
name: 'manf#'
|
||||
# KiCost manf variants
|
||||
- field: 'manufacturer'
|
||||
name: 'manf'
|
||||
- field: 'mnf'
|
||||
name: 'manf'
|
||||
- field: 'man'
|
||||
name: 'manf'
|
||||
- field: 'mfg'
|
||||
name: 'manf'
|
||||
- field: 'mfr'
|
||||
name: 'manf'
|
||||
# Some KiCost digikey# variants
|
||||
- field: 'digikey_part#'
|
||||
name: 'digikey#'
|
||||
- field: 'digikey_p#'
|
||||
name: 'digikey#'
|
||||
- field: 'digikey_pn'
|
||||
name: 'digikey#'
|
||||
- field: 'digikey_vendor#'
|
||||
name: 'digikey#'
|
||||
- field: 'digikey_vpn'
|
||||
name: 'digikey#'
|
||||
- field: 'digikey_num'
|
||||
name: 'digikey#'
|
||||
- field: 'digikey-p#'
|
||||
name: 'digikey#'
|
||||
- field: 'digikeyvp#'
|
||||
name: 'digikey#'
|
||||
|
||||
|
||||
variants:
|
||||
- name: place_holder
|
||||
comment: 'Just a place holder for the subparts splitter'
|
||||
type: kibom
|
||||
pre_transform:
|
||||
- 'Field rename'
|
||||
- 'Subparts splitter'
|
||||
|
||||
outputs:
|
||||
- name: 'bom_internal_subparts'
|
||||
comment: "Bill of Materials in CSV format, subparts splitted"
|
||||
type: bom
|
||||
dir: .
|
||||
options: &bom_options
|
||||
variant: place_holder
|
||||
number: 100
|
||||
group_fields: ['manf#']
|
||||
group_fields_fallbacks: ['value']
|
||||
# int_qtys: false
|
||||
columns:
|
||||
- Row
|
||||
- References
|
||||
- Value
|
||||
- Description
|
||||
- manf
|
||||
- manf#
|
||||
- digikey#
|
||||
- 'Quantity Per PCB'
|
||||
- 'Build Quantity'
|
||||
csv:
|
||||
hide_pcb_info: true
|
||||
|
||||
- name: 'bom_html'
|
||||
comment: "Bill of Materials in HTML format"
|
||||
type: bom
|
||||
dir: .
|
||||
options:
|
||||
<<: *bom_options
|
||||
html:
|
||||
digikey_link: 'digikey#'
|
||||
highlight_empty: false
|
||||
|
||||
|
||||
- name: 'bom_xlsx'
|
||||
comment: "Bill of Materials in XLSX format"
|
||||
type: bom
|
||||
dir: .
|
||||
options:
|
||||
<<: *bom_options
|
||||
xlsx:
|
||||
digikey_link: 'digikey#'
|
||||
highlight_empty: false
|
||||
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
# Example KiBot config file
|
||||
kibot:
|
||||
version: 1
|
||||
|
||||
filters:
|
||||
- name: 'Subparts splitter'
|
||||
type: subparts
|
||||
# We want to also split the `Description` field
|
||||
split_fields: ['desc']
|
||||
split_fields_expand: true
|
||||
# We only use the multiplier in `manf#`
|
||||
check_multiplier: ['manf#', 'digikey#']
|
||||
|
||||
|
||||
variants:
|
||||
- name: place_holder
|
||||
comment: 'Just a place holder for the subparts splitter'
|
||||
type: kibom
|
||||
pre_transform:
|
||||
- '_kicost_rename'
|
||||
- 'Subparts splitter'
|
||||
|
||||
outputs:
|
||||
- name: 'bom_internal_subparts'
|
||||
comment: "Bill of Materials in CSV format, subparts splitted"
|
||||
type: bom
|
||||
dir: .
|
||||
options: &bom_options
|
||||
variant: place_holder
|
||||
number: 100
|
||||
group_fields: ['manf#']
|
||||
group_fields_fallbacks: ['value']
|
||||
# int_qtys: false
|
||||
columns:
|
||||
- Row
|
||||
- References
|
||||
- Value
|
||||
- field: desc
|
||||
name: Description
|
||||
- manf
|
||||
- manf#
|
||||
- digikey#
|
||||
- 'Quantity Per PCB'
|
||||
- 'Build Quantity'
|
||||
csv:
|
||||
hide_pcb_info: true
|
||||
|
||||
- name: 'bom_html'
|
||||
comment: "Bill of Materials in HTML format"
|
||||
type: bom
|
||||
dir: .
|
||||
options:
|
||||
<<: *bom_options
|
||||
html:
|
||||
digikey_link: 'digikey#'
|
||||
highlight_empty: false
|
||||
|
||||
|
||||
- name: 'bom_xlsx'
|
||||
comment: "Bill of Materials in XLSX format"
|
||||
type: bom
|
||||
dir: .
|
||||
options:
|
||||
<<: *bom_options
|
||||
xlsx:
|
||||
digikey_link: 'digikey#'
|
||||
highlight_empty: false
|
||||
|
||||
Loading…
Reference in New Issue