feat: make bec macros dispatched and test against beamline plugins
CI / lint (pull_request) Successful in 29s
CI / lint (push) Successful in 30s
CI / test (3.11) (push) Successful in 43s
CI / test (3.12) (push) Successful in 42s
CI / test (3.11) (pull_request) Successful in 1m29s
CI / test (3.13) (pull_request) Successful in 1m36s
CI / test (3.13) (push) Successful in 2m38s
CI / test (3.12) (pull_request) Successful in 2m35s
CI / test-with-beamline-plugins (pxi_bec) (push) Successful in 46s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 47s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 51s
CI / test-with-beamline-plugins (pxii_bec) (push) Successful in 1m46s
CI / test-with-beamline-plugins (pxiii_bec) (push) Successful in 1m55s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Successful in 1m58s
CI / test-with-coverage (push) Successful in 53s
CI / test-with-coverage (pull_request) Successful in 57s

This commit is contained in:
2026-07-31 12:01:50 +02:00
parent 03e289c6d7
commit 0f1aa3090b
6 changed files with 163 additions and 25 deletions
+57
View File
@@ -42,6 +42,63 @@ jobs:
index_username: ${{ secrets.GITEA_USER }}
index_password: ${{ secrets.GITEA_TOKEN }}
- name: Run Pytest
env:
QT_QPA_PLATFORM: offscreen
BEAMLINE: SIMULATED
run: |
source .venv/bin/activate
pytest ./tests/unit
test-with-beamline-plugins:
runs-on: ubuntu-latest
needs: ["lint", "test"]
strategy:
matrix:
plugin_repo: ["pxi_bec", "pxii_bec", "pxiii_bec"]
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup
uses: ./.gitea/actions/install
with:
python_version: "3.12"
index_username: ${{ secrets.GITEA_USER }}
index_password: ${{ secrets.GITEA_TOKEN }}
- name: Install beamline plugin
run: |
source .venv/bin/activate
git clone https://gitea.psi.ch/bec/mx_bec.git
git clone https://gitea.psi.ch/bec/${{ matrix.plugin_repo }}.git
uv pip install -e ./mx_bec
uv pip install -e ./${{ matrix.plugin_repo }}
- name: Run Pytest
env:
QT_QPA_PLATFORM: offscreen
BEAMLINE: SIMULATED
run: |
source .venv/bin/activate
pytest ./tests/unit
test-with-coverage:
runs-on: ubuntu-latest
needs: ["lint", "test", "test-with-beamline-plugins"]
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup
uses: ./.gitea/actions/install
with:
python_version: "3.12"
index_username: ${{ secrets.GITEA_USER }}
index_password: ${{ secrets.GITEA_TOKEN }}
- name: Run Pytest with Coverage
env:
QT_QPA_PLATFORM: offscreen
@@ -1,6 +1,6 @@
import os
from aare.beamline_dispatch.protocols import AuthDispatch, BeamlineDispatch
from aare.beamline_dispatch.protocols import AuthDispatch, BeamlineDispatch, BecMacros
class DefaultAuthDispatch(AuthDispatch):
@@ -17,4 +17,8 @@ class DefaultDispatch(BeamlineDispatch):
Should be safe and fail rather than assuming anything."""
def __init__(self) -> None:
self.auth = DefaultAuthDispatch()
self._auth = DefaultAuthDispatch()
@property
def auth(self):
return self._auth
+32 -4
View File
@@ -1,9 +1,37 @@
from typing import Protocol
from abc import ABC, abstractmethod
from typing import Any
class AuthDispatch(Protocol):
class AuthDispatch(ABC):
@abstractmethod
def get_jwt_key(self) -> str: ...
class BeamlineDispatch(Protocol):
auth: AuthDispatch
class BecMacros(ABC):
@staticmethod
@abstractmethod
def save_and_reload(): ...
@staticmethod
@abstractmethod
def save_current_position(device, position, axis=None, force=False, max_delta=0.5) -> None: ...
@staticmethod
@abstractmethod
def init_beamline_environment() -> tuple[Any, Any]: ...
@staticmethod
@abstractmethod
def bl_energy(energy_ev, move_gap=True, mono_scan=True, plot=True): ...
@staticmethod
@abstractmethod
def get_current_energy(): ...
@staticmethod
@abstractmethod
def mono_pitch_scan(plot=True): ...
class BeamlineDispatch(ABC):
@property
@abstractmethod
def auth(self) -> AuthDispatch: ...
@property
@abstractmethod
def bec_macros(self) -> BecMacros: ...
@@ -1,5 +1,7 @@
from typing import Any
from aare.beamline_dispatch.default.beamline_dispatch import DefaultDispatch
from aare.beamline_dispatch.protocols import AuthDispatch
from aare.beamline_dispatch.protocols import AuthDispatch, BecMacros
class SimulatedAuthDispatch(AuthDispatch):
@@ -7,6 +9,26 @@ class SimulatedAuthDispatch(AuthDispatch):
return "Ns93ijN8VHv4ybvXaGNEDKUb3Sif4m4MYpfcEBIcs1h"
class SimulatedBecMacros(BecMacros):
@staticmethod
def save_and_reload(): ...
@staticmethod
def save_current_position(device, position, axis=None, force=False, max_delta=0.5) -> None: ...
@staticmethod
def init_beamline_environment() -> tuple[Any, Any]: ...
@staticmethod
def bl_energy(energy_ev, move_gap=True, mono_scan=True, plot=True): ...
@staticmethod
def get_current_energy(): ...
@staticmethod
def mono_pitch_scan(plot=True): ...
class SimulatedDispatch(DefaultDispatch):
def __init__(self) -> None:
self.auth = SimulatedAuthDispatch()
self._auth = SimulatedAuthDispatch()
self._bec_macros = SimulatedBecMacros()
@property
def bec_macros(self):
return self._bec_macros
@@ -1,4 +1,41 @@
from typing import Any
from aare.beamline_dispatch.default.beamline_dispatch import DefaultDispatch
from aare.beamline_dispatch.protocols import BecMacros
class X10saDispatch(DefaultDispatch): ...
class X10SaBecMacros(BecMacros):
def __init__(self) -> None:
from pxii_bec.macros.build_devices import save_and_reload, save_current_position
from pxii_bec.macros.init_beamline import init_beamline_environment
from pxii_bec.macros.pxii_energy import bl_energy, get_current_energy, mono_pitch_scan
self.save_and_reload = save_and_reload
self.save_current_position = save_current_position
self.init_beamline_environment = init_beamline_environment
self.bl_energy = bl_energy
self.get_current_energy = get_current_energy
self.mono_pitch_scan = mono_pitch_scan
@staticmethod
def save_and_reload(): ...
@staticmethod
def save_current_position(device, position, axis=None, force=False, max_delta=0.5) -> None: ...
@staticmethod
def init_beamline_environment() -> tuple[Any, Any]: ...
@staticmethod
def bl_energy(energy_ev, move_gap=True, mono_scan=True, plot=True): ...
@staticmethod
def get_current_energy(): ...
@staticmethod
def mono_pitch_scan(plot=True): ...
class X10saDispatch(DefaultDispatch):
def __init__(self) -> None:
super().__init__()
self._bec_macros = X10SaBecMacros()
@property
def bec_macros(self) -> BecMacros:
return self._bec_macros
+6 -16
View File
@@ -12,23 +12,11 @@ from bec_ipython_client.signals import OperationMode
from bec_lib.device import RPCError, ScanRequestError
from bec_lib.procedures.helper import FrontendProcedureHelper
from bec_lib.service_config import ServiceConfig
from pxii_bec.macros.build_devices import save_and_reload, save_current_position
from pxii_bec.macros.init_beamline import init_beamline_environment
from pxii_bec.macros.pxii_energy import bl_energy, get_current_energy, mono_pitch_scan
from aare.beamline_dispatch.beamline_dispatch import get_beamline_dispatch
logger = setup_logger("aareDAQ")
# specify up to 10 queue to runs in parallel, request more if needed!
# st = client.proc.request_new("sleep", ((), {"time_s":5}), queue="test")
# to see all deevices
# devs.show_all
# helper fucntions
# helper.get.active_and_pending_queue_names()
# helper.get.running_procedures()
# helper.request.abort_queue()
class DetectorCoverEnum(str, Enum):
"""Enum for the detector cover position
@@ -76,6 +64,8 @@ class BECClientWorker:
else:
raise ValueError(f"Unknown beamline: {beamline}")
self.dispatch = get_beamline_dispatch()
if self.beamline is MXBeamline.SIMULATED:
self.simulated = True
@@ -93,7 +83,7 @@ class BECClientWorker:
self.dev = self.client.device_manager.devices
print(self.dev.keys())
self.scans = self.client.scans
self.macros = self.client.macros
self.macros = self.dispatch.bec_macros
self._load_user_macros()
print(self._list_all_macros())
self.helper = FrontendProcedureHelper(self.client.connector)
@@ -107,7 +97,7 @@ class BECClientWorker:
def _init_beamline_environment(self):
try:
self.position_devices, self.planner = init_beamline_environment()
self.position_devices, self.planner = self.macros.init_beamline_environment()
self._backlight_brightness = self.position_devices["bl_bright"]
self._frontlight_brightness = self.position_devices["fl_bright"]
self._zoom = self.dev.scam_zoom