From f0724ede3f3dc837987690ba8e65633abfbdd5f8 Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Sun, 24 May 2020 14:44:19 +0200 Subject: [PATCH 1/4] Auto-decide connector pin side based on wiring --- readme.md | 1 - src/example1.py | 4 ++-- src/example2.py | 10 +++++----- src/example3.py | 16 ++++++++-------- src/wireviz.py | 48 +++++++++++++++++++++++++++++------------------- 5 files changed, 44 insertions(+), 35 deletions(-) diff --git a/readme.md b/readme.md index 45f2743..bc46641 100644 --- a/readme.md +++ b/readme.md @@ -99,7 +99,6 @@ The parser will follow later; contributions are welcome! ## To do -* Automate creation of left/right side ports for connectors * Add simple connectors (ferrules, cable lugs) * no pinout * graphical representation? diff --git a/src/example1.py b/src/example1.py index 0677c28..98c9818 100644 --- a/src/example1.py +++ b/src/example1.py @@ -3,8 +3,8 @@ import wireviz h = wireviz.Harness() h.add_cable('W1', mm2=0.25, length=0.2, show_name=True, show_pinout=True, num_wires=3, color_code='DIN', shield=True) -h.add_node('X1', type='D-Sub', gender='female', pinout=('DCD','RX','TX','DTR','GND','DSR','RTS','CTS','RI'), ports_right=True) -h.add_node('X2', type='Molex KK 254', gender='female', pinout=('GND','RX','TX','NC','OUT','IN'), ports_left=True) +h.add_node('X1', type='D-Sub', gender='female', pinout=('DCD','RX','TX','DTR','GND','DSR','RTS','CTS','RI')) +h.add_node('X2', type='Molex KK 254', gender='female', pinout=('GND','RX','TX','NC','OUT','IN')) # Option 1: define wires and shield in one line h.connect('W1','X1',(5,2,3,5),(1,2,3,'s'),'X2',(1,3,2,None)) h.loop('X2', 5, 6) diff --git a/src/example2.py b/src/example2.py index 952644b..d0f5be0 100644 --- a/src/example2.py +++ b/src/example2.py @@ -14,11 +14,11 @@ h.add_node('X1',type='Molex KK 254', gender='female', pinout=('GND', 'MISO', 'MOSI', 'SCK', - 'N/C'), ports_right=True) -h.add_node('X2', type='Molex KK 254', gender='female', pinout=PINOUT_I2C, ports_left=True) -h.add_node('X3', type='Molex KK 254', gender='female', pinout=PINOUT_I2C, ports_left=True) -h.add_node('X4', type='Molex KK 254', gender='female', pinout=('GND','+12V')+PINOUT_SPI_DATAONLY, ports_left=True) -h.add_node('X5', type='Molex Micro-Fit', gender='male', pinout=('GND','+12V'), ports_right=True) + 'N/C')) +h.add_node('X2', type='Molex KK 254', gender='female', pinout=PINOUT_I2C) +h.add_node('X3', type='Molex KK 254', gender='female', pinout=PINOUT_I2C) +h.add_node('X4', type='Molex KK 254', gender='female', pinout=('GND','+12V')+PINOUT_SPI_DATAONLY) +h.add_node('X5', type='Molex Micro-Fit', gender='male', pinout=('GND','+12V')) h.add_cable('W1', mm2=0.14, show_equiv=True, length=0.2, colors=COLORS_I2C, show_name=False) h.add_cable('W2', mm2=0.14, show_equiv=True, length=0.2, colors=COLORS_I2C, show_name=False) h.add_cable('W3', mm2=0.14, show_equiv=True, length=0.2, colors=('BK','BU','OG','VT'), show_name=False) diff --git a/src/example3.py b/src/example3.py index c4397b9..ef64012 100644 --- a/src/example3.py +++ b/src/example3.py @@ -3,23 +3,23 @@ import wireviz h = wireviz.Harness() h.color_mode = 'full' -h.add_node('X1', num_pins=10, ports_right=True) -h.add_node('X2', num_pins=10, ports_left=True) +h.add_node('X1', num_pins=10) +h.add_node('X2', num_pins=10) h.add_cable('W1', num_wires=10, color_code='IEC') h.connect_all_straight('W1','X1','X2') -h.add_node('X3', num_pins=20, ports_right=True) -h.add_node('X4', num_pins=20, ports_left=True) +h.add_node('X3', num_pins=20) +h.add_node('X4', num_pins=20) h.add_cable('W2', num_wires=20, color_code='DIN') h.connect_all_straight('W2','X3','X4') -h.add_node('X5', num_pins=20, ports_right=True) -h.add_node('X6', num_pins=20, ports_left=True) +h.add_node('X5', num_pins=20) +h.add_node('X6', num_pins=20) h.add_cable('W3', num_wires=20, colors=('RD','YE','BU')) h.connect_all_straight('W3','X5','X6') -h.add_node('X7', num_pins=6, ports_right=True) -h.add_node('X8', num_pins=6, ports_left=True) +h.add_node('X7', num_pins=6) +h.add_node('X8', num_pins=6) h.add_cable('W4', num_wires=6, length=1, mm2=1) h.connect_all_straight('W4','X7','X8') diff --git a/src/wireviz.py b/src/wireviz.py index 4024e1a..11efcf1 100644 --- a/src/wireviz.py +++ b/src/wireviz.py @@ -63,8 +63,8 @@ class Harness: def add_cable(self, name, mm2=None, awg=None, show_equiv=False, length=0, show_name=False, show_pinout=False, num_wires=None, colors=None, color_code=None, shield=False): self.cables[name] = Cable(name, mm2, awg, show_equiv, length, show_name, show_pinout, num_wires, colors, color_code, shield) - def loop(self, node_name, from_pin, to_pin, side=None): - self.nodes[node_name].loop(from_pin, to_pin, side) + def loop(self, node_name, from_pin, to_pin): + self.nodes[node_name].loop(from_pin, to_pin) def connect(self, cable_name, from_name, from_pin, via, to_name, to_pin): self.cables[cable_name].connect(from_name, from_pin, via, to_name, to_pin) @@ -81,6 +81,15 @@ class Harness: dot.attr('node', shape='record', style='rounded,filled', fillcolor='white', fontname=font) dot.attr('edge', style='bold', fontname=font) + # prepare ports on connectors depending on which side they will connect + for k in self.cables: + c = self.cables[k] + for x in c.connections: + if x[1] is not None: # connect to left + self.nodes[x[0]].ports_right = True + if x[4] is not None: # connect to right + self.nodes[x[3]].ports_left = True + for k in self.nodes: n = self.nodes[k] # a = attributes @@ -90,18 +99,26 @@ class Harness: p[1] = list(n.pinout) for i,x in enumerate(n.pinout, 1): if n.ports_left == True: - p[0].append('{portno}'.format(portno=i)) + p[0].append('{portno}'.format(portno=i)) if n.ports_right == True: - p[2].append('{portno}'.format(portno=i)) + p[2].append('{portno}'.format(portno=i)) # l = label l = [n.name if n.show_name == True else '', a, p] dot.node(k, label=nested(l)) if len(n.loops) > 0: dot.attr('edge',color='#000000') + if n.ports_left == True: + loop_side = 'l' + loop_dir = 'w' + elif n.ports_right == True: + loop_side = 'r' + loop_dir = 'e' + else: + raise Exception('No side for loops') for x in n.loops: - dot.edge('{name}:p{port_from}:{loop_side}'.format(name=n.name, port_from=x[0], port_to=x[1], loop_side=x[2]), - '{name}:p{port_to}:{loop_side}'.format(name=n.name, port_from=x[0], port_to=x[1], loop_side=x[2])) + dot.edge('{name}:p{port_from}{loop_side}:{loop_dir}'.format(name=n.name, port_from=x[0], port_to=x[1], loop_side=loop_side, loop_dir=loop_dir), + '{name}:p{port_to}{loop_side}:{loop_dir}'.format(name=n.name, port_from=x[0], port_to=x[1], loop_side=loop_side, loop_dir=loop_dir)) for k in self.cables: c = self.cables[k] @@ -142,11 +159,13 @@ class Harness: else: # it's a shield connection dot.attr('edge',color='#000000') if x[1] is not None: # connect to left - dot.edge('{from_name}:p{from_port}'.format(from_name=x[0],from_port=x[1]), + dot.edge('{from_name}:p{from_port}r'.format(from_name=x[0],from_port=x[1]), '{via_name}:w{via_wire}{via_subport}'.format(via_name=c.name, via_wire=x[2], via_subport='i' if c.show_pinout == True else '')) + # self.nodes[x[0]].ports_right = True if x[4] is not None: # connect to right dot.edge('{via_name}:w{via_wire}{via_subport}'.format(via_name=c.name, via_wire=x[2], via_subport='o' if c.show_pinout == True else ''), - '{to_name}:p{to_port}'.format(to_name=x[3], to_port=x[4])) + '{to_name}:p{to_port}l'.format(to_name=x[3], to_port=x[4])) + # self.nodes[x[3]].ports_left = True return dot @@ -177,17 +196,8 @@ class Node: else: self.pinout = pinout - def loop(self, from_pin, to_pin, side=None): - if self.ports_left == True and self.ports_right == False: - loop_side = 'w' # west = left - elif self.ports_left == False and self.ports_right == True: - loop_side = 'e' # east = right - elif self.ports_left == True and self.ports_right == True: - if side == None: - raise Exception('Must specify side of loop') - else: - loop_side = side - self.loops.append((from_pin, to_pin, loop_side)) + def loop(self, from_pin, to_pin): + self.loops.append((from_pin, to_pin)) class Cable: From 542aea2fe47d6498f277dad79a5a98e0af3e62ae Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Sun, 24 May 2020 15:05:59 +0200 Subject: [PATCH 2/4] Improve handling of empty lists when nesting --- src/wireviz.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/wireviz.py b/src/wireviz.py index 11efcf1..2e3928f 100644 --- a/src/wireviz.py +++ b/src/wireviz.py @@ -261,7 +261,9 @@ def nested(input): for x in input: if isinstance(x, list): if len(x) > 0: - l.append('{' + nested(x) + '}') + n = nested(x) + if n != '': + l.append('{' + n + '}') else: if x is not None: if x != '': From 09bc2825061c939c12f2a596b6adcd60edd84849 Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Sun, 24 May 2020 15:06:30 +0200 Subject: [PATCH 3/4] Add option to hide pin/wire counts --- src/wireviz.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/wireviz.py b/src/wireviz.py index 2e3928f..5116933 100644 --- a/src/wireviz.py +++ b/src/wireviz.py @@ -57,11 +57,11 @@ class Harness: self.nodes = {} self.cables = {} - def add_node(self, name, type=None, gender=None, show_name=True, num_pins=None, pinout=None, ports_left=False, ports_right=False): - self.nodes[name] = Node(name, type, gender, show_name, num_pins, pinout, ports_left, ports_right) + def add_node(self, name, type=None, gender=None, show_name=True, num_pins=None, show_num_pins=True, pinout=None, ports_left=False, ports_right=False): + self.nodes[name] = Node(name, type, gender, show_name, num_pins, show_num_pins, pinout, ports_left, ports_right) - def add_cable(self, name, mm2=None, awg=None, show_equiv=False, length=0, show_name=False, show_pinout=False, num_wires=None, colors=None, color_code=None, shield=False): - self.cables[name] = Cable(name, mm2, awg, show_equiv, length, show_name, show_pinout, num_wires, colors, color_code, shield) + def add_cable(self, name, mm2=None, awg=None, show_equiv=False, length=0, show_name=False, show_pinout=False, num_wires=None, show_num_wires=True, colors=None, color_code=None, shield=False): + self.cables[name] = Cable(name, mm2, awg, show_equiv, length, show_name, show_pinout, num_wires, show_num_wires, colors, color_code, shield) def loop(self, node_name, from_pin, to_pin): self.nodes[node_name].loop(from_pin, to_pin) @@ -93,7 +93,9 @@ class Harness: for k in self.nodes: n = self.nodes[k] # a = attributes - a = [n.type, n.gender, '{}-pin'.format(len(n.pinout))] + a = [n.type, + n.gender, + '{}-pin'.format(len(n.pinout)) if n.show_num_pins == True else ''] # p = pinout p = [[],[],[]] p[1] = list(n.pinout) @@ -123,11 +125,11 @@ class Harness: for k in self.cables: c = self.cables[k] # a = attributes - a = ['{}x'.format(len(c.colors)), - '{} mm\u00B2{}'.format(c.mm2, ' ({} AWG)'.format(awg_equiv(c.mm2)) if c.show_equiv == True else ''), + a = ['{}x'.format(len(c.colors)) if c.show_num_wires == True else '', + '{} mm\u00B2{}'.format(c.mm2, ' ({} AWG)'.format(awg_equiv(c.mm2)) if c.show_equiv == True else '') if c.mm2 is not None else '', c.awg, '+ S' if c.shield == True else '', - '{} m'.format(c.length)] + '{} m'.format(c.length) if c.length > 0 else ''] # p = pinout p = [[],[],[]] for i,x in enumerate(c.colors,1): @@ -178,11 +180,12 @@ class Harness: class Node: - def __init__(self, name, type=None, gender=None, show_name=True, num_pins=None, pinout=None, ports_left=False, ports_right=False): + def __init__(self, name, type=None, gender=None, show_name=True, num_pins=None, show_num_pins=True, pinout=None, ports_left=False, ports_right=False): self.name = name self.type = type self.gender = gender self.show_name = show_name + self.show_num_pins = show_num_pins self.ports_left = ports_left self.ports_right = ports_right self.loops = [] @@ -201,7 +204,7 @@ class Node: class Cable: - def __init__(self, name, mm2=None, awg=None, show_equiv=False, length=0, show_name=False, show_pinout=False, num_wires=None, colors=None, color_code=None, shield=False): + def __init__(self, name, mm2=None, awg=None, show_equiv=False, length=0, show_name=False, show_pinout=False, num_wires=None, show_num_wires=True, colors=None, color_code=None, shield=False): self.name = name if mm2 is not None and awg is not None: raise Exception('You cannot define both mm2 and awg!') @@ -211,6 +214,7 @@ class Cable: self.length = length self.show_name = show_name self.show_pinout = show_pinout + self.show_num_wires = show_num_wires self.shield = shield self.connections = [] if color_code is None and colors is None: From 06a9188e8354d0c398ca4898ba61b485da3b2528 Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Sun, 24 May 2020 15:10:56 +0200 Subject: [PATCH 4/4] Add minimalist example 4 --- src/example2.py | 16 ++++++++-------- src/example4.py | 13 +++++++++++++ 2 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 src/example4.py diff --git a/src/example2.py b/src/example2.py index d0f5be0..5af74f1 100644 --- a/src/example2.py +++ b/src/example2.py @@ -7,14 +7,14 @@ PINOUT_I2C = ('GND','+5V','SCL','SDA') COLORS_I2C = ('BK', 'RD', 'YE', 'GN') PINOUT_SPI_DATAONLY = ('MISO','MOSI','SCK') -h.add_node('X1',type='Molex KK 254', gender='female', pinout=('GND', - '+5V', - 'SCL', - 'SDA', - 'MISO', - 'MOSI', - 'SCK', - 'N/C')) +h.add_node('X1', type='Molex KK 254', gender='female', pinout=('GND', + '+5V', + 'SCL', + 'SDA', + 'MISO', + 'MOSI', + 'SCK', + 'N/C')) h.add_node('X2', type='Molex KK 254', gender='female', pinout=PINOUT_I2C) h.add_node('X3', type='Molex KK 254', gender='female', pinout=PINOUT_I2C) h.add_node('X4', type='Molex KK 254', gender='female', pinout=('GND','+12V')+PINOUT_SPI_DATAONLY) diff --git a/src/example4.py b/src/example4.py new file mode 100644 index 0000000..97f9bb9 --- /dev/null +++ b/src/example4.py @@ -0,0 +1,13 @@ +import wireviz + +h = wireviz.Harness() + +h.add_cable('W1', show_name=False, show_num_wires=False, num_wires=4, color_code='DIN') +h.add_cable('W2', show_name=False, show_num_wires=False, num_wires=4, color_code='DIN') +h.add_node('X1', num_pins=4, show_num_pins=False) +h.add_node('X2', num_pins=4, show_num_pins=False) +h.add_node('X3', num_pins=4, show_num_pins=False) +h.connect_all_straight('W1','X1','X2') +h.connect_all_straight('W2','X2','X3') + +h.output(filename='output', format=('png','svg'), view=False)