diff --git a/CHANGELOG.md b/CHANGELOG.md index e4d6632d..86dd0ea0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - File name patterns: %F is the name of the source file without extension, but with the path. - A hint for pip installations without using `--no-compile`. +- KiBoM variants: support to field overwrite according to variant (experimental). ### Fixed - Now we support missing field names in schematic library entries. diff --git a/kibot/kicad/v5_sch.py b/kibot/kicad/v5_sch.py index 52a4e054..4fe1df6b 100644 --- a/kibot/kicad/v5_sch.py +++ b/kibot/kicad/v5_sch.py @@ -821,6 +821,15 @@ class SchematicComponent(object): return self.dfields[field].value return '' + def set_field(self, field, value): + """ Change the value for an existing field """ + if field in self.dfields: + target = self.dfields[field] + target.value = value + # Adjust special fields + if target.number < 4: + self._solve_fields(LineReader(None, '**Internal**')) + # def get_field_names(self): # return [f.name for f in self.fields] diff --git a/kibot/var_kibom.py b/kibot/var_kibom.py index dbace549..ce813669 100644 --- a/kibot/var_kibom.py +++ b/kibot/var_kibom.py @@ -32,6 +32,10 @@ class KiBoM(BaseVariant): # noqa: F821 """ Name of the field used to clasify components """ self.variant = Optionable """ [string|list(string)=''] Board variant(s) """ + self.field_changer = False + """ Enable the VARIANT.FIELD to FIELD rename mechanism """ + self.field_variant_separator = '.' + """ Separator used for the VARIANT.FIELD rename mechanism """ def set_def_filters(self, exclude_filter, dnf_filter, dnc_filter): """ Filters delegated to the variant """ @@ -93,6 +97,20 @@ class KiBoM(BaseVariant): # noqa: F821 # No match return not exclusive + def _rename_var_fields(self, comp): + """ Look for fields containing VARIANT:FIELD used to change fields according to the variant """ + for variant in self.variant: + for name, value in comp.get_user_fields(): + res = name.strip().split(self.field_variant_separator) + if len(res) == 2: + f_variant = res[0].lower() + f_field = res[1].lower() + if f_variant == variant: + if GS.debug_level > 2: + logger.debug('ref: {} value: {} -> {}'.format(comp.ref, comp.get_field_value(f_field), value)) + comp.set_field(f_field, value) + + def filter(self, comps): super().filter(comps) logger.debug("Applying KiBoM style variants `{}`".format(self.name)) @@ -103,6 +121,8 @@ class KiBoM(BaseVariant): # noqa: F821 value = c.value.lower() config = c.get_field_value(self.config_field).lower() c.fitted = self._variant_comp_is_fitted(value, config) - if not c.fitted and GS.debug_level > 2: + if c.fitted and self.field_changer: + self._rename_var_fields(c) + elif not c.fitted and GS.debug_level > 2: logger.debug('ref: {} value: {} config: {} variant: {} -> False'. format(c.ref, value, config, self.variant)) diff --git a/tests/board_samples/kicad_5/kibom-variant_2.sch b/tests/board_samples/kicad_5/kibom-variant_2.sch index 6a0b9b8a..1153d0eb 100644 --- a/tests/board_samples/kicad_5/kibom-variant_2.sch +++ b/tests/board_samples/kicad_5/kibom-variant_2.sch @@ -49,6 +49,7 @@ F 0 "R1" H 2170 1746 50 0000 L CNN F 1 "1k" H 2170 1655 50 0000 L CNN F 2 "" V 2030 1700 50 0001 C CNN F 3 "~" H 2100 1700 50 0001 C CNN +F 4 "3k3" H 2100 1700 50 0001 C CNN "test:Value" 1 2100 1700 1 0 0 -1 $EndComp diff --git a/tests/test_plot/test_int_bom.py b/tests/test_plot/test_int_bom.py index 127ceebf..841cf56e 100644 --- a/tests/test_plot/test_int_bom.py +++ b/tests/test_plot/test_int_bom.py @@ -60,6 +60,7 @@ REF_COLUMN_NAME_R = 'Referencias' QTY_COLUMN_NAME = 'Quantity Per PCB' COMP_COLUMN_NAME = 'Row' COMP_COLUMN_NAME_R = 'Renglón' +VALUE_COLUMN_NAME = 'Value' DATASHEET_COLUMN_NAME = 'Datasheet' KIBOM_TEST_HEAD = [COMP_COLUMN_NAME, 'Description', 'Part', REF_COLUMN_NAME, 'Value', 'Footprint', QTY_COLUMN_NAME, DATASHEET_COLUMN_NAME, 'Config'] @@ -1197,17 +1198,31 @@ def test_int_bom_variant_t1(): ctx.clean_up() -def test_int_bom_variant_t2(): +def check_value(rows, r_col, ref, v_col, val): + for r in rows: + refs = r[r_col].split(' ') + if ref in refs: + assert r[v_col] == val + logging.debug(ref+'='+val+' OK') + return + assert False, "Failed to find "+ref + + +def test_int_bom_variant_t2b(): prj = 'kibom-variant_2' - ctx = context.TestContextSCH('test_int_bom_variant_t2', prj, 'int_bom_var_t2_csv', BOM_DIR) + ctx = context.TestContextSCH('test_int_bom_variant_t2b', prj, 'int_bom_var_t2_csv', BOM_DIR) ctx.run() rows, header, info = ctx.load_csv(prj+'-bom.csv') ref_column = header.index(REF_COLUMN_NAME) + val_column = header.index(VALUE_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 1, ['C1', 'C2'], ['R1', 'R2']) + check_value(rows, ref_column, 'R1', val_column, '1k') rows, header, info = ctx.load_csv(prj+'-bom_(production).csv') check_kibom_test_netlist(rows, ref_column, 2, ['C1'], ['R1', 'R2', 'C2']) + check_value(rows, ref_column, 'R1', val_column, '1k') rows, header, info = ctx.load_csv(prj+'-bom_(test).csv') check_kibom_test_netlist(rows, ref_column, 2, ['R2'], ['R1', 'C1', 'C2']) + check_value(rows, ref_column, 'R1', val_column, '3k3') ctx.clean_up() diff --git a/tests/yaml_samples/int_bom_var_t2_csv.kibot.yaml b/tests/yaml_samples/int_bom_var_t2_csv.kibot.yaml index 0c79bfbc..40a6e63c 100644 --- a/tests/yaml_samples/int_bom_var_t2_csv.kibot.yaml +++ b/tests/yaml_samples/int_bom_var_t2_csv.kibot.yaml @@ -14,6 +14,8 @@ variants: type: kibom file_id: '_(test)' variant: test + field_changer: true + field_variant_separator: ':' outputs: - name: 'bom_internal'