From 8f384990315a40fd06872683c18147ba885dcc22 Mon Sep 17 00:00:00 2001 From: "Salvador E. Tropea" Date: Fri, 5 Feb 2021 10:25:06 -0300 Subject: [PATCH] Added BoM consolidation example. --- README.md | 283 ++++++++++++++++++++++++++++++++++++++++++++++++- docs/README.in | 283 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 564 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8550d423..fe61e13a 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ To learn more about KiBot variants visit the [example repo](https://inti-cmnb.gi * [The *outputs* section](#the-outputs-section) * [Specifying the layers](#specifying-the-layers) * [Supported outputs](#supported-outputs) - * [Filters and variants](#filters-and-variants) + * [Consolidating BoMs](#consolidating-boms) * [Usage](#usage) * [Installation](#installation) * [Usage for CI/CD](#usage-for-cicd) @@ -1347,6 +1347,287 @@ Next time you need this list just use an alias, like this: Not fitted components are crossed. +#### Consolidating BoMs + +Some times your project is composed by various boards, other you are producing various products at the same time. +In both cases you would want to consolidate the components acquisition in one operation. +Of course you can create individual BoMs for each project in CSV format and then consolidate them using a spreadsheet editor. +But KiBot offers another option: you create a BoM for your main project and then aggregate the components from the other projects. + +Here is a simple example. Suppose you have three projects: *merge_1*, *merge_2* and *merge_3*. +For the *merge_1* project you could use the following output: + +```yaml +kibot: + version: 1 + +outputs: + - name: 'bom_csv' + comment: "Bill of Materials in CSV format" + type: bom + dir: BoM + options: + use_alt: true +``` + +Using the `tests/board_samples/kicad_5/merge_1.sch` from the git repo and storing the above example in `m1.kibot.yaml` you could run: + +```shell +src/kibot -c m1.kibot.yaml -e tests/board_samples/kicad_5/merge_1.sch -d test_merge +``` + +And get `test_merge/BoM/merge_1-bom.csv`: + +| Row | Description | Part | References | Value | Footprint | Quantity Per PCB | Status | Datasheet | +|--------------------|-----------------------------------|------|------------|-------|-----------|------------------|--------|-----------| +| 1 | Unpolarized capacitor | C | C1 | 1nF | | 1 | | ~ | +| 2 | Unpolarized capacitor | C | C2 | 10nF | | 1 | | ~ | +| 3 | Resistor | R | R1-R3 | 1k | | 3 | | ~ | +| | | | | | | | | | +| | | | | | | | | | +| | | | | | | | | | +| | | | | | | | | | +| | | | | | | | | | +| Project info: | | | | | | | | | +| Schematic: | merge_1 | | | | | | | | +| Variant: | default | | | | | | | | +| Revision: | | | | | | | | | +| Date: | 2021-02-02_12-12-27 | | | | | | | | +| KiCad Version: | 5.1.9-73d0e3b20d~88~ubuntu21.04.1 | | | | | | | | +| Statistics: | | | | | | | | | +| Component Groups: | 3 | | | | | | | | +| Component Count: | 5 | | | | | | | | +| Fitted Components: | 5 | | | | | | | | +| Number of PCBs: | 1 | | | | | | | | +| Total Components: | 5 | | | | | | | | + +This CSV says you have five components groped in three different types. They are one 1 nF capacitor, one 10 nF capacitor and three 1 k resistors. +Now lets generate BoMs for the *merge_2* example: + +```shell +src/kibot -c m1.kibot.yaml -e tests/board_samples/kicad_5/merge_2.sch -d test_merge +``` + +We'll get `test_merge/BoM/merge_2-bom.csv`: + +```csv +Row,Description,Part,References,Value,Footprint,Quantity Per PCB,Status,Datasheet +1,Unpolarized capacitor,C,C2,1nF,,1, ,~ +2,Unpolarized capacitor,C,C1,10nF,,1, ,~ +3,Resistor,R,R2-R4,1000,,3, ,~ +4,Resistor,R,R1,10k,,1, ,~ + + + + + +Project info: +Schematic:,merge_2 +Variant:,default +Revision:, +Date:,2021-01-27_10-19-46 +KiCad Version:,5.1.9-73d0e3b20d~88~ubuntu21.04.1 +Statistics: +Component Groups:,4 +Component Count:,6 +Fitted Components:,6 +Number of PCBs:,1 +Total Components:,6 +``` + +In this project we have six components from four different types. They are similar to *merge_1* but now we also have a 10 k resistor. +We don't need to generate this BoM to consolidate our projects, but is good to know what we have. +And now lets generate BoMs for the *merge_3* example: + +```shell +src/kibot -c m1.kibot.yaml -e tests/board_samples/kicad_5/merge_3.sch -d test_merge +``` + +We'll get `test_merge/BoM/merge_3-bom.csv`: + +```csv +Row,Description,Part,References,Value,Footprint,Quantity Per PCB,Status,Datasheet +1,Resistor,R,R5,1k,,1, ,~ +2,Resistor,R,R1-R4,10k,,4, ,~ + + + + + +Project info: +Schematic:,merge_3 +Variant:,default +Revision:, +Date:,2021-01-27_10-21-29 +KiCad Version:,5.1.9-73d0e3b20d~88~ubuntu21.04.1 +Statistics: +Component Groups:,2 +Component Count:,5 +Fitted Components:,5 +Number of PCBs:,1 +Total Components:,5 +``` + +This time we also have five components, but from two different types. They are one 1 k resistor and four 10 k resistors. +Now suppose we want to create 10 boards for *merge_1*, 20 for *merge_2* and 30 for *merge_3*. +We could use the following configuration: + +```yaml +kibot: + version: 1 + +outputs: + - name: 'bom_csv' + comment: "Bill of Materials in CSV format" + type: bom + dir: BoM + options: + use_alt: true + number: 10 + aggregate: + - file: tests/board_samples/kicad_5/merge_2.sch + number: 20 + - file: tests/board_samples/kicad_5/merge_3.sch + number: 30 +``` + +Save it as `m2.kibot.yaml` and run: + +```shell +src/kibot -c m2.kibot.yaml -e tests/board_samples/kicad_5/merge_1.sch -d test_merge_consolidate +``` + +The `test_merge_consolidate/BoM/merge_1-bom.csv` file will be generated containing: + +```csv +Row,Description,Part,References,Value,Footprint,Quantity Per PCB,Build Quantity,Status,Datasheet,Source BoM +1,Unpolarized capacitor,C,C1-C2,1nF,,2,30, ,~,merge_1(1) merge_2(1) +2,Unpolarized capacitor,C,C1-C2,10nF,,2,30, ,~,merge_1(1) merge_2(1) +3,Resistor,R,R1-R5,1k,,5,80, ,~,merge_1(3) merge_2(1) merge_3(1) +4,Resistor,R,R1-R4,10k,,4,110, ,~,merge_2(1) merge_3(3) + + + + + +Project info: +Variant:,default +KiCad Version:,5.1.9-73d0e3b20d~88~ubuntu21.04.1 +Global statistics: +Component Groups:,4 +Component Count:,13 +Fitted Components:,13 +Number of PCBs:,60 +Total Components:,250 +Project info:,merge_1 +Schematic:,merge_1 +Revision:, +Date:,2021-02-02_12-12-27 +Company:,Test company +Statistics:,merge_1 +Component Groups:,3 +Component Count:,5 +Fitted Components:,5 +Number of PCBs:,10 +Total Components:,50 +Project info:,merge_2 +Schematic:,merge_2 +Revision:, +Date:,2021-01-27_10-19-46 +Statistics:,merge_2 +Component Groups:,4 +Component Count:,4 +Fitted Components:,4 +Number of PCBs:,20 +Total Components:,80 +Project info:,merge_3 +Schematic:,merge_3 +Revision:, +Date:,2021-01-27_10-21-29 +Statistics:,merge_3 +Component Groups:,2 +Component Count:,4 +Fitted Components:,4 +Number of PCBs:,30 +Total Components:,120 +``` + +You can see that now we have much more stats. They say we have four different types, thirteen for board sets, a total of 60 boards and 250 components. +Then we have individual stats for each project. +The capacitors are easy to interpret, we have 30 1 nF capacitors *merge_1* project has one and *merge_2* another. +As we have 10 *merge_1* and 20 *merge_2* boards this is clear. +But looking at the 1 k resistors is harder. We have 80, three from *merge_1*, one from *merge_2* and another from *merge_3*. +So we have 10*3+20+30=80, this is clear, but the BoM says they are R1 to R5, which is a little bit confusing. +Lets assing an *id* to each project, we'll use 'A' for *merge_1*, 'B' for *merge_2* and 'C' for *merge_3*: + +```yaml +kibot: + version: 1 + +outputs: + - name: 'bom_csv' + comment: "Bill of Materials in CSV format" + type: bom + dir: BoM + options: + use_alt: true + number: 10 + ref_id: 'A:' + aggregate: + - file: tests/board_samples/kicad_5/merge_2.sch + number: 20 + ref_id: 'B:' + - file: tests/board_samples/kicad_5/merge_3.sch + number: 30 + ref_id: 'C:' +``` + +Now `test_merge_consolidate/BoM/merge_1-bom.csv` will have the following information: + +```csv +Row,Description,Part,References,Value,Footprint,Quantity Per PCB,Build Quantity,Status,Datasheet,Source BoM +1,Unpolarized capacitor,C,A:C1 B:C2,1nF,,2,30, ,~,merge_1(1) merge_2(1) +2,Unpolarized capacitor,C,A:C2 B:C1,10nF,,2,30, ,~,merge_1(1) merge_2(1) +3,Resistor,R,A:R1-A:R3 B:R2-B:R4 C:R5,1k,,7,120, ,~,merge_1(3) merge_2(3) merge_3(1) +4,Resistor,R,B:R1 C:R1-C:R4,10k,,5,140, ,~,merge_2(1) merge_3(4) +``` + +As you can see now we know `A` has R1-R3, `B` R2-R4 and for `C` R5 is the 1k resistor. +If we want to compact the `Source BoM` column we just need to enable the `source_by_id` option: + +```yaml +kibot: + version: 1 + +outputs: + - name: 'bom_csv' + comment: "Bill of Materials in CSV format" + type: bom + dir: BoM + options: + use_alt: true + number: 10 + ref_id: 'A:' + source_by_id: true + aggregate: + - file: tests/board_samples/kicad_5/merge_2.sch + number: 20 + ref_id: 'B:' + - file: tests/board_samples/kicad_5/merge_3.sch + number: 30 + ref_id: 'C:' +``` + +And we'll get: + +```csv +Row,Description,Part,References,Value,Footprint,Quantity Per PCB,Build Quantity,Status,Datasheet,Source BoM +1,Unpolarized capacitor,C,A:C1 B:C2,1nF,,2,30, ,~,A:(1) B:(1) +2,Unpolarized capacitor,C,A:C2 B:C1,10nF,,2,30, ,~,A:(1) B:(1) +3,Resistor,R,A:R1-A:R3 B:R2-B:R4 C:R5,1k,,7,120, ,~,A:(3) B:(3) C:(1) +4,Resistor,R,B:R1 C:R1-C:R4,10k,,5,140, ,~,B:(1) C:(4) +``` + ## Usage If you need a template for the configuration file try: diff --git a/docs/README.in b/docs/README.in index 0f97ea85..23645ff4 100644 --- a/docs/README.in +++ b/docs/README.in @@ -30,7 +30,7 @@ To learn more about KiBot variants visit the [example repo](https://inti-cmnb.gi * [The *outputs* section](#the-outputs-section) * [Specifying the layers](#specifying-the-layers) * [Supported outputs](#supported-outputs) - * [Filters and variants](#filters-and-variants) + * [Consolidating BoMs](#consolidating-boms) * [Usage](#usage) * [Installation](#installation) * [Usage for CI/CD](#usage-for-cicd) @@ -473,6 +473,287 @@ Next time you need this list just use an alias, like this: #### @outputs@ +#### Consolidating BoMs + +Some times your project is composed by various boards, other you are producing various products at the same time. +In both cases you would want to consolidate the components acquisition in one operation. +Of course you can create individual BoMs for each project in CSV format and then consolidate them using a spreadsheet editor. +But KiBot offers another option: you create a BoM for your main project and then aggregate the components from the other projects. + +Here is a simple example. Suppose you have three projects: *merge_1*, *merge_2* and *merge_3*. +For the *merge_1* project you could use the following output: + +```yaml +kibot: + version: 1 + +outputs: + - name: 'bom_csv' + comment: "Bill of Materials in CSV format" + type: bom + dir: BoM + options: + use_alt: true +``` + +Using the `tests/board_samples/kicad_5/merge_1.sch` from the git repo and storing the above example in `m1.kibot.yaml` you could run: + +```shell +src/kibot -c m1.kibot.yaml -e tests/board_samples/kicad_5/merge_1.sch -d test_merge +``` + +And get `test_merge/BoM/merge_1-bom.csv`: + +| Row | Description | Part | References | Value | Footprint | Quantity Per PCB | Status | Datasheet | +|--------------------|-----------------------------------|------|------------|-------|-----------|------------------|--------|-----------| +| 1 | Unpolarized capacitor | C | C1 | 1nF | | 1 | | ~ | +| 2 | Unpolarized capacitor | C | C2 | 10nF | | 1 | | ~ | +| 3 | Resistor | R | R1-R3 | 1k | | 3 | | ~ | +| | | | | | | | | | +| | | | | | | | | | +| | | | | | | | | | +| | | | | | | | | | +| | | | | | | | | | +| Project info: | | | | | | | | | +| Schematic: | merge_1 | | | | | | | | +| Variant: | default | | | | | | | | +| Revision: | | | | | | | | | +| Date: | 2021-02-02_12-12-27 | | | | | | | | +| KiCad Version: | 5.1.9-73d0e3b20d~88~ubuntu21.04.1 | | | | | | | | +| Statistics: | | | | | | | | | +| Component Groups: | 3 | | | | | | | | +| Component Count: | 5 | | | | | | | | +| Fitted Components: | 5 | | | | | | | | +| Number of PCBs: | 1 | | | | | | | | +| Total Components: | 5 | | | | | | | | + +This CSV says you have five components groped in three different types. They are one 1 nF capacitor, one 10 nF capacitor and three 1 k resistors. +Now lets generate BoMs for the *merge_2* example: + +```shell +src/kibot -c m1.kibot.yaml -e tests/board_samples/kicad_5/merge_2.sch -d test_merge +``` + +We'll get `test_merge/BoM/merge_2-bom.csv`: + +```csv +Row,Description,Part,References,Value,Footprint,Quantity Per PCB,Status,Datasheet +1,Unpolarized capacitor,C,C2,1nF,,1, ,~ +2,Unpolarized capacitor,C,C1,10nF,,1, ,~ +3,Resistor,R,R2-R4,1000,,3, ,~ +4,Resistor,R,R1,10k,,1, ,~ + + + + + +Project info: +Schematic:,merge_2 +Variant:,default +Revision:, +Date:,2021-01-27_10-19-46 +KiCad Version:,5.1.9-73d0e3b20d~88~ubuntu21.04.1 +Statistics: +Component Groups:,4 +Component Count:,6 +Fitted Components:,6 +Number of PCBs:,1 +Total Components:,6 +``` + +In this project we have six components from four different types. They are similar to *merge_1* but now we also have a 10 k resistor. +We don't need to generate this BoM to consolidate our projects, but is good to know what we have. +And now lets generate BoMs for the *merge_3* example: + +```shell +src/kibot -c m1.kibot.yaml -e tests/board_samples/kicad_5/merge_3.sch -d test_merge +``` + +We'll get `test_merge/BoM/merge_3-bom.csv`: + +```csv +Row,Description,Part,References,Value,Footprint,Quantity Per PCB,Status,Datasheet +1,Resistor,R,R5,1k,,1, ,~ +2,Resistor,R,R1-R4,10k,,4, ,~ + + + + + +Project info: +Schematic:,merge_3 +Variant:,default +Revision:, +Date:,2021-01-27_10-21-29 +KiCad Version:,5.1.9-73d0e3b20d~88~ubuntu21.04.1 +Statistics: +Component Groups:,2 +Component Count:,5 +Fitted Components:,5 +Number of PCBs:,1 +Total Components:,5 +``` + +This time we also have five components, but from two different types. They are one 1 k resistor and four 10 k resistors. +Now suppose we want to create 10 boards for *merge_1*, 20 for *merge_2* and 30 for *merge_3*. +We could use the following configuration: + +```yaml +kibot: + version: 1 + +outputs: + - name: 'bom_csv' + comment: "Bill of Materials in CSV format" + type: bom + dir: BoM + options: + use_alt: true + number: 10 + aggregate: + - file: tests/board_samples/kicad_5/merge_2.sch + number: 20 + - file: tests/board_samples/kicad_5/merge_3.sch + number: 30 +``` + +Save it as `m2.kibot.yaml` and run: + +```shell +src/kibot -c m2.kibot.yaml -e tests/board_samples/kicad_5/merge_1.sch -d test_merge_consolidate +``` + +The `test_merge_consolidate/BoM/merge_1-bom.csv` file will be generated containing: + +```csv +Row,Description,Part,References,Value,Footprint,Quantity Per PCB,Build Quantity,Status,Datasheet,Source BoM +1,Unpolarized capacitor,C,C1-C2,1nF,,2,30, ,~,merge_1(1) merge_2(1) +2,Unpolarized capacitor,C,C1-C2,10nF,,2,30, ,~,merge_1(1) merge_2(1) +3,Resistor,R,R1-R5,1k,,5,80, ,~,merge_1(3) merge_2(1) merge_3(1) +4,Resistor,R,R1-R4,10k,,4,110, ,~,merge_2(1) merge_3(3) + + + + + +Project info: +Variant:,default +KiCad Version:,5.1.9-73d0e3b20d~88~ubuntu21.04.1 +Global statistics: +Component Groups:,4 +Component Count:,13 +Fitted Components:,13 +Number of PCBs:,60 +Total Components:,250 +Project info:,merge_1 +Schematic:,merge_1 +Revision:, +Date:,2021-02-02_12-12-27 +Company:,Test company +Statistics:,merge_1 +Component Groups:,3 +Component Count:,5 +Fitted Components:,5 +Number of PCBs:,10 +Total Components:,50 +Project info:,merge_2 +Schematic:,merge_2 +Revision:, +Date:,2021-01-27_10-19-46 +Statistics:,merge_2 +Component Groups:,4 +Component Count:,4 +Fitted Components:,4 +Number of PCBs:,20 +Total Components:,80 +Project info:,merge_3 +Schematic:,merge_3 +Revision:, +Date:,2021-01-27_10-21-29 +Statistics:,merge_3 +Component Groups:,2 +Component Count:,4 +Fitted Components:,4 +Number of PCBs:,30 +Total Components:,120 +``` + +You can see that now we have much more stats. They say we have four different types, thirteen for board sets, a total of 60 boards and 250 components. +Then we have individual stats for each project. +The capacitors are easy to interpret, we have 30 1 nF capacitors *merge_1* project has one and *merge_2* another. +As we have 10 *merge_1* and 20 *merge_2* boards this is clear. +But looking at the 1 k resistors is harder. We have 80, three from *merge_1*, one from *merge_2* and another from *merge_3*. +So we have 10*3+20+30=80, this is clear, but the BoM says they are R1 to R5, which is a little bit confusing. +Lets assing an *id* to each project, we'll use 'A' for *merge_1*, 'B' for *merge_2* and 'C' for *merge_3*: + +```yaml +kibot: + version: 1 + +outputs: + - name: 'bom_csv' + comment: "Bill of Materials in CSV format" + type: bom + dir: BoM + options: + use_alt: true + number: 10 + ref_id: 'A:' + aggregate: + - file: tests/board_samples/kicad_5/merge_2.sch + number: 20 + ref_id: 'B:' + - file: tests/board_samples/kicad_5/merge_3.sch + number: 30 + ref_id: 'C:' +``` + +Now `test_merge_consolidate/BoM/merge_1-bom.csv` will have the following information: + +```csv +Row,Description,Part,References,Value,Footprint,Quantity Per PCB,Build Quantity,Status,Datasheet,Source BoM +1,Unpolarized capacitor,C,A:C1 B:C2,1nF,,2,30, ,~,merge_1(1) merge_2(1) +2,Unpolarized capacitor,C,A:C2 B:C1,10nF,,2,30, ,~,merge_1(1) merge_2(1) +3,Resistor,R,A:R1-A:R3 B:R2-B:R4 C:R5,1k,,7,120, ,~,merge_1(3) merge_2(3) merge_3(1) +4,Resistor,R,B:R1 C:R1-C:R4,10k,,5,140, ,~,merge_2(1) merge_3(4) +``` + +As you can see now we know `A` has R1-R3, `B` R2-R4 and for `C` R5 is the 1k resistor. +If we want to compact the `Source BoM` column we just need to enable the `source_by_id` option: + +```yaml +kibot: + version: 1 + +outputs: + - name: 'bom_csv' + comment: "Bill of Materials in CSV format" + type: bom + dir: BoM + options: + use_alt: true + number: 10 + ref_id: 'A:' + source_by_id: true + aggregate: + - file: tests/board_samples/kicad_5/merge_2.sch + number: 20 + ref_id: 'B:' + - file: tests/board_samples/kicad_5/merge_3.sch + number: 30 + ref_id: 'C:' +``` + +And we'll get: + +```csv +Row,Description,Part,References,Value,Footprint,Quantity Per PCB,Build Quantity,Status,Datasheet,Source BoM +1,Unpolarized capacitor,C,A:C1 B:C2,1nF,,2,30, ,~,A:(1) B:(1) +2,Unpolarized capacitor,C,A:C2 B:C1,10nF,,2,30, ,~,A:(1) B:(1) +3,Resistor,R,A:R1-A:R3 B:R2-B:R4 C:R5,1k,,7,120, ,~,A:(3) B:(3) C:(1) +4,Resistor,R,B:R1 C:R1-C:R4,10k,,5,140, ,~,B:(1) C:(4) +``` + ## Usage If you need a template for the configuration file try: