Skip to content

Commit

Permalink
Implement suppliers and supplier part numbers (#241)
Browse files Browse the repository at this point in the history
Co-authored-by: kvid <[email protected]>
  • Loading branch information
formatc1702 and kvid authored Sep 14, 2021
1 parent db05514 commit a3eefe6
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 26 deletions.
18 changes: 14 additions & 4 deletions docs/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,10 @@ tweak: # optional tweaking of .gv output
# product information (all optional)
ignore_in_bom: <bool> # if set to true the connector is not added to the BOM
pn: <str> # [internal] part number
mpn: <str> # manufacturer part number
manufacturer: <str> # manufacturer name
mpn: <str> # manufacturer part number
supplier: <str> # supplier name
spn: <str> # supplier part number
additional_components: # additional components
- <additional-component> # additional component (see below)

Expand Down Expand Up @@ -175,8 +177,10 @@ Since the auto-incremented and auto-assigned designator is not known to the user
# product information (all optional)
ignore_in_bom: <bool> # if set to true the cable or wires are not added to the BOM
pn: <str> # [internal] part number
mpn: <str> # manufacturer part number
manufacturer: <str> # manufacturer name
mpn: <str> # manufacturer part number
supplier: <str> # supplier name
spn: <str> # supplier part number
additional_components: # additional components
- <additional-component> # additional component (see below)

Expand Down Expand Up @@ -311,8 +315,10 @@ Parts can be added to a connector or cable in the section `<additional-component
# total_length sum of lengths of each wire in the bundle
unit: <str>
pn: <str> # [internal] part number
mpn: <str> # manufacturer part number
manufacturer: <str> # manufacturer name
mpn: <str> # manufacturer part number
supplier: <str> # supplier name
spn: <str> # supplier part number
```
Alternatively items can be added to just the BOM by putting them in the section `<bom-item>` above.
Expand All @@ -325,8 +331,10 @@ Alternatively items can be added to just the BOM by putting them in the section
unit: <str>
designators: <List>
pn: <str> # [internal] part number
mpn: <str> # manufacturer part number
manufacturer: <str> # manufacturer name
mpn: <str> # manufacturer part number
supplier: <str> # supplier name
spn: <str> # supplier part number
```

## GraphViz tweaking (experimental)
Expand Down Expand Up @@ -429,6 +437,8 @@ The following attributes accept multiline strings:
- `notes`
- `manufacturer`
- `mpn`
- `supplier`
- `spn`
- `image.caption`
- `tweak.append`

Expand Down
8 changes: 7 additions & 1 deletion src/wireviz/DataClasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ class AdditionalComponent:
subtype: Optional[MultilineHypertext] = None
manufacturer: Optional[MultilineHypertext] = None
mpn: Optional[MultilineHypertext] = None
supplier: Optional[MultilineHypertext] = None
spn: Optional[MultilineHypertext] = None
pn: Optional[Hypertext] = None
qty: float = 1
unit: Optional[str] = None
Expand All @@ -122,6 +124,8 @@ class Connector:
name: Designator
manufacturer: Optional[MultilineHypertext] = None
mpn: Optional[MultilineHypertext] = None
supplier: Optional[MultilineHypertext] = None
spn: Optional[MultilineHypertext] = None
pn: Optional[Hypertext] = None
style: Optional[str] = None
category: Optional[str] = None
Expand Down Expand Up @@ -204,6 +208,8 @@ class Cable:
name: Designator
manufacturer: Union[MultilineHypertext, List[MultilineHypertext], None] = None
mpn: Union[MultilineHypertext, List[MultilineHypertext], None] = None
supplier: Union[MultilineHypertext, List[MultilineHypertext], None] = None
spn: Union[MultilineHypertext, List[MultilineHypertext], None] = None
pn: Union[Hypertext, List[Hypertext], None] = None
category: Optional[str] = None
type: Optional[MultilineHypertext] = None
Expand Down Expand Up @@ -294,7 +300,7 @@ def __post_init__(self) -> None:
raise Exception('"s" may not be used as a wire label for a shielded cable.')

# if lists of part numbers are provided check this is a bundle and that it matches the wirecount.
for idfield in [self.manufacturer, self.mpn, self.pn]:
for idfield in [self.manufacturer, self.mpn, self.supplier, self.spn, self.pn]:
if isinstance(idfield, list):
if self.category == "bundle":
# check the length
Expand Down
29 changes: 20 additions & 9 deletions src/wireviz/Harness.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
from wireviz.wv_colors import get_color_hex, translate_color
from wireviz.wv_gv_html import nested_html_table, html_colorbar, html_image, \
html_caption, remove_links, html_line_breaks
from wireviz.wv_bom import manufacturer_info_field, component_table_entry, \
get_additional_component_table, bom_list, generate_bom
from wireviz.wv_bom import pn_info_string, component_table_entry, \
get_additional_component_table, bom_list, generate_bom, \
HEADER_PN, HEADER_MPN, HEADER_SPN
from wireviz.wv_html import generate_html_output
from wireviz.wv_helper import awg_equiv, mm2_equiv, tuplelist2tsv, flatten2d, \
open_file_read, open_file_write
Expand Down Expand Up @@ -125,8 +126,9 @@ def create_graph(self) -> Graph:
html = []

rows = [[remove_links(connector.name) if connector.show_name else None],
[f'P/N: {remove_links(connector.pn)}' if connector.pn else None,
html_line_breaks(manufacturer_info_field(connector.manufacturer, connector.mpn))],
[pn_info_string(HEADER_PN, None, remove_links(connector.pn)),
html_line_breaks(pn_info_string(HEADER_MPN, connector.manufacturer, connector.mpn)),
html_line_breaks(pn_info_string(HEADER_SPN, connector.supplier, connector.spn))],
[html_line_breaks(connector.type),
html_line_breaks(connector.subtype),
f'{connector.pincount}-pin' if connector.show_pincount else None,
Expand Down Expand Up @@ -208,10 +210,14 @@ def create_graph(self) -> Graph:
awg_fmt = f' ({mm2_equiv(cable.gauge)} mm\u00B2)'

rows = [[remove_links(cable.name) if cable.show_name else None],
[f'P/N: {remove_links(cable.pn)}' if (cable.pn and not isinstance(cable.pn, list)) else None,
html_line_breaks(manufacturer_info_field(
[pn_info_string(HEADER_PN, None,
remove_links(cable.pn)) if not isinstance(cable.pn, list) else None,
html_line_breaks(pn_info_string(HEADER_MPN,
cable.manufacturer if not isinstance(cable.manufacturer, list) else None,
cable.mpn if not isinstance(cable.mpn, list) else None))],
cable.mpn if not isinstance(cable.mpn, list) else None)),
html_line_breaks(pn_info_string(HEADER_SPN,
cable.supplier if not isinstance(cable.supplier, list) else None,
cable.spn if not isinstance(cable.spn, list) else None))],
[html_line_breaks(cable.type),
f'{cable.wirecount}x' if cable.show_wirecount else None,
f'{cable.gauge} {cable.gauge_unit}{awg_fmt}' if cable.gauge else None,
Expand Down Expand Up @@ -263,12 +269,17 @@ def create_graph(self) -> Graph:
# create a list of wire parameters
wireidentification = []
if isinstance(cable.pn, list):
wireidentification.append(f'P/N: {remove_links(cable.pn[i - 1])}')
manufacturer_info = manufacturer_info_field(
wireidentification.append(pn_info_string(HEADER_PN, None, remove_links(cable.pn[i - 1])))
manufacturer_info = pn_info_string(HEADER_MPN,
cable.manufacturer[i - 1] if isinstance(cable.manufacturer, list) else None,
cable.mpn[i - 1] if isinstance(cable.mpn, list) else None)
supplier_info = pn_info_string(HEADER_SPN,
cable.supplier[i - 1] if isinstance(cable.supplier, list) else None,
cable.spn[i - 1] if isinstance(cable.spn, list) else None)
if manufacturer_info:
wireidentification.append(html_line_breaks(manufacturer_info))
if supplier_info:
wireidentification.append(html_line_breaks(supplier_info))
# print parameters into a table row under the wire
if len(wireidentification) > 0 :
wirehtml.append(' <tr><td colspan="3">')
Expand Down
34 changes: 22 additions & 12 deletions src/wireviz/wv_bom.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@
from wireviz.wv_helper import clean_whitespace

BOM_COLUMNS_ALWAYS = ('id', 'description', 'qty', 'unit', 'designators')
BOM_COLUMNS_OPTIONAL = ('pn', 'manufacturer', 'mpn')
BOM_COLUMNS_OPTIONAL = ('pn', 'manufacturer', 'mpn', 'supplier', 'spn')
BOM_COLUMNS_IN_KEY = ('description', 'unit') + BOM_COLUMNS_OPTIONAL

HEADER_PN = 'P/N'
HEADER_MPN = 'MPN'
HEADER_SPN = 'SPN'

BOMKey = Tuple[str, ...]
BOMColumn = str # = Literal[*BOM_COLUMNS_ALWAYS, *BOM_COLUMNS_OPTIONAL]
BOMEntry = Dict[BOMColumn, Union[str, int, float, List[str], None]]
Expand Down Expand Up @@ -143,8 +147,9 @@ def bom_list(bom: List[BOMEntry]) -> List[List[str]]:
# Custom mapping from internal name to BOM column headers.
# Headers not specified here are generated by capitilising the internal name.
bom_headings = {
"pn": "P/N",
"mpn": "MPN"
'pn': HEADER_PN,
'mpn': HEADER_MPN,
'spn': HEADER_SPN,
}
return ([[bom_headings.get(k, k.capitalize()) for k in keys]] + # Create header row with key names
[[make_str(entry.get(k)) for k in keys] for entry in bom]) # Create string list for each entry row
Expand All @@ -156,26 +161,31 @@ def component_table_entry(
pn: Optional[str] = None,
manufacturer: Optional[str] = None,
mpn: Optional[str] = None,
supplier: Optional[str] = None,
spn: Optional[str] = None,
) -> str:
"""Return a diagram node table row string with an additional component."""
manufacturer_str = manufacturer_info_field(manufacturer, mpn)
part_number_list = [
pn_info_string(HEADER_PN, None, pn),
pn_info_string(HEADER_MPN, manufacturer, mpn),
pn_info_string(HEADER_SPN, supplier, spn),
]
output = (f'{qty}'
+ (f' {unit}' if unit else '')
+ f' x {type}'
+ ('<br/>' if pn or manufacturer_str else '')
+ (f'P/N: {pn}' if pn else '')
+ (', ' if pn and manufacturer_str else '')
+ (manufacturer_str or ''))
+ ('<br/>' if any(part_number_list) else '')
+ (', '.join([pn for pn in part_number_list if pn])))
# format the above output as left aligned text in a single visible cell
# indent is set to two to match the indent in the generated html table
return f'''<table border="0" cellspacing="0" cellpadding="3" cellborder="1"><tr>
<td align="left" balign="left">{html_line_breaks(output)}</td>
</tr></table>'''

def manufacturer_info_field(manufacturer: Optional[str], mpn: Optional[str]) -> Optional[str]:
"""Return the manufacturer and/or the mpn in one single string or None otherwise."""
if manufacturer or mpn:
return f'{manufacturer if manufacturer else "MPN"}{": " + str(mpn) if mpn else ""}'
def pn_info_string(header: str, name: Optional[str], number: Optional[str]) -> Optional[str]:
"""Return the company name and/or the part number in one single string or None otherwise."""
number = str(number).strip() if number is not None else ''
if name or number:
return f'{name if name else header}{": " + number if number else ""}'
else:
return None

Expand Down
17 changes: 17 additions & 0 deletions tutorial/tutorial08.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
options:
mini_bom_mode: false

connectors:
X1: &template1 # define a template for later use
type: Molex KK 254
pincount: 4
subtype: female
manufacturer: '<a href="https://www.molex.com/">Molex</a>' # set manufacter name
mpn: '<a href="https://www.molex.com/molex/products/part-detail/crimp_housings/0022013047">22013047</a>' # set manufacturer part number
supplier: Digimouse
spn: 1234
# add a list of additional components to a part (shown in graph)
additional_components:
-
Expand All @@ -13,6 +18,14 @@ connectors:
qty_multiplier: populated # multipier for quantity (number of populated pins)
manufacturer: Molex # set manufacter name
mpn: 08500030 # set manufacturer part number
-
type: Test
qty: 1
pn: ABC
manufacturer: Molex
mpn: 45454
supplier: Mousikey
spn: 9999
X2:
<<: *template1 # reuse template
pn: CON4 # set an internal part number for just this connector
Expand All @@ -27,6 +40,8 @@ cables:
color_code: IEC
manufacturer: CablesCo
mpn: ABC123
supplier: Cables R Us
spn: 999-888-777
pn: CAB1
W2:
category: bundle
Expand All @@ -35,6 +50,8 @@ cables:
colors: [YE, BK, BK, RD]
manufacturer: [WiresCo,WiresCo,WiresCo,WiresCo] # set a manufacter per wire
mpn: [W1-YE,W1-BK,W1-BK,W1-RD]
supplier: [WireShack,WireShack,WireShack,WireShack]
spn: [1001,1002,1002,1009]
pn: [WIRE1,WIRE2,WIRE2,WIRE3]
# add a list of additional components to a part (shown in graph)
additional_components:
Expand Down

0 comments on commit a3eefe6

Please sign in to comment.