diff --git a/bec_widgets/widgets/control/device_control/positioner_box/positioner_box_2d/positioner_box_2d.py b/bec_widgets/widgets/control/device_control/positioner_box/positioner_box_2d/positioner_box_2d.py index 83bb73e14..24cc1d683 100644 --- a/bec_widgets/widgets/control/device_control/positioner_box/positioner_box_2d/positioner_box_2d.py +++ b/bec_widgets/widgets/control/device_control/positioner_box/positioner_box_2d/positioner_box_2d.py @@ -429,7 +429,7 @@ def update_limits_ver(self, limits: tuple): @SafeSlot() def on_stop(self): - self._stop_device(f"{self.device_hor} or {self.device_ver}") + self._stop_device([self.device_hor, self.device_ver]) @SafeProperty(float) def step_size_hor(self): diff --git a/bec_widgets/widgets/control/device_control/positioner_box/positioner_box_base.py b/bec_widgets/widgets/control/device_control/positioner_box/positioner_box_base.py index 85773652e..33afbfa49 100644 --- a/bec_widgets/widgets/control/device_control/positioner_box/positioner_box_base.py +++ b/bec_widgets/widgets/control/device_control/positioner_box/positioner_box_base.py @@ -1,11 +1,10 @@ -import uuid from abc import abstractmethod -from typing import Callable, TypedDict +from typing import Callable, Sequence, TypedDict from bec_lib.device import Positioner from bec_lib.endpoints import MessageEndpoints from bec_lib.logger import bec_logger -from bec_lib.messages import ScanQueueMessage +from bec_lib.messages import VariableMessage from qtpy.QtWidgets import ( QDialog, QDoubleSpinBox, @@ -116,17 +115,16 @@ def _init_device( else: ui["units"].setVisible(False) - def _stop_device(self, device: str): + def _stop_device(self, device: str | Sequence[str]): """Stop call""" - request_id = str(uuid.uuid4()) - params = {"device": device, "rpc_id": request_id, "func": "stop", "args": [], "kwargs": {}} - msg = ScanQueueMessage( - scan_type="device_rpc", - parameter=params, - queue="emergency", - metadata={"RID": request_id, "response": False}, - ) - self.client.connector.send(MessageEndpoints.scan_queue_request(self.client.username), msg) + devices = [device] if isinstance(device, str) else list(device) + devices = [dev for dev in devices if dev] + if not devices: + logger.warning("Stop requested without a valid device.") + return + + msg = VariableMessage(value=devices) + self.client.connector.send(MessageEndpoints.stop_devices(), msg) # pylint: disable=unused-argument def _on_device_readback( diff --git a/tests/unit_tests/test_positioner_box.py b/tests/unit_tests/test_positioner_box.py index 39741e0ea..5f6db0816 100644 --- a/tests/unit_tests/test_positioner_box.py +++ b/tests/unit_tests/test_positioner_box.py @@ -2,7 +2,7 @@ import pytest from bec_lib.endpoints import MessageEndpoints -from bec_lib.messages import ScanQueueMessage +from bec_lib.messages import VariableMessage from qtpy.QtCore import Qt, QTimer from qtpy.QtGui import QValidator from qtpy.QtWidgets import QPushButton @@ -34,15 +34,11 @@ def precision(self): def positioner_box(qtbot, mocked_client): """Fixture for PositionerBox widget""" with mock.patch( - "bec_widgets.widgets.control.device_control.positioner_box.positioner_box_base.uuid.uuid4" - ) as mock_uuid: - mock_uuid.return_value = "fake_uuid" - with mock.patch( - "bec_widgets.widgets.control.device_control.positioner_box.positioner_box_base.PositionerBoxBase._check_device_is_valid", - return_value=True, - ): - db = create_widget(qtbot, PositionerBox, device="samx", client=mocked_client) - yield db + "bec_widgets.widgets.control.device_control.positioner_box.positioner_box_base.PositionerBoxBase._check_device_is_valid", + return_value=True, + ): + db = create_widget(qtbot, PositionerBox, device="samx", client=mocked_client) + yield db def test_positioner_box(positioner_box): @@ -89,16 +85,8 @@ def test_positioner_box_on_stop(positioner_box): """Test on stop button""" with mock.patch.object(positioner_box.client.connector, "send") as mock_send: positioner_box.on_stop() - params = {"device": "samx", "rpc_id": "fake_uuid", "func": "stop", "args": [], "kwargs": {}} - msg = ScanQueueMessage( - scan_type="device_rpc", - parameter=params, - queue="emergency", - metadata={"RID": "fake_uuid", "response": False}, - ) - mock_send.assert_called_once_with( - MessageEndpoints.scan_queue_request(positioner_box.client.username), msg - ) + msg = VariableMessage(value=["samx"]) + mock_send.assert_called_once_with(MessageEndpoints.stop_devices(), msg) def test_positioner_box_setpoint_change(positioner_box): @@ -139,19 +127,15 @@ def test_positioner_control_line(qtbot, mocked_client): Inherits from PositionerBox, but the layout is changed. Check dimensions only """ with mock.patch( - "bec_widgets.widgets.control.device_control.positioner_box.positioner_box_base.uuid.uuid4" - ) as mock_uuid: - mock_uuid.return_value = "fake_uuid" - with mock.patch( - "bec_widgets.widgets.control.device_control.positioner_box.positioner_box.positioner_box.PositionerBox._check_device_is_valid", - return_value=True, - ): - db = PositionerControlLine(device="samx", client=mocked_client) - qtbot.addWidget(db) - - assert db.ui.device_box.height() == db.height() - assert db.ui.device_box.height() >= db.dimensions[0] - assert db.ui.device_box.width() == 600 + "bec_widgets.widgets.control.device_control.positioner_box.positioner_box.positioner_box.PositionerBox._check_device_is_valid", + return_value=True, + ): + db = PositionerControlLine(device="samx", client=mocked_client) + qtbot.addWidget(db) + + assert db.ui.device_box.height() == db.height() + assert db.ui.device_box.height() >= db.dimensions[0] + assert db.ui.device_box.width() == 600 def test_positioner_box_open_dialog_selection(qtbot, positioner_box): diff --git a/tests/unit_tests/test_positioner_box_2d.py b/tests/unit_tests/test_positioner_box_2d.py index 39aff535b..cde9d1b4b 100644 --- a/tests/unit_tests/test_positioner_box_2d.py +++ b/tests/unit_tests/test_positioner_box_2d.py @@ -1,6 +1,8 @@ from unittest import mock import pytest +from bec_lib.endpoints import MessageEndpoints +from bec_lib.messages import VariableMessage from bec_widgets.widgets.control.device_control.positioner_box import PositionerBox2D @@ -12,17 +14,13 @@ def positioner_box_2d(qtbot, mocked_client): """Fixture for PositionerBox widget""" with mock.patch( - "bec_widgets.widgets.control.device_control.positioner_box.positioner_box_base.uuid.uuid4" - ) as mock_uuid: - mock_uuid.return_value = "fake_uuid" - with mock.patch( - "bec_widgets.widgets.control.device_control.positioner_box.positioner_box_base.PositionerBoxBase._check_device_is_valid", - return_value=True, - ): - db = create_widget( - qtbot, PositionerBox2D, device_hor="samx", device_ver="samy", client=mocked_client - ) - yield db + "bec_widgets.widgets.control.device_control.positioner_box.positioner_box_base.PositionerBoxBase._check_device_is_valid", + return_value=True, + ): + db = create_widget( + qtbot, PositionerBox2D, device_hor="samx", device_ver="samy", client=mocked_client + ) + yield db def test_positioner_box_2d(positioner_box_2d): @@ -82,6 +80,14 @@ def test_positioner_box_setpoint_changes(positioner_box_2d: PositionerBox2D): mock_move.assert_called_once_with(100, relative=False) +def test_positioner_box_2d_on_stop(positioner_box_2d: PositionerBox2D): + """Stop button sends both positioners to the immediate stop endpoint.""" + with mock.patch.object(positioner_box_2d.client.connector, "send") as mock_send: + positioner_box_2d.on_stop() + msg = VariableMessage(value=["samx", "samy"]) + mock_send.assert_called_once_with(MessageEndpoints.stop_devices(), msg) + + def _hor_buttons(widget: PositionerBox2D): return [ widget.ui.tweak_increase_hor,