Improved part number support
Added internal part number and manufacturer fields Added support for wire part numbers in a bundle Moved part number information to seperate row in table
This commit is contained in:
parent
92b6b21895
commit
1ec9ca4f81
@ -89,8 +89,12 @@ class Harness:
|
|||||||
colorbar='<TD BGCOLOR="{}" BORDER="1" SIDES="LR" WIDTH="4"></TD>'.format(wv_colors.translate_color(n.color, 'HEX')) if n.color else ''))
|
colorbar='<TD BGCOLOR="{}" BORDER="1" SIDES="LR" WIDTH="4"></TD>'.format(wv_colors.translate_color(n.color, 'HEX')) if n.color else ''))
|
||||||
|
|
||||||
else: # not a ferrule
|
else: # not a ferrule
|
||||||
|
# id = identification
|
||||||
|
id = [n.manufacturer,
|
||||||
|
'MPN:{}'.format(n.manufacturer_part_number) if n.manufacturer_part_number else '',
|
||||||
|
'IPN:{}'.format(n.internal_part_number) if n.internal_part_number else '']
|
||||||
# a = attributes
|
# a = attributes
|
||||||
a = [n.part_number, n.type,
|
a = [n.type,
|
||||||
n.subtype,
|
n.subtype,
|
||||||
'{}-pin'.format(n.pincount) if n.show_pincount else '']
|
'{}-pin'.format(n.pincount) if n.show_pincount else '']
|
||||||
# p = pinout
|
# p = pinout
|
||||||
@ -104,7 +108,7 @@ class Harness:
|
|||||||
if n.ports_right:
|
if n.ports_right:
|
||||||
p[2].append('<p{portno}r>{portno}'.format(portno=pinnumber))
|
p[2].append('<p{portno}r>{portno}'.format(portno=pinnumber))
|
||||||
# l = label
|
# l = label
|
||||||
l = [n.name if n.show_name else '', a, p, n.notes]
|
l = [n.name if n.show_name else '', id, a, p, n.notes]
|
||||||
dot.node(k, label=nested(l))
|
dot.node(k, label=nested(l))
|
||||||
|
|
||||||
if len(n.loops) > 0:
|
if len(n.loops) > 0:
|
||||||
@ -122,9 +126,13 @@ class Harness:
|
|||||||
'{name}:p{port_to}{loop_side}:{loop_dir}'.format(name=n.name, port_from=loop[0], port_to=loop[1], loop_side=loop_side, loop_dir=loop_dir))
|
'{name}:p{port_to}{loop_side}:{loop_dir}'.format(name=n.name, port_from=loop[0], port_to=loop[1], loop_side=loop_side, loop_dir=loop_dir))
|
||||||
|
|
||||||
for k, c in self.cables.items():
|
for k, c in self.cables.items():
|
||||||
|
# id = identification
|
||||||
|
id = [c.manufacturer if not isinstance(c.manufacturer, list) else '',
|
||||||
|
'MPN:{}'.format(c.manufacturer_part_number) if (c.manufacturer_part_number and not isinstance(c.manufacturer_part_number, list)) else '',
|
||||||
|
'IPN:{}'.format(c.internal_part_number) if (c.internal_part_number and not isinstance(c.internal_part_number, list)) else '']
|
||||||
|
id = list(filter(None, id))
|
||||||
# a = attributes
|
# a = attributes
|
||||||
a = [c.part_number,
|
a = ['{}x'.format(len(c.colors)) if c.show_wirecount else '',
|
||||||
'{}x'.format(len(c.colors)) if c.show_wirecount else '',
|
|
||||||
'{} {}{}'.format(c.gauge, c.gauge_unit, ' ({} AWG)'.format(awg_equiv(c.gauge)) if c.gauge_unit == 'mm\u00B2' and c.show_equiv else '') if c.gauge else '', # TODO: show equiv
|
'{} {}{}'.format(c.gauge, c.gauge_unit, ' ({} AWG)'.format(awg_equiv(c.gauge)) if c.gauge_unit == 'mm\u00B2' and c.show_equiv else '') if c.gauge else '', # TODO: show equiv
|
||||||
'+ S' if c.shield else '',
|
'+ S' if c.shield else '',
|
||||||
'{} m'.format(c.length) if c.length > 0 else '']
|
'{} m'.format(c.length) if c.length > 0 else '']
|
||||||
@ -135,6 +143,11 @@ class Harness:
|
|||||||
html = html + '<table border="0" cellspacing="0" cellpadding="3" cellborder="1">' # name+attributes table
|
html = html + '<table border="0" cellspacing="0" cellpadding="3" cellborder="1">' # name+attributes table
|
||||||
if c.show_name:
|
if c.show_name:
|
||||||
html = html + '<tr><td colspan="{colspan}">{name}</td></tr>'.format(colspan=len(a), name=c.name)
|
html = html + '<tr><td colspan="{colspan}">{name}</td></tr>'.format(colspan=len(a), name=c.name)
|
||||||
|
if(len(id) > 0): # print an identification row if values specified
|
||||||
|
html = html + '<tr><td colspan="{colspan}"><table border="0" cellspacing="0" cellpadding="0" cellborder="0"><tr>'.format(colspan=len(a))
|
||||||
|
for attrib in id:
|
||||||
|
html = html + '<td>{attrib}</td>'.format(attrib=attrib)
|
||||||
|
html = html + '</tr></table></td></tr>' # end identification row
|
||||||
html = html + '<tr>' # attribute row
|
html = html + '<tr>' # attribute row
|
||||||
for attrib in a:
|
for attrib in a:
|
||||||
html = html + '<td>{attrib}</td>'.format(attrib=attrib)
|
html = html + '<td>{attrib}</td>'.format(attrib=attrib)
|
||||||
@ -156,6 +169,21 @@ class Harness:
|
|||||||
html = html + '</tr>'
|
html = html + '</tr>'
|
||||||
bgcolor = wv_colors.translate_color(x, 'hex')
|
bgcolor = wv_colors.translate_color(x, 'hex')
|
||||||
html = html + '<tr><td colspan="{colspan}" cellpadding="0" height="6" bgcolor="{bgcolor}" border="2" sides="tb" port="{port}"></td></tr>'.format(colspan=len(p), bgcolor=bgcolor if bgcolor != '' else '#ffffff', port='w{}'.format(i))
|
html = html + '<tr><td colspan="{colspan}" cellpadding="0" height="6" bgcolor="{bgcolor}" border="2" sides="tb" port="{port}"></td></tr>'.format(colspan=len(p), bgcolor=bgcolor if bgcolor != '' else '#ffffff', port='w{}'.format(i))
|
||||||
|
if(c.category == 'bundle'): # for bundles individual wires can have part information
|
||||||
|
# create a list of wire parameters
|
||||||
|
wireid = []
|
||||||
|
if isinstance(c.manufacturer, list):
|
||||||
|
wireid.append(c.manufacturer[i - 1])
|
||||||
|
if isinstance(c.manufacturer_part_number, list):
|
||||||
|
wireid.append('MPN:{}'.format(c.manufacturer_part_number[i - 1]))
|
||||||
|
if isinstance(c.internal_part_number, list):
|
||||||
|
wireid.append('IPN:{}'.format(c.internal_part_number[i - 1]))
|
||||||
|
# print parameters into a table row under the wire
|
||||||
|
if(len(wireid) > 0):
|
||||||
|
html = html + '<tr><td colspan="{colspan}"><table border="0" cellspacing="0" cellborder="0"><tr>'.format(colspan=len(a))
|
||||||
|
for attrib in wireid:
|
||||||
|
html = html + '<td>{attrib}</td>'.format(attrib=attrib)
|
||||||
|
html = html + '</tr></table></td></tr>'
|
||||||
|
|
||||||
if c.shield:
|
if c.shield:
|
||||||
p = ['<!-- s_in -->', 'Shield', '<!-- s_out -->']
|
p = ['<!-- s_in -->', 'Shield', '<!-- s_out -->']
|
||||||
@ -248,39 +276,53 @@ class Harness:
|
|||||||
bom_connectors = []
|
bom_connectors = []
|
||||||
bom_cables = []
|
bom_cables = []
|
||||||
# connectors
|
# connectors
|
||||||
types = Counter([(v.type, v.subtype, v.pincount) for v in self.connectors.values()])
|
types = Counter([(v.type, v.subtype, v.pincount, v.manufacturer, v.manufacturer_part_number, v.internal_part_number) for v in self.connectors.values()])
|
||||||
for type in types:
|
for type in types:
|
||||||
items = {k: v for k, v in self.connectors.items() if (v.type, v.subtype, v.pincount) == type}
|
items = {k: v for k, v in self.connectors.items() if (v.type, v.subtype, v.pincount, v.manufacturer, v.manufacturer_part_number, v.internal_part_number) == type}
|
||||||
shared = next(iter(items.values()))
|
shared = next(iter(items.values()))
|
||||||
designators = list(items.keys())
|
designators = list(items.keys())
|
||||||
designators.sort()
|
designators.sort()
|
||||||
part_number = shared.part_number
|
|
||||||
name = 'Connector{type}{subtype}{pincount}{color}'.format(type = ', {}'.format(shared.type) if shared.type else '',
|
name = 'Connector{type}{subtype}{pincount}{color}'.format(type = ', {}'.format(shared.type) if shared.type else '',
|
||||||
subtype = ', {}'.format(shared.subtype) if shared.subtype else '',
|
subtype = ', {}'.format(shared.subtype) if shared.subtype else '',
|
||||||
pincount = ', {} pins'.format(shared.pincount) if shared.category != 'ferrule' else '',
|
pincount = ', {} pins'.format(shared.pincount) if shared.category != 'ferrule' else '',
|
||||||
color = ', {}'.format(shared.color) if shared.color else '')
|
color = ', {}'.format(shared.color) if shared.color else '')
|
||||||
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.category != 'ferrule' else ''}
|
||||||
if part_number is not None: # set part number only if it exists
|
if shared.manufacturer is not None: # set manufacturer only if it exists
|
||||||
item['part number'] = part_number
|
item['manufacturer'] = shared.manufacturer
|
||||||
|
if shared.manufacturer_part_number is not None: # set part number only if it exists
|
||||||
|
item['manufacturer part number'] = shared.manufacturer_part_number
|
||||||
|
if shared.internal_part_number is not None: # set part number only if it exists
|
||||||
|
item['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
|
||||||
bom.extend(bom_connectors)
|
bom.extend(bom_connectors)
|
||||||
# cables
|
# cables
|
||||||
types = Counter([(v.category, v.gauge, v.gauge_unit, v.wirecount, v.shield) for v in self.cables.values()])
|
types = Counter([(v.category, v.gauge, v.gauge_unit, v.wirecount, v.shield,
|
||||||
|
v.manufacturer if not isinstance(v.manufacturer, list) else None,
|
||||||
|
v.manufacturer_part_number if not isinstance(v.manufacturer_part_number, list) else None,
|
||||||
|
v.internal_part_number if not isinstance(v.manufacturer_part_number, list) else None
|
||||||
|
) for v in self.cables.values()])
|
||||||
for type in types:
|
for type in types:
|
||||||
items = {k: v for k, v in self.cables.items() if (v.category, v.gauge, v.gauge_unit, v.wirecount, v.shield) == type}
|
items = {k: v for k, v in self.cables.items() if (v.category, v.gauge, v.gauge_unit, v.wirecount, v.shield,
|
||||||
|
v.manufacturer if not isinstance(v.manufacturer, list) else None,
|
||||||
|
v.manufacturer_part_number if not isinstance(v.manufacturer_part_number, list) else None,
|
||||||
|
v.internal_part_number if not isinstance(v.manufacturer_part_number, list) else None
|
||||||
|
) == type}
|
||||||
shared = next(iter(items.values()))
|
shared = next(iter(items.values()))
|
||||||
if shared.category != 'bundle':
|
if shared.category != 'bundle':
|
||||||
designators = list(items.keys())
|
designators = list(items.keys())
|
||||||
designators.sort()
|
designators.sort()
|
||||||
part_number = shared.part_number
|
|
||||||
total_length = sum(i.length for i in items.values())
|
total_length = sum(i.length for i in items.values())
|
||||||
name = 'Cable, {wirecount}{gauge}{shield}'.format(wirecount = shared.wirecount,
|
name = 'Cable, {wirecount}{gauge}{shield}'.format(wirecount = shared.wirecount,
|
||||||
gauge = ' x {} {}'.format(shared.gauge, shared.gauge_unit) if shared.gauge else ' wires',
|
gauge = ' x {} {}'.format(shared.gauge, shared.gauge_unit) if shared.gauge else ' wires',
|
||||||
shield = ' shielded' if shared.shield else '')
|
shield = ' shielded' if shared.shield else '')
|
||||||
item = {'item': name, 'qty': round(total_length, 3), 'unit': 'm', 'designators': designators}
|
item = {'item': name, 'qty': round(total_length, 3), 'unit': 'm', 'designators': designators}
|
||||||
if part_number is not None: # set part number only if it exists
|
if shared.manufacturer is not None: # set manufacturer only if it exists
|
||||||
item['part number'] = part_number
|
item['manufacturer'] = shared.manufacturer
|
||||||
|
if shared.manufacturer_part_number is not None: # set part number only if it exists
|
||||||
|
item['manufacturer part number'] = shared.manufacturer_part_number
|
||||||
|
if shared.internal_part_number is not None: # set part number only if it exists
|
||||||
|
item['internal part number'] = shared.internal_part_number
|
||||||
bom_cables.append(item)
|
bom_cables.append(item)
|
||||||
# bundles (ignores wirecount)
|
# bundles (ignores wirecount)
|
||||||
wirelist = []
|
wirelist = []
|
||||||
@ -293,12 +335,16 @@ class Harness:
|
|||||||
if shared.category == 'bundle':
|
if shared.category == 'bundle':
|
||||||
for bundle in items.values():
|
for bundle in items.values():
|
||||||
# add each wire from each bundle to the wirelist
|
# add each wire from each bundle to the wirelist
|
||||||
for color in bundle.colors:
|
for index, color in enumerate(bundle.colors, 0):
|
||||||
wirelist.append({'gauge': shared.gauge, 'gauge_unit': shared.gauge_unit, 'length': shared.length, 'color': color, 'designator': bundle.name})
|
wireinfo = {'gauge': shared.gauge, 'gauge_unit': shared.gauge_unit, 'length': shared.length, 'color': color, 'designator': bundle.name}
|
||||||
|
wireinfo['manufacturer'] = bundle.manufacturer[index] if isinstance(bundle.manufacturer, list) else None
|
||||||
|
wireinfo['manufacturer part number'] = bundle.manufacturer_part_number[index] if isinstance(bundle.manufacturer_part_number, list) else None
|
||||||
|
wireinfo['internal part number'] = bundle.internal_part_number[index] if isinstance(bundle.internal_part_number, list) else None
|
||||||
|
wirelist.append(wireinfo)
|
||||||
# join similar wires from all the bundles to a single BOM item
|
# join similar wires from all the bundles to a single BOM item
|
||||||
types = Counter([(v['gauge'], v['gauge_unit'], v['color']) for v in wirelist])
|
types = Counter([(v['gauge'], v['gauge_unit'], v['color'], v['manufacturer'], v['manufacturer part number'], v['internal part number']) for v in wirelist])
|
||||||
for type in types:
|
for type in types:
|
||||||
items = [v for v in wirelist if (v['gauge'], v['gauge_unit'], v['color']) == type]
|
items = [v for v in wirelist if (v['gauge'], v['gauge_unit'], v['color'], v['manufacturer'], v['manufacturer part number'], v['internal part number']) == type]
|
||||||
shared = items[0]
|
shared = items[0]
|
||||||
designators = [i['designator'] for i in items]
|
designators = [i['designator'] for i in items]
|
||||||
# remove duplicates
|
# remove duplicates
|
||||||
@ -308,6 +354,12 @@ class Harness:
|
|||||||
name = 'Wire{gauge}{color}'.format(gauge=', {} {}'.format(shared['gauge'], shared['gauge_unit']) if shared['gauge'] else '',
|
name = 'Wire{gauge}{color}'.format(gauge=', {} {}'.format(shared['gauge'], shared['gauge_unit']) if shared['gauge'] else '',
|
||||||
color=', {}'.format(shared['color']) if shared['color'] != '' else '')
|
color=', {}'.format(shared['color']) if shared['color'] != '' else '')
|
||||||
item = {'item': name, 'qty': round(total_length, 3), 'unit': 'm', 'designators': designators}
|
item = {'item': name, 'qty': round(total_length, 3), 'unit': 'm', 'designators': designators}
|
||||||
|
if shared['manufacturer'] is not None: # set manufacturer only if it exists
|
||||||
|
item['manufacturer'] = shared['manufacturer']
|
||||||
|
if shared['manufacturer part number'] is not None: # set part number only if it exists
|
||||||
|
item['manufacturer part number'] = shared['manufacturer part number']
|
||||||
|
if shared['internal part number'] is not None: # set part number only if it exists
|
||||||
|
item['internal part number'] = shared['internal part number']
|
||||||
bom_cables.append(item)
|
bom_cables.append(item)
|
||||||
bom_cables = sorted(bom_cables, key=lambda k: k['item']) # https://stackoverflow.com/a/73050
|
bom_cables = sorted(bom_cables, key=lambda k: k['item']) # https://stackoverflow.com/a/73050
|
||||||
bom.extend(bom_cables)
|
bom.extend(bom_cables)
|
||||||
@ -316,9 +368,10 @@ class Harness:
|
|||||||
def bom_list(self):
|
def bom_list(self):
|
||||||
bom = self.bom()
|
bom = self.bom()
|
||||||
keys = ['item', 'qty', 'unit', 'designators']
|
keys = ['item', 'qty', 'unit', 'designators']
|
||||||
# check if any part numbers are set
|
# check if any optional fields are set and add to keys if they are
|
||||||
if any("part number" in x for x in bom):
|
for fieldname in ["manufacturer", "manufacturer part number", "internal part number"]:
|
||||||
keys.append("part number")
|
if any(fieldname in x for x in bom):
|
||||||
|
keys.append(fieldname)
|
||||||
bom_list = []
|
bom_list = []
|
||||||
bom_list.append([k.capitalize() for k in keys]) # create header row with keys
|
bom_list.append([k.capitalize() for k in keys]) # create header row with keys
|
||||||
for item in bom:
|
for item in bom:
|
||||||
@ -332,7 +385,9 @@ class Harness:
|
|||||||
@dataclass
|
@dataclass
|
||||||
class Connector:
|
class Connector:
|
||||||
name: str
|
name: str
|
||||||
part_number: str = None
|
manufacturer: str = None
|
||||||
|
manufacturer_part_number: str = None
|
||||||
|
internal_part_number: str = None
|
||||||
category: str = None
|
category: str = None
|
||||||
type: str = None
|
type: str = None
|
||||||
subtype: str = None
|
subtype: str = None
|
||||||
@ -383,7 +438,9 @@ class Connector:
|
|||||||
@dataclass
|
@dataclass
|
||||||
class Cable:
|
class Cable:
|
||||||
name: str
|
name: str
|
||||||
part_number: str = None
|
manufacturer: str = None
|
||||||
|
manufacturer_part_number: str = None
|
||||||
|
internal_part_number: str = None
|
||||||
category : str = None
|
category : str = None
|
||||||
type: str = None
|
type: str = None
|
||||||
gauge: float = None
|
gauge: float = None
|
||||||
@ -437,6 +494,16 @@ class Cable:
|
|||||||
raise Exception('Unknown number of wires. Must specify wirecount or colors (implicit length)')
|
raise Exception('Unknown number of wires. Must specify wirecount or colors (implicit length)')
|
||||||
self.wirecount = len(self.colors)
|
self.wirecount = len(self.colors)
|
||||||
|
|
||||||
|
# if lists of part numbers are provided check this is a bundle and that it matches the wirecount.
|
||||||
|
for idfield in [self.manufacturer, self.manufacturer_part_number, self.internal_part_number]:
|
||||||
|
if isinstance(idfield, list):
|
||||||
|
if self.category == "bundle":
|
||||||
|
# check the length
|
||||||
|
if len(idfield) != self.wirecount:
|
||||||
|
raise Exception('lists of part data must match wirecount')
|
||||||
|
else:
|
||||||
|
raise Exception('lists of part data are only supported for bundles')
|
||||||
|
|
||||||
# for BOM generation
|
# for BOM generation
|
||||||
self.wirecount_and_shield = (self.wirecount, self.shield)
|
self.wirecount_and_shield = (self.wirecount, self.shield)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user