From 390da80f7cf47901d85a9e5af27d4bdf3ad4b252 Mon Sep 17 00:00:00 2001 From: "Salvador E. Tropea" Date: Fri, 1 Sep 2023 13:51:15 -0300 Subject: [PATCH] [BoM][Added] LCSC links From SchrodingersGat/KiBoM#190 --- CHANGELOG.md | 1 + docs/samples/generic_plot.kibot.yaml | 9 ++++++++- docs/source/configuration/outputs/bom.rst | 6 ++++++ kibot/bom/html_writer.py | 13 +++++++++---- kibot/bom/xlsx_writer.py | 5 +++++ kibot/out_bom.py | 6 ++++++ kibot/out_kibom.py | 10 ++++++++++ tests/board_samples/kicad_5/links.sch | 4 ++++ tests/board_samples/kicad_6/links.kicad_sch | 12 ++++++++++++ tests/board_samples/kicad_7/links.kicad_sch | 12 ++++++++++++ tests/board_samples/kicad_8/links.kicad_sch | 12 ++++++++++++ tests/test_plot/test_int_bom.py | 19 ++++++++++++++++++- .../int_bom_datasheet_link.kibot.yaml | 1 + .../int_bom_datasheet_link_xlsx.kibot.yaml | 1 + .../int_bom_digikey_link.kibot.yaml | 2 ++ .../int_bom_digikey_link_xlsx.kibot.yaml | 2 ++ .../int_bom_digikey_links.kibot.yaml | 1 + .../int_bom_digikey_links_xlsx.kibot.yaml | 1 + 18 files changed, 111 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7e097064..d2efc7fc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 applied to the solder mask apertures. (#476) - BoM: - Support for ${field} expansion. (#471) + - LCSC links (SchrodingersGat/KiBoM#190) - iBoM: - `forced_name` option to force the name displayed at the top left corner (#470) diff --git a/docs/samples/generic_plot.kibot.yaml b/docs/samples/generic_plot.kibot.yaml index 74eb3920b..939067e7c 100644 --- a/docs/samples/generic_plot.kibot.yaml +++ b/docs/samples/generic_plot.kibot.yaml @@ -73,10 +73,11 @@ preflight: command: 'git log -1 --format="%h" "$KIBOT_SCH_NAME"' before: 'Git hash: <' after: '>' - # [dict|list(dict)] Defines KiCad 6 variables. + # [dict|list(dict)] Defines KiCad 6+ variables. # They are expanded using ${VARIABLE}, and stored in the project file. # This preflight replaces `pcb_replace` and `sch_replace` when using KiCad 6. # The KiCad project file is modified. + # Warning: don't use `-s all` or this preflight will be skipped. set_text_variables: - name: 'git_hash' command: 'git log -1 --format="%h" "$KIBOT_PCB_NAME"' @@ -479,6 +480,9 @@ outputs: hide_stats_info: false # [boolean=true] Use a color for empty cells. Applies only when `col_colors` is `true` highlight_empty: true + # [boolean|string|list(string)=''] Column/s containing LCSC part numbers, will be linked to web page. + # Use **true** to copy the value indicated by the `field_lcsc_part` global option + lcsc_link: '' # [string|boolean=''] PNG file to use as logo, use false to remove logo: '' # [string|list(string)=''] Column/s containing Mouser part numbers, will be linked to web page @@ -565,6 +569,9 @@ outputs: kicost_config: '' # [boolean=false] Used to add a column with the distributor's description. So you can check this is the right component kicost_dist_desc: false + # [boolean|string|list(string)=''] Column/s containing LCSC part numbers, will be linked to web page. + # Use **true** to copy the value indicated by the `field_lcsc_part` global option + lcsc_link: '' # [string|boolean=''] PNG file to use as logo, use false to remove logo: '' # [number=2] Scaling factor for the logo. Note that this value isn't honored by all spreadsheet software diff --git a/docs/source/configuration/outputs/bom.rst b/docs/source/configuration/outputs/bom.rst index 33edf20b4..bd705852a 100644 --- a/docs/source/configuration/outputs/bom.rst +++ b/docs/source/configuration/outputs/bom.rst @@ -106,6 +106,9 @@ Parameters: - ``hide_pcb_info`` :index:`: ` [boolean=false] Hide project information. - ``hide_stats_info`` :index:`: ` [boolean=false] Hide statistics information. - ``highlight_empty`` :index:`: ` [boolean=true] Use a color for empty cells. Applies only when `col_colors` is `true`. + - ``lcsc_link`` :index:`: ` [boolean|string|list(string)=''] Column/s containing LCSC part numbers, will be linked to web page. + Use **true** to copy the value indicated by the `field_lcsc_part` global option. + - ``mouser_link`` :index:`: ` [string|list(string)=''] Column/s containing Mouser part numbers, will be linked to web page. - ``style`` :index:`: ` [string='modern-blue'] Page style. Internal styles: modern-blue, modern-green, modern-red and classic. @@ -149,6 +152,9 @@ Parameters: To understand how to achieve this, and also how to make use of the cache please visit the `kicost_ci_test `__ repo. - ``kicost_dist_desc`` :index:`: ` [boolean=false] Used to add a column with the distributor's description. So you can check this is the right component. + - ``lcsc_link`` :index:`: ` [boolean|string|list(string)=''] Column/s containing LCSC part numbers, will be linked to web page. + Use **true** to copy the value indicated by the `field_lcsc_part` global option. + - ``logo_scale`` :index:`: ` [number=2] Scaling factor for the logo. Note that this value isn't honored by all spreadsheet software. - ``max_col_width`` :index:`: ` [number=60] [20,999] Maximum column width (characters). - ``mouser_link`` :index:`: ` [string|list(string)=''] Column/s containing Mouser part numbers, will be linked to web page. diff --git a/kibot/bom/html_writer.py b/kibot/bom/html_writer.py index 69b788e7e..275f8060d 100644 --- a/kibot/bom/html_writer.py +++ b/kibot/bom/html_writer.py @@ -217,7 +217,8 @@ def link(text): return text -def content_table(html, groups, headings, head_names, cfg, link_datasheet, link_digikey, link_mouser, col_colors, dnf=False): +def content_table(html, groups, headings, head_names, cfg, link_datasheet, link_digikey, link_mouser, link_lcsc, col_colors, + dnf=False): cl = '' # Table start html.write('\n') @@ -248,6 +249,8 @@ def content_table(html, groups, headings, head_names, cfg, link_datasheet, link_ r = '' + r + '' if link_mouser and headings[n] in link_mouser: r = '' + r + '' + if link_lcsc and headings[n] in link_lcsc: + r = '' + r + '' # Link this column to the datasheet? if link_datasheet == n and datasheet.startswith('http'): r = '' + r + '' @@ -372,6 +375,7 @@ def write_html(filename, groups, headings, head_names, cfg): link_datasheet = headings.index(cfg.html.datasheet_as_link) link_digikey = cfg.html.digikey_link link_mouser = cfg.html.mouser_link + link_lcsc = cfg.html.lcsc_link col_colors = cfg.html.col_colors # Compute the CSS style_name = cfg.html.style @@ -445,13 +449,14 @@ def write_html(filename, groups, headings, head_names, cfg): # Fitted groups html.write("

Component Groups

\n") - content_table(html, groups, headings, head_names, cfg, link_datasheet, link_digikey, link_mouser, col_colors) + content_table(html, groups, headings, head_names, cfg, link_datasheet, link_digikey, link_mouser, link_lcsc, + col_colors) # DNF component groups if cfg.html.generate_dnf and cfg.n_total != cfg.n_fitted: html.write("

Optional components (DNF=Do Not Fit)

\n") - content_table(html, groups, headings, head_names, cfg, link_datasheet, link_digikey, link_mouser, col_colors, - True) + content_table(html, groups, headings, head_names, cfg, link_datasheet, link_digikey, link_mouser, link_lcsc, + col_colors, True) # Color reference if col_colors: diff --git a/kibot/bom/xlsx_writer.py b/kibot/bom/xlsx_writer.py index fa20241f4..082977b77 100644 --- a/kibot/bom/xlsx_writer.py +++ b/kibot/bom/xlsx_writer.py @@ -730,6 +730,7 @@ def write_xlsx(filename, groups, col_fields, head_names, cfg): link_datasheet = col_fields.index(cfg.xlsx.datasheet_as_link) link_digikey = cfg.xlsx.digikey_link link_mouser = cfg.xlsx.mouser_link + link_lcsc = cfg.xlsx.lcsc_link hl_empty = cfg.xlsx.highlight_empty workbook = Workbook(filename) @@ -813,6 +814,10 @@ def write_xlsx(filename, groups, col_fields, head_names, cfg): elif link_mouser and col_fields[i] in link_mouser: url = 'https://www.mouser.com/ProductDetail/' + cell worksheet.write_url(row_count, i, url, fmt, cell) + # A link to LCSC? + elif link_lcsc and col_fields[i] in link_lcsc: + url = 'https://www.lcsc.com/product-detail/' + cell + worksheet.write_url(row_count, i, url, fmt, cell) else: worksheet.write_string(row_count, i, cell, fmt) if len(cell) > column_widths[i] - 5: diff --git a/kibot/out_bom.py b/kibot/out_bom.py index 75a7a12e4..dc1e59bec 100644 --- a/kibot/out_bom.py +++ b/kibot/out_bom.py @@ -188,6 +188,9 @@ def __init__(self): """ [string|list(string)=''] Column/s containing Digi-Key part numbers, will be linked to web page """ self.mouser_link = Optionable """ [string|list(string)=''] Column/s containing Mouser part numbers, will be linked to web page """ + self.lcsc_link = Optionable + """ [boolean|string|list(string)=''] Column/s containing LCSC part numbers, will be linked to web page. + Use **true** to copy the value indicated by the `field_lcsc_part` global option """ self.generate_dnf = True """ *Generate a separated section for DNF (Do Not Fit) components """ self.hide_pcb_info = False @@ -208,6 +211,9 @@ def config(self, parent): # *_link self.digikey_link = self.force_list(self.digikey_link, comma_sep=False, lower_case=True) self.mouser_link = self.force_list(self.mouser_link, comma_sep=False, lower_case=True) + if isinstance(self.lcsc_link, bool): + self.lcsc_link = self.field_lcsc_part if self.lcsc_link else '' + self.lcsc_link = self.force_list(self.lcsc_link, comma_sep=False, lower_case=True) # Logo if isinstance(self.logo, type): self.logo = '' diff --git a/kibot/out_kibom.py b/kibot/out_kibom.py index ba0fa1b88..3a62e46c5 100644 --- a/kibot/out_kibom.py +++ b/kibot/out_kibom.py @@ -135,6 +135,10 @@ def __init__(self): """ [string|list(string)=''] Column/s containing Digi-Key part numbers, will be linked to web page (HTML only) """ self.mouser_link = Optionable """ [string|list(string)=''] Column/s containing Mouser part numbers, will be linked to web page (HTML only) """ + # Upcoming release + # self.lcsc_link = Optionable + # """ [string|list(string)=''] Column/s containing LCSC part numbers, will be linked to web page (HTML only) """ + # ??? Use **true** to copy the value indicated by the `field_lcsc_part` global option """ self.group_fields = GroupFields """ *[list(string)] List of fields used for sorting individual components into groups. Components which match (comparing *all* fields) will be grouped together. @@ -238,6 +242,11 @@ def config(self, parent): self.mouser_link = None elif isinstance(self.mouser_link, list): self.mouser_link = '\t'.join(self.mouser_link) + # lcsc_link + # if isinstance(self.lcsc_link, type): + # self.lcsc_link = None + # elif isinstance(self.lcsc_link, list): + # self.lcsc_link = '\t'.join(self.lcsc_link) # group_fields if isinstance(self.group_fields, type): self.group_fields = None @@ -335,6 +344,7 @@ def save(self, filename): self.write_str('ref_separator') self.write_str('digikey_link') self.write_str('mouser_link') + # self.write_str('lcsc_link') # Ask to keep the output name f.write('output_file_name = %O\n') self.write_vector(self.group_fields, 'GROUP_FIELDS') diff --git a/tests/board_samples/kicad_5/links.sch b/tests/board_samples/kicad_5/links.sch index 7bf5633a6..604b9df6b 100644 --- a/tests/board_samples/kicad_5/links.sch +++ b/tests/board_samples/kicad_5/links.sch @@ -28,6 +28,7 @@ F 5 "0022232021" H 2850 2300 50 0001 C CNN "manf#" F 6 "WM2700-ND" H 2850 2300 50 0001 C CNN "digikey_alt#" F 7 "538-22-23-2021" H 2850 2300 50 0001 C CNN "mouser#" F 8 "538-22-11-2022" H 2850 2300 50 0001 C CNN "mouser_alt#" +F 9 "C234180" H 2850 2300 50 0001 C CNN "LCSC#" 1 2850 2300 1 0 0 -1 $EndComp @@ -44,6 +45,7 @@ F 5 "0022232021" H 4500 2300 50 0001 C CNN "manf#" F 6 "WM2700-ND" H 4500 2300 50 0001 C CNN "digikey_alt#" F 7 "538-22-23-2021" H 2850 2300 50 0001 C CNN "mouser#" F 8 "538-22-11-2022" H 2850 2300 50 0001 C CNN "mouser_alt#" +F 9 "C234180" H 2850 2300 50 0001 C CNN "LCSC#" 1 4500 2300 -1 0 0 -1 $EndComp @@ -60,6 +62,7 @@ F 5 "CR0805-JW-102ELF" V 3450 2300 50 0001 C CNN "manf#" F 6 "CRS0805-JX-102ELFCT-ND" V 3450 2300 50 0001 C CNN "digikey_alt#" F 7 "652-CR0805JW-102ELF" H 2850 2300 50 0001 C CNN "mouser#" F 8 "652-CRS0805JX102ELF" H 2850 2300 50 0001 C CNN "mouser_alt#" +F 9 "C840623" H 2850 2300 50 0001 C CNN "LCSC#" 1 3450 2300 0 1 1 0 $EndComp @@ -77,6 +80,7 @@ F 6 "DNF" H 3750 2500 50 0001 C CNN "Config" F 7 "399-1149-1-ND" H 3750 2500 50 0001 C CNN "digikey_alt#" F 8 "80-C0805C102K5R" H 2850 2300 50 0001 C CNN "mouser#" F 9 "80-C0805C102K5R7210" H 2850 2300 50 0001 C CNN "mouser_alt#" +F 10 "C2167366" H 2850 2300 50 0001 C CNN "LCSC#" 1 3750 2500 1 0 0 -1 $EndComp diff --git a/tests/board_samples/kicad_6/links.kicad_sch b/tests/board_samples/kicad_6/links.kicad_sch index d2aa78145..26ef99c60 100644 --- a/tests/board_samples/kicad_6/links.kicad_sch +++ b/tests/board_samples/kicad_6/links.kicad_sch @@ -245,6 +245,9 @@ (property "mouser_alt#" "538-22-11-2022" (id 4) (at 72.39 58.42 0) (effects (font (size 1.27 1.27)) hide) ) + (property "LCSC#" "C234180" (at 72.39 58.42 0) + (effects (font (size 1.27 1.27)) hide) + ) (pin "1" (uuid 3a983f51-42e8-405a-9e04-43b2dcabad73)) (pin "2" (uuid 44467fec-706c-4fae-80bc-b9e34c67559e)) ) @@ -279,6 +282,9 @@ (property "mouser_alt#" "538-22-11-2022" (id 4) (at 72.39 58.42 0) (effects (font (size 1.27 1.27)) hide) ) + (property "LCSC#" "C234180" (at 72.39 58.42 0) + (effects (font (size 1.27 1.27)) hide) + ) (pin "1" (uuid 23133abe-63f6-4718-9f66-696cfc78619f)) (pin "2" (uuid 8d936772-f6fa-4d42-bb01-ee988a455edf)) ) @@ -309,6 +315,9 @@ (property "mouser_alt#" "652-CRS0805JX102ELF" (id 4) (at 72.39 58.42 0) (effects (font (size 1.27 1.27)) hide) ) + (property "LCSC#" "C840623" (at 72.39 58.42 0) + (effects (font (size 1.27 1.27)) hide) + ) (pin "1" (uuid 2de833b3-282a-488d-ba66-338c569a1889)) (pin "2" (uuid 60a539f2-60cc-48f9-87ad-8cf3118ca160)) ) @@ -346,6 +355,9 @@ (property "mouser_alt#" "80-C0805C102K5R7210" (id 4) (at 72.39 58.42 0) (effects (font (size 1.27 1.27)) hide) ) + (property "LCSC#" "C2167366" (at 72.39 58.42 0) + (effects (font (size 1.27 1.27)) hide) + ) (pin "1" (uuid 67b819b7-12c7-4dd7-bd3a-61ec6664e433)) (pin "2" (uuid 751f729a-b418-440a-860e-106b8be28d8c)) ) diff --git a/tests/board_samples/kicad_7/links.kicad_sch b/tests/board_samples/kicad_7/links.kicad_sch index 3d604820a..f41159dd2 100644 --- a/tests/board_samples/kicad_7/links.kicad_sch +++ b/tests/board_samples/kicad_7/links.kicad_sch @@ -249,6 +249,9 @@ (property "mouser_alt#" "538-22-11-2022" (at 72.39 58.42 0) (effects (font (size 1.27 1.27)) hide) ) + (property "LCSC#" "C234180" (at 72.39 58.42 0) + (effects (font (size 1.27 1.27)) hide) + ) (pin "1" (uuid 3a983f51-42e8-405a-9e04-43b2dcabad73)) (pin "2" (uuid 44467fec-706c-4fae-80bc-b9e34c67559e)) (instances @@ -290,6 +293,9 @@ (property "mouser_alt#" "538-22-11-2022" (at 72.39 58.42 0) (effects (font (size 1.27 1.27)) hide) ) + (property "LCSC#" "C234180" (at 72.39 58.42 0) + (effects (font (size 1.27 1.27)) hide) + ) (pin "1" (uuid 23133abe-63f6-4718-9f66-696cfc78619f)) (pin "2" (uuid 8d936772-f6fa-4d42-bb01-ee988a455edf)) (instances @@ -331,6 +337,9 @@ (property "mouser_alt#" "652-CRS0805JX102ELF" (at 72.39 58.42 0) (effects (font (size 1.27 1.27)) hide) ) + (property "LCSC#" "C840623" (at 72.39 58.42 0) + (effects (font (size 1.27 1.27)) hide) + ) (pin "1" (uuid 2de833b3-282a-488d-ba66-338c569a1889)) (pin "2" (uuid 60a539f2-60cc-48f9-87ad-8cf3118ca160)) (instances @@ -375,6 +384,9 @@ (property "mouser_alt#" "80-C0805C102K5R7210" (at 72.39 58.42 0) (effects (font (size 1.27 1.27)) hide) ) + (property "LCSC#" "C2167366" (at 72.39 58.42 0) + (effects (font (size 1.27 1.27)) hide) + ) (pin "1" (uuid 67b819b7-12c7-4dd7-bd3a-61ec6664e433)) (pin "2" (uuid 751f729a-b418-440a-860e-106b8be28d8c)) (instances diff --git a/tests/board_samples/kicad_8/links.kicad_sch b/tests/board_samples/kicad_8/links.kicad_sch index 3d604820a..f41159dd2 100644 --- a/tests/board_samples/kicad_8/links.kicad_sch +++ b/tests/board_samples/kicad_8/links.kicad_sch @@ -249,6 +249,9 @@ (property "mouser_alt#" "538-22-11-2022" (at 72.39 58.42 0) (effects (font (size 1.27 1.27)) hide) ) + (property "LCSC#" "C234180" (at 72.39 58.42 0) + (effects (font (size 1.27 1.27)) hide) + ) (pin "1" (uuid 3a983f51-42e8-405a-9e04-43b2dcabad73)) (pin "2" (uuid 44467fec-706c-4fae-80bc-b9e34c67559e)) (instances @@ -290,6 +293,9 @@ (property "mouser_alt#" "538-22-11-2022" (at 72.39 58.42 0) (effects (font (size 1.27 1.27)) hide) ) + (property "LCSC#" "C234180" (at 72.39 58.42 0) + (effects (font (size 1.27 1.27)) hide) + ) (pin "1" (uuid 23133abe-63f6-4718-9f66-696cfc78619f)) (pin "2" (uuid 8d936772-f6fa-4d42-bb01-ee988a455edf)) (instances @@ -331,6 +337,9 @@ (property "mouser_alt#" "652-CRS0805JX102ELF" (at 72.39 58.42 0) (effects (font (size 1.27 1.27)) hide) ) + (property "LCSC#" "C840623" (at 72.39 58.42 0) + (effects (font (size 1.27 1.27)) hide) + ) (pin "1" (uuid 2de833b3-282a-488d-ba66-338c569a1889)) (pin "2" (uuid 60a539f2-60cc-48f9-87ad-8cf3118ca160)) (instances @@ -375,6 +384,9 @@ (property "mouser_alt#" "80-C0805C102K5R7210" (at 72.39 58.42 0) (effects (font (size 1.27 1.27)) hide) ) + (property "LCSC#" "C2167366" (at 72.39 58.42 0) + (effects (font (size 1.27 1.27)) hide) + ) (pin "1" (uuid 67b819b7-12c7-4dd7-bd3a-61ec6664e433)) (pin "2" (uuid 751f729a-b418-440a-860e-106b8be28d8c)) (instances diff --git a/tests/test_plot/test_int_bom.py b/tests/test_plot/test_int_bom.py index f563e8544..9daa672ed 100644 --- a/tests/test_plot/test_int_bom.py +++ b/tests/test_plot/test_int_bom.py @@ -88,7 +88,8 @@ len(KIBOM_TEST_COMPONENTS)] LINKS_STATS = [3, '4 (2 SMD/ 2 THT)', '3 (1 SMD/ 2 THT)', 1, 3] VARIANTE_PRJ_INFO = ['kibom-variante', 'default', 'A', '2020-03-12', None] -LINK_HEAD = ['References', 'Part', 'Value', 'Quantity Per PCB', 'digikey#', 'digikey_alt#', 'mouser#', 'mouser_alt#', 'manf#'] +LINK_HEAD = ['References', 'Part', 'Value', 'Quantity Per PCB', 'digikey#', 'digikey_alt#', 'mouser#', 'mouser_alt#', 'LCSC#', + 'manf#'] LINKS_COMPONENTS = ['J1', 'J2', 'R1'] LINKS_EXCLUDE = ['C1'] LINKS_GROUPS = 2 @@ -576,6 +577,7 @@ def test_int_bom_digikey_link(test_dir): ref_column = headers[0].index(REF_COLUMN_NAME) dk_column = headers[0].index('digikey#') mo_column = headers[0].index('mouser#') + lcsc_column = headers[0].index('LCSC#') # Check the normal table check_kibom_test_netlist(rows[0], ref_column, LINKS_GROUPS, LINKS_EXCLUDE, LINKS_COMPONENTS) # Check the DNF table @@ -591,6 +593,11 @@ def test_int_bom_digikey_link(test_dir): assert c.strip().startswith('