From 553d47f5331ffcd839cce4353bda3c62fc118ae6 Mon Sep 17 00:00:00 2001 From: "Salvador E. Tropea" Date: Fri, 12 Aug 2022 09:09:09 -0300 Subject: [PATCH] [BoM] Added support for text variables expansion - Is done using a filter, the expansion is done at the end, but the filter can be applied at any point in the filter/variant chain. Fixes #247 --- CHANGELOG.md | 1 + README.md | 46 +-- docs/README.in | 35 +-- docs/samples/generic_plot.kibot.yaml | 5 + kibot/fil_base.py | 16 +- kibot/fil_expand_text_vars.py | 49 +++ kibot/misc.py | 1 + kibot/out_bom.py | 14 +- .../kicad_6/kibom-variant_3_txt.kicad_pro | 3 +- .../kicad_6/kibom-variant_3_txt.kicad_sch | 278 +++++++++++++++++- tests/test_plot/test_int_bom.py | 23 +- 11 files changed, 428 insertions(+), 43 deletions(-) create mode 100644 kibot/fil_expand_text_vars.py mode change 120000 => 100644 tests/board_samples/kicad_6/kibom-variant_3_txt.kicad_sch diff --git a/CHANGELOG.md b/CHANGELOG.md index 7140651b..0086e9a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Workaround for problems with DRC exclusions (See INTI-CMNB/KiAuto#26) Global option: `drc_exclusions_workaround` KiCad bug [11562](https://gitlab.com/kicad/code/kicad/-/issues/11562) +- Internal BoM: KiCad 6 text variables expansion in the fields (#247) ### Fixed - OAR computation (Report) (#225) diff --git a/README.md b/README.md index e5c512d5..87d4301c 100644 --- a/README.md +++ b/README.md @@ -738,6 +738,13 @@ filters: #### Supported filters: +- expand_text_vars: Expand_Text_Vars + This filter expands KiCad 6 text variables (${VARIABLE}). + * Valid keys: + - `comment`: [string=''] A comment for documentation purposes. + - `include_kicad_env`: [boolean=true] Also expand KiCad environment variables. + - `include_os_env`: [boolean=false] Also expand system environment variables. + - `name`: [string=''] Used to identify this particular filter definition. - field_rename: Field_Rename This filter implements a field renamer. The internal `_kicost_rename` filter emulates the KiCost behavior. @@ -872,14 +879,15 @@ The [tests/yaml_samples](https://github.com/INTI-CMNB/KiBot/tree/master/tests/ya #### Built-in filters -- **_mechanical** is used to exclude: - - References that start with # - - Virtual components - - References that match: '^TP[0-9]*' or '^FID' - - Part names that match: 'regex': 'mount.*hole' or 'solder.*bridge' or 'solder.*jump' or 'test.*point' - - Footprints that match: 'test.*point' or 'mount.*hole' or 'fiducial' -- **_var_rename** is a default `var_rename` filter -- **_var_rename_kicost** is a default `var_rename_kicost` filter +- **_expand_text_vars** is a default `expand_text_vars` filter +- **_kibom_dnc_Config** it uses the internal `dnc_list` to exclude components with + - Value matching any of the keys + - Any of the keys in the `Config` field (comma or space separated) +- **_kibom_dnf_Config** it uses the internal `dnf_list` to exclude components with + - Value matching any of the keys + - Any of the keys in the `Config` field (comma or space separated) +- **_kicost_dnp** used emulate the way KiCost handles the `dnp` field. + - If the field is 0 the component is included, otherwise excluded. - **_kicost_rename** is a `field_rename` filter that applies KiCost renamings. - Includes all `manf#` and `manf` variations supported by KiCost - Includes all distributor part number variations supported by KiCost @@ -887,17 +895,17 @@ The [tests/yaml_samples](https://github.com/INTI-CMNB/KiBot/tree/master/tests/ya - 'nopop' -> 'dnp' - 'description' -> 'desc' - 'pdf' -> 'datasheet' -- **_kicost_dnp** used emulate the way KiCost handles the `dnp` field. - - If the field is 0 the component is included, otherwise excluded. +- **_mechanical** is used to exclude: + - References that start with # + - Virtual components + - References that match: '^TP[0-9]*' or '^FID' + - Part names that match: 'regex': 'mount.*hole' or 'solder.*bridge' or 'solder.*jump' or 'test.*point' + - Footprints that match: 'test.*point' or 'mount.*hole' or 'fiducial' - **_rot_footprint** is a default `rot_footprint` filter -- **_kibom_dnf_Config** it uses the internal `dnf_list` to exclude components with - - Value matching any of the keys - - Any of the keys in the `Config` field (comma or space separated) -- **_kibom_dnc_Config** it uses the internal `dnc_list` to exclude components with - - Value matching any of the keys - - Any of the keys in the `Config` field (comma or space separated) +- **_var_rename** is a default `var_rename` filter +- **_var_rename_kicost** is a default `var_rename_kicost` filter -Note that the last two uses a field named `Config`, but you can customise them invoking **_kibom_dnf_FIELD**. This will create an equivalent filter, but using the indicated **FIELD**. +Note that the **_kibom_...** filters uses a field named `Config`, but you can customise them invoking **_kibom_dnf_FIELD**. This will create an equivalent filter, but using the indicated **FIELD**. #### Changing the 3D model, simple mechanism @@ -1388,6 +1396,10 @@ Notes: The default filter marks components with a DNF value or DNF in the Config field. - `exclude_filter`: [string|list(string)='_mechanical'] Name of the filter to exclude components from BoM processing. The default filter excludes test points, fiducial marks, mounting holes, etc. + - `expand_text_vars`: [boolean=true] Expand KiCad 6 text variables after applying all filters and variants. + This is done using a **_expand_text_vars** filter. + If you need to customize the filter, or apply it before, you can disable this option and + add a custom filter to the filter chain. - `fit_field`: [string='Config'] Field name used for internal filters. - `footprint_populate_values`: [string|list(string)='no,yes'] Values for the `Footprint Populate` column. - `footprint_type_values`: [string|list(string)='SMD,THT,VIRTUAL'] Values for the `Footprint Type` column. diff --git a/docs/README.in b/docs/README.in index f2c0010f..b06bb8a5 100644 --- a/docs/README.in +++ b/docs/README.in @@ -517,14 +517,15 @@ The [tests/yaml_samples](https://github.com/INTI-CMNB/KiBot/tree/master/tests/ya #### Built-in filters -- **_mechanical** is used to exclude: - - References that start with # - - Virtual components - - References that match: '^TP[0-9]*' or '^FID' - - Part names that match: 'regex': 'mount.*hole' or 'solder.*bridge' or 'solder.*jump' or 'test.*point' - - Footprints that match: 'test.*point' or 'mount.*hole' or 'fiducial' -- **_var_rename** is a default `var_rename` filter -- **_var_rename_kicost** is a default `var_rename_kicost` filter +- **_expand_text_vars** is a default `expand_text_vars` filter +- **_kibom_dnc_Config** it uses the internal `dnc_list` to exclude components with + - Value matching any of the keys + - Any of the keys in the `Config` field (comma or space separated) +- **_kibom_dnf_Config** it uses the internal `dnf_list` to exclude components with + - Value matching any of the keys + - Any of the keys in the `Config` field (comma or space separated) +- **_kicost_dnp** used emulate the way KiCost handles the `dnp` field. + - If the field is 0 the component is included, otherwise excluded. - **_kicost_rename** is a `field_rename` filter that applies KiCost renamings. - Includes all `manf#` and `manf` variations supported by KiCost - Includes all distributor part number variations supported by KiCost @@ -532,17 +533,17 @@ The [tests/yaml_samples](https://github.com/INTI-CMNB/KiBot/tree/master/tests/ya - 'nopop' -> 'dnp' - 'description' -> 'desc' - 'pdf' -> 'datasheet' -- **_kicost_dnp** used emulate the way KiCost handles the `dnp` field. - - If the field is 0 the component is included, otherwise excluded. +- **_mechanical** is used to exclude: + - References that start with # + - Virtual components + - References that match: '^TP[0-9]*' or '^FID' + - Part names that match: 'regex': 'mount.*hole' or 'solder.*bridge' or 'solder.*jump' or 'test.*point' + - Footprints that match: 'test.*point' or 'mount.*hole' or 'fiducial' - **_rot_footprint** is a default `rot_footprint` filter -- **_kibom_dnf_Config** it uses the internal `dnf_list` to exclude components with - - Value matching any of the keys - - Any of the keys in the `Config` field (comma or space separated) -- **_kibom_dnc_Config** it uses the internal `dnc_list` to exclude components with - - Value matching any of the keys - - Any of the keys in the `Config` field (comma or space separated) +- **_var_rename** is a default `var_rename` filter +- **_var_rename_kicost** is a default `var_rename_kicost` filter -Note that the last two uses a field named `Config`, but you can customise them invoking **_kibom_dnf_FIELD**. This will create an equivalent filter, but using the indicated **FIELD**. +Note that the **_kibom_...** filters uses a field named `Config`, but you can customise them invoking **_kibom_dnf_FIELD**. This will create an equivalent filter, but using the indicated **FIELD**. #### Changing the 3D model, simple mechanism diff --git a/docs/samples/generic_plot.kibot.yaml b/docs/samples/generic_plot.kibot.yaml index 2d4b5c59..7d6020d9 100644 --- a/docs/samples/generic_plot.kibot.yaml +++ b/docs/samples/generic_plot.kibot.yaml @@ -211,6 +211,11 @@ outputs: # [string|list(string)='_mechanical'] Name of the filter to exclude components from BoM processing. # The default filter excludes test points, fiducial marks, mounting holes, etc exclude_filter: '_mechanical' + # [boolean=true] Expand KiCad 6 text variables after applying all filters and variants. + # This is done using a **_expand_text_vars** filter. + # If you need to customize the filter, or apply it before, you can disable this option and + # add a custom filter to the filter chain + expand_text_vars: true # [string='Config'] Field name used for internal filters fit_field: 'Config' # [string|list(string)='no,yes'] Values for the `Footprint Populate` column diff --git a/kibot/fil_base.py b/kibot/fil_base.py index 2d019323..d84c2910 100644 --- a/kibot/fil_base.py +++ b/kibot/fil_base.py @@ -1,13 +1,13 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020-2021 Salvador E. Tropea -# Copyright (c) 2020-2021 Instituto Nacional de Tecnología Industrial +# Copyright (c) 2020-2022 Salvador E. Tropea +# Copyright (c) 2020-2022 Instituto Nacional de Tecnología Industrial # License: GPL-3.0 # Project: KiBot (formerly KiPlot) from .registrable import RegFilter, Registrable, RegOutput from .optionable import Optionable from .gs import GS from .misc import (IFILT_MECHANICAL, IFILT_VAR_RENAME, IFILT_ROT_FOOTPRINT, IFILT_KICOST_RENAME, DISTRIBUTORS, - IFILT_VAR_RENAME_KICOST, IFILT_KICOST_DNP) + IFILT_VAR_RENAME_KICOST, IFILT_KICOST_DNP, IFILT_EXPAND_TEXT_VARS) from .error import KiPlotConfigurationError from .bom.columnlist import ColumnList from .macros import macros, document # noqa: F401 @@ -243,6 +243,14 @@ class BaseFilter(RegFilter): logger.debug('Creating internal filter: '+str(o_tree)) return o_tree + @staticmethod + def _create_expand_text_vars(name): + o_tree = {'name': name} + o_tree['type'] = 'expand_text_vars' + o_tree['comment'] = 'Internal default text variables expander' + logger.debug('Creating internal filter: '+str(o_tree)) + return o_tree + @staticmethod def _create_kibom_dnx(name): type = name[7:10] @@ -308,6 +316,8 @@ class BaseFilter(RegFilter): tree = BaseFilter._create_var_rename_kicost(name) elif name == IFILT_KICOST_DNP: tree = BaseFilter._create_kicost_dnp(name) + elif name == IFILT_EXPAND_TEXT_VARS: + tree = BaseFilter._create_expand_text_vars(name) else: return None filter = RegFilter.get_class_for(tree['type'])() diff --git a/kibot/fil_expand_text_vars.py b/kibot/fil_expand_text_vars.py new file mode 100644 index 00000000..384a518b --- /dev/null +++ b/kibot/fil_expand_text_vars.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2022 Salvador E. Tropea +# Copyright (c) 2022 Instituto Nacional de Tecnología Industrial +# License: GPL-3.0 +# Project: KiBot (formerly KiPlot) +# Description: Expands KiCad 6 text variables +import os +from .gs import GS +from .kicad.config import KiConf, expand_env +from .macros import macros, document, filter_class # noqa: F401 +from . import log + +logger = log.get_logger() + + +@filter_class +class Expand_Text_Vars(BaseFilter): # noqa: F821 + """ Expand_Text_Vars + This filter expands KiCad 6 text variables (${VARIABLE}) """ + def __init__(self): + super().__init__() + with document: + self.include_os_env = False + """ Also expand system environment variables """ + self.include_kicad_env = True + """ Also expand KiCad environment variables """ + self._first_pass = True + self._is_transform = True + + def filter(self, comp): + if self._first_pass: + # Ensure we initialized the KiCad environment variables + KiConf.init(GS.sch_file) + # Collect the "extra" variables + self.extra_env = {} + if self.include_os_env: + self.extra_env.update(os.environ) + if self.include_kicad_env: + self.extra_env.update(KiConf.kicad_env) + # Get the text variables from the project + self.text_vars = GS.load_pro_variables() + self._first_pass = False + # Expand text variables in all fields + for f in comp.fields: + new_value = expand_env(f.value, self.text_vars, self.extra_env) + if new_value != f.value: + comp.set_field(f.name, new_value) + if GS.debug_level > 2: + logger.debug('ref: {} {}: {} -> {}'.format(comp.ref, f.name, f.value, new_value)) diff --git a/kibot/misc.py b/kibot/misc.py index 3c9aa8a9..c4048945 100644 --- a/kibot/misc.py +++ b/kibot/misc.py @@ -83,6 +83,7 @@ IFILT_VAR_RENAME_KICOST = '_var_rename_kicost' IFILT_ROT_FOOTPRINT = '_rot_footprint' IFILT_KICOST_RENAME = '_kicost_rename' IFILT_KICOST_DNP = '_kicost_dnp' +IFILT_EXPAND_TEXT_VARS = '_expand_text_vars' # KiCad 5 GUI values for the attribute UI_THT = 0 # 1 for KiCad 6 UI_SMD = 1 # 2 for KiCad 6 diff --git a/kibot/out_bom.py b/kibot/out_bom.py index f5f8c7ca..f03b9f7c 100644 --- a/kibot/out_bom.py +++ b/kibot/out_bom.py @@ -20,7 +20,7 @@ import os import re from copy import deepcopy from .gs import GS -from .misc import W_BADFIELD, W_NEEDSPCB, DISTRIBUTORS +from .misc import W_BADFIELD, W_NEEDSPCB, DISTRIBUTORS, IFILT_EXPAND_TEXT_VARS from .optionable import Optionable, BaseOptions from .registrable import RegOutput from .error import KiPlotConfigurationError @@ -29,7 +29,7 @@ from .bom.columnlist import ColumnList, BoMError from .bom.bom import do_bom from .var_kibom import KiBoM from .fil_base import (BaseFilter, apply_exclude_filter, apply_fitted_filter, apply_fixed_filter, reset_filters, - KICOST_NAME_TRANSLATIONS) + KICOST_NAME_TRANSLATIONS, apply_pre_transform) from .macros import macros, document, output_class # noqa: F401 from . import log # To debug the `with document` we can use: @@ -479,6 +479,11 @@ class BoMOptions(BaseOptions): """ [string|list(string)='no,yes'] Values for the `Footprint Populate` column """ self.footprint_type_values = Optionable """ [string|list(string)='SMD,THT,VIRTUAL'] Values for the `Footprint Type` column """ + self.expand_text_vars = True + """ Expand KiCad 6 text variables after applying all filters and variants. + This is done using a **_expand_text_vars** filter. + If you need to customize the filter, or apply it before, you can disable this option and + add a custom filter to the filter chain """ self._format_example = 'CSV' self._footprint_populate_values_example = 'no,yes' self._footprint_type_values_example = 'SMD,THT,VIRTUAL' @@ -724,6 +729,11 @@ class BoMOptions(BaseOptions): apply_fixed_filter(comps, self.dnc_filter) # Apply the variant comps = self.variant.filter(comps) + # Now expand the text variables, the user can disable it and insert a customized filter + # in the variant or even before. + if self.expand_text_vars: + comps = apply_pre_transform(comps, BaseFilter.solve_filter(IFILT_EXPAND_TEXT_VARS, 'KiCad 6 text vars', + is_transform=True)) # We add the main project to the aggregate list so do_bom sees a complete list base_sch = Aggregate() base_sch.file = GS.sch_file diff --git a/tests/board_samples/kicad_6/kibom-variant_3_txt.kicad_pro b/tests/board_samples/kicad_6/kibom-variant_3_txt.kicad_pro index 6eee7740..66fb4676 100644 --- a/tests/board_samples/kicad_6/kibom-variant_3_txt.kicad_pro +++ b/tests/board_samples/kicad_6/kibom-variant_3_txt.kicad_pro @@ -415,6 +415,7 @@ ] ], "text_variables": { - "text": "Test" + "text": "Test", + "VAL_C2": "1000 pF" } } diff --git a/tests/board_samples/kicad_6/kibom-variant_3_txt.kicad_sch b/tests/board_samples/kicad_6/kibom-variant_3_txt.kicad_sch deleted file mode 120000 index eb88def2..00000000 --- a/tests/board_samples/kicad_6/kibom-variant_3_txt.kicad_sch +++ /dev/null @@ -1 +0,0 @@ -kibom-variant_3.kicad_sch \ No newline at end of file diff --git a/tests/board_samples/kicad_6/kibom-variant_3_txt.kicad_sch b/tests/board_samples/kicad_6/kibom-variant_3_txt.kicad_sch new file mode 100644 index 00000000..2c600c50 --- /dev/null +++ b/tests/board_samples/kicad_6/kibom-variant_3_txt.kicad_sch @@ -0,0 +1,277 @@ +(kicad_sch (version 20211123) (generator eeschema) + + (uuid e6521bef-4109-48f7-8b88-4121b0468927) + + (paper "A4") + + (title_block + (title "KiBom Test Schematic") + (date "2020-03-12") + (rev "A") + (company "https://github.com/SchrodingersGat/KiBom") + ) + + (lib_symbols + (symbol "Device:C" (pin_numbers hide) (pin_names (offset 0.254)) (in_bom yes) (on_board yes) + (property "Reference" "C" (id 0) (at 0.635 2.54 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "C" (id 1) (at 0.635 -2.54 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (id 2) (at 0.9652 -3.81 0) + (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" "cap capacitor" (id 4) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Unpolarized capacitor" (id 5) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_fp_filters" "C_*" (id 6) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "C_0_1" + (polyline + (pts + (xy -2.032 -0.762) + (xy 2.032 -0.762) + ) + (stroke (width 0.508) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (polyline + (pts + (xy -2.032 0.762) + (xy 2.032 0.762) + ) + (stroke (width 0.508) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + ) + (symbol "C_1_1" + (pin passive line (at 0 3.81 270) (length 2.794) + (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 2.794) + (name "~" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + ) + ) + (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 "Mechanical:Fiducial" (in_bom yes) (on_board yes) + (property "Reference" "FID" (id 0) (at 0 5.08 0) + (effects (font (size 1.27 1.27))) + ) + (property "Value" "Fiducial" (id 1) (at 0 3.175 0) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (id 2) (at 0 0 0) + (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" "fiducial marker" (id 4) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Fiducial Marker" (id 5) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_fp_filters" "Fiducial*" (id 6) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "Fiducial_0_1" + (circle (center 0 0) (radius 1.27) + (stroke (width 0.508) (type default) (color 0 0 0 0)) + (fill (type background)) + ) + ) + ) + ) + + + (text "This schematic serves as a test-file for the KiBot export script.\nHere we implement the IBoM variants style." + (at 12.7 19.05 0) + (effects (font (size 2.0066 2.0066)) (justify left bottom)) + (uuid 9a9f2d82-f64d-4264-8bec-c182528fc4de) + ) + (text "The test tests the following \nvariants matrix:\n production test default\nC1 X\nC2 X X\nR1 X X X\nR2 X X\n\nproduction: blacklist T2\ntest: blacklist T1\ndefault: whitelist T1,default \n blacklist T2,T3" + (at 151.13 81.28 0) + (effects (font (size 2.9972 2.9972)) (justify left bottom)) + (uuid b60c50d1-225e-415c-8712-7acb5e3dc8ea) + ) + + (symbol (lib_id "Device:C") (at 25.4 43.18 0) (unit 1) + (in_bom yes) (on_board yes) + (uuid 00000000-0000-0000-0000-00005f43bec2) + (property "Reference" "C1" (id 0) (at 28.321 42.0116 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "1nF" (id 1) (at 28.321 44.323 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "Capacitor_SMD:C_0805_2012Metric" (id 2) (at 26.3652 46.99 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 25.4 43.18 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Config" "T2" (id 4) (at 25.4 43.18 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid d22e95aa-f3db-4fbc-a331-048a2523233e)) + (pin "2" (uuid 0d0bb7b2-a6e5-46d2-9492-a1aa6e5a7b2f)) + ) + + (symbol (lib_id "Device:C") (at 36.83 43.18 0) (unit 1) + (in_bom yes) (on_board yes) + (uuid 00000000-0000-0000-0000-00005f43ce1c) + (property "Reference" "C2" (id 0) (at 39.751 42.0116 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "${VAL_C2}" (id 1) (at 39.751 44.323 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "Capacitor_SMD:C_0805_2012Metric" (id 2) (at 37.7952 46.99 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 36.83 43.18 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Config" "T3" (id 4) (at 36.83 43.18 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 0a3cc030-c9dd-4d74-9d50-715ed2b361a2)) + (pin "2" (uuid 8322f275-268c-4e87-a69f-4cfbf05e747f)) + ) + + (symbol (lib_id "Device:R") (at 53.34 43.18 0) (unit 1) + (in_bom yes) (on_board yes) + (uuid 00000000-0000-0000-0000-00005f43d144) + (property "Reference" "R1" (id 0) (at 55.118 42.0116 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "1k" (id 1) (at 55.118 44.323 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "Resistor_SMD:R_0805_2012Metric" (id 2) (at 51.562 43.18 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 53.34 43.18 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Config" "default" (id 4) (at 53.34 43.18 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 48f827a8-6e22-4a2e-abdc-c2a03098d883)) + (pin "2" (uuid e877bf4a-4210-4bd3-b7b0-806eb4affc5b)) + ) + + (symbol (lib_id "Device:R") (at 63.5 43.18 0) (unit 1) + (in_bom yes) (on_board yes) + (uuid 00000000-0000-0000-0000-00005f43d4bb) + (property "Reference" "R2" (id 0) (at 65.278 42.0116 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "1000" (id 1) (at 65.278 44.323 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "Resistor_SMD:R_0805_2012Metric" (id 2) (at 61.722 43.18 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 63.5 43.18 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Config" "T1" (id 4) (at 63.5 43.18 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "default:_3D_model" "${KICAD6_3DMODEL_DIR}/Resistor_SMD.3dshapes/R_2010_5025Metric.wrl" (id 5) (at 63.5 43.18 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid c70d9ef3-bfeb-47e0-a1e1-9aeba3da7864)) + (pin "2" (uuid 4e3d7c0d-12e3-42f2-b944-e4bcdbbcac2a)) + ) + + (symbol (lib_id "Mechanical:Fiducial") (at 44.45 57.15 0) (unit 1) + (in_bom yes) (on_board yes) + (uuid 00000000-0000-0000-0000-00005f57eddb) + (property "Reference" "FID1" (id 0) (at 46.609 55.9816 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "Fiducial" (id 1) (at 46.609 58.293 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "Fiducial:Fiducial_0.5mm_Mask1mm" (id 2) (at 44.45 57.15 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 44.45 57.15 0) + (effects (font (size 1.27 1.27)) hide) + ) + ) + + (sheet_instances + (path "/" (page "1")) + ) + + (symbol_instances + (path "/00000000-0000-0000-0000-00005f43bec2" + (reference "C1") (unit 1) (value "1nF") (footprint "Capacitor_SMD:C_0805_2012Metric") + ) + (path "/00000000-0000-0000-0000-00005f43ce1c" + (reference "C2") (unit 1) (value "${VAL_C2}") (footprint "Capacitor_SMD:C_0805_2012Metric") + ) + (path "/00000000-0000-0000-0000-00005f57eddb" + (reference "FID1") (unit 1) (value "Fiducial") (footprint "Fiducial:Fiducial_0.5mm_Mask1mm") + ) + (path "/00000000-0000-0000-0000-00005f43d144" + (reference "R1") (unit 1) (value "1k") (footprint "Resistor_SMD:R_0805_2012Metric") + ) + (path "/00000000-0000-0000-0000-00005f43d4bb" + (reference "R2") (unit 1) (value "1000") (footprint "Resistor_SMD:R_0805_2012Metric") + ) + ) +) diff --git a/tests/test_plot/test_int_bom.py b/tests/test_plot/test_int_bom.py index c62e0ac3..c59e0160 100644 --- a/tests/test_plot/test_int_bom.py +++ b/tests/test_plot/test_int_bom.py @@ -48,9 +48,10 @@ pytest-3 --log-cli-level debug """ -import os -import logging from base64 import b64decode +import logging +import os +import pytest from . import context from kibot.misc import EXIT_BAD_CONFIG @@ -1349,6 +1350,24 @@ def test_int_bom_variant_t2if(test_dir): ctx.clean_up(keep_project=True) +@pytest.mark.skipif(context.ki5(), reason="needs KiCad 6 text variables") +def test_int_bom_variant_t2it(test_dir): + """ IBoM variants test full, here we expand KiCad 6 variables """ + prj = 'kibom-variant_3_txt' + ctx = context.TestContextSCH(test_dir, prj, 'int_bom_var_t2i_csv', BOM_DIR) + ctx.run() + rows, header, info = ctx.load_csv(prj+'-bom.csv') + ref_column = header.index(REF_COLUMN_NAME) + check_kibom_test_netlist(rows, ref_column, 1, ['C1', 'C2'], ['R1', 'R2']) + rows, header, info = ctx.load_csv(prj+'-bom_[2].csv') + check_kibom_test_netlist(rows, ref_column, 1, ['C1', 'C2'], ['R1', 'R2']) + rows, header, info = ctx.load_csv(prj+'-bom_(production).csv') + check_kibom_test_netlist(rows, ref_column, 2, ['C1'], ['R1', 'R2', 'C2']) + rows, header, info = ctx.load_csv(prj+'-bom_(test).csv') + check_kibom_test_netlist(rows, ref_column, 2, ['R2'], ['R1', 'C1', 'C2']) + ctx.clean_up(keep_project=True) + + def test_int_bom_variant_t2is(test_dir): """ IBoM variants test simple """ prj = 'kibom-variant_3'