From 87cd2ccfafd5c28720d339e7c562dfdf7035920e Mon Sep 17 00:00:00 2001 From: appel_c Date: Thu, 28 May 2026 17:20:47 +0200 Subject: [PATCH] fix(bec-processed-signal): fix read on processed signal, will force a read on linked signal now --- ophyd_devices/utils/bec_processed_signal.py | 13 +++++++++++++ tests/test_processed_signal.py | 9 +++++++++ 2 files changed, 22 insertions(+) diff --git a/ophyd_devices/utils/bec_processed_signal.py b/ophyd_devices/utils/bec_processed_signal.py index 22f0c1a..abcbe50 100644 --- a/ophyd_devices/utils/bec_processed_signal.py +++ b/ophyd_devices/utils/bec_processed_signal.py @@ -147,6 +147,19 @@ class BECProcessedSignal(SignalRO): compute_method=model_config["compute_method"], **model_config["devices"] ) + def read(self) -> dict[str, Any]: + if self._metadata.get("connected", False) is False: + return super().read() + # Lazy import DSDevice to avoid circular import issues + # pylint: disable=import-outside-toplevel + from bec_server.device_server.devices.devicemanager import DSDevice + + for inp in self.compute_model.method_inputs.values(): + if not isinstance(inp, (Component, Device, Signal, DSDevice)): + continue # Skip non-ophyd objects, they are additional arguments for the compute method + inp.read() # Read the linked device/signals to ensure to be up to date before computing the value + return super().read() + @staticmethod def get_device_object_from_bec( object_name: str, signal_name: str, device_manager: DeviceManagerDS diff --git a/tests/test_processed_signal.py b/tests/test_processed_signal.py index a42b577..1597941 100644 --- a/tests/test_processed_signal.py +++ b/tests/test_processed_signal.py @@ -2,6 +2,8 @@ # pylint: disable=redefined-outer-name +from unittest import mock + import pytest from bec_server.device_server.tests.utils import DMMock from ophyd import Component as Cpt @@ -121,6 +123,13 @@ def test_processed_signal_describe_metadata(processed_signal_from_device_manager assert "samy.readback" in info["method_inputs"] +def test_processed_signal_forces_read(processed_signal_from_device_manager, samx): + """Test that get() forces read of all input signals.""" + with mock.patch.object(samx.readback, "read") as mock_read: + processed_signal_from_device_manager.read() + mock_read.assert_called_once() + + def test_processed_signal_model_rejects_missing_required_inputs(): """Test compute model validation when required kwargs are missing."""