controllers: consistent device/simulation specification

This commit is contained in:
Sebastien Bourdeauducq 2015-03-22 00:48:15 +01:00
parent 7e61f66493
commit 1b7f71bda9
8 changed files with 35 additions and 42 deletions

View File

@ -13,8 +13,7 @@ class HidError(Exception):
class Ldasim: class Ldasim:
"""Lab Brick Digital Attenuator simulation driver. """Lab Brick Digital Attenuator simulation driver."""
"""
def __init__(self): def __init__(self):
self._attenuation = None self._attenuation = None
@ -117,8 +116,7 @@ class Lda:
raise IOError raise IOError
def close(self): def close(self):
"""Close the device. """Close the device."""
"""
self.hidapi.hid_close(self._dev) self.hidapi.hid_close(self._dev)
def get_att_step_size(self): def get_att_step_size(self):

View File

@ -22,8 +22,8 @@ class Novatech409B:
# maximum frequency of Novatech 409B when using PLL and external reference # maximum frequency of Novatech 409B when using PLL and external reference
max_freq_with_pll = 171.1276031 max_freq_with_pll = 171.1276031
def __init__(self, serial_dev="/dev/ttyUSB0"): def __init__(self, serial_dev):
if serial_dev == "sim": if serial_dev is None:
self.simulation = True self.simulation = True
else: else:
self.simulation = False self.simulation = False

View File

@ -10,11 +10,12 @@ from artiq.tools import verbosity_args, simple_network_args, init_logger
def get_argparser(): def get_argparser():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="ARTIQ controller for the Lab Brick Digital Attenuator") description="ARTIQ controller for the Lab Brick Digital Attenuator")
parser.add_argument("-d", "--device", default="LDA-102", parser.add_argument("-P", "--product", default="LDA-102",
choices=["LDA-102", "LDA-602", "sim"]) choices=["LDA-102", "LDA-602"])
simple_network_args(parser, 3253) simple_network_args(parser, 3253)
parser.add_argument("-s", "--serial", default=None, parser.add_argument("-d", "--device", default=None,
help="USB serial number of the device") help="USB serial number of the device."
" Omit for simulation mode.")
verbosity_args(parser) verbosity_args(parser)
return parser return parser
@ -22,10 +23,10 @@ def get_argparser():
def main(): def main():
args = get_argparser().parse_args() args = get_argparser().parse_args()
init_logger(args) init_logger(args)
if args.device == "sim": if args.device is None:
lda = Ldasim() lda = Ldasim()
else: else:
lda = Lda(args.serial, args.device) lda = Lda(args.serial, args.product)
simple_server_loop({"lda": lda}, simple_server_loop({"lda": lda},
args.bind, args.port) args.bind, args.port)

View File

@ -20,11 +20,8 @@ def get_argparser():
" 409B 4-channel DDS box") " 409B 4-channel DDS box")
simple_network_args(parser, 3254) simple_network_args(parser, 3254)
parser.add_argument( parser.add_argument(
"-s", "--serial-dev", "-d", "--device", default=None,
default="/dev/ttyUSB0", type=str, help="serial port. Omit for simulation mode.")
help="serial port: on Windows \"COMx\","
" on Linux a device path (e.g. \"/dev/ttyUSB0\")."
" Use \"sim\" for simulation mode.")
verbosity_args(parser) verbosity_args(parser)
return parser return parser
@ -32,7 +29,7 @@ def main():
args = get_argparser().parse_args() args = get_argparser().parse_args()
init_logger(args) init_logger(args)
dev = Novatech409B(args.serial_dev) dev = Novatech409B(args.device)
try: try:
simple_server_loop( simple_server_loop(
{"novatech409b": dev}, args.bind, args.port) {"novatech409b": dev}, args.bind, args.port)

View File

@ -11,9 +11,10 @@ def get_argparser():
parser = argparse.ArgumentParser(description="PDQ2 controller") parser = argparse.ArgumentParser(description="PDQ2 controller")
simple_network_args(parser, 3252) simple_network_args(parser, 3252)
parser.add_argument( parser.add_argument(
"-d", "--device", required=True, help="device url/path/name") "-d", "--device", default=None,
help="serial port. Omit for simulation mode.")
parser.add_argument( parser.add_argument(
"-u", "--dump", default=None, "--dump", default="pdq2_dump.bin",
help="file to dump pdq2 data into, for later simulation") help="file to dump pdq2 data into, for later simulation")
verbosity_args(parser) verbosity_args(parser)
return parser return parser
@ -23,7 +24,7 @@ def main():
args = get_argparser().parse_args() args = get_argparser().parse_args()
init_logger(args) init_logger(args)
port = None port = None
if args.dump: if args.device is None:
port = open(args.dump, "wb") port = open(args.dump, "wb")
dev = Pdq2(url=args.device, dev=port) dev = Pdq2(url=args.device, dev=port)
try: try:

View File

@ -9,16 +9,15 @@ from artiq.tools import verbosity_args, init_logger
def get_argparser(): def get_argparser():
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("-d", "--device", required=True, parser.add_argument("-P", "--product", required=True,
help="type of the Thorlabs T-Cube device to control", help="type of the Thorlabs T-Cube device to control",
choices=["TDC001", "TPZ001", "TDCSim", "TPZSim"]) choices=["TDC001", "TPZ001"])
parser.add_argument("--bind", default="::1", parser.add_argument("--bind", default="::1",
help="hostname or IP address to bind to") help="hostname or IP address to bind to")
parser.add_argument("-p", "--port", default=3255, type=int, parser.add_argument("-p", "--port", default=3255, type=int,
help="TCP port to listen to") help="TCP port to listen to")
parser.add_argument("-s", "--serial", default="/dev/ttyUSB0", parser.add_argument("-d", "--device", default=None,
help="serial port: on Windows \"COMx\", on Linux a " help="serial port. Omit for simulation mode.")
"device path (e.g. \"/dev/ttyUSB0\").")
verbosity_args(parser) verbosity_args(parser)
return parser return parser
@ -27,21 +26,18 @@ def main():
args = get_argparser().parse_args() args = get_argparser().parse_args()
init_logger(args) init_logger(args)
devname = args.device.lower() if args.device is None:
if args.product == "TDC001":
if devname == "tdc001": dev = TdcSim()
dev = Tdc(args.serial) elif args.product == "TPZ001":
elif devname == "tpz001": dev = TpzSim()
dev = Tpz(args.serial)
elif devname == "tdcsim":
dev = TdcSim()
elif devname == "tpzsim":
dev = TpzSim()
else: else:
raise ValueError("Device can be either TDC001, TPZ001, TDCSim" if args.product == "TDC001":
" or TPZSim") dev = Tdc(args.device)
elif args.product == "TPZ001":
dev = Tpz(args.device)
simple_server_loop({devname: dev}, args.bind, args.port) simple_server_loop({args.product.lower(): dev}, args.bind, args.port)
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -175,9 +175,9 @@ General guidelines
* Do not use ``__del__`` to implement the cleanup code of your driver. Instead, define a ``close`` method, and call it using a ``try...finally...`` block in the controller. * Do not use ``__del__`` to implement the cleanup code of your driver. Instead, define a ``close`` method, and call it using a ``try...finally...`` block in the controller.
* Format your source code according to PEP8. We suggest using ``flake8`` to check for compliance. * Format your source code according to PEP8. We suggest using ``flake8`` to check for compliance.
* Use new-style formatting (``str.format``) except for logging where it is not well supported, and double quotes for strings. * Use new-style formatting (``str.format``) except for logging where it is not well supported, and double quotes for strings.
* The device identification (e.g. serial number) to attach to must be passed as a command-line parameter to the controller. We suggest using ``-s`` and ``--serial`` as parameter name. * The device identification (e.g. serial number, or entry in ``/dev``) to attach to must be passed as a command-line parameter to the controller. We suggest using ``-d`` and ``--device`` as parameter name.
* Controllers must be able to operate in "simulation" mode, where they behave properly even if the associated hardware is not connected. For example, they can print the data to the console instead of sending it to the device, or dump it into a file. * Controllers must be able to operate in "simulation" mode, where they behave properly even if the associated hardware is not connected. For example, they can print the data to the console instead of sending it to the device, or dump it into a file.
* We suggest that the simulation mode is entered by using "sim" in place of the serial number or device name. * We suggest that the simulation mode is entered whenever the ``-d/--device`` option is omitted.
* Keep command line parameters consistent across clients/controllers. When adding new command line options, look for a client/controller that does a similar thing and follow its use of ``argparse``. If the original client/controller could use ``argparse`` in a better way, improve it. * Keep command line parameters consistent across clients/controllers. When adding new command line options, look for a client/controller that does a similar thing and follow its use of ``argparse``. If the original client/controller could use ``argparse`` in a better way, improve it.
* Use docstrings for all public methods of the driver (note that those will be retrieved by ``artiq_rpctool``). * Use docstrings for all public methods of the driver (note that those will be retrieved by ``artiq_rpctool``).
* Choose a free default TCP port and add it to the default port list in this manual. * Choose a free default TCP port and add it to the default port list in this manual.

View File

@ -120,7 +120,7 @@
"host": "::1", "host": "::1",
"port": 3253, "port": 3253,
"target_name": "lda", "target_name": "lda",
"command": "lda_controller -p {port} --bind {bind} -d sim" "command": "lda_controller -p {port} --bind {bind}"
}, },
"pmt": "pmt0", "pmt": "pmt0",