Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
E
experiment-control
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
whuie2
experiment-control
Commits
891e59ad
Commit
891e59ad
authored
3 years ago
by
whooie
Browse files
Options
Downloads
Patches
Plain Diff
move all the stuff for rtcontrol into a submodule
parent
5341c27e
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
lib/rtcontrol/driver.py
+211
-0
211 additions, 0 deletions
lib/rtcontrol/driver.py
lib/rtcontrol/parser.py
+77
-0
77 additions, 0 deletions
lib/rtcontrol/parser.py
rtcontrol.py
+2
-281
2 additions, 281 deletions
rtcontrol.py
with
290 additions
and
281 deletions
lib/rtcontrol/driver.py
0 → 100644
+
211
−
0
View file @
891e59ad
from
__future__
import
annotations
from
lib.system
import
MAIN
from
lib.ew
import
EventType
import
lib.rtcontrol.parser
as
parser
import
cmd
import
readline
import
getopt
import
sys
def
set_digital_state
(
state_args
:
list
[
tuple
[
int
,
int
,
int
]]):
for
connector
,
mask
,
state
in
state_args
:
MAIN
.
default
(
EventType
.
Digital
,
c
=
connector
,
m
=
mask
,
s
=
state
)
def
set_analog_state
(
state_args
:
list
[
tuple
[
int
,
float
]]):
for
channel
,
state
in
state_args
:
MAIN
.
default
(
EventType
.
Analog
,
ch
=
channel
,
s
=
state
)
def
set_zero
(
zero_type
:
tuple
[
bool
,
bool
]):
if
zero_type
[
0
]:
MAIN
.
zero
(
EventType
.
Digital
)
if
zero_type
[
1
]:
MAIN
.
zero
(
EventType
.
Analog
)
helptext
=
"""
Simple script to set the output state managed by the EntangleWare backend.
Usage:
rtcontrol [ options ]
rtcontrol [ command ]
Options:
-i, --interactive
Run the script in interactive mode. See the `help` command in this mode
for more information.
-h, --help
Print this text and exit.
Commands:
help [ command [ ... ] ]
Print usage information for the supplied command(s) or this text if none
are supplied, and exit.
digital <args>
Set the digital output state of the computer. See `help digital` for
more information.
analog <args>
Set the analog output state of the computer. See `help analog` for more
information.
zero <args>
Set all outputs of the given type(s) to be zero. See `help zero` for
more information.
"""
[
1
:
-
1
]
def
print_help
(
arg
:
str
):
cmds
=
arg
.
split
(
"
"
)
if
cmds
[
0
]
==
""
:
print
(
helptext
)
else
:
for
cmd
in
cmds
:
if
cmd
==
"
digital
"
:
print
(
"
Command `digital`
"
)
print
(
"
=================
"
)
print
(
RTControl
.
do_digital
.
__doc__
[
1
:
-
1
])
elif
cmd
==
"
analog
"
:
print
(
"
Command `analog`
"
)
print
(
"
================
"
)
print
(
RTControl
.
do_analog
.
__doc__
[
1
:
-
1
])
elif
cmd
==
"
zero
"
:
print
(
"
Command `zero`
"
)
print
(
"
==============
"
)
print
(
RTControl
.
do_zero
.
__doc__
[
1
:
-
1
])
class
RTControl
(
cmd
.
Cmd
):
intro
=
"""
Welcome to the real-time EntangleWare control interface.
Type
'
help
'
or
'
?
'
list available commands.
"""
[
1
:
-
1
]
prompt
=
"
<EW>
"
def
do_digital
(
self
,
arg
):
"""
Set the digital output state.
Usage:
digital <connector> <channel> <state>
Args:
connector : <int>[/<int>...]
Number(s) of the connector(s) whose state is to be set. To specify
multiple connectors, separate numbers by a slash (
'
/
'
). Connector
numbers must be 0-3.
channel : <int>[,<int>][/<int>,...]
Number(s) of the channel(s) whose state is to be set. To specify
multiple channels, separate channel numbers on the same connector by a
comma (
'
,
'
) and those on other connectors by a slash (
'
/
'
). The number
of slashes must equal that in the previous argument. Channel numbers
must be 0-31.
state : <0|1>[,<0|1>][/<0|1>,...]
HIGH/LOW state of the channel(s) to be set. To specify the states of
multiple channels, follow the same rules as those for <channel>. A state
must be specified for every channel number in the previous arg. States
must be 0 (LOW) or 1 (HIGH).
"""
try
:
state_args
=
parser
.
parse_digital_state
(
arg
)
except
Exception
as
err
:
print
(
err
)
set_digital_state
(
state_args
)
def
do_analog
(
self
,
arg
):
"""
Set the analog output state.
Usage:
analog <channel> <state>
Args:
channel : <int>[,<int>...]
Number(s) of the channel(s) whose state is to be set. To specify
multiple channels, separate channel numbers by a comma (
'
,
'
). Channel
numbers must be 0-31.
state : <float>[,<float>...]
Output states of the channel(s) to be set. To specify the states of
multiple channels, separate numbers by a comma (
'
,
'
). States must be in
the range [-10.0, +10.0].
"""
try
:
state_args
=
parser
.
parse_analog_state
(
arg
)
except
Exception
as
err
:
print
(
err
)
set_analog_state
(
state_args
)
def
do_zero
(
self
,
arg
):
"""
Set all channels of the given type to be zero.
Usage:
zero <type>
Args:
type : <str>
Type of the channels whose states are to be set to zero. Must be one of
{
'
digital
'
,
'
analog
'
,
'
all
'
}.
"""
try
:
zero_type
=
parser
.
parse_zero
(
arg
)
except
Exception
as
err
:
print
(
err
)
set_zero
(
zero_type
)
def
do_quit
(
self
,
arg
):
"""
Disconnect and quit.
"""
if
MAIN
.
_connected
:
MAIN
.
disconnect
()
return
True
def
main
(
script_args
):
shortopts
=
"
hi
"
longopts
=
[
"
help
"
,
"
interactive
"
,
]
try
:
opts
,
args
=
getopt
.
gnu_getopt
(
script_args
,
shortopts
,
longopts
)
for
opt
,
optarg
in
opts
:
if
opt
in
{
"
-h
"
,
"
--help
"
}:
print
(
helptext
)
sys
.
exit
(
0
)
elif
opt
in
{
"
-i
"
,
"
--interactive
"
}:
MAIN
.
connect
()
RTControl
().
cmdloop
()
sys
.
exit
(
0
)
assert
len
(
args
)
>=
1
,
"
Must provide a command
"
cmd_args
=
"
"
.
join
(
args
[
1
:])
if
args
[
0
]
==
"
help
"
:
print_help
(
cmd_args
)
elif
args
[
0
]
==
"
digital
"
:
MAIN
.
connect
()
set_digital_state
(
parser
.
parse_digital_state
(
cmd_args
))
MAIN
.
disconnect
()
elif
args
[
0
]
==
"
analog
"
:
MAIN
.
connect
()
set_analog_state
(
parser
.
parse_analog_state
(
cmd_args
))
MAIN
.
disconnect
()
elif
args
[
0
]
==
"
zero
"
:
MAIN
.
connect
()
set_zero
(
parser
.
parse_zero
(
cmd_args
))
MAIN
.
disconnect
()
elif
args
[
0
]
==
"
alldefaults
"
:
system
.
set_defaults
()
else
:
print
(
helptext
)
sys
.
exit
(
1
)
sys
.
exit
(
0
)
except
Exception
as
ERR
:
print
(
ERR
)
if
MAIN
.
_connected
:
MAIN
.
disconnect
()
sys
.
exit
(
1
)
This diff is collapsed.
Click to expand it.
lib/rtcontrol/parser.py
0 → 100644
+
77
−
0
View file @
891e59ad
from
__future__
import
annotations
from
lib.system
import
MAIN
from
lib.ew
import
EventType
CONNECTOR_D_RANGE
=
range
(
MAIN
.
num_connectors_d
)
CHANNEL_D_RANGE
=
range
(
MAIN
.
num_channels_d
)
STATE_D_RANGE
=
range
(
2
)
CHANNEL_A_RANGE
=
range
(
MAIN
.
num_channels_a
)
STATE_A_RANGE
=
(
MAIN
.
Vmin
,
MAIN
.
Vmax
)
def
parse_digital_state
(
arg
:
str
):
items
=
arg
.
split
(
'
'
)
while
''
in
items
:
items
.
remove
(
''
)
assert
len
(
items
)
==
3
,
\
"
Command accepts exactly three arguments
"
connectors
=
[
int
(
c
)
for
c
in
items
[
0
].
split
(
'
/
'
)]
assert
all
(
c
in
CONNECTOR_D_RANGE
for
c
in
connectors
),
\
"
Invalid connector number
"
channels
=
[[
int
(
ch
)
for
ch
in
CH
.
split
(
'
,
'
)]
for
CH
in
items
[
1
].
split
(
'
/
'
)]
assert
len
(
channels
)
==
len
(
connectors
),
\
"
Channel specification does not match connector specification
"
assert
all
(
all
(
ch
in
CHANNEL_D_RANGE
for
ch
in
CH
)
for
CH
in
channels
),
\
"
Invalid channel specified
"
states
=
[[
int
(
s
)
for
s
in
S
.
split
(
'
,
'
)]
for
S
in
items
[
2
].
split
(
'
/
'
)]
assert
all
(
len
(
S
)
==
len
(
CH
)
for
S
,
CH
in
zip
(
states
,
channels
)),
\
"
Channel state specification does not match channel specification
"
assert
all
(
all
(
s
in
STATE_D_RANGE
for
s
in
S
)
for
S
in
states
),
\
"
Invalid channel state specified
"
state_args
=
[
(
C
,
sum
(
2
**
ch
for
ch
in
CH
),
sum
(
s
*
2
**
ch
for
s
,
ch
in
zip
(
S
,
CH
))
)
for
C
,
CH
,
S
in
zip
(
connectors
,
channels
,
states
)
]
return
state_args
def
parse_analog_state
(
arg
:
str
):
items
=
arg
.
split
(
'
'
)
while
''
in
items
:
items
.
remove
(
''
)
assert
len
(
items
)
==
2
,
\
"
Command accepts exactly two arguments
"
channels
=
[
int
(
ch
)
for
ch
in
items
[
0
].
split
(
'
,
'
)]
assert
all
(
ch
in
CHANNEL_A_RANGE
for
ch
in
channels
),
\
"
Invalid channel specified
"
states
=
[
float
(
s
)
for
s
in
items
[
1
].
split
(
'
,
'
)]
assert
len
(
states
)
==
len
(
channels
),
\
"
Channel state specification does not match channel specification
"
assert
all
(
s
>=
STATE_A_RANGE
[
0
]
and
s
<=
STATE_A_RANGE
[
1
]
for
s
in
states
),
\
"
Invalid channel state specified
"
state_args
=
list
(
zip
(
channels
,
states
))
return
state_args
def
parse_zero
(
arg
:
str
):
items
=
arg
.
split
(
'
'
)
while
''
in
items
:
items
.
remove
(
''
)
assert
len
(
items
)
==
1
,
\
"
Command accepts exactly one argument
"
if
items
[
0
].
lower
()
==
"
digital
"
:
return
(
True
,
False
)
elif
items
[
0
].
lower
()
==
"
analog
"
:
return
(
False
,
True
)
elif
items
[
0
].
lower
()
==
"
all
"
:
return
(
True
,
True
)
This diff is collapsed.
Click to expand it.
rtcontrol.py
+
2
−
281
View file @
891e59ad
from
__future__
import
annotations
import
lib.rtcontrol.driver
,
sys
from
lib
import
EventType
,
MAIN
lib
.
rtcontrol
.
driver
.
main
(
sys
.
argv
[
1
:])
import
cmd
import
readline
import
getopt
import
sys
CONNECTOR_D_RANGE
=
range
(
MAIN
.
num_connectors_d
)
CHANNEL_D_RANGE
=
range
(
MAIN
.
num_channels_d
)
STATE_D_RANGE
=
range
(
2
)
CHANNEL_A_RANGE
=
range
(
MAIN
.
num_channels_a
)
STATE_A_RANGE
=
(
MAIN
.
Vmin
,
MAIN
.
Vmax
)
def
parse_digital_state
(
arg
:
str
):
items
=
arg
.
split
(
'
'
)
while
''
in
items
:
items
.
remove
(
''
)
assert
len
(
items
)
==
3
,
\
"
Command accepts exactly three arguments
"
connectors
=
[
int
(
c
)
for
c
in
items
[
0
].
split
(
'
/
'
)]
assert
all
(
c
in
CONNECTOR_D_RANGE
for
c
in
connectors
),
\
"
Invalid connector number
"
channels
=
[[
int
(
ch
)
for
ch
in
CH
.
split
(
'
,
'
)]
for
CH
in
items
[
1
].
split
(
'
/
'
)]
assert
len
(
channels
)
==
len
(
connectors
),
\
"
Channel specification does not match connector specification
"
assert
all
(
all
(
ch
in
CHANNEL_D_RANGE
for
ch
in
CH
)
for
CH
in
channels
),
\
"
Invalid channel specified
"
states
=
[[
int
(
s
)
for
s
in
S
.
split
(
'
,
'
)]
for
S
in
items
[
2
].
split
(
'
/
'
)]
assert
all
(
len
(
S
)
==
len
(
CH
)
for
S
,
CH
in
zip
(
states
,
channels
)),
\
"
Channel state specification does not match channel specification
"
assert
all
(
all
(
s
in
STATE_D_RANGE
for
s
in
S
)
for
S
in
states
),
\
"
Invalid channel state specified
"
state_args
=
[
(
C
,
sum
(
2
**
ch
for
ch
in
CH
),
sum
(
s
*
2
**
ch
for
s
,
ch
in
zip
(
S
,
CH
))
)
for
C
,
CH
,
S
in
zip
(
connectors
,
channels
,
states
)
]
return
state_args
def
set_digital_state
(
state_args
:
list
[
tuple
[
int
,
int
,
int
]]):
for
connector
,
mask
,
state
in
state_args
:
MAIN
.
default
(
EventType
.
Digital
,
c
=
connector
,
m
=
mask
,
s
=
state
)
def
parse_analog_state
(
arg
:
str
):
items
=
arg
.
split
(
'
'
)
while
''
in
items
:
items
.
remove
(
''
)
assert
len
(
items
)
==
2
,
\
"
Command accepts exactly two arguments
"
channels
=
[
int
(
ch
)
for
ch
in
items
[
0
].
split
(
'
,
'
)]
assert
all
(
ch
in
CHANNEL_A_RANGE
for
ch
in
channels
),
\
"
Invalid channel specified
"
states
=
[
float
(
s
)
for
s
in
items
[
1
].
split
(
'
,
'
)]
assert
len
(
states
)
==
len
(
channels
),
\
"
Channel state specification does not match channel specification
"
assert
all
(
s
>=
STATE_A_RANGE
[
0
]
and
s
<=
STATE_A_RANGE
[
1
]
for
s
in
states
),
\
"
Invalid channel state specified
"
state_args
=
list
(
zip
(
channels
,
states
))
return
state_args
def
set_analog_state
(
state_args
:
list
[
tuple
[
int
,
float
]]):
for
channel
,
state
in
state_args
:
MAIN
.
default
(
EventType
.
Analog
,
ch
=
channel
,
s
=
state
)
def
parse_zero
(
arg
:
str
):
items
=
arg
.
split
(
'
'
)
while
''
in
items
:
items
.
remove
(
''
)
assert
len
(
items
)
==
1
,
\
"
Command accepts exactly one argument
"
if
items
[
0
].
lower
()
==
"
digital
"
:
return
(
True
,
False
)
elif
items
[
0
].
lower
()
==
"
analog
"
:
return
(
False
,
True
)
elif
items
[
0
].
lower
()
==
"
all
"
:
return
(
True
,
True
)
def
set_zero
(
zero_type
:
tuple
[
bool
,
bool
]):
if
zero_type
[
0
]:
MAIN
.
zero
(
EventType
.
Digital
)
if
zero_type
[
1
]:
MAIN
.
zero
(
EventType
.
Analog
)
helptext
=
"""
Simple script to set the output state managed by the EntangleWare backend.
Usage:
rtcontrol [ options ]
rtcontrol [ command ]
Options:
-i, --interactive
Run the script in interactive mode. See the `help` command in this mode
for more information.
-h, --help
Print this text and exit.
Commands:
help [ command [ ... ] ]
Print usage information for the supplied command(s) or this text if none
are supplied, and exit.
digital <args>
Set the digital output state of the computer. See `help digital` for
more information.
analog <args>
Set the analog output state of the computer. See `help analog` for more
information.
zero <args>
Set all outputs of the given type(s) to be zero. See `help zero` for
more information.
"""
[
1
:
-
1
]
def
print_help
(
arg
:
str
):
cmds
=
arg
.
split
(
"
"
)
if
cmds
[
0
]
==
""
:
print
(
helptext
)
else
:
for
cmd
in
cmds
:
if
cmd
==
"
digital
"
:
print
(
"
Command `digital`
"
)
print
(
"
=================
"
)
print
(
RTControl
.
do_digital
.
__doc__
[
1
:
-
1
])
elif
cmd
==
"
analog
"
:
print
(
"
Command `analog`
"
)
print
(
"
================
"
)
print
(
RTControl
.
do_analog
.
__doc__
[
1
:
-
1
])
elif
cmd
==
"
zero
"
:
print
(
"
Command `zero`
"
)
print
(
"
==============
"
)
print
(
RTControl
.
do_zero
.
__doc__
[
1
:
-
1
])
class
RTControl
(
cmd
.
Cmd
):
intro
=
"""
Welcome to the real-time EntangleWare control interface.
Type
'
help
'
or
'
?
'
list available commands.
"""
[
1
:
-
1
]
prompt
=
"
<EW>
"
def
do_digital
(
self
,
arg
):
"""
Set the digital output state.
Usage:
digital <connector> <channel> <state>
Args:
connector : <int>[/<int>...]
Number(s) of the connector(s) whose state is to be set. To specify
multiple connectors, separate numbers by a slash (
'
/
'
). Connector
numbers must be 0-3.
channel : <int>[,<int>][/<int>,...]
Number(s) of the channel(s) whose state is to be set. To specify
multiple channels, separate channel numbers on the same connector by a
comma (
'
,
'
) and those on other connectors by a slash (
'
/
'
). The number
of slashes must equal that in the previous argument. Channel numbers
must be 0-31.
state : <0|1>[,<0|1>][/<0|1>,...]
HIGH/LOW state of the channel(s) to be set. To specify the states of
multiple channels, follow the same rules as those for <channel>. A state
must be specified for every channel number in the previous arg. States
must be 0 (LOW) or 1 (HIGH).
"""
try
:
state_args
=
parse_digital_state
(
arg
)
except
Exception
as
err
:
print
(
err
)
set_digital_state
(
state_args
)
def
do_analog
(
self
,
arg
):
"""
Set the analog output state.
Usage:
analog <channel> <state>
Args:
channel : <int>[,<int>...]
Number(s) of the channel(s) whose state is to be set. To specify
multiple channels, separate channel numbers by a comma (
'
,
'
). Channel
numbers must be 0-31.
state : <float>[,<float>...]
Output states of the channel(s) to be set. To specify the states of
multiple channels, separate numbers by a comma (
'
,
'
). States must be in
the range [-10.0, +10.0].
"""
try
:
state_args
=
parse_analog_state
(
arg
)
except
Exception
as
err
:
print
(
err
)
set_analog_state
(
state_args
)
def
do_zero
(
self
,
arg
):
"""
Set all channels of the given type to be zero.
Usage:
zero <type>
Args:
type : <str>
Type of the channels whose states are to be set to zero. Must be one of
{
'
digital
'
,
'
analog
'
,
'
all
'
}.
"""
try
:
zero_type
=
parse_zero
(
arg
)
except
Exception
as
err
:
print
(
err
)
set_zero
(
zero_type
)
def
do_quit
(
self
,
arg
):
"""
Disconnect and quit.
"""
if
MAIN
.
_connected
:
MAIN
.
disconnect
()
return
True
if
__name__
==
"
__main__
"
:
shortopts
=
"
hi
"
longopts
=
[
"
help
"
,
"
interactive
"
,
]
try
:
opts
,
args
=
getopt
.
gnu_getopt
(
sys
.
argv
[
1
:],
shortopts
,
longopts
)
for
opt
,
optarg
in
opts
:
if
opt
in
{
"
-h
"
,
"
--help
"
}:
print
(
helptext
)
sys
.
exit
(
0
)
elif
opt
in
{
"
-i
"
,
"
--interactive
"
}:
MAIN
.
connect
()
RTControl
().
cmdloop
()
sys
.
exit
(
0
)
assert
len
(
args
)
>=
1
,
"
Must provide a command
"
cmd_args
=
"
"
.
join
(
args
[
1
:])
if
args
[
0
]
==
"
help
"
:
print_help
(
cmd_args
)
elif
args
[
0
]
==
"
digital
"
:
MAIN
.
connect
()
set_digital_state
(
parse_digital_state
(
cmd_args
))
MAIN
.
disconnect
()
elif
args
[
0
]
==
"
analog
"
:
MAIN
.
connect
()
set_analog_state
(
parse_analog_state
(
cmd_args
))
MAIN
.
disconnect
()
elif
args
[
0
]
==
"
zero
"
:
MAIN
.
connect
()
set_zero
(
parse_zero
(
cmd_args
))
MAIN
.
disconnect
()
elif
args
[
0
]
==
"
alldefaults
"
:
system
.
set_defaults
()
else
:
print
(
helptext
)
sys
.
exit
(
1
)
sys
.
exit
(
0
)
except
Exception
as
ERR
:
print
(
ERR
)
if
MAIN
.
_connected
:
MAIN
.
disconnect
()
sys
.
exit
(
1
)
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment