Skip to content

Commit

Permalink
Allow addittional BOM items within components (#115)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tyler-Ward authored Oct 22, 2020
1 parent 4e4dac8 commit e85ee5d
Show file tree
Hide file tree
Showing 6 changed files with 266 additions and 110 deletions.
57 changes: 39 additions & 18 deletions docs/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,12 @@ additional_bom_items: # custom items to add to BOM
notes: <str>

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

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

# product information (all optional)
pn: <str> # [internal] part number
mpn: <str> # manufacturer part number
manufacturer: <str> # manufacturer name
ignore_in_bom: <bool> # if set to true the cable or wires are not added to the BOM
pn: <str> # [internal] part number
mpn: <str> # manufacturer part number
manufacturer: <str> # manufacturer name
additional_components: # additional components
- <additional-component> # additional component (see below)

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


## BOM items
## BOM items and additional components

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

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

Additional BOM entries can be generated in the sections marked `<bom-item>` above.
```yaml
-
type: <str> # type of additional component
# all the following are optional:
subtype: <str> # additional description (only shown in bom)
qty: <int/float> # qty to add to the bom (defaults to 1)
qty_multiplier: <str> # multiplies qty by a feature of the parent component
# when used in a connector:
# pincount number of pins of connector
# populated number of populated positions in a connector
# when used in a cable:
# wirecount number of wires of cable/bundle
# terminations number of terminations on a cable/bundle
# length length of cable/bundle
# total_length sum of lengths of each wire in the bundle
unit: <str>
pn: <str> # [internal] part number
mpn: <str> # manufacturer part number
manufacturer: <str> # manufacturer name
```
<!-- BOM items inside connectors/cables are not implemented yet, but should be soon (#50) -->
Alternatively items can be added to just the BOM by putting them in the section `<bom-item>` above.

```yaml
-
description: <str>
qty: <int/str> # when used in the additional_bom_items section:
# <int> manually specify qty.
# when used within a component:
# <int> manually specify qty.
# pincount match number of pins of connector
# wirecount match number of wires of cable/bundle
# connectioncount match number of connected pins
# all the following are optional:
qty: <int/float> # qty to add to the bom (defaults to 1)
unit: <str>
designators: <List>
pn: <str> # [internal] part number
Expand Down
54 changes: 54 additions & 0 deletions src/wireviz/DataClasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
from wireviz.wv_helper import int2tuple, aspect_ratio
from wireviz import wv_colors

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


@dataclass
class Image:
Expand Down Expand Up @@ -43,6 +47,21 @@ def __post_init__(self, gv_dir):
if self.width:
self.height = self.width / aspect_ratio(gv_dir.joinpath(self.src))

@dataclass
class AdditionalComponent:
type: str
subtype: Optional[str] = None
manufacturer: Optional[str] = None
mpn: Optional[str] = None
pn: Optional[str] = None
qty: float = 1
unit: Optional[str] = None
qty_multiplier: Union[ConnectorMultiplier, CableMultiplier, None] = None

@property
def description(self) -> str:
return self.type.rstrip() + (f', {self.subtype.rstrip()}' if self.subtype else '')


@dataclass
class Connector:
Expand All @@ -65,6 +84,8 @@ class Connector:
hide_disconnected_pins: bool = False
autogenerate: bool = False
loops: List[Any] = field(default_factory=list)
ignore_in_bom: bool = False
additional_components: List[AdditionalComponent] = field(default_factory=list)

def __post_init__(self):

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

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

def activate_pin(self, pin):
self.visible_pins[pin] = True

def get_qty_multiplier(self, qty_multiplier: Optional[ConnectorMultiplier]) -> int:
if not qty_multiplier:
return 1
elif qty_multiplier == 'pincount':
return self.pincount
elif qty_multiplier == 'populated':
return sum(self.visible_pins.values())
else:
raise ValueError(f'invalid qty multiplier parameter for connector {qty_multiplier}')


@dataclass
class Cable:
Expand All @@ -139,6 +174,8 @@ class Cable:
color_code: Optional[str] = None
show_name: bool = True
show_wirecount: bool = True
ignore_in_bom: bool = False
additional_components: List[AdditionalComponent] = field(default_factory=list)

def __post_init__(self):

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

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

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

def get_qty_multiplier(self, qty_multiplier: Optional[CableMultiplier]) -> float:
if not qty_multiplier:
return 1
elif qty_multiplier == 'wirecount':
return self.wirecount
elif qty_multiplier == 'terminations':
return len(self.connections)
elif qty_multiplier == 'length':
return self.length
elif qty_multiplier == 'total_length':
return self.length * self.wirecount
else:
raise ValueError(f'invalid qty multiplier parameter for cable {qty_multiplier}')


@dataclass
class Connection:
Expand Down
Loading

0 comments on commit e85ee5d

Please # to comment.