Eliminate ferrule category, unify connectors (#78)
This commit is contained in:
parent
cae16bf440
commit
831b423c03
@ -13,6 +13,7 @@ class Connector:
|
|||||||
manufacturer: Optional[str] = None
|
manufacturer: Optional[str] = None
|
||||||
manufacturer_part_number: Optional[str] = None
|
manufacturer_part_number: Optional[str] = None
|
||||||
internal_part_number: Optional[str] = None
|
internal_part_number: Optional[str] = None
|
||||||
|
style: Optional[str] = None
|
||||||
category: Optional[str] = None
|
category: Optional[str] = None
|
||||||
type: Optional[str] = None
|
type: Optional[str] = None
|
||||||
subtype: Optional[str] = None
|
subtype: Optional[str] = None
|
||||||
@ -21,8 +22,8 @@ class Connector:
|
|||||||
pinout: List[Any] = field(default_factory=list)
|
pinout: List[Any] = field(default_factory=list)
|
||||||
pinnumbers: List[Any] = field(default_factory=list)
|
pinnumbers: List[Any] = field(default_factory=list)
|
||||||
color: Optional[str] = None
|
color: Optional[str] = None
|
||||||
show_name: bool = True
|
show_name: bool = None
|
||||||
show_pincount: bool = True
|
show_pincount: bool = None
|
||||||
hide_disconnected_pins: bool = False
|
hide_disconnected_pins: bool = False
|
||||||
autogenerate: bool = False
|
autogenerate: bool = False
|
||||||
loops: List[Any] = field(default_factory=list)
|
loops: List[Any] = field(default_factory=list)
|
||||||
@ -32,13 +33,16 @@ class Connector:
|
|||||||
self.ports_right = False
|
self.ports_right = False
|
||||||
self.visible_pins = {}
|
self.visible_pins = {}
|
||||||
|
|
||||||
|
if self.style == 'simple':
|
||||||
|
if self.pincount and self.pincount > 1:
|
||||||
|
raise Exception('Connectors with style set to simple may only have one pin')
|
||||||
|
self.pincount = 1
|
||||||
|
|
||||||
if self.pincount is None:
|
if self.pincount is None:
|
||||||
if self.pinout:
|
if self.pinout:
|
||||||
self.pincount = len(self.pinout)
|
self.pincount = len(self.pinout)
|
||||||
elif self.pinnumbers:
|
elif self.pinnumbers:
|
||||||
self.pincount = len(self.pinnumbers)
|
self.pincount = len(self.pinnumbers)
|
||||||
elif self.category == 'ferrule':
|
|
||||||
self.pincount = 1
|
|
||||||
else:
|
else:
|
||||||
raise Exception('You need to specify at least one, pincount, pinout or pinnumbers')
|
raise Exception('You need to specify at least one, pincount, pinout or pinnumbers')
|
||||||
|
|
||||||
@ -55,6 +59,12 @@ class Connector:
|
|||||||
if len(self.pinnumbers) != len(set(self.pinnumbers)):
|
if len(self.pinnumbers) != len(set(self.pinnumbers)):
|
||||||
raise Exception('Pin numbers are not unique')
|
raise Exception('Pin numbers are not unique')
|
||||||
|
|
||||||
|
if self.show_name is None:
|
||||||
|
self.show_name = not self.autogenerate # hide auto-generated designators by default
|
||||||
|
|
||||||
|
if self.show_pincount is None:
|
||||||
|
self.show_pincount = self.style != 'simple' # hide pincount for simple (1 pin) connectors by default
|
||||||
|
|
||||||
for loop in self.loops:
|
for loop in self.loops:
|
||||||
# TODO: check that pins to connect actually exist
|
# TODO: check that pins to connect actually exist
|
||||||
# TODO: allow using pin labels in addition to pin numbers, just like when defining regular connections
|
# TODO: allow using pin labels in addition to pin numbers, just like when defining regular connections
|
||||||
|
|||||||
@ -86,34 +86,24 @@ class Harness:
|
|||||||
self.connectors[connection_color.to_name].ports_left = True
|
self.connectors[connection_color.to_name].ports_left = True
|
||||||
|
|
||||||
for key, connector in self.connectors.items():
|
for key, connector in self.connectors.items():
|
||||||
if connector.category == 'ferrule':
|
|
||||||
|
|
||||||
rows = [[connector.manufacturer,
|
rows = [[connector.name if connector.show_name else None],
|
||||||
f'MPN: {connector.manufacturer_part_number}' if connector.manufacturer_part_number else None,
|
[connector.manufacturer,
|
||||||
f'IPN: {connector.internal_part_number}' if connector.internal_part_number else None],
|
f'MPN: {connector.manufacturer_part_number}' if connector.manufacturer_part_number else None,
|
||||||
[html_line_breaks(connector.type), html_line_breaks(connector.subtype), connector.color, '<!-- colorbar -->' if connector.color else None],
|
f'IPN: {connector.internal_part_number}' if connector.internal_part_number else None],
|
||||||
[html_line_breaks(connector.notes)]]
|
[html_line_breaks(connector.type),
|
||||||
html = nested_html_table(rows)
|
html_line_breaks(connector.subtype),
|
||||||
|
f'{connector.pincount}-pin' if connector.show_pincount else None,
|
||||||
|
connector.color, '<!-- colorbar -->' if connector.color else None],
|
||||||
|
'<!-- connector table -->' if connector.style != 'simple' else None,
|
||||||
|
[html_line_breaks(connector.notes)]]
|
||||||
|
html = nested_html_table(rows)
|
||||||
|
|
||||||
if connector.color: # add color bar next to color info, if present
|
if connector.color: # add color bar next to color info, if present
|
||||||
colorbar = f' bgcolor="{wv_colors.translate_color(connector.color, "HEX")}" width="4"></td>' # leave out '<td' from string to preserve any existing attributes of the <td> tag
|
colorbar = f' bgcolor="{wv_colors.translate_color(connector.color, "HEX")}" width="4"></td>' # leave out '<td' from string to preserve any existing attributes of the <td> tag
|
||||||
html = html.replace('><!-- colorbar --></td>', colorbar)
|
html = html.replace('><!-- colorbar --></td>', colorbar)
|
||||||
|
|
||||||
dot.node(key, label=f'<{html}>', shape='none', margin='0', style='filled', fillcolor='white')
|
|
||||||
|
|
||||||
else: # not a ferrule
|
|
||||||
|
|
||||||
rows = [[connector.name if connector.show_name else None],
|
|
||||||
[connector.manufacturer,
|
|
||||||
f'MPN: {connector.manufacturer_part_number}' if connector.manufacturer_part_number else None,
|
|
||||||
f'IPN: {connector.internal_part_number}' if connector.internal_part_number else None],
|
|
||||||
[html_line_breaks(connector.type),
|
|
||||||
html_line_breaks(connector.subtype),
|
|
||||||
f'{connector.pincount}-pin' if connector.show_pincount else None],
|
|
||||||
'<!-- connector table -->',
|
|
||||||
[html_line_breaks(connector.notes)]]
|
|
||||||
html = nested_html_table(rows)
|
|
||||||
|
|
||||||
|
if connector.style != 'simple':
|
||||||
pinouts = []
|
pinouts = []
|
||||||
for pinnumber, pinname in zip(connector.pinnumbers, connector.pinout):
|
for pinnumber, pinname in zip(connector.pinnumbers, connector.pinout):
|
||||||
if connector.hide_disconnected_pins and not connector.visible_pins.get(pinnumber, False):
|
if connector.hide_disconnected_pins and not connector.visible_pins.get(pinnumber, False):
|
||||||
@ -132,21 +122,22 @@ class Harness:
|
|||||||
pinhtml = f'{pinhtml}</table>'
|
pinhtml = f'{pinhtml}</table>'
|
||||||
html = html.replace('<!-- connector table -->', pinhtml)
|
html = html.replace('<!-- connector table -->', pinhtml)
|
||||||
|
|
||||||
dot.node(key, label=f'<{html}>', shape='none', margin='0', style='filled', fillcolor='white')
|
|
||||||
|
|
||||||
if len(connector.loops) > 0:
|
dot.node(key, label=f'<{html}>', shape='none', margin='0', style='filled', fillcolor='white')
|
||||||
dot.attr('edge', color='#000000:#ffffff:#000000')
|
|
||||||
if connector.ports_left:
|
if len(connector.loops) > 0:
|
||||||
loop_side = 'l'
|
dot.attr('edge', color='#000000:#ffffff:#000000')
|
||||||
loop_dir = 'w'
|
if connector.ports_left:
|
||||||
elif connector.ports_right:
|
loop_side = 'l'
|
||||||
loop_side = 'r'
|
loop_dir = 'w'
|
||||||
loop_dir = 'e'
|
elif connector.ports_right:
|
||||||
else:
|
loop_side = 'r'
|
||||||
raise Exception('No side for loops')
|
loop_dir = 'e'
|
||||||
for loop in connector.loops:
|
else:
|
||||||
dot.edge(f'{connector.name}:p{loop[0]}{loop_side}:{loop_dir}',
|
raise Exception('No side for loops')
|
||||||
f'{connector.name}:p{loop[1]}{loop_side}:{loop_dir}')
|
for loop in connector.loops:
|
||||||
|
dot.edge(f'{connector.name}:p{loop[0]}{loop_side}:{loop_dir}',
|
||||||
|
f'{connector.name}:p{loop[1]}{loop_side}:{loop_dir}')
|
||||||
|
|
||||||
for _, cable in self.cables.items():
|
for _, cable in self.cables.items():
|
||||||
|
|
||||||
@ -258,20 +249,18 @@ class Harness:
|
|||||||
# shield is shown as a thin tinned wire
|
# shield is shown as a thin tinned wire
|
||||||
dot.attr('edge', color=':'.join(['#000000', wv_colors.get_color_hex('SN', pad=False)[0], '#000000']))
|
dot.attr('edge', color=':'.join(['#000000', wv_colors.get_color_hex('SN', pad=False)[0], '#000000']))
|
||||||
if connection_color.from_port is not None: # connect to left
|
if connection_color.from_port is not None: # connect to left
|
||||||
from_ferrule = self.connectors[connection_color.from_name].category == 'ferrule'
|
from_port = f':p{connection_color.from_port}r' if self.connectors[connection_color.from_name].style != 'simple' else ''
|
||||||
port = f':p{connection_color.from_port}r' if not from_ferrule else ''
|
code_left_1 = f'{connection_color.from_name}{from_port}:e'
|
||||||
code_left_1 = f'{connection_color.from_name}{port}:e'
|
|
||||||
code_left_2 = f'{cable.name}:w{connection_color.via_port}:w'
|
code_left_2 = f'{cable.name}:w{connection_color.via_port}:w'
|
||||||
dot.edge(code_left_1, code_left_2)
|
dot.edge(code_left_1, code_left_2)
|
||||||
from_string = f'{connection_color.from_name}:{connection_color.from_port}' if not from_ferrule else ''
|
from_string = f'{connection_color.from_name}:{connection_color.from_port}' if self.connectors[connection_color.from_name].show_name else ''
|
||||||
html = html.replace(f'<!-- {connection_color.via_port}_in -->', from_string)
|
html = html.replace(f'<!-- {connection_color.via_port}_in -->', from_string)
|
||||||
if connection_color.to_port is not None: # connect to right
|
if connection_color.to_port is not None: # connect to right
|
||||||
to_ferrule = self.connectors[connection_color.to_name].category == 'ferrule'
|
|
||||||
code_right_1 = f'{cable.name}:w{connection_color.via_port}:e'
|
code_right_1 = f'{cable.name}:w{connection_color.via_port}:e'
|
||||||
to_port = f':p{connection_color.to_port}l' if not to_ferrule else ''
|
to_port = f':p{connection_color.to_port}l' if self.connectors[connection_color.to_name].style != 'simple' else ''
|
||||||
code_right_2 = f'{connection_color.to_name}{to_port}:w'
|
code_right_2 = f'{connection_color.to_name}{to_port}:w'
|
||||||
dot.edge(code_right_1, code_right_2)
|
dot.edge(code_right_1, code_right_2)
|
||||||
to_string = f'{connection_color.to_name}:{connection_color.to_port}' if not to_ferrule else ''
|
to_string = f'{connection_color.to_name}:{connection_color.to_port}' if self.connectors[connection_color.to_name].show_name else ''
|
||||||
html = html.replace(f'<!-- {connection_color.via_port}_out -->', to_string)
|
html = html.replace(f'<!-- {connection_color.via_port}_out -->', to_string)
|
||||||
|
|
||||||
dot.node(cable.name, label=f'<{html}>', shape='box',
|
dot.node(cable.name, label=f'<{html}>', shape='box',
|
||||||
@ -353,10 +342,10 @@ class Harness:
|
|||||||
designators.sort()
|
designators.sort()
|
||||||
conn_type = f', {remove_line_breaks(shared.type)}' if shared.type else ''
|
conn_type = f', {remove_line_breaks(shared.type)}' if shared.type else ''
|
||||||
conn_subtype = f', {remove_line_breaks(shared.subtype)}' if shared.subtype else ''
|
conn_subtype = f', {remove_line_breaks(shared.subtype)}' if shared.subtype else ''
|
||||||
conn_pincount = f', {shared.pincount} pins' if shared.category != 'ferrule' else ''
|
conn_pincount = f', {shared.pincount} pins' if shared.style != 'simple' else ''
|
||||||
conn_color = f', {shared.color}' if shared.color else ''
|
conn_color = f', {shared.color}' if shared.color else ''
|
||||||
name = f'Connector{conn_type}{conn_subtype}{conn_pincount}{conn_color}'
|
name = f'Connector{conn_type}{conn_subtype}{conn_pincount}{conn_color}'
|
||||||
item = {'item': name, 'qty': len(designators), 'unit': '', 'designators': designators if shared.category != 'ferrule' else '',
|
item = {'item': name, 'qty': len(designators), 'unit': '', 'designators': designators if shared.show_name else '',
|
||||||
'manufacturer': shared.manufacturer, 'manufacturer part number': shared.manufacturer_part_number, 'internal part number': shared.internal_part_number}
|
'manufacturer': shared.manufacturer, 'manufacturer part number': shared.manufacturer_part_number, 'internal part number': shared.internal_part_number}
|
||||||
bom_connectors.append(item)
|
bom_connectors.append(item)
|
||||||
bom_connectors = sorted(bom_connectors, key=lambda k: k['item']) # https://stackoverflow.com/a/73050
|
bom_connectors = sorted(bom_connectors, key=lambda k: k['item']) # https://stackoverflow.com/a/73050
|
||||||
|
|||||||
@ -37,8 +37,8 @@ def parse(yaml_input: str, file_out: (str, Path) = None, return_types: (None, st
|
|||||||
harness = Harness()
|
harness = Harness()
|
||||||
|
|
||||||
# add items
|
# add items
|
||||||
sections = ['connectors', 'cables', 'ferrules', 'connections']
|
sections = ['connectors', 'cables', 'connections']
|
||||||
types = [dict, dict, dict, list]
|
types = [dict, dict, list]
|
||||||
for sec, ty in zip(sections, types):
|
for sec, ty in zip(sections, types):
|
||||||
if sec in yaml_data and type(yaml_data[sec]) == ty:
|
if sec in yaml_data and type(yaml_data[sec]) == ty:
|
||||||
if len(yaml_data[sec]) > 0:
|
if len(yaml_data[sec]) > 0:
|
||||||
@ -49,8 +49,6 @@ def parse(yaml_input: str, file_out: (str, Path) = None, return_types: (None, st
|
|||||||
harness.add_connector(name=key, **attribs)
|
harness.add_connector(name=key, **attribs)
|
||||||
elif sec == 'cables':
|
elif sec == 'cables':
|
||||||
harness.add_cable(name=key, **attribs)
|
harness.add_cable(name=key, **attribs)
|
||||||
elif sec == 'ferrules':
|
|
||||||
pass
|
|
||||||
else:
|
else:
|
||||||
pass # section exists but is empty
|
pass # section exists but is empty
|
||||||
else: # section does not exist, create empty section
|
else: # section does not exist, create empty section
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user