From 8c26c8fbbd6df555f617fb2620384fcb3372c803 Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Tue, 23 Mar 2021 10:49:56 +0100 Subject: [PATCH 01/15] New addit. compo. BOM table proof of concept --- src/wireviz/Harness.py | 14 ++++++++------ src/wireviz/wv_bom.py | 40 +++++++++++++++++++++++++++++++--------- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/wireviz/Harness.py b/src/wireviz/Harness.py index 9d83a3d..4df9c7a 100644 --- a/src/wireviz/Harness.py +++ b/src/wireviz/Harness.py @@ -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,16 +115,17 @@ 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 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, '' 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)) @@ -209,7 +211,7 @@ class Harness: [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)) diff --git a/src/wireviz/wv_bom.py b/src/wireviz/wv_bom.py index f71abc1..85ff0f8 100644 --- a/src/wireviz/wv_bom.py +++ b/src/wireviz/wv_bom.py @@ -20,18 +20,40 @@ 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"]) + # rows.append(["Additional components"]) 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: - 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))) - return rows + # 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) + manufacturer_str = manufacturer_info_field(part.manufacturer, part.mpn) + columns = [] + if harness.show_bom_item_numbers: + columns.append(f'
{id}
') + columns.append(f'{part.qty}' + (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 '') + # TODO: Add note column as proposed in #222 + + rowstr = '' + ''.join([f'{col}' for col in columns]) + '' + rows.append(rowstr) + + print(rows) + pre = '' + post = '
' + if len(rows) > 0: + tbl = pre + ''.join(rows) + post + else: + return None + return tbl def get_additional_component_bom(component: Union[Connector, Cable]) -> List[BOMEntry]: """Return a list of BOM entries with additional components.""" @@ -157,9 +179,9 @@ def component_table_entry( + (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''' + return f''' -
{html_line_breaks(output)}
''' + ''' 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.""" From e61d14ba43a3a0a64cf99278167e7bac35b1b8e3 Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Tue, 23 Mar 2021 11:00:26 +0100 Subject: [PATCH 02/15] Create `bom_bubble()` function --- src/wireviz/Harness.py | 4 ++-- src/wireviz/wv_bom.py | 4 ++-- src/wireviz/wv_gv_html.py | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/wireviz/Harness.py b/src/wireviz/Harness.py index 4df9c7a..117e0d9 100644 --- a/src/wireviz/Harness.py +++ b/src/wireviz/Harness.py @@ -12,7 +12,7 @@ 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 + html_caption, remove_links, html_line_breaks, bom_bubble from wireviz.wv_bom import manufacturer_info_field, component_table_entry, \ get_additional_component_table, bom_list, generate_bom from wireviz.wv_html import generate_html_output @@ -115,7 +115,7 @@ class Harness: html = [] rows = [[remove_links(connector.name) if connector.show_name else None], - ['<BOM Number>' if self.show_bom_item_numbers else None, # TODO: Show actual BOM number + [bom_bubble('###') 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, diff --git a/src/wireviz/wv_bom.py b/src/wireviz/wv_bom.py index 85ff0f8..461a82e 100644 --- a/src/wireviz/wv_bom.py +++ b/src/wireviz/wv_bom.py @@ -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'] @@ -35,7 +35,7 @@ def get_additional_component_table(harness: "Harness", component: Union[Connecto manufacturer_str = manufacturer_info_field(part.manufacturer, part.mpn) columns = [] if harness.show_bom_item_numbers: - columns.append(f'
{id}
') + columns.append(bom_bubble(id)) columns.append(f'{part.qty}' + (f' {part.unit}' if part.unit else ' x')) columns.append(f'{part.type}') if harness.show_part_numbers: diff --git a/src/wireviz/wv_gv_html.py b/src/wireviz/wv_gv_html.py index ee5b2e2..87b2496 100644 --- a/src/wireviz/wv_gv_html.py +++ b/src/wireviz/wv_gv_html.py @@ -64,3 +64,6 @@ def html_size_attr(image): def html_line_breaks(inp): return remove_links(inp).replace('\n', '
') if isinstance(inp, str) else inp + +def bom_bubble(inp): + return(f'
{inp}
') From 53fefa8f3cc43404fcc35b507c73e06539818696 Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Tue, 23 Mar 2021 11:04:33 +0100 Subject: [PATCH 03/15] Add `note` attribute to additional components --- src/wireviz/DataClasses.py | 1 + src/wireviz/wv_bom.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wireviz/DataClasses.py b/src/wireviz/DataClasses.py index fac6ab5..c56f984 100644 --- a/src/wireviz/DataClasses.py +++ b/src/wireviz/DataClasses.py @@ -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: diff --git a/src/wireviz/wv_bom.py b/src/wireviz/wv_bom.py index 461a82e..5f61aba 100644 --- a/src/wireviz/wv_bom.py +++ b/src/wireviz/wv_bom.py @@ -41,7 +41,7 @@ def get_additional_component_table(harness: "Harness", component: Union[Connecto 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 '') - # TODO: Add note column as proposed in #222 + columns.append(f'{part.note}' if part.note else '') rowstr = '' + ''.join([f'{col}' for col in columns]) + '' rows.append(rowstr) From 0dc02fe8b5091baa3c2bc4340f98ca494e853f35 Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Tue, 23 Mar 2021 11:14:49 +0100 Subject: [PATCH 04/15] Correctly determine qty --- src/wireviz/wv_bom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wireviz/wv_bom.py b/src/wireviz/wv_bom.py index 5f61aba..990e153 100644 --- a/src/wireviz/wv_bom.py +++ b/src/wireviz/wv_bom.py @@ -36,7 +36,7 @@ def get_additional_component_table(harness: "Harness", component: Union[Connecto columns = [] if harness.show_bom_item_numbers: columns.append(bom_bubble(id)) - columns.append(f'{part.qty}' + (f' {part.unit}' if part.unit else ' x')) + 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 '') From 9a93d8605845304cdf14cf4f7a1f721b46481d8b Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Tue, 23 Mar 2021 11:19:20 +0100 Subject: [PATCH 05/15] remove `component_table_entry()` as separate func. to simplyfy code --- src/wireviz/Harness.py | 2 +- src/wireviz/wv_bom.py | 29 +---------------------------- 2 files changed, 2 insertions(+), 29 deletions(-) diff --git a/src/wireviz/Harness.py b/src/wireviz/Harness.py index 117e0d9..3ad4ee0 100644 --- a/src/wireviz/Harness.py +++ b/src/wireviz/Harness.py @@ -13,7 +13,7 @@ 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, bom_bubble -from wireviz.wv_bom import manufacturer_info_field, component_table_entry, \ +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, \ diff --git a/src/wireviz/wv_bom.py b/src/wireviz/wv_bom.py index 990e153..eca24ca 100644 --- a/src/wireviz/wv_bom.py +++ b/src/wireviz/wv_bom.py @@ -22,10 +22,6 @@ def get_additional_component_table(harness: "Harness", component: Union[Connecto if component.additional_components: # rows.append(["Additional components"]) for part in component.additional_components: - common_args = { - 'qty': part.qty * component.get_qty_multiplier(part.qty_multiplier), - 'unit': part.unit, - } # if True: # id = get_bom_index(harness.bom(), part) # rows.append(component_table_entry(f'#{id} ({part.type.rstrip()})', **common_args)) @@ -43,7 +39,7 @@ def get_additional_component_table(harness: "Harness", component: Union[Connecto columns.append(f'{manufacturer_str}' if manufacturer_str else '') columns.append(f'{part.note}' if part.note else '') - rowstr = '' + ''.join([f'{col}' for col in columns]) + '' + rowstr = '' + ''.join([f'{html_line_breaks(col)}' for col in columns]) + '' rows.append(rowstr) print(rows) @@ -160,29 +156,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}' - + ('
' 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''' - {html_line_breaks(output)} - ''' - 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: From 4338b7a1c5b5286e66afd51009cbbc4fd92ab923 Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Tue, 23 Mar 2021 11:22:09 +0100 Subject: [PATCH 06/15] Remove header row for additional components --- src/wireviz/wv_bom.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wireviz/wv_bom.py b/src/wireviz/wv_bom.py index eca24ca..93f6676 100644 --- a/src/wireviz/wv_bom.py +++ b/src/wireviz/wv_bom.py @@ -20,7 +20,6 @@ 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"]) for part in component.additional_components: # if True: # id = get_bom_index(harness.bom(), part) From 7e168ea77568b7b586e9b0435dd55a1ab68cdfcf Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Tue, 23 Mar 2021 11:26:13 +0100 Subject: [PATCH 07/15] Improve GraphViz output, remove debug print --- src/wireviz/wv_bom.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/wireviz/wv_bom.py b/src/wireviz/wv_bom.py index 93f6676..3a2d55c 100644 --- a/src/wireviz/wv_bom.py +++ b/src/wireviz/wv_bom.py @@ -38,12 +38,11 @@ def get_additional_component_table(harness: "Harness", component: Union[Connecto columns.append(f'{manufacturer_str}' if manufacturer_str else '') columns.append(f'{part.note}' if part.note else '') - rowstr = '' + ''.join([f'{html_line_breaks(col)}' for col in columns]) + '' + rowstr = '\n \n' + ''.join([f' {html_line_breaks(col)}\n' for col in columns]) + ' ' rows.append(rowstr) - print(rows) pre = '' - post = '
' + post = '\n ' if len(rows) > 0: tbl = pre + ''.join(rows) + post else: From f928bc73ca499f3129be274dd9202770ce91e83b Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Tue, 23 Mar 2021 11:50:02 +0100 Subject: [PATCH 08/15] Add BOM bubble cell to cables --- src/wireviz/Harness.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/wireviz/Harness.py b/src/wireviz/Harness.py index 3ad4ee0..c575f95 100644 --- a/src/wireviz/Harness.py +++ b/src/wireviz/Harness.py @@ -197,16 +197,17 @@ 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('###') 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))], '', [html_image(cable.image)], [html_caption(cable.image)]] From aaf88d7601048bdb4ffd40d55e60edf7baa75d1f Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Tue, 23 Mar 2021 12:15:03 +0100 Subject: [PATCH 09/15] Remove vertical separators in BOM table --- src/wireviz/wv_bom.py | 10 ++++++++-- test/bomnumbertest.bom.tsv | 9 +++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 test/bomnumbertest.bom.tsv diff --git a/src/wireviz/wv_bom.py b/src/wireviz/wv_bom.py index 3a2d55c..2e5cbb2 100644 --- a/src/wireviz/wv_bom.py +++ b/src/wireviz/wv_bom.py @@ -31,14 +31,20 @@ def get_additional_component_table(harness: "Harness", component: Union[Connecto 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.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 '') - rowstr = '\n \n' + ''.join([f' {html_line_breaks(col)}\n' for col in columns]) + ' ' + # TODO: Remove empty columns + + rowstr = '\n \n' + for index, column in enumerate(columns): + sides = "tbl" if index == 0 else "tbr" if index == len(columns) -1 else "tb" + rowstr = rowstr + f' {html_line_breaks(column)}\n' + rowstr = rowstr + ' ' rows.append(rowstr) pre = '' diff --git a/test/bomnumbertest.bom.tsv b/test/bomnumbertest.bom.tsv new file mode 100644 index 0000000..fb6b2da --- /dev/null +++ b/test/bomnumbertest.bom.tsv @@ -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 From 6aa53f6ce450eae22883f3b698b1ebe788f82d9a Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Tue, 23 Mar 2021 12:40:56 +0100 Subject: [PATCH 10/15] Remove unused columns in BOM table --- src/wireviz/wv_bom.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/wireviz/wv_bom.py b/src/wireviz/wv_bom.py index 2e5cbb2..6e48b1a 100644 --- a/src/wireviz/wv_bom.py +++ b/src/wireviz/wv_bom.py @@ -20,6 +20,7 @@ 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: + parts = [] for part in component.additional_components: # if True: # id = get_bom_index(harness.bom(), part) @@ -38,11 +39,18 @@ def get_additional_component_table(harness: "Harness", component: Union[Connecto columns.append(f'{manufacturer_str}' if manufacturer_str else '') columns.append(f'{part.note}' if part.note else '') - # TODO: Remove empty columns + 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 \n' - for index, column in enumerate(columns): - sides = "tbl" if index == 0 else "tbr" if index == len(columns) -1 else "tb" + for index, column in enumerate(part): + sides = "tbl" if index == 0 else "tbr" if index == len(part) -1 else "tb" rowstr = rowstr + f' \n' rowstr = rowstr + ' ' rows.append(rowstr) @@ -52,7 +60,7 @@ def get_additional_component_table(harness: "Harness", component: Union[Connecto if len(rows) > 0: tbl = pre + ''.join(rows) + post else: - return None + tbl = '' return tbl def get_additional_component_bom(component: Union[Connector, Cable]) -> List[BOMEntry]: From 09d5496ca4392812797689a9809180b37276d17a Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Tue, 23 Mar 2021 13:04:31 +0100 Subject: [PATCH 11/15] Add new `bom_item_number` property to components --- src/wireviz/DataClasses.py | 2 ++ src/wireviz/Harness.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/wireviz/DataClasses.py b/src/wireviz/DataClasses.py index c56f984..87dfe6c 100644 --- a/src/wireviz/DataClasses.py +++ b/src/wireviz/DataClasses.py @@ -105,6 +105,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) @@ -189,6 +190,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) diff --git a/src/wireviz/Harness.py b/src/wireviz/Harness.py index c575f95..14f96b0 100644 --- a/src/wireviz/Harness.py +++ b/src/wireviz/Harness.py @@ -115,7 +115,7 @@ class Harness: html = [] rows = [[remove_links(connector.name) if connector.show_name else None], - [bom_bubble('###') if self.show_bom_item_numbers else None, # TODO: Show actual BOM number + [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, @@ -197,7 +197,7 @@ class Harness: awg_fmt = f' ({mm2_equiv(cable.gauge)} mm\u00B2)' rows = [[remove_links(cable.name) if cable.show_name else None], - [bom_bubble('###') if self.show_bom_item_numbers else None, # TODO: Show actual BOM number + [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, From 1f86c97c6725e7f22c8df7d5d1d6363a5b5374d0 Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Tue, 23 Mar 2021 15:15:20 +0100 Subject: [PATCH 12/15] Fix rendering bug for empty add.comp. table --- src/wireviz/wv_bom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wireviz/wv_bom.py b/src/wireviz/wv_bom.py index 6e48b1a..b0ac666 100644 --- a/src/wireviz/wv_bom.py +++ b/src/wireviz/wv_bom.py @@ -60,7 +60,7 @@ def get_additional_component_table(harness: "Harness", component: Union[Connecto if len(rows) > 0: tbl = pre + ''.join(rows) + post else: - tbl = '' + tbl = None return tbl def get_additional_component_bom(component: Union[Connector, Cable]) -> List[BOMEntry]: From b4a0ae50b84ab7d23a84247d440382b1944ecdb6 Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Tue, 23 Mar 2021 15:57:38 +0100 Subject: [PATCH 13/15] Implement additional parameter table as proposed in #222 --- src/wireviz/DataClasses.py | 4 +++- src/wireviz/Harness.py | 5 ++++- src/wireviz/wv_gv_html.py | 15 ++++++++++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/wireviz/DataClasses.py b/src/wireviz/DataClasses.py index 87dfe6c..6aa9e66 100644 --- a/src/wireviz/DataClasses.py +++ b/src/wireviz/DataClasses.py @@ -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 @@ -94,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) @@ -182,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) diff --git a/src/wireviz/Harness.py b/src/wireviz/Harness.py index 14f96b0..486dfdd 100644 --- a/src/wireviz/Harness.py +++ b/src/wireviz/Harness.py @@ -12,7 +12,7 @@ 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, bom_bubble + 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 @@ -122,11 +122,13 @@ class Harness: 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), '' if connector.style != 'simple' else None, [html_image(connector.image)], [html_caption(connector.image)]] 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': @@ -208,6 +210,7 @@ class Harness: 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), '', [html_image(cable.image)], [html_caption(cable.image)]] diff --git a/src/wireviz/wv_gv_html.py b/src/wireviz/wv_gv_html.py index 87b2496..a54f002 100644 --- a/src/wireviz/wv_gv_html.py +++ b/src/wireviz/wv_gv_html.py @@ -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('
{html_line_breaks(column)}
') + for (key, value) in rows.items(): + html.append(f' ') + html.append(f' ') + html.append('
{key}{value}
') + 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 From 37bf5309f033e07b93e978a573378291c5280528 Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Tue, 23 Mar 2021 18:02:55 +0100 Subject: [PATCH 14/15] Allow line breaks in additional parameters --- src/wireviz/wv_gv_html.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wireviz/wv_gv_html.py b/src/wireviz/wv_gv_html.py index a54f002..ea80ada 100644 --- a/src/wireviz/wv_gv_html.py +++ b/src/wireviz/wv_gv_html.py @@ -13,7 +13,7 @@ def nested_html_table_dict(rows): html.append('') for (key, value) in rows.items(): html.append(f' ') - html.append(f' ') + html.append(f' ') html.append('
{key}{value}
{html_line_breaks(value)}
') out = '\n'.join(html) else: From 9821ca31f77edfc0e0b0793a76ba27cdfd174cf3 Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Tue, 23 Mar 2021 18:02:28 +0100 Subject: [PATCH 15/15] Update demo02 to showcase more features zzz --- examples/demo02.yml | 151 ++++++++++++++++++++++++++++++-------------- 1 file changed, 104 insertions(+), 47 deletions(-) diff --git a/examples/demo02.yml b/examples/demo02.yml index 5002e7d..ca5cadf 100644 --- a/examples/demo02.yml +++ b/examples/demo02.yml @@ -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