Skip to content

Commit afc1405

Browse files
committed
feat: loop use object to provide more attributes
1 parent 0029fc1 commit afc1405

File tree

7 files changed

+133
-15
lines changed

7 files changed

+133
-15
lines changed

docs/syntax.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,14 @@ options: # dictionary of common attributes for the whole harness
8181
hide_disconnected_pins: <bool> # defaults to false
8282

8383
# loops
84-
loops: <List> # every list item is itself a list of exactly two pins
84+
loops: <List[loop]> # every list item is a loop object representing two pins
8585
# on the connector that are to be shorted
86+
loop:
87+
- <first>: the first <pin> of the loop
88+
- <second>: the second <pin> of the loop
89+
- <side>: either "LEFT" or "RIGHT"
90+
- show_label: <bool> defaults to true, will show the loop label
91+
8692
```
8793

8894
## Cable attributes

examples/ex11.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Example 11: loopback wires
2+
connectors:
3+
X1:
4+
type: Stewart Connector SS-37000-002
5+
subtype: male
6+
pinlabels: [DA+,DA-,LB4,LB3,DD+,DD-,LB1, LB2] # pincount is implicit in pinout
7+
loops:
8+
- first: 1
9+
second: 2
10+
side: LEFT
11+
- first: LB3
12+
second: LB4
13+
side: LEFT
14+
X2:
15+
type: Stewart Connector SS-37000-002
16+
subtype: male
17+
pinlabels: [LB5,LB6,DA+,DD+,DD-,DA-,LB7,LB8]
18+
loops:
19+
- first: 1
20+
second: 2
21+
side: RIGHT
22+
show_label: false
23+
- first: LB7
24+
second: LB8
25+
side: LEFT
26+
27+
cables:
28+
W1:
29+
color_code: T568A # auto-color wires based on a standard
30+
wirecount: 4 # need to specify number of wires explicitly when using a color code
31+
gauge: 24 AWG # also accepts AWG as unit
32+
length: 1 # length in m
33+
shield: false
34+
type: CAT5e
35+
36+
#WLB1:
37+
# wirecount: 1
38+
39+
#WLB2:
40+
# wirecount: 1
41+
42+
43+
connections:
44+
- - X1: [1,2,5,6]
45+
- W1: [1-4]
46+
- X2: [3,6,4,5] # crossover
47+
#- - X1: [7]
48+
# - WLB1: [1]
49+
# - X1: [8]
50+
#- - X2: [8]
51+
# - WLB2: [1]
52+
# - X2: [7]

examples/readme.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,9 @@
6060
[Source](ex10.yml) - [Bill of Materials](ex10.bom.tsv)
6161

6262

63+
## Example 11
64+
![](ex11.png)
65+
66+
[Source](ex11.yml) - [Bill of Materials](ex11.bom.tsv)
67+
68+

src/wireviz/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# -*- coding: utf-8 -*-
22
# Please don't import anything in this file to avoid issues when it is imported in setup.py
33

4-
__version__ = "0.5.3"
4+
__version__ = "0.5.4"
55

66
CMD_NAME = "wireviz" # Lower case command and module name
77
APP_NAME = "WireViz" # Application name in texts meant to be human readable

src/wireviz/wv_dataclasses.py

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,32 @@ def __post_init__(self):
210210

211211
self.designator = remove_links(self.designator)
212212

213+
@dataclass
214+
class Loop():
215+
first: PinClass = None
216+
second: PinClass = None
217+
side: Side = None
218+
show_label: bool = True
219+
220+
def __post_init__(self):
221+
if self.side.upper() == 'LEFT':
222+
self.side = Side.LEFT
223+
elif self.side.upper() == 'RIGHT':
224+
self.side = Side.RIGHT
225+
226+
@property
227+
def label(self):
228+
if self.show_label:
229+
return f'{self.first}<->{self.second}'
230+
else:
231+
return ''
232+
213233

214234
@dataclass
215235
class Connector(GraphicalComponent):
216236
# connector-specific properties
217237
style: Optional[str] = None
218-
loops: List[List[Pin]] = field(default_factory=list)
238+
loops: List[Loop] = field(default_factory=list)
219239
# pin information in particular
220240
pincount: Optional[int] = None
221241
pins: List[Pin] = field(default_factory=list) # legacy
@@ -308,6 +328,7 @@ def to_int_pin(pin):
308328
return pin
309329
self.pins = [to_int_pin(p) for p in self.pins]
310330

331+
311332
# all checks have passed
312333
pin_tuples = zip_longest(
313334
self.pins,
@@ -332,17 +353,41 @@ def to_int_pin(pin):
332353
# hide pincount for simple (1 pin) connectors by default
333354
self.show_pincount = self.style != "simple"
334355

335-
self.loops = [[to_int_pin(p) for p in loop] for loop in self.loops]
356+
def get_pin_object(value):
357+
pin_id = None
358+
if value in self.pinlabels:
359+
pin_id = self.pins[self.pinlabels.index(value)]
360+
else:
361+
err = f'{value} not found in {self.pinlabels}'
362+
try:
363+
value = int(value)
364+
except ValueError as exc:
365+
raise ValueError(f'{err} and is not an int')
366+
367+
if value in self.pins:
368+
pin_id = value
369+
370+
if pin_id is not None:
371+
return self.pin_objects[pin_id]
372+
373+
raise ValueError(f'{err} and is not one of the pins {self.pins}')
374+
375+
self.loops = [Loop(
376+
first=get_pin_object(loop['first']),
377+
second=get_pin_object(loop['second']),
378+
side=loop.get('side'),
379+
show_label=loop.get('show_label', True),
380+
) for loop in self.loops]
381+
382+
383+
#self.loops = [[to_int_pin(p) for p in loop] for loop in self.loops]
336384
for loop in self.loops:
337385
# TODO: check that pins to connect actually exist
338386
# TODO: allow using pin labels in addition to pin numbers,
339387
# just like when defining regular connections
340388
# TODO: include properties of wire used to create the loop
341-
if len(loop) != 2:
342-
raise Exception("Loops must be between exactly two pins!")
343-
# side=None, determine side to show loops during rendering
344-
self.activate_pin(loop[0], side=None, is_connection=True)
345-
self.activate_pin(loop[1], side=None, is_connection=True)
389+
self.activate_pin(loop.first.id, side=loop.side, is_connection=True)
390+
self.activate_pin(loop.second.id, side=loop.side, is_connection=True)
346391

347392
def activate_pin(self, pin_id, side: Side = None, is_connection=True) -> None:
348393
if is_connection:

src/wireviz/wv_graphviz.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from wireviz import APP_NAME, APP_URL, __version__
77
from wireviz.wv_colors import MultiColor, SingleColor
8-
from wireviz.wv_dataclasses import Cable, Component, Connector, ShieldClass, WireClass
8+
from wireviz.wv_dataclasses import Cable, Component, Connector, ShieldClass, WireClass, Side
99
from wireviz.wv_html import Img, Table, Td, Tr
1010
from wireviz.wv_templates import get_template
1111
from wireviz.wv_utils import html_line_breaks, remove_links
@@ -45,9 +45,18 @@ def gv_connector_loops(connector: Connector) -> List:
4545
else:
4646
raise Exception("No side for loops")
4747
for loop in connector.loops:
48-
head = f"{connector.designator}:p{loop[0]}{loop_side}:{loop_dir}"
49-
tail = f"{connector.designator}:p{loop[1]}{loop_side}:{loop_dir}"
50-
loop_edges.append((head, tail))
48+
this_loop_side = loop_side
49+
this_loop_dir = loop_dir
50+
if loop.side == Side.RIGHT:
51+
this_loop_side = 'r'
52+
this_loop_dir = 'e'
53+
elif loop.side == Side.LEFT:
54+
this_loop_side = 'l'
55+
this_loop_dir = 'w'
56+
57+
head = f"{connector.designator}:p{loop.first.id}{this_loop_side}:{this_loop_dir}"
58+
tail = f"{connector.designator}:p{loop.second.id}{this_loop_side}:{this_loop_dir}"
59+
loop_edges.append((loop, head, tail))
5160
return loop_edges
5261

5362

src/wireviz/wv_harness.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,8 +317,8 @@ def create_graph(self) -> Graph:
317317
if len(connector.loops) > 0:
318318
dot.attr("edge", color="#000000")
319319
loops = gv_connector_loops(connector)
320-
for head, tail in loops:
321-
dot.edge(head, tail)
320+
for loop, head, tail in loops:
321+
dot.edge(head, tail, xlabel=loop.label)
322322

323323
# determine if there are double- or triple-colored wires in the harness;
324324
# if so, pad single-color wires to make all wires of equal thickness

0 commit comments

Comments
 (0)