From 1c54bc6a44d9d57c8e3088203d14d88aed25a918 Mon Sep 17 00:00:00 2001 From: perl_d Date: Fri, 7 Aug 2026 12:13:27 +0200 Subject: [PATCH] feat: simulated bec backend --- .../simulated/beamline_dispatch.py | 13 ++++- src/aare/daq/operations/screenshot/service.py | 2 +- src/aare/devices/bec_definitions.py | 53 +++++++++++++++++ src/aare/devices/bec_worker.py | 58 +++---------------- 4 files changed, 71 insertions(+), 55 deletions(-) create mode 100644 src/aare/devices/bec_definitions.py diff --git a/src/aare/beamline_dispatch/simulated/beamline_dispatch.py b/src/aare/beamline_dispatch/simulated/beamline_dispatch.py index b2521b1e..6ff05f59 100644 --- a/src/aare/beamline_dispatch/simulated/beamline_dispatch.py +++ b/src/aare/beamline_dispatch/simulated/beamline_dispatch.py @@ -3,9 +3,11 @@ from unittest.mock import MagicMock from aarecommon.config.beamline import MXBeamline from bec_ipython_client import BECIPythonClient +from bec_lib.devicemanager import DeviceContainer from aare.beamline_dispatch.default.beamline_dispatch import DefaultConfigKeys, DefaultDispatch from aare.beamline_dispatch.protocols import AuthDispatch, BecMacros, BecSetup +from aare.devices.bec_definitions import BecDevices class SimulatedAuthDispatch(AuthDispatch): @@ -16,13 +18,13 @@ class SimulatedAuthDispatch(AuthDispatch): class SimulatedBecMacros(BecMacros): @staticmethod def save_and_reload() -> tuple[Any, Any]: - return (None, None) + return (MagicMock(), MagicMock()) @staticmethod def save_current_position(device, position, axis=None, force=False, max_delta=0.5) -> None: ... @staticmethod def init_beamline_environment() -> tuple[Any, Any]: - return (None, None) + return (MagicMock(), MagicMock()) @staticmethod def bl_energy(energy_ev, move_gap=True, mono_scan=True, plot=True): ... @@ -38,13 +40,18 @@ class SimulatedBecSetup(BecSetup): self._beamline = beamline def create_client(self) -> BECIPythonClient: - return MagicMock(spec=BECIPythonClient) + mock_client = MagicMock() + mock_client.device_manager.devices = DeviceContainer() + for dev in [d.value for d in list(BecDevices)]: + mock_client.device_manager.devices[dev] = MagicMock() + return mock_client class SimulatedDispatch(DefaultDispatch): def __init__(self) -> None: # pyright: ignore[reportMissingSuperCall] self._auth = SimulatedAuthDispatch() self._bec_macros = SimulatedBecMacros() + self._bec_setup = SimulatedBecSetup(MXBeamline.SIMULATED) self._config = DefaultConfigKeys(MXBeamline.SIMULATED) @property diff --git a/src/aare/daq/operations/screenshot/service.py b/src/aare/daq/operations/screenshot/service.py index 13d20dac..34afdc2b 100644 --- a/src/aare/daq/operations/screenshot/service.py +++ b/src/aare/daq/operations/screenshot/service.py @@ -7,10 +7,10 @@ from typing import Protocol import cv2 import numpy as np from aarecommon.models.models import SampleShortInfo +from aarecommon.utils.paths import clean_filename from aare.daq.aaredb import AareWrapper from aare.daq.mlbox import MlBox -from aare.devices.mx_lib import clean_filename class NonCriticalRunner(Protocol): diff --git a/src/aare/devices/bec_definitions.py b/src/aare/devices/bec_definitions.py new file mode 100644 index 00000000..42adaa13 --- /dev/null +++ b/src/aare/devices/bec_definitions.py @@ -0,0 +1,53 @@ +from enum import StrEnum + +from aarecommon.errors.exception_handler import BECException + + +class DetectorCoverEnum(StrEnum): + """Enum for the detector cover position + position devices can take string or number to move + Currently dictated string in DAQ for consitency""" + + OPEN = "open" # 2 + CLOSED = "closed" # 1 + + +class BrightnessEnum(StrEnum): + """Enum for the backlight brightness + position devices can take string or number to move + """ + + ON = "on" + OFF = "off" + + +class BeamlineState(StrEnum): + ROBOT_SAMPLE_EXCHANGE = "robot_sample_exchange" + SAMPLE_ALIGNMENT = "sample_alignment" + DATA_COLLECTION = "data_collection" + DC_XRF = "DC_XRF" + MANUAL_SAMPLE_EXCHANGE = "manual_sample_exchange" + BEAM_VISUALISATION = "beam_visualisation" + FLUX_MEASUREMENT = "flux_measurement" + BEAMSTOP_ALIGNMENT = "beamstop_alignment" + MAINTENANCE = "maintenance" + XTAL_SNAPSHOT = "xtal_snapshot" + + +class BecDevices(StrEnum): + DET_Z = "det_z" + FL_BRIGHT = "fl_bright" + BACKLIGHT_BRIGHT = "bl_bright" + BACKLIGHT_POS = "bl_pos" + SAMCAM_ZOOM = "scam_zoom" + CRYO_POS = "cryo_pos" + CRYO_TEMP = "cryo_temp" + CRYO_X = "cryo_x" + TRANSM = "transm" + BCU_SHUTTER = "bcu_shutter" + MAG_OK = "mag_ok" + MAG_RBV = "mag_rbv" + SLS_CURRENT = "sls_current" + + +class MissingDevicesError(BECException): ... diff --git a/src/aare/devices/bec_worker.py b/src/aare/devices/bec_worker.py index 25c4c1fa..0f351d9c 100644 --- a/src/aare/devices/bec_worker.py +++ b/src/aare/devices/bec_worker.py @@ -1,68 +1,24 @@ import sys import time -from enum import Enum, StrEnum from aarecommon.config.logger import setup_logger from aarecommon.config.logger_events import log_timing -from aarecommon.errors.exception_handler import BECCommunicationError, BECException +from aarecommon.errors.exception_handler import BECCommunicationError from aarecommon.models.beamline import MXBeamline from bec_lib.device import RPCError, ScanRequestError from bec_lib.devicemanager import DeviceContainer from aare.beamline_dispatch.beamline_dispatch import get_beamline_dispatch +from aare.devices.bec_definitions import ( + BeamlineState, + BecDevices, + BrightnessEnum, + MissingDevicesError, +) logger = setup_logger("aareDAQ") -class DetectorCoverEnum(str, Enum): - """Enum for the detector cover position - position devices can take string or number to move - Currently dictated string in DAQ for consitency""" - - OPEN = "open" # 2 - CLOSED = "closed" # 1 - - -class BrightnessEnum(str, Enum): - """Enum for the backlight brightness - position devices can take string or number to move - """ - - ON = "on" - OFF = "off" - - -class BeamlineState(str, Enum): - ROBOT_SAMPLE_EXCHANGE = "robot_sample_exchange" - SAMPLE_ALIGNMENT = "sample_alignment" - DATA_COLLECTION = "data_collection" - DC_XRF = "DC_XRF" - MANUAL_SAMPLE_EXCHANGE = "manual_sample_exchange" - BEAM_VISUALISATION = "beam_visualisation" - FLUX_MEASUREMENT = "flux_measurement" - BEAMSTOP_ALIGNMENT = "beamstop_alignment" - MAINTENANCE = "maintenance" - XTAL_SNAPSHOT = "xtal_snapshot" - - -class BecDevices(StrEnum): - DET_Z = "det_z" - FL_BRIGHT = "fl_bright" - BACKLIGHT_BRIGHT = "bl_bright" - BACKLIGHT_POS = "bl_pos" - SAMCAM_ZOOM = "scam_zoom" - CRYO_POS = "cryo_pos" - CRYO_TEMP = "cryo_temp" - CRYO_X = "cryo_x" - TRANSM = "transm" - BCU_SHUTTER = "bcu_shutter" - MAG_OK = "mag_ok" - MAG_RBV = "mag_rbv" - - -class MissingDevicesError(BECException): ... - - class BECClientWorker: def __init__(self, beamline: MXBeamline, name: str = "default"): self.dispatch = get_beamline_dispatch()