forked from M-Labs/artiq
1
0
Fork 0

Compare commits

...

5 Commits

6 changed files with 154 additions and 16 deletions

View File

@ -94,9 +94,7 @@ class CommMonInj:
self.injection_status_cb(channel, override, value)
else:
raise ValueError("Unknown packet type", ty)
except asyncio.CancelledError:
raise
except:
except Exception:
logger.error("Moninj connection terminating with exception", exc_info=True)
finally:
if self.disconnect_cb is not None:

View File

@ -0,0 +1,133 @@
import logging
from PyQt5 import QtCore, QtWidgets, QtGui
from artiq.gui.tools import LayoutWidget
from artiq.gui.models import DictSyncModel
from artiq.gui.applets import EntryArea
logger = logging.getLogger(__name__)
class Model(DictSyncModel):
def __init__(self, init):
DictSyncModel.__init__(self,
["RID", "argdesc"],
init)
def convert(self, k, v, column):
if column == 0:
return k
elif column == 1:
return v
else:
raise ValueError
class _InteractiveArgsArea(QtWidgets.QScrollArea):
supplied = QtCore.pyqtSignal(int, dict)
cancelled = QtCore.pyqtSignal(int)
def __init__(self, interactive_args_sub):
QtWidgets.QScrollArea.__init__(self)
self.setWidgetResizable(True)
self.interactive_args_sub = interactive_args_sub
self.request_stack = QtWidgets.QStackedWidget()
self.setWidget(self.request_stack)
self.model = Model({})
self.interactive_args_sub.add_setmodel_callback(self.setModel)
def setModel(self, model):
self.model = model
self.model.dataChanged.connect(self.update_widget)
self.model.rowsInserted.connect(self.insert)
self.model.rowsMoved.connect(self.move)
self.model.rowsRemoved.connect(self.remove)
def _insert_widget(self, index):
logger.info("inserting widget at index %d", index)
rid = self.model.row_to_key[index]
arglist_desc = self.model.backing_store[rid]
entry_area = EntryArea()
for args in arglist_desc:
entry_area.setattr_argument(*args)
self.request_stack.insertWidget(index, entry_area)
def update_widget(self, top_left, bottom_right, roles):
index = top_left.row()
widget = self.request_stack.widget(index)
self.request_stack.removeWidget(widget)
self._insert_widget(index)
widget.deleteLater()
def insert(self, parent, first, last):
self._insert_widget(first)
def move(self, src_parent, src_start, src_end, dest_parent, dest_end):
widget = self.request_stack.widget(src_start)
self.request_stack.insertWidget(dest_end)
def remove(self, parent, first, last):
widget = self.request_stack.widget(first)
self.request_stack.removeWidget(widget)
widget.deleteLater()
def set_active_widget(self, index):
self.request_stack.setCurrentIndex(index.row())
def supply_current(self):
index = self.request_stack.getCurrentIndex()
self.supply(index)
def supply(self, index):
rid = self.model.row_to_key[index]
widget = self.request_stack.widget(index)
self.supply.emit(rid, d)
d = widget.get_values()
def cancel_current(self):
index = self.request_stack.getCurrentIndex()
self.cancel(index)
def cancel(self, index):
rid = self.model.row_to_key[index]
self.cancel.emit(rid)
class InteractiveArgsDock(QtWidgets.QDockWidget):
def __init__(self, interactive_args_sub, interactive_args_rpc):
QtWidgets.QDockWidget.__init__(self, "Interactive Args")
layout = LayoutWidget(self)
self.setWidget(layout)
self.request_queue = QtWidgets.QListView()
model = Model({})
self.request_queue.setModel(model)
layout.addWidget(self.request_queue, 0, 0)
self.args_area = _InteractiveArgsArea(interactive_args_sub)
self.args_area.supplied.connect(interactive_args_rpc.supply)
self.args_area.cancelled.connect(interactive_args_rpc.cancel)
layout.addWidget(self.args_area, 0, 1)
self.request_queue.doubleClicked.connect(self.args_area.set_active_widget)
self.supply_all_btn = QtWidgets.QPushButton("Supply all")
self.supply_all_btn.clicked.connect(self.supply_all)
layout.addWidget(self.supply_all_btn, 1, 0)
self.cancel_all_btn = QtWidgets.QPushButton("Cancel all")
self.cancel_all_btn.clicked.connect(self.cancel_all)
layout.addWidget(self.cancel_all_btn, 1, 1)
interactive_args_sub.add_setmodel_callback(self.request_queue.setModel)
def supply_all(self):
pass
def cancel_all(self):
pass

View File

@ -719,10 +719,7 @@ class _DeviceManager:
self.disconnect_cb)
try:
await new_mi_connection.connect(self.mi_addr, self.mi_port)
except asyncio.CancelledError:
logger.info("cancelled connection to moninj")
break
except:
except Exception:
logger.error("failed to connect to moninj. Is aqctl_moninj_proxy running?", exc_info=True)
await asyncio.sleep(10.)
self.reconnect_mi.set()

View File

@ -45,7 +45,7 @@ class ProxyClient():
self.addr = addr
self.port = port
self.port_proxy = port_proxy
self.reconnect()
self._reconnect_event.set()
async def trigger_proxy_task(self):
remote = AsyncioClient()
@ -72,12 +72,12 @@ class ProxyClient():
await self.receiver.close()
self.receiver = None
new_receiver = comm_analyzer.AnalyzerProxyReceiver(
self.receive_cb, self.reconnect)
self.receive_cb, self.disconnect_cb)
try:
if self.addr is not None:
await asyncio.wait_for(new_receiver.connect(self.addr, self.port_proxy),
self.timeout)
logger.info("connected to analyzer proxy %s:%d", self.addr, self.port_proxy)
logger.info("ARTIQ dashboard connected to analyzer proxy (%s)", self.addr)
self.timer_cur = self.timer
self.receiver = new_receiver
continue
@ -100,7 +100,8 @@ class ProxyClient():
if self.receiver is not None:
await self.receiver.close()
def reconnect(self):
def disconnect_cb(self):
logger.error("lost connection to analyzer proxy")
self._reconnect_event.set()

View File

@ -23,7 +23,7 @@ from artiq.gui.models import ModelSubscriber
from artiq.gui import state, log
from artiq.dashboard import (experiments, shortcuts, explorer,
moninj, datasets, schedule, applets_ccb,
waveform)
waveform, interactive_args)
def get_argparser():
@ -141,7 +141,7 @@ def main():
# create connections to master
rpc_clients = dict()
for target in "schedule", "experiment_db", "dataset_db", "device_db":
for target in "schedule", "experiment_db", "dataset_db", "device_db", "interactive_arg_db":
client = AsyncioClient()
loop.run_until_complete(client.connect_rpc(
args.server, args.port_control, target))
@ -166,7 +166,8 @@ def main():
for notifier_name, modelf in (("explist", explorer.Model),
("explist_status", explorer.StatusUpdater),
("datasets", datasets.Model),
("schedule", schedule.Model)):
("schedule", schedule.Model),
("interactive_args", interactive_args.Model)):
subscriber = ModelSubscriber(notifier_name, modelf,
report_disconnect)
loop.run_until_complete(subscriber.connect(
@ -244,6 +245,11 @@ def main():
loop.run_until_complete(devices_sub.connect(args.server, args.port_notify))
atexit_register_coroutine(devices_sub.close, loop=loop)
d_interactive_args = interactive_args.InteractiveArgsDock(
sub_clients["interactive_args"],
rpc_clients["interactive_arg_db"]
)
d_schedule = schedule.ScheduleDock(
rpc_clients["schedule"], sub_clients["schedule"])
smgr.register(d_schedule)
@ -257,7 +263,7 @@ def main():
right_docks = [
d_explorer, d_shortcuts,
d_ttl_dds.ttl_dock, d_ttl_dds.dds_dock, d_ttl_dds.dac_dock,
d_datasets, d_applets, d_waveform
d_datasets, d_applets, d_waveform, d_interactive_args
]
main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, right_docks[0])
for d1, d2 in zip(right_docks, right_docks[1:]):

View File

@ -69,7 +69,10 @@ class EntryArea(QtWidgets.QTreeWidget):
def setattr_argument(self, key, processor, group=None, tooltip=None):
argument = dict()
desc = processor.describe()
if isinstance(processor, dict):
desc = processor
else:
desc = processor.describe()
argument["desc"] = desc
argument["group"] = group
argument["tooltip"] = tooltip