Implement YAML to WireViz converter

This commit is contained in:
Daniel Rojas 2020-05-26 22:07:39 +02:00
parent e0286b2f51
commit 517cba4863
5 changed files with 160 additions and 66 deletions

View File

@ -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:

View File

@ -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

43
src/testconnections.yml Normal file
View File

@ -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]

View File

@ -248,12 +248,6 @@ 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)

View File

@ -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)