[BoM][Added] LCSC links

From SchrodingersGat/KiBoM#190
This commit is contained in:
Salvador E. Tropea 2023-09-01 13:51:15 -03:00
parent 91f5bb81da
commit 390da80f7c
18 changed files with 111 additions and 6 deletions

View File

@ -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)

View File

@ -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

View File

@ -106,6 +106,9 @@ Parameters:
- ``hide_pcb_info`` :index:`: <pair: output - bom - options - html; hide_pcb_info>` [boolean=false] Hide project information.
- ``hide_stats_info`` :index:`: <pair: output - bom - options - html; hide_stats_info>` [boolean=false] Hide statistics information.
- ``highlight_empty`` :index:`: <pair: output - bom - options - html; highlight_empty>` [boolean=true] Use a color for empty cells. Applies only when `col_colors` is `true`.
- ``lcsc_link`` :index:`: <pair: output - bom - options - html; lcsc_link>` [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:`: <pair: output - bom - options - html; mouser_link>` [string|list(string)=''] Column/s containing Mouser part numbers, will be linked to web page.
- ``style`` :index:`: <pair: output - bom - options - html; style>` [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 <https://github.com/set-soft/kicost_ci_test>`__ repo.
- ``kicost_dist_desc`` :index:`: <pair: output - bom - options - xlsx; kicost_dist_desc>` [boolean=false] Used to add a column with the distributor's description. So you can check this is the right component.
- ``lcsc_link`` :index:`: <pair: output - bom - options - xlsx; lcsc_link>` [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:`: <pair: output - bom - options - xlsx; logo_scale>` [number=2] Scaling factor for the logo. Note that this value isn't honored by all spreadsheet software.
- ``max_col_width`` :index:`: <pair: output - bom - options - xlsx; max_col_width>` [number=60] [20,999] Maximum column width (characters).
- ``mouser_link`` :index:`: <pair: output - bom - options - xlsx; mouser_link>` [string|list(string)=''] Column/s containing Mouser part numbers, will be linked to web page.

View File

@ -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('<table class="content-table">\n')
@ -248,6 +249,8 @@ def content_table(html, groups, headings, head_names, cfg, link_datasheet, link_
r = '<a href="https://www.digikey.com/products/en?keywords=' + r + '">' + r + '</a>'
if link_mouser and headings[n] in link_mouser:
r = '<a href="https://www.mouser.com/ProductDetail/' + r + '">' + r + '</a>'
if link_lcsc and headings[n] in link_lcsc:
r = '<a href="https://www.lcsc.com/product-detail/' + r + '">' + r + '</a>'
# Link this column to the datasheet?
if link_datasheet == n and datasheet.startswith('http'):
r = '<a href="' + datasheet + '">' + r + '</a>'
@ -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("<h2>Component Groups</h2>\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("<h2>Optional components (DNF=Do Not Fit)</h2>\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:

View File

@ -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:

View File

@ -188,6 +188,9 @@ class BoMLinkable(Optionable):
""" [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 @@ class BoMLinkable(Optionable):
# *_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 = ''

View File

@ -135,6 +135,10 @@ class KiBoMConfig(Optionable):
""" [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 @@ class KiBoMConfig(Optionable):
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 @@ class KiBoMConfig(Optionable):
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')

View File

@ -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

View File

@ -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))
)

View File

@ -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

View File

@ -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

View File

@ -88,7 +88,8 @@ KIBOM_STATS = [KIBOM_TEST_GROUPS+len(KIBOM_TEST_EXCLUDE),
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('<a href')
assert 'mouser' in c
logging.debug(c + ' OK')
parts = get_column(rows[0]+rows[1], lcsc_column, False)
for c in parts:
assert c.strip().startswith('<a href')
assert 'lcsc.com' in c
logging.debug(c + ' OK')
ctx.clean_up()
@ -1212,6 +1219,16 @@ def test_int_bom_digikey_link_xlsx(test_dir):
assert c.strip().startswith('<a href')
assert 'digikey' in c
logging.debug(c + ' OK')
parts = get_column(rows+rows2, headers.index('LCSC#'), False)
for c in parts:
assert c.strip().startswith('<a href')
assert 'lcsc.com' in c
logging.debug(c + ' OK')
parts = get_column(rows+rows2, headers.index('mouser#'), False)
for c in parts:
assert c.strip().startswith('<a href')
assert 'mouser' in c
logging.debug(c + ' OK')
ctx.clean_up()

View File

@ -21,4 +21,5 @@ outputs:
- digikey_alt#
- mouser#
- mouser_alt#
- LCSC#
- manf#

View File

@ -24,4 +24,5 @@ outputs:
comment: "Alternative code in case digikey# isn't available"
- mouser#
- mouser_alt#
- LCSC#
- manf#

View File

@ -11,6 +11,7 @@ outputs:
html:
digikey_link: 'digikey#'
mouser_link: 'mouser#'
lcsc_link: 'LCSC#'
output: '%f.%x'
columns:
- References
@ -21,4 +22,5 @@ outputs:
- digikey_alt#
- mouser#
- mouser_alt#
- LCSC#
- manf#

View File

@ -11,6 +11,7 @@ outputs:
xlsx:
digikey_link: 'digikey#'
mouser_link: 'mouser#'
lcsc_link: 'LCSC#'
output: '%f.%x'
columns:
- References
@ -21,4 +22,5 @@ outputs:
- digikey_alt#
- mouser#
- mouser_alt#
- LCSC#
- manf#

View File

@ -21,4 +21,5 @@ outputs:
- digikey_alt#
- mouser#
- mouser_alt#
- LCSC#
- manf#

View File

@ -21,4 +21,5 @@ outputs:
- digikey_alt#
- mouser#
- mouser_alt#
- LCSC#
- manf#