From a3267413cbdc35ca3e417a2affb30ceca90183a2 Mon Sep 17 00:00:00 2001 From: appleb_m Date: Fri, 16 Jan 2026 17:25:33 +0100 Subject: [PATCH] DAQ: added bec class --- src/aare/devices/bec_worker.py | 86 ++++++++++++++++++++++++++++++++++ src/aare/devices/my_motor.py | 34 +++++++++++++- 2 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 src/aare/devices/bec_worker.py diff --git a/src/aare/devices/bec_worker.py b/src/aare/devices/bec_worker.py new file mode 100644 index 00000000..ee98dff9 --- /dev/null +++ b/src/aare/devices/bec_worker.py @@ -0,0 +1,86 @@ +from bec_lib.client import BECClient +from bec_lib.service_config import ServiceConfig +from bec_lib.procedures.helper import FrontendProcedureHelper, BackendProcedureHelper + +#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 BECClientWorker: + def __init__(self, service_config:ServiceConfig, name:str = "default"): + self.client = BECClient(config=service_config, name=name) + self.client.start() + #self.client.config.update_session_with_file("/sls/x10sa/config/bec/production/bec/bec_lib/bec_lib/config_helper.py") + self.devs = self.client.device_manager.devices + self.scans = self.client.scans + self.macros = self.client.macros + self.load_user_macros() + self.helper = FrontendProcedureHelper(self.client.connector) + + def run_macro(self, macro_name:str, *args, queue:str = "default", **kwargs): + return self.client.proc.run_macro(macro_name, *args, "iln", queue=queue) + + def run_macro_blocked(self, macro_name:str, *args, queue:str = "default", **kwargs): + try: + status = self.run_macro(macro_name, *args, queue=queue) + print(status) + status.wait() + print(status) + return status + except Exception as e: + print(f"Error: {e}") + return None + + def show_all_devices(self): + return self.devs.show_all + + def list_all_macros(self): + return self.macros.list_user_macros() + + def load_user_macros(self): + self.macros.load_all_user_macros() + + def shutdown_client(self): + self.client.shutdown() + +if __name__ == "__main__": + service_config = ServiceConfig(redis={"host": "x10sa-bec-001.psi.ch", "port": 6379}) + client = BECClientWorker(service_config, "default") + client.show_all_devices() + client.list_all_macros() + try: + client.run_macro_blocked("a2e", 160, "iln", queue="test") + except Exception as e: + print(f"Error: {e}") + client.shutdown_client() + +# +# try: +# st = client.proc.run_macro("a2e", 160, "iln", queue="test") +# print(st) +# st.wait() +# print(st) +# status_1 = scans.umv(bec_dev.bs_x, -1.0, bec_dev.bs_y, -1.0, relative = True) # blocking +# print( +# f"Moved to position {bec_dev.bs_x.position} with status {status.status}" +# ) +# status = scans.mv(bec_dev.bs_x, 1.0, bec_dev.bs_y, 1.0, relative=True) # none blocking +# status.wait() +# print( +# f"Moved to position {bec_dev.bs_x.position} with status {status.status}" +# ) +# except Exception as e: +# print(f"Error: {e}") +# +# client.shutdown() + + +#backend wont work unless bec server will work, frontend anywehre with user access + diff --git a/src/aare/devices/my_motor.py b/src/aare/devices/my_motor.py index 97ab3603..b4180d36 100644 --- a/src/aare/devices/my_motor.py +++ b/src/aare/devices/my_motor.py @@ -66,6 +66,7 @@ class MyMotor(Motor): :param wait: If True, waits for completion (synchronous) :param timeout: Maximum time to wait for completion """ + return self.move(val, relative=relative, wait=wait, timeout=timeout) def home(self, direction='forward', wait=False): @@ -97,4 +98,35 @@ class MyMotor(Motor): while self.moving: await asyncio.sleep(poll_rate) if time.time() - start_time > timeout: - raise RuntimeError(f"Timeout waiting for motor {self.name} to stop") \ No newline at end of file + raise RuntimeError(f"Timeout waiting for motor {self.name} to stop") + + # def pv_wait(pv: Union[PV, Motor], target: Union[str, int, float], timeout: float = 30.0, + # polling: float = 0.1, tolerance: float | None = None): + # """ + # Unified wait function for Motors and PVs (Strings, Enums, Floats). + # """ + # start_time = time.monotonic() + # end_time = start_time + timeout + # + # # Handle Motors + # if isinstance(pv, Motor): + # if tolerance is None: + # # Try to get the motor resolution/deadband + # tolerance = pv.get("RDBD") or 0.01 + # + # while time.monotonic() < end_time: + # if pv.done_moving and abs(pv.readback - target) <= tolerance: + # return + # + # raise ValueWaitTimeout( + # f"Motor {pv.name} timeout. Target: {target}, Current: {pv.readback}, Done: {pv.done_moving}" + # ) + # + # def wait_for_movement_to_finish(*motors: Motor, timeout: float = 60.0): + # """Wait for a group of motors to stop moving.""" + # start_time = time.time() + # while not all(m.done_moving for m in motors): + # if time.time() - start_time > timeout: + # moving = [m.name for m in motors if not m.done_moving] + # raise TimeoutError(f"Timeout waiting for motors: {', '.join(moving)}") + # poll(0.1) \ No newline at end of file