Add relay element
I couldn’t find a relay element so I created one:
import SchemDraw
import SchemDraw.elements as elm
import copy
def relay(switch=elm.SWITCH_SPST, inductor=elm.INDUCTOR, core=True, box=True, unit=3.0):
''' Generate a relay element
Parameters
----------
switch : dict
Element to use for switch
inductor : dict
Element to use for inductor
core : bool
Draw line separating inductor and switch
box : bool
Draw box
unit : float
Total length of element including leads
Returns
-------
elm : dict
The relay element definition dictionary
'''
switch = copy.deepcopy(switch)
inductor = copy.deepcopy(inductor)
if 'base' in switch:
switch.setdefault('paths', []).extend(switch['base']['paths'])
switch.setdefault('shapes', []).extend(switch['base']['shapes'])
element = {'name': 'RELAY',
'extend': False,
'paths': [],
'shapes': []}
lead_len = max(0, (unit - 1) / 2)
left = lead_len
right = lead_len + 1
sw_scale = 0.75
sw_left = left + (1 - sw_scale) / 2
# Adjust for core
ind_gap = .5
if core:
ind_gap += .2
# Add inductor
element['paths'].extend(inductor['paths'])
if 'shapes' in inductor:
element['shapes'].extend(inductor['shapes'])
for path in inductor['paths']:
element['paths'].append([])
for node in path:
element['paths'][-1].append([node[0] + left, node[1]])
for shape in inductor.get('shapes', []):
c = shape['center']
shape['center'] = [c[0] + left, c[1]]
element['shapes'].append(shape)
anchors = {'in1': [0, 0],
'in2': [unit, 0]}
element['paths'].extend([[[left, 0], anchors['in1']],
[[right, 0], anchors['in2']]])
# Add the core
if core:
center = ind_gap/2
element['paths'].append([[left, center], [right, center]])
# Add switch
ind_gap -= min(s['center'][1]*sw_scale for s in switch['shapes'])
for path in switch.get('paths', []):
element['paths'].append([])
for node in path:
element['paths'][-1].append([node[0]*sw_scale + sw_left, node[1]*sw_scale + ind_gap])
for shape in switch['shapes']:
c = shape['center']
shape['center'] = [c[0]*sw_scale + sw_left, c[1]*sw_scale + ind_gap]
shape['radius'] *= sw_scale
element['shapes'].append(shape)
if 'anchors' in switch:
for key, pos in switch['anchors'].items():
x = 0 if pos[0] < 0.5 else unit
pos = [pos[0]*sw_scale + sw_left, pos[1]*sw_scale + ind_gap]
anchors[key] = [x, pos[1]]
element['paths'].append([pos, anchors[key]])
else:
a = element['paths'][-1][0]
b = element['paths'][-1][-1]
anchors['a'] = [0, a[1]]
anchors['b'] = [unit, b[1]]
element['paths'].extend([[a, anchors['a']],
[b, anchors['b']]])
if box:
margin = 0.255
top = max(a[1] for a in anchors.values())
element['shapes'].append({'shape': 'poly',
'xy': [[left - margin, -margin],
[right + margin, -margin],
[right + margin, top + margin],
[left - margin, top + margin]],
'closed': True,
'fill': False})
element['anchors'] = anchors
return element
d = SchemDraw.Drawing()
r=d.add(relay(core=True, box=True, unit=2, switch=elm.SWITCH_SPDT2), anchor='in1', d='down')
d.draw()
It supports all the standard switch types. Feel free to modify it or add it to the code base.
A bit of feedback about the API: Why are all the standard elements defined as dicts instead of being subclasses of Element
or something? It would be easier to create elements like this if there were some instance methods like bbox()
and transform(x, y, theta, scale)
etc that you could call on individual elements. Also, there should be a way to define the ‘natural’ direction of the anchors so the automatic lead extending could work for elements with more than two anchors (and if the elements were classes you could pass extend=False
when instantiating it to disable this feature when needed).
Comments (2)
-
repo owner -
repo owner - changed status to resolved
Added Relay in 0.7.
- Log in to comment
Thanks for the code, I’ll try to get it worked in. Regarding API, I was headed in that direction during my last refactor, but didn’t get a chance to finish. I hope to revisit the idea soon.