mirror of
https://github.com/bec-project/bec_widgets.git
synced 2026-03-04 16:02:51 +01:00
feat: save and load config from devicebrowser
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
import os
|
||||
import re
|
||||
from functools import partial
|
||||
from typing import Callable
|
||||
|
||||
import bec_lib
|
||||
from bec_lib.callback_handler import EventType
|
||||
from bec_lib.config_helper import ConfigHelper
|
||||
from bec_lib.endpoints import MessageEndpoints
|
||||
@@ -10,7 +12,14 @@ from bec_lib.messages import ConfigAction, ScanStatusMessage
|
||||
from bec_qthemes import material_icon
|
||||
from pyqtgraph import SignalProxy
|
||||
from qtpy.QtCore import QSize, QThreadPool, Signal
|
||||
from qtpy.QtWidgets import QLabel, QListWidget, QListWidgetItem, QToolButton, QVBoxLayout, QWidget
|
||||
from qtpy.QtWidgets import (
|
||||
QFileDialog,
|
||||
QListWidget,
|
||||
QListWidgetItem,
|
||||
QToolButton,
|
||||
QVBoxLayout,
|
||||
QWidget,
|
||||
)
|
||||
|
||||
from bec_widgets.cli.rpc.rpc_register import RPCRegister
|
||||
from bec_widgets.utils.bec_widget import BECWidget
|
||||
@@ -61,12 +70,14 @@ class DeviceBrowser(BECWidget, QWidget):
|
||||
self.bec_dispatcher.client.callbacks.register(
|
||||
EventType.SCAN_STATUS, self.scan_status_changed
|
||||
)
|
||||
self._default_config_dir = os.path.abspath(
|
||||
os.path.join(os.path.dirname(bec_lib.__file__), "./configs/")
|
||||
)
|
||||
|
||||
self.devices_changed.connect(self.update_device_list)
|
||||
self.ui.add_button.clicked.connect(self._create_add_dialog)
|
||||
self.ui.add_button.setIcon(material_icon("add", size=(20, 20), convert_to_pixmap=False))
|
||||
|
||||
self.init_warning_label()
|
||||
self.init_tool_buttons()
|
||||
|
||||
self.init_device_list()
|
||||
self.update_device_list()
|
||||
@@ -90,6 +101,18 @@ class DeviceBrowser(BECWidget, QWidget):
|
||||
initial_status = scan_status.status if scan_status is not None else "closed"
|
||||
self.set_editing_mode(initial_status not in ["open", "paused"])
|
||||
|
||||
def init_tool_buttons(self):
|
||||
def _setup_button(button: QToolButton, icon: str, slot: Callable, tooltip: str = ""):
|
||||
button.clicked.connect(slot)
|
||||
button.setIcon(material_icon(icon, size=(20, 20), convert_to_pixmap=False))
|
||||
button.setToolTip(tooltip)
|
||||
|
||||
_setup_button(self.ui.add_button, "add", self._create_add_dialog, "add new device")
|
||||
_setup_button(self.ui.save_button, "save", self._save_to_file, "save config to file")
|
||||
_setup_button(
|
||||
self.ui.import_button, "input", self._load_from_file, "append/merge config from file"
|
||||
)
|
||||
|
||||
def _create_add_dialog(self):
|
||||
dialog = DeviceConfigDialog(parent=self, device=None, action="add")
|
||||
dialog.open()
|
||||
@@ -148,7 +171,7 @@ class DeviceBrowser(BECWidget, QWidget):
|
||||
self.dev_list.addItem(item)
|
||||
self._device_items[device] = item
|
||||
|
||||
@SafeSlot(bool)
|
||||
@SafeSlot(dict, dict)
|
||||
def scan_status_changed(self, scan_info: dict, _: dict):
|
||||
"""disable editing when scans are running and enable editing when they are finished"""
|
||||
msg = ScanStatusMessage.model_validate(scan_info)
|
||||
@@ -190,6 +213,22 @@ class DeviceBrowser(BECWidget, QWidget):
|
||||
for device in self.dev:
|
||||
self._device_items[device].setHidden(not self.regex.search(device))
|
||||
|
||||
@SafeSlot()
|
||||
def _load_from_file(self):
|
||||
file_path, _ = QFileDialog.getOpenFileName(
|
||||
self, "Update config from file", self._default_config_dir, "Config files (*.yml *.yaml)"
|
||||
)
|
||||
if file_path:
|
||||
self._config_helper.update_session_with_file(file_path)
|
||||
|
||||
@SafeSlot()
|
||||
def _save_to_file(self):
|
||||
file_path, _ = QFileDialog.getSaveFileName(
|
||||
self, "Save config to file", self._default_config_dir, "Config files (*.yml *.yaml)"
|
||||
)
|
||||
if file_path:
|
||||
self._config_helper.save_current_session(file_path)
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
import sys
|
||||
|
||||
@@ -51,6 +51,20 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="save_button">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="import_button">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -39,9 +39,10 @@ class CommunicateConfigAction(QRunnable):
|
||||
raise ValueError(
|
||||
"Must be updating a device or be supplied a name for a new device"
|
||||
)
|
||||
if "deviceConfig" not in self.config:
|
||||
if "deviceConfig" not in self.config or self.action in ["add", "remove"]:
|
||||
self.process_simple_action(dev_name)
|
||||
else:
|
||||
# updating an existing device, but need to recreate it for this change
|
||||
self.process_remove_readd(dev_name)
|
||||
else:
|
||||
raise ValueError(f"action {self.action} is not supported")
|
||||
|
||||
@@ -68,7 +68,7 @@ class DeviceConfigDialog(BECWidget, QDialog):
|
||||
self.client.connector, self.client._service_name
|
||||
)
|
||||
self._device = device
|
||||
self._action = action
|
||||
self._action: Literal["update", "add"] = action
|
||||
self._q_threadpool = threadpool or QThreadPool()
|
||||
self.setWindowTitle(f"Edit config for: {device}")
|
||||
self._container = QStackedLayout()
|
||||
@@ -168,10 +168,9 @@ class DeviceConfigDialog(BECWidget, QDialog):
|
||||
diff = {
|
||||
k: v for k, v in new_config.items() if self._initial_config.get(k) != new_config.get(k)
|
||||
}
|
||||
if self._initial_config["deviceConfig"] in [{}, None] and new_config["deviceConfig"] in [
|
||||
{},
|
||||
None,
|
||||
]:
|
||||
if self._initial_config.get("deviceConfig") in [{}, None] and new_config.get(
|
||||
"deviceConfig"
|
||||
) in [{}, None]:
|
||||
diff.pop("deviceConfig", None)
|
||||
if diff.get("deviceConfig") is not None:
|
||||
# TODO: special cased in some parts of device manager but not others, should
|
||||
@@ -222,7 +221,7 @@ class DeviceConfigDialog(BECWidget, QDialog):
|
||||
self._proc_device_config_change(updated_config)
|
||||
|
||||
def _proc_device_config_change(self, config: dict):
|
||||
logger.info(f"Sending request to update device config: {config}")
|
||||
logger.info(f"Sending request to {self._action} device config: {config}")
|
||||
|
||||
self._start_waiting_display()
|
||||
communicate_update = CommunicateConfigAction(
|
||||
|
||||
Reference in New Issue
Block a user