Merge yaml2wireviz into wireviz module
This commit is contained in:
parent
50e3441eaa
commit
d99952c4d3
10
src/batch.py
10
src/batch.py
@ -1,7 +1,7 @@
|
|||||||
import yaml2wireviz
|
import wireviz
|
||||||
|
|
||||||
# TODO: make examples (progressively more complex), batch process all of them
|
# TODO: make examples (progressively more complex), batch process all of them
|
||||||
yaml2wireviz.parse('../examples/example1.yml')
|
wireviz.parse('../examples/example1.yml')
|
||||||
yaml2wireviz.parse('../examples/example2.yml')
|
wireviz.parse('../examples/example2.yml')
|
||||||
yaml2wireviz.parse('../examples/ferrules.yml')
|
wireviz.parse('../examples/ferrules.yml')
|
||||||
yaml2wireviz.parse('../examples/bundles.yml')
|
wireviz.parse('../examples/bundles.yml')
|
||||||
|
|||||||
194
src/wireviz.py
Normal file → Executable file
194
src/wireviz.py
Normal file → Executable file
@ -1,5 +1,8 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import os
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from typing import Any, List
|
from typing import Any, List
|
||||||
|
import yaml
|
||||||
from graphviz import Graph
|
from graphviz import Graph
|
||||||
|
|
||||||
COLOR_CODES = {'DIN': ['WH','BN','GN','YE','GY','PK','BU','RD','BK','VT'], # ,'GYPK','RDBU','WHGN','BNGN','WHYE','YEBN','WHGY','GYBN','WHPK','PKBN'],
|
COLOR_CODES = {'DIN': ['WH','BN','GN','YE','GY','PK','BU','RD','BK','VT'], # ,'GYPK','RDBU','WHGN','BNGN','WHYE','YEBN','WHGY','GYBN','WHPK','PKBN'],
|
||||||
@ -385,3 +388,194 @@ def awg_equiv(mm2):
|
|||||||
return awg_equiv_table[k]
|
return awg_equiv_table[k]
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def parse(file_in, file_out=None):
|
||||||
|
|
||||||
|
file_in = os.path.abspath(file_in)
|
||||||
|
if not file_out:
|
||||||
|
file_out = file_in
|
||||||
|
pre, ext = os.path.splitext(file_out)
|
||||||
|
file_out = pre # extension will be added by graphviz output function
|
||||||
|
file_out = os.path.abspath(file_out)
|
||||||
|
|
||||||
|
with open(file_in, 'r') as stream:
|
||||||
|
try:
|
||||||
|
input = yaml.safe_load(stream)
|
||||||
|
except yaml.YAMLError as exc:
|
||||||
|
print(exc)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
h = Harness()
|
||||||
|
|
||||||
|
# add items
|
||||||
|
sections = ['nodes','wires','ferrules','connections']
|
||||||
|
types = [dict, dict, dict, list]
|
||||||
|
for sec, ty in zip(sections, types):
|
||||||
|
if sec in input and type(input[sec]) == ty:
|
||||||
|
if len(input[sec]) > 0:
|
||||||
|
if ty == dict:
|
||||||
|
for k, o in input[sec].items():
|
||||||
|
if sec == 'nodes':
|
||||||
|
h.add_node(name=k, **o)
|
||||||
|
elif sec == 'wires':
|
||||||
|
h.add_cable(name=k, **o)
|
||||||
|
elif sec == 'ferrules':
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
print('{} section empty'.format(sec))
|
||||||
|
else:
|
||||||
|
print('No {} section found'.format(sec))
|
||||||
|
if ty == dict:
|
||||||
|
input[sec] = {}
|
||||||
|
elif ty == list:
|
||||||
|
input[sec] = []
|
||||||
|
|
||||||
|
# add connections
|
||||||
|
ferrule_counter = 0
|
||||||
|
for con in input['connections']:
|
||||||
|
if len(con) == 3: # format: connector -- wire -- conector
|
||||||
|
|
||||||
|
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]
|
||||||
|
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(from_name, from_pin, via_name, via_pin, to_name, to_pin)
|
||||||
|
|
||||||
|
elif len(con) == 2:
|
||||||
|
|
||||||
|
for c in con:
|
||||||
|
if type(c) is dict:
|
||||||
|
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')
|
||||||
|
|
||||||
|
# hack to make the format for ferrules compatible with the formats for connectors and wires
|
||||||
|
if type(con[0]) == str:
|
||||||
|
name = con[0]
|
||||||
|
con[0] = {}
|
||||||
|
con[0][name] = name
|
||||||
|
if type(con[1]) == str:
|
||||||
|
name = con[1]
|
||||||
|
con[1] = {}
|
||||||
|
con[1][name] = name
|
||||||
|
|
||||||
|
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'))
|
||||||
|
|
||||||
|
|
||||||
|
f_w = check_designators([from_name, to_name],('ferrules','wires'))
|
||||||
|
w_f = check_designators([from_name, to_name],('wires','ferrules'))
|
||||||
|
|
||||||
|
if not n_w and not w_n and not n_n and not f_w and not w_f:
|
||||||
|
raise Exception('Wrong designators')
|
||||||
|
|
||||||
|
from_pins = expand(con[0][from_name])
|
||||||
|
to_pins = expand(con[1][to_name])
|
||||||
|
|
||||||
|
if n_w or w_n or n_n:
|
||||||
|
if len(from_pins) != len(to_pins):
|
||||||
|
raise Exception('List length mismatch')
|
||||||
|
|
||||||
|
if n_w or w_n:
|
||||||
|
for (from_pin, to_pin) in zip(from_pins, to_pins):
|
||||||
|
if n_w:
|
||||||
|
h.connect(from_name, from_pin, to_name, to_pin, None, None)
|
||||||
|
else: # w_n
|
||||||
|
h.connect(None, None, from_name, from_pin, to_name, to_pin)
|
||||||
|
elif n_n:
|
||||||
|
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)
|
||||||
|
if f_w or w_f:
|
||||||
|
from_pins = expand(con[0][from_name])
|
||||||
|
to_pins = expand(con[1][to_name])
|
||||||
|
|
||||||
|
if f_w:
|
||||||
|
ferrule_name = from_name
|
||||||
|
wire_name = to_name
|
||||||
|
wire_pins = to_pins
|
||||||
|
else:
|
||||||
|
ferrule_name = to_name
|
||||||
|
wire_name = from_name
|
||||||
|
wire_pins = from_pins
|
||||||
|
|
||||||
|
ferrule_params = input['ferrules'][ferrule_name]
|
||||||
|
for wire_pin in wire_pins:
|
||||||
|
ferrule_counter = ferrule_counter + 1
|
||||||
|
ferrule_id = 'F{}'.format(ferrule_counter)
|
||||||
|
h.add_node(ferrule_id, **ferrule_params)
|
||||||
|
|
||||||
|
if f_w:
|
||||||
|
h.connect(ferrule_id, 1, wire_name, wire_pin, None, None)
|
||||||
|
else:
|
||||||
|
h.connect(None, None, wire_name, wire_pin, ferrule_id, 1)
|
||||||
|
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise Exception('Wrong number of connection parameters')
|
||||||
|
|
||||||
|
h.output(filename=file_out, format=('png','svg'), view=False)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import argparse
|
||||||
|
ap = argparse.ArgumentParser()
|
||||||
|
ap.add_argument('file_input', nargs='?', default='_test/test.yml')
|
||||||
|
ap.add_argument('file_output', nargs='?', default=None)
|
||||||
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
parse(args.file_input, args.file_output)
|
||||||
|
|||||||
@ -1,200 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
import os
|
|
||||||
import yaml
|
|
||||||
import wireviz
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
def _parse(file_in, file_out):
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
with open(file_in, 'r') as stream:
|
|
||||||
try:
|
|
||||||
input = yaml.safe_load(stream)
|
|
||||||
except yaml.YAMLError as exc:
|
|
||||||
print(exc)
|
|
||||||
|
|
||||||
h = wireviz.Harness()
|
|
||||||
|
|
||||||
# add items
|
|
||||||
sections = ['nodes','wires','ferrules','connections']
|
|
||||||
types = [dict, dict, dict, list]
|
|
||||||
for sec, ty in zip(sections, types):
|
|
||||||
if sec in input and type(input[sec]) == ty:
|
|
||||||
if len(input[sec]) > 0:
|
|
||||||
if ty == dict:
|
|
||||||
for k, o in input[sec].items():
|
|
||||||
if sec == 'nodes':
|
|
||||||
h.add_node(name=k, **o)
|
|
||||||
elif sec == 'wires':
|
|
||||||
h.add_cable(name=k, **o)
|
|
||||||
elif sec == 'ferrules':
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
print('{} section empty'.format(sec))
|
|
||||||
else:
|
|
||||||
print('No {} section found'.format(sec))
|
|
||||||
if ty == dict:
|
|
||||||
input[sec] = {}
|
|
||||||
elif ty == list:
|
|
||||||
input[sec] = []
|
|
||||||
|
|
||||||
# add connections
|
|
||||||
ferrule_counter = 0
|
|
||||||
for con in input['connections']:
|
|
||||||
if len(con) == 3: # format: connector -- wire -- conector
|
|
||||||
|
|
||||||
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]
|
|
||||||
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(from_name, from_pin, via_name, via_pin, to_name, to_pin)
|
|
||||||
|
|
||||||
elif len(con) == 2:
|
|
||||||
|
|
||||||
for c in con:
|
|
||||||
if type(c) is dict:
|
|
||||||
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')
|
|
||||||
|
|
||||||
# hack to make the format for ferrules compatible with the formats for connectors and wires
|
|
||||||
if type(con[0]) == str:
|
|
||||||
name = con[0]
|
|
||||||
con[0] = {}
|
|
||||||
con[0][name] = name
|
|
||||||
if type(con[1]) == str:
|
|
||||||
name = con[1]
|
|
||||||
con[1] = {}
|
|
||||||
con[1][name] = name
|
|
||||||
|
|
||||||
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'))
|
|
||||||
|
|
||||||
|
|
||||||
f_w = check_designators([from_name, to_name],('ferrules','wires'))
|
|
||||||
w_f = check_designators([from_name, to_name],('wires','ferrules'))
|
|
||||||
|
|
||||||
if not n_w and not w_n and not n_n and not f_w and not w_f:
|
|
||||||
raise Exception('Wrong designators')
|
|
||||||
|
|
||||||
from_pins = expand(con[0][from_name])
|
|
||||||
to_pins = expand(con[1][to_name])
|
|
||||||
|
|
||||||
if n_w or w_n or n_n:
|
|
||||||
if len(from_pins) != len(to_pins):
|
|
||||||
raise Exception('List length mismatch')
|
|
||||||
|
|
||||||
if n_w or w_n:
|
|
||||||
for (from_pin, to_pin) in zip(from_pins, to_pins):
|
|
||||||
if n_w:
|
|
||||||
h.connect(from_name, from_pin, to_name, to_pin, None, None)
|
|
||||||
else: # w_n
|
|
||||||
h.connect(None, None, from_name, from_pin, to_name, to_pin)
|
|
||||||
elif n_n:
|
|
||||||
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)
|
|
||||||
if f_w or w_f:
|
|
||||||
from_pins = expand(con[0][from_name])
|
|
||||||
to_pins = expand(con[1][to_name])
|
|
||||||
|
|
||||||
if f_w:
|
|
||||||
ferrule_name = from_name
|
|
||||||
wire_name = to_name
|
|
||||||
wire_pins = to_pins
|
|
||||||
else:
|
|
||||||
ferrule_name = to_name
|
|
||||||
wire_name = from_name
|
|
||||||
wire_pins = from_pins
|
|
||||||
|
|
||||||
ferrule_params = input['ferrules'][ferrule_name]
|
|
||||||
for wire_pin in wire_pins:
|
|
||||||
ferrule_counter = ferrule_counter + 1
|
|
||||||
ferrule_id = 'F{}'.format(ferrule_counter)
|
|
||||||
h.add_node(ferrule_id, **ferrule_params)
|
|
||||||
|
|
||||||
if f_w:
|
|
||||||
h.connect(ferrule_id, 1, wire_name, wire_pin, None, None)
|
|
||||||
else:
|
|
||||||
h.connect(None, None, wire_name, wire_pin, ferrule_id, 1)
|
|
||||||
|
|
||||||
|
|
||||||
else:
|
|
||||||
raise Exception('Wrong number of connection parameters')
|
|
||||||
|
|
||||||
h.output(filename=file_out, format=('png','svg'), view=False)
|
|
||||||
|
|
||||||
def parse(filename_in, filename_out=None):
|
|
||||||
fin = os.path.abspath(filename_in)
|
|
||||||
if filename_out:
|
|
||||||
fout = filename_out
|
|
||||||
else:
|
|
||||||
fout = fin
|
|
||||||
pre, ext = os.path.splitext(fout)
|
|
||||||
fout = pre # extension will be added by graphviz output function
|
|
||||||
fout = os.path.abspath(fout)
|
|
||||||
|
|
||||||
_parse(fin, fout)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
import argparse
|
|
||||||
ap = argparse.ArgumentParser()
|
|
||||||
ap.add_argument('file_input', nargs='?', default='_test/test.yml')
|
|
||||||
ap.add_argument('file_output', nargs='?', default=None)
|
|
||||||
args = ap.parse_args()
|
|
||||||
|
|
||||||
parse(args.file_input, args.file_output)
|
|
||||||
Loading…
x
Reference in New Issue
Block a user