From 5eba9dbc4cd056ceaa600ded106fa7da6cc72b1f Mon Sep 17 00:00:00 2001 From: x01da Date: Mon, 28 Sep 2026 14:43:25 +0200 Subject: [PATCH] wip --- .../widgets/scheduler/item_dialog.py | 3 +- .../widgets/scheduler/scheduler.py | 35 +++++++++++++++---- debye_bec/devices/reffoilchanger.py | 2 +- .../file_writer/debye_nexus_structure.py | 4 +-- 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/debye_bec/bec_widgets/widgets/scheduler/item_dialog.py b/debye_bec/bec_widgets/widgets/scheduler/item_dialog.py index 4a64828..b5a0315 100644 --- a/debye_bec/bec_widgets/widgets/scheduler/item_dialog.py +++ b/debye_bec/bec_widgets/widgets/scheduler/item_dialog.py @@ -247,11 +247,12 @@ class ScheduleItemDialog(QDialog): if not device_name: raise ValueError("No movable device available/selected.") value = self.move_value_spin.value() + units = self.move_value_spin.suffix() relative = self.move_relative_check.isChecked() return { "command": f"dev.{device_name}.move({value!r}, relative={relative!r})", "kind": "move", - "form_state": {"device_name": device_name, "value": value, "relative": relative}, + "form_state": {"device_name": device_name, "value": value, "units": units, "relative": relative}, } def _prefill_move_page(self, state: dict): diff --git a/debye_bec/bec_widgets/widgets/scheduler/scheduler.py b/debye_bec/bec_widgets/widgets/scheduler/scheduler.py index 2bcf498..5b203e6 100644 --- a/debye_bec/bec_widgets/widgets/scheduler/scheduler.py +++ b/debye_bec/bec_widgets/widgets/scheduler/scheduler.py @@ -96,9 +96,9 @@ def build_item_display_text(item: ScheduleItem, beamline: str | None) -> str: ) elif re.match(r"^dev\..*\.move", item.command): if item.form_state["relative"]: - text = f"Move {item.form_state['device_name']} by {item.form_state['value']:+g}" + text = f"Move {item.form_state['device_name']} by {item.form_state['value']:+g} {item.form_state['units']}" else: - text = f"Move {item.form_state['device_name']} to {item.form_state['value']}" + text = f"Move {item.form_state['device_name']} to {item.form_state['value']} {item.form_state['units']}" elif item.command.startswith("dev.ic"): text = ( f"Fill {item.form_state['chamber']} with {item.form_state['conc1']} % " @@ -345,6 +345,7 @@ class Scheduler(BECWidget, QWidget): self._endpoint = schedule_endpoint(self.schedule_name) self._lock = threading.Lock() # guards self.schedule (see module docstring) self._abort_requested = False + self._pause_requested = False self._guard_interrupt_requested = False # see "Guard interaction" in module docstring self._current_report = None # ScanReport of the item currently executing, if any self._current_item_kind: str | None = None # kind of the item _current_report belongs to @@ -461,16 +462,24 @@ class Scheduler(BECWidget, QWidget): run_row = QHBoxLayout() self.run_btn = MyButton("Run / Continue", "success") self.run_from_current_btn = MyButton("Run / Continue from current selection", "success") - self.abort_btn = MyButton("Pause after current item", "emergency") + self.abort_btn = MyButton("Pause now", "emergency") + self.pause_btn = MyButton("Pause after current item", "warning") self.reset_btn = MyButton("Reset Schedule Status", "warning") - for button in (self.run_btn, self.run_from_current_btn, self.abort_btn, self.reset_btn): + for button in ( + self.run_btn, + self.run_from_current_btn, + self.pause_btn, + self.abort_btn, + self.reset_btn, + ): run_row.addWidget(button) run_row.addStretch() control_layout.addLayout(run_row) self.run_btn.clicked.connect(self.run_schedule) - self.run_from_current_btn.connect(self.run_schedule_from_selection) + self.run_from_current_btn.clicked.connect(self.run_schedule_from_selection) self.abort_btn.clicked.connect(self.abort_schedule) + self.pause_btn.clicked.connect(self.pause_schedule) self.reset_btn.clicked.connect(self.reset_schedule) layout.addWidget(control_group) @@ -729,8 +738,9 @@ class Scheduler(BECWidget, QWidget): # Update execution control buttons state = self._current_report is None # True if schedule is not running self.run_btn.setEnabled(state) - self.run_from_current_btn.setEnabled(state) + self.run_from_current_btn.setEnabled(state and self._selected_item_id is not None) self.abort_btn.setEnabled(not state) + self.pause_btn.setEnabled(not state) self.reset_btn.setEnabled(state) @SafeSlot() @@ -1131,6 +1141,7 @@ class Scheduler(BECWidget, QWidget): == QMessageBox.StandardButton.Yes ) self._abort_requested = False + self._pause_requested = False self.schedule.is_running = True self._persist_locked() self.schedule_changed.emit() @@ -1163,6 +1174,10 @@ class Scheduler(BECWidget, QWidget): except Exception: # pylint: disable=broad-except logger.exception("Failed to cancel the currently running schedule item") + @SafeSlot() + def pause_schedule(self): + self._pause_requested = True + @SafeSlot() def reset_schedule(self): """Clear all execution state and start the schedule over from item 1.""" @@ -1390,7 +1405,9 @@ class Scheduler(BECWidget, QWidget): "auto_gain": self.auto_gain, "np": np, } - while not self._abort_requested and not self._closing.is_set(): + while ( + not self._abort_requested and not self._closing.is_set() and not self._pause_requested + ): with self._lock: next_item = self._pick_next_runnable_locked(repeat_aborted_item, first_item) if next_item is None or next_item == "stop": @@ -1411,6 +1428,10 @@ class Scheduler(BECWidget, QWidget): self.schedule.schedule_name, "widget_closed", ) + elif self._pause_requested: + notify_schedule_state( + self.client, self.schedule.notifications, self.schedule.schedule_name, "paused" + ) else: notify_schedule_state( self.client, self.schedule.notifications, self.schedule.schedule_name, "finished" diff --git a/debye_bec/devices/reffoilchanger.py b/debye_bec/devices/reffoilchanger.py index d3daee9..4a2a6a6 100644 --- a/debye_bec/devices/reffoilchanger.py +++ b/debye_bec/devices/reffoilchanger.py @@ -56,7 +56,7 @@ class CurrentFoilSignal(Signal): return None idx = self.parent.ref_rb.get() try: - idx = int(round(idx)) + 1 + idx = int(round(idx)) except (TypeError, ValueError): return None return getattr(self.parent, f"foil{idx:02d}", None) diff --git a/debye_bec/file_writer/debye_nexus_structure.py b/debye_bec/file_writer/debye_nexus_structure.py index f647b29..af74e79 100644 --- a/debye_bec/file_writer/debye_nexus_structure.py +++ b/debye_bec/file_writer/debye_nexus_structure.py @@ -1,6 +1,6 @@ from bec_server.file_writer.default_writer import DefaultFormat -import debye_bec.bec_widgets.widgets.digital_twin.x01da_parameters as bl +import debye_bec.bec_ipython_client.plugins.digital_twin_core.x01da_parameters as bl class DebyeNexusStructure(DefaultFormat): @@ -292,7 +292,7 @@ class DebyeNexusStructure(DefaultFormat): foil = ( self.device_manager.devices.reffoilchanger.read(cached=True) - .get("current_foil") + .get("reffoilchanger_current_foil") .get("value") ) ref_foil = ai2ai4_active.create_dataset(name="Reference", data=foil)