diff --git a/debye_bec/bec_ipython_client/plugins/digital_twin_core/digital_twin_core.py b/debye_bec/bec_ipython_client/plugins/digital_twin_core/digital_twin_core.py index 243afa1..c89dbe0 100644 --- a/debye_bec/bec_ipython_client/plugins/digital_twin_core/digital_twin_core.py +++ b/debye_bec/bec_ipython_client/plugins/digital_twin_core/digital_twin_core.py @@ -73,7 +73,7 @@ class DigitalTwinCoreError(Exception): class DigitalTwinCore: - def __init__(self): + def __init__(self, load_offsets: bool = True): logger.info("This is the digital twin from the ipython client!") dev = builtins.__dict__.get("dev") bec = builtins.__dict__.get("bec") @@ -92,7 +92,8 @@ class DigitalTwinCore: case "x10da": self.offset_file = OFFSET_FILE_X10DA self.offsets = {} - self.load_offsets() + if load_offsets: + self.load_offsets() def _exclusive_group_key(self, motor: str): """Return (group_index, subgroup_index) for `motor`, or (None, None) diff --git a/debye_bec/bec_widgets/widgets/digital_twin/digital_twin.py b/debye_bec/bec_widgets/widgets/digital_twin/digital_twin.py index ea583c7..205d380 100644 --- a/debye_bec/bec_widgets/widgets/digital_twin/digital_twin.py +++ b/debye_bec/bec_widgets/widgets/digital_twin/digital_twin.py @@ -62,7 +62,7 @@ class DigitalTwin(BECWidget, QWidget): super().__init__(parent=parent, *arg, **kwargs) self.get_bec_shortcuts() - self.core = DigitalTwinCore() + self.core = DigitalTwinCore(load_offsets=False) # Offsets are loaded through GUI later self.beamline = self.core.beamline # Debugging, override beamline! diff --git a/debye_bec/bec_widgets/widgets/scheduler/item_dialog.py b/debye_bec/bec_widgets/widgets/scheduler/item_dialog.py index 2a6ceff..4a64828 100644 --- a/debye_bec/bec_widgets/widgets/scheduler/item_dialog.py +++ b/debye_bec/bec_widgets/widgets/scheduler/item_dialog.py @@ -299,7 +299,11 @@ class ScheduleItemDialog(QDialog): # already-added schedule item (see module docstring). config = self.digital_twin.get_assistant_config() cmd = f"digital_twin.move_with_config({config})" - return {"command": cmd, "kind": "custom", "form_state": {"text": cmd, "config": config}} + return { + "command": cmd, + "kind": "custom", + "form_state": {"text": cmd, "source": "digital_twin", "config": config}, + } def _cleanup_digital_twin(self, *_): digital_twin = getattr(self, "digital_twin", None) @@ -516,6 +520,8 @@ class ScheduleItemDialog(QDialog): self.pips_check = QCheckBox("") form.addRow("PIPS", self.pips_check) + layout.addStretch() + self.edge_selector_button.clicked.connect(self._update_edge) self._add_page("auto_gain", "Auto-Gain", page) @@ -613,6 +619,8 @@ class ScheduleItemDialog(QDialog): def _apply_initial(self, initial: dict): self.pause_on_failure_check.setChecked(bool(initial.get("pause_on_failure", False))) + logger.info(f"Got initial: {initial}") + kind = initial.get("kind") state = initial.get("form_state") or {} source = state.get("source") @@ -622,9 +630,8 @@ class ScheduleItemDialog(QDialog): state["scan_name"], state.get("args") or [], state.get("kwargs") or {} ) self._select_page("scan") - elif kind == "custom" and source == "digital_twin": + elif kind == "custom" and source == "digital_twin" and self._select_page("digital_twin"): self._prefill_digital_twin_page(state) - self._select_page("digital_twin") elif kind == "move" and state.get("device_name"): self._prefill_move_page(state) self._select_page("move") diff --git a/debye_bec/bec_widgets/widgets/scheduler/scheduler.py b/debye_bec/bec_widgets/widgets/scheduler/scheduler.py index 9ebaaf1..6b947ef 100644 --- a/debye_bec/bec_widgets/widgets/scheduler/scheduler.py +++ b/debye_bec/bec_widgets/widgets/scheduler/scheduler.py @@ -812,7 +812,7 @@ class Scheduler(BECWidget, QWidget): self._update_buttons() @SafeSlot() - def _on_edit_clicked(self, _): + def _on_edit_clicked(self, *_): if self._selected_item_id is None: return with self._lock: @@ -834,7 +834,12 @@ class Scheduler(BECWidget, QWidget): logger.info(f"Initial: {initial}") dialog = ScheduleItemDialog( - self.scans, self.dev, parent=self, initial=initial, client=self.client + self.scans, + self.dev, + parent=self, + initial=initial, + client=self.client, + beamline=self.beamline, ) if dialog.exec_() != QDialog.DialogCode.Accepted: return diff --git a/debye_bec/devices/absorber.py b/debye_bec/devices/absorber.py index f069962..5f90a42 100644 --- a/debye_bec/devices/absorber.py +++ b/debye_bec/devices/absorber.py @@ -7,13 +7,14 @@ from typing import TYPE_CHECKING from ophyd import Component as Cpt from ophyd import EpicsSignal, EpicsSignalRO -from ophyd_devices import CompareStatus, DeviceStatus +from ophyd_devices import CompareStatus from ophyd_devices.interfaces.base_classes.psi_device_base import PSIDeviceBase from .utils.bl_status_enum import BlStatus if TYPE_CHECKING: from bec_lib.devicemanager import ScanInfo + from bec_server.device_server.device_server import DeviceManagerDS TIMEOUT_FOR_PV = 5 @@ -68,8 +69,19 @@ class Absorber(PSIDeviceBase): ) close4bl = Cpt(EpicsSignal, suffix="CLOSE4BL", kind="config", doc="Beamline enable") - def __init__(self, *, name: str, prefix: str = "", scan_info: ScanInfo | None = None, **kwargs): - super().__init__(name=name, prefix=prefix, scan_info=scan_info, **kwargs) + def __init__( + self, + *, + name: str, + prefix: str = "", + scan_info: ScanInfo | None = None, + device_manager: DeviceManagerDS | None = None, + **kwargs, + ): + super().__init__( + name=name, prefix=prefix, scan_info=scan_info, device_manager=device_manager, **kwargs + ) + self.device_manager = device_manager self.timeout_for_move = 10 # Wait for connection on all components, ensure IOC is connected @@ -82,12 +94,10 @@ class Absorber(PSIDeviceBase): force(bool): If needed, set bl status to enable and bl enable to ENABLE, defaults to False """ - if force and self.device_manager.devices.get("bl_status", None) is None: - raise AbsorberError("bl_status is not in device config, thus cannot use force = True") if self.status.get() == STATUS.CLOSED: if force: - if self.device_manager.bl_status.get() == BlStatus.OFFLINE: - status = self.device_manager.bl_status.put(BlStatus.ATTENDED) + if self.device_manager.devices.bl_status.get() == BlStatus.OFFLINE: + status = self.device_manager.devices.bl_status.put(BlStatus.ATTENDED) status.wait(timeout=TIMEOUT_FOR_PV) if self.close4bl.get() == BL_ENABLE.DISABLE: status = self.close4bl.set(BL_ENABLE.ENABLE) @@ -98,8 +108,7 @@ class Absorber(PSIDeviceBase): status.wait(timeout=self.timeout_for_move) return None return status - else: - return None + return None def close(self, wait: bool = True) -> CompareStatus | None: """Close the Absorber""" @@ -110,5 +119,4 @@ class Absorber(PSIDeviceBase): status.wait(timeout=self.timeout_for_move) return None return status - else: - return None + return None diff --git a/debye_bec/devices/eh_shutter.py b/debye_bec/devices/eh_shutter.py index ad9d30b..f6b1de5 100644 --- a/debye_bec/devices/eh_shutter.py +++ b/debye_bec/devices/eh_shutter.py @@ -7,11 +7,9 @@ from typing import TYPE_CHECKING from ophyd import Component as Cpt from ophyd import EpicsSignal, EpicsSignalRO -from ophyd_devices import CompareStatus, DeviceStatus +from ophyd_devices import CompareStatus from ophyd_devices.interfaces.base_classes.psi_device_base import PSIDeviceBase -from .utils.bl_status_enum import BlStatus - if TYPE_CHECKING: from bec_lib.devicemanager import ScanInfo @@ -75,8 +73,7 @@ class EHPhotonShutter(PSIDeviceBase): status.wait(timeout=self.timeout_for_move) return None return status - else: - return None + return None def close(self, wait: bool = True) -> CompareStatus | None: """Close the Shutter""" @@ -87,5 +84,4 @@ class EHPhotonShutter(PSIDeviceBase): status.wait(timeout=self.timeout_for_move) return None return status - else: - return None + return None diff --git a/debye_bec/devices/op_shutter.py b/debye_bec/devices/op_shutter.py index 68b0a8d..2d71a75 100644 --- a/debye_bec/devices/op_shutter.py +++ b/debye_bec/devices/op_shutter.py @@ -7,13 +7,14 @@ from typing import TYPE_CHECKING from ophyd import Component as Cpt from ophyd import EpicsSignal, EpicsSignalRO -from ophyd_devices import CompareStatus, DeviceStatus +from ophyd_devices import CompareStatus from ophyd_devices.interfaces.base_classes.psi_device_base import PSIDeviceBase from .utils.bl_status_enum import BlStatus if TYPE_CHECKING: from bec_lib.devicemanager import ScanInfo + from bec_server.device_server.device_server import DeviceManagerDS TIMEOUT_FOR_PV = 5 @@ -64,8 +65,19 @@ class OPPhotonShutter(PSIDeviceBase): ) close4bl = Cpt(EpicsSignal, suffix="FE-BST1:CLOSE4BL", kind="config", doc="Beamline enable") - def __init__(self, *, name: str, prefix: str = "", scan_info: ScanInfo | None = None, **kwargs): - super().__init__(name=name, prefix=prefix, scan_info=scan_info, **kwargs) + def __init__( + self, + *, + name: str, + prefix: str = "", + scan_info: ScanInfo | None = None, + device_manager: DeviceManagerDS | None = None, + **kwargs, + ): + super().__init__( + name=name, prefix=prefix, scan_info=scan_info, device_manager=device_manager, **kwargs + ) + self.device_manager = device_manager self.timeout_for_move = 10 # Wait for connection on all components, ensure IOC is connected @@ -78,14 +90,10 @@ class OPPhotonShutter(PSIDeviceBase): force(bool): If needed, set bl status to enable and bl enable to ENABLE, defaults to False """ - if force and self.device_manager.devices.get("bl_status", None) is None: - raise OPPhotonShutterError( - "bl_status is not in device config, thus cannot use force = True" - ) if self.status.get() == STATUS.CLOSED: if force: - if self.device_manager.bl_status.get() == BlStatus.OFFLINE: - status = self.device_manager.bl_status.put(BlStatus.ATTENDED) + if self.device_manager.devices.bl_status.get() == BlStatus.OFFLINE: + status = self.device_manager.devices.bl_status.put(BlStatus.ATTENDED) status.wait(timeout=TIMEOUT_FOR_PV) if self.close4bl.get() == BL_ENABLE.DISABLE: status = self.close4bl.set(BL_ENABLE.ENABLE) @@ -96,8 +104,7 @@ class OPPhotonShutter(PSIDeviceBase): status.wait(timeout=self.timeout_for_move) return None return status - else: - return None + return None def close(self, wait: bool = True) -> CompareStatus | None: """Close the Shutter""" @@ -108,5 +115,4 @@ class OPPhotonShutter(PSIDeviceBase): status.wait(timeout=self.timeout_for_move) return None return status - else: - return None + return None