forked from M-Labs/artiq
1
0
Fork 0

applets: add controller and set_dataset API

This commit is contained in:
Sebastien Bourdeauducq 2023-05-31 22:51:48 +08:00
parent e12219e803
commit c6ddd3af17
7 changed files with 64 additions and 14 deletions

View File

@ -6,7 +6,7 @@ from artiq.applets.simple import SimpleApplet
class NumberWidget(QtWidgets.QLCDNumber): class NumberWidget(QtWidgets.QLCDNumber):
def __init__(self, args): def __init__(self, args, ctl):
QtWidgets.QLCDNumber.__init__(self) QtWidgets.QLCDNumber.__init__(self)
self.setDigitCount(args.digit_count) self.setDigitCount(args.digit_count)
self.dataset_name = args.dataset self.dataset_name = args.dataset

View File

@ -7,7 +7,7 @@ from artiq.applets.simple import SimpleApplet
class Image(pyqtgraph.ImageView): class Image(pyqtgraph.ImageView):
def __init__(self, args): def __init__(self, args, ctl):
pyqtgraph.ImageView.__init__(self) pyqtgraph.ImageView.__init__(self)
self.args = args self.args = args

View File

@ -8,7 +8,7 @@ from artiq.applets.simple import TitleApplet
class HistogramPlot(pyqtgraph.PlotWidget): class HistogramPlot(pyqtgraph.PlotWidget):
def __init__(self, args): def __init__(self, args, ctl):
pyqtgraph.PlotWidget.__init__(self) pyqtgraph.PlotWidget.__init__(self)
self.args = args self.args = args
self.timer = QTimer() self.timer = QTimer()

View File

@ -9,7 +9,7 @@ from artiq.applets.simple import TitleApplet
class XYPlot(pyqtgraph.PlotWidget): class XYPlot(pyqtgraph.PlotWidget):
def __init__(self, args): def __init__(self, args, ctl):
pyqtgraph.PlotWidget.__init__(self) pyqtgraph.PlotWidget.__init__(self)
self.args = args self.args = args
self.timer = QTimer() self.timer = QTimer()

View File

@ -22,7 +22,7 @@ def _compute_ys(histogram_bins, histograms_counts):
# pyqtgraph.GraphicsWindow fails to behave like a regular Qt widget # pyqtgraph.GraphicsWindow fails to behave like a regular Qt widget
# and breaks embedding. Do not use as top widget. # and breaks embedding. Do not use as top widget.
class XYHistPlot(QtWidgets.QSplitter): class XYHistPlot(QtWidgets.QSplitter):
def __init__(self, args): def __init__(self, args, ctl):
QtWidgets.QSplitter.__init__(self) QtWidgets.QSplitter.__init__(self)
self.resize(1000, 600) self.resize(1000, 600)
self.setWindowTitle("XY/Histogram") self.setWindowTitle("XY/Histogram")

View File

@ -6,7 +6,7 @@ from artiq.applets.simple import SimpleApplet
class ProgressWidget(QtWidgets.QProgressBar): class ProgressWidget(QtWidgets.QProgressBar):
def __init__(self, args): def __init__(self, args, ctl):
QtWidgets.QProgressBar.__init__(self) QtWidgets.QProgressBar.__init__(self)
self.setMinimum(args.min) self.setMinimum(args.min)
self.setMaximum(args.max) self.setMaximum(args.max)

View File

@ -7,6 +7,7 @@ import string
from qasync import QEventLoop, QtWidgets, QtCore from qasync import QEventLoop, QtWidgets, QtCore
from sipyco.sync_struct import Subscriber, process_mod from sipyco.sync_struct import Subscriber, process_mod
from sipyco.pc_rpc import AsyncioClient as RPCClient
from sipyco import pyon from sipyco import pyon
from sipyco.pipe_ipc import AsyncioChildComm from sipyco.pipe_ipc import AsyncioChildComm
@ -14,6 +15,29 @@ from sipyco.pipe_ipc import AsyncioChildComm
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class AppletControlIPC:
def __init__(self, ipc):
self.ipc = ipc
def set_dataset(self, key, value, persist=None):
self.ipc.set_dataset(key, value, persist)
class AppletControlRPC:
def __init__(self, loop, dataset_ctl):
self.loop = loop
self.dataset_ctl = dataset_ctl
self.background_tasks = set()
def _background(self, coro, *args):
task = self.loop.create_task(coro(*args))
self.background_tasks.add(task)
task.add_done_callback(self.background_tasks.discard)
def set_dataset(self, key, value, persist=None):
self._background(self.dataset_ctl.set, key, value, persist)
class AppletIPCClient(AsyncioChildComm): class AppletIPCClient(AsyncioChildComm):
def set_close_cb(self, close_cb): def set_close_cb(self, close_cb):
self.close_cb = close_cb self.close_cb = close_cb
@ -72,6 +96,12 @@ class AppletIPCClient(AsyncioChildComm):
self.mod_cb = mod_cb self.mod_cb = mod_cb
asyncio.ensure_future(self.listen()) asyncio.ensure_future(self.listen())
def set_dataset(self, key, value, persist=None):
self.write_pyon({"action": "set_dataset",
"key": key,
"value": value,
"persist": persist})
class SimpleApplet: class SimpleApplet:
def __init__(self, main_widget_class, cmd_description=None, def __init__(self, main_widget_class, cmd_description=None,
@ -92,8 +122,11 @@ class SimpleApplet:
"for dataset notifications " "for dataset notifications "
"(ignored in embedded mode)") "(ignored in embedded mode)")
group.add_argument( group.add_argument(
"--port", default=3250, type=int, "--port-notify", default=3250, type=int,
help="TCP port to connect to") help="TCP port to connect to for notifications (ignored in embedded mode)")
group.add_argument(
"--port-control", default=3251, type=int,
help="TCP port to connect to for control (ignored in embedded mode)")
self._arggroup_datasets = self.argparser.add_argument_group("datasets") self._arggroup_datasets = self.argparser.add_argument_group("datasets")
@ -132,8 +165,21 @@ class SimpleApplet:
if self.embed is not None: if self.embed is not None:
self.ipc.close() self.ipc.close()
def ctl_init(self):
if self.embed is None:
dataset_ctl = RPCClient()
self.loop.run_until_complete(dataset_ctl.connect_rpc(
self.args.server, self.args.port_control, "master_dataset_db"))
self.ctl = AppletControlRPC(self.loop, dataset_ctl)
else:
self.ctl = AppletControlIPC(self.ipc)
def ctl_close(self):
if self.embed is None:
self.ctl.dataset_ctl.close_rpc()
def create_main_widget(self): def create_main_widget(self):
self.main_widget = self.main_widget_class(self.args) self.main_widget = self.main_widget_class(self.args, self.ctl)
if self.embed is not None: if self.embed is not None:
self.ipc.set_close_cb(self.main_widget.close) self.ipc.set_close_cb(self.main_widget.close)
if os.name == "nt": if os.name == "nt":
@ -214,7 +260,7 @@ class SimpleApplet:
self.subscriber = Subscriber("datasets", self.subscriber = Subscriber("datasets",
self.sub_init, self.sub_mod) self.sub_init, self.sub_mod)
self.loop.run_until_complete(self.subscriber.connect( self.loop.run_until_complete(self.subscriber.connect(
self.args.server, self.args.port)) self.args.server, self.args.port_notify))
else: else:
self.ipc.subscribe(self.datasets, self.sub_init, self.sub_mod, self.ipc.subscribe(self.datasets, self.sub_init, self.sub_mod,
dataset_prefixes=self.dataset_prefixes) dataset_prefixes=self.dataset_prefixes)
@ -228,6 +274,8 @@ class SimpleApplet:
self.qasync_init() self.qasync_init()
try: try:
self.ipc_init() self.ipc_init()
try:
self.ctl_init()
try: try:
self.create_main_widget() self.create_main_widget()
self.subscribe() self.subscribe()
@ -235,6 +283,8 @@ class SimpleApplet:
self.loop.run_forever() self.loop.run_forever()
finally: finally:
self.unsubscribe() self.unsubscribe()
finally:
self.ctl_close()
finally: finally:
self.ipc_close() self.ipc_close()
finally: finally: