-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathkikusui.py
executable file
·156 lines (126 loc) · 4.25 KB
/
kikusui.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/env python3
import click
from yaml import safe_load
import pyvisa as visa
import os
APP_NAME = 'kikusui'
class AliasedGroup(click.Group):
def get_command(self, ctx, cmd_name):
rv = click.Group.get_command(self, ctx, cmd_name)
if rv is not None:
return rv
matches = [x for x in self.list_commands(ctx)
if x.startswith(cmd_name)]
if not matches:
return None
elif len(matches) == 1:
return click.Group.get_command(self, ctx, matches[0])
ctx.fail('Too many matches: %s' % ', '.join(sorted(matches)))
def get_ipaddr_from_config():
cfg_dirs = [os.getcwd(), click.get_app_dir(APP_NAME)]
for cfg_dir in cfg_dirs:
cfg_file = os.path.join(cfg_dir, 'kikusui.yml')
try:
with click.open_file(cfg_file, 'r') as stream:
try:
cfg = safe_load(stream)
ipaddr = cfg['ip']
return ipaddr
except yaml.YAMLError:
click.echo("Oops", err=True)
except FileNotFoundError:
continue
dirs = ' or '.join(cfg_dirs)
raise Exception(f'"kikusui.yml" not found in either {dirs}')
@click.command(cls=AliasedGroup, context_settings=dict(help_option_names=["-h", "--help"]))
@click.option('--ipaddr', help='IP address to connect to.')
@click.pass_context
def cli(ctx, ipaddr):
if not ipaddr:
ipaddr = get_ipaddr_from_config()
rm = visa.ResourceManager('@py')
inst = rm.open_resource(f'TCPIP0::{ipaddr}::5025::SOCKET')
inst.read_termination = '\n'
inst.write_termination = '\n'
ctx.obj['inst'] = inst
pass
@click.command()
@click.pass_context
def id(ctx):
click.echo('%s' % ctx.obj['inst'].query('*IDN?'))
@click.command()
@click.pass_context
def measure(ctx):
"""Print current status and measured values. Voltages and Current
are printed with three values: Measured / Set / Protection
"""
outp = ctx.obj['inst'].query('OUTP?')
mvolt = float(ctx.obj['inst'].query('MEAS:VOLT?'))
mcurr = float(ctx.obj['inst'].query('MEAS:CURR?'))
volt = float(ctx.obj['inst'].query('VOLT?'))
curr = float(ctx.obj['inst'].query('CURR?'))
ovp = float(ctx.obj['inst'].query('VOLT:PROT?'))
ocp = float(ctx.obj['inst'].query('CURR:PROT?'))
click.echo('out %s' % ('yes' if outp == '1' else 'no'))
click.echo(f'voltage {mvolt} V / {volt} V / {ovp} V')
click.echo(f'current {mcurr} A / {curr} A / {ocp} A')
@click.command()
@click.pass_context
@click.option('-s', '--set', type=float)
def voltage(ctx, set):
if set:
ctx.obj['inst'].write(f'VOLT {set}')
else:
click.echo('%s' % float(ctx.obj['inst'].query('VOLT?')))
@click.command()
@click.pass_context
@click.option('-t', '--type', 'curr_type', default='setting',
type=click.Choice(['setting', 'measure', 'ocp']))
@click.option('-lt', '--less-than')
def current(ctx, curr_type, less_than):
if curr_type == 'measure':
value = float(ctx.obj['inst'].query('MEAS:CURR?'))
elif curr_type == 'ocp':
value = float(ctx.obj['inst'].query('CURR:PROT?'))
else:
value = float(ctx.obj['inst'].query('CURR?'))
if less_than:
if value < float(less_than):
ctx.exit(0)
else:
ctx.exit(1)
else:
click.echo(value)
@click.command()
@click.pass_context
@click.option('-s', '--set', type=click.IntRange(0, 1))
def output(ctx, set):
if set == None:
click.echo('%s' % ctx.obj['inst'].query('OUTP?'))
else:
ctx.obj['inst'].write(f'OUTP {set}')
@click.command()
@click.pass_context
@click.option('-s', '--set', type=float)
def ovp(ctx, set):
if set:
ctx.obj['inst'].write(f'VOLT:PROT {set}')
else:
click.echo('%s' % float(ctx.obj['inst'].query('VOLT:PROT?')))
@click.command()
@click.pass_context
@click.option('-s', '--set', type=float)
def ocp(ctx, set):
if set:
ctx.obj['inst'].write(f'CURR:PROT {set}')
else:
click.echo('%s' % float(ctx.obj['inst'].query('CURR:PROT?')))
cli.add_command(id)
cli.add_command(measure)
cli.add_command(voltage)
cli.add_command(current)
cli.add_command(output)
cli.add_command(ovp)
cli.add_command(ocp)
if __name__ == '__main__':
cli(obj={})