Skip to content

Commit

Permalink
Add href attribute to connectors, cables, and additional_bom_items
Browse files Browse the repository at this point in the history
  • Loading branch information
kvid committed Sep 14, 2020
1 parent df90d83 commit c7c0820
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 18 deletions.
14 changes: 14 additions & 0 deletions examples/demo02.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ templates: # defining templates to be used later on
- &molex_f
type: Molex KK 254
subtype: female
href: "https://www.molex.com/molex/products/family/kk_254_rpc_connector_system"
- &con_i2c
pinlabels: [GND, +5V, SCL, SDA]
- &wire_i2c
category: bundle
gauge: 0.14 mm2
colors: [BK, RD, YE, GN]
href: [a, b, c, d]

connectors:
X1:
Expand Down Expand Up @@ -67,3 +69,15 @@ connections:
- ferrule_crimp
- W4: [1,2]
- X4: [1,2]

additional_bom_items:
- # define an additional item to add to the bill of materials
description: Label, pinout information
qty: 2
designators:
- X2
- X3
manufacturer: generic company
mpn: Label1
pn: Label-ID-1
href: "https://www.bradyid.com/wire-cable-labels/bmp71-bmp61-m611-tls-2200-nylon-cloth-wire-general-id-labels-cps-2958789"
2 changes: 2 additions & 0 deletions src/wireviz/DataClasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class Connector:
manufacturer: Optional[str] = None
mpn: Optional[str] = None
pn: Optional[str] = None
href: Optional[str] = None
style: Optional[str] = None
category: Optional[str] = None
type: Optional[str] = None
Expand Down Expand Up @@ -82,6 +83,7 @@ class Cable:
manufacturer: Optional[Union[str, List[str]]] = None
mpn: Optional[Union[str, List[str]]] = None
pn: Optional[Union[str, List[str]]] = None
href: Optional[str] = None
category: Optional[str] = None
type: Optional[str] = None
gauge: Optional[float] = None
Expand Down
49 changes: 31 additions & 18 deletions src/wireviz/Harness.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ def create_graph(self) -> Graph:
html = [row.replace('<!-- connector table -->', '\n'.join(pinhtml)) for row in html]

html = '\n'.join(html)
dot.node(connector.name, label=f'<\n{html}\n>', shape='none', margin='0', style='filled', fillcolor='white')
dot.node(connector.name, label=f'<\n{html}\n>', shape='none', href=connector.href,
margin='0', style='filled', fillcolor='white')

if len(connector.loops) > 0:
dot.attr('edge', color='#000000:#ffffff:#000000')
Expand Down Expand Up @@ -243,7 +244,8 @@ def create_graph(self) -> Graph:
# connections
for connection_color in cable.connections:
if isinstance(connection_color.via_port, int): # check if it's an actual wire and not a shield
dot.attr('edge', color=':'.join(['#000000'] + wv_colors.get_color_hex(cable.colors[connection_color.via_port - 1], pad=pad) + ['#000000']))
dot.attr('edge', color=':'.join(['#000000'] + wv_colors.get_color_hex(cable.colors[connection_color.via_port - 1], pad=pad) + ['#000000']),
href=index_if_list(cable.href, connection_color.via_port - 1) if cable.href else '')
else: # it's a shield connection
# shield is shown with specified color and black borders, or as a thin black wire otherwise
dot.attr('edge', color=':'.join(['#000000', shield_color_hex, '#000000']) if isinstance(cable.shield, str) else '#000000')
Expand All @@ -264,6 +266,7 @@ def create_graph(self) -> Graph:

html = '\n'.join(html)
dot.node(cable.name, label=f'<\n{html}\n>', shape='box',
href=cable.href if isinstance(cable.href, str) else None,
style='filled,dashed' if cable.category == 'bundle' else '', margin='0', fillcolor='white')

return dot
Expand Down Expand Up @@ -322,6 +325,8 @@ def output(self, filename: (str, Path), view: bool = False, cleanup: bool = True
file.write('<tr>')
for i, item in enumerate(row):
item_str = item.replace('\u00b2', '&sup2;')
if listy[0][i] == 'URL':
item_str = f'<a href="{item}">{item_str}</a>'
align = 'align="right"' if listy[0][i] == 'Qty' else ''
file.write(f'<td {align} style="border:1px solid #000000; padding: 4px">{item_str}</td>')
file.write('</tr>')
Expand All @@ -335,7 +340,7 @@ def bom(self):
bom_cables = []
bom_extra = []
# connectors
connector_group = lambda c: (c.type, c.subtype, c.pincount, c.manufacturer, c.mpn, c.pn)
connector_group = lambda c: (c.type, c.subtype, c.pincount, c.manufacturer, c.mpn, c.pn, c.href)
for group in Counter([connector_group(v) for v in self.connectors.values()]):
items = {k: v for k, v in self.connectors.items() if connector_group(v) == group}
shared = next(iter(items.values()))
Expand All @@ -346,15 +351,18 @@ def bom(self):
conn_pincount = f', {shared.pincount} pins' if shared.style != 'simple' else ''
conn_color = f', {shared.color}' if shared.color else ''
name = f'Connector{conn_type}{conn_subtype}{conn_pincount}{conn_color}'
item = {'item': name, 'qty': len(designators), 'unit': '', 'designators': designators if shared.show_name else '',
'manufacturer': remove_line_breaks(shared.manufacturer), 'mpn': remove_line_breaks(shared.mpn), 'pn': shared.pn}
item = {'item': name, 'qty': len(designators), 'unit': '',
'designators': designators if shared.show_name else '',
'manufacturer': remove_line_breaks(shared.manufacturer),
'mpn': remove_line_breaks(shared.mpn), 'pn': shared.pn,
'href': shared.href}
bom_connectors.append(item)
bom_connectors = sorted(bom_connectors, key=lambda k: k['item']) # https://stackoverflow.com/a/73050
bom.extend(bom_connectors)
# cables
# TODO: If category can have other non-empty values than 'bundle', maybe it should be part of item name?
# The category needs to be included in cable_group to keep the bundles excluded.
cable_group = lambda c: (c.category, c.type, c.gauge, c.gauge_unit, c.wirecount, c.shield, c.manufacturer, c.mpn, c.pn)
cable_group = lambda c: (c.category, c.type, c.gauge, c.gauge_unit, c.wirecount, c.shield, c.manufacturer, c.mpn, c.pn, c.href)
for group in Counter([cable_group(v) for v in self.cables.values() if v.category != 'bundle']):
items = {k: v for k, v in self.cables.items() if cable_group(v) == group}
shared = next(iter(items.values()))
Expand All @@ -365,8 +373,11 @@ def bom(self):
gauge_name = f' x {shared.gauge} {shared.gauge_unit}' if shared.gauge else ' wires'
shield_name = ' shielded' if shared.shield else ''
name = f'Cable{cable_type}, {shared.wirecount}{gauge_name}{shield_name}'
item = {'item': name, 'qty': round(total_length, 3), 'unit': 'm', 'designators': designators,
'manufacturer': remove_line_breaks(shared.manufacturer), 'mpn': remove_line_breaks(shared.mpn), 'pn': shared.pn}
item = {'item': name, 'qty': round(total_length, 3), 'unit': 'm',
'designators': designators,
'manufacturer': remove_line_breaks(shared.manufacturer),
'mpn': remove_line_breaks(shared.mpn), 'pn': shared.pn,
'href': shared.href}
bom_cables.append(item)
# bundles (ignores wirecount)
wirelist = []
Expand All @@ -378,9 +389,9 @@ def bom(self):
wirelist.append({'type': bundle.type, 'gauge': bundle.gauge, 'gauge_unit': bundle.gauge_unit, 'length': bundle.length, 'color': color, 'designator': bundle.name,
'manufacturer': remove_line_breaks(index_if_list(bundle.manufacturer, index)),
'mpn': remove_line_breaks(index_if_list(bundle.mpn, index)),
'pn': index_if_list(bundle.pn, index)})
'pn': index_if_list(bundle.pn, index), 'href': index_if_list(bundle.href, index)})
# join similar wires from all the bundles to a single BOM item
wire_group = lambda w: (w.get('type', None), w['gauge'], w['gauge_unit'], w['color'], w['manufacturer'], w['mpn'], w['pn'])
wire_group = lambda w: (w.get('type', None), w['gauge'], w['gauge_unit'], w['color'], w['manufacturer'], w['mpn'], w['pn'], w['href'])
for group in Counter([wire_group(v) for v in wirelist]):
items = [v for v in wirelist if wire_group(v) == group]
shared = items[0]
Expand All @@ -393,17 +404,18 @@ def bom(self):
gauge_color = f', {shared["color"]}' if 'color' in shared != '' else ''
name = f'Wire{wire_type}{gauge_name}{gauge_color}'
item = {'item': name, 'qty': round(total_length, 3), 'unit': 'm', 'designators': designators,
'manufacturer': shared['manufacturer'], 'mpn': shared['mpn'], 'pn': shared['pn']}
'manufacturer': shared['manufacturer'], 'mpn': shared['mpn'], 'pn': shared['pn'],
'href': shared['href']}
bom_cables.append(item)
bom_cables = sorted(bom_cables, key=lambda k: k['item']) # sort list of dicts by their values (https://stackoverflow.com/a/73050)
bom.extend(bom_cables)

for item in self.additional_bom_items:
name = item['description'] if item.get('description', None) else ''
if isinstance(item.get('designators', None), List):
name = item['description'] if item.get('description') else ''
if isinstance(item.get('designators'), List):
item['designators'].sort() # sort designators if a list is provided
item = {'item': name, 'qty': item.get('qty', None), 'unit': item.get('unit', None), 'designators': item.get('designators', None),
'manufacturer': item.get('manufacturer', None), 'mpn': item.get('mpn', None), 'pn': item.get('pn', None)}
item = {'item': name, 'qty': item.get('qty'), 'unit': item.get('unit'), 'designators': item.get('designators'),
'manufacturer': item.get('manufacturer'), 'mpn': item.get('mpn'), 'pn': item.get('pn'), 'href': item.get('href')}
bom_extra.append(item)
bom_extra = sorted(bom_extra, key=lambda k: k['item'])
bom.extend(bom_extra)
Expand All @@ -412,14 +424,15 @@ def bom(self):
def bom_list(self):
bom = self.bom()
keys = ['item', 'qty', 'unit', 'designators'] # these BOM columns will always be included
for fieldname in ['pn', 'manufacturer', 'mpn']: # these optional BOM columns will only be included if at least one BOM item actually uses them
if any(fieldname in x and x.get(fieldname, None) for x in bom):
for fieldname in ['pn', 'manufacturer', 'mpn', 'href']: # these optional BOM columns will only be included if at least one BOM item actually uses them
if any(item.get(fieldname) for item in bom):
keys.append(fieldname)
bom_list = []
# list of staic bom header names, headers not specified here are generated by capitilising the internal name
bom_headings = {
"pn": "P/N",
"mpn": "MPN"
"mpn": "MPN",
"href": "URL",
}
bom_list.append([(bom_headings[k] if k in bom_headings else k.capitalize()) for k in keys]) # create header row with keys
for item in bom:
Expand Down

0 comments on commit c7c0820

Please sign in to comment.