Compute qty's of additional components (WIP)

This commit is contained in:
Daniel Rojas 2021-10-24 18:18:03 +02:00 committed by KV
parent 7902ba6aa6
commit b2e5c467c3
4 changed files with 79 additions and 48 deletions

View File

@ -22,10 +22,10 @@ BomCategory = Enum(
"BomEntry", "CONNECTOR CABLE WIRE ADDITIONAL_INSIDE ADDITIONAL_OUTSIDE" "BomEntry", "CONNECTOR CABLE WIRE ADDITIONAL_INSIDE ADDITIONAL_OUTSIDE"
) )
QtyMultiplierConnector = Enum( QtyMultiplierConnector = Enum(
"QtyMultiplierConnector", "ONE PINCOUNT POPULATED CONNECTIONS" "QtyMultiplierConnector", "PINCOUNT POPULATED CONNECTIONS"
) )
QtyMultiplierCable = Enum( QtyMultiplierCable = Enum(
"QtyMultiplierCable", "ONE WIRECOUNT TERMINATION LENGTH TOTAL_LENGTH" "QtyMultiplierCable", "WIRECOUNT TERMINATION LENGTH TOTAL_LENGTH"
) )
PART_NUMBER_HEADERS = PartNumberInfo( PART_NUMBER_HEADERS = PartNumberInfo(

View File

@ -262,7 +262,7 @@ class Component:
@dataclass @dataclass
class AdditionalComponent(Component): class AdditionalComponent(Component):
qty_multiplier: Union[QtyMultiplierConnector, QtyMultiplierCable, int] = 1 qty_multiplier: Union[QtyMultiplierConnector, QtyMultiplierCable, int] = 1
qty_multipliers_computed: Dict = field(default_factory=list) _qty_multiplier_computed: Union[int, float] = 1
designators: Optional[str] = None # used for components definedi in the designators: Optional[str] = None # used for components definedi in the
# additional_bom_items section within another component # additional_bom_items section within another component
bgcolor: SingleColor = None # ^ same here bgcolor: SingleColor = None # ^ same here
@ -288,12 +288,11 @@ class AdditionalComponent(Component):
@property @property
def bom_qty(self): def bom_qty(self):
return 999 return self.qty.number * self._qty_multiplier_computed
@property @property
def description(self) -> str: def description(self) -> str:
substrs = [self.type, self.subtype if self.subtype else ""] return f"{self.type}{', ' + self.subtype if self.subtype else ''}"
return ", ".join(substrs)
@dataclass @dataclass
@ -450,32 +449,26 @@ class Connector(TopLevelGraphicalComponent):
self.ports_right = True self.ports_right = True
def compute_qty_multipliers(self): def compute_qty_multipliers(self):
# do not run before all connections in harness have been made!
num_populated_pins = len(
[pin for pin in self.pin_objects.values() if pin._num_connections > 0]
)
num_connections = sum(
[pin._num_connections for pin in self.pin_objects.values()]
)
qty_multipliers_computed = {
"PINCOUNT": self.pincount,
"POPULATED": num_populated_pins,
"CONNECTIONS": num_connections,
}
for subitem in self.additional_components: for subitem in self.additional_components:
populated_pins = [] if isinstance(subitem.qty_multiplier, QtyMultiplierConnector):
subitem.qty_multipliers_computed["ONE"] = 1 computed_factor = qty_multipliers_computed[subitem.qty_multiplier.name]
subitem.qty_multipliers_computed["PINCOUNT"] = self.pincount elif isinstance(subitem.qty_multiplier, QtyMultiplierCable):
subitem.qty_multipliers_computed["POPULATED"] = 999 raise Exception("Used a cable multiplier in a connector!")
subitem.qty_multipliers_computed["CONNECTIONS"] = 999 else: # int or float
computed_factor = subitem.qty_multiplier
# QtyMultiplierConnector = Enum( subitem._qty_multiplier_computed = computed_factor
# "QtyMultiplierConnector", "ONE PINCOUNT POPULATED CONNECTIONS"
# )
# QtyMultiplierCable = Enum(
# "QtyMultiplierCable", "ONE WIRECOUNT TERMINATION LENGTH TOTAL_LENGTH"
# )
# def get_qty_multiplier(self, qty_multiplier: Optional[ConnectorMultiplier]) -> int:
# # TODO!!! how and when to compute final qty for additional components???
# 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 @dataclass
@ -744,21 +737,37 @@ class Cable(TopLevelGraphicalComponent):
via_wire_obj = self.wire_objects[via_wire_id] via_wire_obj = self.wire_objects[via_wire_id]
self._connections.append(Connection(from_pin_obj, via_wire_obj, to_pin_obj)) self._connections.append(Connection(from_pin_obj, via_wire_obj, to_pin_obj))
# def get_qty_multiplier(self, qty_multiplier: Optional[CableMultiplier]) -> float: def compute_qty_multipliers(self):
# if not qty_multiplier: # do not run before all connections in harness have been made!
# return 1 total_length = sum(
# elif qty_multiplier == "wirecount": [
# return self.wirecount wire.length.number if wire.length else 0
# elif qty_multiplier == "terminations": for wire in self.wire_objects.values()
# return len(self.connections) ]
# elif qty_multiplier == "length": )
# return self.length qty_multipliers_computed = {
# elif qty_multiplier == "total_length": "WIRECOUNT": len(self.wire_objects),
# return self.length * self.wirecount "TERMINATIONS": 999, # TODO
# else: "LENGTH": self.length.number if self.length else 0,
# raise ValueError( "TOTAL_LENGTH": total_length,
# f"invalid qty multiplier parameter for cable {qty_multiplier}" }
# ) for subitem in self.additional_components:
if isinstance(subitem.qty_multiplier, QtyMultiplierCable):
computed_factor = qty_multipliers_computed[subitem.qty_multiplier.name]
# inherit component's length unit if appropriate
if subitem.qty_multiplier.name in ["LENGTH", "TOTAL_LENGTH"]:
if subitem.qty.unit is not None:
raise Exception(
f"No unit may be specified when using"
f"{subitem.qty_multiplier} as a multiplier"
)
subitem.qty = NumberAndUnit(subitem.qty.number, self.length.unit)
elif isinstance(subitem.qty_multiplier, QtyMultiplierConnector):
raise Exception("Used a connector multiplier in a cable!")
else: # int or float
computed_factor = subitem.qty_multiplier
subitem._qty_multiplier_computed = computed_factor
@dataclass @dataclass

View File

@ -64,8 +64,7 @@ def gv_node_component(component: Component) -> Table:
x = colorbar_cell(component.color) if component.color else None x = colorbar_cell(component.color) if component.color else None
line_image, line_image_caption = image_and_caption_cells(component) line_image, line_image_caption = image_and_caption_cells(component)
# line_additional_component_table = get_additional_component_table(self, connector) line_additional_component_table = gv_additional_component_table(component)
line_additional_component_table = None
line_notes = [html_line_breaks(component.notes)] line_notes = [html_line_breaks(component.notes)]
if isinstance(component, Connector): if isinstance(component, Connector):
@ -100,6 +99,25 @@ def gv_node_component(component: Component) -> Table:
return tbl return tbl
def gv_additional_component_table(component):
if not component.additional_components:
return None
rows = []
for subitem in component.additional_components:
rows.append(
Tr(
[
Td(f"{subitem.bom_qty}"),
Td(f"{subitem.qty.unit if subitem.qty.unit else 'x'}"),
Td(f"{subitem.description}"),
]
)
)
return Table(rows)
def calculate_node_bgcolor(component, harness_options): def calculate_node_bgcolor(component, harness_options):
# assign component node bgcolor at the GraphViz node level # assign component node bgcolor at the GraphViz node level
# instead of at the HTML table level for better rendering of node outline # instead of at the HTML table level for better rendering of node outline

View File

@ -142,6 +142,10 @@ class Harness:
designator=item.designator, designator=item.designator,
category=cat, category=cat,
) )
if item.additional_components:
if item.category == "bundle":
pass # TODO
item.compute_qty_multipliers()
for comp in item.additional_components: for comp in item.additional_components:
if comp.ignore_in_bom: if comp.ignore_in_bom:
continue continue