mirror of
https://github.com/bec-project/bec_widgets.git
synced 2025-07-13 11:11:49 +02:00
fix: put waiting in thread
This commit is contained in:
@ -1,10 +1,12 @@
|
|||||||
import traceback
|
import traceback
|
||||||
|
from threading import Thread
|
||||||
|
|
||||||
from bec_lib.atlas_models import Device as DeviceConfigModel
|
from bec_lib.atlas_models import Device as DeviceConfigModel
|
||||||
from bec_lib.config_helper import CONF as DEVICE_CONF_KEYS
|
from bec_lib.config_helper import CONF as DEVICE_CONF_KEYS
|
||||||
from bec_lib.config_helper import ConfigHelper
|
from bec_lib.config_helper import ConfigHelper
|
||||||
from bec_lib.logger import bec_logger
|
from bec_lib.logger import bec_logger
|
||||||
from qtpy.QtCore import QSize, Qt
|
from PySide6.QtCore import QObject
|
||||||
|
from qtpy.QtCore import QRunnable, QSize, Qt, QThreadPool, Signal
|
||||||
from qtpy.QtWidgets import (
|
from qtpy.QtWidgets import (
|
||||||
QApplication,
|
QApplication,
|
||||||
QDialog,
|
QDialog,
|
||||||
@ -24,6 +26,39 @@ from bec_widgets.widgets.utility.spinner.spinner import SpinnerWidget
|
|||||||
logger = bec_logger.logger
|
logger = bec_logger.logger
|
||||||
|
|
||||||
|
|
||||||
|
class _CommSignals(QObject):
|
||||||
|
error = Signal(str)
|
||||||
|
done = Signal()
|
||||||
|
|
||||||
|
|
||||||
|
class _CommunicateUpdate(QRunnable):
|
||||||
|
|
||||||
|
def __init__(self, config_helper: ConfigHelper, device: str, config: dict) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.config_helper = config_helper
|
||||||
|
self.device = device
|
||||||
|
self.config = config
|
||||||
|
self.signals = _CommSignals()
|
||||||
|
|
||||||
|
@SafeSlot()
|
||||||
|
def run(self):
|
||||||
|
try:
|
||||||
|
timeout = self.config_helper.suggested_timeout_s(self.config)
|
||||||
|
RID = self.config_helper.send_config_request(
|
||||||
|
action="update", config={self.device: self.config}, wait_for_response=False
|
||||||
|
)
|
||||||
|
logger.info("Waiting for config reply")
|
||||||
|
reply = self.config_helper.wait_for_config_reply(RID, timeout=timeout)
|
||||||
|
logger.info("Handling config reply")
|
||||||
|
self.config_helper.handle_update_reply(reply, RID, timeout)
|
||||||
|
except Exception as e:
|
||||||
|
self.signals.error.emit(
|
||||||
|
f"Error updating config: \n {''.join(traceback.format_exception(e))}"
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
self.signals.done.emit()
|
||||||
|
|
||||||
|
|
||||||
class DeviceConfigDialog(BECWidget, QDialog):
|
class DeviceConfigDialog(BECWidget, QDialog):
|
||||||
RPC = False
|
RPC = False
|
||||||
|
|
||||||
@ -38,7 +73,7 @@ class DeviceConfigDialog(BECWidget, QDialog):
|
|||||||
self._config_helper = config_helper or ConfigHelper(
|
self._config_helper = config_helper or ConfigHelper(
|
||||||
self.client.connector, self.client._service_name
|
self.client.connector, self.client._service_name
|
||||||
)
|
)
|
||||||
|
self.threadpool = QThreadPool()
|
||||||
self._device = device
|
self._device = device
|
||||||
self.setWindowTitle(f"Edit config for: {device}")
|
self.setWindowTitle(f"Edit config for: {device}")
|
||||||
self._container = QStackedLayout()
|
self._container = QStackedLayout()
|
||||||
@ -58,6 +93,10 @@ class DeviceConfigDialog(BECWidget, QDialog):
|
|||||||
self._form = DeviceConfigForm()
|
self._form = DeviceConfigForm()
|
||||||
self._layout.addWidget(self._form)
|
self._layout.addWidget(self._form)
|
||||||
|
|
||||||
|
for row in self._form.enumerate_form_widgets():
|
||||||
|
if row.label.property("_model_field_name") in DEVICE_CONF_KEYS.NON_UPDATABLE:
|
||||||
|
row.widget._set_pretty_display()
|
||||||
|
|
||||||
self._fetch_config()
|
self._fetch_config()
|
||||||
self._fill_form()
|
self._fill_form()
|
||||||
self._container.addWidget(self._form_widget)
|
self._container.addWidget(self._form_widget)
|
||||||
@ -90,7 +129,9 @@ class DeviceConfigDialog(BECWidget, QDialog):
|
|||||||
self.client.device_manager is not None
|
self.client.device_manager is not None
|
||||||
and self._device in self.client.device_manager.devices
|
and self._device in self.client.device_manager.devices
|
||||||
):
|
):
|
||||||
self._initial_config = self.client.device_manager.devices.get(self._device)._config
|
dev = self.client.device_manager.devices.get(self._device)
|
||||||
|
dev.read_configuration(cached=False)
|
||||||
|
self._initial_config = dev._config
|
||||||
|
|
||||||
def _fill_form(self):
|
def _fill_form(self):
|
||||||
self._form.set_data(DeviceConfigModel.model_validate(self._initial_config))
|
self._form.set_data(DeviceConfigModel.model_validate(self._initial_config))
|
||||||
@ -122,32 +163,28 @@ class DeviceConfigDialog(BECWidget, QDialog):
|
|||||||
self._update_device_config(updated_config)
|
self._update_device_config(updated_config)
|
||||||
|
|
||||||
def _update_device_config(self, config: dict):
|
def _update_device_config(self, config: dict):
|
||||||
|
if self._device is None:
|
||||||
|
return
|
||||||
if config == {}:
|
if config == {}:
|
||||||
logger.info("No changes made to device config")
|
logger.info("No changes made to device config")
|
||||||
return
|
return
|
||||||
logger.info(f"Sending request to update device config: {config}")
|
logger.info(f"Sending request to update device config: {config}")
|
||||||
|
|
||||||
self._start_waiting_display()
|
self._start_waiting_display()
|
||||||
|
communicate_update = _CommunicateUpdate(self._config_helper, self._device, config)
|
||||||
|
communicate_update.signals.error.connect(self.update_error)
|
||||||
|
communicate_update.signals.done.connect(self.update_done)
|
||||||
|
self.threadpool.start(communicate_update)
|
||||||
|
|
||||||
def _communicate_update():
|
@SafeSlot()
|
||||||
try:
|
def update_done(self):
|
||||||
RID = self._config_helper.send_config_request(
|
self._stop_waiting_display()
|
||||||
action="update", config={self._device: config}, wait_for_response=False
|
self._fetch_config()
|
||||||
)
|
self._fill_form()
|
||||||
logger.info("Waiting for config reply")
|
|
||||||
reply = self._config_helper.wait_for_config_reply(
|
|
||||||
RID, timeout=self._config_helper.suggested_timeout_s(config)
|
|
||||||
)
|
|
||||||
logger.info("Handling config reply")
|
|
||||||
self._config_helper.handle_update_reply(reply, RID)
|
|
||||||
except Exception as e:
|
|
||||||
self._stop_waiting_display()
|
|
||||||
logger.error(f"Error updating config: \n {''.join(traceback.format_exception(e))}")
|
|
||||||
finally:
|
|
||||||
self._fetch_config()
|
|
||||||
self._fill_form()
|
|
||||||
|
|
||||||
Thread(target=_communicate_update).start()
|
@SafeSlot(str)
|
||||||
|
def update_error(self, e: str):
|
||||||
|
logger.error(e)
|
||||||
|
|
||||||
def _start_waiting_display(self):
|
def _start_waiting_display(self):
|
||||||
self._overlay_widget.setVisible(True)
|
self._overlay_widget.setVisible(True)
|
||||||
|
@ -91,6 +91,7 @@ def test_update_cycle(dialog, qtbot):
|
|||||||
|
|
||||||
assert dialog.updated_config() == update
|
assert dialog.updated_config() == update
|
||||||
dialog.apply()
|
dialog.apply()
|
||||||
|
qtbot.waitUntil(lambda: dialog._config_helper.send_config_request.call_count == 1, timeout=100)
|
||||||
|
|
||||||
dialog._config_helper.send_config_request.assert_called_with(
|
dialog._config_helper.send_config_request.assert_called_with(
|
||||||
action="update", config={"test_device": update}, wait_for_response=False
|
action="update", config={"test_device": update}, wait_for_response=False
|
||||||
|
Reference in New Issue
Block a user