diff --git a/readme.md b/readme.md index bc46641..f25e63a 100644 --- a/readme.md +++ b/readme.md @@ -23,6 +23,8 @@ It is based on [GraphViz](https://www.graphviz.org/) and designed as an "extensi * Allows more than one connector per side, as well as loopbacks * Allows for easy-autorouting for 1-to-1 wiring +_Note_: WireViz is not designed to represent the complete wiring of a system. Its main aim is to document the construction of individual wires and harnesses. + ## Example WireViz input file: diff --git a/src/example1.yml b/src/example1.yml index f0c0270..05a5877 100644 --- a/src/example1.yml +++ b/src/example1.yml @@ -2,7 +2,7 @@ nodes: X1: type: D-Sub gender: female - pinout: [DCD,RX,TX,DTR,GND,DSR,RTS,CTS,RI] + pinout: [DCD, RX, TX, DTR, GND, DSR, RTS, CTS, RI] random: yes X2: type: Molex KK 254 @@ -18,33 +18,13 @@ wires: shield: true connections: - - - items: [X1,W1,X2] - X1: 5 # [5,2,3] - W1: 1 # [1,2,3] - X2: 1 # [1,3,2] - - - items: [X1,W1,X2] - X1: 2 # [5,2,3] - W1: 2 # [1,2,3] - X2: 3 # [1,3,2] - - - items: [X1,W1,X2] - X1: 3 # [5,2,3] - W1: 3 # [1,2,3] - X2: 2 # [1,3,2] - - - items: [X1,W1,X2] - X1: 5 - W1: s - X2: ~ - -options: - # for connectors - show_connector_name: true - show_num_pins: true - # for wires - show_wire_name: true - show_num_wires: true - show_wire_pinout: true - show awg_equiv: true + - # format: connector->wire->connector + - X1: [5,2,1] + - W1: [1,2,3] + - X2: [1,3,2] + - # format: connector->wire or wire->connector + - X1: 5 + - W1: s + - # loop: connector-connector + - X2: 5 + - X2: 6 diff --git a/src/testconnections.yml b/src/testconnections.yml new file mode 100644 index 0000000..ac0f9bc --- /dev/null +++ b/src/testconnections.yml @@ -0,0 +1,43 @@ +nodes: + X1: + # type: D-Sub + # gender: female + num_pins: 15 + X2: + type: Molex KK 254 + gender: female + num_pins: 10 + +wires: + W1: + mm2: 0.25 + length: 0.2 + color_code: DIN + num_wires: 15 + shield: true + +connections: + - + - X1: 1 + - W1: 1 + - X2: 1 + - + - X1: [2,3,4] + - W1: [2,3,4] + - X2: [4,3,2] + - + - X1: [5-10] + - W1: [5-7,10,9,8] + - X2: [10-5] + - + - X1: 11 + - W1: s + - + - X1: [1-5] + - W1: [11-15] + - + - W1: [12-15] + - X2: [2-5] + - + - X1: [12,14] + - X1: [13,15] diff --git a/src/wireviz.py b/src/wireviz.py index d39282b..d228297 100644 --- a/src/wireviz.py +++ b/src/wireviz.py @@ -248,15 +248,9 @@ class Cable: self.colors = cc[:n] def connect(self, from_name, from_pin, via, to_name, to_pin): - if from_pin == 'auto': - from_pin = tuple(x+1 for x in range(len(self.colors))) - if via == 'auto': - via = tuple(x+1 for x in range(len(self.colors))) - if to_pin == 'auto': - to_pin = tuple(x+1 for x in range(len(self.colors))) from_pin = int2tuple(from_pin) - via = int2tuple(via) - to_pin = int2tuple(to_pin) + via = int2tuple(via) + to_pin = int2tuple(to_pin) if len(from_pin) != len(to_pin): raise Exception('from_pin must have the same number of elements as to_pin') for i, x in enumerate(from_pin): diff --git a/src/yaml2wireviz.py b/src/yaml2wireviz.py index 292cab8..6ceeda4 100644 --- a/src/yaml2wireviz.py +++ b/src/yaml2wireviz.py @@ -3,41 +3,116 @@ import wireviz filename = 'example1.yml' +def check_designators(what, where): + for i,x in enumerate(what): + # print('Looking for {} in {}'.format(x,where[i])) + if x not in input[where[i]]: + return False + return True + +def expand(input): + # input can be: + # - a singleton (normally str or int) + # - a list of str or int + # if str is of the format '#-#', it is treated as a range (inclusive) and expanded + output = [] + if not isinstance(input, list): + input = [input,] + for e in input: + e = str(e) + if '-' in e: # list of pins + a, b = tuple(map(int, e.split('-'))) + if a < b: + for x in range(a,b+1): + output.append(x) + elif a > b: + for x in range(a,b-1,-1): + output.append(x) + elif a == b: + output.append(a) + else: + try: + x = int(e) + except: + x = e + output.append(x) + return output + with open(filename, 'r') as stream: try: input = yaml.safe_load(stream) except yaml.YAMLError as exc: print(exc) -# print(input) - -sections = ('options','nodes','wires') - -for s in sections: - print(s + ':') - for k in input[s]: - print(k + ': ', end='') - print(input[s][k]) - print() - -print('connections:') -for s in input['connections']: - print(s) -print() - h = wireviz.Harness() -for k in input['nodes']: - n = input['nodes'][k] - h.add_node(k, type=n['type'], gender=n['gender'], pinout=n['pinout']) +# add nodes +for k, o in input['nodes'].items(): + h.add_node(k, type=o.get('type'), gender=o.get('gender'), num_pins=o.get('num_pins'), pinout=o.get('pinout')) +# add wires +for k, o in input['wires'].items(): + h.add_cable(k, mm2=o.get('mm2'), length=o.get('length'), num_wires=o.get('num_wires'), color_code=o.get('color_code'), shield=o.get('shield')) +# add connections +conlist = input['connections'] +for con in conlist: + if len(con) == 3: # format: connector -- wire -- conector -for k in input['wires']: - c = input['wires'][k] - h.add_cable(k, mm2=c['mm2'], length=c['length'], num_wires=c['num_wires'], color_code=c['color_code'], shield=c['shield']) + for c in con: + if len(list(c.keys())) != 1: # check that each entry in con has only one key, which is the designator + raise Exception('Too many keys') -for o in input['connections']: - c1 = o['items'][0] - w = o['items'][1] - c2 = o['items'][2] - h.connect(w,c1,o[c1],o[w],c2,o[c2]) + from_name = list(con[0].keys())[0] + via_name = list(con[1].keys())[0] + to_name = list(con[2].keys())[0] + + if not check_designators([from_name,via_name,to_name],('nodes','wires','nodes')): + raise Exception('Bad connection definition (3)') + + from_pins = expand(con[0][from_name]) + via_pins = expand(con[1][via_name]) + to_pins = expand(con[2][to_name]) + + if len(from_pins) != len(via_pins) or len(via_pins) != len(to_pins): + raise Exception('List length mismatch') + + for (from_pin, via_pin, to_pin) in zip(from_pins, via_pins, to_pins): + h.connect(via_name, from_name, from_pin, via_pin, to_name, to_pin) + + elif len(con) == 2: + + for c in con: + if len(list(c.keys())) != 1: # check that each entry in con has only one key, which is the designator + raise Exception('Too many keys') + + from_name = list(con[0].keys())[0] + to_name = list(con[1].keys())[0] + + n_w = check_designators([from_name, to_name],('nodes','wires')) + w_n = check_designators([from_name, to_name],('wires','nodes')) + n_n = check_designators([from_name, to_name],('nodes','nodes')) + + if not n_w and not w_n and not n_n: + raise Exception('Wrong designators') + + from_pins = expand(con[0][from_name]) + to_pins = expand(con[1][to_name]) + + if len(from_pins) != len(to_pins): + raise Exception('List length mismatch') + + if n_w == True or w_n == True: + for (from_pin, to_pin) in zip(from_pins, to_pins): + if n_w: + h.connect(to_name, from_name, from_pin, to_pin, None, None) + else: # w_n + h.connect(from_name, None, None, from_pin, to_name, to_pin) + elif n_n == True: + con_name = list(con[0].keys())[0] + from_pins = expand(con[0][from_name]) + to_pins = expand(con[1][to_name]) + + for (from_pin, to_pin) in zip(from_pins, to_pins): + h.loop(con_name, from_pin, to_pin) + else: + raise Exception('Wrong number of connection parameters') h.output(filename='output', format=('png',), view=False)