Skip to content

Commit e85ee5d

Browse files
authored
Allow addittional BOM items within components (#115)
1 parent 4e4dac8 commit e85ee5d

File tree

6 files changed

+266
-110
lines changed

6 files changed

+266
-110
lines changed

docs/syntax.md

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,12 @@ additional_bom_items: # custom items to add to BOM
4343
notes: <str>
4444

4545
# product information (all optional)
46-
pn: <str> # [internal] part number
47-
mpn: <str> # manufacturer part number
48-
manufacturer: <str> # manufacturer name
46+
ignore_in_bom: <bool> # if set to true the connector is not added to the BOM
47+
pn: <str> # [internal] part number
48+
mpn: <str> # manufacturer part number
49+
manufacturer: <str> # manufacturer name
50+
additional_components: # additional components
51+
- <additional-component> # additional component (see below)
4952

5053
# pinout information
5154
# at least one of the following must be specified
@@ -108,9 +111,12 @@ Since the auto-incremented and auto-assigned designator is not known to the user
108111
notes: <str>
109112

110113
# product information (all optional)
111-
pn: <str> # [internal] part number
112-
mpn: <str> # manufacturer part number
113-
manufacturer: <str> # manufacturer name
114+
ignore_in_bom: <bool> # if set to true the cable or wires are not added to the BOM
115+
pn: <str> # [internal] part number
116+
mpn: <str> # manufacturer part number
117+
manufacturer: <str> # manufacturer name
118+
additional_components: # additional components
119+
- <additional-component> # additional component (see below)
114120

115121
# conductor information
116122
# the following combinations are permitted:
@@ -212,27 +218,42 @@ For connectors with `autogenerate: true`, a new instance, with auto-generated de
212218
- `<int>-<int>` auto-expands to a range.
213219

214220

215-
## BOM items
221+
## BOM items and additional components
216222

217-
Connectors (both regular, and auto-generated), cables, and wires of a bundle are automatically added to the BOM.
223+
Connectors (both regular, and auto-generated), cables, and wires of a bundle are automatically added to the BOM,
224+
unless the `ignore_in_bom` attribute is set to `true`.
225+
Additional items can be added to the BOM as either part of a connector or cable or on their own.
218226

219-
<!-- unless the `ignore_in_bom` attribute is set to `true` (#115) -->
227+
Parts can be added to a connector or cable in the section `<additional-component>` which will also list them in the graph.
220228

221-
Additional BOM entries can be generated in the sections marked `<bom-item>` above.
229+
```yaml
230+
-
231+
type: <str> # type of additional component
232+
# all the following are optional:
233+
subtype: <str> # additional description (only shown in bom)
234+
qty: <int/float> # qty to add to the bom (defaults to 1)
235+
qty_multiplier: <str> # multiplies qty by a feature of the parent component
236+
# when used in a connector:
237+
# pincount number of pins of connector
238+
# populated number of populated positions in a connector
239+
# when used in a cable:
240+
# wirecount number of wires of cable/bundle
241+
# terminations number of terminations on a cable/bundle
242+
# length length of cable/bundle
243+
# total_length sum of lengths of each wire in the bundle
244+
unit: <str>
245+
pn: <str> # [internal] part number
246+
mpn: <str> # manufacturer part number
247+
manufacturer: <str> # manufacturer name
248+
```
222249
223-
<!-- BOM items inside connectors/cables are not implemented yet, but should be soon (#50) -->
250+
Alternatively items can be added to just the BOM by putting them in the section `<bom-item>` above.
224251

225252
```yaml
226253
-
227254
description: <str>
228-
qty: <int/str> # when used in the additional_bom_items section:
229-
# <int> manually specify qty.
230-
# when used within a component:
231-
# <int> manually specify qty.
232-
# pincount match number of pins of connector
233-
# wirecount match number of wires of cable/bundle
234-
# connectioncount match number of connected pins
235255
# all the following are optional:
256+
qty: <int/float> # qty to add to the bom (defaults to 1)
236257
unit: <str>
237258
designators: <List>
238259
pn: <str> # [internal] part number

src/wireviz/DataClasses.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
from wireviz.wv_helper import int2tuple, aspect_ratio
88
from wireviz import wv_colors
99

10+
# Literal type aliases below are commented to avoid requiring python 3.8
11+
ConnectorMultiplier = str # = Literal['pincount', 'populated']
12+
CableMultiplier = str # = Literal['wirecount', 'terminations', 'length', 'total_length']
13+
1014

1115
@dataclass
1216
class Image:
@@ -43,6 +47,21 @@ def __post_init__(self, gv_dir):
4347
if self.width:
4448
self.height = self.width / aspect_ratio(gv_dir.joinpath(self.src))
4549

50+
@dataclass
51+
class AdditionalComponent:
52+
type: str
53+
subtype: Optional[str] = None
54+
manufacturer: Optional[str] = None
55+
mpn: Optional[str] = None
56+
pn: Optional[str] = None
57+
qty: float = 1
58+
unit: Optional[str] = None
59+
qty_multiplier: Union[ConnectorMultiplier, CableMultiplier, None] = None
60+
61+
@property
62+
def description(self) -> str:
63+
return self.type.rstrip() + (f', {self.subtype.rstrip()}' if self.subtype else '')
64+
4665

4766
@dataclass
4867
class Connector:
@@ -65,6 +84,8 @@ class Connector:
6584
hide_disconnected_pins: bool = False
6685
autogenerate: bool = False
6786
loops: List[Any] = field(default_factory=list)
87+
ignore_in_bom: bool = False
88+
additional_components: List[AdditionalComponent] = field(default_factory=list)
6889

6990
def __post_init__(self):
7091

@@ -114,9 +135,23 @@ def __post_init__(self):
114135
if len(loop) != 2:
115136
raise Exception('Loops must be between exactly two pins!')
116137

138+
for i, item in enumerate(self.additional_components):
139+
if isinstance(item, dict):
140+
self.additional_components[i] = AdditionalComponent(**item)
141+
117142
def activate_pin(self, pin):
118143
self.visible_pins[pin] = True
119144

145+
def get_qty_multiplier(self, qty_multiplier: Optional[ConnectorMultiplier]) -> int:
146+
if not qty_multiplier:
147+
return 1
148+
elif qty_multiplier == 'pincount':
149+
return self.pincount
150+
elif qty_multiplier == 'populated':
151+
return sum(self.visible_pins.values())
152+
else:
153+
raise ValueError(f'invalid qty multiplier parameter for connector {qty_multiplier}')
154+
120155

121156
@dataclass
122157
class Cable:
@@ -139,6 +174,8 @@ class Cable:
139174
color_code: Optional[str] = None
140175
show_name: bool = True
141176
show_wirecount: bool = True
177+
ignore_in_bom: bool = False
178+
additional_components: List[AdditionalComponent] = field(default_factory=list)
142179

143180
def __post_init__(self):
144181

@@ -196,6 +233,9 @@ def __post_init__(self):
196233
else:
197234
raise Exception('lists of part data are only supported for bundles')
198235

236+
for i, item in enumerate(self.additional_components):
237+
if isinstance(item, dict):
238+
self.additional_components[i] = AdditionalComponent(**item)
199239

200240
def connect(self, from_name, from_pin, via_pin, to_name, to_pin):
201241
from_pin = int2tuple(from_pin)
@@ -207,6 +247,20 @@ def connect(self, from_name, from_pin, via_pin, to_name, to_pin):
207247
# self.connections.append((from_name, from_pin[i], via_pin[i], to_name, to_pin[i]))
208248
self.connections.append(Connection(from_name, from_pin[i], via_pin[i], to_name, to_pin[i]))
209249

250+
def get_qty_multiplier(self, qty_multiplier: Optional[CableMultiplier]) -> float:
251+
if not qty_multiplier:
252+
return 1
253+
elif qty_multiplier == 'wirecount':
254+
return self.wirecount
255+
elif qty_multiplier == 'terminations':
256+
return len(self.connections)
257+
elif qty_multiplier == 'length':
258+
return self.length
259+
elif qty_multiplier == 'total_length':
260+
return self.length * self.wirecount
261+
else:
262+
raise ValueError(f'invalid qty multiplier parameter for cable {qty_multiplier}')
263+
210264

211265
@dataclass
212266
class Connection:

0 commit comments

Comments
 (0)