Merge 9821ca31f77edfc0e0b0793a76ba27cdfd174cf3 into 523d0c659ee58412d8cf11416978eb80e424ec4c
This commit is contained in:
commit
edbe2b1e89
@ -1,69 +1,126 @@
|
||||
templates: # defining templates to be used later on
|
||||
- &molex_f
|
||||
type: Molex KK 254
|
||||
subtype: female
|
||||
- &con_i2c
|
||||
pinlabels: [GND, +5V, SCL, SDA]
|
||||
- &wire_i2c
|
||||
category: bundle
|
||||
gauge: 0.14 mm2
|
||||
colors: [BK, RD, YE, GN]
|
||||
|
||||
connectors:
|
||||
X1:
|
||||
<<: *molex_f # copying items from the template
|
||||
pinlabels: [GND, +5V, SCL, SDA, MISO, MOSI, SCK, N/C]
|
||||
type: KK 254
|
||||
pn: CON-245-8
|
||||
manufacturer: Molex
|
||||
mpn: '0022013087'
|
||||
subtype: female
|
||||
pincount: 8
|
||||
pinlabels: [Audio L, Audio R, Audio GND, N/C, I2C GND, I2C +5V, SCL, SDA]
|
||||
additional_parameters:
|
||||
Sleeving removal: 20 mm
|
||||
Insulation removal: 2 mm
|
||||
additional_components:
|
||||
-
|
||||
type: Crimp
|
||||
pn: CRI-254
|
||||
manufacturer: Molex
|
||||
mpn: '008500032'
|
||||
qty_multiplier: populated
|
||||
-
|
||||
type: Label
|
||||
pn: LAB-444
|
||||
note: '"C745-X1"'
|
||||
notes: |
|
||||
- Attach to main PCB
|
||||
- Ensure proper contact
|
||||
- Clamp down cables after attaching
|
||||
X2:
|
||||
<<: *molex_f
|
||||
<<: *con_i2c # it is possible to copy from more than one template
|
||||
type: 3.5 mm
|
||||
subtype: jack
|
||||
color: BK
|
||||
pins: [T,R,S]
|
||||
show_pincount: false
|
||||
pinlabels: [L, R, GND]
|
||||
image:
|
||||
src: resources/stereo-phone-plug-TRS.png
|
||||
caption: Tip, Ring, and Sleeve
|
||||
X3:
|
||||
<<: *molex_f
|
||||
<<: *con_i2c
|
||||
type: KK 254
|
||||
subtype: female
|
||||
pinlabels: [VCC, GND, SCL, SDA]
|
||||
pincolors: [RD, BK, GN, BU]
|
||||
X4:
|
||||
<<: *molex_f
|
||||
pinlabels: [GND, +12V, MISO, MOSI, SCK]
|
||||
ferrule_crimp:
|
||||
type: D-Sub
|
||||
subtype: female
|
||||
pincount: 9
|
||||
pn: CON-D9-F
|
||||
pinlabels: [GND, +5V, SCL, SDA, N/C, +12V IN, GND, +12V OUT, GND]
|
||||
additional_components:
|
||||
-
|
||||
type: Casing, plastic
|
||||
pn: CAS-D9
|
||||
-
|
||||
type: Mounting screws, M3 x 8
|
||||
qty: 2
|
||||
F:
|
||||
style: simple
|
||||
autogenerate: true
|
||||
type: Crimp ferrule
|
||||
subtype: 0.25 mm²
|
||||
color: YE
|
||||
subtype: 0.5 mm²
|
||||
color: OG
|
||||
|
||||
cables:
|
||||
W1:
|
||||
<<: *wire_i2c
|
||||
length: 0.2
|
||||
show_equiv: true
|
||||
W2:
|
||||
<<: *wire_i2c
|
||||
length: 0.4
|
||||
show_equiv: true
|
||||
W3:
|
||||
category: bundle
|
||||
gauge: 0.14 mm2
|
||||
length: 0.3
|
||||
colors: [BK, BU, OG, VT]
|
||||
show_equiv: true
|
||||
W4:
|
||||
wirecount: 3
|
||||
shield: true
|
||||
length: 0.5
|
||||
gauge: 0.25 mm2
|
||||
length: 0.3
|
||||
colors: [BK, RD]
|
||||
show_equiv: true
|
||||
colors: [WH, RD, BK]
|
||||
color: GY
|
||||
additional_components:
|
||||
-
|
||||
type: Heatshrink D=5mm
|
||||
qty: 15
|
||||
unit: mm
|
||||
note: left
|
||||
-
|
||||
type: Heatshrink D=5mm
|
||||
qty: 25
|
||||
unit: mm
|
||||
note: right
|
||||
W2: &wire_i2c
|
||||
wirecount: 4
|
||||
length: 0.2
|
||||
gauge: 0.25 mm2
|
||||
show_equiv: true
|
||||
color_code: IEC
|
||||
W3:
|
||||
<<: *wire_i2c
|
||||
color_code: DIN
|
||||
W4: &wire_power
|
||||
category: bundle
|
||||
show_name: false
|
||||
wirecount: 2
|
||||
colors: [RD, BK]
|
||||
gauge: 0.5 mm2
|
||||
show_equiv: true
|
||||
length: 1.0
|
||||
additional_parameters:
|
||||
Twist rate: 10/m
|
||||
Twist direction: CCW
|
||||
W5:
|
||||
<<: *wire_power
|
||||
|
||||
connections:
|
||||
-
|
||||
- X1: [1-4]
|
||||
- W1: [1-4]
|
||||
- X2: [1-4]
|
||||
- X1: [Audio L, Audio R, Audio GND, Audio GND]
|
||||
- W1: [1-3,s]
|
||||
- X2: [T,R,S,S]
|
||||
-
|
||||
- X1: [1-4]
|
||||
- X1: [I2C GND, I2C +5V, SCL, SDA]
|
||||
- W2: [1-4]
|
||||
- X3: [1-4]
|
||||
- X3: [GND, VCC, SCL, SDA]
|
||||
-
|
||||
- X1: [1,5-7]
|
||||
- X1: [I2C GND, I2C +5V, SCL, SDA]
|
||||
- W3: [1-4]
|
||||
- X4: [1,3-5]
|
||||
- X4: [1,2,3,4]
|
||||
-
|
||||
- ferrule_crimp
|
||||
- F
|
||||
- W4: [1,2]
|
||||
- X4: [1,2]
|
||||
- X4: [6,7]
|
||||
-
|
||||
- X4: [8,9]
|
||||
- W5: [1,2]
|
||||
- F
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from typing import Optional, List, Tuple, Union
|
||||
from typing import Optional, List, Dict, Tuple, Union
|
||||
from dataclasses import dataclass, field, InitVar
|
||||
from pathlib import Path
|
||||
|
||||
@ -76,6 +76,7 @@ class AdditionalComponent:
|
||||
qty: float = 1
|
||||
unit: Optional[str] = None
|
||||
qty_multiplier: Union[ConnectorMultiplier, CableMultiplier, None] = None
|
||||
note: Optional[str] = None
|
||||
|
||||
@property
|
||||
def description(self) -> str:
|
||||
@ -93,6 +94,7 @@ class Connector:
|
||||
type: Optional[MultilineHypertext] = None
|
||||
subtype: Optional[MultilineHypertext] = None
|
||||
pincount: Optional[int] = None
|
||||
additional_parameters: Optional[Dict] = None
|
||||
image: Optional[Image] = None
|
||||
notes: Optional[MultilineHypertext] = None
|
||||
pinlabels: List[Pin] = field(default_factory=list)
|
||||
@ -104,6 +106,7 @@ class Connector:
|
||||
hide_disconnected_pins: bool = False
|
||||
autogenerate: bool = False
|
||||
loops: List[List[Pin]] = field(default_factory=list)
|
||||
bom_item_number: Optional[int] = None
|
||||
ignore_in_bom: bool = False
|
||||
additional_components: List[AdditionalComponent] = field(default_factory=list)
|
||||
|
||||
@ -180,6 +183,7 @@ class Cable:
|
||||
color: Optional[Color] = None
|
||||
wirecount: Optional[int] = None
|
||||
shield: Union[bool, Color] = False
|
||||
additional_parameters: Optional[Dict] = None
|
||||
image: Optional[Image] = None
|
||||
notes: Optional[MultilineHypertext] = None
|
||||
colors: List[Colors] = field(default_factory=list)
|
||||
@ -188,6 +192,7 @@ class Cable:
|
||||
show_name: bool = True
|
||||
show_wirecount: bool = True
|
||||
show_wirenumbers: Optional[bool] = None
|
||||
bom_item_number: Optional[int] = None
|
||||
ignore_in_bom: bool = False
|
||||
additional_components: List[AdditionalComponent] = field(default_factory=list)
|
||||
|
||||
|
||||
@ -12,8 +12,8 @@ from wireviz import wv_colors, __version__, APP_NAME, APP_URL
|
||||
from wireviz.DataClasses import Connector, Cable
|
||||
from wireviz.wv_colors import get_color_hex
|
||||
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, \
|
||||
html_caption, remove_links, html_line_breaks, bom_bubble, nested_html_table_dict
|
||||
from wireviz.wv_bom import manufacturer_info_field, \
|
||||
get_additional_component_table, bom_list, generate_bom
|
||||
from wireviz.wv_html import generate_html_output
|
||||
from wireviz.wv_helper import awg_equiv, mm2_equiv, tuplelist2tsv, flatten2d, \
|
||||
@ -24,7 +24,8 @@ class Harness:
|
||||
|
||||
def __init__(self):
|
||||
self.color_mode = 'SHORT'
|
||||
self.mini_bom_mode = True
|
||||
self.show_part_numbers = True # TODO: Make configurable via YAML
|
||||
self.show_bom_item_numbers = True # TODO: Make configurable via YAML
|
||||
self.connectors = {}
|
||||
self.cables = {}
|
||||
self._bom = [] # Internal Cache for generated bom
|
||||
@ -114,17 +115,20 @@ class Harness:
|
||||
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))],
|
||||
[html_line_breaks(connector.type),
|
||||
[bom_bubble(connector.bom_item_number) if self.show_bom_item_numbers else None, # TODO: Show actual BOM number
|
||||
html_line_breaks(connector.type),
|
||||
html_line_breaks(connector.subtype),
|
||||
f'{connector.pincount}-pin' if connector.show_pincount else None,
|
||||
connector.color, html_colorbar(connector.color)],
|
||||
[f'P/N: {remove_links(connector.pn)}' if connector.pn else None,
|
||||
html_line_breaks(manufacturer_info_field(connector.manufacturer, connector.mpn))] if self.show_part_numbers else None,
|
||||
nested_html_table_dict(connector.additional_parameters),
|
||||
'<!-- connector table -->' if connector.style != 'simple' else None,
|
||||
[html_image(connector.image)],
|
||||
[html_caption(connector.image)]]
|
||||
rows.extend(get_additional_component_table(self, connector))
|
||||
rows.append(get_additional_component_table(self, connector))
|
||||
rows.append([html_line_breaks(connector.notes)])
|
||||
|
||||
html.extend(nested_html_table(rows))
|
||||
|
||||
if connector.style != 'simple':
|
||||
@ -195,21 +199,23 @@ class Harness:
|
||||
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(
|
||||
cable.manufacturer if not isinstance(cable.manufacturer, list) else None,
|
||||
cable.mpn if not isinstance(cable.mpn, list) else None))],
|
||||
[html_line_breaks(cable.type),
|
||||
[bom_bubble(cable.bom_item_number) if self.show_bom_item_numbers else None, # TODO: Show actual BOM number
|
||||
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,
|
||||
'+ S' if cable.shield else None,
|
||||
f'{cable.length} {cable.length_unit}' if cable.length > 0 else None,
|
||||
cable.color, html_colorbar(cable.color)],
|
||||
[f'P/N: {remove_links(cable.pn)}' if (cable.pn and not isinstance(cable.pn, list)) else None,
|
||||
html_line_breaks(manufacturer_info_field(
|
||||
cable.manufacturer if not isinstance(cable.manufacturer, list) else None,
|
||||
cable.mpn if not isinstance(cable.mpn, list) else None))],
|
||||
nested_html_table_dict(cable.additional_parameters),
|
||||
'<!-- wire table -->',
|
||||
[html_image(cable.image)],
|
||||
[html_caption(cable.image)]]
|
||||
|
||||
rows.extend(get_additional_component_table(self, cable))
|
||||
rows.append(get_additional_component_table(self, cable)) # TODO: reimplement
|
||||
rows.append([html_line_breaks(cable.notes)])
|
||||
html.extend(nested_html_table(rows))
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ from itertools import groupby
|
||||
from typing import Any, Dict, List, Optional, Tuple, Union
|
||||
|
||||
from wireviz.DataClasses import AdditionalComponent, Connector, Cable
|
||||
from wireviz.wv_gv_html import html_line_breaks
|
||||
from wireviz.wv_gv_html import html_line_breaks, bom_bubble
|
||||
from wireviz.wv_helper import clean_whitespace
|
||||
|
||||
BOMColumn = str # = Literal['id', 'description', 'qty', 'unit', 'designators', 'pn', 'manufacturer', 'mpn']
|
||||
@ -20,18 +20,48 @@ def get_additional_component_table(harness: "Harness", component: Union[Connecto
|
||||
"""Return a list of diagram node table row strings with additional components."""
|
||||
rows = []
|
||||
if component.additional_components:
|
||||
rows.append(["Additional components"])
|
||||
parts = []
|
||||
for part in component.additional_components:
|
||||
common_args = {
|
||||
'qty': part.qty * component.get_qty_multiplier(part.qty_multiplier),
|
||||
'unit': part.unit,
|
||||
}
|
||||
if harness.mini_bom_mode:
|
||||
# if True:
|
||||
# id = get_bom_index(harness.bom(), part)
|
||||
# rows.append(component_table_entry(f'#{id} ({part.type.rstrip()})', **common_args))
|
||||
# else:
|
||||
# rows.append(component_table_entry(part.description, **common_args, **optional_fields(part)))
|
||||
id = get_bom_index(harness.bom(), part)
|
||||
rows.append(component_table_entry(f'#{id} ({part.type.rstrip()})', **common_args))
|
||||
manufacturer_str = manufacturer_info_field(part.manufacturer, part.mpn)
|
||||
columns = []
|
||||
if harness.show_bom_item_numbers:
|
||||
columns.append(bom_bubble(id))
|
||||
columns.append(f'{part.qty * component.get_qty_multiplier(part.qty_multiplier)}' + (f' {part.unit}' if part.unit else 'x'))
|
||||
columns.append(f'{part.type}')
|
||||
if harness.show_part_numbers:
|
||||
columns.append(f'P/N: {part.pn}' if part.pn else '')
|
||||
columns.append(f'{manufacturer_str}' if manufacturer_str else '')
|
||||
columns.append(f'{part.note}' if part.note else '')
|
||||
|
||||
parts.append(columns)
|
||||
|
||||
# remove unused columns
|
||||
transp = list(map(list, zip(*parts))) # transpose list
|
||||
transp = [item for item in transp if any(item)] # remove empty rows (easier)
|
||||
parts = list(map(list, zip(*transp))) # transpose back
|
||||
|
||||
# generate HTML output
|
||||
for part in parts:
|
||||
rowstr = '\n <tr>\n'
|
||||
for index, column in enumerate(part):
|
||||
sides = "tbl" if index == 0 else "tbr" if index == len(part) -1 else "tb"
|
||||
rowstr = rowstr + f' <td align="left" balign="left" sides="{sides}">{html_line_breaks(column)}</td>\n'
|
||||
rowstr = rowstr + ' </tr>'
|
||||
rows.append(rowstr)
|
||||
|
||||
pre = '<table border="0" cellspacing="0" cellpadding="3" cellborder="1">'
|
||||
post = '\n </table>'
|
||||
if len(rows) > 0:
|
||||
tbl = pre + ''.join(rows) + post
|
||||
else:
|
||||
rows.append(component_table_entry(part.description, **common_args, **optional_fields(part)))
|
||||
return rows
|
||||
tbl = None
|
||||
return tbl
|
||||
|
||||
def get_additional_component_bom(component: Union[Connector, Cable]) -> List[BOMEntry]:
|
||||
"""Return a list of BOM entries with additional components."""
|
||||
@ -138,29 +168,6 @@ def bom_list(bom: List[BOMEntry]) -> List[List[str]]:
|
||||
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
|
||||
|
||||
def component_table_entry(
|
||||
type: str,
|
||||
qty: Union[int, float],
|
||||
unit: Optional[str] = None,
|
||||
pn: Optional[str] = None,
|
||||
manufacturer: Optional[str] = None,
|
||||
mpn: Optional[str] = None,
|
||||
) -> str:
|
||||
"""Return a diagram node table row string with an additional component."""
|
||||
manufacturer_str = manufacturer_info_field(manufacturer, mpn)
|
||||
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 ''))
|
||||
# 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:
|
||||
|
||||
@ -1,12 +1,25 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from typing import List, Union
|
||||
from typing import List, Dict, Union
|
||||
import re
|
||||
|
||||
from wireviz.wv_colors import translate_color
|
||||
from wireviz.wv_helper import remove_links
|
||||
|
||||
def nested_html_table_dict(rows):
|
||||
if isinstance(rows, Dict):
|
||||
html = []
|
||||
html.append('<table border="0" cellspacing="0" cellpadding="3" cellborder="1">')
|
||||
for (key, value) in rows.items():
|
||||
html.append(f' <tr><td align="left" balign="left">{key}</td>')
|
||||
html.append(f' <td align="left" balign="left">{html_line_breaks(value)}</td></tr>')
|
||||
html.append(' </table>')
|
||||
out = '\n'.join(html)
|
||||
else:
|
||||
out = None
|
||||
return out
|
||||
|
||||
def nested_html_table(rows):
|
||||
# input: list, each item may be scalar or list
|
||||
# output: a parent table with one child table per parent item that is list, and one cell per parent item that is scalar
|
||||
@ -64,3 +77,6 @@ def html_size_attr(image):
|
||||
|
||||
def html_line_breaks(inp):
|
||||
return remove_links(inp).replace('\n', '<br />') if isinstance(inp, str) else inp
|
||||
|
||||
def bom_bubble(inp):
|
||||
return(f'<table border="0"><tr><td border="1" style="rounded">{inp}</td></tr></table>')
|
||||
|
||||
9
test/bomnumbertest.bom.tsv
generated
Normal file
9
test/bomnumbertest.bom.tsv
generated
Normal file
@ -0,0 +1,9 @@
|
||||
Id Item Qty Unit Designators P/N Manufacturer MPN
|
||||
1 Cable, 4 x 0.25 mm² 99 m W1 qwerty uiop
|
||||
2 Connector, Plug, 4 pins 1 X1 123 ACME ABC
|
||||
3 Connector, Receptacle, 4 pins 1 X2 234 ACME DEF
|
||||
4 Crimp 1 X2 876 ACME WVU
|
||||
5 Crimp 4 X1 987 ACME ZYX
|
||||
6 Housing 1 X1 345 OTHER
|
||||
7 Label 1 X1
|
||||
8 Sleeving 5 m W1
|
||||
|
Loading…
x
Reference in New Issue
Block a user