moninj: add load/save config

This commit is contained in:
Simon Renblad 2024-04-22 14:06:09 +08:00
parent 6730f35489
commit c1c0f63f81

View File

@ -1,15 +1,19 @@
import asyncio
import logging
import textwrap
import os
from collections import namedtuple
from PyQt5 import QtCore, QtWidgets, QtGui
import pyqtgraph as pg
from sipyco import pyon
from artiq.coredevice.comm_moninj import CommMonInj, TTLOverride, TTLProbe
from artiq.coredevice.ad9912_reg import AD9912_SER_CONF
from artiq.gui.tools import LayoutWidget
from artiq.gui.tools import LayoutWidget, get_open_file_name, get_save_file_name
from artiq.gui.models import DictSyncTreeSepModel
from artiq.tools import exc_to_warning
logger = logging.getLogger(__name__)
@ -930,6 +934,14 @@ class MonInjDock(QtWidgets.QDockWidget):
layout = LayoutWidget()
self.setWidget(layout)
self._current_dir = os.getcwd()
self._menu_btn = QtWidgets.QPushButton()
self._menu_btn.setIcon(
QtWidgets.QApplication.style().standardIcon(
QtWidgets.QStyle.SP_FileDialogStart))
layout.addWidget(self._menu_btn, 0, 0)
self._channel_model = Model({})
self.add_channel_dialog = _AddChannelDialog(self, self._channel_model)
self.add_channel_dialog.accepted.connect(
@ -940,11 +952,22 @@ class MonInjDock(QtWidgets.QDockWidget):
QtWidgets.QApplication.style().standardIcon(
QtWidgets.QStyle.SP_FileDialogListView))
add_channel_btn.clicked.connect(self.add_channel_dialog.open)
layout.addWidget(add_channel_btn, 0, 0, colspan=1)
layout.addWidget(add_channel_btn, 0, 1)
self.tree = MoninjTreeWidget()
layout.addWidget(self.tree, 1, 0, colspan=10)
self._file_menu = QtWidgets.QMenu()
self._add_async_action("Open configuration...", self.load_configuration)
self._add_async_action("Save configuration...", self.save_configuration)
self._menu_btn.setMenu(self._file_menu)
def _add_async_action(self, label, coro):
action = QtWidgets.QAction(label, self)
action.triggered.connect(
lambda: asyncio.ensure_future(exc_to_warning(coro())))
self._file_menu.addAction(action)
def layout_widgets(self, handlers):
for handler in handlers:
handler.create_widget()
@ -955,6 +978,67 @@ class MonInjDock(QtWidgets.QDockWidget):
self._channel_model.clear()
self._channel_model.update(handlers)
def _get_widget_from_handler(self, uid):
if uid in self.dm.handlers_by_uid:
handler = self.dm.handlers_by_uid[uid]
handler.create_widget()
return handler.widget
else:
logger.warning("skipping moninj widget with uid {}:"
" description incorrect/missing from device db".format(uid))
return None
def _connect_config(self, config):
out_config = []
for item in config:
if isinstance(item, dict):
out_widgets = []
for uid in item["widgets"]:
widget = self._get_widget_from_handler(uid)
if widget is not None:
out_widgets.append(widget)
item["widgets"] = out_widgets
out_config.append(item)
else:
widget = self._get_widget_from_handler(item)
if widget is not None:
out_config.append(widget)
return out_config
async def load_configuration(self):
try:
filename = await get_open_file_name(
self,
"Load configuration",
self._current_dir,
"PYON files (*.pyon);;All files (*.*)")
except asyncio.CancelledError:
return
self._current_dir = os.path.dirname(filename)
try:
configuration = pyon.load_file(filename)
connected_config = self._connect_config(configuration)
self.tree.clear()
self.tree.extend(connected_config)
except Exception:
logger.error("Failed to load moninj configuration", exc_info=True)
async def save_configuration(self):
try:
filename = await get_save_file_name(
self,
"Save configuration",
self._current_dir,
"PYON files (*.pyon);;All files (*.*)")
except asyncio.CancelledError:
return
self._current_dir = os.path.dirname(filename)
try:
configuration = self.tree.export_list()
pyon.store_file(filename, configuration)
except Exception:
logger.error("Failed to save moninj configuration", exc_info=True)
async def stop(self):
if self.dm is not None:
await self.dm.close()